From bafa5d2b1604dbf94ba319da41482f39ebdc3e31 Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Thu, 25 Aug 2022 07:11:30 +0200 Subject: [PATCH 01/70] HBG 4 Cards (#1338) * Add files via upload * Update flames_of_moradin.txt * Update water_weird.txt * Update water_weird.txt * Update water_weird.txt * Update water_weird.txt * Update mind_spike.txt * Update yuan_ti_scaleshield.txt * Update water_weird.txt * Update mind_spike.txt * Update mind_spike.txt * Update mind_spike.txt * Update flames_of_moradin.txt * Update flames_of_moradin.txt Targeting a Token still makes Forge Crash * Update flames_of_moradin.txt * Update water_weird.txt * Update yuan_ti_scaleshield.txt * update * Update flames_of_moradin.txt * Update flames_of_moradin.txt * Create arcane_archery.txt * Update arcane_archery.txt * Update water_weird.txt * Delete flames_of_moradin.txt * Update yuan_ti_scaleshield.txt * Update water_weird.txt --- .../res/cardsfolder/upcoming/arcane_archery.txt | 11 +++++++++++ forge-gui/res/cardsfolder/upcoming/mind_spike.txt | 8 ++++++++ forge-gui/res/cardsfolder/upcoming/water_weird.txt | 12 ++++++++++++ .../res/cardsfolder/upcoming/yuan_ti_scaleshield.txt | 7 +++++++ 4 files changed, 38 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/arcane_archery.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/mind_spike.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/water_weird.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/yuan_ti_scaleshield.txt diff --git a/forge-gui/res/cardsfolder/upcoming/arcane_archery.txt b/forge-gui/res/cardsfolder/upcoming/arcane_archery.txt new file mode 100644 index 00000000000..55f85231ece --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/arcane_archery.txt @@ -0,0 +1,11 @@ +Name:Arcane Archery +ManaCost:2 G +Types:Instant +A:SP$ Pump | ValidTgts$ Creature | NumAtt$ 3 | NumDef$ 3 | KW$ Reach,Trample | SubAbility$ DBDelayedTrigger | SpellDescription$ Target creature gets +3/+3 and gains reach and trample until end of turn. You get a boon with "When you cast your next creature spell, that creature enters the battlefield with an additional +1/+1 counter, reach counter, and trample counter on it." +SVar:DBDelayedTrigger:DB$ DelayedTrigger | Execute$ TrigAddAPI | Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You +SVar:TrigAddAPI:DB$ Effect | RememberObjects$ TriggeredCard | ForgetOnMoved$ Stack | ReplacementEffects$ ReplaceEnter +SVar:ReplaceEnter:Event$ Moved | ValidCard$ Card.IsRemembered | Destination$ Battlefield | ReplaceWith$ AddExtraCounter | ReplacementResult$ Updated | Description$ This creature enters the battlefield with an additional +1/+1 counter, reach counter, and trample counter on it. +SVar:AddExtraCounter:DB$ PutCounter | ETB$ True | Defined$ ReplacedCard | CounterTypes$ P1P1,Trample,Reach | CounterNum$ 1 | SubAbility$ DBExile +SVar:DBExile:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile +DeckHas:Ability$Counters +Oracle:Target creature gets +3/+3 and gains reach and trample until end of turn.\nYou get a boon with "When you cast your next creature spell, that creature enters the battlefield with an additional +1/+1 counter, reach counter, and trample counter on it." \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/mind_spike.txt b/forge-gui/res/cardsfolder/upcoming/mind_spike.txt new file mode 100644 index 00000000000..2c805966e9e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/mind_spike.txt @@ -0,0 +1,8 @@ +Name:Mind Spike +ManaCost:B +Types:Sorcery +A:SP$ Reveal | ValidTgts$ Opponent | RevealAllValid$ Card.nonLand+nonCreature+TargetedPlayerCtrl | RememberRevealed$ True | SubAbility$ DBDiscard | StackDescription$ SpellDescription | SpellDescription$ Target opponent reveals each noncreature, nonland card in their hand. You choose a card revealed this way. That player discards that card. You lose 2 life. If they didn't reveal a card this way, you draw a card. +SVar:DBDiscard:DB$ Discard | Defined$ Targeted | Mode$ YouChoose | NumCards$ 1 | DiscardValid$ Card.nonLand+nonCreature | SubAbility$ DBLoseLife +SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ 2 | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | NumCards$ 1 | Defined$ You | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0 +Oracle:Target opponent reveals each noncreature, nonland card in their hand. You choose a card revealed this way. That player discards that card. You lose 2 life. If they didn't reveal a card this way, you draw a card. diff --git a/forge-gui/res/cardsfolder/upcoming/water_weird.txt b/forge-gui/res/cardsfolder/upcoming/water_weird.txt new file mode 100644 index 00000000000..b8a4b1247c6 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/water_weird.txt @@ -0,0 +1,12 @@ +Name:Water Weird +ManaCost:3 U +Types:Creature Elemental Weird +PT:3/4 +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ TrigReveal | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, put a +1/+1 counter on CARDNAME if the top card of your library is a nonland card. Otherwise, you may mill a card. +SVar:TrigReveal:DB$ PeekAndReveal | PeekAmount$ 1 | NoPeek$ True | NoReveal$ True | RememberPeeked$ True | SubAbility$ DBCounter +SVar:DBCounter:DB$ PutCounter | CounterNum$ 1 | Defined$ Self | ConditionDefined$ Remembered | ConditionPresent$ Card.nonLand | ConditionCompare$ EQ1 | CounterType$ P1P1 | SubAbility$ DBMill +SVar:DBMill:DB$ Mill | NumCards$ 1 | Optional$ True | ConditionDefined$ Remembered | ConditionPresent$ Card.Land | ConditionCompare$ EQ1 | SubAbility$ DBCleanup +A:AB$ Pump | Cost$ 1 U | NumAtt$ +1 | NumDef$ -1 | SpellDescription$ CARDNAME gets +1/-1 until end of turn. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +DeckHas:Ability$Counters +Oracle:Whenever Water Weird deals combat damage to a player, put a +1/+1 counter on Water Weird if the top card of your library is a nonland card. Otherwise, you may mill a card.\n{1}{U}: Water Weird gets +1/-1 until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/yuan_ti_scaleshield.txt b/forge-gui/res/cardsfolder/upcoming/yuan_ti_scaleshield.txt new file mode 100644 index 00000000000..8e9e8007e51 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/yuan_ti_scaleshield.txt @@ -0,0 +1,7 @@ +Name:Yuan-Ti Scaleshield +ManaCost:2 G +Types:Instant +A:SP$ PumpAll | ValidCards$ Permanent.YouCtrl | KW$ Hexproof & Indestructible | SubAbility$ DBSeek | SpellDescription$ Permanents you control gain hexproof and indestructible until end of turn. Seek a creature card if an opponent has cast a spell with mana value 3 or less this turn. +SVar:DBSeek:DB$ ChangeZone | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1 | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Card.Creature | ChangeNum$ 1 +SVar:X:Count$ThisTurnCast_Card.cmcLE3+OppCtrl +Oracle:Permanents you control gain hexproof and indestructible until end of turn.\nSeek a creature card if an opponent has cast a spell with mana value 3 or less this turn. From 4b40ff9a366aebcf98c9ee939532f875ad2d7c6b Mon Sep 17 00:00:00 2001 From: Agetian Date: Thu, 25 Aug 2022 14:24:42 +0300 Subject: [PATCH 02/70] - Fix last state battlefield check on replacement abilities such as Temple of the Dragon Queen (#1398) --- forge-game/src/main/java/forge/game/ability/AbilityUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 806ba8a6b40..e49f7f1d688 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -2737,10 +2737,10 @@ public class AbilityUtils { SpellAbility sa = (SpellAbility) ctb; if (sa.isReplacementAbility()) { if (zones.get(0).equals(ZoneType.Battlefield)) { - cardsInZones = sa.getLastStateBattlefield(); + cardsInZones = sa.getRootAbility().getLastStateBattlefield(); usedLastState = true; } else if (zones.get(0).equals(ZoneType.Graveyard)) { - cardsInZones = sa.getLastStateGraveyard(); + cardsInZones = sa.getRootAbility().getLastStateGraveyard(); usedLastState = true; } } From 77b752cf53b313c30c2ffc062e799d15983aefcd Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Thu, 25 Aug 2022 15:54:59 +0200 Subject: [PATCH 03/70] DMU 9 Cards + Phyresis counter support (#1395) * update * update * Create wingmantle_chaplain.txt * Update vohar_vodalian_desecrator.txt * Update vohar_vodalian_desecrator.txt * Update jodah_the_unifier.txt * Delete walking_bulwark.txt * Update weatherlight_compleated.txt * Update wingmantle_chaplain.txt * Update vohar_vodalian_desecrator.txt * Update vohar_vodalian_desecrator.txt * Update zar_ojanen_scion_of_efrava.txt * Update wingmantle_chaplain.txt * Update vohar_vodalian_desecrator.txt * update * Update vesuvan_duplimancy.txt * Update vesuvan_duplimancy.txt * Update vohar_vodalian_desecrator.txt * Update weatherlight_compleated.txt * Update wingmantle_chaplain.txt * Update writhing_necromass.txt * Update zar_ojanen_scion_of_efrava.txt --- .../java/forge/game/card/CounterEnumType.java | 2 ++ .../cardsfolder/upcoming/jodah_the_unifier.txt | 12 ++++++++++++ .../cardsfolder/upcoming/vesuvan_duplimancy.txt | 9 +++++++++ .../cardsfolder/upcoming/vodalian_mindsinger.txt | 12 ++++++++++++ .../upcoming/vohar_vodalian_desecrator.txt | 16 ++++++++++++++++ .../upcoming/weatherlight_compleated.txt | 13 +++++++++++++ .../cardsfolder/upcoming/wingmantle_chaplain.txt | 13 +++++++++++++ .../cardsfolder/upcoming/writhing_necromass.txt | 8 ++++++++ .../cardsfolder/upcoming/yavimaya_sojourner.txt | 7 +++++++ .../upcoming/zar_ojanen_scion_of_efrava.txt | 9 +++++++++ 10 files changed, 101 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/jodah_the_unifier.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/vesuvan_duplimancy.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/vodalian_mindsinger.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/vohar_vodalian_desecrator.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/weatherlight_compleated.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/wingmantle_chaplain.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/writhing_necromass.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/yavimaya_sojourner.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/zar_ojanen_scion_of_efrava.txt 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 826632e478e..dfcbaa4c21e 100644 --- a/forge-game/src/main/java/forge/game/card/CounterEnumType.java +++ b/forge-game/src/main/java/forge/game/card/CounterEnumType.java @@ -267,6 +267,8 @@ public enum CounterEnumType { PHYLACTERY("PHYLA", 117, 219, 153), + PHYRESIS("PHYRE", 125, 97, 128), + POINT("POINT", 153, 255, 130), POLYP("POLYP", 236, 185, 198), diff --git a/forge-gui/res/cardsfolder/upcoming/jodah_the_unifier.txt b/forge-gui/res/cardsfolder/upcoming/jodah_the_unifier.txt new file mode 100644 index 00000000000..6265e392e0d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/jodah_the_unifier.txt @@ -0,0 +1,12 @@ +Name:Jodah, the Unifier +ManaCost:W U B R G +Types:Legendary Creature Human Wizard +PT:5/5 +S:Mode$ Continuous | Affected$ Creature.Legendary+YouCtrl | AddPower$ X | AddToughness$ X | Description$ Legendary creatures you control get +X/+X, where X is the number of legendary creatures you control. +T:Mode$ SpellCast | ValidCard$ Card.Legendary+wasCastFromYourHandByYou | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ DBDigUntil | TriggerDescription$ Whenever you cast a legendary spell from your hand, exile cards from the top of your library until you exile a legendary nonland card with lesser mana value. You may cast that card without paying its mana cost. Put the rest on the bottom of your library in a random order. +SVar:DBDigUntil:DB$ DigUntil | Defined$ You | Valid$ Card.nonLand+Legendary+cmcLEY | FoundDestination$ Exile | RevealedDestination$ Library | RestRandomOrder$ True | SubAbility$ DBPlay | StackDescription$ then reveals cards from the top of it until they reveal a legendary nonland card with lesser mana value. {p:You} exiles that card and puts the rest on the bottom of their library in a random order. +SVar:DBPlay:DB$ Play | Defined$ Remembered | ValidSA$ Spell | WithoutManaCost$ True | Optional$ True | StackDescription$ {p:You} may cast the exiled card without paying its mana cost. | SpellDescription$ You may cast the exiled card without paying its mana cost. +SVar:X:Count$Valid Creature.Legendary+YouCtrl +SVar:Y:TriggeredCard$CardManaCost +DeckHints:Type$Legendary +Oracle:Legendary creatures you control get +X/+X, where X is the number of legendary creatures you control.\nWhenever you cast a legendary spell from your hand, exile cards from the top of your library until you exile a legendary nonland card with lesser mana value. You may cast that card without paying its mana cost. Put the rest on the bottom of your library in a random order diff --git a/forge-gui/res/cardsfolder/upcoming/vesuvan_duplimancy.txt b/forge-gui/res/cardsfolder/upcoming/vesuvan_duplimancy.txt new file mode 100644 index 00000000000..38db238969f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/vesuvan_duplimancy.txt @@ -0,0 +1,9 @@ +Name:Vesuvan Duplimancy +ManaCost:3 U +Types:Enchantment +T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | Execute$ TrigCopyTarget | ValidActivatingPlayer$ You | IsSingleTarget$ True | TriggerZones$ Battlefield | TargetsValid$ Creature.YouCtrl+inZoneBattlefield,Artifact.YouCtrl+inZoneBattlefield | RememberValidCards$ True | TriggerDescription$ Whenever you cast a spell that targets only a single artifact or creature you control, create a token that's a copy of that artifact or creature, except it's not legendary. +SVar:TrigCopyTarget:DB$ CopyPermanent | Choices$ Permanent.IsRemembered | NonLegendary$ True | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +DeckHints:Type$Instant|Sorcery +DeckHas:Ability$Token & Type$Artifact +Oracle:Whenever you cast a spell that targets only a single artifact or creature you control, create a token that's a copy of that artifact or creature, except it's not legendary diff --git a/forge-gui/res/cardsfolder/upcoming/vodalian_mindsinger.txt b/forge-gui/res/cardsfolder/upcoming/vodalian_mindsinger.txt new file mode 100644 index 00000000000..d88f94d08ba --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/vodalian_mindsinger.txt @@ -0,0 +1,12 @@ +Name:Vodalian Mindsinger +ManaCost:1 U U +Types:Creature Merfolk Wizard +PT:2/2 +K:Kicker:1 B:1 G +K:etbCounter:P1P1:X:CheckSVar$ X:CARDNAME enters the battlefield with two +1/+1 counters on it for each time it was kicked +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | TriggerDescription$ When CARDNAME enters the battlefield, gain control of target creature with power less than CARDNAME's power for as long as you control CARDNAME. +SVar:TrigChange:DB$ GainControl | TgtPrompt$ Choose target creature with power less than CARDNAME's power | ValidTgts$ Creature.cmcLEY | LoseControl$ LeavesPlay,LoseControl +SVar:X:Count$TimesKicked/Twice +SVar:Y:TriggeredCard$CardPower +DeckHas:Ability$Counters +Oracle:Kicker {1}{R} and/or {1}{G}\nVodalian Mindsinger enters the battlefield with two +1/+1 counters on it for each time it was kicked.\nWhen Vodalian Mindsinger enters the battlefield, gain control of target creature with power less than Vodalian Mindsinger’s power for as long as you control Vodalian Mindsinger. diff --git a/forge-gui/res/cardsfolder/upcoming/vohar_vodalian_desecrator.txt b/forge-gui/res/cardsfolder/upcoming/vohar_vodalian_desecrator.txt new file mode 100644 index 00000000000..0df46213bbc --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/vohar_vodalian_desecrator.txt @@ -0,0 +1,16 @@ +Name:Vohar, Vodalian Desecrator +ManaCost:U B +Types:Legendary Creature Phyrexian Merfolk Wizard +PT:1/2 +A:AB$ Draw | Cost$ T | SubAbility$ DBDiscard | SpellDescription$ Draw a card, then discard a card. If you discarded an instant or sorcery card this way, each opponent loses 1 life and you gain 1 life. +SVar:DBDiscard:DB$ Discard | Mode$ TgtChoose | RememberDiscarded$ True | SubAbility$ DBLoseLife +SVar:DBLoseLife:DB$ LoseLife | ConditionDefined$ Remembered | ConditionPresent$ Instant,Sorcery | Defined$ Player.Opponent | LifeAmount$ 1 | SubAbility$ DBGainLife +SVar:DBGainLife:DB$ GainLife | ConditionDefined$ Remembered | ConditionPresent$ Instant,Sorcery | Defined$ You | LifeAmount$ 1 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +A:AB$ Effect | Cost$ 2 Sac<1/CARDNAME> | ValidTgts$ Instant.YouOwn,Sorcery.YouOwn | SorcerySpeed$ True | TgtZone$ Graveyard | TgtPrompt$ Select target instant or sorcery card in your graveyard | RememberObjects$ Targeted | StaticAbilities$ MayPlay | ReplacementEffects$ ReplaceGraveyard | SpellDescription$ You may cast target instant or sorcery card from your graveyard this turn. If that spell would be put into your graveyard, exile it instead. Activate only as a sorcery. +SVar:MayPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Graveyard | Description$ You may cast target instant or sorcery card from your graveyard this turn. (You still pay the spell's costs. Timing rules for the spell still apply.) +SVar:ReplaceGraveyard:Event$ Moved | ValidCard$ Card.IsRemembered | Destination$ Graveyard | ReplaceWith$ MoveExile | Description$ If that spell would be put into your graveyard, exile it instead. +SVar:MoveExile:DB$ ChangeZone | Defined$ ReplacedCard | Origin$ All | Destination$ Exile +DeckNeeds:Type$Instant|Sorcery +DeckHas:Ability$Discard|LifeGain +Oracle:{T}: Draw a card, then discard a card. If you discarded an instant or sorcery card this way, each opponent loses 1 life and you gain 1 life.\n{2},Sacrifice Vohar, Vodalian Desecrator: You may cast target instant or sorcery card from your graveyard this turn. If that spell would be put into your graveyard, exile it instead. Activate only as a sorcery. diff --git a/forge-gui/res/cardsfolder/upcoming/weatherlight_compleated.txt b/forge-gui/res/cardsfolder/upcoming/weatherlight_compleated.txt new file mode 100644 index 00000000000..71cfa8585cf --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/weatherlight_compleated.txt @@ -0,0 +1,13 @@ +Name:Weatherlight Compleated +ManaCost:2 +Types:Legendary Artifact Vehicle +PT:5/5 +K:Flying +S:Mode$ Continuous | Affected$ Card.Self+counters_GE4_PHYRESIS | AddType$ Creature & Phyrexian | Description$ As long as CARDNAME has four or more phyresis counters on it, it's a Phyrexian creature in addition to its other types. +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever a creature you control dies, put a phyresis counter on CARDNAME. Then draw a card if it has seven or more phyresis counters on it. If it doesn't, scry 1. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ PHYRESIS | CounterNum$ 1 | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | NumCards$ 1 | ConditionDefined$ Self | ConditionPresent$ Card.Self+counters_GE7_PHYRESIS | SubAbility$ DBScry +SVar:DBScry:DB$ Scry | ScryNum$ 1 | ConditionDefined$ Self | ConditionPresent$ Card.Self+counters_LE6_PHYRESIS +DeckHints:Ability$Graveyard|Sacrifice & Type$Phyrexian +DeckHas:Ability$Counters +Oracle:Flying\nAs long as Weatherlight Compleated has four or more phyresis counters on it, it's a Phyrexian creature in addition to its other types.\nWhenever a creature you control dies, put a phyresis counter on Weatherlight Compleated. Then draw a card if it has seven or more phyresis counters on it. If it doesn't, scry 1. diff --git a/forge-gui/res/cardsfolder/upcoming/wingmantle_chaplain.txt b/forge-gui/res/cardsfolder/upcoming/wingmantle_chaplain.txt new file mode 100644 index 00000000000..6b19ce9fd06 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/wingmantle_chaplain.txt @@ -0,0 +1,13 @@ +Name:Wingmantle Chaplain +ManaCost:3 W +Types:Creature Human Cleric +PT:0/3 +K:Defender +T:Mode$ ChangesZone | ValidCard$ Card.Self | Destination$ Battlefield | Execute$ TrigBird | TriggerDescription$ When CARDNAME enters the battlefield, create a 1/1 white Bird creature token with flying for each creature with defender you control. +SVar:TrigBird:DB$ Token | TokenScript$ w_1_1_bird_flying | TokenAmount$ X +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.withDefender+YouCtrl+Other | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever another creature with defender enters the battlefield under your control, create a 1/1 white Bird creature token with flying. +SVar:TrigToken:DB$ Token | TokenScript$ w_1_1_bird_flying +SVar:X:Count$Valid Creature.withDefender+YouCtrl +DeckHints:Keyword$Defender +DeckHas:Ability$Token +Oracle:Defender\nWhen Wingmantle Chaplain enters the battlefield, create a 1/1 white Bird creature token with flying for each creature with defender you control.\nWhenever another creature with defender enters the battlefield under your control, create a 1/1 white Bird creature token with flying. diff --git a/forge-gui/res/cardsfolder/upcoming/writhing_necromass.txt b/forge-gui/res/cardsfolder/upcoming/writhing_necromass.txt new file mode 100644 index 00000000000..cad1aa48472 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/writhing_necromass.txt @@ -0,0 +1,8 @@ +Name:Writhing Necromass +ManaCost:6 B +Types:Creature Zombie Giant +PT:5/5 +K:Deathtouch +S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ X | EffectZone$ All | Description$ This spell costs {1} less to cast for each creature card in your graveyard. +SVar:X:Count$TypeInYourYard.Creature +Oracle:This spell costs {1} less to cast for each creature card in your graveyard.\nDeathtouch diff --git a/forge-gui/res/cardsfolder/upcoming/yavimaya_sojourner.txt b/forge-gui/res/cardsfolder/upcoming/yavimaya_sojourner.txt new file mode 100644 index 00000000000..493ce4d8956 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/yavimaya_sojourner.txt @@ -0,0 +1,7 @@ +Name:Yavimaya Sojourner +ManaCost:7 G +Types:Creature Treefolk +PT:4/6 +S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ X | EffectZone$ All | Description$ Domain — This spell costs {1} less to cast for each basic land type among lands you control. +SVar:X:Count$Domain +Oracle:Domain — This spell costs {1} less to cast for each basic land type among lands you control. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/zar_ojanen_scion_of_efrava.txt b/forge-gui/res/cardsfolder/upcoming/zar_ojanen_scion_of_efrava.txt new file mode 100644 index 00000000000..d9a947d6470 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/zar_ojanen_scion_of_efrava.txt @@ -0,0 +1,9 @@ +Name:Zar Ojanen, Scion of Efrava +ManaCost:3 G W +Types:Legendary Creature Cat Warrior +PT:4/4 +T:Mode$ Taps | ValidCard$ Card.Self | Execute$ TrigPutcounter | TriggerZones$ Battlefield | TriggerDescription$ Domain — Whenever CARDNAME becomes tapped, put a +1/+1 counter on each creature you control with toughness less than the number of basic land types among lands you control. +SVar:TrigPutcounter:DB$ PutCounterAll | ValidCards$ Creature.YouCtrl+toughnessLTX | CounterType$ P1P1 | CounterNum$ 1 +SVar:X:Count$Domain +DeckHas:Ability$Counters +Oracle:Domain — Whenever Zar Ojanen, Scion of Efrava becomes tapped, put a +1/+1 counter on each creature you control with toughness less than the number of basic land types among lands you control. From eaacf0f0f03bf1b4bc0857002d86dead722a10df Mon Sep 17 00:00:00 2001 From: paulsnoops Date: Thu, 25 Aug 2022 19:37:25 +0100 Subject: [PATCH 04/70] DMU & DMC edition updates --- .../editions/Dominaria United Commander.txt | 132 ++++++++++++++++ forge-gui/res/editions/Dominaria United.txt | 143 +++++++++++++++++- 2 files changed, 272 insertions(+), 3 deletions(-) diff --git a/forge-gui/res/editions/Dominaria United Commander.txt b/forge-gui/res/editions/Dominaria United Commander.txt index 8286b9388f2..bc3578f5e0d 100644 --- a/forge-gui/res/editions/Dominaria United Commander.txt +++ b/forge-gui/res/editions/Dominaria United Commander.txt @@ -32,6 +32,7 @@ ScryfallCode=DMC 32 R Hazezon, Shaper of Sand @Bryan Sola 33 U Jasmine Boreal of the Seven @Bastien L. Deharme 34 M Jedit Ojanen, Mercenary @Ilse Gort +35 M The Lady of Otaria @Scott Murphy 36 R Ohabi Caleria @Nestor Ossandon Leal 37 R Orca, Siege Demon @Daarken 38 U Ramirez DePietro, Pillager @Anna Steinbauer @@ -41,6 +42,7 @@ ScryfallCode=DMC 42 R Stangg, Echo Warrior @Randy Vargas 43 M Sivitri, Dragon Master @Livia Prima 44 M Tetsuo, Imperial Champion @Lius Lasahido +45 U Tobias, Doomed Conqueror @Dmitry Burmak 46 U Tor Wauki the Younger @Karl Kopinski 47 M Torsten, Founder of Benalia @Volkan Baǵa 48 R Xira, the Golden Sting @Mila Pesic @@ -56,18 +58,148 @@ ScryfallCode=DMC 66 M Tetsuo, Imperial Champion @Lius Lasahido 68 U Tor Wauki the Younger @Karl Kopinski 69 M Torsten, Founder of Benalia @Volkan Baǵa +97 R Anafenza, Kin-Tree Spirit @Ryan Yee +98 M The Circle of Loyalty @Bastien L. Deharme +99 R Day of Destiny @Daren Bader +100 U Generous Gift @Kev Walker +101 R Hero of Precinct One @Bram Sels +102 M Jazal Goldmane @Aaron Miller +103 R Odric, Lunarch Marshal @Chase Stone 104 U Path to Exile @Todd Lockwood +105 R Teshar, Ancestor's Apostle @Even Amundsen +106 R Unbreakable Formation @Matt Stewart +107 R Urza's Ruinous Blast @Slawomir Maniak +108 R Zetalpa, Primal Dawn @Chris Rallis +109 C Echoing Truth @Greg Staples +110 U Ambition's Cost @Zezhou Chen +111 M Drana, Liberator of Malakir @Mike Bierek +112 U Hero's Downfall @Chris Rallis +113 R Josu Vess, Lich Knight @Tyler Jacobson +114 R Kothophed, Soul Hoarder @Jakub Kasper +115 C Night's Whisper @John Severin Brassell +116 R Painful Truths @Winona Nelson +117 C Read the Bones @Lars Grant-West +118 R Alesha, Who Smiles at Death @Anastasia Ovchinnikova +119 R Ashling the Pilgrim @Wayne Reynolds +120 R Captain Lannery Storm @Chris Rallis +121 R Etali, Primal Storm @Raymond Swanland +122 C Faithless Looting @Karl Kopinski +123 R Kari Zev, Skyship Raider @Brad Rigney +124 R Krenko, Tin Street Kingpin @Mark Behm +125 R Neheb, Dreadhorde Champion @Igor Kieryluk +126 R Radiant Flames @Slawomir Maniak 127 C Thrill of Possibility @Izzy +128 C Abundant Growth @Vincent Proce +129 U Beast Within @Jesper Ejsing +130 U Cultivate @Anthony Palumbo +131 C Explore @John Avon +132 U Explosive Vegetation @John Avon +133 C Farseek @Martina Pilcerova +134 C Kodama's Reach @Sam Burley +135 U Migration Path @Grzegorz Rutkowski +136 U Path to the World Tree @Daniel Ljunggren +137 C Search for Tomorrow @Greg Staples +138 U Abzan Charm @Mathias Kollros +139 R Adriana, Captain of the Guard @Chris Rallis +140 R Archelos, Lagoon Mystic @Dan Scott +141 U Arvad the Cursed @Lius Lasahido +142 R Atla Palani, Nest Tender @Ekaterina Burmak 143 R Baleful Strix @Nils Hamm +144 R Bedevil @Seb McKinnon +145 R Bell Borca, Spectral Sergeant @Mila Pesic +146 M Chromanticore @Min Yum +147 C Coiling Oracle @Mark Zug +148 R Duneblast @Ryan Alexander Lee 149 R Faeburrow Elder @Raoul Vitale +150 U Fusion Elemental @Michael Komarck +151 U Garna, the Bloodflame @Winona Nelson +152 R Glint-Eye Nephilim @Mark Zug +153 C Growth Spiral @Seb McKinnon +155 R Kaya's Wrath @Victor Adame Minguez +156 R Knight of New Alara @Chris Rahn +157 R Lavalanche @Steve Argyle +158 M Maelstrom Archangel @Cyril Van Der Haegen 159 M Maelstrom Nexus @Steven Belledin +160 R Merciless Eviction @Richard Wright +161 U Mortify @Anthony Palumbo +162 U Naya Charm @Jesper Ejsing 163 M Nethroi, Apex of Death @Slawomir Maniak 164 M O-Kagachi, Vengeful Kami @Daarken +165 R Primevals' Glorious Rebirth @Yigit Koroglu +166 M Rienne, Angel of Rebirth @Kieran Yanner +167 R Selvala, Explorer Returned @Tyler Jacobson +168 U Sultai Charm @Mathias Kollros 169 M Surrak Dragonclaw @Jaime Jones +170 U Sylvan Reclamation @Seb McKinnon +171 R Tajic, Blade of the Legion @James Ryman +172 C Terminate @DiTerlizzi +173 R Time Wipe @Svetlin Velinov +174 U Wear // Tear @Ryan Pancoast +175 M Xyris, the Writhing Storm @Filip Burburan +176 M Zaxara, the Exemplary @Simon Dominic +177 C Arcane Signet @Dan Scott +178 R Blackblade Reforged @Chris Rahn +179 U Bontu's Monument @Jonas De Ro +180 R Coalition Relic @Donato Giancola +181 C Commander's Sphere @Ryan Alexander Lee +182 U Fellwar Stone @John Avon +183 U Hazoret's Monument @Richard Wright +184 U Hedron Archive @Craig J Spearing +185 R Heroes' Podium @Willian Murai +186 U Hero's Blade @Aaron Miller +187 U Honor-Worn Shaku @Tony Szczudlo +188 U Oketra's Monument @Christine Choi +189 C Prophetic Prism @John Avon +190 U Sol Ring @Mike Bierek +191 R Solemn Simulacrum @Donato Giancola +192 R Sword of the Chosen @Adam Rex +193 U Tenza, Godo's Maul @Paolo Parente +194 U Transguild Courier @John Avon +195 R Traxos, Scourge of Kroog @Lius Lasahido +196 U Arcane Sanctum @Anthony Francisco 197 U Bad River @Nils Hamm +198 R Battlefield Forge @Darrell Riche +199 C Bojuka Bog @Howard Lyon +200 U Boros Garrison @John Avon +201 R Canopy Vista @Adam Paquette 202 R Cascading Cataracts @Paul Scott Canavan +203 R Cinder Glade @Adam Paquette +204 C Command Tower @Evan Shipard +205 U Crumbling Necropolis @Volkan Baǵa 206 R Crystal Quarry @Alan Pollack +207 R Dragonskull Summit @Alayna Danner +208 C Evolving Wilds @Steven Belledin +209 R Exotic Orchard @Steven Belledin +211 R Foreboding Ruins @Adam Paquette +212 U Frontier Bivouac @Titus Lunter +213 R Geier Reach Sanitarium @Cliff Childs +214 U Grasslands @John Avon +215 U Jungle Shrine @Wayne Reynolds +216 U Krosan Verge @Ruxing Gao +217 R Mikokoro, Center of the Sea @John Avon +218 R Mobilized District @Jedd Chevrier +219 U Mountain Valley @Kari Johnson 220 R Murmuring Bosk @John Avon +221 U Mystic Monastery @Florian de Gesincourt +222 U Nomad Outpost @Kamila Szutenberg +223 U Opulent Palace @Adam Paquette +224 U Orzhov Basilica @John Avon +225 R Prairie Stream @Adam Paquette +226 U Rakdos Carnarium @John Avon +227 U Reliquary Tower @Jesper Ejsing +228 U Rocky Tar Pit @Jeff Miracola +229 U Sandsteppe Citadel @Sam Burley +230 U Savage Lands @Vance Kovacs +231 U Seaside Citadel @Volkan Baǵa +232 R Shivan Gorge @John Matson +233 R Shizo, Death's Storehouse @John Matson +234 R Smoldering Marsh @Adam Paquette +235 R Sunken Hollow @Adam Paquette +236 R Temple of Malice @Jonas De Ro +237 R Temple of Silence @Adam Paquette +238 R Temple of Triumph @Piotr Dura +239 C Terramorphic Expanse @Dan Scott +240 R Tyrite Sanctum @Volkan Baǵa [tokens] rgw_1_1_sand_warrior diff --git a/forge-gui/res/editions/Dominaria United.txt b/forge-gui/res/editions/Dominaria United.txt index 13873fc6612..4a06689afe7 100644 --- a/forge-gui/res/editions/Dominaria United.txt +++ b/forge-gui/res/editions/Dominaria United.txt @@ -9,37 +9,56 @@ ScryfallCode=DMU [cards] 1 M Karn, Living Legacy @Chris Rahn +2 R Anointed Peacekeeper @Tia Masic 3 R Archangel of Wrath @Miguel Mercado 4 C Argivian Cavalier @Chris Seaman 8 C Benalish Sleeper @Josu Hernaiz 10 C Charismatic Vanguard @David Palumbo 11 C Citizen's Arrest @Wisnu Tan +12 U Cleaving Skyrider @Joshua Raphael 14 U Coalition Skyknight @Aaron Miller -18 R Defiler of Faith @Magali Villeneuve +15 R Danitha, Benalia's Hope @Magali Villeneuve +16 R Defiler of Faith @Magali Villeneuve 19 R Guardian of New Benalia @Ernanda Souza 21 U Join Forces @Aurore Folny +22 C Juniper Order Rootweaver @Matt Stewart +23 U Knight of Dawn's Light @Billy Christian +24 R Leyline Binding @Cristi Balanescu 26 C Mesa Cavalier @David Palumbo 29 U Resolute Reinforcements @Billy Christian +30 U Runic Shot @Cristi Balanescu 31 C Samite Herbalist @Alessandra Pisano +32 M Serra Paragon @Heonhwa Choe 33 U Shalai's Acolyte @Zara Alfonso 34 C Stall for Time @Ryan Alexander Lee 35 C Take Up the Shield @Manuel Castañón 36 R Temporary Lockdown @Bryan Sola +38 R Valiant Veteran @Nestor Ossandon Leal 39 U Wingmantle Chaplain @Miranda Meeks +41 C Academy Wall @Adam Paquette +43 U Battlewing Mystic @Borja Pindado 45 U Coral Colony @Campbell White 46 R Defiler of Dreams @Ryan Pancoast +47 U Djinn of the Fountain @Bastien L. Deharme 50 U Founding the Third Path @Chris Seaman 51 U Frostfist Strider @Francisco Miyara +52 R Haughty Djinn @Mike Jordana 54 C Impede Momentum @Igor Kieryluk +56 U Joint Exploration @Zezhou Chen 57 U Micromancer @Ernanda Souza +58 C Negate @Isis 59 R The Phasing of Zhalfir @LA Draws +60 C Phyrexian Espionage @Allen Douglas 62 U Protect the Negotiators @Dominik Mayer 63 U Rona's Vortex @Dominik Mayer +65 R Silver Scrutiny @Donato Giancola 67 M Sphinx of Clear Skies @Valera Lutfullina 70 C Timely Interference @Joshua Raphael 71 C Tolarian Geyser @Olivier Bernard 72 C Tolarian Terror @Vincent Christiaens +73 M Vesuvan Duplimancy @Wylie Beckert 74 C Voda Sea Scavenger @Uriah Voth +75 R Vodalian Hexcatcher @Dmitry Burmak 76 R Vodalian Mindsinger @Steve Prescott 77 C Volshe Tideturner @Tia Masic 79 U Balduvian Atrocity @Mike Jordana @@ -47,22 +66,34 @@ ScryfallCode=DMU 84 R Braids, Arisen Nightmare @Heonhwa Choe 88 U Cult Conscript @Joe Slucher 89 U Cut Down @Dominik Mayer +90 R Defiler of Flesh @Mathias Kollros +91 R Drag to the Bottom @Nino Is 93 R Evolved Sleeper @Jason A. Engle +94 C Extinguish the Light @Ekaterina Burmak 97 M Liliana of the Veil @Martina Fackova 98 U Monstrous War-Leech @Christopher Burdett +99 C Phyrexian Rager @Brock Grossman +101 C Phyrexian Warhorse @Chris Cold 102 U Pilfer @Pauline Voss 103 R The Raven Man @Chris Rahn 104 U Sengir Connoisseur @Irina Nordsol 107 M Sheoldred, the Apocalypse @Chris Rahn +108 U Sheoldred's Restoration @Igor Kieryluk 110 R Stronghold Arena @Alexander Mokhov 111 C Tattered Apparition @Jason A. Engle 112 C Toxic Abomination @Igor Kieryluk +113 C Tribute to Urborg @Jodie Muir 114 C Urborg Repossession @Cristi Balanescu 115 C Writhing Necromass @Campbell White +116 U Balduvian Berserker @Cristi Balanescu 117 R Chaotic Transformation @Joseph Meehan +119 R Defiler of Instinct @Steven Belledin 120 U Dragon Whelp @Jokubas Uogintas +121 R The Elder Dragon War @Filip Burburan +122 U Electrostatic Infantry @Kekai Kotaki 123 U Fires of Victory @Sidharth Chaturvedi 130 U Hurler Cyclops @Xavier Ribeiro +131 U Hurloon Battle Hymn @Dominik Mayer 133 M Jaya, Fiery Negotiator @Marta Nael 134 C Jaya's Firenado @Jeremy Wilson 135 R Keldon Flamesage @Jason A. Engle @@ -72,50 +103,84 @@ ScryfallCode=DMU 141 R Radha's Firebrand @Ângelo Bortolini 142 R Rundvelt Hordemaster @Bruno Biazotto 143 M Shivan Devastator @Brent Hollowell +144 C Smash to Dust @Marc Simonetti +145 U Sprouting Goblin @Uriah Voth 146 R Squee, Dubious Monarch @Zoltan Boros 147 R Temporal Firestorm @Nestor Ossandon Leal +148 C Thrill of Possibility @David Auden Nash 149 U Twinferno @Justyna Gil 150 C Viashino Branchrider @Andrew Mar 151 U Warhost's Frenzy @Igor Grechanyi 152 C Yavimaya Steelcrusher @Gabor Szikszai +153 U Yotia Declares War @Fariba Khamseh 156 C Bog Badger @Sam Burley 158 C Colossal Growth @Eelis Kyttanen 160 R Defiler of Vigor @Chase Stone +162 U Elvish Hydromancer @Fajareka Setiawan +164 C Gaea's Might @Alex Negrea 165 R Herd Migration @Antonio José Manzanedo +167 R Leaf-Crowned Visionary @Anna Steinbauer +168 U Linebreaker Baloth @Brent Hollowell 169 R Llanowar Greenwidow @Jokubas Uogintas 170 R Llanowar Loamspeaker @Zara Alfonso 172 C Magnigoth Sentry @Dave Kendall +173 U Mossbeard Ancient @Alexandre Honoré 174 U Nishoba Brawler @Valera Lutfullina +175 R Quirion Beastcaller @Valera Lutfullina 176 C Scout the Wilderness @A. M. Sartor 178 U Slimefoot's Survey @Piotr Dura 179 C Snarespinner @Michele Giorgi 180 U Strength of the Coalition @Justine Cruz +181 C Sunbathing Rootwalla @Campbell White +182 U Tail Swipe @Ângelo Bortolini +183 U Tear Asunder @Dave Kendall 184 U Territorial Maro @Simon Dominic 185 R Threats Undetected @Randy Vargas 186 R Urborg Lhurgoyf @Andrey Kuzinskiy 187 C Vineshaper Prodigy @Inka Schulz +188 U The Weatherseed Treaty @Livia Prima 189 M The World Spell @Adam Paquette 190 U Yavimaya Iconoclast @Caio Monteiro +191 C Yavimaya Sojourner @Brian Valeza 192 M Ajani, Sleeper Agent @Matt Stewart +193 U Aron, Benalia's Ruin @Mark Winters 194 R Astor, Bearer of Blades @Josh Hass +196 U Balmor, Battlemage Captain @Bram Sels 197 U Bortuk Bonerattle @Wayne Reynolds +198 U Elas il-Kor, Sadistic Pilgrim @G-host Lee +201 R Ivy, Gleeful Spellthief @Evyn Fong 202 R Jhoira, Ageless Innovator @Justyna Gil +204 R King Darien XLVIII @Donato Giancola 205 U Lagomos, Hand of Hatred @Tuan Duong Chu +206 R Meria, Scholar of Antiquity @Aurore Folny +207 U Nael, Avizoa Aeronaut @Miguel Mercado 208 U Najal, the Storm Runner @PINDURSKI 209 R Nemata, Primeval Warden @Andrew Mar 210 U Queen Allenal of Ruadach @Ekaterina Burmak 212 U Raff, Weatherlight Stalwart @Eelis Kyttanen 213 R Ratadrabik of Urborg @Anna Pavleeva +214 M Rith, Liberated Primeval @Victor Adame Minguez +215 R Rivaz of the Claw @Joshua Raphael +216 U Rona, Sheoldred's Faithful @Ryan Alexander Lee 217 U Rulik Mons, Warren Chief @Tuan Duong Chu 218 M Shanna, Purifying Blade @Magali Villeneuve 219 M Sol'Kanar the Tainted @Filip Burburan 220 M Soul of Windgrace @Liiga Smilshkalne +221 R Stenn, Paranoid Partisan @Mila Pesic +222 U Tatyova, Steward of Tides @Howard Lyon 223 U Tori D'Avenant, Fury Rider @Anna Podedworna +224 U Tura Kennerüd, Skyknight @Donato Giancola +225 U Uurg, Spawn of Turg @Nicholas Gregory +226 U Vohar, Vodalian Desecrator @Daarken +227 U Zar Ojanen, Scion of Efrava @Justine Cruz 228 M Zur, Eternal Schemer @Jesper Ejsing +229 C Automatic Librarian @Alex Konstad 230 R Golden Argosy @Daniel Ljunggren 231 U Hero's Heirloom @Ovidio Cartagena 232 U Inscribed Tablet @Jarel Threat +233 U Jodah's Codex @Aaron Miller 234 M Karn's Sylex @Adam Paquette +238 C Shield-Wall Sentinel @Titus Lunter 239 M Timeless Lotus @Lindsey Look 241 U Walking Bulwark @Jonas De Ro 242 M Weatherlight Compleated @Adam Paquette @@ -125,6 +190,7 @@ ScryfallCode=DMU 252 R Plaza of Heroes @Gabor Szikszai 255 R Shivan Reef @Andrew Mar 256 R Sulfurous Springs @Bruce Brenneise +259 R Thran Portal @Sarah Finnigan 261 R Yavimaya Coast @Jesper Ejsing 262 L Plains @Lorenzo Lanfranconi 263 L Plains @Seb McKinnon @@ -146,29 +212,73 @@ ScryfallCode=DMU 279 L Swamp @Magali Villeneuve 280 L Mountain @Magali Villeneuve 281 L Forest @Magali Villeneuve +282 R Serra Redeemer @Joshua Raphael +283 R Cosmic Epiphany @Eli Minaya +284 R Tyrannical Pitlord @Donato Giancola +285 R Ragefire Hellkite @Xavier Ribeiro +286 R Briar Hydra @Caio Monteiro +287 R Danitha, Benalia's Hope @Barbara Rosiak 288 R Braids, Arisen Nightmare @Dibujante Nocturno 289 R The Raven Man @David Curtis 290 M Sheoldred, the Apocalypse @Joe Esposito 291 R Squee, Dubious Monarch @Daniel Lieske 292 U Aron, Benalia's Ruin @Jody Clark 293 R Astor, Bearer of Blades @Ivan Shavrin +295 U Balmor, Battlemage Captain @Nino Vecia +297 U Elas il-Kor, Sadistic Pilgrim @Joe Esposito +300 R Ivy, Gleeful Spellthief @Eshpur 301 R Jhoira, Ageless Innovator @Lisa Heidhoff +302 M Jodah, the Unifier @Barbara Rosiak +303 R King Darien XLVIII @Jody Clark 304 U Lagomos, Hand of Hatred @Joe Esposito +305 R Meria, Scholar of Antiquity @Carly Mazur +307 U Najal, the Storm Runner @Serena Malyon 308 R Nemata, Primeval Warden @Bastien Grivet +309 U Queen Allenal of Ruadach @Carly Mazur 311 U Raff, Weatherlight Stalwart @Ivan Shavrin 312 R Ratadrabik of Urborg @Nino Vecia +313 M Rith, Liberated Primeval @Roman Kuteynikov +314 R Rivaz of the Claw @Eugene Frost +315 U Rona, Sheoldred's Faithful @Nino Vecia +316 U Rulik Mons, Warren Chief @Roman Kuteynikov +317 M Shanna, Purifying Blade @Jody Clark 318 M Sol'Kanar the Tainted @Lisa Heidhoff 319 M Soul of Windgrace @Ivan Shavrin +320 R Stenn, Paranoid Partisan @Tyler Crook +321 U Tatyova, Steward of Tides @Lisa Heidhoff +322 U Tori D'Avenant, Fury Rider @Jody Clark +323 U Tura Kennerüd, Skyknight @Benjamin Ee +326 U Zar Ojanen, Scion of Efrava @Eshpur 327 M Zur, Eternal Schemer @Dan Mumford +328 R Danitha, Benalia's Hope @Barbara Rosiak +329 R Braids, Arisen Nightmare @Dibujante Nocturno 330 R The Raven Man @David Curtis 331 M Sheoldred, the Apocalypse @Joe Esposito -332 R Squee, Dubious Monarch @ +332 R Squee, Dubious Monarch @Daniel Lieske +336 U Balmor, Battlemage Captain @Nino Vecia 337 U Bortuk Bonerattle @Justin Hernandez & Alexis Hernandez +341 R Ivy, Gleeful Spellthief @Eshpur +342 R Jhoira, Ageless Innovator @Lisa Heidhoff +343 M Jodah, the Unifier @Barbara Rosiak +344 R King Darien XLVIII @Jody Clark +345 U Lagomos, Hand of Hatred @Joe Esposito +347 U Nael, Avizoa Aeronaut @Lisa Heidhoff 348 U Najal, the Storm Runner @Serena Malyon 350 U Queen Allenal of Ruadach @Carly Mazur -357 U Rulik Mons, Warren Chief +352 U Raff, Weatherlight Stalwart @Ivan Shavrin +353 R Ratadrabik of Urborg @Nino Vecia +356 U Rona, Sheoldred's Faithful @Nino Vecia +357 U Rulik Mons, Warren Chief @Roman Kuteynikov 358 M Shanna, Purifying Blade @Jody Clark +359 M Sol'Kanar the Tainted @Lisa Heidhoff +360 M Soul of Windgrace @Ivan Shavrin +361 R Stenn, Paranoid Partisan @Tyler Crook +362 U Tatyova, Steward of Tides @Lisa Heidhoff 363 U Tori D'Avenant, Fury Rider @Jody Clark +364 U Tura Kennerüd, Skyknight @Benjamin Ee +365 U Uurg, Spawn of Turg @Eugene Frost +367 U Zar Ojanen, Scion of Efrava @Eshpur +368 M Zur, Eternal Schemer @Dan Mumford 369 M Sheoldred, the Apocalypse @Chris Rahn 370 M Ajani, Sleeper Agent @Victor Adame Minguez 371 M Ajani, Sleeper Agent @Victor Adame Minguez @@ -183,24 +293,51 @@ ScryfallCode=DMU 380 R Shivan Reef @Donato Giancola 381 R Sulfurous Springs @Mark Tedin 382 R Yavimaya Coast @Mark Poole +383 R Anointed Peacekeeper @Tia Masic 384 R Archangel of Wrath @Miguel Mercado 385 R Defiler of Faith @Magali Villeneuve 386 R Guardian of New Benalia @Ernanda Souza +387 R Leyline Binding @Cristi Balanescu +388 M Serra Paragon @Heonhwa Choe 389 R Temporary Lockdown @Bryan Sola +390 R Valiant Veteran @Nestor Ossandon Leal +393 R Defiler of Dreams @Ryan Pancoast +394 R Haughty Djinn @Mike Jordana +395 R Silver Scrutiny @Donato Giancola 396 M Sphinx of Clear Skies @Valera Lutfullina +398 R Vodalian Hexcatcher @Dmitry Burmak +399 R Vodalian Mindsinger @Steve Prescott +400 R Defiler of Flesh @Mathias Kollros +401 R Drag to the Bottom @Nino Is 402 R Evolved Sleeper @Jason A. Engle 404 R Stronghold Arena @Alexander Mokhov 405 R Chaotic Transformation @Joseph Meehan 407 R Keldon Flamesage @Jason A. Engle +408 R Radha's Firebrand @Ângelo Bortolini +409 R Rundvelt Hordemaster @Bruno Biazotto 410 M Shivan Devastator @Brent Hollowell 411 R Temporal Firestorm @Nestor Ossandon Leal +412 R Defiler of Vigor @Chase Stone +413 R Herd Migration @Antonio José Manzanedo +414 R Leaf-Crowned Visionary @Anna Steinbauer 415 R Llanowar Greenwidow @Jokubas Uogintas 416 R Llanowar Loamspeaker @Zara Alfonso +417 R Quirion Beastcaller @Valera Lutfullina 419 R Threats Undetected @Randy Vargas 420 R Urborg Lhurgoyf @Andrey Kuzinskiy 421 R Plaza of Heroes @Gabor Szikszai +422 R Thran Portal @Sarah Finnigan +423 R Serra Redeemer @Joshua Raphael +424 R Cosmic Epiphany @Eli Minaya +425 R Tyrannical Pitlord @Donato Giancola +426 R Ragefire Hellkite @Xavier Ribeiro +427 R Briar Hydra @Caio Monteiro 428 R Llanowar Loamspeaker @Volkan Baǵa 429 R Herd Migration @Antonio José Manzanedo +430 U Resolute Reinforcements @Billy Christian +431 U Micromancer @Ernanda Souza +432 U Cut Down @Dominik Mayer +433 C Lightning Strike @Marta Nael 434 U Nishoba Brawler @Valera Lutfullina [tokens] From 6c0b3e97ed32964c76d25308f0820ef67af3e719 Mon Sep 17 00:00:00 2001 From: tool4ever Date: Thu, 25 Aug 2022 22:38:55 +0200 Subject: [PATCH 05/70] Some card fixes (#1401) --- forge-ai/src/main/java/forge/ai/ability/ManaEffectAi.java | 8 +++----- forge-gui/res/cardsfolder/a/alpha_brawl.txt | 4 ++-- forge-gui/res/cardsfolder/d/dauntless_bodyguard.txt | 2 +- forge-gui/res/cardsfolder/e/eye_of_the_storm.txt | 2 +- forge-gui/res/cardsfolder/f/fiend_of_the_shadows.txt | 2 +- forge-gui/res/cardsfolder/h/heap_gate.txt | 2 +- forge-gui/res/cardsfolder/h/hedonists_trove.txt | 2 +- forge-gui/res/cardsfolder/i/intellect_devourer.txt | 2 +- forge-gui/res/cardsfolder/j/jeleva_nephalias_scourge.txt | 2 +- forge-gui/res/cardsfolder/k/kheru_mind_eater.txt | 2 +- forge-gui/res/cardsfolder/l/living_inferno.txt | 2 +- forge-gui/res/cardsfolder/m/muse_vessel.txt | 2 +- forge-gui/res/cardsfolder/n/nautiloid_ship.txt | 2 +- forge-gui/res/cardsfolder/n/nightveil_specter.txt | 2 +- forge-gui/res/cardsfolder/r/ravenous_gigantotherium.txt | 2 +- forge-gui/res/cardsfolder/r/rona_disciple_of_gix.txt | 2 +- forge-gui/res/cardsfolder/s/seraph.txt | 2 +- forge-gui/res/cardsfolder/t/theater_of_horrors.txt | 2 +- ...valentin_dean_of_the_vein_lisette_dean_of_the_root.txt | 2 +- forge-gui/res/cardsfolder/v/void_maw.txt | 4 ++-- forge-gui/res/cardsfolder/w/wormfang_crab.txt | 2 +- 21 files changed, 25 insertions(+), 27 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/ManaEffectAi.java b/forge-ai/src/main/java/forge/ai/ability/ManaEffectAi.java index 69813b33293..e8a2349b30c 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ManaEffectAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ManaEffectAi.java @@ -105,13 +105,11 @@ public class ManaEffectAi extends SpellAbilityAi { } PhaseHandler ph = ai.getGame().getPhaseHandler(); - boolean moreManaNextTurn = false; - if (ph.is(PhaseType.END_OF_TURN) && (ph.getNextTurn() == ai || ComputerUtilCard.willUntap(ai, sa.getHostCard())) && canRampPool(ai, sa.getHostCard())) { - moreManaNextTurn = true; - } + boolean moreManaNextTurn = ph.is(PhaseType.END_OF_TURN) && (ph.getNextTurn() == ai || ComputerUtilCard.willUntap(ai, sa.getHostCard())) + && canRampPool(ai, sa.getHostCard()); return sa.getPayCosts().hasNoManaCost() && sa.getPayCosts().isReusuableResource() - && sa.getSubAbility() == null && (ComputerUtil.playImmediately(ai, sa) || moreManaNextTurn); + && sa.getSubAbility() == null && (moreManaNextTurn || ComputerUtil.playImmediately(ai, sa)); } /** diff --git a/forge-gui/res/cardsfolder/a/alpha_brawl.txt b/forge-gui/res/cardsfolder/a/alpha_brawl.txt index f884aebaf94..35b7b736ef1 100644 --- a/forge-gui/res/cardsfolder/a/alpha_brawl.txt +++ b/forge-gui/res/cardsfolder/a/alpha_brawl.txt @@ -2,8 +2,8 @@ Name:Alpha Brawl ManaCost:6 R R Types:Sorcery A:SP$ Pump | Cost$ 6 R R | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | RememberTargets$ True | StackDescription$ None | SubAbility$ AlphaAttack | SpellDescription$ Target creature an opponent controls deals damage equal to its power to each other creature that player controls, then each of those creatures deals damage equal to its power to that creature. -SVar:AlphaAttack:DB$ DamageAll | ValidCards$ Creature.OppCtrl+IsNotRemembered | DamageSource$ Targeted | NumDmg$ Y | SubAbility$ SucksToBeAlpha | StackDescription$ Targeted creature deals damage equal to its power to each other creature that player controls, -SVar:SucksToBeAlpha:DB$ EachDamage | ValidCards$ Creature.OppCtrl+IsNotRemembered | ValidDescription$ of those creatures | NumDmg$ X | DamageDesc$ damage equal to its power | DefinedCards$ Remembered | SubAbility$ DBCleanup | StackDescription$ then each of those creatures deals damage equal to its power to that creature +SVar:AlphaAttack:DB$ DamageAll | ValidCards$ Creature.IsNotRemembered+ControlledBy TargetedController | DamageSource$ Targeted | NumDmg$ Y | SubAbility$ SucksToBeAlpha | StackDescription$ Targeted creature deals damage equal to its power to each other creature that player controls, +SVar:SucksToBeAlpha:DB$ EachDamage | ValidCards$ Creature.IsNotRemembered+ControlledBy TargetedController | ValidDescription$ of those creatures | NumDmg$ X | DamageDesc$ damage equal to its power | DefinedCards$ Remembered | SubAbility$ DBCleanup | StackDescription$ then each of those creatures deals damage equal to its power to that creature #NumDmg isn't really used here. It is left for clarity. The AF pulls Damage straight from "X" hardcoded. SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:Count$CardPower diff --git a/forge-gui/res/cardsfolder/d/dauntless_bodyguard.txt b/forge-gui/res/cardsfolder/d/dauntless_bodyguard.txt index e438fde5527..5dd7f6d221b 100644 --- a/forge-gui/res/cardsfolder/d/dauntless_bodyguard.txt +++ b/forge-gui/res/cardsfolder/d/dauntless_bodyguard.txt @@ -4,6 +4,6 @@ Types:Creature Human Knight PT:2/1 K:ETBReplacement:Other:ChooseC SVar:ChooseC:DB$ ChooseCard | Defined$ You | Choices$ Creature.YouCtrl+Other | AILogic$ AtLeast1 | Mandatory$ True | SpellDescription$ As CARDNAME enters the battlefield, choose another creature you control. -A:AB$ Pump | Cost$ Sac<1/CARDNAME> | Defined$ ChosenCard | KW$ Indestructible | SubAbility$ DBCleanup | SpellDescription$ The chosen creature gains indestructible until end of turn. +A:AB$ Pump | Cost$ Sac<1/CARDNAME> | Defined$ Valid Card.ChosenCardStrict | KW$ Indestructible | SubAbility$ DBCleanup | SpellDescription$ The chosen creature gains indestructible until end of turn. SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True Oracle:As Dauntless Bodyguard enters the battlefield, choose another creature you control.\nSacrifice Dauntless Bodyguard: The chosen creature gains indestructible until end of turn. diff --git a/forge-gui/res/cardsfolder/e/eye_of_the_storm.txt b/forge-gui/res/cardsfolder/e/eye_of_the_storm.txt index 109a0016483..32c7794fef5 100644 --- a/forge-gui/res/cardsfolder/e/eye_of_the_storm.txt +++ b/forge-gui/res/cardsfolder/e/eye_of_the_storm.txt @@ -6,7 +6,7 @@ SVar:TrigExileSpell:DB$ ChangeZone | Defined$ TriggeredCardLKICopy | Origin$ Sta SVar:DBPlaySpell:DB$ RepeatEach | UseImprinted$ True | RepeatCards$ Card.IsRemembered | ChooseOrder$ True | Zone$ Exile | RepeatSubAbility$ DBPlay SVar:DBPlay:DB$ Play | Defined$ Imprinted | Controller$ TriggeredCardController | WithoutManaCost$ True | ValidSA$ Spell | CopyCard$ True | Optional$ True T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget -SVar:DBForget:DB$ Pump | Defined$ TriggeredCard | ForgetObjects$ TriggeredCard +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 AI:RemoveDeck:All diff --git a/forge-gui/res/cardsfolder/f/fiend_of_the_shadows.txt b/forge-gui/res/cardsfolder/f/fiend_of_the_shadows.txt index fcd2c8557e2..b15a6d5d391 100644 --- a/forge-gui/res/cardsfolder/f/fiend_of_the_shadows.txt +++ b/forge-gui/res/cardsfolder/f/fiend_of_the_shadows.txt @@ -7,7 +7,7 @@ T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage SVar:TrigExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | ChangeType$ Card | DefinedPlayer$ TriggeredTarget | Chooser$ TriggeredTarget | Mandatory$ True | ChangeNum$ 1 | RememberChanged$ True S:Mode$ Continuous | MayPlay$ True | Affected$ Card.IsRemembered | AffectedZone$ Exile T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget -SVar:DBForget:DB$ Pump | Defined$ TriggeredCard | ForgetObjects$ TriggeredCard +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 A:AB$ Regenerate | Cost$ Sac<1/Human> | SpellDescription$ Regenerate CARDNAME. diff --git a/forge-gui/res/cardsfolder/h/heap_gate.txt b/forge-gui/res/cardsfolder/h/heap_gate.txt index 4e54da25754..dccf4374986 100644 --- a/forge-gui/res/cardsfolder/h/heap_gate.txt +++ b/forge-gui/res/cardsfolder/h/heap_gate.txt @@ -3,7 +3,7 @@ ManaCost:no cost Types:Land Gate A:AB$ Mana | Cost$ T | Produced$ C | Amount$ 1 | SpellDescription$ Add {C}. A:AB$ Mana | Cost$ 1 T | Produced$ Any | SpellDescription$ Add one mana of any color. -A:AB$ Token | Cost$ 1 T tapXType<1/Gate> | TokenScript$ c_a_treasure_sac | TokenAmount$ 1 +A:AB$ Token | Cost$ 1 T tapXType<1/Gate> | TokenScript$ c_a_treasure_sac | TokenAmount$ 1 | SpellDescription$ Create a Treasure token. DeckHas:Ability$Sacrifice|Token & Type$Treasure|Artifact DeckHints:Type$Gate Oracle:{T}: Add {C}.\n{1}, {T}: Add one mana of any color.\n{1}, {T}, Tap an untapped Gate you control: Create a Treasure token. (It's an artifact with "{T}, Sacrifice this artifact: Add one mana of any color.") diff --git a/forge-gui/res/cardsfolder/h/hedonists_trove.txt b/forge-gui/res/cardsfolder/h/hedonists_trove.txt index 0dc0ed085f6..09a87e9d0bd 100644 --- a/forge-gui/res/cardsfolder/h/hedonists_trove.txt +++ b/forge-gui/res/cardsfolder/h/hedonists_trove.txt @@ -6,7 +6,7 @@ SVar:TrigExile:DB$ ChangeZoneAll | ValidTgts$ Opponent | TgtPrompt$ Select targe S:Mode$ Continuous | MayPlay$ True | Affected$ Land.IsRemembered+ExiledWithSource | AffectedZone$ Exile | Description$ You may play lands from among cards exiled with CARDNAME. S:Mode$ Continuous | MayPlay$ True | MayPlayLimit$ 1 | Affected$ Card.nonLand+IsRemembered+ExiledWithSource | AffectedZone$ Exile | Description$ You may play cards exiled with CARDNAME. T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered+ExiledWithSource | Execute$ DBForget -SVar:DBForget:DB$ Pump | Defined$ TriggeredCard | ForgetObjects$ TriggeredCard +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:When Hedonist's Trove enters the battlefield, exile all cards from target opponent's graveyard.\nYou may play lands from among cards exiled with Hedonist's Trove.\nYou may cast spells from among cards exiled with Hedonist's Trove. You can't cast more than one spell this way each turn. diff --git a/forge-gui/res/cardsfolder/i/intellect_devourer.txt b/forge-gui/res/cardsfolder/i/intellect_devourer.txt index 3917f412c96..05e70cfb4e5 100644 --- a/forge-gui/res/cardsfolder/i/intellect_devourer.txt +++ b/forge-gui/res/cardsfolder/i/intellect_devourer.txt @@ -6,7 +6,7 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S SVar:TrigExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | ChangeType$ Card | DefinedPlayer$ Opponent | Mandatory$ True | ChangeType$ Card | Hidden$ True | Duration$ UntilHostLeavesPlay | IsCurse$ True | RememberChanged$ True S:Mode$ Continuous | MayPlay$ True | MayPlayIgnoreColor$ True | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ Body Thief — You may play lands and cast spells from among cards exiled with CARDNAME. If you cast a spell this way, you may spend mana as though it were mana of any color to cast it. T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget -SVar:DBForget:DB$ Pump | Defined$ TriggeredCard | ForgetObjects$ TriggeredCard +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:Devour Intellect — When Intellect Devourer enters the battlefield, each opponent exiles a card from their hand until Intellect Devourer leaves the battlefield.\nBody Thief — You may play lands and cast spells from among cards exiled with Intellect Devourer. If you cast a spell this way, you may spend mana as though it were mana of any color to cast it. diff --git a/forge-gui/res/cardsfolder/j/jeleva_nephalias_scourge.txt b/forge-gui/res/cardsfolder/j/jeleva_nephalias_scourge.txt index 0ae54cf591b..f7e2967bb2b 100644 --- a/forge-gui/res/cardsfolder/j/jeleva_nephalias_scourge.txt +++ b/forge-gui/res/cardsfolder/j/jeleva_nephalias_scourge.txt @@ -9,7 +9,7 @@ SVar:X:Count$CastTotalManaSpent T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPlay | OptionalDecider$ You | TriggerDescription$ Whenever NICKNAME attacks, you may cast an instant or sorcery card from among cards exiled with NICKNAME without paying its mana cost. SVar:TrigPlay:DB$ Play | ValidZone$ Exile | Valid$ Instant.IsRemembered+ExiledWithSource,Sorcery.IsRemembered+ExiledWithSource | ValidSA$ Spell | Controller$ You | WithoutManaCost$ True | Amount$ 1 T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered+ExiledWithSource | Execute$ DBForget -SVar:DBForget:DB$ Pump | Defined$ TriggeredCard | ForgetObjects$ TriggeredCard +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:Flying\nWhen Jeleva, Nephalia's Scourge enters the battlefield, each player exiles the top X cards of their library, where X is the amount of mana spent to cast Jeleva.\nWhenever Jeleva attacks, you may cast an instant or sorcery spell from among cards exiled with Jeleva without paying its mana cost. diff --git a/forge-gui/res/cardsfolder/k/kheru_mind_eater.txt b/forge-gui/res/cardsfolder/k/kheru_mind_eater.txt index 4fce2a74012..94e35c424f3 100644 --- a/forge-gui/res/cardsfolder/k/kheru_mind_eater.txt +++ b/forge-gui/res/cardsfolder/k/kheru_mind_eater.txt @@ -7,7 +7,7 @@ T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage SVar:TrigExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | ChangeType$ Card | DefinedPlayer$ TriggeredTarget | Chooser$ TriggeredTarget | ExileFaceDown$ True | Mandatory$ True | ChangeNum$ 1 | RememberChanged$ True S:Mode$ Continuous | MayPlay$ True | MayLookAt$ You | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may look at cards exiled with CARDNAME, and you may play lands and cast spells from among those cards. T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget -SVar:DBForget:DB$ Pump | Defined$ TriggeredCard | ForgetObjects$ TriggeredCard +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:Menace\nWhenever Kheru Mind-Eater deals combat damage to a player, that player exiles a card from their hand face down.\nYou may look at cards exiled with Kheru Mind-Eater, and you may play lands and cast spells from among those cards. diff --git a/forge-gui/res/cardsfolder/l/living_inferno.txt b/forge-gui/res/cardsfolder/l/living_inferno.txt index 0ea5dbf610f..4685a02324b 100644 --- a/forge-gui/res/cardsfolder/l/living_inferno.txt +++ b/forge-gui/res/cardsfolder/l/living_inferno.txt @@ -3,7 +3,7 @@ ManaCost:6 R R Types:Creature Elemental PT:8/5 A:AB$ DealDamage | Cost$ T | ValidTgts$ Creature | TgtPrompt$ Select target creature to distribute damage to | NumDmg$ FirePower | TargetMin$ Min | TargetMax$ FirePower | DividedAsYouChoose$ FirePower | SubAbility$ Retribution | RememberTargets$ True | SpellDescription$ CARDNAME deals damage equal to its power divided as you choose among any number of target creatures. Each of those creatures deals damage equal to its power to CARDNAME. -SVar:Retribution:DB$ EachDamage | ValidCards$ Creature.IsRemembered | ValidDescription$ of those creatures | NumDmg$ X | DamageDesc$ damage equal to its power | DefinedCards$ Remembered | SubAbility$ DBCleanup | StackDescription$ then each of those creatures deals damage equal to its power to CARDNAME +SVar:Retribution:DB$ EachDamage | ValidCards$ Creature.IsRemembered | ValidDescription$ of those creatures | NumDmg$ X | DamageDesc$ damage equal to its power | DefinedPlayers$ Self | SubAbility$ DBCleanup | StackDescription$ then each of those creatures deals damage equal to its power to CARDNAME #NumDmg isn't really used here. It is left for clarity. The AF pulls Damage straight from "X" hardcoded. SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:Count$CardPower diff --git a/forge-gui/res/cardsfolder/m/muse_vessel.txt b/forge-gui/res/cardsfolder/m/muse_vessel.txt index b418acf1eb3..33c5fccd51e 100644 --- a/forge-gui/res/cardsfolder/m/muse_vessel.txt +++ b/forge-gui/res/cardsfolder/m/muse_vessel.txt @@ -8,7 +8,7 @@ SVar:STPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ C SVar:TrigCleanup:Mode$ ChangesZone | ValidCard$ Card.ChosenCard | Origin$ Exile | Destination$ Any | TriggerZones$ Command | Execute$ DBExileSelf | Static$ True SVar:DBExileSelf:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered+ExiledWithSource | Execute$ DBForget -SVar:DBForget:DB$ Pump | Defined$ TriggeredCard | ForgetObjects$ TriggeredCard +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:{3}, {T}: Target player exiles a card from their hand. Activate only as a sorcery.\n{1}: Choose a card exiled with Muse Vessel. You may play that card this turn. diff --git a/forge-gui/res/cardsfolder/n/nautiloid_ship.txt b/forge-gui/res/cardsfolder/n/nautiloid_ship.txt index 051bd37bc56..71cf351c5ac 100644 --- a/forge-gui/res/cardsfolder/n/nautiloid_ship.txt +++ b/forge-gui/res/cardsfolder/n/nautiloid_ship.txt @@ -8,7 +8,7 @@ SVar:TrigExileGrave:DB$ ChangeZoneAll | Origin$ Graveyard | Destination$ Exile | T:Mode$ DamageDone | ValidSource$ Card.Self | Execute$ TrigPut | CombatDamage$ True | ValidTarget$ Player | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may put a creature card exiled with CARDNAME onto the battlefield under your control. SVar:TrigPut:DB$ ChangeZone | Origin$ Exile | Destination$ Battlefield | Hidden$ True | ChooseType$ Creature.IsRemembered | SelectPrompt$ Select a creature card exiled with this | GainControl$ True T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget -SVar:DBForget:DB$ Pump | Defined$ TriggeredCard | ForgetObjects$ TriggeredCard +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 K:Crew:3 diff --git a/forge-gui/res/cardsfolder/n/nightveil_specter.txt b/forge-gui/res/cardsfolder/n/nightveil_specter.txt index 79165723916..1b3ae2f5522 100644 --- a/forge-gui/res/cardsfolder/n/nightveil_specter.txt +++ b/forge-gui/res/cardsfolder/n/nightveil_specter.txt @@ -7,7 +7,7 @@ T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage SVar:TrigExile:DB$ Dig | Defined$ TriggeredTarget | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True S:Mode$ Continuous | MayPlay$ True | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play lands and cast spells from among cards exiled with CARDNAME. T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget -SVar:DBForget:DB$ Pump | Defined$ TriggeredCard | ForgetObjects$ TriggeredCard +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:Flying\nWhenever Nightveil Specter deals combat damage to a player, that player exiles the top card of their library.\nYou may play lands and cast spells from among cards exiled with Nightveil Specter. diff --git a/forge-gui/res/cardsfolder/r/ravenous_gigantotherium.txt b/forge-gui/res/cardsfolder/r/ravenous_gigantotherium.txt index a9d7ce0068e..74d7af9c125 100644 --- a/forge-gui/res/cardsfolder/r/ravenous_gigantotherium.txt +++ b/forge-gui/res/cardsfolder/r/ravenous_gigantotherium.txt @@ -4,7 +4,7 @@ Types:Creature Beast PT:3/3 K:Devour:3 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDmg | TriggerDescription$ When CARDNAME enters the battlefield, it deals X damage divided as you choose among up to X target creatures, where X is its power. Each of those creatures deals damage equal to its power to CARDNAME. -SVar:TrigDmg:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature to distribute damage to | NumDmg$ FirePower | TargetMin$ 0 | TargetMax$ FirePower | DividedAsYouChoose$ FirePower | SubAbility$ DBDmg | RememberTargets$ True | StackDescription$ None +SVar:TrigDmg:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature to distribute damage to | NumDmg$ FirePower | TargetMin$ 0 | TargetMax$ FirePower | DividedAsYouChoose$ FirePower | SubAbility$ DBDmg | StackDescription$ None SVar:DBDmg:DB$ RepeatEach | RepeatSubAbility$ GigantotheriumFight | UseImprinted$ True | DefinedCards$ Targeted | StackDescription$ None | DamageMap$ True SVar:GigantotheriumFight:DB$ DealDamage | DamageSource$ Imprinted | NumDmg$ Y | Defined$ Self | StackDescription$ None SVar:FirePower:Count$CardPower diff --git a/forge-gui/res/cardsfolder/r/rona_disciple_of_gix.txt b/forge-gui/res/cardsfolder/r/rona_disciple_of_gix.txt index a4a1b51313c..6e926d02277 100644 --- a/forge-gui/res/cardsfolder/r/rona_disciple_of_gix.txt +++ b/forge-gui/res/cardsfolder/r/rona_disciple_of_gix.txt @@ -6,7 +6,7 @@ T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefi SVar:HistoricExile:DB$ ChangeZone | ValidTgts$ Card.Historic+YouOwn | TgtPrompt$ Select target historic card from your graveyard | Origin$ Graveyard | Destination$ Exile | RememberChanged$ True S:Mode$ Continuous | MayPlay$ True | Affected$ Card.nonLand+IsRemembered+ExiledWithSource | AffectedZone$ Exile | Description$ You may play cards exiled with CARDNAME. T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered+ExiledWithSource | Execute$ DBForget -SVar:DBForget:DB$ Pump | Defined$ TriggeredCard | ForgetObjects$ TriggeredCard +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 A:AB$ Dig | Cost$ 4 T | Defined$ You | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SpellDescription$ Exile the top card of your library. diff --git a/forge-gui/res/cardsfolder/s/seraph.txt b/forge-gui/res/cardsfolder/s/seraph.txt index 3d53dded332..23fbe1996fb 100644 --- a/forge-gui/res/cardsfolder/s/seraph.txt +++ b/forge-gui/res/cardsfolder/s/seraph.txt @@ -8,7 +8,7 @@ SVar:DelTrigReturn:DB$ DelayedTrigger | Mode$ Phase | Phase$ End Of Turn | Execu SVar:DBReturn:DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Graveyard | Destination$ Battlefield | GainControl$ True | RememberChanged$ True #TODO make the sacrifice part as another delayed Trigger T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget -SVar:DBForget:DB$ Pump | Defined$ Card.Self | ForgetObjects$ TriggeredCard +SVar:DBForget:DB$ Pump | ForgetObjects$ TriggeredCard T:Mode$ ChangesController | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ Sacrifice | TriggerDescription$ Sacrifice the creature when you lose control of CARDNAME. SVar:Sacrifice:DB$ SacrificeAll | ValidCards$ Card.IsRemembered | Controller$ You | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True diff --git a/forge-gui/res/cardsfolder/t/theater_of_horrors.txt b/forge-gui/res/cardsfolder/t/theater_of_horrors.txt index cdebe368331..c01ca4b72c6 100644 --- a/forge-gui/res/cardsfolder/t/theater_of_horrors.txt +++ b/forge-gui/res/cardsfolder/t/theater_of_horrors.txt @@ -6,7 +6,7 @@ SVar:TrigExile:DB$ Dig | Defined$ You | DestinationZone$ Exile | DigNum$ 1 | Cha S:Mode$ Continuous | Affected$ Card.IsRemembered | AffectedZone$ Exile | MayPlay$ True | Condition$ PlayerTurn | CheckSVar$ X | Description$ During your turn, if an opponent lost life this turn, you may play lands and cast spells from among cards exiled with CARDNAME. SVar:X:Count$LifeOppsLostThisTurn T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget -SVar:DBForget:DB$ Pump | Defined$ TriggeredCard | ForgetObjects$ TriggeredCard +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 A:AB$ DealDamage | Cost$ 3 R | ValidTgts$ Opponent,Planeswalker | TgtPrompt$ Select target opponent or planeswalker | NumDmg$ 1 | SpellDescription$ CARDNAME deals 1 damage to target opponent or planeswalker. diff --git a/forge-gui/res/cardsfolder/v/valentin_dean_of_the_vein_lisette_dean_of_the_root.txt b/forge-gui/res/cardsfolder/v/valentin_dean_of_the_vein_lisette_dean_of_the_root.txt index a5c0d01106f..ae689c01407 100644 --- a/forge-gui/res/cardsfolder/v/valentin_dean_of_the_vein_lisette_dean_of_the_root.txt +++ b/forge-gui/res/cardsfolder/v/valentin_dean_of_the_vein_lisette_dean_of_the_root.txt @@ -4,7 +4,7 @@ Types:Legendary Creature Vampire Warlock PT:1/1 K:Menace K:Lifelink -R:Event$ Moved | ActiveZones$ Battlefield | Origin$ Battlefield | Destination$ Graveyard | ValidLKI$ Card.Creature+nonToken+OppOwn | ReplaceWith$ Exile | Description$ If a nontoken creature an opponent controls would die, exile it instead. When you do, you may pay {2}. If you do, create a 1/1 black and green Pest creature token with "When this creature dies, you gain 1 life." +R:Event$ Moved | ActiveZones$ Battlefield | Origin$ Battlefield | Destination$ Graveyard | ValidLKI$ Card.Creature+nonToken+OppCtrl | CheckSelfLKIZone$ True | ReplaceWith$ Exile | Description$ If a nontoken creature an opponent controls would die, exile it instead. When you do, you may pay {2}. If you do, create a 1/1 black and green Pest creature token with "When this creature dies, you gain 1 life." SVar:Exile:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Exile | Defined$ ReplacedCard | SubAbility$ DBImmediateTrigger SVar:DBImmediateTrigger:DB$ ImmediateTrigger | Execute$ TrigToken | TriggerDescription$ If a nontoken creature an opponent controls would die, exile it instead. When you do, you may pay {2}. If you do, create a 1/1 black and green Pest creature token with "When this creature dies, you gain 1 life." SVar:TrigToken:AB$ Token | Cost$ 2 | TokenAmount$ 1 | TokenScript$ bg_1_1_pest_lifegain | TokenOwner$ You diff --git a/forge-gui/res/cardsfolder/v/void_maw.txt b/forge-gui/res/cardsfolder/v/void_maw.txt index aa24541cdc2..ffb810857bb 100644 --- a/forge-gui/res/cardsfolder/v/void_maw.txt +++ b/forge-gui/res/cardsfolder/v/void_maw.txt @@ -3,11 +3,11 @@ ManaCost:4 B B Types:Creature Horror PT:4/5 K:Trample -R:Event$ Moved | ActiveZones$ Battlefield | Origin$ Battlefield | Destination$ Graveyard | ValidLKI$ Creature.Other | ReplaceWith$ Exile | Description$ If another creature would die, exile it instead. +R:Event$ Moved | ActiveZones$ Battlefield | Origin$ Battlefield | Destination$ Graveyard | ValidLKI$ Creature.Other | CheckSelfLKIZone$ True | ReplaceWith$ Exile | Description$ If another creature would die, exile it instead. SVar:Exile:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Exile | Defined$ ReplacedCard | SubAbility$ DBRemember | RememberChanged$ True SVar:DBRemember:DB$ Pump | ConditionDefined$ Remembered | ConditionPresent$ Card.inZoneExile | ConditionCompare$ GE1 T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered+ExiledWithSource | Execute$ DBForget -SVar:DBForget:DB$ Pump | Defined$ TriggeredCard | ForgetObjects$ TriggeredCard +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 A:AB$ Pump | Cost$ ExiledMoveToGrave<1/Card.IsRemembered+ExiledWithSource/card exiled with CARDNAME> | Defined$ Self | NumAtt$ +2 | NumDef$ +2 | SpellDescription$ CARDNAME gets +2/+2 until end of turn. diff --git a/forge-gui/res/cardsfolder/w/wormfang_crab.txt b/forge-gui/res/cardsfolder/w/wormfang_crab.txt index 29bca66a065..3cb1b917a1d 100644 --- a/forge-gui/res/cardsfolder/w/wormfang_crab.txt +++ b/forge-gui/res/cardsfolder/w/wormfang_crab.txt @@ -8,7 +8,7 @@ SVar:ChooseP:DB$ ChoosePlayer | Defined$ You | Choices$ Player.Opponent | AILogi SVar:TrigChoice:DB$ ChooseCard | Defined$ ChosenPlayer | Amount$ 1 | Choices$ Permanent.YouCtrl+Other | RememberChosen$ True | Mandatory$ True | SubAbility$ ExileChoice SVar:ExileChoice:DB$ ChangeZone | IsCurse$ True | Defined$ Remembered | Origin$ Battlefield | Destination$ Exile T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered+ExiledWithSource | Execute$ DBForget -SVar:DBForget:DB$ Pump | Defined$ TriggeredCard | ForgetObjects$ TriggeredCard +SVar:DBForget:DB$ Pump | ForgetObjects$ TriggeredCard T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME leaves the battlefield, return the exiled card to the battlefield under its owner's control. SVar:TrigReturn:DB$ ChangeZone | Defined$ Remembered.ExiledWithSource | Origin$ Exile | Destination$ Battlefield | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True From 0dac718115577ab58477b83b026fbfa2bc512a79 Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Fri, 26 Aug 2022 05:42:38 +0200 Subject: [PATCH 06/70] DMC 6 Cards (#1389) * Update * Update * update * Update gerrards_hourglass_endant.txt * Update stangg_echo_warrior.txt * Update gerrards_hourglass_endant.txt * Update stangg_echo_warrior.txt * Update stangg_echo_warrior.txt * Update tobias_conqueror_of_bad_luck.txt * Update torsten_founder_of_benalia.txt * Update orca_siege_demon.txt * Delete stangg_echo_warrior.txt * Update gerrards_hourglass_endant.txt --- .../upcoming/gerrards_hourglass_endant.txt | 7 +++++++ .../res/cardsfolder/upcoming/orca_siege_demon.txt | 12 ++++++++++++ .../upcoming/tetsuo_imperial_champion.txt | 12 ++++++++++++ .../res/cardsfolder/upcoming/the_lady_of_otaria.txt | 10 ++++++++++ .../upcoming/tobias_conqueror_of_bad_luck.txt | 10 ++++++++++ .../upcoming/torsten_founder_of_benalia.txt | 10 ++++++++++ 6 files changed, 61 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/gerrards_hourglass_endant.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/orca_siege_demon.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/tetsuo_imperial_champion.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/the_lady_of_otaria.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/tobias_conqueror_of_bad_luck.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/torsten_founder_of_benalia.txt diff --git a/forge-gui/res/cardsfolder/upcoming/gerrards_hourglass_endant.txt b/forge-gui/res/cardsfolder/upcoming/gerrards_hourglass_endant.txt new file mode 100644 index 00000000000..c22ea2fcaab --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/gerrards_hourglass_endant.txt @@ -0,0 +1,7 @@ +Name:Gerrard's Hourglass Pendant +ManaCost:1 +Types:Legendary Artifact +K:Flash +R:Event$ BeginTurn | ActiveZones$ Battlefield | ExtraTurn$ True | Skip$ True | Description$ If a player would begin an extra turn, that player skips that turn instead. +A:AB$ ChangeZone | Cost$ 4 T Exile<1/CARDNAME> | Origin$ Graveyard | Destination$ Battlefield | Defined$ ValidGraveyard Artifact.YouOwn+ThisTurnEnteredFrom_Battlefield,Creature.YouOwn+ThisTurnEnteredFrom_Battlefield,Land.YouOwn+ThisTurnEnteredFrom_Battlefield,Enchantment.YouOwn+ThisTurnEnteredFrom_Battlefield | Tapped$ True | SpellDescription$ Return to the battlefield tapped all artifact, creature, enchantment, and land cards in your graveyard that were put there from the battlefield this turn. +Oracle:Flash\nIf a player would begin an extra turn, that player skips that turn instead.\n{4}, {T}, Exile Gerrard's Hourglass Pendant: Return to the battlefield tapped all artifact, creature, enchantment, and land cards in your graveyard that were put there from the battlefield this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/orca_siege_demon.txt b/forge-gui/res/cardsfolder/upcoming/orca_siege_demon.txt new file mode 100644 index 00000000000..6bfd73fb062 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/orca_siege_demon.txt @@ -0,0 +1,12 @@ +Name:Orca, Siege Demon +ManaCost:5 B R +Types:Legendary Creature Human Soldier +K:Trample +PT:5/5 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.Other | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever another creature dies, put a +1/+1 counter on CARDNAME. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDamage | TriggerDescription$ When NICKNAME dies, it deals damage equal to its power divided as you choose among any number of targets. +SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any number of targets to distribute damage to | NumDmg$ X | TargetMin$ 1 | TargetMax$ X | DividedAsYouChoose$ X +SVar:X:TriggeredCard$CardPower +DeckHas:Ability$Counters +Oracle:Whenever another creature dies, put a +1/+1 counter on Orca, Siege Demon.\nWhen Orca dies, it deals damage equal to its power divided as you choose among any number of targets. diff --git a/forge-gui/res/cardsfolder/upcoming/tetsuo_imperial_champion.txt b/forge-gui/res/cardsfolder/upcoming/tetsuo_imperial_champion.txt new file mode 100644 index 00000000000..5a4915857a7 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/tetsuo_imperial_champion.txt @@ -0,0 +1,12 @@ +Name:Tetsuo, Imperial Champion +ManaCost:U B R +Types:Legendary Creature Human Samurai +PT:3/3 +T:Mode$ Attacks | ValidCard$ Card.Self+equipped | Execute$ TrigChoose | TriggerDescription$ Whenever CARDNAME attacks,if it's equipped, ABILITY +SVar:TrigChoose:DB$ Charm | Choices$ DBDealDamage,DBCast | CharmNum$ 1 +SVar:DBDealDamage:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | NumDmg$ X | SpellDescription$ NICKNAME deals damage equal to the highest mana value among Equipment attached to it to any target. +SVar:DBCast:DB$ Play | TgtZone$ Hand | ValidTgts$ Instant.YouCtrl+cmcLEX,Sorcery.YouCtrl+cmcLEX | ValidSA$ Spell | Optional$ True | WithoutManaCost$ True | AILogic$ ReplaySpell | SpellDescription$ You may cast an instant or sorcery spell from your hand with mana value less than or equal to the highest mana value among Equipment attached to NICKNAME without paying its mana cost. +SVar:X:Count$HighestCMC_Equipment.Attached +SVar:EquipMe +DeckHints:Type$Equipment +Oracle:Whenever Tetsuo, Imperial Champion attacks, if it's equipped, choose one —\n• Tetsuo deals damage equal to the highest mana value among Equipment attached to it to any target.\n• You may cast an instant or sorcery spell from your hand with mana value less than or equal to the highest mana value among Equipment attached to Tetsuo without paying its mana cost. diff --git a/forge-gui/res/cardsfolder/upcoming/the_lady_of_otaria.txt b/forge-gui/res/cardsfolder/upcoming/the_lady_of_otaria.txt new file mode 100644 index 00000000000..597fe3e6a35 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/the_lady_of_otaria.txt @@ -0,0 +1,10 @@ +Name:The Lady of Otaria +ManaCost:3 R G +Types:Legendary Creature Avatar +PT:5/5 +SVar:AltCost:Cost$ tapXType<3/Creature.Dwarf> | Description$ You may tap three untapped Dwarves you control rather than pay this spell's mana cost. +T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | Execute$ TrigDig | CheckSVar$ X | SVarCompare$ GE1 | TriggerDescription$ At the beginning of each end step, if a land you controlled was put into your graveyard from the battlefield this turn, reveal the top four cards of your library. Put any number of Dwarf cards from among them into your hand and the rest on the bottom of your library in a random order. +SVar:TrigDig:DB$ Dig | DigNum$ 4 | ChangeValid$ Dwarf | DestinationZone$ Hand | RestRandomOrder$ True | AnyNumber$ True +SVar:X:Count$ValidGraveyard Land.YouCtrl+ThisTurnEnteredFrom_Battlefield +DeckNeeds:Type$Dwarf +Oracle:You may tap three untapped Dwarves you control rather than pay this spell's mana cost.\nAt the beginning of each end step, if a land you controlled was put into your graveyard from the battlefield this turn, reveal the top four cards of your library. Put any number of Dwarf cards from among them into your hand and the rest on the bottom of your library in a random order. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/tobias_conqueror_of_bad_luck.txt b/forge-gui/res/cardsfolder/upcoming/tobias_conqueror_of_bad_luck.txt new file mode 100644 index 00000000000..523144f2e65 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/tobias_conqueror_of_bad_luck.txt @@ -0,0 +1,10 @@ +Name:Tobias, Doomed Conqueror +ManaCost:2 W U +Types:Legendary Creature Human Soldier +K:Flash +PT:3/2 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME dies, create a 2/2 black Zombie creature token for each nontoken creature you controlled that died this turn. +SVar:TrigToken:DB$ Token | TokenAmount$ X | TokenScript$ b_2_2_zombie | TokenOwner$ You +SVar:X:Count$ThisTurnEntered_Graveyard_from_Battlefield_Creature.nonToken+YouCtrl +DeckHas:Ability$Token +Oracle:Flash\nWhen Tobias, Doomed Conqueror dies, create a 2/2 black Zombie creature token for each nontoken creature you controlled that died this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/torsten_founder_of_benalia.txt b/forge-gui/res/cardsfolder/upcoming/torsten_founder_of_benalia.txt new file mode 100644 index 00000000000..8b2d234d200 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/torsten_founder_of_benalia.txt @@ -0,0 +1,10 @@ +Name:Torsten, Founder of Benalia +ManaCost:5 G W +Types:Legendary Creature Human Soldier +PT:7/7 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDig | TriggerDescription$ When CARDNAME enters the battlefield, reveal the top seven cards of your library. Put any number of creature and/or land cards from among them into your hand and the rest on the bottom of your library in a random order. +SVar:TrigDig:DB$ Dig | DigNum$ 7 | ChangeValid$ Creature,Land | DestinationZone$ Hand | RestRandomOrder$ True | AnyNumber$ True +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When NICKNAME dies, create seven 1/1 white Soldier creature tokens. +SVar:TrigToken:DB$ Token | TokenAmount$ 7 | TokenScript$ w_1_1_soldier | TokenOwner$ You +DeckHas:Ability$Token +Oracle:When Torsten, Founder of Benalia enters the battlefield, reveal the top seven cards of your library. Put any number of creature and/or land cards from among them into your hand and the rest on the bottom of your library in a random order.\nWhen Torsten dies, create seven 1/1 white Soldier creature tokens. From 895cffffde704b7877b19d97aabe89b8fa177329 Mon Sep 17 00:00:00 2001 From: Suthro <81990938+Suthro@users.noreply.github.com> Date: Fri, 26 Aug 2022 03:12:22 -0500 Subject: [PATCH 07/70] DMC: Bladewing, Deathless Tyrant + 6 cards (#1394) --- .../upcoming/bladewing_deathless_tyrant.txt | 12 ++++++++++++ .../cardsfolder/upcoming/cadric_soul_kindler.txt | 11 +++++++++++ .../cardsfolder/upcoming/iridian_maelstrom.txt | 5 +++++ .../upcoming/jenson_carthalion_druid_exile.txt | 10 ++++++++++ .../res/cardsfolder/upcoming/primeval_spawn.txt | 15 +++++++++++++++ .../upcoming/shanid_sleepers_scourge.txt | 13 +++++++++++++ .../cardsfolder/upcoming/the_peregrine_dynamo.txt | 9 +++++++++ 7 files changed, 75 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/bladewing_deathless_tyrant.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/cadric_soul_kindler.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/iridian_maelstrom.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/jenson_carthalion_druid_exile.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/primeval_spawn.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/shanid_sleepers_scourge.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/the_peregrine_dynamo.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bladewing_deathless_tyrant.txt b/forge-gui/res/cardsfolder/upcoming/bladewing_deathless_tyrant.txt new file mode 100644 index 00000000000..697478d0848 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/bladewing_deathless_tyrant.txt @@ -0,0 +1,12 @@ +Name:Bladewing, Deathless Tyrant +ManaCost:5 B R +Types:Legendary Creature Dragon Skeleton +PT:6/6 +K:Flying +K:Haste +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player,Planeswalker | CombatDamage$ True | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player or planeswalker, for each creature card in your graveyard, create a 2/2 black Zombie Knight creature token with menace. +SVar:TrigToken:DB$ Token | TokenScript$ b_2_2_zombie_knight_menace | TokenAmount$ X | TokenOwner$ You +SVar:X:Count$TypeInYourYard.Creature +DeckHas:Ability$Token & Type$Zombie|Knight +DeckHints:Ability$Graveyard +Oracle:Flying, haste\nWhenever Bladewing, Deathless Tyrant deals combat damage to a player or planeswalker, for each creature card in your graveyard, create a 2/2 black Zombie Knight creature token with menace. diff --git a/forge-gui/res/cardsfolder/upcoming/cadric_soul_kindler.txt b/forge-gui/res/cardsfolder/upcoming/cadric_soul_kindler.txt new file mode 100644 index 00000000000..d779a59aec3 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/cadric_soul_kindler.txt @@ -0,0 +1,11 @@ +Name:Cadric, Soul Kindler +ManaCost:2 R W +Types:Legendary Creature Dwarf Wizard +PT:4/3 +S:Mode$ IgnoreLegendRule | ValidCard$ Permanent.token+YouCtrl | Description$ The "legend rule" doesn't apply to tokens you control. +T:Mode$ ChangesZone | ValidCard$ Permanent.nonToken+Legendary+Other+YouCtrl | Origin$ Any | Destination$ Battlefield | TriggerZones$ Battlefield | Execute$ TrigCopy | TriggerDescription$ Whenever another nontoken legendary permanent enters the battlefield under your control, you may pay {1}. If you do, create a token that's a copy of it. That token gains haste. Sacrifice it at the beginning of the next end step. +SVar:TrigCopy:AB$ CopyPermanent | Cost$ 1 | Defined$ TriggeredCard | PumpKeywords$ Haste | AtEOT$ Sacrifice +SVar:BuffedBy:Legendary +DeckHas:Ability$Token +DeckNeeds:Type$Legendary +Oracle:The "legend rule" doesn't apply to tokens you control.\nWhenever another nontoken legendary permanent enters the battlefield under your control, you may pay {1}. If you do, create a token that's a copy of it. That token gains haste. Sacrifice it at the beginning of the next end step. diff --git a/forge-gui/res/cardsfolder/upcoming/iridian_maelstrom.txt b/forge-gui/res/cardsfolder/upcoming/iridian_maelstrom.txt new file mode 100644 index 00000000000..a3b8e41c226 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/iridian_maelstrom.txt @@ -0,0 +1,5 @@ +Name:Iridian Maelstrom +ManaCost:W U B R G +Types:Sorcery +A:SP$ DestroyAll | ValidCards$ Creature.!AllColors | SpellDescription$ Destroy each creature that isn't all colors. +Oracle:Destroy each creature that isn't all colors. diff --git a/forge-gui/res/cardsfolder/upcoming/jenson_carthalion_druid_exile.txt b/forge-gui/res/cardsfolder/upcoming/jenson_carthalion_druid_exile.txt new file mode 100644 index 00000000000..912b766910a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/jenson_carthalion_druid_exile.txt @@ -0,0 +1,10 @@ +Name:Jenson Carthalion, Druid Exile +ManaCost:G W +Types:Legendary Creature Human Druid +PT:2/2 +T:Mode$ SpellCast | ValidCard$ Card.MultiColor | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigScry | TriggerDescription$ Whenever you cast a multicolored spell, scry 1. If that spell was all colors, create a 4/4 white Angel creature token with flying and vigilance. +SVar:TrigScry:DB$ Scry | ScryNum$ 1 | SubAbility$ DBToken +SVar:DBToken:DB$ Token | TokenScript$ w_4_4_angel_flying_vigilance | TokenAmount$ 1 | ConditionDefined$ TriggeredCard | ConditionPresent$ Card.AllColors +A:AB$ Mana | Cost$ 5 T | Produced$ W U B R G | SpellDescription$ Add {W}{U}{B}{R}{G}. +DeckHas:Ability$Token & Type$Angel +Oracle:Whenever you cast a multicolored spell, scry 1. If that spell was all colors, create a 4/4 white Angel creature token with flying and vigilance.\n{5}, {T}: Add {W}{U}{B}{R}{G}. diff --git a/forge-gui/res/cardsfolder/upcoming/primeval_spawn.txt b/forge-gui/res/cardsfolder/upcoming/primeval_spawn.txt new file mode 100644 index 00000000000..ab6d80d5ccc --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/primeval_spawn.txt @@ -0,0 +1,15 @@ +Name:Primeval Spawn +ManaCost:5 W U B R G +Types:Creature Avatar +PT:10/10 +K:Vigilance +K:Trample +K:Lifelink +R:Event$ Moved | ActiveZones$ Battlefield | Destination$ Battlefield | ValidCard$ Card.Self+wasNotCast | ReplaceWith$ Exile | Description$ If CARDNAME would enter the battlefield and it wasn't cast or no mana was spent to cast it, exile it instead. +R:Event$ Moved | ActiveZones$ Battlefield | Destination$ Battlefield | ValidCard$ Card.Self | CheckSVar$ X | SVarCompare$ EQ0 | ReplaceWith$ Exile | Description$ If CARDNAME would enter the battlefield and it wasn't cast or no mana was spent to cast it, exile it instead. +SVar:Exile:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Exile | Defined$ ReplacedCard +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME leaves the battlefield, exile the top ten cards of your library. You may cast any number of spells with total mana value 10 or less from among them without paying their mana costs. +SVar:TrigExile:DB$ Dig | Defined$ You | DigNum$ 10 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBPlay +SVar:DBPlay:DB$ Play | Valid$ Card.nonLand+IsRemembered+YouOwn+cmcLE10 | WithTotalCMC$ 10 | ValidZone$ Exile | ValidSA$ Spell | Controller$ You | WithoutManaCost$ True | Optional$ True | Amount$ All +SVar:X:Count$CastTotalManaSpent +Oracle:If Primeval Spawn would enter the battlefield and it wasn't cast or no mana was spent to cast it, exile it instead.\nVigilance, trample, lifelink\nWhen Primeval Spawn leaves the battlefield, exile the top ten cards of your library. You may cast any number of spells with total mana value 10 or less from among them without paying their mana costs. diff --git a/forge-gui/res/cardsfolder/upcoming/shanid_sleepers_scourge.txt b/forge-gui/res/cardsfolder/upcoming/shanid_sleepers_scourge.txt new file mode 100644 index 00000000000..424264be656 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/shanid_sleepers_scourge.txt @@ -0,0 +1,13 @@ +Name:Shanid, Sleepers' Scourge +ManaCost:1 R W B +Types:Legendary Creature Human Knight +PT:2/4 +K:Menace +S:Mode$ Continuous | Affected$ Creature.Legendary+Other+YouCtrl | AddKeyword$ Menace | Description$ Other legendary creatures you control have menace. +T:Mode$ LandPlayed | ValidCard$ Land.Legendary+YouCtrl | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you play a legendary land or cast a legendary spell, you draw a card and you lose 1 life. +T:Mode$ SpellCast | ValidCard$ Card.Legendary+YouCtrl | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | Secondary$ True | TriggerDescription$ Whenever you play a legendary land or cast a legendary spell, you draw a card and you lose 1 life. +SVar:TrigDraw:DB$ Draw | Defined$ You | SubAbility$ DBLoseLife +SVar:DBLoseLife:DB$ LoseLife | Defined$ You | LifeAmount$ 1 +SVar:BuffedBy:Legendary +DeckNeeds:Type$Legendary +Oracle:Menace\nOther legendary creatures you control have menace.\nWhenever you play a legendary land or cast a legendary spell, you draw a card and you lose 1 life. diff --git a/forge-gui/res/cardsfolder/upcoming/the_peregrine_dynamo.txt b/forge-gui/res/cardsfolder/upcoming/the_peregrine_dynamo.txt new file mode 100644 index 00000000000..02c028d48cf --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/the_peregrine_dynamo.txt @@ -0,0 +1,9 @@ +Name:The Peregrine Dynamo +ManaCost:3 +Types:Legendary Artifact Creature Construct +PT:1/5 +K:Haste +A:AB$ CopySpellAbility | Cost$ 1 T | TargetType$ Activated.YouCtrl,Triggered.YouCtrl | ValidTgts$ Card.Legendary+Other+IsNotCommander+YouCtrl | TgtPrompt$ Choose target triggered ability you control | MayChooseTarget$ True | SpellDescription$ Copy target activated or triggered ability you control from another legendary source that's not a commander. You may choose new targets for the copy. +SVar:BuffedBy:Legendary +DeckNeeds:Type$Legendary +Oracle:Haste\n{1}, {T}: Copy target activated or triggered ability you control from another legendary source that's not a commander. You may choose new targets for the copy. (Mana abilities can't be targeted.) From 77ed724edb93227096be4b39f7195dd2d851052d Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Fri, 26 Aug 2022 17:30:05 +0200 Subject: [PATCH 08/70] DMC 8 cards + 1 Fix (#1388) --- .../res/cardsfolder/upcoming/activated_sleeper.txt | 8 ++++++++ .../res/cardsfolder/upcoming/baru_wurmspeaker.txt | 10 ++++++++++ .../res/cardsfolder/upcoming/emperor_mihail_ii.txt | 11 +++++++++++ .../upcoming/greensleeves_maro-sorcerer.txt | 12 ++++++++++++ .../cardsfolder/upcoming/hazezon_shaper_of_sand.txt | 2 +- forge-gui/res/cardsfolder/upcoming/ohabi_caleria.txt | 9 +++++++++ .../res/cardsfolder/upcoming/robaran_mercenaries.txt | 8 ++++++++ .../upcoming/rosnakht_heir_of_rohgahh.txt | 9 +++++++++ forge-gui/res/cardsfolder/upcoming/the_mana_rig.txt | 9 +++++++++ forge-gui/res/tokenscripts/g_3_3_badger.txt | 6 ++++++ forge-gui/res/tokenscripts/g_4_4_wurm.txt | 6 ++++++ 11 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/activated_sleeper.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/baru_wurmspeaker.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/emperor_mihail_ii.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/greensleeves_maro-sorcerer.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/ohabi_caleria.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/robaran_mercenaries.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/rosnakht_heir_of_rohgahh.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/the_mana_rig.txt create mode 100644 forge-gui/res/tokenscripts/g_3_3_badger.txt create mode 100644 forge-gui/res/tokenscripts/g_4_4_wurm.txt diff --git a/forge-gui/res/cardsfolder/upcoming/activated_sleeper.txt b/forge-gui/res/cardsfolder/upcoming/activated_sleeper.txt new file mode 100644 index 00000000000..9619e847cc8 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/activated_sleeper.txt @@ -0,0 +1,8 @@ +Name:Activated Sleeper +ManaCost:2 B +Types:Creature Phyrexian Shapeshifter +PT:0/0 +K:Flash +K:ETBReplacement:Copy:DBCopy:Optional +SVar:DBCopy:DB$ Clone | Choices$ Creature.ThisTurnEnteredFrom_Battlefield | ChoiceZone$ Graveyard | AddTypes$ Phyrexian | SpellDescription$ You may have CARDNAME enter the battlefield as a copy of any creature card in a graveyard that was put there from the battlefield this turn, except it's a Phyrexian in addition to its other types. +Oracle:You may have Activated Sleeper enter the battlefield as a copy of any creature card in a graveyard that was put there from the battlefield this turn, except it's a Phyrexian in addition to its other types. diff --git a/forge-gui/res/cardsfolder/upcoming/baru_wurmspeaker.txt b/forge-gui/res/cardsfolder/upcoming/baru_wurmspeaker.txt new file mode 100644 index 00000000000..b1612c6562f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/baru_wurmspeaker.txt @@ -0,0 +1,10 @@ +Name:Baru, Wurmspeaker +ManaCost:2 G G +Types:Legendary Creature Human Druid +PT:3/3 +S:Mode$ Continuous | Affected$ Wurm.YouCtrl | AddPower$ 2 | AddToughness$ 2 | AddKeyword$ Trample | Description$ Wurms you control get +2/+2 and have trample. +A:AB$ Token | Cost$ 7 G T | ReduceCost$ X | TokenScript$ g_4_4_wurm | TokenOwner$ You | SpellDescription$ Create a 4/4 green Wurm creature token. This ability costs {X} less to activate, where X is the greatest power among Wurms you control +SVar:X:Count$GreatestPower_Wurm.YouCtrl +DeckHas:Ability$Token & Type$Wurm +DeckHints:Type$Wurm +Oracle:Wurms you control get +2/+2 and have trample.\n{7}{G}, {T}: Create a 4/4 green Wurm creature token. This ability costs {X} less to activate, where X is the greatest power among Wurms you control diff --git a/forge-gui/res/cardsfolder/upcoming/emperor_mihail_ii.txt b/forge-gui/res/cardsfolder/upcoming/emperor_mihail_ii.txt new file mode 100644 index 00000000000..13e4b61e93f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/emperor_mihail_ii.txt @@ -0,0 +1,11 @@ +Name:Emperor Mihail II +ManaCost:1 U U +Types:Legendary Creature Merfolk Noble +PT:3/3 +S:Mode$ Continuous | Affected$ Card.TopLibrary+YouCtrl | AffectedZone$ Library | MayLookAt$ You | Description$ You may look at the top card of your library any time. +S:Mode$ Continuous | Affected$ Merfolk.TopLibrary+YouCtrl | AffectedZone$ Library | MayPlay$ True | Description$ You may play Merfolk spells from the top of your library. +T:Mode$ SpellCast | ValidCard$ Merfolk | ValidActivatingPlayer$ You | Execute$ TrigToken | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a Merfolk spell, you may pay {1}. If you do, create a 1/1 blue Merfolk creature token. +SVar:TrigToken:AB$ Token | Cost$ 1 | TokenScript$ u_1_1_merfolk | TokenOwner$ You | SpellDescription$ Create a 1/1 blue Merfolk creature token. +DeckHas:Ability$Token +DeckHints:Type$Merfolk +Oracle:You may look at the top card of your library any time.\nYou may cast Merfolk spells from the top of your library.\nWhenever you cast a Merfolk spell, you may pay {1}. If you do, create a 1/1 blue Merfolk creature token. diff --git a/forge-gui/res/cardsfolder/upcoming/greensleeves_maro-sorcerer.txt b/forge-gui/res/cardsfolder/upcoming/greensleeves_maro-sorcerer.txt new file mode 100644 index 00000000000..7fa458c3bf3 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/greensleeves_maro-sorcerer.txt @@ -0,0 +1,12 @@ +Name:Greensleeves, Maro-Sorcerer +ManaCost:3 G G +Types:Legendary Creature Elemental +PT:*/* +K:Protection:Planeswalker,Wizards:Protection from planeswalkers and Wizards +S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ X | SetToughness$ X | Description$ CARDNAME's power and toughness are each equal to the number of lands you control. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever a land enters the battlefield under your control, create a 3/3 green Badger creature token. +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ g_3_3_badger | TokenOwner$ You +SVar:X:Count$Valid Land.YouCtrl +DeckHas:Ability$Token & Type$Badger +Oracle:Protection from planeswalkers and from Wizards\nGreensleeves, Maro-Sorcerer’s power and toughness are each equal to the number of lands you control.\nWhenever a land enters the battlefield under your control, create a 3/3 green Badger creature token. + diff --git a/forge-gui/res/cardsfolder/upcoming/hazezon_shaper_of_sand.txt b/forge-gui/res/cardsfolder/upcoming/hazezon_shaper_of_sand.txt index fa544161b16..662863a2028 100644 --- a/forge-gui/res/cardsfolder/upcoming/hazezon_shaper_of_sand.txt +++ b/forge-gui/res/cardsfolder/upcoming/hazezon_shaper_of_sand.txt @@ -4,7 +4,7 @@ Types:Legendary Creature Human Warrior PT:3/3 K:Desertwalk S:Mode$ Continuous | Affected$ Desert.YouOwn | MayPlay$ True | AffectedZone$ Graveyard | Description$ You may play Desert lands from your graveyard -T:Mode$ ChangesZone | ValidCard$ Desert.YouCtrl | Origin$ Any | Destination$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever a Desert enters the battlefield under your control, create two 1/1 red, green, and white Sand Warrior creature tokens. +T:Mode$ ChangesZone | ValidCard$ Desert.YouCtrl | Origin$ Any | Destination$ Battlefield | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever a Desert enters the battlefield under your control, create two 1/1 red, green, and white Sand Warrior creature tokens. SVar:TrigToken:DB$ Token | TokenAmount$ 2 | TokenScript$ rgw_1_1_sand_warrior | TokenOwner$ You DeckHas:Ability$Token DeckHints:Type$Desert diff --git a/forge-gui/res/cardsfolder/upcoming/ohabi_caleria.txt b/forge-gui/res/cardsfolder/upcoming/ohabi_caleria.txt new file mode 100644 index 00000000000..62649ca9900 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ohabi_caleria.txt @@ -0,0 +1,9 @@ +Name:Ohabi Caleria +ManaCost:1 G W +Types:Legendary Creature Elf Archer +PT:1/3 +K:Reach +S:Mode$ Continuous | Affected$ Archer.YouCtrl | AddHiddenKeyword$ CARDNAME untaps during each other player's untap step. | Description$ Untap all Archers you control during each other player's untap step. +T:Mode$ DamageDone | ValidSource$ Archer.YouCtrl | ValidTarget$ Creature | TriggerZones$ Battlefield | Execute$ DBDraw | TriggerDescription$ Whenever an Archer you control deals damage to a creature, you may pay {2}. If you do, draw a card. +SVar:DBDraw:AB$ Draw | Cost$ 2 +Oracle:Reach\nUntap all Archers you control during each other player's untap step.\nWhenever an Archer you control deals damage to a creature, you may pay {2}. If you do, draw a card. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/robaran_mercenaries.txt b/forge-gui/res/cardsfolder/upcoming/robaran_mercenaries.txt new file mode 100644 index 00000000000..138014e0678 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/robaran_mercenaries.txt @@ -0,0 +1,8 @@ +Name:Robaran Mercenaries +ManaCost:3 W +Types:Creature Human Mercenary +PT:3/4 +K:Vigilance +S:Mode$ Continuous | Affected$ Card.Self | EffectZone$ Battlefield | GainsAbilitiesOf$ Creature.Legendary+YouCtrl | Description$ CARDNAME has all activated abilities of all legendary creatures you control +DeckHints:Type$Legendary +Oracle:Vigilance\nRobaran Mercenaries has all activated abilities of all legendary creatures you control. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/rosnakht_heir_of_rohgahh.txt b/forge-gui/res/cardsfolder/upcoming/rosnakht_heir_of_rohgahh.txt new file mode 100644 index 00000000000..d03fad1f43a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/rosnakht_heir_of_rohgahh.txt @@ -0,0 +1,9 @@ +Name:Rosnakht, Heir of Rohgahh +ManaCost:R +Types:Legendary Creature Kobold Warrior +PT:0/1 +K:Battle Cry +T:Mode$ SpellCast | ValidActivatingPlayer$ You | TargetsValid$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigToken| TriggerDescription$ Heroic — Whenever you cast a spell that targets CARDNAME, create a 0/1 red Kobold creature token named Kobolds of Kher Keep +SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenOwner$ You | TokenScript$ kobolds_of_kher_keep +DeckHas:Ability$Token +Oracle:Battle cry (Whenever this creature attacks, each other attacking creature gets +1/+0 until end of turn.)\nHeroic — Whenever you cast a spell that targets Rosnakht, Heir of Rohgahh, create a 0/1 red Kobold creature token named Kobolds of Kher Keep diff --git a/forge-gui/res/cardsfolder/upcoming/the_mana_rig.txt b/forge-gui/res/cardsfolder/upcoming/the_mana_rig.txt new file mode 100644 index 00000000000..7d5e67742f4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/the_mana_rig.txt @@ -0,0 +1,9 @@ +Name:The Mana Rig +ManaCost:3 +Types:Legendary Artifact +T:Mode$ SpellCast | ValidCard$ Card.MultiColor | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPowerStone | TriggerDescription$ Whenever you cast a multicolored spell, create a tapped Powerstone token. (It's an artifact with "T: Add C. This mana can't be spent to cast a nonartifact spell.") +SVar:TrigPowerStone:DB$ Token | TokenAmount$ 1 | TokenTapped$ True | TokenScript$ c_a_powerstone | TokenOwner$ You +A:AB$ Dig | Cost$ T X X X | DigNum$ X | ChangeNum$ 2 | RestRandomOrder$ True | SpellDescription$ Look at the top X cards of your library. Put up to two of them into your hand and the rest on the bottom of your library in a random order. +SVar:X:Count$xPaid +DeckHas:Ability$Token & Type|Artifact +Oracle:Whenever you cast a multicolored spell, create a tapped Powerstone token. (It's an artifact with "{T}: Add {C}. This mana can't be spent to cast a nonartifact spell.")\n{X}{X}{X}, {T}:Look at the top X cards of your library. Put up to two of them into your hand and the rest on the bottom of your library in a random order. diff --git a/forge-gui/res/tokenscripts/g_3_3_badger.txt b/forge-gui/res/tokenscripts/g_3_3_badger.txt new file mode 100644 index 00000000000..d71398dd18b --- /dev/null +++ b/forge-gui/res/tokenscripts/g_3_3_badger.txt @@ -0,0 +1,6 @@ +Name:Badger Token +ManaCost:no cost +Types:Creature Badger +Colors:green +PT:3/3 +Oracle: diff --git a/forge-gui/res/tokenscripts/g_4_4_wurm.txt b/forge-gui/res/tokenscripts/g_4_4_wurm.txt new file mode 100644 index 00000000000..1be6f14fe8c --- /dev/null +++ b/forge-gui/res/tokenscripts/g_4_4_wurm.txt @@ -0,0 +1,6 @@ +Name:Wurm Token +ManaCost:no cost +Colors:green +Types:Creature Wurm +PT:4/4 +Oracle: From 1e3a54e01d1cf2e0654840dccc45582c7bbd7272 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 11 Aug 2022 14:34:39 -0400 Subject: [PATCH 09/70] alora_rogue_companion.txt --- .../upcoming/alora_rogue_companion.txt | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/alora_rogue_companion.txt diff --git a/forge-gui/res/cardsfolder/upcoming/alora_rogue_companion.txt b/forge-gui/res/cardsfolder/upcoming/alora_rogue_companion.txt new file mode 100644 index 00000000000..84a7558cc7e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/alora_rogue_companion.txt @@ -0,0 +1,86 @@ +Name:Alora, Rogue Companion +ManaCost:3 U +Types:Legendary Creature Halfling Rogue +PT:3/3 +K:Specialize:2 +T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, up to one target attacking creature can't be blocked this turn. At the beginning of the next end step, return that creature to its owner's hand. +SVar:TrigPump:DB$ Pump | KW$ HIDDEN Unblockable | TgtPrompt$ Select target attacking creature | ValidTgts$ Creature.attacking | TargetMin$ 0 | TargetMax$ 1 | SubAbility$ DBDelTrig +SVar:DBDelTrig:DB$ DelayedTrigger | ConditionDefined$ Targeted | ConditionPresent$ Card | Mode$ Phase | Phase$ End of Turn | RememberObjects$ Targeted | Execute$ TrigReturn | TriggerDescription$ At the beginning of the next end step, return that creature to its owner's hand. +SVar:TrigReturn:DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Battlefield | Destination$ Hand +AlternateMode:Specialize +Oracle:Specialize {2}\nWhenever you attack, up to one target attacking creature can't be blocked this turn. At the beginning of the next end step, return that creature to its owner's hand. + +SPECIALIZE:WHITE + +Name:Alora, Cheerful Mastermind +ManaCost:3 W U +Types:Legendary Creature Halfling Rogue +PT:4/4 +T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, up to one target attacking creature can't be blocked this turn. At the beginning of the next end step, return that creature to its owner's hand. If you do, create a 1/1 white Soldier creature token. +SVar:TrigPump:DB$ Pump | KW$ HIDDEN Unblockable | TgtPrompt$ Select target attacking creature | ValidTgts$ Creature.attacking | TargetMin$ 0 | TargetMax$ 1 | SubAbility$ DBDelTrig +SVar:DBDelTrig:DB$ DelayedTrigger | ConditionDefined$ Targeted | ConditionPresent$ Card | Mode$ Phase | Phase$ End of Turn | RememberObjects$ Targeted | Execute$ TrigReturn | TriggerDescription$ At the beginning of the next end step, return that creature to its owner's hand. If you do, create a 1/1 white Soldier creature token. +SVar:TrigReturn:DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Battlefield | Destination$ Hand | ForgetOtherRemembered$ True | RememberChanged$ True | SubAbility$ DBToken +SVar:DBToken:DB$ Token | TokenScript$ w_1_1_soldier | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +DeckHas:Ability$Token & Type$Soldier +Oracle:Whenever you attack, up to one target attacking creature can't be blocked this turn. At the beginning of the next end step, return that creature to its owner's hand. If you do, create a 1/1 white Soldier creature token. + +SPECIALIZE:BLUE + +Name:Alora, Cheerful Thief +ManaCost:3 U U +Types:Legendary Creature Halfling Rogue +PT:4/4 +T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, up to one target attacking creature can't be blocked this turn. At the beginning of the next end step, return that creature to its owner's hand. If you do, a creature of your choice an opponent controls perpetually gets -1/-0. +SVar:TrigPump:DB$ Pump | KW$ HIDDEN Unblockable | TgtPrompt$ Select target attacking creature | ValidTgts$ Creature.attacking | TargetMin$ 0 | TargetMax$ 1 | SubAbility$ DBDelTrig +SVar:DBDelTrig:DB$ DelayedTrigger | ConditionDefined$ Targeted | ConditionPresent$ Card | Mode$ Phase | Phase$ End of Turn | RememberObjects$ Targeted | Execute$ TrigReturn | TriggerDescription$ At the beginning of the next end step, return that creature to its owner's hand. If you do, a creature of your choice an opponent controls perpetually gets -1/-0. +SVar:TrigReturn:DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Battlefield | Destination$ Hand | ForgetOtherRemembered$ True | RememberChanged$ True | SubAbility$ DBChooseCard +SVar:DBChooseCard:DB$ ChooseCard | ConditionDefined$ Remembered | ConditionPresent$ Card | Choices$ Creature.OppCtrl | Mandatory$ True | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBPerpetual +SVar:DBPerpetual:DB$ Effect | ConditionDefined$ ChosenCard | ConditionPresent$ Card | StaticAbilities$ PerpetualDebuff | Name$ Alora, Cheerful Thief's Perpetual Effect | Duration$ Permanent | SubAbility$ DBClearChosen +SVar:PerpetualDebuff:Mode$ Continuous | Affected$ Card.ChosenCard | AddPower$ -1 | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ The chosen creature perpetually gets -1/-0. +SVar:DBClearChosen:DB$ Cleanup | ClearChosenCard$ True +Oracle:Whenever you attack, up to one target attacking creature can't be blocked this turn. At the beginning of the next end step, return that creature to its owner's hand. If you do, a creature of your choice an opponent controls perpetually gets -1/-0. + +SPECIALIZE:BLACK + +Name:Alora, Cheerful Assassin +ManaCost:3 U B +Types:Legendary Creature Halfling Rogue Assassin +PT:4/4 +T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, up to one target attacking creature can't be blocked this turn. At the beginning of the next end step, return that creature to its owner's hand. If you do, each opponent loses 2 life. +SVar:TrigPump:DB$ Pump | KW$ HIDDEN Unblockable | TgtPrompt$ Select target attacking creature | ValidTgts$ Creature.attacking | TargetMin$ 0 | TargetMax$ 1 | SubAbility$ DBDelTrig +SVar:DBDelTrig:DB$ DelayedTrigger | ConditionDefined$ Targeted | ConditionPresent$ Card | Mode$ Phase | Phase$ End of Turn | RememberObjects$ Targeted | Execute$ TrigReturn | TriggerDescription$ At the beginning of the next end step, return that creature to its owner's hand. If you do, each opponent loses 2 life. +SVar:TrigReturn:DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Battlefield | Destination$ Hand | ForgetOtherRemembered$ True | RememberChanged$ True | SubAbility$ DBDrain +SVar:DBDrain:DB$ LoseLife | Defined$ Opponent | LifeAmount$ 2 | ConditionDefined$ Remembered | ConditionPresent$ Card +Oracle:Whenever you attack, up to one target attacking creature can't be blocked this turn. At the beginning of the next end step, return that creature to its owner's hand. If you do, each opponent loses 2 life. + +SPECIALIZE:RED + +Name:Alora, Cheerful Swashbuckler +ManaCost:3 U R +Types:Legendary Creature Halfling Rogue +PT:4/4 +T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, up to one target attacking creature can't be blocked this turn. At the beginning of the next end step, return that creature to its owner's hand. If you do, create a Treasure token. +SVar:TrigPump:DB$ Pump | KW$ HIDDEN Unblockable | TgtPrompt$ Select target attacking creature | ValidTgts$ Creature.attacking | TargetMin$ 0 | TargetMax$ 1 | SubAbility$ DBDelTrig +SVar:DBDelTrig:DB$ DelayedTrigger | ConditionDefined$ Targeted | ConditionPresent$ Card | Mode$ Phase | Phase$ End of Turn | RememberObjects$ Targeted | Execute$ TrigReturn | TriggerDescription$ At the beginning of the next end step, return that creature to its owner's hand. If you do, create a Treasure token. +SVar:TrigReturn:DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Battlefield | Destination$ Hand | ForgetOtherRemembered$ True | RememberChanged$ True | SubAbility$ DBTreasure +SVar:DBTreasure:DB$ Token | TokenScript$ c_a_treasure_sac | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +DeckHas:Ability$Token|Sacrifice & Type$Artifact|Treasure +Oracle:Whenever you attack, up to one target attacking creature can't be blocked this turn. At the beginning of the next end step, return that creature to its owner's hand. If you do, create a Treasure token. + +SPECIALIZE:GREEN + +Name:Alora, Cheerful Scout +ManaCost:3 G U +Types:Legendary Creature Halfling Rogue Scout +PT:4/4 +T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, up to one target attacking creature can't be blocked this turn. At the beginning of the next end step, return that creature to its owner's hand. If you do, it perpetually gets +1/+1. +SVar:TrigPump:DB$ Pump | KW$ HIDDEN Unblockable | TgtPrompt$ Select target attacking creature | ValidTgts$ Creature.attacking | TargetMin$ 0 | TargetMax$ 1 | SubAbility$ DBDelTrig +SVar:DBDelTrig:DB$ DelayedTrigger | ConditionDefined$ Targeted | ConditionPresent$ Card | Mode$ Phase | Phase$ End of Turn | RememberObjects$ Targeted | Execute$ TrigReturn | TriggerDescription$ At the beginning of the next end step, return that creature to its owner's hand. If you do, it perpetually gets +1/+1. +SVar:TrigReturn:DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Battlefield | Destination$ Hand | ForgetOtherRemembered$ True | RememberChanged$ True | SubAbility$ DBPerpetual +SVar:DBPerpetual:DB$ Effect | ConditionDefined$ Remembered | ConditionPresent$ Card | RememberObjects$ Remembered | StaticAbilities$ PerpetualP1P1 | Name$ Alora, Cheerful Scout's Perpetual Effect | Duration$ Permanent | SubAbility$ DBCleanup +SVar:PerpetualP1P1:Mode$ Continuous | Affected$ Card.IsRemembered | AddPower$ 1 | AddToughness$ 1 | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ That creature perpetually gets +1/+1. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:Whenever you attack, up to one target attacking creature can't be blocked this turn. At the beginning of the next end step, return that creature to its owner's hand. If you do, it perpetually gets +1/+1. From 9a6c45726f24d2ff77c749178b75980c182619fd Mon Sep 17 00:00:00 2001 From: Northmoc Date: Sat, 13 Aug 2022 01:15:30 -0400 Subject: [PATCH 10/70] alora_merry_thief.txt don't fire deltrig if nothing affected --- forge-gui/res/cardsfolder/a/alora_merry_thief.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/a/alora_merry_thief.txt b/forge-gui/res/cardsfolder/a/alora_merry_thief.txt index 675d135aab0..622a1939e5f 100644 --- a/forge-gui/res/cardsfolder/a/alora_merry_thief.txt +++ b/forge-gui/res/cardsfolder/a/alora_merry_thief.txt @@ -4,7 +4,7 @@ Types:Legendary Creature Halfling Rogue PT:3/2 T:Mode$ AttackersDeclared | AttackingPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever you attack, up to one target attacking creature can't be blocked this turn. Return that creature to its owner's hand at the beginning of the next end step. SVar:TrigPump:DB$ Pump | KW$ HIDDEN Unblockable | TgtPrompt$ Select target attacking creature | ValidTgts$ Creature.attacking | TargetMin$ 0 | TargetMax$ 1 | SubAbility$ DBDelTrig -SVar:DBDelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | RememberObjects$ Targeted | Execute$ TrigReturn | SpellDescription$ Return that creature to its owner's hand at the beginning of the next end step. +SVar:DBDelTrig:DB$ DelayedTrigger | ConditionDefined$ Targeted | ConditionPresent$ Card | Mode$ Phase | Phase$ End of Turn | RememberObjects$ Targeted | Execute$ TrigReturn | SpellDescription$ Return that creature to its owner's hand at the beginning of the next end step. SVar:TrigReturn:DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Battlefield | Destination$ Hand K:Choose a Background Oracle:Whenever you attack, up to one target attacking creature can't be blocked this turn. Return that creature to its owner's hand at the beginning of the next end step.\nChoose a Background (You can have a Background as a second commander.) From 47333d29b494b51f2fe9a3dc83183a33cdbedaeb Mon Sep 17 00:00:00 2001 From: Northmoc Date: Sat, 13 Aug 2022 22:44:39 -0400 Subject: [PATCH 11/70] Card.keywordsToText() add Specialize to list for now --- forge-game/src/main/java/forge/game/card/Card.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index fe29ac14162..412b34b2aee 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -2010,7 +2010,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } else if (keyword.startsWith("Morph") || keyword.startsWith("Megamorph") || keyword.startsWith("Escape") || keyword.startsWith("Foretell:") || keyword.startsWith("Disturb") || keyword.startsWith("Madness:") - || keyword.startsWith("Reconfigure")) { + || keyword.startsWith("Reconfigure") || keyword.startsWith("Specialize")) { String[] k = keyword.split(":"); sbLong.append(k[0]); if (k.length > 1) { From 5c14fd06e45254b117f01350cc49a80dfdf2d9ee Mon Sep 17 00:00:00 2001 From: Northmoc Date: Sat, 13 Aug 2022 22:45:24 -0400 Subject: [PATCH 12/70] CardRules support multiple specialize faces --- .../src/main/java/forge/card/CardRules.java | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/forge-core/src/main/java/forge/card/CardRules.java b/forge-core/src/main/java/forge/card/CardRules.java index c6369afec49..707dbe450a6 100644 --- a/forge-core/src/main/java/forge/card/CardRules.java +++ b/forge-core/src/main/java/forge/card/CardRules.java @@ -43,6 +43,11 @@ public final class CardRules implements ICardCharacteristics { private CardSplitType splitType; private ICardFace mainPart; private ICardFace otherPart; + private ICardFace wSpecialize; + private ICardFace uSpecialize; + private ICardFace bSpecialize; + private ICardFace rSpecialize; + private ICardFace gSpecialize; private CardAiHints aiHints; private ColorSet colorIdentity; private ColorSet deckbuildingColors; @@ -54,6 +59,12 @@ public final class CardRules implements ICardCharacteristics { splitType = altMode; mainPart = faces[0]; otherPart = faces[1]; + wSpecialize = faces[2]; + uSpecialize = faces[3]; + bSpecialize = faces[4]; + rSpecialize = faces[5]; + gSpecialize = faces[6]; + aiHints = cah; meldWith = ""; partnerWith = ""; @@ -74,6 +85,11 @@ public final class CardRules implements ICardCharacteristics { splitType = newRules.splitType; mainPart = newRules.mainPart; otherPart = newRules.otherPart; + wSpecialize = newRules.wSpecialize; + uSpecialize = newRules.uSpecialize; + bSpecialize = newRules.bSpecialize; + rSpecialize = newRules.rSpecialize; + gSpecialize = newRules.gSpecialize; aiHints = newRules.aiHints; colorIdentity = newRules.colorIdentity; meldWith = newRules.meldWith; @@ -132,6 +148,22 @@ public final class CardRules implements ICardCharacteristics { return otherPart; } + public ICardFace getWSpecialize() { + return wSpecialize; + } + public ICardFace getUSpecialize() { + return uSpecialize; + } + public ICardFace getBSpecialize() { + return bSpecialize; + } + public ICardFace getRSpecialize() { + return rSpecialize; + } + public ICardFace getGSpecialize() { + return gSpecialize; + } + public String getName() { switch (splitType.getAggregationMethod()) { case COMBINE: @@ -335,7 +367,7 @@ public final class CardRules implements ICardCharacteristics { // Reads cardname.txt public static class Reader { // fields to build - private CardFace[] faces = new CardFace[] { null, null }; + private CardFace[] faces = new CardFace[] { null, null, null, null, null, null, null }; private int curFace = 0; private CardSplitType altMode = CardSplitType.None; private String meldWith = ""; @@ -518,6 +550,18 @@ public final class CardRules implements ICardCharacteristics { case 'S': if ("S".equals(key)) { this.faces[this.curFace].addStaticAbility(value); + } else if (key.startsWith("SPECIALIZE")) { + if (value.equals("WHITE")) { + this.curFace = 2; + } else if (value.equals("BLUE")) { + this.curFace = 3; + } else if (value.equals("BLACK")) { + this.curFace = 4; + } else if (value.equals("RED")) { + this.curFace = 5; + } else if (value.equals("GREEN")) { + this.curFace = 6; + } } else if ("SVar".equals(key)) { if (null == value) throw new IllegalArgumentException("SVar has no variable name"); @@ -600,7 +644,7 @@ public final class CardRules implements ICardCharacteristics { public static CardRules getUnsupportedCardNamed(String name) { CardAiHints cah = new CardAiHints(true, true, true, null, null, null); - CardFace[] faces = { new CardFace(name), null}; + CardFace[] faces = { new CardFace(name), null, null, null, null, null, null}; faces[0].setColor(ColorSet.fromMask(0)); faces[0].setType(CardType.parse("", false)); faces[0].setOracleText("This card is not supported by Forge. Whenever you start a game with this card, it will be bugged."); From 8221dd73d238f164742186d33abdd765b35faa87 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Sat, 13 Aug 2022 22:45:54 -0400 Subject: [PATCH 13/70] Keyword.SPECIALIZE --- forge-game/src/main/java/forge/game/keyword/Keyword.java | 1 + 1 file changed, 1 insertion(+) diff --git a/forge-game/src/main/java/forge/game/keyword/Keyword.java b/forge-game/src/main/java/forge/game/keyword/Keyword.java index c92bcd4d4c7..e293c449d2d 100644 --- a/forge-game/src/main/java/forge/game/keyword/Keyword.java +++ b/forge-game/src/main/java/forge/game/keyword/Keyword.java @@ -153,6 +153,7 @@ public enum Keyword { SCAVENGE("Scavenge", KeywordWithCost.class, false, "%s, Exile this card from your graveyard: Put a number of +1/+1 counters equal to this card's power on target creature. Scavenge only as a sorcery."), SOULBOND("Soulbond", SimpleKeyword.class, true, "You may pair this creature with another unpaired creature when either enters the battlefield. They remain paired for as long as you control both of them."), SOULSHIFT("Soulshift", KeywordWithAmount.class, false, "When this creature dies, you may return target Spirit card with mana value %d or less from your graveyard to your hand."), + SPECIALIZE("Specialize", KeywordWithCost.class, false, "%s, Choose a color, discard a card of that color or associated basic land type: This card perpetually specializes into that color. Activate only as a sorcery."), SPECTACLE("Spectacle", KeywordWithCost.class, false, "You may cast this spell for its spectacle cost rather than its mana cost if an opponent lost life this turn."), SPLICE("Splice", KeywordWithCostAndType.class, false, "As you cast an %2$s spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell."), SPLIT_SECOND("Split second", SimpleKeyword.class, true, "As long as this spell is on the stack, players can't cast other spells or activate abilities that aren't mana abilities."), From 6d14daaa7664dbc73e7f6fb8a188b2bb7a94a65b Mon Sep 17 00:00:00 2001 From: Northmoc Date: Sat, 13 Aug 2022 22:46:16 -0400 Subject: [PATCH 14/70] CardStateName for Specialize --- forge-core/src/main/java/forge/card/CardStateName.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/forge-core/src/main/java/forge/card/CardStateName.java b/forge-core/src/main/java/forge/card/CardStateName.java index 90149dde340..fca71c5556f 100644 --- a/forge-core/src/main/java/forge/card/CardStateName.java +++ b/forge-core/src/main/java/forge/card/CardStateName.java @@ -10,7 +10,12 @@ public enum CardStateName { LeftSplit, RightSplit, Adventure, - Modal + Modal, + SpecializeW, + SpecializeU, + SpecializeB, + SpecializeR, + SpecializeG ; From 58a96a6acc35eb9dbd658f2341039c5ae166e814 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Sat, 13 Aug 2022 22:46:35 -0400 Subject: [PATCH 15/70] CardSplitType.Specialize --- forge-core/src/main/java/forge/card/CardSplitType.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/forge-core/src/main/java/forge/card/CardSplitType.java b/forge-core/src/main/java/forge/card/CardSplitType.java index 43670c7bafe..69c6aea1814 100644 --- a/forge-core/src/main/java/forge/card/CardSplitType.java +++ b/forge-core/src/main/java/forge/card/CardSplitType.java @@ -10,7 +10,8 @@ public enum CardSplitType Split(FaceSelectionMethod.COMBINE, CardStateName.RightSplit), Flip(FaceSelectionMethod.USE_PRIMARY_FACE, CardStateName.Flipped), Adventure(FaceSelectionMethod.USE_PRIMARY_FACE, CardStateName.Adventure), - Modal(FaceSelectionMethod.USE_ACTIVE_FACE, CardStateName.Modal); + Modal(FaceSelectionMethod.USE_ACTIVE_FACE, CardStateName.Modal), + Specialize(FaceSelectionMethod.USE_ACTIVE_FACE, null); CardSplitType(FaceSelectionMethod calcMode, CardStateName stateName) { method = calcMode; From 3ad89fbca7b4eb130552be4b29880cc36c493da4 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 10:43:24 -0400 Subject: [PATCH 16/70] CardFactory.readCard handle Specialize states --- .../java/forge/game/card/CardFactory.java | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index 2f6aa6fc87b..fbde15700a4 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -364,7 +364,33 @@ public class CardFactory { readCardFace(card, rules.getMainPart()); - if (st != CardSplitType.None) { + if (st == CardSplitType.Specialize) { + card.addAlternateState(CardStateName.SpecializeW, false); + card.setState(CardStateName.SpecializeW, false); + if (rules.getWSpecialize() != null) { + readCardFace(card, rules.getWSpecialize()); + } + card.addAlternateState(CardStateName.SpecializeU, false); + card.setState(CardStateName.SpecializeU, false); + if (rules.getUSpecialize() != null) { + readCardFace(card, rules.getUSpecialize()); + } + card.addAlternateState(CardStateName.SpecializeB, false); + card.setState(CardStateName.SpecializeB, false); + if (rules.getBSpecialize() != null) { + readCardFace(card, rules.getBSpecialize()); + } + card.addAlternateState(CardStateName.SpecializeR, false); + card.setState(CardStateName.SpecializeR, false); + if (rules.getRSpecialize() != null) { + readCardFace(card, rules.getRSpecialize()); + } + card.addAlternateState(CardStateName.SpecializeG, false); + card.setState(CardStateName.SpecializeG, false); + if (rules.getGSpecialize() != null) { + readCardFace(card, rules.getGSpecialize()); + } + } else if (st != CardSplitType.None) { card.addAlternateState(st.getChangedStateName(), false); card.setState(st.getChangedStateName(), false); if (rules.getOtherPart() != null) { From 4dbc3ae49a1d90f51dfda919be726150285d4451 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 10:44:05 -0400 Subject: [PATCH 17/70] CardFactoryUtil.addSpellAbility rough in Specialize KW --- .../java/forge/game/card/CardFactoryUtil.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 0e205ff0d64..53589e22fe7 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -3215,6 +3215,21 @@ public class CardFactoryUtil { final AbilitySub cleanSub = (AbilitySub) AbilityFactory.getAbility(cleanStr, card); effectSub.setSubAbility(cleanSub); + sa.setIntrinsic(intrinsic); + inst.addSpellAbility(sa); + } else if (keyword.startsWith("Specialize")) { + final String[] k = keyword.split(":"); + final String cost = k[1]; + + //this needs to just be AB$ SetState with choosecolor and discard costs + //don't forget to add SorcerySpeed$ True!!! + final String effect = "AB$ ChooseColor | Cost$ " + cost; + final String sub = "DB$ SetState | Mode$ Specialize"; + + final SpellAbility sa = AbilityFactory.getAbility(effect, card); + final AbilitySub subSa = (AbilitySub) AbilityFactory.getAbility(sub, card); + sa.setSubAbility(subSa); + sa.setIntrinsic(intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Spectacle")) { From 84384981be8485d230a4d97d6a7b1c8583bd0992 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 10:44:49 -0400 Subject: [PATCH 18/70] CardRules.Reader.getCard support additional faces for Specialize --- forge-core/src/main/java/forge/card/CardRules.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/forge-core/src/main/java/forge/card/CardRules.java b/forge-core/src/main/java/forge/card/CardRules.java index 707dbe450a6..d5646e6b949 100644 --- a/forge-core/src/main/java/forge/card/CardRules.java +++ b/forge-core/src/main/java/forge/card/CardRules.java @@ -414,6 +414,11 @@ public final class CardRules implements ICardCharacteristics { CardAiHints cah = new CardAiHints(removedFromAIDecks, removedFromRandomDecks, removedFromNonCommanderDecks, hints, needs, has); faces[0].assignMissingFields(); if (null != faces[1]) faces[1].assignMissingFields(); + if (null != faces[2]) faces[2].assignMissingFields(); + if (null != faces[3]) faces[3].assignMissingFields(); + if (null != faces[4]) faces[4].assignMissingFields(); + if (null != faces[5]) faces[5].assignMissingFields(); + if (null != faces[6]) faces[6].assignMissingFields(); final CardRules result = new CardRules(faces, altMode, cah); result.setNormalizedName(this.normalizedName); From c6d91f170fae62983127461d7ad19487a9904306 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 10:46:06 -0400 Subject: [PATCH 19/70] SetStateEffect.resolve add "Specialize" mode support --- .../main/java/forge/game/ability/effects/SetStateEffect.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java index 820e1ae2a91..718a9ce7f3a 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java @@ -160,6 +160,9 @@ public class SetStateEffect extends SpellAbilityEffect { hasTransformed = gameCard.turnFaceUp(sa); } else if (sa.isManifestUp()) { hasTransformed = gameCard.turnFaceUp(true, true, sa); + } else if ("Specialize".equals(mode)) { + hasTransformed = gameCard.changeCardState(mode, host.getChosenColor(), sa); + //remove Chosen Color here? Or just add to kw handling? } else { hasTransformed = gameCard.changeCardState(mode, sa.getParam("NewState"), sa); if (gameCard.isFaceDown() && (sa.hasParam("FaceDownPower") || sa.hasParam("FaceDownToughness") From 67c285c9b0a697f4e795b55c1e8a7e7a91d9159c Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 10:46:44 -0400 Subject: [PATCH 20/70] Card.changeCardState support Specialize --- forge-game/src/main/java/forge/game/card/Card.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 412b34b2aee..2302a2e742c 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -661,6 +661,19 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } } else if (mode.equals("Meld") && isMeldable()) { return changeToState(CardStateName.Meld); + } else if (mode.equals("Specialize")) { + if (customState.equalsIgnoreCase("white")) { + return changeToState(CardStateName.SpecializeW); + } else if (customState.equalsIgnoreCase("blue")) { + return changeToState(CardStateName.SpecializeU); + } else if (customState.equalsIgnoreCase("black")) { + return changeToState(CardStateName.SpecializeB); + } else if (customState.equalsIgnoreCase("red")) { + return changeToState(CardStateName.SpecializeR); + } else if (customState.equalsIgnoreCase("green")) { + return changeToState(CardStateName.SpecializeG); + } + //do trigger here? } return false; } From 9492e4212c26dba42688409b6fc76aaba6d032b3 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 15:24:10 -0400 Subject: [PATCH 21/70] AiCostDecision.visit for CostChooseColor --- forge-ai/src/main/java/forge/ai/AiCostDecision.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/forge-ai/src/main/java/forge/ai/AiCostDecision.java b/forge-ai/src/main/java/forge/ai/AiCostDecision.java index 16b01575594..210209a702e 100644 --- a/forge-ai/src/main/java/forge/ai/AiCostDecision.java +++ b/forge-ai/src/main/java/forge/ai/AiCostDecision.java @@ -2,10 +2,12 @@ package forge.ai; import static forge.ai.ComputerUtilCard.getBestCreatureAI; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import forge.card.MagicColor; import forge.game.cost.*; import org.apache.commons.lang3.ObjectUtils; @@ -55,6 +57,14 @@ public class AiCostDecision extends CostDecisionMakerBase { return PaymentDecision.number(c); } + @Override + public PaymentDecision visit(CostChooseColor cost) { + int c = cost.getAbilityAmount(ability); + List choices = player.getController().chooseColors("Color", ability, c, c, + new ArrayList<>(MagicColor.Constant.ONLY_COLORS)); + return PaymentDecision.colors(choices); + } + @Override public PaymentDecision visit(CostChooseCreatureType cost) { String choice = player.getController().chooseSomeType("Creature", ability, CardType.getAllCreatureTypes(), From 4970359dfa9c880bdb263d8bf488af2a21a4b949 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 15:24:30 -0400 Subject: [PATCH 22/70] HumanCostDecision.visit for CostChooseColor --- .../src/main/java/forge/player/HumanCostDecision.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/forge-gui/src/main/java/forge/player/HumanCostDecision.java b/forge-gui/src/main/java/forge/player/HumanCostDecision.java index b18470d7029..1ee72ae4699 100644 --- a/forge-gui/src/main/java/forge/player/HumanCostDecision.java +++ b/forge-gui/src/main/java/forge/player/HumanCostDecision.java @@ -11,6 +11,7 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import forge.card.CardType; +import forge.card.MagicColor; import forge.game.Game; import forge.game.GameEntity; import forge.game.GameEntityCounterTable; @@ -68,6 +69,15 @@ public class HumanCostDecision extends CostDecisionMakerBase { return PaymentDecision.number(cost.getAbilityAmount(ability)); } + @Override + public PaymentDecision visit(CostChooseColor cost) { + int c = cost.getAbilityAmount(ability); + List choices = player.getController().chooseColors(Localizer.getInstance(). + getMessage("lblChooseAColor"), ability, c, c, + new ArrayList<>(MagicColor.Constant.ONLY_COLORS)); + return PaymentDecision.colors(choices); + } + @Override public PaymentDecision visit(final CostChooseCreatureType cost) { final String choice = controller.chooseSomeType(Localizer.getInstance().getMessage("lblCreature"), ability, new ArrayList<>(CardType.Constant.CREATURE_TYPES), new ArrayList<>(), true); From dd262636a28a65659bcfe33a897da6fc77236d7d Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 15:25:13 -0400 Subject: [PATCH 23/70] ICostVisitor add CostChooseColor --- forge-game/src/main/java/forge/game/cost/ICostVisitor.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/forge-game/src/main/java/forge/game/cost/ICostVisitor.java b/forge-game/src/main/java/forge/game/cost/ICostVisitor.java index 89b69c2c2e1..29df064dd01 100644 --- a/forge-game/src/main/java/forge/game/cost/ICostVisitor.java +++ b/forge-game/src/main/java/forge/game/cost/ICostVisitor.java @@ -3,6 +3,7 @@ package forge.game.cost; public interface ICostVisitor { T visit(CostGainControl cost); + T visit(CostChooseColor cost); T visit(CostChooseCreatureType cost); T visit(CostDiscard cost); T visit(CostDamage cost); @@ -40,6 +41,11 @@ public interface ICostVisitor { return null; } + @Override + public T visit(CostChooseColor cost) { + return null; + } + @Override public T visit(CostChooseCreatureType cost) { return null; From 2155fa0f2e8d3969c70278c17ff3082af4d7bc71 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 15:26:49 -0400 Subject: [PATCH 24/70] PaymentDecision support CostChooseColor --- .../src/main/java/forge/game/cost/PaymentDecision.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/forge-game/src/main/java/forge/game/cost/PaymentDecision.java b/forge-game/src/main/java/forge/game/cost/PaymentDecision.java index d7af147ac3d..0c24234f5f2 100644 --- a/forge-game/src/main/java/forge/game/cost/PaymentDecision.java +++ b/forge-game/src/main/java/forge/game/cost/PaymentDecision.java @@ -13,6 +13,7 @@ import forge.util.TextUtil; public class PaymentDecision { public int c = 0; public String type; + public List colors; public final CardCollection cards = new CardCollection(); public final List mana; @@ -48,6 +49,11 @@ public class PaymentDecision { type = choice; } + public PaymentDecision(List choices) { + this(null, null, null, null, null); + colors = choices; + } + public static PaymentDecision card(Card chosen) { return new PaymentDecision(chosen); } @@ -88,6 +94,10 @@ public class PaymentDecision { return new PaymentDecision(choice); } + public static PaymentDecision colors(List choices) { + return new PaymentDecision(choices); + } + public static PaymentDecision players(List players) { return new PaymentDecision(null, null, players, null, null); } From 09208ba1be540fc8d1cbdf746358c6dd02a2b848 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 15:27:07 -0400 Subject: [PATCH 25/70] ForgeScript.cardStateHasProperty "AssociatedWithChosenColor" --- .../src/main/java/forge/game/ForgeScript.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/forge-game/src/main/java/forge/game/ForgeScript.java b/forge-game/src/main/java/forge/game/ForgeScript.java index 93897c40050..6ac6897e72d 100644 --- a/forge-game/src/main/java/forge/game/ForgeScript.java +++ b/forge-game/src/main/java/forge/game/ForgeScript.java @@ -80,6 +80,22 @@ public class ForgeScript { return source.hasChosenColor() && colors.hasAnyColor(ColorSet.fromNames(source.getChosenColors()).getColor()); + } else if (property.equals("AssociatedWithChosenColor")) { + final String color = source.getChosenColor(); + switch (color) { + case "white": + return cardState.getTypeWithChanges().getLandTypes().contains("Plains"); + case "blue": + return cardState.getTypeWithChanges().getLandTypes().contains("Island"); + case "black": + return cardState.getTypeWithChanges().getLandTypes().contains("Swamp"); + case "red": + return cardState.getTypeWithChanges().getLandTypes().contains("Mountain"); + case "green": + return cardState.getTypeWithChanges().getLandTypes().contains("Forest"); + default: + return false; + } } else if (property.startsWith("non")) { // ... Other Card types return !cardState.getTypeWithChanges().hasStringType(property.substring(3)); From 6f3a1178367c89bc51f847e8c5ff8044db4ed7d3 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 15:28:06 -0400 Subject: [PATCH 26/70] CostDiscard.canPay workaround for discarding card of chosen color when color not yet chosen --- forge-game/src/main/java/forge/game/cost/CostDiscard.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/cost/CostDiscard.java b/forge-game/src/main/java/forge/game/cost/CostDiscard.java index 676b262af16..8478e5e58c4 100644 --- a/forge-game/src/main/java/forge/game/cost/CostDiscard.java +++ b/forge-game/src/main/java/forge/game/cost/CostDiscard.java @@ -166,7 +166,9 @@ public class CostDiscard extends CostPartWithList { sameName = true; type = TextUtil.fastReplace(type, "+WithSameName", ""); } - if (!type.equals("Random") && !type.contains("X")) { + if (type.contains("ChosenColor") && !source.hasChosenColor()) { + //color hasn't been chosen yet, so skip getValidCards + } else if (!type.equals("Random") && !type.contains("X")) { // Knollspine Invocation fails to activate without the above conditional handList = CardLists.getValidCards(handList, type.split(";"), payer, source, ability); } From 8a691a511422e60a916ea58df47bed08ea9c0f3e Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 15:28:20 -0400 Subject: [PATCH 27/70] CostChooseColor.java --- .../java/forge/game/cost/CostChooseColor.java | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 forge-game/src/main/java/forge/game/cost/CostChooseColor.java diff --git a/forge-game/src/main/java/forge/game/cost/CostChooseColor.java b/forge-game/src/main/java/forge/game/cost/CostChooseColor.java new file mode 100644 index 00000000000..f50facff3da --- /dev/null +++ b/forge-game/src/main/java/forge/game/cost/CostChooseColor.java @@ -0,0 +1,83 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package forge.game.cost; + +import forge.game.player.Player; +import forge.game.spellability.SpellAbility; + +/** + * the class CostChooseColor + */ +public class CostChooseColor extends CostPart { + + /** + * Serializables need a version ID. + */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new cost choose color. + * + * @param amount + * the amount + */ + public CostChooseColor(final String amount) { + this.setAmount(amount); + } + + /* + * (non-Javadoc) + * + * @see + * forge.card.cost.CostPart#canPay(forge.card.spellability.SpellAbility, + * forge.Card, forge.Player, forge.card.cost.Cost) + */ + @Override + public final boolean canPay(final SpellAbility ability, final Player payer, final boolean effect) { + return true; + } + + @Override + public boolean payAsDecided(Player payer, PaymentDecision pd, SpellAbility sa, final boolean effect) { + sa.getHostCard().setChosenColors(pd.colors); + return true; + } + + @Override + public int paymentOrder() { return 8; } + + /* + * (non-Javadoc) + * + * @see forge.card.cost.CostPart#toString() + */ + @Override + public final String toString() { + final StringBuilder sb = new StringBuilder(); + final Integer i = this.convertAmount(); + sb.append("Choose "); + sb.append(Cost.convertAmountTypeToWords(i, this.getAmount(), "color")); + return sb.toString(); + } + + @Override + public T accept(ICostVisitor visitor) { + return visitor.visit(this); + } + +} From a3238ee6574939b100a0eb00d5a5ed794ba56dd2 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 15:29:06 -0400 Subject: [PATCH 28/70] Cost.parseCostPart add ChooseColor --- forge-game/src/main/java/forge/game/cost/Cost.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/forge-game/src/main/java/forge/game/cost/Cost.java b/forge-game/src/main/java/forge/game/cost/Cost.java index ec5f54224a5..731e36e9e1a 100644 --- a/forge-game/src/main/java/forge/game/cost/Cost.java +++ b/forge-game/src/main/java/forge/game/cost/Cost.java @@ -341,6 +341,13 @@ public class Cost implements Serializable { return new CostUnattach(splitStr[0], description); } + if (parse.startsWith("ChooseColor<")) { + // ChooseColor + //TODO expand this to set off different UI for Specialize + final String[] splitStr = abCostParse(parse, 1); + return new CostChooseColor(splitStr[0]); + } + if (parse.startsWith("ChooseCreatureType<")) { final String[] splitStr = abCostParse(parse, 1); return new CostChooseCreatureType(splitStr[0]); From b773dc59d5919d67a032de0a6a4f6011eb0eb880 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 15:30:40 -0400 Subject: [PATCH 29/70] CardFactoryUtil.addSpellAbility improve Specialize KW --- .../src/main/java/forge/game/card/CardFactoryUtil.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 53589e22fe7..f1e4e33d444 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -3221,15 +3221,11 @@ public class CardFactoryUtil { final String[] k = keyword.split(":"); final String cost = k[1]; - //this needs to just be AB$ SetState with choosecolor and discard costs - //don't forget to add SorcerySpeed$ True!!! - final String effect = "AB$ ChooseColor | Cost$ " + cost; - final String sub = "DB$ SetState | Mode$ Specialize"; + final String effect = "AB$ SetState | Cost$ " + cost + " ChooseColor<1> Discard<1/Card.ChosenColor;" + + "Card.AssociatedWithChosenColor/card of the chosen color or its associated basic land type> | " + + "Mode$ Specialize | SorcerySpeed$ True"; final SpellAbility sa = AbilityFactory.getAbility(effect, card); - final AbilitySub subSa = (AbilitySub) AbilityFactory.getAbility(sub, card); - sa.setSubAbility(subSa); - sa.setIntrinsic(intrinsic); inst.addSpellAbility(sa); } else if (keyword.startsWith("Spectacle")) { From b951478d2468955b4e829ea162755055100a498c Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 23:12:24 -0400 Subject: [PATCH 30/70] SetStateEffect.getStackDescription support Specialize --- .../java/forge/game/ability/effects/SetStateEffect.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java index 718a9ce7f3a..e6735d9f7b4 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java @@ -21,15 +21,22 @@ public class SetStateEffect extends SpellAbilityEffect { @Override protected String getStackDescription(final SpellAbility sa) { + final Card host = sa.getHostCard(); final StringBuilder sb = new StringBuilder(); + boolean specialize = sa.getParam("Mode").equals("Specialize"); if (sa.hasParam("Flip")) { sb.append("Flip "); + } else if (specialize) { // verb will come later } else { sb.append("Transform "); } sb.append(Lang.joinHomogenous(getTargetCards(sa))); + if (specialize) { + sb.append(" perpetually specializes into "); + sb.append(host.hasChosenColor() ? host.getChosenColor() : "the chosen color"); + } sb.append("."); return sb.toString(); } From e6486fbdaf847cc88ee563dca477030bedc2fc7a Mon Sep 17 00:00:00 2001 From: Northmoc Date: Wed, 17 Aug 2022 23:12:50 -0400 Subject: [PATCH 31/70] SetStateEffect.resolve clean up ChosenColor --- .../main/java/forge/game/ability/effects/SetStateEffect.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java index e6735d9f7b4..c6e8445a96b 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java @@ -169,7 +169,7 @@ public class SetStateEffect extends SpellAbilityEffect { hasTransformed = gameCard.turnFaceUp(true, true, sa); } else if ("Specialize".equals(mode)) { hasTransformed = gameCard.changeCardState(mode, host.getChosenColor(), sa); - //remove Chosen Color here? Or just add to kw handling? + host.setChosenColors(null); } else { hasTransformed = gameCard.changeCardState(mode, sa.getParam("NewState"), sa); if (gameCard.isFaceDown() && (sa.hasParam("FaceDownPower") || sa.hasParam("FaceDownToughness") From 33550baada3ca5d632a4d967970cf88f9c3d5ed7 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 09:39:25 -0400 Subject: [PATCH 32/70] Card.specialized private boolean --- forge-game/src/main/java/forge/game/card/Card.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 2302a2e742c..a73ad63df92 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -212,6 +212,8 @@ public class Card extends GameEntity implements Comparable, IHasSVars { private boolean foretoldThisTurn; private boolean foretoldByEffect; + private boolean specialized; + private int timesCrewedThisTurn = 0; private int classLevel = 1; From 25cfb3e0dfcedf51948ddf905765358ab57d7a95 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 09:40:26 -0400 Subject: [PATCH 33/70] Card.isSpecialized/setSpecialized/canSpecialize --- forge-game/src/main/java/forge/game/card/Card.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index a73ad63df92..ee3776155ee 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -5745,6 +5745,16 @@ public class Card extends GameEntity implements Comparable, IHasSVars { foretoldThisTurn = false; } + public boolean isSpecialized() { + return specialized; + } + public final void setSpecialized(final boolean bool) { + specialized = bool; + } + public final boolean canSpecialize() { + return getRules() != null && getRules().getSplitType() == CardSplitType.Specialize; + } + public int getTimesCrewedThisTurn() { return timesCrewedThisTurn; } From c7404192b31b54893da25b09d35ba585f23ff6d2 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 09:41:29 -0400 Subject: [PATCH 34/70] Card.changeCardState ensure card can Specialize before changing state --- forge-game/src/main/java/forge/game/card/Card.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index ee3776155ee..7c28c3e83d0 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -663,7 +663,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } } else if (mode.equals("Meld") && isMeldable()) { return changeToState(CardStateName.Meld); - } else if (mode.equals("Specialize")) { + } else if (mode.equals("Specialize") && canSpecialize()) { if (customState.equalsIgnoreCase("white")) { return changeToState(CardStateName.SpecializeW); } else if (customState.equalsIgnoreCase("blue")) { From afd193505ccb4bd33aecb52f5b5e5e719e3b7c82 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 09:41:47 -0400 Subject: [PATCH 35/70] Card.changeCardState support "Unspecialize" --- forge-game/src/main/java/forge/game/card/Card.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 7c28c3e83d0..df07ee7c763 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -676,6 +676,8 @@ public class Card extends GameEntity implements Comparable, IHasSVars { return changeToState(CardStateName.SpecializeG); } //do trigger here? + } else if (mode.equals("Unspecialize") && isSpecialized()) { + return changeToState(CardStateName.Original); } return false; } From b7d38c92faa051106f9e11eb52c4f19da3f8c4ff Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 09:42:20 -0400 Subject: [PATCH 36/70] CardFactory.copyCard copy Specialized boolean --- forge-game/src/main/java/forge/game/card/CardFactory.java | 1 + 1 file changed, 1 insertion(+) diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index fbde15700a4..29a8259d448 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -97,6 +97,7 @@ public class CardFactory { out.setAttachedCards(in.getAttachedCards()); out.setEntityAttachedTo(in.getEntityAttachedTo()); + out.setSpecialized(in.isSpecialized()); out.addRemembered(in.getRemembered()); out.addImprintedCards(in.getImprintedCards()); out.setCommander(in.isRealCommander()); From 3c6bb641e42a24d7b2a48d38cc0f9cfec137d509 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 09:43:26 -0400 Subject: [PATCH 37/70] CardFactoryUtil.addSpellAbility add additional fields/parsing to Specialize keyword --- .../src/main/java/forge/game/card/CardFactoryUtil.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index f1e4e33d444..d7167b476c2 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -3220,10 +3220,14 @@ public class CardFactoryUtil { } else if (keyword.startsWith("Specialize")) { final String[] k = keyword.split(":"); final String cost = k[1]; + String flavor = k.length > 2 && !k[2].isEmpty() ? k[2] + " – " : ""; + String extra = k.length > 3 && !k[3].isEmpty() ? k[3] + " | " : ""; final String effect = "AB$ SetState | Cost$ " + cost + " ChooseColor<1> Discard<1/Card.ChosenColor;" + "Card.AssociatedWithChosenColor/card of the chosen color or its associated basic land type> | " + - "Mode$ Specialize | SorcerySpeed$ True"; + "Mode$ Specialize | SorcerySpeed$ True | " + extra + "PrecostDesc$ " + flavor + "Specialize | " + + "CostDesc$ " + ManaCostParser.parse(cost) + " | SpellDescription$ (" + inst.getReminderText() + + ")"; final SpellAbility sa = AbilityFactory.getAbility(effect, card); sa.setIntrinsic(intrinsic); From 55c51be63cda22c172430c7ea57c2ba0511d1e21 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 09:43:38 -0400 Subject: [PATCH 38/70] lukamina_moon_druid.txt incomplete --- .../upcoming/lukamina_moon_druid.txt | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/lukamina_moon_druid.txt diff --git a/forge-gui/res/cardsfolder/upcoming/lukamina_moon_druid.txt b/forge-gui/res/cardsfolder/upcoming/lukamina_moon_druid.txt new file mode 100644 index 00000000000..9ba94426d29 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/lukamina_moon_druid.txt @@ -0,0 +1,76 @@ +Name:Lukamina, Moon Druid +ManaCost:2 G +Types:Legendary Creature Human Druid +PT:2/2 +K:Specialize:3:Wild Shape:Activate only if you control six or more lands.:IsPresent$ Land.YouCtrl | PresentCompare$ GE6 +T:Mode$ ChangesZone | ValidCard$ Card.wasCastByYou+Self | Destination$ Battlefield | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, if you cast it, seek a land card with a basic land type. +SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Land.hasABasicLandType | ChangeNum$ 1 +AlternateMode:Specialize +Oracle:Wild Shape — Specialize {3}. Activate only if you control six or more lands.\nWhen Lukamina, Moon Druid enters the battlefield, if you cast it, seek a land card with a basic land type. + +SPECIALIZE:WHITE + +Name:Lukamina, Hawk Form +ManaCost:2 G W +Types:Legendary Creature Bird Druid +PT:4/4 +K:Flying +K:Lifelink +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigUnspecialize | TriggerDescription$ When CARDNAME dies, it unspecializes. If it unspecializes this way, return it to the battlefield tapped. +SVar:TrigUnspecialize:DB$ SetState | Mode$ Unspecialize | RememberChanged$ True | SubAbility$ DBReturn +SVar:DBReturn:DB$ ChangeZone | ConditionDefined$ Remembered | ConditionPresent$ Card | Origin$ Graveyard | Destination$ Battlefield | Tapped$ True | Defined$ Remembered +DeckHas:Ability$LifeGain +Oracle:Flying, lifelink\nWhen Lukamina, Hawk Form dies, it unspecializes. If it unspecializes this way, return it to the battlefield tapped. + +SPECIALIZE:BLUE + +Name:Lukamina, Crocodile Form +ManaCost:2 G U +Types:Legendary Creature Crocodile Druid +PT:4/4 +#Needs specialize trigger +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigUnspecialize | TriggerDescription$ When NICKNAME dies, it unspecializes. If it unspecializes this way, return it to the battlefield tapped. +SVar:TrigUnspecialize:DB$ SetState | Defined$ TriggeredCard | Mode$ Unspecialize | RememberChanged$ True | SubAbility$ DBReturn +SVar:DBReturn:DB$ ChangeZone | ConditionDefined$ Remembered | ConditionPresent$ Card | Origin$ Graveyard | Destination$ Battlefield | Tapped$ True | Defined$ Remembered +Oracle:When this creature specializes, tap target nonland permanent an opponent controls. That permanent doesn't untap during its controller's untap step for as long as you control Lukamina, Crocodile Form.\nWhen Lukamina dies, it unspecializes. If it unspecializes this way, return it to the battlefield tapped. + +SPECIALIZE:BLACK + +Name:Lukamina, Scorpion Form +ManaCost:2 B G +Types:Legendary Creature Scorpion Druid +PT:4/4 +K:Deathtouch +K:CARDNAME must be blocked if able. +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigUnspecialize | TriggerDescription$ When NICKNAME dies, it unspecializes. If it unspecializes this way, return it to the battlefield tapped. +SVar:TrigUnspecialize:DB$ SetState | Defined$ TriggeredCard | Mode$ Unspecialize | RememberChanged$ True | SubAbility$ DBReturn +SVar:DBReturn:DB$ ChangeZone | ConditionDefined$ Remembered | ConditionPresent$ Card | Origin$ Graveyard | Destination$ Battlefield | Tapped$ True | Defined$ Remembered +Oracle:Deathtouch\nLukamina, Scorpion Form must be blocked if able.\nWhen Lukamina dies, it unspecializes. If it unspecializes this way, return it to the battlefield tapped. + +SPECIALIZE:RED + +Name:Lukamina, Wolf Form +ManaCost:2 R G +Types:Legendary Creature Wolf Druid +PT:4/4 +K:Menace +#Needs specialize trigger - then make attacks trigger secondary +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ Whenever this creature specializes or attacks, create a 2/2 green Wolf creature token. +SVar:TrigToken:DB$ Token | TokenScript$ g_2_2_wolf +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigUnspecialize | TriggerDescription$ When NICKNAME dies, it unspecializes. If it unspecializes this way, return it to the battlefield tapped. +SVar:TrigUnspecialize:DB$ SetState | Defined$ TriggeredCard | Mode$ Unspecialize | RememberChanged$ True | SubAbility$ DBReturn +SVar:DBReturn:DB$ ChangeZone | ConditionDefined$ Remembered | ConditionPresent$ Card | Origin$ Graveyard | Destination$ Battlefield | Tapped$ True | Defined$ Remembered +DeckHas:Ability$Token +Oracle:Menace\nWhenever this creature specializes or attacks, create a 2/2 green Wolf creature token.\nWhen Lukamina, Wolf Form dies, it unspecializes. If it unspecializes this way, return it to the battlefield tapped. + +SPECIALIZE:GREEN + +Name:Lukamina, Bear Form +ManaCost:2 G G +Types:Legendary Creature Bear Druid +K:Trample +S:Mode$ Continuous | Affected$ Creature.YouCtrl+Other | AddPower$ 1 | AddToughness$ 1 | AddKeyword$ Trample | Description$ Other creatures you control get +1/+1 and have trample. +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigUnspecialize | TriggerDescription$ When CARDNAME dies, it unspecializes. If it unspecializes this way, return it to the battlefield tapped. +SVar:TrigUnspecialize:DB$ SetState | Defined$ TriggeredCard | Mode$ Unspecialize | RememberChanged$ True | SubAbility$ DBReturn +SVar:DBReturn:DB$ ChangeZone | ConditionDefined$ Remembered | ConditionPresent$ Card | Origin$ Graveyard | Destination$ Battlefield | Tapped$ True | Defined$ Remembered +Oracle:Trample\nOther creatures you control get +1/+1 and have trample.\nWhen Lukamina, Bear Form dies, it unspecializes. If it unspecializes this way, return it to the battlefield tapped. From 747c964f59290638bfd97703dde1cf2933715011 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 09:44:12 -0400 Subject: [PATCH 39/70] SetStateEffect.resolve setSpecialized as appropriate --- .../main/java/forge/game/ability/effects/SetStateEffect.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java index c6e8445a96b..29b4d27bd84 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java @@ -203,6 +203,11 @@ public class SetStateEffect extends SpellAbilityEffect { } if (!gameCard.isDoubleFaced()) transformedCards.add(gameCard); + if ("Specialize".equals(mode)) { + gameCard.setSpecialized(true); + } else if ("Unspecialize".equals(mode)) { + gameCard.setSpecialized(false); + } } } table.replaceCounterEffect(game, sa, true); From 5f4c4067e99295a308ef5a8c1107f5200e8912d6 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 09:46:40 -0400 Subject: [PATCH 40/70] GameAction.changeZone avoid resetting state if Specialized --- forge-game/src/main/java/forge/game/GameAction.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 76e000ca8e5..433ae194876 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -608,6 +608,10 @@ public class GameAction { if (c.hasIntensity()) { copied.setIntensity(c.getIntensity(false)); } + // specialize is perpetual + if (c.isSpecialized()) { + copied.setState(c.getCurrentStateName(), false); + } // update state for view copied.updateStateForView(); @@ -688,7 +692,7 @@ public class GameAction { } if (fromBattlefield) { - if (!c.isRealToken()) { + if (!c.isRealToken() && !c.isSpecialized()) { copied.setState(CardStateName.Original, true); } // Soulbond unpairing From 0298d0da9e8d1f554c336dc0fa39f0d55b85df2f Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 11:11:29 -0400 Subject: [PATCH 41/70] SetStateEffect.resolve allow Unspecialize in any zone --- .../main/java/forge/game/ability/effects/SetStateEffect.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java index 29b4d27bd84..94444deb53e 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java @@ -94,7 +94,9 @@ public class SetStateEffect extends SpellAbilityEffect { // Cards which are not on the battlefield should not be able to transform. // TurnFace should be allowed in other zones like Exile too - if (!"TurnFace".equals(mode) && !gameCard.isInPlay() && !sa.hasParam("ETB")) { + // Unspecialize is allowed in other zones + if (!"TurnFace".equals(mode) && !"Unspecialize".equals(mode) && !gameCard.isInPlay() + && !sa.hasParam("ETB")) { continue; } From 7e289012a9abb2c8bee50b0426ebd92ad40ba19c Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 11:13:45 -0400 Subject: [PATCH 42/70] KeywordWithCost.cost avoid bad cost parse for complicated keywords --- .../src/main/java/forge/game/keyword/KeywordWithCost.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/keyword/KeywordWithCost.java b/forge-game/src/main/java/forge/game/keyword/KeywordWithCost.java index 98f83a95879..5d6c642cd46 100644 --- a/forge-game/src/main/java/forge/game/keyword/KeywordWithCost.java +++ b/forge-game/src/main/java/forge/game/keyword/KeywordWithCost.java @@ -7,7 +7,8 @@ public class KeywordWithCost extends KeywordInstance { @Override protected void parse(String details) { - cost = new Cost(details.split("\\|", 2)[0].trim(), false); + String[] allDetails = details.split(":"); + cost = new Cost(allDetails[0].split("\\|", 2)[0].trim(), false); } @Override From 3c35381a6a84f90c500ccc0eea3c855d19a5ddd4 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 11:23:44 -0400 Subject: [PATCH 43/70] Card.keywordsToText add "Specialize" to don't parse list --- forge-game/src/main/java/forge/game/card/Card.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index df07ee7c763..626ba22a44d 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -2238,7 +2238,8 @@ public class Card extends GameEntity implements Comparable, IHasSVars { || keyword.startsWith("Transfigure") || keyword.startsWith("Aura swap") || keyword.startsWith("Cycling") || keyword.startsWith("TypeCycling") || keyword.startsWith("Encore") || keyword.startsWith("Mutate") || keyword.startsWith("Dungeon") - || keyword.startsWith("Class") || keyword.startsWith("Blitz")) { + || keyword.startsWith("Class") || keyword.startsWith("Blitz") + || keyword.startsWith("Specialize")) { // keyword parsing takes care of adding a proper description } else if (keyword.equals("Unblockable")) { sbLong.append(getName()).append(" can't be blocked.\r\n"); From 3e19ff2c483fdaf232be91488258febea1e21e72 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 11:24:26 -0400 Subject: [PATCH 44/70] CardFactoryUtil support condition detail for Specialize --- .../src/main/java/forge/game/card/CardFactoryUtil.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index d7167b476c2..7434da24508 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -3221,13 +3221,14 @@ public class CardFactoryUtil { final String[] k = keyword.split(":"); final String cost = k[1]; String flavor = k.length > 2 && !k[2].isEmpty() ? k[2] + " – " : ""; - String extra = k.length > 3 && !k[3].isEmpty() ? k[3] + " | " : ""; + String condition = k.length > 3 && !k[3].isEmpty() ? ". " + k[3] : ""; + String extra = k.length > 4 && !k[4].isEmpty() ? k[4] + " | " : ""; final String effect = "AB$ SetState | Cost$ " + cost + " ChooseColor<1> Discard<1/Card.ChosenColor;" + "Card.AssociatedWithChosenColor/card of the chosen color or its associated basic land type> | " + "Mode$ Specialize | SorcerySpeed$ True | " + extra + "PrecostDesc$ " + flavor + "Specialize | " + - "CostDesc$ " + ManaCostParser.parse(cost) + " | SpellDescription$ (" + inst.getReminderText() + - ")"; + "CostDesc$ " + ManaCostParser.parse(cost) + condition + " | SpellDescription$ (" + + inst.getReminderText() + ")"; final SpellAbility sa = AbilityFactory.getAbility(effect, card); sa.setIntrinsic(intrinsic); From e466400745de7a181bc15ebdca0d0d3f9aeab947 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 11:29:05 -0400 Subject: [PATCH 45/70] Card.keywordsToText remove "Specialize" from bad list --- forge-game/src/main/java/forge/game/card/Card.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 626ba22a44d..e6af90692f7 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -2027,7 +2027,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } else if (keyword.startsWith("Morph") || keyword.startsWith("Megamorph") || keyword.startsWith("Escape") || keyword.startsWith("Foretell:") || keyword.startsWith("Disturb") || keyword.startsWith("Madness:") - || keyword.startsWith("Reconfigure") || keyword.startsWith("Specialize")) { + || keyword.startsWith("Reconfigure")) { String[] k = keyword.split(":"); sbLong.append(k[0]); if (k.length > 1) { From 815f3c2493fff899db45ada886787d031b91f316 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 18 Aug 2022 12:18:34 -0400 Subject: [PATCH 46/70] Card.getFaceupCardStateName handle Specialized --- forge-game/src/main/java/forge/game/card/Card.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index e6af90692f7..3335dda1814 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -3998,6 +3998,8 @@ public class Card extends GameEntity implements Comparable, IHasSVars { public final CardStateName getFaceupCardStateName() { if (isFlipped() && hasState(CardStateName.Flipped)) { return CardStateName.Flipped; + } else if (isSpecialized()) { + return getCurrentStateName(); } else if (backside && hasBackSide()) { CardStateName stateName = getRules().getSplitType().getChangedStateName(); if (hasState(stateName)) { From 708934a7a6baf9bacf2692d13c89a6fab56e9fd7 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Fri, 19 Aug 2022 11:23:41 -0400 Subject: [PATCH 47/70] lblSpecialized for TriggerSpecializes --- 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/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 ++ 7 files changed, 14 insertions(+) diff --git a/forge-gui/res/languages/de-DE.properties b/forge-gui/res/languages/de-DE.properties index 1fb9b3368eb..61c024a14e0 100644 --- a/forge-gui/res/languages/de-DE.properties +++ b/forge-gui/res/languages/de-DE.properties @@ -1601,6 +1601,8 @@ lblScryer=Hellsicht angewendet lblSearcher=hat gesucht #TriggerShuffled.java lblShuffler=hat gemischt +#TriggerSpecializes.java +lblSpecialized=Specialized #TriggerSpellAbilityCast.java lblActivator=hat aktiviert #TriggerSpellAbilityCast.java diff --git a/forge-gui/res/languages/en-US.properties b/forge-gui/res/languages/en-US.properties index 20ecfe6fe61..418ea0c7a31 100644 --- a/forge-gui/res/languages/en-US.properties +++ b/forge-gui/res/languages/en-US.properties @@ -1601,6 +1601,8 @@ lblScryer=Scryer lblSearcher=Searcher #TriggerShuffled.java lblShuffler=Shuffler +#TriggerSpecializes.java +lblSpecialized=Specialized #TriggerSpellAbilityCast.java lblActivator=Activator #TriggerSpellAbilityCast.java diff --git a/forge-gui/res/languages/es-ES.properties b/forge-gui/res/languages/es-ES.properties index cfe54f6ef24..6d276328b86 100644 --- a/forge-gui/res/languages/es-ES.properties +++ b/forge-gui/res/languages/es-ES.properties @@ -1601,6 +1601,8 @@ lblScryer=Escrutador lblSearcher=Buscador #TriggerShuffled.java lblShuffler=Barajeador +#TriggerSpecializes.java +lblSpecialized=Specialized #TriggerSpellAbilityCast.java lblActivator=Activador #TriggerSpellAbilityCast.java diff --git a/forge-gui/res/languages/it-IT.properties b/forge-gui/res/languages/it-IT.properties index ec41fa235de..e8e0a4838f8 100644 --- a/forge-gui/res/languages/it-IT.properties +++ b/forge-gui/res/languages/it-IT.properties @@ -1599,6 +1599,8 @@ lblScryer=Giocatore che profetizza lblSearcher=Giocatore che passa in rassegna il grimorio #TriggerShuffled.java lblShuffler=Giocatore che mescola +#TriggerSpecializes.java +lblSpecialized=Specialized #TriggerSpellAbilityCast.java lblActivator=Attivatore #TriggerSpellAbilityCast.java diff --git a/forge-gui/res/languages/ja-JP.properties b/forge-gui/res/languages/ja-JP.properties index 66a13db3fa8..4615c61800a 100644 --- a/forge-gui/res/languages/ja-JP.properties +++ b/forge-gui/res/languages/ja-JP.properties @@ -1600,6 +1600,8 @@ lblScryer=占術プレイヤー lblSearcher=探したプレイヤー #TriggerShuffled.java lblShuffler=シャッフルしたプレイヤー +#TriggerSpecializes.java +lblSpecialized=Specialized #TriggerSpellAbilityCast.java lblActivator=起動者 #TriggerSpellAbilityCast.java diff --git a/forge-gui/res/languages/pt-BR.properties b/forge-gui/res/languages/pt-BR.properties index 6fe8946637b..bc6a529ee73 100644 --- a/forge-gui/res/languages/pt-BR.properties +++ b/forge-gui/res/languages/pt-BR.properties @@ -1635,6 +1635,8 @@ lblScryer=Vidente lblSearcher=Buscador #TriggerShuffled.java lblShuffler=Embaralhador +#TriggerSpecializes.java +lblSpecialized=Specialized #TriggerSpellAbilityCast.java lblActivator=Ativador #TriggerSpellAbilityCast.java diff --git a/forge-gui/res/languages/zh-CN.properties b/forge-gui/res/languages/zh-CN.properties index 6f7c6f70e1f..8e5b4c654f3 100644 --- a/forge-gui/res/languages/zh-CN.properties +++ b/forge-gui/res/languages/zh-CN.properties @@ -1602,6 +1602,8 @@ lblScryer=占卜者 lblSearcher=搜寻者 #TriggerShuffled.java lblShuffler=洗牌者 +#TriggerSpecializes.java +lblSpecialized=Specialized #TriggerSpellAbilityCast.java lblActivator=起动自 #TriggerSpellAbilityCast.java From 3333038a99c901847d86ff7d46f40d25a11feafe Mon Sep 17 00:00:00 2001 From: Northmoc Date: Fri, 19 Aug 2022 11:24:22 -0400 Subject: [PATCH 48/70] Card.changeCardState remove unneeded note --- forge-game/src/main/java/forge/game/card/Card.java | 1 - 1 file changed, 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 3335dda1814..d572e536935 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -675,7 +675,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } else if (customState.equalsIgnoreCase("green")) { return changeToState(CardStateName.SpecializeG); } - //do trigger here? } else if (mode.equals("Unspecialize") && isSpecialized()) { return changeToState(CardStateName.Original); } From cb978890bf1d834053f42a2e2f065b76a30ae2e5 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Fri, 19 Aug 2022 11:30:12 -0400 Subject: [PATCH 49/70] lukamina_moon_druid.txt add Specializes trigger --- .../res/cardsfolder/upcoming/lukamina_moon_druid.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/forge-gui/res/cardsfolder/upcoming/lukamina_moon_druid.txt b/forge-gui/res/cardsfolder/upcoming/lukamina_moon_druid.txt index 9ba94426d29..77b78cd62d7 100644 --- a/forge-gui/res/cardsfolder/upcoming/lukamina_moon_druid.txt +++ b/forge-gui/res/cardsfolder/upcoming/lukamina_moon_druid.txt @@ -28,7 +28,9 @@ Name:Lukamina, Crocodile Form ManaCost:2 G U Types:Legendary Creature Crocodile Druid PT:4/4 -#Needs specialize trigger +T:Mode$ Specializes | ValidCard$ Card.Self | Execute$ TrigTap | TriggerDescription$ When this creature specializes, tap target nonland permanent an opponent controls. That permanent doesn't untap during its controller's untap step for as long as you control CARDNAME. +SVar:TrigTap:DB$ Tap | ValidTgts$ Permanent.nonLand+OppCtrl | TgtPrompt$ Select target nonland permanent an opponent controls | SubAbility$ DBPump +SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ HIDDEN CARDNAME doesn't untap during your untap step. | Duration$ UntilLoseControlOfHost T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigUnspecialize | TriggerDescription$ When NICKNAME dies, it unspecializes. If it unspecializes this way, return it to the battlefield tapped. SVar:TrigUnspecialize:DB$ SetState | Defined$ TriggeredCard | Mode$ Unspecialize | RememberChanged$ True | SubAbility$ DBReturn SVar:DBReturn:DB$ ChangeZone | ConditionDefined$ Remembered | ConditionPresent$ Card | Origin$ Graveyard | Destination$ Battlefield | Tapped$ True | Defined$ Remembered @@ -54,8 +56,8 @@ ManaCost:2 R G Types:Legendary Creature Wolf Druid PT:4/4 K:Menace -#Needs specialize trigger - then make attacks trigger secondary -T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ Whenever this creature specializes or attacks, create a 2/2 green Wolf creature token. +T:Mode$ Specializes | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When this creature specializes or attacks, create a 2/2 green Wolf creature token. +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigToken | Secondary$ True | TriggerDescription$ Whenever this creature specializes or attacks, create a 2/2 green Wolf creature token. SVar:TrigToken:DB$ Token | TokenScript$ g_2_2_wolf T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigUnspecialize | TriggerDescription$ When NICKNAME dies, it unspecializes. If it unspecializes this way, return it to the battlefield tapped. SVar:TrigUnspecialize:DB$ SetState | Defined$ TriggeredCard | Mode$ Unspecialize | RememberChanged$ True | SubAbility$ DBReturn From 4335fce675744f8cab21ac4b7e9b444b4ece53b4 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Fri, 19 Aug 2022 11:30:22 -0400 Subject: [PATCH 50/70] karlach_raging_tiefling.txt --- .../upcoming/karlach_raging_tiefling.txt | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/karlach_raging_tiefling.txt diff --git a/forge-gui/res/cardsfolder/upcoming/karlach_raging_tiefling.txt b/forge-gui/res/cardsfolder/upcoming/karlach_raging_tiefling.txt new file mode 100644 index 00000000000..89d94a2cd6f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/karlach_raging_tiefling.txt @@ -0,0 +1,96 @@ +Name:Karlach, Raging Tiefling +ManaCost:1 R +Types:Legendary Creature Tiefling Barbarian +PT:2/2 +K:First strike +K:Specialize:6:Rage Beyond Death:You may also activate this ability if CARDNAME is in your graveyard.:AdditionalActivationZone$ Graveyard +AlternateMode:Specialize +DeckHas:Ability$Graveyard +Oracle:First strike\nRage Beyond Death — Specialize {6}. You may also activate this ability if Karlach, Raging Tiefling is in your graveyard. + +SPECIALIZE:WHITE + +Name:Karlach, Tiefling Zealot +ManaCost:1 R W +Types:Legendary Creature Tiefling Barbarian +PT:4/4 +K:First strike +K:Haste +T:Mode$ Specializes | ValidCard$ Card.Self | TriggerZones$ Graveyard | Execute$ TrigReturn | TriggerDescription$ When this card specializes from your graveyard, return it from your graveyard to the battlefield. It perpetually gains "This creature can't block." +SVar:TrigReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Defined$ TriggeredCard | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ TriggeredCard | StaticAbilities$ PerpetualStatic | Duration$ Permanent +SVar:PerpetualStatic:Mode$ Continuous | Affected$ Card.IsRemembered | AddKeyword$ CARDNAME can't block. | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ It perpetually gains "This creature can't block." +T:Mode$ Specializes | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When this card specializes from any zone, create a 2/2 white Knight creature token. Creatures you control get +1/+1 and gain haste until end of turn. +SVar:TrigToken:DB$ Token | TokenScript$ w_2_2_knight | SubAbility$ DBPumpAll +SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Creature.YouCtrl | NumAtt$ +1 | NumDef$ +1 | KW$ Haste +DeckHas:Ability$Token & Type$Knight +Oracle:First strike, haste\nWhen this card specializes from your graveyard, return it from your graveyard to the battlefield. It perpetually gains "This creature can't block."\nWhen this card specializes from any zone, create a 2/2 white Knight creature token. Creatures you control get +1/+1 and gain haste until end of turn. + +SPECIALIZE:BLUE + +Name:Karlach, Tiefling Spellrager +ManaCost:1 U R +Types:Legendary Creature Tiefling Barbarian +PT:4/4 +K:First strike +K:Haste +T:Mode$ Specializes | ValidCard$ Card.Self | TriggerZones$ Graveyard | Execute$ TrigReturn | TriggerDescription$ When this card specializes from your graveyard, return it from your graveyard to the battlefield. It perpetually gains "This creature can't block." +SVar:TrigReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Defined$ TriggeredCard | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ TriggeredCard | StaticAbilities$ PerpetualStatic | Duration$ Permanent +SVar:PerpetualStatic:Mode$ Continuous | Affected$ Card.IsRemembered | AddKeyword$ CARDNAME can't block. | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ It perpetually gains "This creature can't block." +T:Mode$ Specializes | ValidCard$ Card.Self | Execute$ TrigSeek | TriggerDescription$ When this card specializes from any zone, seek an instant or sorcery card with mana value 3 or less. Until end of turn, you may cast that card without paying its mana cost. +SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | NoLooking$ True | NoReveal$ True | ChangeNum$ 1 | ChangeType$ Instant.cmcLE3,Sorcery.cmcLE3 | RememberChanged$ True +SVar:DBEffect:DB$ Effect | StaticAbilities$ MayPlay | RememberObjects$ Remembered | ForgetOnMoved$ Hand | SubAbility$ DBCleanup +SVar:MayPlay:Mode$ Continuous | Affected$ Card.IsRemembered+nonLand | MayPlayWithoutManaCost$ True | EffectZone$ Command | AffectedZone$ Hand +DeckHints:Type$Instant|Sorcery +Oracle:First strike, haste\nWhen this card specializes from your graveyard, return it from your graveyard to the battlefield. It perpetually gains "This creature can't block."\nWhen this card specializes from any zone, seek an instant or sorcery card with mana value 3 or less. Until end of turn, you may cast that card without paying its mana cost. + +SPECIALIZE:BLACK + +Name:Karlach, Tiefling Punisher +ManaCost:1 B R +Types:Legendary Creature Tiefling Barbarian +PT:4/4 +K:First strike +K:Haste +T:Mode$ Specializes | ValidCard$ Card.Self | TriggerZones$ Graveyard | Execute$ TrigReturn | TriggerDescription$ When this card specializes from your graveyard, return it from your graveyard to the battlefield. It perpetually gains "This creature can't block." +SVar:TrigReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Defined$ TriggeredCard | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ TriggeredCard | StaticAbilities$ PerpetualStatic | Duration$ Permanent +SVar:PerpetualStatic:Mode$ Continuous | Affected$ Card.IsRemembered | AddKeyword$ CARDNAME can't block. | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ It perpetually gains "This creature can't block." +T:Mode$ Specializes | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When this card specializes from any zone, you may sacrifice a creature. If you do, you draw two cards and each opponent loses 2 life. +SVar:TrigDraw:AB$ Draw | Cost$ Sac<1/Creature> | NumCards$ 2 | SubAbility$ DBLoseLife +SVar:DBLoseLife:DB$ LoseLife | Defined$ Opponent | LifeAmount$ 2 +DeckHas:Ability$Sacrifice +Oracle:First strike, haste\nWhen this card specializes from your graveyard, return it from your graveyard to the battlefield. It perpetually gains "This creature can't block."\nWhen this card specializes from any zone, you may sacrifice a creature. If you do, you draw two cards and each opponent loses 2 life. + +SPECIALIZE:RED + +Name:Karlach, Tiefling Berserker +ManaCost:1 R R +Types:Legendary Creature Tiefling Barbarian +PT:4/4 +K:First strike +K:Haste +T:Mode$ Specializes | ValidCard$ Card.Self | TriggerZones$ Graveyard | Execute$ TrigReturn | TriggerDescription$ When this card specializes from your graveyard, return it from your graveyard to the battlefield. It perpetually gains "This creature can't block." +SVar:TrigReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Defined$ TriggeredCard | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ TriggeredCard | StaticAbilities$ PerpetualStatic | Duration$ Permanent +SVar:PerpetualStatic:Mode$ Continuous | Affected$ Card.IsRemembered | AddKeyword$ CARDNAME can't block. | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ It perpetually gains "This creature can't block." +T:Mode$ Specializes | ValidCard$ Card.Self | Execute$ TrigPump | TriggerDescription$ When this card specializes from any zone, target creature an opponent controls can't block this turn. +SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.OppCtrl | KW$ HIDDEN CARDNAME can't block. | TgtPrompt$ Select target creature an opponent controls | IsCurse$ True +Oracle:First strike, haste\nWhen this card specializes from your graveyard, return it from your graveyard to the battlefield. It perpetually gains "This creature can't block."\nWhen this card specializes from any zone, target creature an opponent controls can't block this turn. + +SPECIALIZE:GREEN + +Name:Karlach, Tiefling Guardian +ManaCost:1 R G +Types:Legendary Creature Tiefling Barbarian +PT:4/4 +K:First strike +K:Haste +T:Mode$ Specializes | ValidCard$ Card.Self | TriggerZones$ Graveyard | Execute$ TrigReturn | TriggerDescription$ When this card specializes from your graveyard, return it from your graveyard to the battlefield. It perpetually gains "This creature can't block." +SVar:TrigReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Defined$ TriggeredCard | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ TriggeredCard | StaticAbilities$ PerpetualStatic | Duration$ Permanent +SVar:PerpetualStatic:Mode$ Continuous | Affected$ Card.IsRemembered | AddKeyword$ CARDNAME can't block. | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ It perpetually gains "This creature can't block." +T:Mode$ Specializes | ValidCard$ Card.Self | Execute$ TrigPump | TriggerDescription$ When this card specializes from any zone, another target creature you control gets +4/+4 until end of turn. +SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.Other+YouCtrl | TgtPrompt$ Select another target creature you control | NumAtt$ +4 | NumDef$ +4 +Oracle:First strike, haste\nWhen this card specializes from your graveyard, return it from your graveyard to the battlefield. It perpetually gains "This creature can't block."\nWhen this card specializes from any zone, another target creature you control gets +4/+4 until end of turn. From 6538cf795ed16f9e336ed30555b5e2f2a31e91c1 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Fri, 19 Aug 2022 11:31:18 -0400 Subject: [PATCH 51/70] SetStateEffect.resolve allow Specialize in other zones --- .../java/forge/game/ability/effects/SetStateEffect.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java index 94444deb53e..3a67a401114 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java @@ -94,9 +94,9 @@ public class SetStateEffect extends SpellAbilityEffect { // Cards which are not on the battlefield should not be able to transform. // TurnFace should be allowed in other zones like Exile too - // Unspecialize is allowed in other zones - if (!"TurnFace".equals(mode) && !"Unspecialize".equals(mode) && !gameCard.isInPlay() - && !sa.hasParam("ETB")) { + // Specialize and Unspecialize are allowed in other zones + if (!"TurnFace".equals(mode) && !"Unspecialize".equals(mode) && !"Specialize".equals(mode) + && !gameCard.isInPlay() && !sa.hasParam("ETB")) { continue; } From fcb567f3f54fbcf5d1e2fd2f50daae550c22a074 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Fri, 19 Aug 2022 11:31:38 -0400 Subject: [PATCH 52/70] SetStateEffect.resolve run TriggerSpecializes --- .../forge/game/ability/effects/SetStateEffect.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java index 3a67a401114..da458252bbb 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java @@ -4,12 +4,15 @@ import forge.card.CardStateName; import forge.game.Game; import forge.game.GameEntityCounterTable; import forge.game.GameLogEntryType; +import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; import forge.game.card.*; import forge.game.event.GameEventCardStatsChanged; import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; +import forge.game.trigger.TriggerHandler; +import forge.game.trigger.TriggerType; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; import forge.util.Lang; @@ -17,6 +20,8 @@ import forge.util.Localizer; import forge.util.TextUtil; import org.apache.commons.lang3.StringUtils; +import java.util.Map; + public class SetStateEffect extends SpellAbilityEffect { @Override @@ -207,6 +212,12 @@ public class SetStateEffect extends SpellAbilityEffect { transformedCards.add(gameCard); if ("Specialize".equals(mode)) { gameCard.setSpecialized(true); + //run Specializes trigger + final TriggerHandler th = game.getTriggerHandler(); + th.clearActiveTriggers(gameCard, null); + th.registerActiveTrigger(gameCard, false); + final Map runParams = AbilityKey.mapFromCard(gameCard); + th.runTrigger(TriggerType.Specializes, runParams, false); } else if ("Unspecialize".equals(mode)) { gameCard.setSpecialized(false); } From 0b0722f5f1df4d660f879be7e28fa0b37f68403a Mon Sep 17 00:00:00 2001 From: Northmoc Date: Fri, 19 Aug 2022 11:31:51 -0400 Subject: [PATCH 53/70] TriggerType.Specializes --- forge-game/src/main/java/forge/game/trigger/TriggerType.java | 1 + 1 file changed, 1 insertion(+) 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 2490cb3b9aa..70250039a72 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerType.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerType.java @@ -102,6 +102,7 @@ public enum TriggerType { SearchedLibrary(TriggerSearchedLibrary.class), SetInMotion(TriggerSetInMotion.class), Shuffled(TriggerShuffled.class), + Specializes(TriggerSpecializes.class), SpellAbilityCast(TriggerSpellAbilityCastOrCopy.class), SpellAbilityCopy(TriggerSpellAbilityCastOrCopy.class), SpellCast(TriggerSpellAbilityCastOrCopy.class), From 2979f2ea874ae51adf290d81f12a0a251cc48c8e Mon Sep 17 00:00:00 2001 From: Northmoc Date: Fri, 19 Aug 2022 11:32:10 -0400 Subject: [PATCH 54/70] TriggerSpecializes.java --- .../game/trigger/TriggerSpecializes.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 forge-game/src/main/java/forge/game/trigger/TriggerSpecializes.java diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerSpecializes.java b/forge-game/src/main/java/forge/game/trigger/TriggerSpecializes.java new file mode 100644 index 00000000000..067bbc6c004 --- /dev/null +++ b/forge-game/src/main/java/forge/game/trigger/TriggerSpecializes.java @@ -0,0 +1,73 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 Forge Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +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; + +/** + *

+ * TriggerSpecializes class. + *

+ */ +public class TriggerSpecializes extends Trigger { + + /** + *

+ * Constructor for TriggerSpecializes + *

+ * + * @param params + * a {@link java.util.HashMap} object. + * @param host + * a {@link forge.game.card.Card} object. + * @param intrinsic + * the intrinsic + */ + public TriggerSpecializes (Map params, final Card host, final boolean intrinsic) { + super(params, host, intrinsic); + } + + /** {@inheritDoc} + * @param runParams*/ + @Override + public final boolean performTest(Map runParams) { + if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Card))) { + return false; + } + return true; + } + + /** {@inheritDoc} */ + @Override + public final void setTriggeringObjects(final SpellAbility sa, Map runParams) { + sa.setTriggeringObjectsFrom(runParams, AbilityKey.Card); + } + + @Override + public String getImportantStackObjects(SpellAbility sa) { + StringBuilder sb = new StringBuilder(); + sb.append(Localizer.getInstance().getMessage("lblSpecialized")).append(": "); + sb.append(sa.getTriggeringObject(AbilityKey.Card)); + return sb.toString(); + } +} From 6b551e0852135798e1c99566791078a35b48c34a Mon Sep 17 00:00:00 2001 From: Northmoc Date: Fri, 19 Aug 2022 13:18:54 -0400 Subject: [PATCH 55/70] HumanCostDecision.visit(CostDiscard) handle corner case opened up by Specialize costs --- forge-gui/src/main/java/forge/player/HumanCostDecision.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/forge-gui/src/main/java/forge/player/HumanCostDecision.java b/forge-gui/src/main/java/forge/player/HumanCostDecision.java index 1ee72ae4699..b0d21c28d6b 100644 --- a/forge-gui/src/main/java/forge/player/HumanCostDecision.java +++ b/forge-gui/src/main/java/forge/player/HumanCostDecision.java @@ -174,6 +174,9 @@ public class HumanCostDecision extends CostDecisionMakerBase { final String type = discardType; final String[] validType = type.split(";"); hand = CardLists.getValidCards(hand, validType, player, source, ability); + if (hand.size() < 1) { // if we somehow have no valids (e.g. picked bad Specialize color), cancel payment + return null; + } final InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, c, c, hand, ability); inp.setMessage(Localizer.getInstance().getMessage("lblSelectNMoreTargetTypeCardToDiscard", "%d", cost.getDescriptiveType())); From e2e3b58deae98f2179683337ad66721f9c21f276 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Fri, 19 Aug 2022 13:19:17 -0400 Subject: [PATCH 56/70] CostChooseColor.isUndoable and CostChooseColor.refund --- .../main/java/forge/game/cost/CostChooseColor.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/forge-game/src/main/java/forge/game/cost/CostChooseColor.java b/forge-game/src/main/java/forge/game/cost/CostChooseColor.java index f50facff3da..0e07cbf9489 100644 --- a/forge-game/src/main/java/forge/game/cost/CostChooseColor.java +++ b/forge-game/src/main/java/forge/game/cost/CostChooseColor.java @@ -17,6 +17,7 @@ */ package forge.game.cost; +import forge.game.card.Card; import forge.game.player.Player; import forge.game.spellability.SpellAbility; @@ -75,6 +76,19 @@ public class CostChooseColor extends CostPart { return sb.toString(); } + @Override + public boolean isUndoable() { return true; } + + /* + * (non-Javadoc) + * + * @see forge.card.cost.CostPart#refund(forge.Card) + */ + @Override + public final void refund(final Card source) { + source.setChosenColors(null); + } + @Override public T accept(ICostVisitor visitor) { return visitor.visit(this); From d3acef97adbcb17679370c71927ffe93fbc46c6b Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 11 Aug 2022 11:43:04 -0400 Subject: [PATCH 57/70] racketeer_boss.txt (thanks Simisays) --- forge-gui/res/cardsfolder/r/racketeer_boss.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 forge-gui/res/cardsfolder/r/racketeer_boss.txt diff --git a/forge-gui/res/cardsfolder/r/racketeer_boss.txt b/forge-gui/res/cardsfolder/r/racketeer_boss.txt new file mode 100644 index 00000000000..f8b9c797710 --- /dev/null +++ b/forge-gui/res/cardsfolder/r/racketeer_boss.txt @@ -0,0 +1,14 @@ +Name:Racketeer Boss +ManaCost:R G +Types:Creature Cat Warrior +PT:3/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChoose | TriggerDescription$ When CARDNAME enters the battlefield, you may choose 2 creature and/or planeswalker cards in your hand. They perpetually gain "When you cast this spell, create a Treasure token and this spell perpetually loses this ability." +SVar:TrigChoose:DB$ ChooseCard | ChoiceZone$ Hand | Choices$ Creature.YouOwn,Planeswalker.YouOwn | ChoiceTitle$ Choose up to two creature and/or planeswalker cards in your hand. | MinAmount$ 0 | Amount$ 2 | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ ChosenCard | ForgetOnCast$ True | ConditionDefined$ ChosenCard | ConditionPresent$ Card | ConditionCompare$ GE1 | StaticAbilities$ PerpetualEffect | Name$ Racketeer Boss's Perpetual Effect | Duration$ Permanent | SubAbility$ DBCleanup +SVar:PerpetualEffect:Mode$ Continuous | Affected$ Card.IsRemembered | AddTrigger$ SpellCastTrig | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ When you cast this spell, create a Treasure token and this spell perpetually loses this ability. +SVar:SpellCastTrig:Mode$ SpellCast | ValidCard$ Card.Self | Execute$ TrigTreasure | TriggerDescription$ When you cast this spell, create a Treasure token and this spell perpetually loses this ability. +SVar:TrigTreasure:DB$ Token | TokenScript$ c_a_treasure_sac +SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True +DeckHints:Type$Planeswalker +DeckHas:Ability$Token|Sacrifice & Type$Treasure|Artifact +Oracle:When Racketeer Boss enters the battlefield, choose up to two creature and/or planeswalker cards in your hand. They perpetually gain "When you cast this spell, create a Treasure token and this spell perpetually loses this ability." From 979805c920bd047fef8b8cd85b5bdacf743492a7 Mon Sep 17 00:00:00 2001 From: Northmoc Date: Thu, 11 Aug 2022 11:43:42 -0400 Subject: [PATCH 58/70] EffectEffect.resolve support "ForgetOnCast" --- .../src/main/java/forge/game/ability/effects/EffectEffect.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java b/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java index 80b567426df..c4dbb589cdb 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java @@ -226,6 +226,8 @@ public class EffectEffect extends SpellAbilityEffect { if (!"Stack".equals(sa.getParam("ForgetOnMoved"))) { addForgetOnCastTrigger(eff); } + } else if (sa.hasParam("ForgetOnCast")) { + addForgetOnCastTrigger(eff); } else if (sa.hasParam("ExileOnMoved")) { addExileOnMovedTrigger(eff, sa.getParam("ExileOnMoved")); } From 34fa0de248f0ebe4213a306ddbb2b57e5bb1c126 Mon Sep 17 00:00:00 2001 From: paulsnoops Date: Fri, 26 Aug 2022 22:56:55 +0100 Subject: [PATCH 59/70] WIP: Final DMU & DMC edition lists --- .../editions/Dominaria United Commander.txt | 22 +++++++++++++++++++ forge-gui/res/editions/Dominaria United.txt | 10 +++++++++ 2 files changed, 32 insertions(+) diff --git a/forge-gui/res/editions/Dominaria United Commander.txt b/forge-gui/res/editions/Dominaria United Commander.txt index bc3578f5e0d..b1bae958665 100644 --- a/forge-gui/res/editions/Dominaria United Commander.txt +++ b/forge-gui/res/editions/Dominaria United Commander.txt @@ -202,5 +202,27 @@ ScryfallCode=DMC 240 R Tyrite Sanctum @Volkan Baǵa [tokens] +all_3_3_kavu_trample +b_1_1_insect_flying +b_2_2_zombie +b_2_2_zombie_knight_menace +c_a_treasure_sac +g_0_0_hydra +g_0_1_egg_defender +g_1_1_snake +g_2_2_bear +g_2_2_cat_warrior_forestwalk +g_3_3_badger +g_3_3_elephant +g_4_4_wurm +kobolds_of_kher_keep +ragavan rgw_1_1_sand_warrior stangg_twin +u_1_1_merfolk +w_1_1_human +w_1_1_warrior_vigilance +w_2_2_griffin_flying +w_2_2_knight_pro_red +w_2_2_knight_vigilance +w_4_4_angel_flying_vigilance diff --git a/forge-gui/res/editions/Dominaria United.txt b/forge-gui/res/editions/Dominaria United.txt index 4a06689afe7..8b6a4e10ca2 100644 --- a/forge-gui/res/editions/Dominaria United.txt +++ b/forge-gui/res/editions/Dominaria United.txt @@ -342,4 +342,14 @@ ScryfallCode=DMU [tokens] b_1_1_bird_flying_noblock +b_2_2_phyrexian +c_a_powerstone +g_1_1_saproling +g_3_3_beast +ornithopter +r_1_1_goblin r_1_1_monk_prowess +r_2_1_elemental_trample_haste +r_4_4_dragon_flying +w_1_1_bird_flying +w_1_1_soldier From 1ca077cc57b93cdc9e673749b8efaa87f3d171ae Mon Sep 17 00:00:00 2001 From: paulsnoops Date: Fri, 26 Aug 2022 23:53:27 +0100 Subject: [PATCH 60/70] add_all_but_two --- .../editions/Dominaria United Commander.txt | 46 ++++++++ forge-gui/res/editions/Dominaria United.txt | 103 ++++++++++++++++++ 2 files changed, 149 insertions(+) diff --git a/forge-gui/res/editions/Dominaria United Commander.txt b/forge-gui/res/editions/Dominaria United Commander.txt index b1bae958665..23264d7a64a 100644 --- a/forge-gui/res/editions/Dominaria United Commander.txt +++ b/forge-gui/res/editions/Dominaria United Commander.txt @@ -26,6 +26,14 @@ ScryfallCode=DMC 18 R Obsidian Obelisk @Andrew Mar 19 R The Peregrine Dynamo @Zoltan Boros 20 R Tiller Engine @Alexander Mokhov +21 R Historian's Boon @Irina Nordsol +22 R Robaran Mercenaries @Chuck Lukacs +23 R Emperor Mihail II @PINDURSKI +24 R Activated Sleeper @Mathias Kollros +25 R Rosnakht, Heir of Rohgahh @Chris Seaman +26 R Baru, Wurmspeaker @Andrew Mar +27 M Greensleeves, Maro-Sorcerer @Tuan Duong Chu +28 M The Mana Rig @Zoltan Boros 29 R Ayesha Tanaka, Armorer @Aurore Folny 30 R The Ever-Changing 'Dane @Campbell White 31 U General Marhault Elsdragon @Heonhwa Choe @@ -46,18 +54,54 @@ ScryfallCode=DMC 46 U Tor Wauki the Younger @Karl Kopinski 47 M Torsten, Founder of Benalia @Volkan Baǵa 48 R Xira, the Golden Sting @Mila Pesic + + 51 R Ayesha Tanaka, Armorer @Aurore Folny 52 R The Ever-Changing 'Dane @Campbell White +53 U General Marhault Elsdragon @Heonhwa Choe 54 R Hazezon, Shaper of Sand @Bryan Sola 55 U Jasmine Boreal of the Seven @Bastien L. Deharme 56 M Jedit Ojanen, Mercenary @Ilse Gort +57 M The Lady of Otaria @Scott Murphy +58 R Ohabi Caleria @Nestor Ossandon Leal +59 R Orca, Siege Demon @Daarken 60 U Ramirez DePietro, Pillager @Anna Steinbauer 61 R Ramses, Assassin Lord @Manuel Castañón +62 R Rasputin, the Oneiromancer @Matt Stewart +63 R Rohgahh, Kher Keep Overlord @Chris Seaman 64 R Stangg, Echo Warrior @Randy Vargas 65 M Sivitri, Dragon Master @Livia Prima 66 M Tetsuo, Imperial Champion @Lius Lasahido +67 U Tobias, Doomed Conqueror @Dmitry Burmak 68 U Tor Wauki the Younger @Karl Kopinski 69 M Torsten, Founder of Benalia @Volkan Baǵa +70 R Xira, the Golden Sting @Mila Pesic +71 R Historian's Boon @Irina Nordsol +72 R Robaran Mercenaries @Chuck Lukacs +73 R Emperor Mihail II @PINDURSKI +74 R Activated Sleeper @Mathias Kollros +75 R Rosnakht, Heir of Rohgahh @Chris Seaman +76 R Baru, Wurmspeaker @Andrew Mar +77 M Greensleeves, Maro-Sorcerer @Tuan Duong Chu +78 M Jenson Carthalion, Druid Exile @Livia Prima +79 M Shanid, Sleepers' Scourge @Ryan Pancoast +80 M The Mana Rig @Zoltan Boros +81 R Zeriam, Golden Wind @John Tedrick +82 R Moira, Urborg Haunt @Marta Nael +83 R Mana Cannons @Sidharth Chaturvedi +84 R The Reaver Cleaver @Yigit Koroglu +85 R Bladewing, Deathless Tyrant @Antonio José Manzanedo +86 R Cadric, Soul Kindler @Joseph Weston +87 R Fallaji Wayfarer @Victor Adame Minguez +88 R Iridian Maelstrom @Justyna Gil +89 R Primeval Spawn @Filip Burburan +90 R Two-Headed Hellkite @Fajareka Setiawan +91 R Unite the Coalition @Nestor Ossandon Leal +92 R Verrak, Warped Sengir @Alix Branwyn +93 R Gerrard's Hourglass Pendant @Sam Burley +94 R Obsidian Obelisk @Andrew Mar +95 R The Peregrine Dynamo @Zoltan Boros +96 R Tiller Engine @Alexander Mokhov 97 R Anafenza, Kin-Tree Spirit @Ryan Yee 98 M The Circle of Loyalty @Bastien L. Deharme 99 R Day of Destiny @Daren Bader @@ -115,6 +159,7 @@ ScryfallCode=DMC 151 U Garna, the Bloodflame @Winona Nelson 152 R Glint-Eye Nephilim @Mark Zug 153 C Growth Spiral @Seb McKinnon +154 M Illuna, Apex of Wishes @Chris Rahn 155 R Kaya's Wrath @Victor Adame Minguez 156 R Knight of New Alara @Chris Rahn 157 R Lavalanche @Steve Argyle @@ -170,6 +215,7 @@ ScryfallCode=DMC 207 R Dragonskull Summit @Alayna Danner 208 C Evolving Wilds @Steven Belledin 209 R Exotic Orchard @Steven Belledin +210 U Flood Plain @Pat Lewis 211 R Foreboding Ruins @Adam Paquette 212 U Frontier Bivouac @Titus Lunter 213 R Geier Reach Sanitarium @Cliff Childs diff --git a/forge-gui/res/editions/Dominaria United.txt b/forge-gui/res/editions/Dominaria United.txt index 8b6a4e10ca2..9bb37a77ed1 100644 --- a/forge-gui/res/editions/Dominaria United.txt +++ b/forge-gui/res/editions/Dominaria United.txt @@ -12,19 +12,30 @@ ScryfallCode=DMU 2 R Anointed Peacekeeper @Tia Masic 3 R Archangel of Wrath @Miguel Mercado 4 C Argivian Cavalier @Chris Seaman +5 C Argivian Phalanx @Josh Hass +6 C Artillery Blast @Julian Kok Joon Wen +7 C Benalish Faithbonder @Francisco Miyara 8 C Benalish Sleeper @Josu Hernaiz +9 C Captain's Call @A. M. Sartor 10 C Charismatic Vanguard @David Palumbo 11 C Citizen's Arrest @Wisnu Tan 12 U Cleaving Skyrider @Joshua Raphael +13 C Clockwork Drawbridge @Nadia Hurianova 14 U Coalition Skyknight @Aaron Miller 15 R Danitha, Benalia's Hope @Magali Villeneuve 16 R Defiler of Faith @Magali Villeneuve +17 C Destroy Evil @Anna Christenson +18 C Griffin Protector @Omar Rayyan 19 R Guardian of New Benalia @Ernanda Souza +20 C Heroic Charge @Paul Scott Canavan 21 U Join Forces @Aurore Folny 22 C Juniper Order Rootweaver @Matt Stewart 23 U Knight of Dawn's Light @Billy Christian 24 R Leyline Binding @Cristi Balanescu +25 U Love Song of Night and Day @Eli Minaya 26 C Mesa Cavalier @David Palumbo +27 U Phyrexian Missionary @Mila Pesic +28 U Prayer of Binding @Wylie Beckert 29 U Resolute Reinforcements @Billy Christian 30 U Runic Shot @Cristi Balanescu 31 C Samite Herbalist @Alessandra Pisano @@ -33,26 +44,39 @@ ScryfallCode=DMU 34 C Stall for Time @Ryan Alexander Lee 35 C Take Up the Shield @Manuel Castañón 36 R Temporary Lockdown @Bryan Sola +37 R Urza Assembles the Titans @Josu Hernaiz 38 R Valiant Veteran @Nestor Ossandon Leal 39 U Wingmantle Chaplain @Miranda Meeks +40 R Academy Loremaster @Marcela Medeiros 41 C Academy Wall @Adam Paquette +42 R Aether Channeler @Caio Monteiro 43 U Battlewing Mystic @Borja Pindado +44 U Combat Research @Justine Cruz 45 U Coral Colony @Campbell White 46 R Defiler of Dreams @Ryan Pancoast 47 U Djinn of the Fountain @Bastien L. Deharme +48 C Ertai's Scorn @Alex Negrea +49 C Essence Scatter @Anastasia Ovchinnikova 50 U Founding the Third Path @Chris Seaman 51 U Frostfist Strider @Francisco Miyara 52 R Haughty Djinn @Mike Jordana +53 C Haunting Figment @Chris Cold 54 C Impede Momentum @Igor Kieryluk +55 C Impulse @Sam Guay 56 U Joint Exploration @Zezhou Chen 57 U Micromancer @Ernanda Souza 58 C Negate @Isis 59 R The Phasing of Zhalfir @LA Draws 60 C Phyrexian Espionage @Allen Douglas +61 C Pixie Illusionist @Anastasia Ovchinnikova 62 U Protect the Negotiators @Dominik Mayer 63 U Rona's Vortex @Dominik Mayer +64 C Shore Up @Mark Behm 65 R Silver Scrutiny @Donato Giancola +66 C Soaring Drake @Jason Kang 67 M Sphinx of Clear Skies @Valera Lutfullina +68 C Talas Lookout @Julia Metzger +69 C Tidepool Turtle @Andrew Mar 70 C Timely Interference @Joshua Raphael 71 C Tolarian Geyser @Olivier Bernard 72 C Tolarian Terror @Vincent Christiaens @@ -61,24 +85,38 @@ ScryfallCode=DMU 75 R Vodalian Hexcatcher @Dmitry Burmak 76 R Vodalian Mindsinger @Steve Prescott 77 C Volshe Tideturner @Tia Masic +78 C Aggressive Sabotage @Daarken 79 U Balduvian Atrocity @Mike Jordana +80 C Battle-Rage Blessing @Jarel Threat +81 C Battlefly Swarm @Xavier Ribeiro 82 U Blight Pile @Olivier Bernard +83 C Bone Splinters @Jeremy Wilson 84 R Braids, Arisen Nightmare @Heonhwa Choe +85 U Braids's Frightful Return @Dominik Mayer +86 U Choking Miasma @Inka Schulz +87 R The Cruelty of Gix @Volkan Baǵa 88 U Cult Conscript @Joe Slucher 89 U Cut Down @Dominik Mayer 90 R Defiler of Flesh @Mathias Kollros 91 R Drag to the Bottom @Nino Is +92 C Eerie Soultender @Igor Kieryluk 93 R Evolved Sleeper @Jason A. Engle 94 C Extinguish the Light @Ekaterina Burmak +95 C Gibbering Barricade @Drew Tucker +96 U Knight of Dusk's Shadow @Wisnu Tan 97 M Liliana of the Veil @Martina Fackova 98 U Monstrous War-Leech @Christopher Burdett 99 C Phyrexian Rager @Brock Grossman +100 C Phyrexian Vivisector @Irina Nordsol 101 C Phyrexian Warhorse @Chris Cold 102 U Pilfer @Pauline Voss 103 R The Raven Man @Chris Rahn 104 U Sengir Connoisseur @Irina Nordsol +105 C Shadow Prophecy @Rovina Cai +106 R Shadow-Rite Priest @Michael C. Hayes 107 M Sheoldred, the Apocalypse @Chris Rahn 108 U Sheoldred's Restoration @Igor Kieryluk +109 C Splatter Goblin @Lars Grant-West 110 R Stronghold Arena @Alexander Mokhov 111 C Tattered Apparition @Jason A. Engle 112 C Toxic Abomination @Igor Kieryluk @@ -87,17 +125,27 @@ ScryfallCode=DMU 115 C Writhing Necromass @Campbell White 116 U Balduvian Berserker @Cristi Balanescu 117 R Chaotic Transformation @Joseph Meehan +118 C Coalition Warbrute @Will Gist 119 R Defiler of Instinct @Steven Belledin 120 U Dragon Whelp @Jokubas Uogintas 121 R The Elder Dragon War @Filip Burburan 122 U Electrostatic Infantry @Kekai Kotaki 123 U Fires of Victory @Sidharth Chaturvedi +124 C Flowstone Infusion @Allen Williams +125 C Flowstone Kavu @Simon Dominic +126 C Furious Bellow @Joshua Raphael +127 C Ghitu Amplifier @Deruchenko Alexander +128 C Goblin Picker @Vladimir Krisetskiy +129 C Hammerhand @Joshua Raphael 130 U Hurler Cyclops @Xavier Ribeiro 131 U Hurloon Battle Hymn @Dominik Mayer +132 C In Thrall to the Pit @Andrey Kuzinskiy 133 M Jaya, Fiery Negotiator @Marta Nael 134 C Jaya's Firenado @Jeremy Wilson 135 R Keldon Flamesage @Jason A. Engle +136 C Keldon Strike Team @Josu Hernaiz 137 C Lightning Strike @Marta Nael +138 C Meria's Outrider @Lius Lasahido 139 C Molten Monstrosity @Manuel Castañón 140 U Phoenix Chick @Brian Valeza 141 R Radha's Firebrand @Ângelo Bortolini @@ -113,21 +161,30 @@ ScryfallCode=DMU 151 U Warhost's Frenzy @Igor Grechanyi 152 C Yavimaya Steelcrusher @Gabor Szikszai 153 U Yotia Declares War @Fariba Khamseh +154 C Barkweave Crusher @Kev Walker +155 C Bite Down @Kitt Lapeña 156 C Bog Badger @Sam Burley +157 C Broken Wings @Svetlin Velinov 158 C Colossal Growth @Eelis Kyttanen +159 C Deathbloom Gardener @Marta Nael 160 R Defiler of Vigor @Chase Stone +161 C Elfhame Wurm @Victor Adame Minguez 162 U Elvish Hydromancer @Fajareka Setiawan +163 C Floriferous Vinewall @Jakub Kasper 164 C Gaea's Might @Alex Negrea 165 R Herd Migration @Antonio José Manzanedo +166 C Hexbane Tortoise @Joshua Raphael 167 R Leaf-Crowned Visionary @Anna Steinbauer 168 U Linebreaker Baloth @Brent Hollowell 169 R Llanowar Greenwidow @Jokubas Uogintas 170 R Llanowar Loamspeaker @Zara Alfonso +171 C Llanowar Stalker @Fariba Khamseh 172 C Magnigoth Sentry @Dave Kendall 173 U Mossbeard Ancient @Alexandre Honoré 174 U Nishoba Brawler @Valera Lutfullina 175 R Quirion Beastcaller @Valera Lutfullina 176 C Scout the Wilderness @A. M. Sartor +177 M Silverback Elder @Alexander Mokhov 178 U Slimefoot's Survey @Piotr Dura 179 C Snarespinner @Michele Giorgi 180 U Strength of the Coalition @Justine Cruz @@ -145,11 +202,15 @@ ScryfallCode=DMU 192 M Ajani, Sleeper Agent @Matt Stewart 193 U Aron, Benalia's Ruin @Mark Winters 194 R Astor, Bearer of Blades @Josh Hass +195 U Baird, Argivian Recruiter @Jarel Threat 196 U Balmor, Battlemage Captain @Bram Sels 197 U Bortuk Bonerattle @Wayne Reynolds 198 U Elas il-Kor, Sadistic Pilgrim @G-host Lee +199 R Ertai Resurrected @Ryan Pancoast +200 U Garna, Bloodfist of Keld @Andrey Kuzinskiy 201 R Ivy, Gleeful Spellthief @Evyn Fong 202 R Jhoira, Ageless Innovator @Justyna Gil +203 M Jodah, the Unifier @Ryan Pancoast 204 R King Darien XLVIII @Donato Giancola 205 U Lagomos, Hand of Hatred @Tuan Duong Chu 206 R Meria, Scholar of Antiquity @Aurore Folny @@ -157,6 +218,7 @@ ScryfallCode=DMU 208 U Najal, the Storm Runner @PINDURSKI 209 R Nemata, Primeval Warden @Andrew Mar 210 U Queen Allenal of Ruadach @Ekaterina Burmak +211 U Radha, Coalition Warlord @Randy Vargas 212 U Raff, Weatherlight Stalwart @Eelis Kyttanen 213 R Ratadrabik of Urborg @Anna Pavleeva 214 M Rith, Liberated Primeval @Victor Adame Minguez @@ -180,17 +242,32 @@ ScryfallCode=DMU 232 U Inscribed Tablet @Jarel Threat 233 U Jodah's Codex @Aaron Miller 234 M Karn's Sylex @Adam Paquette +235 C Meteorite @Olena Richards +236 U Relic of Legends @Titus Lunter +237 R Salvaged Manaworker @Julian Kok Joon Wen 238 C Shield-Wall Sentinel @Titus Lunter 239 M Timeless Lotus @Lindsey Look +240 C Vanquisher's Axe @Joe Slucher 241 U Walking Bulwark @Jonas De Ro 242 M Weatherlight Compleated @Adam Paquette 243 R Adarkar Wastes @Piotr Dura 244 R Caves of Koilos @Julian Kok Joon Wen +245 L Contaminated Aquifer @Robin Olausson +246 C Crystal Grotto @Piotr Dura +247 L Geothermal Bog @Gabor Szikszai +248 L Haunted Mire @Bruce Brenneise +249 L Idyllic Beachfront @Robin Olausson 250 R Karplusan Forest @Sam Burley +251 L Molten Tributary @Yeong-Hao Han 252 R Plaza of Heroes @Gabor Szikszai +253 L Radiant Grove @Lorenzo Lanfranconi +254 L Sacred Peaks @Kamila Szutenberg 255 R Shivan Reef @Andrew Mar 256 R Sulfurous Springs @Bruce Brenneise +257 L Sunlit Marsh @Marc Simonetti +258 L Tangled Islet @Randy Gallegos 259 R Thran Portal @Sarah Finnigan +260 L Wooded Ridgeline @Jinho Bae 261 R Yavimaya Coast @Jesper Ejsing 262 L Plains @Lorenzo Lanfranconi 263 L Plains @Seb McKinnon @@ -224,17 +301,23 @@ ScryfallCode=DMU 291 R Squee, Dubious Monarch @Daniel Lieske 292 U Aron, Benalia's Ruin @Jody Clark 293 R Astor, Bearer of Blades @Ivan Shavrin +294 U Baird, Argivian Recruiter @Barbara Rosiak 295 U Balmor, Battlemage Captain @Nino Vecia +296 U Bortuk Bonerattle @Justin Hernandez & Alexis Hernandez 297 U Elas il-Kor, Sadistic Pilgrim @Joe Esposito +298 R Ertai Resurrected @Justin Hernandez & Alexis Hernandez +299 U Garna, Bloodfist of Keld @Benjamin Ee 300 R Ivy, Gleeful Spellthief @Eshpur 301 R Jhoira, Ageless Innovator @Lisa Heidhoff 302 M Jodah, the Unifier @Barbara Rosiak 303 R King Darien XLVIII @Jody Clark 304 U Lagomos, Hand of Hatred @Joe Esposito 305 R Meria, Scholar of Antiquity @Carly Mazur +306 U Nael, Avizoa Aeronaut @Lisa Heidhoff 307 U Najal, the Storm Runner @Serena Malyon 308 R Nemata, Primeval Warden @Bastien Grivet 309 U Queen Allenal of Ruadach @Carly Mazur +310 U Radha, Coalition Warlord @Carly Mazur 311 U Raff, Weatherlight Stalwart @Ivan Shavrin 312 R Ratadrabik of Urborg @Nino Vecia 313 M Rith, Liberated Primeval @Roman Kuteynikov @@ -248,6 +331,8 @@ ScryfallCode=DMU 321 U Tatyova, Steward of Tides @Lisa Heidhoff 322 U Tori D'Avenant, Fury Rider @Jody Clark 323 U Tura Kennerüd, Skyknight @Benjamin Ee +324 U Uurg, Spawn of Turg @Eugene Frost +325 U Vohar, Vodalian Desecrator @Nino Vecia 326 U Zar Ojanen, Scion of Efrava @Eshpur 327 M Zur, Eternal Schemer @Dan Mumford 328 R Danitha, Benalia's Hope @Barbara Rosiak @@ -255,18 +340,29 @@ ScryfallCode=DMU 330 R The Raven Man @David Curtis 331 M Sheoldred, the Apocalypse @Joe Esposito 332 R Squee, Dubious Monarch @Daniel Lieske +333 U Aron, Benalia's Ruin @@Jody Clark +334 R Astor, Bearer of Blades @Ivan Shavrin +335 U Baird, Argivian Recruiter @Barbara Rosiak 336 U Balmor, Battlemage Captain @Nino Vecia 337 U Bortuk Bonerattle @Justin Hernandez & Alexis Hernandez +338 U Elas il-Kor, Sadistic Pilgrim @Joe Esposito +339 R Ertai Resurrected @Justin Hernandez & Alexis Hernandez +340 U Garna, Bloodfist of Keld @Benjamin Ee 341 R Ivy, Gleeful Spellthief @Eshpur 342 R Jhoira, Ageless Innovator @Lisa Heidhoff 343 M Jodah, the Unifier @Barbara Rosiak 344 R King Darien XLVIII @Jody Clark 345 U Lagomos, Hand of Hatred @Joe Esposito +346 R Meria, Scholar of Antiquity @Carly Mazur 347 U Nael, Avizoa Aeronaut @Lisa Heidhoff 348 U Najal, the Storm Runner @Serena Malyon +349 R Nemata, Primeval Warden @Bastien Grivet 350 U Queen Allenal of Ruadach @Carly Mazur +351 U Radha, Coalition Warlord @Carly Mazur 352 U Raff, Weatherlight Stalwart @Ivan Shavrin 353 R Ratadrabik of Urborg @Nino Vecia +354 M Rith, Liberated Primeval @Roman Kuteynikov +355 R Rivaz of the Claw @Eugene Frost 356 U Rona, Sheoldred's Faithful @Nino Vecia 357 U Rulik Mons, Warren Chief @Roman Kuteynikov 358 M Shanna, Purifying Blade @Jody Clark @@ -277,6 +373,7 @@ ScryfallCode=DMU 363 U Tori D'Avenant, Fury Rider @Jody Clark 364 U Tura Kennerüd, Skyknight @Benjamin Ee 365 U Uurg, Spawn of Turg @Eugene Frost +366 U Vohar, Vodalian Desecrator @Nino Vecia 367 U Zar Ojanen, Scion of Efrava @Eshpur 368 M Zur, Eternal Schemer @Dan Mumford 369 M Sheoldred, the Apocalypse @Chris Rahn @@ -301,17 +398,22 @@ ScryfallCode=DMU 388 M Serra Paragon @Heonhwa Choe 389 R Temporary Lockdown @Bryan Sola 390 R Valiant Veteran @Nestor Ossandon Leal +391 R Academy Loremaster @Marcela Medeiros +392 R Aether Channeler @Caio Monteiro 393 R Defiler of Dreams @Ryan Pancoast 394 R Haughty Djinn @Mike Jordana 395 R Silver Scrutiny @Donato Giancola 396 M Sphinx of Clear Skies @Valera Lutfullina +397 M Vesuvan Duplimancy @Wylie Beckert 398 R Vodalian Hexcatcher @Dmitry Burmak 399 R Vodalian Mindsinger @Steve Prescott 400 R Defiler of Flesh @Mathias Kollros 401 R Drag to the Bottom @Nino Is 402 R Evolved Sleeper @Jason A. Engle +403 R Shadow-Rite Priest @Michael C. Hayes 404 R Stronghold Arena @Alexander Mokhov 405 R Chaotic Transformation @Joseph Meehan +406 R Defiler of Instinct @Steven Belledin 407 R Keldon Flamesage @Jason A. Engle 408 R Radha's Firebrand @Ângelo Bortolini 409 R Rundvelt Hordemaster @Bruno Biazotto @@ -323,6 +425,7 @@ ScryfallCode=DMU 415 R Llanowar Greenwidow @Jokubas Uogintas 416 R Llanowar Loamspeaker @Zara Alfonso 417 R Quirion Beastcaller @Valera Lutfullina +418 M Silverback Elder @Alexander Mokhov 419 R Threats Undetected @Randy Vargas 420 R Urborg Lhurgoyf @Andrey Kuzinskiy 421 R Plaza of Heroes @Gabor Szikszai From 5b8e26d909522839de9ccf368fe45fb296d82d76 Mon Sep 17 00:00:00 2001 From: paulsnoops Date: Sat, 27 Aug 2022 00:16:49 +0100 Subject: [PATCH 61/70] DMU quick fix --- forge-gui/res/editions/Dominaria United.txt | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/forge-gui/res/editions/Dominaria United.txt b/forge-gui/res/editions/Dominaria United.txt index 9bb37a77ed1..67775daad7a 100644 --- a/forge-gui/res/editions/Dominaria United.txt +++ b/forge-gui/res/editions/Dominaria United.txt @@ -244,7 +244,7 @@ ScryfallCode=DMU 234 M Karn's Sylex @Adam Paquette 235 C Meteorite @Olena Richards 236 U Relic of Legends @Titus Lunter -237 R Salvaged Manaworker @Julian Kok Joon Wen +237 C Salvaged Manaworker @Julian Kok Joon Wen 238 C Shield-Wall Sentinel @Titus Lunter 239 M Timeless Lotus @Lindsey Look 240 C Vanquisher's Axe @Joe Slucher @@ -252,22 +252,22 @@ ScryfallCode=DMU 242 M Weatherlight Compleated @Adam Paquette 243 R Adarkar Wastes @Piotr Dura 244 R Caves of Koilos @Julian Kok Joon Wen -245 L Contaminated Aquifer @Robin Olausson +245 C Contaminated Aquifer @Robin Olausson 246 C Crystal Grotto @Piotr Dura -247 L Geothermal Bog @Gabor Szikszai -248 L Haunted Mire @Bruce Brenneise -249 L Idyllic Beachfront @Robin Olausson +247 C Geothermal Bog @Gabor Szikszai +248 C Haunted Mire @Bruce Brenneise +249 C Idyllic Beachfront @Robin Olausson 250 R Karplusan Forest @Sam Burley -251 L Molten Tributary @Yeong-Hao Han +251 C Molten Tributary @Yeong-Hao Han 252 R Plaza of Heroes @Gabor Szikszai -253 L Radiant Grove @Lorenzo Lanfranconi -254 L Sacred Peaks @Kamila Szutenberg +253 C Radiant Grove @Lorenzo Lanfranconi +254 C Sacred Peaks @Kamila Szutenberg 255 R Shivan Reef @Andrew Mar 256 R Sulfurous Springs @Bruce Brenneise -257 L Sunlit Marsh @Marc Simonetti -258 L Tangled Islet @Randy Gallegos +257 C Sunlit Marsh @Marc Simonetti +258 C Tangled Islet @Randy Gallegos 259 R Thran Portal @Sarah Finnigan -260 L Wooded Ridgeline @Jinho Bae +260 C Wooded Ridgeline @Jinho Bae 261 R Yavimaya Coast @Jesper Ejsing 262 L Plains @Lorenzo Lanfranconi 263 L Plains @Seb McKinnon @@ -340,7 +340,7 @@ ScryfallCode=DMU 330 R The Raven Man @David Curtis 331 M Sheoldred, the Apocalypse @Joe Esposito 332 R Squee, Dubious Monarch @Daniel Lieske -333 U Aron, Benalia's Ruin @@Jody Clark +333 U Aron, Benalia's Ruin @Jody Clark 334 R Astor, Bearer of Blades @Ivan Shavrin 335 U Baird, Argivian Recruiter @Barbara Rosiak 336 U Balmor, Battlemage Captain @Nino Vecia From 5d410d9a61d6b37b64db747257098c1c78ecda0b Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Sat, 27 Aug 2022 14:00:57 +0200 Subject: [PATCH 62/70] DMU 5 Jumpstart Cards (#1399) --- forge-gui/res/cardsfolder/upcoming/briar_hydra.txt | 11 +++++++++++ .../res/cardsfolder/upcoming/cosmic_epiphany.txt | 8 ++++++++ .../res/cardsfolder/upcoming/ragefire_hellkite.txt | 10 ++++++++++ .../res/cardsfolder/upcoming/serra_redeemer.txt | 9 +++++++++ .../cardsfolder/upcoming/tyrannical_pitlord.txt | 14 ++++++++++++++ 5 files changed, 52 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/briar_hydra.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/cosmic_epiphany.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/ragefire_hellkite.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/serra_redeemer.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/tyrannical_pitlord.txt diff --git a/forge-gui/res/cardsfolder/upcoming/briar_hydra.txt b/forge-gui/res/cardsfolder/upcoming/briar_hydra.txt new file mode 100644 index 00000000000..e40aa59e8eb --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/briar_hydra.txt @@ -0,0 +1,11 @@ +Name:Briar Hydra +ManaCost:5 G +Types:Creature Plant Hydra +PT:6/6 +K:Trample +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ DBCounter | TriggerZones$ Battlefield | TriggerDescription$ Domain — Whenever CARDNAME deals combat damage to a player, put X +1/+1 counters on target creature you control, where X is the number of basic land types among lands you control. +SVar:DBCounter:DB$ PutCounter | CounterNum$ X | CounterType$ P1P1 | ValidTgts$ Creature.YouCtrl +SVar:X:Count$Domain +DeckHas:Ability$Counters +AI:RemoveDeck:Random ( +Oracle:Trample\nDomain — Whenever Briar Hydra deals combat damage to a player, put X +1/+1 counters on target creature you control, where X is the number of basic land types among lands you control. diff --git a/forge-gui/res/cardsfolder/upcoming/cosmic_epiphany.txt b/forge-gui/res/cardsfolder/upcoming/cosmic_epiphany.txt new file mode 100644 index 00000000000..04537388761 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/cosmic_epiphany.txt @@ -0,0 +1,8 @@ +Name:Cosmic Epiphany +ManaCost:4 U U +Types:Sorcery +A:SP$ Draw | NumCards$ X | SpellDescription$ Draw cards equal to the number of instant and sorcery cards in your graveyard. +SVar:X:Count$ValidGraveyard Instant.YouOwn,Sorcery.YouOwn +DeckNeeds:Type$Instant|Sorcery +DeckHas:Ability$Graveyard +Oracle:Draw cards equal to the number of instant and sorcery cards in your graveyard. diff --git a/forge-gui/res/cardsfolder/upcoming/ragefire_hellkite.txt b/forge-gui/res/cardsfolder/upcoming/ragefire_hellkite.txt new file mode 100644 index 00000000000..5e8d467b493 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ragefire_hellkite.txt @@ -0,0 +1,10 @@ +Name:Ragefire Hellkite +ManaCost:4 R R +Types:Creature Dragon +PT:5/3 +K:Flying +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPump | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks, you may sacrifice another creature. If you do, CARDNAME gains double strike until end of turn. +SVar:TrigPump:AB$ Pump | Cost$ Sac<1/Creature.Other/another creature> | Defined$ Self | KW$ Double Strike +DeckHas:Ability$Sacrifice +SVar:HasAttackEffect:TRUE +Oracle:Flying\nWhenever Ragefire Hellkite attacks, you may sacrifice another creature. If you do, Ragefire Hellkite gains double strike until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/serra_redeemer.txt b/forge-gui/res/cardsfolder/upcoming/serra_redeemer.txt new file mode 100644 index 00000000000..5529862cf11 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/serra_redeemer.txt @@ -0,0 +1,9 @@ +Name:Serra Redeemer +ManaCost:3 W W +Types:Creature Angel Soldier +PT:2/4 +K:Flying +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.powerLE2+YouCtrl+Other | TriggerZones$ Battlefield | Execute$ TrigCounter | TriggerDescription$ Whenever another creature with power 2 or less enters the battlefield under your control, put two +1/+1 counters on that creature. +SVar:TrigCounter:DB$ PutCounter | Defined$ TriggeredCardLKICopy | CounterType$ P1P1 | CounterNum$ 2 +DeckHas:Ability$Counters +Oracle:Flying\nWhenever another creature with power 2 or less enters the battlefield under your control, put two +1/+1 counters on that creature. diff --git a/forge-gui/res/cardsfolder/upcoming/tyrannical_pitlord.txt b/forge-gui/res/cardsfolder/upcoming/tyrannical_pitlord.txt new file mode 100644 index 00000000000..eaf43137c45 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/tyrannical_pitlord.txt @@ -0,0 +1,14 @@ +Name:Tyrannical Pitlord +ManaCost:4 B B +Types:Creature Demon +PT:6/6 +K:Flying +K:Trample +K:ETBReplacement:Other:DBChoose +SVar:DBChoose:DB$ ChooseCard | Choices$ Creature.Other+YouCtrl |TgtPrompt$ Select another target creature you control | Description$ As CARDNAME enters the battlefield, choose another creature you control. +S:Mode$ Continuous | Affected$ Card.ChosenCardStrict | AddKeyword$ Flying | AddToughness$ 3 | AddPower$ 3 | SpellDescription$ The chosen creature gets +3/+3 and has flying. +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Any | Execute$ TrigSacrifice | SubAbility$ DBCleanup | SpellDescription$ When CARDNAME leaves the battlefield, sacrifice the chosen creature. +SVar:TrigSacrifice:DB$ SacrificeAll | Defined$ ChosenCard +SVar:DBCleanup:DB$ Cleanup | ClearChosen$ True +DeckHas:Ability$Sacrifice +Oracle:Flying, trample\nAs Tyrannical Pitlord enters the battlefield, choose another creature you control.\nThe chosen creature gets +3/+3 and has flying.\nWhen Tyrannical Pitlord leaves the battlefield, sacrifice the chosen creature. From ba8df4cd71554471bcc45b9d9bffe92b22f4e2eb Mon Sep 17 00:00:00 2001 From: Suthro <81990938+Suthro@users.noreply.github.com> Date: Sat, 27 Aug 2022 07:08:48 -0500 Subject: [PATCH 63/70] DMU: Queen Allenal of Ruadach + 5 cards, 1 token (#1404) DMU: Add scripts for 6 new DMU cards, plus 1 token - Bortuk Bonerattle - King Darien XLVIII - Lagomos, Hand of Hatred - Queen Allenal of Ruadach - Sphinx of Clear Skies - Uurg, Spawn of Turg Token: - 2/1 red Elemental creature with trample and haste --- .../res/cardsfolder/upcoming/bortuk_bonerattle.txt | 12 ++++++++++++ .../cardsfolder/upcoming/king_darien_xlviii.txt | 12 ++++++++++++ .../upcoming/lagomos_hand_of_hatred.txt | 10 ++++++++++ .../upcoming/queen_allenal_of_ruadach.txt | 13 +++++++++++++ .../cardsfolder/upcoming/sphinx_of_clear_skies.txt | 14 ++++++++++++++ .../cardsfolder/upcoming/uurg_spawn_of_turg.txt | 12 ++++++++++++ .../tokenscripts/r_2_1_elemental_trample_haste.txt | 8 ++++++++ 7 files changed, 81 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/bortuk_bonerattle.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/king_darien_xlviii.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/lagomos_hand_of_hatred.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/queen_allenal_of_ruadach.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/sphinx_of_clear_skies.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/uurg_spawn_of_turg.txt create mode 100644 forge-gui/res/tokenscripts/r_2_1_elemental_trample_haste.txt diff --git a/forge-gui/res/cardsfolder/upcoming/bortuk_bonerattle.txt b/forge-gui/res/cardsfolder/upcoming/bortuk_bonerattle.txt new file mode 100644 index 00000000000..b21ad37cf29 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/bortuk_bonerattle.txt @@ -0,0 +1,12 @@ +Name:Bortuk Bonerattle +ManaCost:4 B G +Types:Legendary Creature Troll Shaman +PT:4/4 +T:Mode$ ChangesZone | ValidCard$ Card.wasCastByYou+Self | Destination$ Battlefield | Execute$ TrigChangeZone | TriggerDescription$ Domain — When CARDNAME enters the battlefield, if you cast it, choose target creature card in your graveyard. Return that card to the battlefield if its mana value is less than or equal to the number of basic land types among lands you control. Otherwise, put it into your hand. +SVar:TrigChangeZone:DB$ ChangeZone | ValidTgts$ Creature.YouOwn | Origin$ Graveyard | Destination$ Battlefield | ConditionDefined$ Targeted | ConditionPresent$ Card.cmcLEX | SubAbility$ DBChangeZone +SVar:DBChangeZone:DB$ ChangeZone | Defined$ Targeted | Origin$ Graveyard | Destination$ Hand | ConditionDefined$ Targeted | ConditionPresent$ Card.cmcGTX +SVar:X:Count$Domain +SVar:BuffedBy:Plains,Island,Swamp,Mountain,Forest +RemoveDeck:Random +DeckHas:Ability$Graveyard +Oracle:Domain — When Bortuk Bonerattle enters the battlefield, if you cast it, choose target creature card in your graveyard. Return that card to the battlefield if its mana value is less than or equal to the number of basic land types among lands you control. Otherwise, put it into your hand. diff --git a/forge-gui/res/cardsfolder/upcoming/king_darien_xlviii.txt b/forge-gui/res/cardsfolder/upcoming/king_darien_xlviii.txt new file mode 100644 index 00000000000..c192e7c161f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/king_darien_xlviii.txt @@ -0,0 +1,12 @@ +Name:King Darien XLVIII +ManaCost:1 G W +Types:Legendary Creature Human Soldier +PT:2/3 +S:Mode$ Continuous | Affected$ Creature.Other+YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Other creatures you control get +1/+1. +A:AB$ PutCounter | Cost$ 3 G W | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBToken | SpellDescription$ Put a +1/+1 counter on NICKNAME and create a 1/1 white Soldier creature token. +SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_soldier | TokenOwner$ You | StackDescription$ None +A:AB$ PumpAll | Cost$ Sac<1/CARDNAME> | ValidCards$ Creature.token+YouCtrl | KW$ Hexproof & Indestructible | SpellDescription$ Creature tokens you control gain hexproof and indestructible until end of turn. +DeckHas:Ability$Counters|Token|Sacrifice & Type|Soldier +DeckHints:Ability$Token +SVar:PlayMain1:TRUE +Oracle:Other creatures you control get +1/+1.\n{3}{G}{W}: Put a +1/+1 counter on King Darien and create a 1/1 white Soldier creature token.\nSacrifice King Darien: Creature tokens you control gain hexproof and indestructible until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/lagomos_hand_of_hatred.txt b/forge-gui/res/cardsfolder/upcoming/lagomos_hand_of_hatred.txt new file mode 100644 index 00000000000..3df559e2f14 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/lagomos_hand_of_hatred.txt @@ -0,0 +1,10 @@ +Name:Lagomos, Hand of Hatred +ManaCost:1 B R +Types:Legendary Creature Human Shaman +PT:1/3 +T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ At the beginning of combat on your turn, create a 2/1 red Elemental creature token with trample and haste. Sacrifice it at the beginning of the next end step. +SVar:TrigToken:DB$ Token | TokenScript$ r_2_1_elemental_trample_haste | TokenAmount$ 1 | AtEOT$ Sacrifice +A:AB$ ChangeZone | Cost$ T | Origin$ Library | Destination$ Hand | ChangeType$ Card | ChangeNum$ 1 | Mandatory$ True | CheckSVar$ X | SVarCompare$ GE5 | SpellDescription$ Search your library for a card, put that card into your hand, then shuffle. Activate only if five or more creatures died this turn. +SVar:X:Count$ThisTurnEntered_Graveyard_from_Battlefield_Creature +DeckHas:Ability$Counters|Sacrifice|Token & Type$Elemental +Oracle:\nAt the beginning of combat on your turn, create a 2/1 red Elemental creature token with trample and haste. Sacrifice it at the beginning of the next end step.\n{T}: Search your library for a card, put it into your hand, then shuffle. Activate only if five or more creatures died this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/queen_allenal_of_ruadach.txt b/forge-gui/res/cardsfolder/upcoming/queen_allenal_of_ruadach.txt new file mode 100644 index 00000000000..23074d79091 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/queen_allenal_of_ruadach.txt @@ -0,0 +1,13 @@ +Name:Queen Allenal of Ruadach +ManaCost:G W W +Types:Legendary Creature Elf Noble +PT:*/* +S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ X | SetToughness$ X | Description$ CARDNAME's power and toughness are each equal to the number of creatures you control. +R:Event$ CreateToken | ActiveZones$ Battlefield | ValidToken$ Card.YouCtrl | ReplaceWith$ DBReplace | Description$ If one or more tokens would be created under your control, those tokens plus a 1/1 white Soldier creature token are created instead. +SVar:DBReplace:DB$ ReplaceToken | Type$ AddToken | Amount$ 1 | ValidCard$ Card.YouCtrl | TokenScript$ w_1_1_soldier +SVar:X:Count$Valid Creature.YouCtrl +SVar:BuffedBy:Creature +SVar:NoZeroToughnessAI:True +DeckHas:Ability$Token & Type$Soldier +DeckHints:Ability$Token +Oracle:Queen Allenal of Ruadach's power and toughness are each equal to the number of creatures you control.\nIf one or more creature tokens would be created under your control, those tokens plus a 1/1 white Soldier creature token are created instead. diff --git a/forge-gui/res/cardsfolder/upcoming/sphinx_of_clear_skies.txt b/forge-gui/res/cardsfolder/upcoming/sphinx_of_clear_skies.txt new file mode 100644 index 00000000000..842f5b7156f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/sphinx_of_clear_skies.txt @@ -0,0 +1,14 @@ +Name:Sphinx of Clear Skies +ManaCost:3 U U +Types:Creature Sphinx +PT:5/5 +K:Flying +K:Ward:2 +T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigChangeZone | TriggerDescription$ Domain — Whenever CARDNAME deals combat damage to a player, reveal the top X cards of your library, where X is the number of basic land types among lands you control. An opponent separates those cards into two piles. Put one pile into your hand and the other into your graveyard. (Piles can be empty.) +SVar:TrigChangeZone:DB$ PeekAndReveal | PeekAmount$ X | NoPeek$ True | RememberRevealed$ True | SubAbility$ DBTwoPiles +SVar:DBTwoPiles:DB$ TwoPiles | Defined$ You | DefinedCards$ Remembered | Separator$ Opponent | ChosenPile$ DBHand | UnchosenPile$ DBGrave +SVar:DBHand:DB$ ChangeZone | Defined$ Remembered | Origin$ Library | Destination$ Hand +SVar:DBGrave:DB$ ChangeZone | Defined$ Remembered | Origin$ Library | Destination$ Graveyard +SVar:X:Count$Domain +DeckHas:Ability$Graveyard +Oracle:Flying, ward {2}\nDomain — Whenever Sphinx of Clear Skies deals combat damage to a player, reveal the top X cards of your library, where X is the number of basic land types among lands you control. An opponent separates those cards into two piles. Put one pile into your hand and the other into your graveyard. (Piles can be empty.) diff --git a/forge-gui/res/cardsfolder/upcoming/uurg_spawn_of_turg.txt b/forge-gui/res/cardsfolder/upcoming/uurg_spawn_of_turg.txt new file mode 100644 index 00000000000..3b9bc1ac44e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/uurg_spawn_of_turg.txt @@ -0,0 +1,12 @@ +Name:Uurg, Spawn of Turg +ManaCost:B B G +Types:Legendary Creature Frog Beast +PT:*/5 +S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ X | Description$ CARDNAME's power is equal to the number of land cards in your graveyard. +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDig | TriggerDescription$ At the beginning of your upkeep, look at the top card of your library. You may put that card into your graveyard. +SVar:TrigDig:DB$ Dig | DigNum$ 1 | DestinationZone$ Graveyard | Optional$ True | LibraryPosition2$ 0 +A:AB$ GainLife | Cost$ B G Sac<1/Land> | LifeAmount$ 2 +SVar:X:Count$TypeInYourYard.Land +DeckHas:Ability$LifeGain|Graveyard +DeckHints:Ability$Graveyard +Oracle:Uurg, Spawn of Turg's power is equal to the number of land cards in your graveyard.\nAt the beginning of your upkeep, look at the top card of your library. You may put that card into your graveyard.\n{B}{G}, Sacrifice a land: You gain 2 life. diff --git a/forge-gui/res/tokenscripts/r_2_1_elemental_trample_haste.txt b/forge-gui/res/tokenscripts/r_2_1_elemental_trample_haste.txt new file mode 100644 index 00000000000..0afab06de77 --- /dev/null +++ b/forge-gui/res/tokenscripts/r_2_1_elemental_trample_haste.txt @@ -0,0 +1,8 @@ +Name:Elemental token +ManaCost:no cost +Colors:red +Types:Creature Elemental +PT:2/1 +K:Trample +K:Haste +Oracle:Trample, haste From a35ffbcb0fccac5a7eea6ff513a52a518fe23f3d Mon Sep 17 00:00:00 2001 From: tool4ever Date: Sun, 28 Aug 2022 05:40:44 +0200 Subject: [PATCH 64/70] Rith, Liberated Primeval and support (#1409) * Rith, Liberated Primeval and support * Add AI hints Co-authored-by: TRT <> --- forge-game/src/main/java/forge/game/GameAction.java | 2 +- .../main/java/forge/game/card/CardDamageMap.java | 6 +++++- .../upcoming/rith_liberated_primeval.txt | 13 +++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/rith_liberated_primeval.txt diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 433ae194876..ffb86ed9e9a 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -2419,7 +2419,7 @@ public class GameAction { } // for Zangief do this before runWaitingTriggers DamageDone - damageMap.triggerExcessDamage(isCombat, lethalDamage, game); + damageMap.triggerExcessDamage(isCombat, lethalDamage, game, lkiCache); // lose life simultaneously if (isCombat) { diff --git a/forge-game/src/main/java/forge/game/card/CardDamageMap.java b/forge-game/src/main/java/forge/game/card/CardDamageMap.java index 37dd9c620b8..0d4d7333737 100644 --- a/forge-game/src/main/java/forge/game/card/CardDamageMap.java +++ b/forge-game/src/main/java/forge/game/card/CardDamageMap.java @@ -104,7 +104,7 @@ public class CardDamageMap extends ForwardingTable { game.getTriggerHandler().runTrigger(TriggerType.DamageAll, runParams, false); } - public void triggerExcessDamage(boolean isCombat, Map lethalDamage, final Game game) { + public void triggerExcessDamage(boolean isCombat, Map lethalDamage, final Game game, final Map lkiCache) { for (Entry damaged : lethalDamage.entrySet()) { int sum = 0; for (Integer i : this.column(damaged.getKey()).values()) { @@ -112,6 +112,10 @@ public class CardDamageMap extends ForwardingTable { } int excess = sum - (damaged.getKey().hasBeenDealtDeathtouchDamage() ? 1 : damaged.getValue()); + + // also update the DamageHistory, but overwrite previous excess outcomes + // because Rith, Liberated Primeval cares about who controlled it at this moment + lkiCache.get(damaged.getKey().getId()).setHasBeenDealtExcessDamageThisTurn(excess > 0); if (excess > 0) { damaged.getKey().setHasBeenDealtExcessDamageThisTurn(true); // Run triggers diff --git a/forge-gui/res/cardsfolder/upcoming/rith_liberated_primeval.txt b/forge-gui/res/cardsfolder/upcoming/rith_liberated_primeval.txt new file mode 100644 index 00000000000..6a2d8c12795 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/rith_liberated_primeval.txt @@ -0,0 +1,13 @@ +Name:Rith, Liberated Primeval +ManaCost:2 R G W +Types:Legendary Creature Dragon +PT:5/5 +K:Flying +K:Ward:2 +S:Mode$ Continuous | Affected$ Dragon.Other+YouCtrl | AddKeyword$ Ward:2 | Description$ Other Dragons you control have ward {2}. +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | CheckSVar$ DragonCheck | Execute$ DBDragon | TriggerDescription$ At the beginning of your end step, if a creature or planeswalker an opponent controlled was dealt excess damage this turn, create a 4/4 red Dragon creature token with flying. +SVar:DBDragon:DB$ Token | TokenScript$ r_4_4_dragon_flying +SVar:DragonCheck:Count$NumDamageThisTurn Card Creature.OppCtrl+wasDealtExcessDamageThisTurn,Planeswalker.OppCtrl+wasDealtExcessDamageThisTurn +DeckHas:Ability$Token +DeckHints:Type$Dragon +Oracle:Flying, ward {2}\nOther dragons you control have ward {2}.\nAt the beginning of your end step, if a creature or planeswalker an opponent controlled was dealt excess damage this turn, create a 4/4 red Dragon creature token with flying. From 743fd20776b4fabe6e8a9b7c14c2c96a69de7870 Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Sun, 28 Aug 2022 05:40:52 +0200 Subject: [PATCH 65/70] DMU 8 Cards (#1407) * DMU 8 Cards * Update colossal_growth.txt * Update charismatic_vanguard.txt * Update silverback_elder.txt * Update silverback_elder.txt --- forge-gui/res/cardsfolder/upcoming/blight_pile.txt | 9 +++++++++ forge-gui/res/cardsfolder/upcoming/bog_badger.txt | 10 ++++++++++ .../cardsfolder/upcoming/charismatic_vanguard.txt | 6 ++++++ .../res/cardsfolder/upcoming/citizens_arrest.txt | 7 +++++++ .../res/cardsfolder/upcoming/cleaving_skyrider.txt | 12 ++++++++++++ .../res/cardsfolder/upcoming/colossal_growth.txt | 7 +++++++ .../res/cardsfolder/upcoming/plaza_of_heroes.txt | 9 +++++++++ .../res/cardsfolder/upcoming/silverback_elder.txt | 11 +++++++++++ 8 files changed, 71 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/blight_pile.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/bog_badger.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/charismatic_vanguard.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/citizens_arrest.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/cleaving_skyrider.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/colossal_growth.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/plaza_of_heroes.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/silverback_elder.txt diff --git a/forge-gui/res/cardsfolder/upcoming/blight_pile.txt b/forge-gui/res/cardsfolder/upcoming/blight_pile.txt new file mode 100644 index 00000000000..1313707248b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/blight_pile.txt @@ -0,0 +1,9 @@ +Name:Blight Pile +ManaCost:1 B +Types:Creature Phyrexian +K:Defender +PT:3/3 +A:AB$ LoseLife | Cost$ T 2 B | Defined$ Player.Opponent | LifeAmount$ X | SpellDescription$ Each opponent loses X life, where X is the number of creatures with defender you control. +SVar:X:Count$Valid Creature.withDefender+YouCtrl +DeckHints:Keyword$Defender +Oracle:Defender\n{2}{B}, {T}: Each opponent loses X life, where X is the number of creatures with defender you control. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/bog_badger.txt b/forge-gui/res/cardsfolder/upcoming/bog_badger.txt new file mode 100644 index 00000000000..514d1cb62e0 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/bog_badger.txt @@ -0,0 +1,10 @@ +Name:Bog Badger +ManaCost:2 G +Types:Creature Badger +PT:3/3 +K:Kicker:B +K:Flash +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self+kicked | Execute$ TrigPump | TriggerDescription$ When CARDNAME enters the battlefield, if it was kicked, creatures you control gain menace until end of turn. (A creature with menace can't be blocked except by two or more creatures.) +SVar:TrigPump:DB$ PumpAll | ValidCards$ Creature.YouCtrl | KW$ Menace +DeckHas:Keyword$Menace +Oracle:Kicker {B} (You may pay an additional {B} as you cast this spell.)\nWhen Bog Badger enters the battlefield, if it was kicked, creatures you control gain menace until end of turn. (A creature with menace can't be blocked except by two or more creatures.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/charismatic_vanguard.txt b/forge-gui/res/cardsfolder/upcoming/charismatic_vanguard.txt new file mode 100644 index 00000000000..484b860e3bc --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/charismatic_vanguard.txt @@ -0,0 +1,6 @@ +Name:Charismatic Vanguard +ManaCost:2 W +Types:Creature Dwarf Soldier +PT:3/2 +A:AB$ PumpAll | Cost$ 4 W | ValidCards$ Creature.YouCtrl | NumAtt$ +1 | NumDef$ +1 | SpellDescription$ Creatures you control get +1/+1 until end of turn. +Oracle:{4}{W}: Creatures you control get +1/+1 until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/citizens_arrest.txt b/forge-gui/res/cardsfolder/upcoming/citizens_arrest.txt new file mode 100644 index 00000000000..e9b48bc6021 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/citizens_arrest.txt @@ -0,0 +1,7 @@ +Name:Citizen's Arrest +ManaCost:1 W W +Types:Enchantment +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | SpellDescription$ When CARDNAME enters the battlefield, exile target creature or planeswalker an opponent controls until CARDNAME leaves the battlefield. +SVar:TrigExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Creature.OppCtrl,Planeswalker.OppCtrl | Duration$ UntilHostLeavesPlay +SVar:PlayMain1:TRUE +Oracle:When Citizen's Arrest enters the battlefield, exile target creature or planeswalker an opponent controls until Citizen's Arrest leaves the battlefield. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/cleaving_skyrider.txt b/forge-gui/res/cardsfolder/upcoming/cleaving_skyrider.txt new file mode 100644 index 00000000000..b6882f7c242 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/cleaving_skyrider.txt @@ -0,0 +1,12 @@ +Name:Cleaving Skyrider +ManaCost:2 W +Types:Creature Human Warrior +PT:2/2 +K:Flash +K:Kicker:2 R +K:Flying +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self+kicked | Execute$ TrigDamage | TriggerDescription$ When CARDNAME enters the battlefield, if it was kicked, it deals X damage to any target, where X is the number of attacking creatures. +SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ X +SVar:X:Count$Valid Creature.attacking +SVar:BuffedBy:Creature.attacking +Oracle:Flash\nKicker {2}{R} (You may pay an additional {2}{R} as you cast this spell.)\nFlying\nWhen Cleaving Skyrider enters the battlefield, if it was kicked, it deals X damage to any target, where X is the number of attacking creatures. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/colossal_growth.txt b/forge-gui/res/cardsfolder/upcoming/colossal_growth.txt new file mode 100644 index 00000000000..869b64ea077 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/colossal_growth.txt @@ -0,0 +1,7 @@ +Name:Colossal Growth +ManaCost:1 G +Types:Instant +K:Kicker:R +A:SP$ Pump | ValidTgts$ Creature | NumAtt$ +3 | NumDef$ +3 | SubAbility$ PumpKicked | SpellDescription$ Target creature gets +3/+3 until end of turn. +SVar:PumpKicked:DB$ Pump | Defined$ Targeted | Condition$ Kicked | KW$ Haste & Trample | NumAtt$ +1 | NumDef$ +1 +Oracle:Kicker {R} (You may pay an additional {R} as you cast this spell.)\nTarget creature gets +3/+3 until end of turn. If this spell was kicked, instead that creature gets +4/+4 and gains trample and haste until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/plaza_of_heroes.txt b/forge-gui/res/cardsfolder/upcoming/plaza_of_heroes.txt new file mode 100644 index 00000000000..ece3c6f5803 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/plaza_of_heroes.txt @@ -0,0 +1,9 @@ +Name:Plaza of Heroes +ManaCost:no cost +Types:Land +A:AB$ Mana | Cost$ T | Produced$ C | Amount$ 1 | SpellDescription$ Add {C} +A:AB$ Mana | Cost$ T | Produced$ Any | Amount$ 1 | RestrictValid$ Spell.Legendary | SpellDescription$ Add one mana of any color. Spend this mana only to cast a legendary spell. +A:AB$ ManaReflected | Cost$ T | ColorOrType$ Color | Valid$ Permanent.Legendary+YouCtrl | ReflectProperty$ Is | SpellDescription$ Add one mana of any color among legendary permanents you control. +A:AB$ Pump | Cost$ 3 T Exile<1/CARDNAME> | ValidTgts$ Creature.Legendary | KW$ Hexproof & Indestructible | SpellDescription$ Target legendary creature gains hexproof and indestructible until end of turn. +DeckHints:Type$Legendary +Oracle:{T}: Add {C}.\n{T}: Add one mana of any color. Spend this mana only to cast a legendary spell.\n{T}: Add one mana of any color among legendary permanents you control.\n{3}, {T}, Exile Plaza of Heroes: Target legendary creature gains hexproof and indestructible until end of turn. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/silverback_elder.txt b/forge-gui/res/cardsfolder/upcoming/silverback_elder.txt new file mode 100644 index 00000000000..ea2e88f68f7 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/silverback_elder.txt @@ -0,0 +1,11 @@ +Name:Silverback Elder +ManaCost:2 G G G +Types:Creature Ape Shaman +PT:5/7 +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | Execute$ TrigCharm | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell, ABILITY +SVar:TrigCharm:DB$ Charm | Choices$ Destroy,DigLand,GainLife | CharmNum$ 1 +SVar:Destroy:DB$ Destroy | ValidTgts$ Artifact,Enchantment | TgtPrompt$ Select target artifact or enchantment | SpellDescription$ Destroy target artifact or enchantment. +SVar:DigLand:DB$ Dig | DigNum$ 5 | ChangeNum$ 1 | ChangeValid$ Card.Land | Optional$ True | DestinationZone$ Battlefield | RestRandomOrder$ True | Tapped$ True | SpellDescription$ Look at the top five cards of your library. You may put a land card from among them onto the battlefield tapped. Put the rest on the bottom of your library in a random order. +SVar:GainLife:DB$ GainLife | LifeAmount$ 4 | SpellDescription$ You gain 4 life. +DeckHas:Ability$LifeGain +Oracle:Whenever you cast a creature spell, choose one —\n• Destroy target artifact or enchantment.\n• Look at the top five cards of your library. You may put a land card from among them onto the battlefield tapped. Put the rest on the bottom of your library in a random order.\n• You gain 4 life. From c259f81b477deaa0a270d474d00fbdcd8edea128 Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Sun, 28 Aug 2022 05:41:04 +0200 Subject: [PATCH 66/70] DMU 11 Cards (#1403) * Create academy_loremaster.txt * DMU 10 Cards * Create academy_wall.txt * Update anointed_peacekeeper.txt * Update anointed_peacekeeper.txt * Update battlewing_mystic.txt * Update benalish_sleeper.txt * Update battlewing_mystic.txt * Update benalish_sleeper.txt * Update balduvian_atrocity.txt * Update anointed_peacekeeper.txt * Update academy_wall.txt * Update * Update academy_loremaster.txt * Update balduvian_atrocity.txt * Update ivy_gleeful_spellthief.txt * Update balduvian_atrocity.txt * Update academy_wall.txt * Update ivy_gleeful_spellthief.txt * Update academy_loremaster.txt * Update ivy_gleeful_spellthief.txt * Update academy_loremaster.txt * Update balduvian_atrocity.txt * Update academy_loremaster.txt --- .../cardsfolder/upcoming/academy_loremaster.txt | 10 ++++++++++ .../res/cardsfolder/upcoming/academy_wall.txt | 8 ++++++++ .../cardsfolder/upcoming/aggressive_sabotage.txt | 7 +++++++ .../cardsfolder/upcoming/anointed_peacekeeper.txt | 14 ++++++++++++++ .../res/cardsfolder/upcoming/argivian_phalanx.txt | 8 ++++++++ .../cardsfolder/upcoming/automatic_librarian.txt | 7 +++++++ .../cardsfolder/upcoming/balduvian_atrocity.txt | 11 +++++++++++ .../res/cardsfolder/upcoming/battlewing_mystic.txt | 11 +++++++++++ .../res/cardsfolder/upcoming/benalish_sleeper.txt | 9 +++++++++ .../upcoming/ivy_gleeful_spellthief.txt | 8 ++++++++ .../res/cardsfolder/upcoming/timeless_lotus.txt | 6 ++++++ 11 files changed, 99 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/academy_loremaster.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/academy_wall.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/aggressive_sabotage.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/anointed_peacekeeper.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/argivian_phalanx.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/automatic_librarian.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/balduvian_atrocity.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/battlewing_mystic.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/benalish_sleeper.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/ivy_gleeful_spellthief.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/timeless_lotus.txt diff --git a/forge-gui/res/cardsfolder/upcoming/academy_loremaster.txt b/forge-gui/res/cardsfolder/upcoming/academy_loremaster.txt new file mode 100644 index 00000000000..81b9e42eb11 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/academy_loremaster.txt @@ -0,0 +1,10 @@ +Name:Academy Loremaster +ManaCost:U U +Types:Creature Human Wizard +PT:2/3 +T:Mode$ Phase | Phase$ Draw | ValidPlayer$ Player | TriggerZones$ Battlefield | OptionalDecider$ TriggeredPlayer | Execute$ TrigDraw | TriggerDescription$ At the beginning of each player's draw step, that player may draw an additional card. If they do, spells they cast this turn cost {2} more to cast +SVar:TrigDraw:DB$ Draw | NumCards$ 1 | Defined$ TriggeredPlayer | RememberDrawn$ True | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | ConditionDefined$ Remembered | ConditionPresent$ Card | Duration$ EndOfTurn | StaticAbilities$ RaiseCost | SubAbility$ DBCleanup | SpellDescription$ Spells they cast this turn cost {2} more to cast +SVar:RaiseCost:Mode$ RaiseCost | ValidCard$ Card.ActivePlayerCtrl | Type$ Spell | Amount$ 2 | Description$ Spells they cast this turn cost {2} more to cast +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:At the beginning of each player's draw step, that player may draw an additional card. If they do, spells they cast this turn cost {2} more to cast diff --git a/forge-gui/res/cardsfolder/upcoming/academy_wall.txt b/forge-gui/res/cardsfolder/upcoming/academy_wall.txt new file mode 100644 index 00000000000..4e182e2a56e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/academy_wall.txt @@ -0,0 +1,8 @@ +Name:Academy Wall +ManaCost:2 U +Types:Creature Wall +PT:0/5 +K:Defender +T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | OptionalDecider$ You | Execute$ TrigLoot | ActivationLimit$ 1 | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an instant or sorcery spell, you may draw a card. If you do, discard a card. This ability triggers only once each turn. +SVar:TrigLoot:AB$ Discard | Defined$ You | Mode$ TgtChoose | Cost$ Draw<1/You> +Oracle:Defender\nWhenever you cast an instant or sorcery spell, you may draw a card. If you do, discard a card. This ability triggers only once each turn. diff --git a/forge-gui/res/cardsfolder/upcoming/aggressive_sabotage.txt b/forge-gui/res/cardsfolder/upcoming/aggressive_sabotage.txt new file mode 100644 index 00000000000..4ecc1732c34 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/aggressive_sabotage.txt @@ -0,0 +1,7 @@ +Name:Aggressive Sabotage +ManaCost:2 B +Types:Sorcery +K:Kicker:R +A:SP$ Discard | ValidTgts$ Opponent | Mode$ TgtChoose | NumCards$ 2 | SubAbility$ DBDealDamage | SpellDescription$ Target opponent discards two cards, if this spell was kicked, it deals 3 damage to that player. +SVar:DBDealDamage:DB$ DealDamage | Defined$ ParentTarget | Condition$ Kicked | NumDmg$ 3 +Oracle:Kicker {R} (You may pay an additional {R} as you cast this spell.)\nTarget player discards two cards. If this spell was kicked, it deals 3 damage to that player. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/anointed_peacekeeper.txt b/forge-gui/res/cardsfolder/upcoming/anointed_peacekeeper.txt new file mode 100644 index 00000000000..4a19b6facbf --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/anointed_peacekeeper.txt @@ -0,0 +1,14 @@ +Name:Anointed Peacekeeper +ManaCost:2 W +Types:Creature Human Cleric +PT:3/3 +K:Vigilance +K:ETBReplacement:Other:ChoosePlayer +SVar:ChoosePlayer:DB$ ChoosePlayer | Defined$ You | Choices$ Player.Opponent | ChoiceTitle$ Choose an opponent to look at the hand: | SubAbility$ DBLook | SpellDescription$ As CARDNAME enters the battlefield, look at an opponent's hand, then choose any card name. +SVar:DBLook:DB$ RevealHand | Defined$ ChosenPlayer | Look$ True | SubAbility$ DBNameCard +SVar:DBNameCard:DB$ NameCard | Defined$ You | SubAbility$ DBClear +SVar:DBClear:DB$ Cleanup | ClearChosenPlayer$ True +S:Mode$ RaiseCost | EffectZone$ Battlefield | ValidCard$ Card.NamedCard | Type$ Spell | Amount$ 2 | Activator$ Opponent | Description$ Spells your opponents cast with the chosen name cost {2} more to cast. +S:Mode$ RaiseCost | EffectZone$ Battlefield | ValidCard$ Card.NamedCard | Type$ NonManaAbility | Amount$ 2 | Description$ Activated abilities of sources with the chosen name cost {2} more to activate unless they're mana abilities. +AI:RemoveDeck:Random +Oracle:Vigilance\nAs Anointed Peacekeeper enters the battlefield, look at an opponent's hand, then choose any card name.\nSpells your opponents cast with the chosen name cost {2} more to cast.\nActivated abilities of sources with the chosen name cost {2} more to activate unless they're mana abilities. diff --git a/forge-gui/res/cardsfolder/upcoming/argivian_phalanx.txt b/forge-gui/res/cardsfolder/upcoming/argivian_phalanx.txt new file mode 100644 index 00000000000..ccc33c5c225 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/argivian_phalanx.txt @@ -0,0 +1,8 @@ +Name:Argivian Phalanx +ManaCost:5 W +Types:Creature Human Kor Soldier +PT:4/4 +K:Vigilance +S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ X | EffectZone$ All | Description$ This spell costs {1} less to cast for each creature you control. +SVar:X:Count$Valid Creature.YouCtrl +Oracle:This spell costs {1} less to cast for each creature you control.\nVigilance \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/automatic_librarian.txt b/forge-gui/res/cardsfolder/upcoming/automatic_librarian.txt new file mode 100644 index 00000000000..374ddf7ccaa --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/automatic_librarian.txt @@ -0,0 +1,7 @@ +Name:Automatic Librarian +ManaCost:3 +Types:Artifact Creature Construct +PT:3/2 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigScry | TriggerDescription$ When CARDNAME enters the battlefield, scry 2. (Look at the top two cards of your library, then put any number of them on the bottom of your library and the rest on top in any order.) +SVar:TrigScry:DB$ Scry | ScryNum$ 2 +Oracle:When Automatic Librarian enters the battlefield, scry 2. (Look at the top two cards of your library, then put any number of them on the bottom of your library and the rest on top in any order.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/balduvian_atrocity.txt b/forge-gui/res/cardsfolder/upcoming/balduvian_atrocity.txt new file mode 100644 index 00000000000..bde937587b1 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/balduvian_atrocity.txt @@ -0,0 +1,11 @@ +Name:Balduvian Atrocity +ManaCost:2 B +Types:Creature Phyrexian Berserker +PT:2/3 +K:Kicker:R +K:Menace +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self+kicked | Execute$ TrigChange | TriggerDescription$ When CARDNAME enters the battlefield, if it was kicked, return target creature card with mana value 3 or less from your graveyard to the battlefield. It gains haste. Sacrifice it at the beginning of the next end step. +SVar:TrigChange:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ValidTgts$ Creature.YouCtrl+cmcLE3 | SubAbility$ DBPump +SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ Haste | AtEOT$ Sacrifice +DeckHints:Ability$Graveyard +Oracle:Kicker {R} (You may pay an additional {R} as you cast this spell.)\nMenace\nWhen Balduvian Atrocity enters the battlefield, if it was kicked, return target creature card with mana value 3 or less from your graveyard to the battlefield. It gains haste. Sacrifice it at the beginning of the next end step. diff --git a/forge-gui/res/cardsfolder/upcoming/battlewing_mystic.txt b/forge-gui/res/cardsfolder/upcoming/battlewing_mystic.txt new file mode 100644 index 00000000000..839c3675c0c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/battlewing_mystic.txt @@ -0,0 +1,11 @@ +Name:Battlewing Mystic +ManaCost:1 U +Types:Bird Wizard +PT:2/1 +K:Kicker:R +K:Flying +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self+kicked | Execute$ TrigDiscard | TriggerDescription$ When CARDNAME enters the battlefield, if it was kicked, discard your hand, then draw two cards. +SVar:TrigDiscard:DB$ Discard | Mode$ Hand | Defined$ You | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | Condition$ Kicked | Defined$ You | NumCards$ 2 +DeckHints:Ability$Discard +Oracle:Kicker {R} (You may pay an additional {R} as you cast this spell.)\nFlying\nWhen Battlewing Mystic enters the battlefield, if it was kicked, discard your hand, then draw two cards. diff --git a/forge-gui/res/cardsfolder/upcoming/benalish_sleeper.txt b/forge-gui/res/cardsfolder/upcoming/benalish_sleeper.txt new file mode 100644 index 00000000000..43457c1a1e4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/benalish_sleeper.txt @@ -0,0 +1,9 @@ +Name:Benalish Sleeper +ManaCost:1 W +Types:Creature Phyrexian Human Soldier +PT:3/1 +K:Kicker:B +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self+kicked | Execute$ TrigSac | TriggerDescription$ When CARDNAME enters the battlefield, if it was kicked, each player sacrifices a creature. +SVar:TrigSac:DB$ Sacrifice | Defined$ Player | SacValid$ Creature +SVar:NeedsToPlay:Creature.OppCtrl +Oracle:Kicker {B} (You may pay an additional {B} as you cast this spell.)\nWhen Benalish Sleeper enters the battlefield, if it was kicked, each player sacrifices a creature. diff --git a/forge-gui/res/cardsfolder/upcoming/ivy_gleeful_spellthief.txt b/forge-gui/res/cardsfolder/upcoming/ivy_gleeful_spellthief.txt new file mode 100644 index 00000000000..4b96e6e0dbe --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ivy_gleeful_spellthief.txt @@ -0,0 +1,8 @@ +Name:Ivy, Gleeful Spellthief +ManaCost:G U +Types:Legendary Creature Faerie Rogue +PT:2/1 +K:Flying +T:Mode$ SpellCast | TriggerZones$ Battlefield | IsSingleTarget$ True | TargetsValid$ Creature.Other+inZoneBattlefield | Execute$ TrigCopyTarget | OptionalDecider$ You | TriggerDescription$ Whenever a player casts a spell that targets only a single creature other than CARDNAME, you may copy that spell. The copy targets NICKNAME. (A copy of an Aura spell becomes a token.) +SVar:TrigCopyTarget:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | CopyForEachCanTarget$ Card.Self +Oracle:Flying\nWhenever a player casts a spell that targets only a single creature other than Ivy, Gleeful Spellthief, you may copy that spell. The copy targets Ivy. (A copy of an Aura spell becomes a token.) \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/upcoming/timeless_lotus.txt b/forge-gui/res/cardsfolder/upcoming/timeless_lotus.txt new file mode 100644 index 00000000000..710c8bd08d5 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/timeless_lotus.txt @@ -0,0 +1,6 @@ +Name:Timeless Lotus +ManaCost:5 +Types:Legendary Artifact +K:CARDNAME enters the battlefield tapped. +A:AB$ Mana | Cost$ T | Produced$ W U B R G | SpellDescription$ Add {W}{U}{B}{R}{G} +Oracle:Timeless Lotus enters the battlefield tapped.\n{T}: Add {W}{U}{B}{R}{G}. From 7b0f32be63d6a43630a1cce6d26a378a6fd1d6ee Mon Sep 17 00:00:00 2001 From: squee1968 <105706641+squee1968@users.noreply.github.com> Date: Sun, 28 Aug 2022 01:21:56 -0500 Subject: [PATCH 67/70] Rundvelt Hordemaster (#1408) * Rundvelt Hordemaster * Update rundvelt_hordemaster.txt * Update rundvelt_hordemaster.txt * Update rundvelt_hordemaster.txt --- .../cardsfolder/upcoming/rundvelt_hordemaster.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/rundvelt_hordemaster.txt diff --git a/forge-gui/res/cardsfolder/upcoming/rundvelt_hordemaster.txt b/forge-gui/res/cardsfolder/upcoming/rundvelt_hordemaster.txt new file mode 100644 index 00000000000..c171afd4ef9 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/rundvelt_hordemaster.txt @@ -0,0 +1,14 @@ +Name:Rundvelt Hordemaster +ManaCost:1 R +Types:Creature Goblin Warrior +PT:1/1 +S:Mode$ Continuous | AffectedZone$ Battlefield | Affected$ Goblin.Other+YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Other Goblins you control get +1/+1. +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self,Goblin.Other+YouCtrl | Execute$ TrigExile | TriggerDescription$ Whenever CARDNAME or another Goblin you control dies, exile the top card of your library. +SVar:TrigExile:DB$ Dig | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ Play | ForgetOnMoved$ Exile | Duration$ UntilTheEndOfYourNextTurn | ConditionCheckSVar$ Z | ConditionSVarCompare$ EQ1 | SubAbility$ DBCleanup +SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ If it's a Goblin creature card, you may cast that card until the end of your next turn. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:Z:Remembered$Valid Creature.Goblin +DeckNeeds:Type$Goblin +DeckHints:Type$Goblin +Oracle:Other Goblins you control get +1/+1.\nWhenever Rundvelt Hordemaster or another Goblin you control dies, exile the top card of your library. If it's a Goblin creature card, you may cast that card until the end of your next turn. From 69a77412d99263bd8c2a2871d967e7edfe19b78d Mon Sep 17 00:00:00 2001 From: Simisays <67333662+Simisays@users.noreply.github.com> Date: Sun, 28 Aug 2022 15:13:26 +0200 Subject: [PATCH 68/70] Add files via upload (#1411) --- forge-gui/res/cardsfolder/upcoming/contaminated_aquifer.txt | 5 +++++ forge-gui/res/cardsfolder/upcoming/geothermal_bog.txt | 5 +++++ forge-gui/res/cardsfolder/upcoming/haunted_mire.txt | 5 +++++ forge-gui/res/cardsfolder/upcoming/idyllic_beachfront.txt | 5 +++++ forge-gui/res/cardsfolder/upcoming/molten_tributary.txt | 5 +++++ forge-gui/res/cardsfolder/upcoming/radiant_grove.txt | 5 +++++ forge-gui/res/cardsfolder/upcoming/sacred_peaks.txt | 5 +++++ forge-gui/res/cardsfolder/upcoming/sunlit_marsh.txt | 5 +++++ forge-gui/res/cardsfolder/upcoming/tangled_islet.txt | 5 +++++ forge-gui/res/cardsfolder/upcoming/wooded_ridgeline.txt | 5 +++++ 10 files changed, 50 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/contaminated_aquifer.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/geothermal_bog.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/haunted_mire.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/idyllic_beachfront.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/molten_tributary.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/radiant_grove.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/sacred_peaks.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/sunlit_marsh.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/tangled_islet.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/wooded_ridgeline.txt diff --git a/forge-gui/res/cardsfolder/upcoming/contaminated_aquifer.txt b/forge-gui/res/cardsfolder/upcoming/contaminated_aquifer.txt new file mode 100644 index 00000000000..5810a129cc9 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/contaminated_aquifer.txt @@ -0,0 +1,5 @@ +Name:Contaminated Aquifer +ManaCost:no cost +Types:Land Island Swamp +K:CARDNAME enters the battlefield tapped. +Oracle:({T}: Add {U} or {B}.)\nContaminated Aquifer enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/upcoming/geothermal_bog.txt b/forge-gui/res/cardsfolder/upcoming/geothermal_bog.txt new file mode 100644 index 00000000000..c058db87128 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/geothermal_bog.txt @@ -0,0 +1,5 @@ +Name:Geothermal Bog +ManaCost:no cost +Types:Land Swamp Mountain +K:CARDNAME enters the battlefield tapped. +Oracle:({T}: Add {B} or {R}.)\nGeothermal Bog enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/upcoming/haunted_mire.txt b/forge-gui/res/cardsfolder/upcoming/haunted_mire.txt new file mode 100644 index 00000000000..35f8031f8c7 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/haunted_mire.txt @@ -0,0 +1,5 @@ +Name:Haunted Mire +ManaCost:no cost +Types:Land Swamp Forest +K:CARDNAME enters the battlefield tapped. +Oracle:({T}: Add {B} or {G}.)\nHaunted Mire enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/upcoming/idyllic_beachfront.txt b/forge-gui/res/cardsfolder/upcoming/idyllic_beachfront.txt new file mode 100644 index 00000000000..23ab599777d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/idyllic_beachfront.txt @@ -0,0 +1,5 @@ +Name:Idyllic Beachfront +ManaCost:no cost +Types:Land Plains Island +K:CARDNAME enters the battlefield tapped. +Oracle:({T}: Add {W} or {U}.)\nIdyllic Beachfront enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/upcoming/molten_tributary.txt b/forge-gui/res/cardsfolder/upcoming/molten_tributary.txt new file mode 100644 index 00000000000..a20896f0d83 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/molten_tributary.txt @@ -0,0 +1,5 @@ +Name:Molten Tributary +ManaCost:no cost +Types:Land Island Mountain +K:CARDNAME enters the battlefield tapped. +Oracle:({T}: Add {U} or {R}.)\nMolten Tributary enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/upcoming/radiant_grove.txt b/forge-gui/res/cardsfolder/upcoming/radiant_grove.txt new file mode 100644 index 00000000000..0225e9f05a2 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/radiant_grove.txt @@ -0,0 +1,5 @@ +Name:Radiant Grove +ManaCost:no cost +Types:Land Forest Plains +K:CARDNAME enters the battlefield tapped. +Oracle:({T}: Add {G} or {W}.)\nRadiant Grove enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/upcoming/sacred_peaks.txt b/forge-gui/res/cardsfolder/upcoming/sacred_peaks.txt new file mode 100644 index 00000000000..d334cbf5545 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/sacred_peaks.txt @@ -0,0 +1,5 @@ +Name:Sacred Peaks +ManaCost:no cost +Types:Land Mountain Plains +K:CARDNAME enters the battlefield tapped. +Oracle:({T}: Add {R} or {W}.)\nSacred Peaks enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/upcoming/sunlit_marsh.txt b/forge-gui/res/cardsfolder/upcoming/sunlit_marsh.txt new file mode 100644 index 00000000000..9bc6fa46d66 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/sunlit_marsh.txt @@ -0,0 +1,5 @@ +Name:Sunlit Marsh +ManaCost:no cost +Types:Land Plains Swamp +K:CARDNAME enters the battlefield tapped. +Oracle:({T}: Add {W} or {B}.)\nSunlit Marsh enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/upcoming/tangled_islet.txt b/forge-gui/res/cardsfolder/upcoming/tangled_islet.txt new file mode 100644 index 00000000000..f28ba583a54 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/tangled_islet.txt @@ -0,0 +1,5 @@ +Name:Tangled Islet +ManaCost:no cost +Types:Land Forest Island +K:CARDNAME enters the battlefield tapped. +Oracle:({T}: Add {G} or {U}.)\nTangled Islet enters the battlefield tapped. diff --git a/forge-gui/res/cardsfolder/upcoming/wooded_ridgeline.txt b/forge-gui/res/cardsfolder/upcoming/wooded_ridgeline.txt new file mode 100644 index 00000000000..85eb74cbd0d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/wooded_ridgeline.txt @@ -0,0 +1,5 @@ +Name:Wooded Ridgeline +ManaCost:no cost +Types:Land Mountain Forest +K:CARDNAME enters the battlefield tapped. +Oracle:({T}: Add {R} or {G}.)\nWooded Ridgeline enters the battlefield tapped. From 17cf2c39457ad96bbb1890a861bd71f4df7c5ac9 Mon Sep 17 00:00:00 2001 From: squee1968 <105706641+squee1968@users.noreply.github.com> Date: Sun, 28 Aug 2022 08:13:33 -0500 Subject: [PATCH 69/70] Create leaf-crowned_visionary.txt (#1412) --- .../cardsfolder/upcoming/leaf-crowned_visionary.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/leaf-crowned_visionary.txt diff --git a/forge-gui/res/cardsfolder/upcoming/leaf-crowned_visionary.txt b/forge-gui/res/cardsfolder/upcoming/leaf-crowned_visionary.txt new file mode 100644 index 00000000000..7303138582b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/leaf-crowned_visionary.txt @@ -0,0 +1,11 @@ +Name:Leaf-Crowned Visionary +ManaCost:G G +Types:Creature Elf Druid +PT:1/1 +S:Mode$ Continuous | AffectedZone$ Battlefield | Affected$ Elf.Other+YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Other Elves you control get +1/+1. +T:Mode$ SpellCast | ValidCard$ Elf | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigDraw | TriggerDescription$ Whenever you cast an Elf spell, you may pay {G}. If you do, draw a card. +SVar:TrigDraw:AB$Draw | Cost$ G +AI:RemoveDeck:Random +DeckNeeds:Type$Elf +DeckHints:Type$Elf +Oracle:Other Elves you control get +1/+1.\nWhenever you cast an Elf spell, you may pay {G}. If you do, draw a card. From 0c3536a561a947c84cdf922956ba2a6d3ccbb1eb Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Sun, 28 Aug 2022 16:28:55 +0200 Subject: [PATCH 70/70] Read ahead Saga Ability (#1413) --- .../src/main/java/forge/ai/GameState.java | 2 +- .../src/main/java/forge/ai/SpecialCardAi.java | 2 +- .../src/main/java/forge/game/ForgeScript.java | 2 ++ .../src/main/java/forge/game/GameEntity.java | 7 +++--- .../forge/game/GameEntityCounterTable.java | 9 +++++++- .../ability/effects/CountersPutEffect.java | 7 +++++- .../src/main/java/forge/game/card/Card.java | 18 ++++++++++++--- .../java/forge/game/card/CardFactoryUtil.java | 22 +++++++++++++++++-- .../main/java/forge/game/player/Player.java | 6 ++++- .../forge/game/spellability/SpellAbility.java | 11 ++++++++++ .../game/trigger/TriggerAbilityTriggered.java | 7 ++++-- .../game/trigger/TriggerCounterAdded.java | 13 +++++++++++ .../forge/game/trigger/WrappedAbility.java | 14 +++++++++++- .../ai/simulation/GameSimulationTest.java | 16 +++++++------- .../cardsfolder/upcoming/historians_boon.txt | 10 +++++++++ .../upcoming/the_elder_dragon_war.txt | 12 ++++++++++ .../forge/player/PlayerControllerHuman.java | 2 +- 17 files changed, 135 insertions(+), 25 deletions(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/historians_boon.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/the_elder_dragon_war.txt diff --git a/forge-ai/src/main/java/forge/ai/GameState.java b/forge-ai/src/main/java/forge/ai/GameState.java index 40c0d4127ec..dc9782dc05c 100644 --- a/forge-ai/src/main/java/forge/ai/GameState.java +++ b/forge-ai/src/main/java/forge/ai/GameState.java @@ -1201,7 +1201,7 @@ public abstract class GameState { String[] allCounterStrings = counterString.split(","); for (final String counterPair : allCounterStrings) { String[] pair = counterPair.split("=", 2); - entity.addCounterInternal(CounterType.getType(pair[0]), Integer.parseInt(pair[1]), null, false, null); + entity.addCounterInternal(CounterType.getType(pair[0]), Integer.parseInt(pair[1]), null, false, null, null); } } diff --git a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java index 476fbde124e..612695cab97 100644 --- a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java +++ b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java @@ -218,7 +218,7 @@ public class SpecialCardAi { Card animated = AnimateAi.becomeAnimated(sa.getHostCard(), sa.getSubAbility()); if (sa.getHostCard().canReceiveCounters(CounterEnumType.P1P1)) { - animated.addCounterInternal(CounterEnumType.P1P1, 2, ai, false, null); + animated.addCounterInternal(CounterEnumType.P1P1, 2, ai, false, null, null); } boolean isOppEOT = ph.is(PhaseType.END_OF_TURN) && ph.getNextTurn() == ai; boolean isValuableAttacker = ph.is(PhaseType.MAIN1, ai) && ComputerUtilCard.doesSpecifiedCreatureAttackAI(ai, animated); diff --git a/forge-game/src/main/java/forge/game/ForgeScript.java b/forge-game/src/main/java/forge/game/ForgeScript.java index 6ac6897e72d..87b2a061002 100644 --- a/forge-game/src/main/java/forge/game/ForgeScript.java +++ b/forge-game/src/main/java/forge/game/ForgeScript.java @@ -223,6 +223,8 @@ public class ForgeScript { return sa.hasParam("Nightbound"); } else if (property.equals("paidPhyrexianMana")) { return sa.getSpendPhyrexianMana(); + } else if (property.equals("LastChapter")) { + return sa.isLastChapter(); } else if (property.startsWith("ManaSpent")) { String[] k = property.split(" ", 2); String comparator = k[1].substring(0, 2); diff --git a/forge-game/src/main/java/forge/game/GameEntity.java b/forge-game/src/main/java/forge/game/GameEntity.java index f7ba73ef30b..dd2cc5c98af 100644 --- a/forge-game/src/main/java/forge/game/GameEntity.java +++ b/forge-game/src/main/java/forge/game/GameEntity.java @@ -26,6 +26,7 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import forge.game.ability.AbilityKey; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.card.Card; @@ -330,9 +331,9 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { subtractCounter(CounterType.get(counterName), n); } - abstract public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table); - public void addCounterInternal(final CounterEnumType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table) { - addCounterInternal(CounterType.get(counterType), n, source, fireEvents, table); + abstract public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table, Map params); + public void addCounterInternal(final CounterEnumType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table, Map params) { + addCounterInternal(CounterType.get(counterType), n, source, fireEvents, table, params); } public void receiveDamage(Pair dmg) { diff --git a/forge-game/src/main/java/forge/game/GameEntityCounterTable.java b/forge-game/src/main/java/forge/game/GameEntityCounterTable.java index ef0db0e993f..c768247e03e 100644 --- a/forge-game/src/main/java/forge/game/GameEntityCounterTable.java +++ b/forge-game/src/main/java/forge/game/GameEntityCounterTable.java @@ -155,11 +155,18 @@ public class GameEntityCounterTable extends ForwardingTable, Ga continue; } + // Add ETB flag + final Map runParams = AbilityKey.newMap(); + runParams.put(AbilityKey.ETB, etb); + if (params != null) { + runParams.putAll(params); + } + // Apply counter after replacement effect for (Map.Entry, Map> e : values.entrySet()) { boolean remember = cause != null && cause.hasParam("RememberPut"); for (Map.Entry ec : e.getValue().entrySet()) { - gm.getKey().addCounterInternal(ec.getKey(), ec.getValue(), e.getKey().orNull(), true, result); + gm.getKey().addCounterInternal(ec.getKey(), ec.getValue(), e.getKey().orNull(), true, result, runParams); if (remember && ec.getValue() >= 1) { cause.getHostCard().addRemembered(gm.getKey()); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java index f41b7cbdcd0..2b1d895d981 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java @@ -450,11 +450,12 @@ public class CountersPutEffect extends SpellAbilityEffect { 0); } if (sa.hasParam("UpTo")) { + int min = AbilityUtils.calculateAmount(card, sa.getParamOrDefault("UpToMin", "0"), sa); Map params = Maps.newHashMap(); params.put("Target", obj); params.put("CounterType", counterType); counterAmount = pc.chooseNumber(sa, - Localizer.getInstance().getMessage("lblHowManyCounters"), 0, counterAmount, params); + Localizer.getInstance().getMessage("lblHowManyCounters"), min, counterAmount, params); } if (sa.isDividedAsYouChoose() && !sa.usesTargeting()) { Map params = Maps.newHashMap(); @@ -479,6 +480,10 @@ public class CountersPutEffect extends SpellAbilityEffect { } } + if (sa.hasParam("ReadAhead")) { + gameCard.setReadAhead(counterAmount); + } + if (sa.hasParam("Tribute")) { // make a copy to check if it would be on the battlefield Card noTributeLKI = CardUtil.getLKICopy(gameCard); diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index d572e536935..f3323a8b814 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -338,6 +338,8 @@ public class Card extends GameEntity implements Comparable, IHasSVars { private ReplacementEffect shieldCounterReplaceDestroy = null; private ReplacementEffect stunCounterReplaceUntap = null; + private Integer readAhead = null; + // Enumeration for CMC request types public enum SplitCMCMode { CurrentSideCMC, @@ -1405,7 +1407,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } @Override - public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table) { + public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table, Map params) { int addAmount = n; if (addAmount <= 0 || !canReceiveCounters(counterType)) { // As per rule 107.1b @@ -1439,6 +1441,9 @@ public class Card extends GameEntity implements Comparable, IHasSVars { final Map runParams = AbilityKey.mapFromCard(this); runParams.put(AbilityKey.Source, source); runParams.put(AbilityKey.CounterType, counterType); + if (params != null) { + runParams.putAll(params); + } for (int i = 0; i < addAmount; i++) { runParams.put(AbilityKey.CounterAmount, oldValue + i + 1); getGame().getTriggerHandler().runTrigger( @@ -2233,7 +2238,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { || keyword.startsWith("Embalm") || keyword.startsWith("Level up") || keyword.equals("Prowess") || keyword.startsWith("Eternalize") || keyword.startsWith("Reinforce") || keyword.startsWith("Champion") || keyword.startsWith("Prowl") || keyword.startsWith("Adapt") - || keyword.startsWith("Amplify") || keyword.startsWith("Ninjutsu") || keyword.startsWith("Saga") + || keyword.startsWith("Amplify") || keyword.startsWith("Ninjutsu") || keyword.startsWith("Saga") || keyword.startsWith("Read ahead") || keyword.startsWith("Transfigure") || keyword.startsWith("Aura swap") || keyword.startsWith("Cycling") || keyword.startsWith("TypeCycling") || keyword.startsWith("Encore") || keyword.startsWith("Mutate") || keyword.startsWith("Dungeon") @@ -4520,7 +4525,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } return result; } - + public final void addKeywordForStaticAbility(KeywordInterface kw) { if (kw.getStaticId() > 0) { storedKeywords.put(kw.getStaticId(), kw.getOriginal(), kw); @@ -7132,4 +7137,11 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } return StaticAbilityIgnoreLegendRule.ignoreLegendRule(this); } + + public Integer getReadAhead() { + return readAhead; + } + public void setReadAhead(int value) { + readAhead = value; + } } diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 7434da24508..cb3ef24e228 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -1697,7 +1697,7 @@ public class CardFactoryUtil { parsedTrigger.setOverridingAbility(sa); inst.addTrigger(parsedTrigger); - } else if (keyword.startsWith("Saga")) { + } else if (keyword.startsWith("Saga") || keyword.startsWith("Read ahead")) { final String[] k = keyword.split(":"); final List abs = Arrays.asList(k[2].split(",")); if (abs.size() != Integer.valueOf(k[1])) { @@ -1724,9 +1724,10 @@ public class CardFactoryUtil { for (int i = idx; i <= skipId; i++) { SpellAbility sa = AbilityFactory.getAbility(card, ab); sa.setChapter(i); + sa.setLastChapter(idx == abs.size()); StringBuilder trigStr = new StringBuilder("Mode$ CounterAdded | ValidCard$ Card.Self | TriggerZones$ Battlefield"); - trigStr.append("| CounterType$ LORE | CounterAmount$ EQ").append(i); + trigStr.append("| Chapter$ True | CounterType$ LORE | CounterAmount$ EQ").append(i); if (i != idx) { trigStr.append(" | Secondary$ True"); } @@ -2311,6 +2312,23 @@ public class CardFactoryUtil { re.getOverridingAbility().setSVar("Sunburst", "Count$Converge"); } inst.addReplacement(re); + } else if (keyword.startsWith("Read ahead")) { + final String[] k = keyword.split(":"); + String repeffstr = "Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | Secondary$ True | ReplacementResult$ Updated | Description$ Choose a chapter and start with that many lore counters."; + + String effStr = "DB$ PutCounter | Defined$ Self | CounterType$ LORE | ETB$ True | UpTo$ True | UpToMin$ 1 | ReadAhead$ True | CounterNum$ " + k[1]; + + SpellAbility saCounter = AbilityFactory.getAbility(effStr, card); + + if (!intrinsic) { + saCounter.setIntrinsic(false); + } + + ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, host, intrinsic, card); + + re.setOverridingAbility(saCounter); + + inst.addReplacement(re); } else if (keyword.equals("Rebound")) { String repeffstr = "Event$ Moved | ValidLKI$ Card.Self+wasCastFromHand+YouOwn+YouCtrl " + " | Origin$ Stack | Destination$ Graveyard | Fizzle$ False " diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index 0dc1738b021..4fd95a2c9d8 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -835,7 +835,8 @@ public class Player extends GameEntity implements Comparable { return true; } - public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table) { + @Override + public void addCounterInternal(final CounterType counterType, final int n, final Player source, final boolean fireEvents, GameEntityCounterTable table, Map params) { int addAmount = n; if (addAmount <= 0 || !canReceiveCounters(counterType)) { // As per rule 107.1b @@ -849,6 +850,9 @@ public class Player extends GameEntity implements Comparable { final Map runParams = AbilityKey.mapFromPlayer(this); runParams.put(AbilityKey.Source, source); runParams.put(AbilityKey.CounterType, counterType); + if (params != null) { + runParams.putAll(params); + } for (int i = 0; i < addAmount; i++) { runParams.put(AbilityKey.CounterAmount, oldValue + i + 1); getGame().getTriggerHandler().runTrigger(TriggerType.CounterAdded, AbilityKey.newMap(runParams), false); diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index da3dd1b2383..9fa31cdd55f 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -135,6 +135,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit private boolean cumulativeupkeep = false; private boolean blessing = false; private Integer chapter = null; + private boolean lastChapter = false; /** The pay costs. */ private Cost payCosts; @@ -1066,6 +1067,13 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit chapter = val; } + public boolean isLastChapter() { + return lastChapter; + } + public boolean setLastChapter(boolean value) { + return lastChapter = value; + } + public StaticAbility getMayPlay() { return mayPlay; } @@ -1129,6 +1137,9 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit clone.paidAbilities = Lists.newArrayList(); clone.setPaidHash(Maps.newHashMap(getPaidHash())); + // copy last chapter flag for Trigger + clone.lastChapter = this.lastChapter; + if (usesTargeting()) { // the targets need to be cloned, otherwise they might be cleared clone.targetChosen = getTargets().clone(); diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerAbilityTriggered.java b/forge-game/src/main/java/forge/game/trigger/TriggerAbilityTriggered.java index 45ea1fa3851..bace9cd7439 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerAbilityTriggered.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerAbilityTriggered.java @@ -19,7 +19,6 @@ package forge.game.trigger; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; -import forge.game.Game; import forge.game.ability.AbilityKey; import forge.game.card.Card; import forge.game.card.CardZoneTable; @@ -54,8 +53,8 @@ public class TriggerAbilityTriggered extends Trigger { return false; } final Card source = spellAbility.getHostCard(); + @SuppressWarnings("unchecked") final Iterable causes = (Iterable) runParams.get(AbilityKey.Cause); - final Game game = source.getGame(); if (hasParam("ValidMode")) { List validModes = Arrays.asList(getParam("ValidMode").split(",")); @@ -73,6 +72,10 @@ public class TriggerAbilityTriggered extends Trigger { } } + if (!matchesValidParam("ValidSpellAbility", spellAbility)) { + return false; + } + if (!matchesValidParam("ValidSource", source)) { return false; } diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerCounterAdded.java b/forge-game/src/main/java/forge/game/trigger/TriggerCounterAdded.java index 3cf55d0f868..bc652bc459b 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerCounterAdded.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerCounterAdded.java @@ -89,6 +89,19 @@ public class TriggerCounterAdded extends Trigger { } } + // TODO check CR for Read Ahead when they are out + // for now assume it only is about etb counter + if (hasParam("Chapter") && runParams.containsKey(AbilityKey.ETB) && true == (boolean)runParams.get(AbilityKey.ETB)) { + Card card = (Card)runParams.get(AbilityKey.Card); + Integer readAhead = card.getReadAhead(); + if (readAhead != null) { + final int actualAmount = (Integer) runParams.get(AbilityKey.CounterAmount); + if (actualAmount < readAhead) { + return false; + } + } + } + return true; } diff --git a/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java b/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java index 5e512dad07b..ac6dbc662c1 100644 --- a/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java +++ b/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java @@ -286,19 +286,30 @@ public class WrappedAbility extends Ability { return sa.isCycling(); } - + @Override public boolean isChapter() { return sa.isChapter(); } + @Override public Integer getChapter() { return sa.getChapter(); } + @Override public void setChapter(int val) { sa.setChapter(val); } + @Override + public boolean isLastChapter() { + return sa.isLastChapter(); + } + @Override + public boolean setLastChapter(boolean value) { + return sa.setLastChapter(value); + } + @Override public boolean isFlashBackAbility() { return sa.isFlashBackAbility(); @@ -566,4 +577,5 @@ public class WrappedAbility extends Ability { public void setChosenList(List choices) { sa.setChosenList(choices); } + } \ No newline at end of file diff --git a/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulationTest.java b/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulationTest.java index bd4dad3a7f8..3641d7c3254 100644 --- a/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulationTest.java +++ b/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulationTest.java @@ -230,7 +230,7 @@ public class GameSimulationTest extends SimulationTest { Game game = initAndCreateGame(); Player p = game.getPlayers().get(1); Card sorin = addCard("Sorin, Solemn Visitor", p); - sorin.addCounterInternal(CounterEnumType.LOYALTY, 5, p, false, null); + sorin.addCounterInternal(CounterEnumType.LOYALTY, 5, p, false, null, null); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getAction().checkStateEffects(true); @@ -275,7 +275,7 @@ public class GameSimulationTest extends SimulationTest { String bearCardName = "Runeclaw Bear"; addCard(bearCardName, p); Card gideon = addCard("Gideon, Ally of Zendikar", p); - gideon.addCounterInternal(CounterEnumType.LOYALTY, 4, p, false, null); + gideon.addCounterInternal(CounterEnumType.LOYALTY, 4, p, false, null, null); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getAction().checkStateEffects(true); @@ -404,7 +404,7 @@ public class GameSimulationTest extends SimulationTest { Game game = initAndCreateGame(); Player p = game.getPlayers().get(1); Card sarkhan = addCard(sarkhanCardName, p); - sarkhan.addCounterInternal(CounterEnumType.LOYALTY, 4, p, false, null); + sarkhan.addCounterInternal(CounterEnumType.LOYALTY, 4, p, false, null, null); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getAction().checkStateEffects(true); @@ -439,7 +439,7 @@ public class GameSimulationTest extends SimulationTest { addCard(ornithoperCardName, p); addCard(bearCardName, p); Card ajani = addCard(ajaniCardName, p); - ajani.addCounterInternal(CounterEnumType.LOYALTY, 4, p, false, null); + ajani.addCounterInternal(CounterEnumType.LOYALTY, 4, p, false, null, null); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getAction().checkStateEffects(true); @@ -472,7 +472,7 @@ public class GameSimulationTest extends SimulationTest { SpellAbility boltSA = boltCard.getFirstSpellAbility(); Card ajani = addCard(ajaniCardName, p); - ajani.addCounterInternal(CounterEnumType.LOYALTY, 8, p, false, null); + ajani.addCounterInternal(CounterEnumType.LOYALTY, 8, p, false, null, null); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getAction().checkStateEffects(true); @@ -523,7 +523,7 @@ public class GameSimulationTest extends SimulationTest { addCard("Swamp", p); addCard("Swamp", p); Card depths = addCard("Dark Depths", p); - depths.addCounterInternal(CounterEnumType.ICE, 10, p, false, null); + depths.addCounterInternal(CounterEnumType.ICE, 10, p, false, null, null); Card thespian = addCard("Thespian's Stage", p); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getAction().checkStateEffects(true); @@ -2256,7 +2256,7 @@ public class GameSimulationTest extends SimulationTest { Player p = game.getPlayers().get(0); Card polukranos = addCard(polukranosCardName, p); - polukranos.addCounterInternal(CounterEnumType.P1P1, 6, p, false, null); + polukranos.addCounterInternal(CounterEnumType.P1P1, 6, p, false, null, null); addCard(hydraCardName, p); addCard(leylineCardName, p); for (int i = 0; i < 2; ++i) { @@ -2301,7 +2301,7 @@ public class GameSimulationTest extends SimulationTest { } Card nishoba = addCard(nishobaName, p1); - nishoba.addCounterInternal(CounterEnumType.P1P1, 7, p1, false, null); + nishoba.addCounterInternal(CounterEnumType.P1P1, 7, p1, false, null, null); addCard(capridorName, p1); Card pridemate = addCard(pridemateName, p1); Card indestructibility = addCard(indestructibilityName, p1); diff --git a/forge-gui/res/cardsfolder/upcoming/historians_boon.txt b/forge-gui/res/cardsfolder/upcoming/historians_boon.txt new file mode 100644 index 00000000000..dbf3831cd42 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/historians_boon.txt @@ -0,0 +1,10 @@ +Name:Historian's Boon +ManaCost:3 W +Types:Enchantment +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self,Enchantment.nonToken+Other+YouCtrl | Execute$ TrigSmallToken | TriggerDescription$ Whenever CARDNAME or another nontoken enchantment enters the battlefield under your control, create a 1/1 white Soldier creature token. +SVar:TrigSmallToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_soldier | TokenOwner$ You +T:Mode$ AbilityTriggered | ValidMode$ CounterAdded | ValidSpellAbility$ Triggered.LastChapter | TriggerZones$ Battlefield | Execute$ TrigBigToken | TriggerDescription$ Whenever the final chapter of a Saga you control triggers, create a 4/4 white Angel creature token with flying and vigilance. +SVar:TrigBigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_4_4_angel_flying_vigilance | TokenOwner$ You +DeckHas:Ability$Token +DeckHints:Type$Enchantment|Saga +Oracle:Whenever Historian’s Boon or another nontoken enchantment enters the battlefield under your control, create a 1/1 white Soldier creature token.\nWhenever the final chapter of a Saga you control triggers, create a 4/4 white Angel creature token with flying and vigilance. diff --git a/forge-gui/res/cardsfolder/upcoming/the_elder_dragon_war.txt b/forge-gui/res/cardsfolder/upcoming/the_elder_dragon_war.txt new file mode 100644 index 00000000000..be93ceab96a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/the_elder_dragon_war.txt @@ -0,0 +1,12 @@ +Name:The Elder Dragon War +ManaCost:2 R R +Types:Enchantment Saga +K:Read ahead:3:DBDealDamage,DBDiscard,DBToken +SVar:DBDealDamage:DB$ DamageAll | ValidCards$ Creature | ValidPlayers$ Opponent | NumDmg$ 2 | ValidDescription$ each creature and each opponent. | SpellDescription$ CARDNAME deals 2 damage to each opponent and you gain 2 life. +SVar:DBDiscard:DB$ Discard | AnyNumber$ True | Optional$ True | Mode$ TgtChoose | RememberDiscarded$ True | SubAbility$ DBDraw | StackDescription$ {p:You} discards any number of cards, | SpellDescription$ Discard any number of cards, +SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ Y | SubAbility$ DBCleanup | StackDescription$ then draws that many cards. | SpellDescription$ then draw that many cards. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:Y:Count$RememberedSize +SVar:DBToken:DB$ Token | TokenScript$ r_4_4_dragon_flying | SpellDescription$ Create a 4/4 red Dragon creature token with flying. +DeckHas:Ability$Token +Oracle:Read ahead (Choose a chapter and start with that many lore counters. Add one after your draw step. Skipped chapters don’t trigger. Sacrifice after III.)\nI — The Elder Dragon War deals 2 damage to each creature and each opponent.\nII — Discard any number of cards, then draw that many cards.\nIII — Create a 4/4 red Dragon creature token with flying. diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 7e0a4b8ee01..2b3d675b671 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -2527,7 +2527,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont if (subtract) { card.subtractCounter(counter, count); } else { - card.addCounterInternal(counter, count, card.getController(), false, null); + card.addCounterInternal(counter, count, card.getController(), false, null, null); } }