diff --git a/projects/mtg/Android/src/net/wagic/utils/ImgDownloader.java b/projects/mtg/Android/src/net/wagic/utils/ImgDownloader.java index aa6dbaea7..3ab67110f 100644 --- a/projects/mtg/Android/src/net/wagic/utils/ImgDownloader.java +++ b/projects/mtg/Android/src/net/wagic/utils/ImgDownloader.java @@ -957,8 +957,10 @@ public class ImgDownloader { cardurl = "https://img.scryfall.com/cards/large/front/1/f/1fe2b76f-ddb7-49d5-933b-ccb06be5d46f.jpg?1562875903"; else if (id.equals("376399")) cardurl = "https://img.scryfall.com/cards/large/front/c/e/cec89c38-0b72-44b0-ac6c-7eb9503e1256.jpg?1562938742"; - else if (id.equals("451089")) + else if (id.equals("451089") || id.equals("45108910t")) cardurl = "https://img.scryfall.com/cards/large/front/5/8/58164521-aeec-43fc-9db9-d595432dea6f.jpg?1564694999"; + else if (id.equals("451089t")) + cardurl = "https://c1.scryfall.com/file/scryfall-cards/large/front/c/5/c5ad13b4-bbf5-4c98-868f-4d105eaf8833.jpg?1592710082"; else if (id.equals("470745")) cardurl = "https://img.scryfall.com/cards/large/front/c/a/ca4caa4e-6b8f-4be8-b177-de2ebe2c9201.jpg?1567044873"; else if (id.equals("470609")) diff --git a/projects/mtg/bin/Res/sets/C18/_cards.dat b/projects/mtg/bin/Res/sets/C18/_cards.dat index 87283f20d..1cf18f9d7 100644 --- a/projects/mtg/bin/Res/sets/C18/_cards.dat +++ b/projects/mtg/bin/Res/sets/C18/_cards.dat @@ -672,8 +672,8 @@ rarity=C [/card] [card] primitive=Dokai, Weaver of Life -id=451089 -rarity=R +id=-45108910 +rarity=T [/card] [card] primitive=Budoka Gardener diff --git a/projects/mtg/bin/Res/sets/PAL00/_cards.dat b/projects/mtg/bin/Res/sets/PAL00/_cards.dat index 097f67544..1068fbcb5 100644 --- a/projects/mtg/bin/Res/sets/PAL00/_cards.dat +++ b/projects/mtg/bin/Res/sets/PAL00/_cards.dat @@ -7,7 +7,7 @@ total=11 [/meta] [card] primitive=Duress -id=17973 +id=18040 rarity=R [/card] [card] diff --git a/projects/mtg/bin/Res/sets/UST/_cards.dat b/projects/mtg/bin/Res/sets/UST/_cards.dat index 56af981f7..37e4214af 100644 --- a/projects/mtg/bin/Res/sets/UST/_cards.dat +++ b/projects/mtg/bin/Res/sets/UST/_cards.dat @@ -3,7 +3,7 @@ author=Wagic Team name=Unstable orderindex=UN-3.UST year=2017-12-08 -total=269 +total=268 [/meta] [card] primitive=Adorable Kitten @@ -1345,8 +1345,3 @@ primitive=Enraged Killbot id=439657 rarity=C [/card] -[card] -primitive=Baffling End -id=439658 -rarity=U -[/card] diff --git a/projects/mtg/bin/Res/sets/WAR/_cards.dat b/projects/mtg/bin/Res/sets/WAR/_cards.dat index f5d27cd4d..fc0f2156e 100644 --- a/projects/mtg/bin/Res/sets/WAR/_cards.dat +++ b/projects/mtg/bin/Res/sets/WAR/_cards.dat @@ -4,7 +4,7 @@ name=War of the Spark block=Guilds of Ravnica orderindex=EXP-ZZC.WAR year=2019-05-03 -total=311 +total=275 [/meta] [card] primitive=Ahn-Crop Invader @@ -27,11 +27,6 @@ id=461111 rarity=R [/card] [card] -primitive=Ajani, the Greathearted -id=null -rarity=R -[/card] -[card] primitive=Angrath's Rampage id=461112 rarity=U @@ -42,11 +37,6 @@ id=461154 rarity=U [/card] [card] -primitive=Angrath, Captain of Chaos -id=null -rarity=U -[/card] -[card] primitive=Arboreal Grazer id=461076 rarity=C @@ -62,11 +52,6 @@ id=461077 rarity=U [/card] [card] -primitive=Arlinn, Voice of the Pack -id=null -rarity=U -[/card] -[card] primitive=Ashiok's Skulker id=460967 rarity=C @@ -77,11 +62,6 @@ id=461155 rarity=U [/card] [card] -primitive=Ashiok, Dream Render -id=null -rarity=U -[/card] -[card] primitive=Augur of Bolas id=460968 rarity=U @@ -222,11 +202,6 @@ id=461046 rarity=R [/card] [card] -primitive=Chandra, Fire Artisan -id=null -rarity=R -[/card] -[card] primitive=Charity Extractor id=461008 rarity=C @@ -282,11 +257,6 @@ id=461010 rarity=U [/card] [card] -primitive=Davriel, Rogue Shadowmage -id=null -rarity=U -[/card] -[card] primitive=Deathsprout id=461116 rarity=U @@ -337,11 +307,6 @@ id=461118 rarity=R [/card] [card] -primitive=Domri, Anarch of Bolas -id=null -rarity=R -[/card] -[card] primitive=Dovin's Veto id=461120 rarity=U @@ -352,11 +317,6 @@ id=461156 rarity=U [/card] [card] -primitive=Dovin, Hand of Control -id=null -rarity=U -[/card] -[card] primitive=Dreadhorde Arcanist id=461052 rarity=R @@ -507,11 +467,6 @@ id=460940 rarity=M [/card] [card] -primitive=Gideon Blackblade -id=null -rarity=M -[/card] -[card] primitive=Gideon's Battle Cry id=463834 rarity=R @@ -627,11 +582,6 @@ id=461157 rarity=U [/card] [card] -primitive=Huatli, the Sun's Heart -id=null -rarity=U -[/card] -[card] primitive=Ignite the Beacon id=460945 rarity=R @@ -707,11 +657,6 @@ id=460981 rarity=R [/card] [card] -primitive=Jace, Wielder of Mysteries -id=null -rarity=R -[/card] -[card] primitive=Jaya's Greeting id=461063 rarity=C @@ -722,21 +667,11 @@ id=461062 rarity=U [/card] [card] -primitive=Jaya, Venerated Firemage -id=null -rarity=U -[/card] -[card] primitive=Jiang Yanggu, Wildcrafter id=461091 rarity=U [/card] [card] -primitive=Jiang Yanggu, Wildcrafter -id=null -rarity=U -[/card] -[card] primitive=Karn's Bastion id=461175 rarity=R @@ -747,11 +682,6 @@ id=460928 rarity=R [/card] [card] -primitive=Karn, the Great Creator -id=null -rarity=R -[/card] -[card] primitive=Kasmina's Transmutation id=460984 rarity=C @@ -762,11 +692,6 @@ id=460983 rarity=U [/card] [card] -primitive=Kasmina, Enigmatic Mentor -id=null -rarity=U -[/card] -[card] primitive=Kaya's Ghostform id=461021 rarity=C @@ -777,11 +702,6 @@ id=461158 rarity=U [/card] [card] -primitive=Kaya, Bane of the Dead -id=null -rarity=U -[/card] -[card] primitive=Kiora's Dambreaker id=460985 rarity=C @@ -792,11 +712,6 @@ id=461159 rarity=U [/card] [card] -primitive=Kiora, Behemoth Beckoner -id=null -rarity=U -[/card] -[card] primitive=Kraul Stinger id=461092 rarity=C @@ -847,11 +762,6 @@ id=461024 rarity=M [/card] [card] -primitive=Liliana, Dreadhorde General -id=null -rarity=M -[/card] -[card] primitive=Living Twister id=461130 rarity=R @@ -937,11 +847,6 @@ id=461160 rarity=U [/card] [card] -primitive=Nahiri, Storm of Stone -id=null -rarity=U -[/card] -[card] primitive=Narset's Reversal id=460989 rarity=R @@ -952,11 +857,6 @@ id=460988 rarity=U [/card] [card] -primitive=Narset, Parter of Veils -id=null -rarity=U -[/card] -[card] primitive=Neheb, Dreadhorde Champion id=461067 rarity=R @@ -977,11 +877,6 @@ id=461134 rarity=M [/card] [card] -primitive=Nicol Bolas, Dragon-God -id=null -rarity=M -[/card] -[card] primitive=Nissa's Triumph id=461097 rarity=U @@ -992,11 +887,6 @@ id=461096 rarity=R [/card] [card] -primitive=Nissa, Who Shakes the World -id=null -rarity=R -[/card] -[card] primitive=Niv-Mizzet Reborn id=461135 rarity=M @@ -1022,11 +912,6 @@ id=461027 rarity=U [/card] [card] -primitive=Ob Nixilis, the Hate-Twisted -id=null -rarity=U -[/card] -[card] primitive=Orzhov Guildgate id=463836 rarity=C @@ -1112,11 +997,6 @@ id=461138 rarity=R [/card] [card] -primitive=Ral, Storm Conduit -id=null -rarity=R -[/card] -[card] primitive=Rally of Wings id=460954 rarity=U @@ -1172,11 +1052,6 @@ id=461161 rarity=U [/card] [card] -primitive=Saheeli, Sublime Artificer -id=null -rarity=U -[/card] -[card] primitive=Samut's Sprint id=461069 rarity=C @@ -1187,21 +1062,11 @@ id=461162 rarity=U [/card] [card] -primitive=Samut, Tyrant Smasher -id=null -rarity=U -[/card] -[card] primitive=Sarkhan the Masterless id=461070 rarity=R [/card] [card] -primitive=Sarkhan the Masterless -id=null -rarity=R -[/card] -[card] primitive=Sarkhan's Catharsis id=461071 rarity=C @@ -1252,11 +1117,6 @@ id=461144 rarity=R [/card] [card] -primitive=Sorin, Vengeful Bloodlord -id=null -rarity=R -[/card] -[card] primitive=Soul Diviner id=461145 rarity=R @@ -1337,11 +1197,6 @@ id=461147 rarity=R [/card] [card] -primitive=Tamiyo, Collector of Tales -id=null -rarity=R -[/card] -[card] primitive=Teferi's Time Twist id=460999 rarity=C @@ -1352,11 +1207,6 @@ id=461148 rarity=R [/card] [card] -primitive=Teferi, Time Raveler -id=null -rarity=R -[/card] -[card] primitive=Tenth District Legionnaire id=461149 rarity=U @@ -1372,11 +1222,6 @@ id=460959 rarity=U [/card] [card] -primitive=Teyo, the Shieldmage -id=null -rarity=U -[/card] -[card] primitive=Tezzeret, Master of the Bridge id=463842 rarity=M @@ -1392,11 +1237,6 @@ id=460964 rarity=U [/card] [card] -primitive=The Wanderer -id=null -rarity=U -[/card] -[card] primitive=Thunder Drake id=461000 rarity=C @@ -1417,11 +1257,6 @@ id=461073 rarity=U [/card] [card] -primitive=Tibalt, Rakish Instigator -id=null -rarity=U -[/card] -[card] primitive=Time Wipe id=461150 rarity=R @@ -1482,11 +1317,6 @@ id=460929 rarity=R [/card] [card] -primitive=Ugin, the Ineffable -id=null -rarity=R -[/card] -[card] primitive=Unlikely Aid id=461036 rarity=C @@ -1512,11 +1342,6 @@ id=461107 rarity=R [/card] [card] -primitive=Vivien, Champion of the Wilds -id=null -rarity=R -[/card] -[card] primitive=Vizier of the Scorpion id=461038 rarity=U @@ -1532,11 +1357,6 @@ id=461163 rarity=U [/card] [card] -primitive=Vraska, Swarm's Eminence -id=null -rarity=U -[/card] -[card] primitive=Wall of Runes id=461002 rarity=C diff --git a/projects/mtg/bin/Res/sets/primitives/_macros.txt b/projects/mtg/bin/Res/sets/primitives/_macros.txt index 8174ad7c2..bfc2ceb9c 100644 --- a/projects/mtg/bin/Res/sets/primitives/_macros.txt +++ b/projects/mtg/bin/Res/sets/primitives/_macros.txt @@ -12,9 +12,6 @@ # Basic Landcycling #AUTO_DEFINE __BASIC_LANDCYCLING__($cost) $cost{cycle}:name(basic landcycling) moveTo(myhand) target(land[basic]|mylibrary) -# Fabricate -#AUTO_DEFINE _FABRICATE_($c) transforms((,newability[choice counter(1/1.$c)],newability[choice create(Servo:Artifact Creature Servo:1/1)*$c])) ueot - # Dies, Evergreen #AUTO_DEFINE _DIES_ @movedTo(this|mygraveyard) from(battlefield): diff --git a/projects/mtg/bin/Res/sets/primitives/borderline.txt b/projects/mtg/bin/Res/sets/primitives/borderline.txt index ae3e8c973..6fbb5a281 100644 --- a/projects/mtg/bin/Res/sets/primitives/borderline.txt +++ b/projects/mtg/bin/Res/sets/primitives/borderline.txt @@ -173,7 +173,7 @@ toughness=2 [card] name=Act of Authority auto=may name(Exile artifact or enchantment) target(*[artifact;enchantment]|battlefield) moveTo(ownerExile) -auto=@each my upkeep:ability$!name(Choose one) choice name(Exile opponent's artifact or enchantment) target(*[artifact;enchantment]|opponentbattlefield) moveTo(ownerExile) && all(mystored) moveto(opponentBattlefield) _ choice name(Exile your artifact or enchantment) target(*[artifact;enchantment]|mybattlefield) moveTo(ownerExile) _ choice name(Don't exile any artifact or enchantment) donothing!$ controller +auto=@each my upkeep:ability$!name(Choose one) choice name(Exile opponent's artifact or enchantment) target(*[artifact;enchantment]|opponentbattlefield) moveTo(ownerExile) && all(mysource) moveto(opponentBattlefield) _ choice name(Exile your artifact or enchantment) target(*[artifact;enchantment]|mybattlefield) moveTo(ownerExile) _ choice name(Don't exile any artifact or enchantment) donothing!$ controller text=When Act of Authority enters the battlefield, you may exile target artifact or enchantment. -- At the beginning of your upkeep, you may exile target artifact or enchantment. If you do, its controller gains control of Act of Authority. mana={1}{W}{W} type=Enchantment @@ -526,7 +526,7 @@ type=Sorcery [/card] [card] name=Agadeem, the Undercrypt -auto=ability$!name(Choose one) choice name(Pay 3 life) life:-3 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 3 life) life:-3 _ choice name(Tap) tap(noevent) all(mysource)!$ controller auto={T}:add{B} text=As Agadeem, the Undercrypt enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped. -- {T}: Add {B}. type=Land @@ -1040,6 +1040,21 @@ power=2 toughness=2 [/card] [card] +name=Alrund, God of the Cosmos +other={1}{U} name(Hakka, Whispering Raven) +otherrestriction=can play creature +autostack=if paid(alternative) then name(Hakka, Whispering Raven) name(Hakka, Whispering Raven) flip(Hakka, Whispering Raven) forcetype(Legendary Creature) +auto=this(variable{isflipped}<1) foreach(*[foretold]|myexile) 1/1 +auto=@each my endofturn restriction{compare(isflipped)~equalto~0}:transforms((,newability[choice name(Creature) reveal:2 optionone name(Get Creature) target(<2>Creature|reveal) moveto(myhand) optiononeend optiontwo name(Bottom of library) target(<2>*|reveal) bottomoflibrary optiontwoend revealend],newability[choice name(Artifact) reveal:2 optionone name(Get Artifact) target(<2>artifact|reveal) moveto(myhand) optiononeend optiontwo name(Bottom of library) target(<2>*|reveal) bottomoflibrary optiontwoend revealend],newability[choice name(Enchantment) reveal:2 optionone name(Get Enchantment) target(<2>enchantment|reveal) moveto(myhand) optiononeend optiontwo name(Bottom of library) target(<2>*|reveal) bottomoflibrary optiontwoend revealend],newability[choice name(Instant) reveal:2 optionone name(Get Instant) target(<2>instant|reveal) moveto(myhand) optiononeend optiontwo name(put in grave) name(Bottom of library) bottomoflibrary optiontwoend revealend],newability[choice name(Land) reveal:2 optionone name(Get Land) target(<2>land|reveal) moveto(myhand) optiononeend optiontwo name(Bottom of library) target(<2>*|reveal) bottomoflibrary optiontwoend revealend],newability[choice name(Planeswalker) reveal:2 optionone name(Get Planeswalker) target(<2>planeswalker|reveal) moveto(myhand) optiononeend optiontwo name(Bottom of library) target(<2>*|reveal) bottomoflibrary optiontwoend revealend],newability[choice name(Sorcery) reveal:2 optionone name(Get Sorcery) target(<2>sorcery|reveal) moveto(myhand) optiononeend optiontwo name(Bottom of library) target(<2>*|reveal) bottomoflibrary optiontwoend revealend],newability[choice name(Tribal) reveal:2 optionone name(Get Tribal) target(<2>tribal|reveal) moveto(myhand) optiononeend optiontwo name(Bottom of library) target(<2>*|reveal) bottomoflibrary optiontwoend revealend])) oneshot +aicode=@each my endofturn restriction{compare(isflipped)~equalto~0}:ability$!name(Choose one) choice name(Creature) all(*[creature;zpos<=2]|mylibrary) moveto(myhand) && all(*[-creature;zpos<=2]|mylibrary) bottomoflibrary _ choice name(Artifact) all(*[artifact;zpos<=2]|mylibrary) moveto(myhand) && all(*[-artifact;zpos<=2]|mylibrary) bottomoflibrary _ choice name(Enchantment) all(*[enchantment;zpos<=2]|mylibrary) moveto(myhand) && all(*[-enchantment;zpos<=2]|mylibrary) bottomoflibrary _ choice name(Instant) all(*[instant;zpos<=2]|mylibrary) moveto(myhand) && all(*[-instant;zpos<=2]|mylibrary) bottomoflibrary _ choice name(Land) all(*[land;zpos<=2]|mylibrary) moveto(myhand) && all(*[-land;zpos<=2]|mylibrary) bottomoflibrary _ choice name(Planeswalker) all(*[planeswalker;zpos<=2]|mylibrary) moveto(myhand) && all(*[-planeswalker;zpos<=2]|mylibrary) bottomoflibrary _ choice name(Sorcery) all(*[sorcery;zpos<=2]|mylibrary) moveto(myhand) && all(*[-sorcery;zpos<=2]|mylibrary) bottomoflibrary _ choice name(Tribal) all(*[tribal;zpos<=2]|mylibrary) moveto(myhand) && all(*[-tribal;zpos<=2]|mylibrary) bottomoflibrary!$ controller +text=Alrund gets +1/+1 for each card in your hand and each foretold card you own in exile. -- At the beginning of your end step, choose a card type, then reveal the top two cards of your library. Put all cards of the chosen type into your hand and the rest on the bottom of your library in any order. +mana={3}{U}{U} +type=Legendary Creature +subtype=God +power=1 +toughness=1 +[/card] +[card] name=Alseid of Life's Bounty abilities=lifelink auto={1}{S}:name(Protection from white) protection from white target(creature,enchantment|myBattlefield) @@ -6713,8 +6728,8 @@ toughness=3 [/card] [card] name=Carrion Rats -auto=@combat(attacking,blocking) source(this):ability$!name(Choose one) choice name(Exile a card) moveto(exile) target(*|mygraveyard) && all(mystored) fog from(this) _ choice name(Don't exile any card) donothing!$ opponent -auto=@combat(attacking,blocking) source(this):ability$!name(Choose one) choice name(Exile a card) moveto(exile) target(*|mygraveyard) && all(mystored) fog from(this) _ choice name(Don't exile any card) donothing!$ controller +auto=@combat(attacking,blocking) source(this):ability$!name(Choose one) choice name(Exile a card) moveto(exile) target(*|mygraveyard) && all(mysource) fog from(this) _ choice name(Don't exile any card) donothing!$ opponent +auto=@combat(attacking,blocking) source(this):ability$!name(Choose one) choice name(Exile a card) moveto(exile) target(*|mygraveyard) && all(mysource) fog from(this) _ choice name(Don't exile any card) donothing!$ controller text=Whenever Carrion Rats attacks or blocks, any player may exile a card from his or her graveyard. If a player does, Carrion Rats assigns no combat damage this turn. mana={B} type=Creature @@ -6734,8 +6749,8 @@ toughness=1 [/card] [card] name=Carrion Wurm -auto=@combat(attacking,blocking) source(this):ability$!name(Choose one) choice name(Exile a card) moveto(exile) target(*|mygraveyard) && all(mystored) fog from(this) _ choice name(Don't exile any card) donothing!$ opponent -auto=@combat(attacking,blocking) source(this):ability$!name(Choose one) choice name(Exile a card) moveto(exile) target(*|mygraveyard) && all(mystored) fog from(this) _ choice name(Don't exile any card) donothing!$ controller +auto=@combat(attacking,blocking) source(this):ability$!name(Choose one) choice name(Exile a card) moveto(exile) target(*|mygraveyard) && all(mysource) fog from(this) _ choice name(Don't exile any card) donothing!$ opponent +auto=@combat(attacking,blocking) source(this):ability$!name(Choose one) choice name(Exile a card) moveto(exile) target(*|mygraveyard) && all(mysource) fog from(this) _ choice name(Don't exile any card) donothing!$ controller text=Whenever Carrion Wurm attacks or blocks, any player may exile three cards from his or her graveyard. If a player does, Carrion Wurm assigns no combat damage this turn. mana={3}{B}{B} type=Creature @@ -11091,7 +11106,7 @@ toughness=2 [/card] [card] name=Deadeye Tracker -auto={1}{B}{T}:moveto(exile) target(<2>*|opponentgraveyard) && explores && reveal:1 optionone if type(land|reveal)~lessthan~1 then transforms((,newability[counter(1/1)])) forever optiononeend optiontwo if type(land|reveal)~morethan~0 then name(move to Hand) target(<1>*|reveal) moveto(myHand) else transforms((,newability[Choice name(back to library) target(<1>*|reveal) moveto(mylibrary)],newability[Choice name(put into Graveyard) target(<1>*|reveal) moveto(myGraveyard)])) oneshot optiontwoend revealend limit:1 +auto={1}{B}{T}{E(*|opponentgraveyard)} restriction{type(*|opponentgraveyard)~morethan~1}:moveto(exile) target(*|opponentgraveyard) && explores && reveal:1 optionone if type(land|reveal)~lessthan~1 then transforms((,newability[counter(1/1)])) forever optiononeend optiontwo if type(land|reveal)~morethan~0 then name(move to Hand) target(<1>*|reveal) moveto(myHand) else transforms((,newability[Choice name(back to library) target(<1>*|reveal) moveto(mylibrary)],newability[Choice name(put into Graveyard) target(<1>*|reveal) moveto(myGraveyard)])) oneshot optiontwoend revealend limit:1 text={1}{B}, {T}: Exile two target cards from an opponent's graveyard. Deadeye Tracker explores. (Reveal the top card of your library. Put that card into your hand if it's a land. Otherwise, put a +1/+1 counter on this creature, then put the card back or put it into your graveyard.) mana={B} type=Creature @@ -14308,7 +14323,7 @@ type=Sorcery [/card] [card] name=Emeria, Shattered Skyclave -auto=ability$!name(Choose one) choice name(Pay 3 life) life:-3 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 3 life) life:-3 _ choice name(Tap) tap(noevent) all(mysource)!$ controller auto={T}:add{W} text=As Emeria, Shattered Skyclave enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped. -- {T}: Add {W}. type=Land @@ -21071,6 +21086,18 @@ mana={X}{W} type=Instant [/card] [card] +name=Hakka, Whispering Raven +abilities=flying +auto=@combatdamagefoeof(player) from(this):name(Return to hand and scry 2) name(Return to hand and scry 2) moveTo(ownerhand) and!( scry:2 scrycore delayed dontshow donothing scrycoreend scryend )! +auto=@combatdamageof(player) from(this):name(Return to hand and scry 2) name(Return to hand and scry 2) moveTo(ownerhand) and!( scry:2 scrycore delayed dontshow donothing scrycoreend scryend )! +text=Flying -- Whenever Hakka, Whispering Raven deals combat damage to a player, return it to its owner’s hand, then scry 2. +mana={1}{U} +type=Legendary Creature +subtype=Bird +power=2 +toughness=3 +[/card] +[card] name=Halana, Kessig Ranger abilities=reach,partner auto=@movedTo(other creature|mybattlefield):may pay({2}) name(Pay 2) all(trigger[to]) transforms((,newability[name(Damage creature) dynamicability target(creature)])) oneshot @@ -21149,6 +21176,22 @@ text=Cumulative upkeep {1} (At the beginning of your upkeep, put an age counter type=Land [/card] [card] +name=Halvar, God of Battle +other={1}{W} name(Sword of the Realms) +otherrestriction=can play equipment +autostack=if paid(alternative) then flip(Sword of the Realms) forcetype(Legendary Artifact) +auto=this(variable{isflipped}<1) lord(creature[geared;enchanted]|myBattlefield) double strike +auto=@each combatbegins restriction{compare(isflipped)~equalto~0,type(creature|mybattlefield)~morethan~1,type(creature[equipped]|mybattlefield)~morethan~0,type(creature[enchanted]|mybattlefield)~equalto~0}:may name(Re-attach target equipment) target(*[equipment]|mybattlefield) transforms((,newability[name(Attach to creature) name(Attach to creature) rehook target(creature|mybattlefield)])) oneshot +auto=@each combatbegins restriction{compare(isflipped)~equalto~0,type(creature|mybattlefield)~morethan~1,type(creature[equipped]|mybattlefield)~equalto~0,type(creature[enchanted]|mybattlefield)~morethan~0}:may name(Re-attach target aura) target(*[aura]|mybattlefield) transforms((,newability[name(Attach to creature) name(Attach to creature) rehook target(creature|mybattlefield)])) oneshot +auto=@each combatbegins restriction{compare(isflipped)~equalto~0,type(creature|mybattlefield)~morethan~1,type(creature[equipped]|mybattlefield)~morethan~0,type(creature[enchanted]|mybattlefield)~morethan~0}:may name(Re-attach target equipment or aura) target(*[aura;equipment]|mybattlefield) transforms((,newability[name(Attach to creature) name(Attach to creature) rehook target(creature|mybattlefield)])) oneshot +text=Creatures you control that are enchanted or equipped have double strike. -- At the beginning of each combat, you may attach target Aura or Equipment attached to a creature you control to target creature you control. +mana={2}{W}{W} +type=Legendary Creature +subtype=God +power=4 +toughness=4 +[/card] +[card] name=Hammer Dropper abilities=mentor auto=@combat(attacking) source(this) restriction{compare(p)~lessthan~1}:counter(1/1,1) target(other creature[attacking;power<=-1]|myBattlefield) @@ -23020,7 +23063,7 @@ type=Instant [/card] [card] name=Hungry Hungry Heifer -auto=@each my upkeep:if type(*[counter{any}]|mybattlefield)~equalto~0 then sacrifice all(this) else ability!$name(Choose one) choice name(Remove a counter) removesinglecountertype(1) target(*[counter{any}]|mybattlefield) _ choice name(Sacrifice) sacrifice all(mystored)!$ controller +auto=@each my upkeep:if type(*[counter{any}]|mybattlefield)~equalto~0 then sacrifice all(this) else ability!$name(Choose one) choice name(Remove a counter) removesinglecountertype(1) target(*[counter{any}]|mybattlefield) _ choice name(Sacrifice) sacrifice all(mysource)!$ controller text=During your upkeep, remove a counter from any card you control or sacrifice Hungry Hungry Heifer. mana={2}{G} type=Summon @@ -25356,6 +25399,19 @@ power=3 toughness=2 [/card] [card] +name=Jorn, God of Winter +other={1}{U}{B} name(Kaldring, the Rimestaff) +otherrestriction=can play artifact +autostack=if paid(alternative) then flip(Kaldring, the Rimestaff) forcetype(Legendary Snow Artifact) +auto=@combat(attacking) source(this) restriction{compare(isflipped)~equalto~0}:all(*[snow]|mybattlefield) untap +text=Whenever Jorn attacks, untap each snow permanent you control. +mana={2}{G} +type=Legendary Snow Creature +subtype=God +power=4 +toughness=4 +[/card] +[card] name=Josu Vess, Lich Knight abilities=menace kicker={5}{B} @@ -25688,6 +25744,18 @@ power=3 toughness=3 [/card] [card] +name=Kaldring, the Rimestaff +auto={T}:name(Choose snow permanent) name(Choose snow permanent) target(*[snow]|mygraveyard) transforms((,newability[canplayfromgraveyard])) ueot && counter(0/0,1,KaldEffect) all(this) +auto=@movedto(*[snow]|mybattlefield) from(mygraveyard):this(counter{0/0.1.KaldEffect}>0) all(trigger[to]) tap(noevent) && ability$!counter(0/0,-1,KaldEffect) all(mysource)!$ controller +auto=@movedto(*[snow]|mystack) from(mygraveyard):this(counter{0/0.1.KaldEffect}>0) counter(0/0,1,KaldEffect2) && ability$!counter(0/0,-1,KaldEffect) all(mysource)!$ controller +auto=@movedto(*[snow]|mybattlefield):this(counter{0/0.1.KaldEffect2}>0) all(trigger[to]) tap(noevent) && ability$!counter(0/0,-1,KaldEffect2) all(mysource)!$ controller +auto=@each endofturn:this(counter{0/0.1.KaldEffect}>0) counter(0/0,-1,KaldEffect) +auto=@each endofturn:this(counter{0/0.1.KaldEffect2}>0) counter(0/0,-1,KaldEffect2) +text={T}: You may play target snow permanent card from your graveyard this turn. If you do, it enters the battlefield tapped. +mana={1}{U}{B} +type=Legendary Snow Artifact +[/card] +[card] name=Kalitas, Traitor of Ghet abilities=lifelink auto=@movedto(creature[token]|opponentbattlefield):all(trigger[to]) moveTo(exile) && token(Zombie,Creature Zombie,2/2,black) @@ -32438,7 +32506,7 @@ toughness=3 [card] name=Nessian Wilds Ravager abilities=flying -auto=ability$!choice name(Tribute 6) all(mystored) counter(1/1,6) _ choice name(May fight another target creature) may transforms((,newability[target(creature) dynamicability])) ueot opponent !$ opponent +auto=ability$!choice name(Tribute 6) all(mysource) counter(1/1,6) _ choice name(May fight another target creature) may transforms((,newability[target(creature) dynamicability])) ueot opponent !$ opponent text=Tribute 6 (As this creature enters the battlefield, an opponent of your choice may put six +1/+1 counters on it.) -- When Nessian Wilds Ravager enters the battlefield, if tribute wasn’t paid, you may have Nessian Wilds Ravager fight another target creature. (Each deals damage equal to its power to the other.) mana={4}{G}{G} type=Creature @@ -33689,7 +33757,7 @@ toughness=4 [card] name=Ogre Marauder text=Whenever Ogre Marauder attacks, it gains "Ogre Marauder can't be blocked" until end of turn unless defending player sacrifices a creature. -auto=@combat(attacking) source(this):ability$!name(choose one) if type(creature|mybattlefield)~morethan~0 then choice sacrifice notatarget(creature|mybattlefield) _ choice all(mystored) unblockable ueot!$ opponent +auto=@combat(attacking) source(this):ability$!name(choose one) if type(creature|mybattlefield)~morethan~0 then choice sacrifice notatarget(creature|mybattlefield) _ choice all(mysource) unblockable ueot!$ opponent mana={1}{B}{B} type=Creature subtype=Ogre Warrior @@ -41468,6 +41536,17 @@ power=3 toughness=3 [/card] [card] +name=Saw It Coming +abilities=foretell +target=*|stack +auto=fizzle +autohand={2}:name(Pay 2 and exile face-down) name(Pay 2 and exile face-down) foretell myturnonly +autoexile={1}{U} restriction{compare(canforetellcast)~morethan~0,type(*|stack)~morethan~0}:name(Cast with foretell) name(Cast with foretell) activate castcard(alternative) +text=Counter target spell. -- Foretell {1}{U} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.) +mana={1}{U}{U} +type=Instant +[/card] +[card] name=Sawtusk Demolisher abilities=trample,mutate otherrestriction=type(creature[-human]|mybattlefield)~morethan~0 @@ -41999,7 +42078,7 @@ toughness=1 [/card] [card] name=Sea Gate, Reborn -auto=ability$!name(Choose one) choice name(Pay 3 life) life:-3 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 3 life) life:-3 _ choice name(Tap) tap(noevent) all(mysource)!$ controller auto={T}:add{U} text=As Sea Gate, Reborn enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped. -- {T}: Add {U}. type=Land @@ -43085,7 +43164,7 @@ type=Sorcery [/card] [card] name=Shatterskull, the Hammer Pass -auto=ability$!name(Choose one) choice name(Pay 3 life) life:-3 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 3 life) life:-3 _ choice name(Tap) tap(noevent) all(mysource)!$ controller auto={T}:add{R} text=As Shatterskull, the Hammer Pass enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped. -- {T}: Add {R}. type=Land @@ -43532,7 +43611,7 @@ type=Instant [/card] [card] name=Shrouded Serpent -auto=@combat(attacking) source(this):ability$!name(pay 4 mana) pay[[{4}]] donothing?unblockable all(mystored) ueot!$ opponent +auto=@combat(attacking) source(this):ability$!name(pay 4 mana) pay[[{4}]] donothing?unblockable all(mysource) ueot!$ opponent text=Whenever Shrouded Serpent attacks, defending player may pay {4}. If he or she doesn't, Shrouded Serpent is unblockable this turn. mana={4}{U}{U}{U} type=Creature @@ -48491,6 +48570,17 @@ type=Artifact subtype=Equipment [/card] [card] +name=Sword of the Realms +auto={1}{W}:equip +auto=teach(creature) 2/0 +auto=teach(creature) vigilance +auto=teach(creature) handdeath +text=Equipped creature gets +2/+0 and has vigilance. -- Whenever equipped creature dies, return it to its owner’s hand. -- Equip {1}{W} +mana={1}{W} +type=Legendary Artifact +subttype=Equipment +[/card] +[card] name=Sword of Truth and Justice auto={2}:equip auto=teach(creature) protection from white @@ -52212,7 +52302,7 @@ type=Sorcery [/card] [card] name=Turntimber, Serpentine Wood -auto=ability$!name(Choose one) choice name(Pay 3 life) life:-3 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 3 life) life:-3 _ choice name(Tap) tap(noevent) all(mysource)!$ controller auto={T}:add{G} text=As Turntimber, Serpentine Wood enters the battlefield, you may pay 3 life. If you don't, it enters the battlefield tapped. -- {T}: Add {G}. type=Land diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 20b450192..275d137c9 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -12010,7 +12010,7 @@ type=Artifact [/card] [card] name=Blood Crypt -auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mysource)!$ controller text=({T}: Add {B} or {R} to your mana pool.) -- As Blood Crypt enters the battlefield, you may pay 2 life. If you don't, Blood Crypt enters the battlefield tapped. type=Land subtype=Swamp Mountain @@ -14762,7 +14762,7 @@ type=Enchantment [/card] [card] name=Breeding Pool -auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mysource)!$ controller text=({T}: Add {G} or {U} to your mana pool.) -- As Breeding Pool enters the battlefield, you may pay 2 life. If you don't, Breeding Pool enters the battlefield tapped. type=Land subtype=Forest Island @@ -15510,7 +15510,10 @@ type=Sorcery [card] name=Budoka Gardener doublefaced=kamiflip -auto={T}:all(this) transforms((,newability[if type(land|mybattlefield)~morethan~9 then flip(Dokai, Weaver of Life)],newability[may moveto(mybattlefield) notatarget(land|myhand)],newability[@movedto(land|mybattlefield) restriction{type:land:mybattlefield~morethan~9}:flip(Dokai, Weaver of Life)])) +auto={T}:name(Put land in play) name(Put land in play) target(land|myhand) moveto(mybattlefield) && if type(land|mybattlefield)~morethan~9 then all(this) flip(Dokai, Weaver of Life) else all(this) counter(0/0.1.BudokaFlp) +auto={T}:name(Don't put land in play) name(Don't put land in play) if type(land|mybattlefield)~lessthan~10 then counter(0/0.1.BudokaFlp) else flip(Dokai, Weaver of Life) && counter(0/0.-1.BudokaFlp) +auto=@movedto(land|mybattlefield) restriction{compare(type:land:mybattlefield)~morethan~9}:this(counter{0/0.1.BudokaFlp}>0) flip(Dokai, Weaver of Life) && counter(0/0.-1.BudokaFlp) +auto=@each endofturn:this(counter{0/0.1.BudokaFlp}>0) counter(0/0.-1.BudokaFlp) text={T}: You may put a land card from your hand onto the battlefield. If you control ten or more lands, flip Budoka Gardener. mana={1}{G} type=Creature @@ -20101,7 +20104,7 @@ toughness=2 [/card] [card] name=Civilized Scholar -auto={T}:draw:1 && ability$! reject notatarget(*|myhand) and!( if cantargetcard(creature|*) then all(mystored) flip(Homicidal Brute) && all(mystored) untap )! !$ controller +auto={T}:draw:1 && ability$! reject notatarget(*|myhand) and!( if cantargetcard(creature|*) then all(mysource) flip(Homicidal Brute) && all(mysource) untap )! !$ controller text={T}: Draw a card, then discard a card. If a creature card is discarded this way, untap Civilized Scholar, then transform it. mana={2}{U} type=Creature @@ -25075,7 +25078,7 @@ toughness=5 [card] name=Custody Battle target=creature -auto=teach(creature) transforms((,newability[@each my upkeep:ability$!name(sacrifice or exchange) if type(land|mybattlefield)~morethan~0 then choice sacrifice notatarget(land|mybattlefield) _ choice name(exchange controller) moveto(opponentbattlefield) all(mystored)!$ controller])) +auto=teach(creature) transforms((,newability[@each my upkeep:ability$!name(sacrifice or exchange) if type(land|mybattlefield)~morethan~0 then choice sacrifice notatarget(land|mybattlefield) _ choice name(exchange controller) moveto(opponentbattlefield) all(mysource)!$ controller])) text=Enchant creature -- Enchanted creature has "At the beginning of your upkeep, target opponent gains control of this creature unless you sacrifice a land." mana={1}{R} type=Enchantment @@ -38814,7 +38817,7 @@ toughness=2 [card] name=Fanatic of Xenagos abilities=trample -auto=ability$!choice name(Tribute 1) all(mystored) counter(1/1) _ choice name(+1/+1 and Haste) all(mystored) haste ueot && all(mystored) 1/1 ueot!$ opponent +auto=ability$!choice name(Tribute 1) all(mysource) counter(1/1) _ choice name(+1/+1 and Haste) all(mysource) haste ueot && all(mysource) 1/1 ueot!$ opponent text=Trample -- Tribute 1 (As this creature enters the battlefield, an opponent of your choice may place a +1/+1 counter on it.) -- When Fanatic of Xenagos enters the battlefield, if tribute wasn't paid, it gets +1/+1 and gains haste until end of turn. mana={1}{R}{G} type=Creature @@ -38968,7 +38971,7 @@ toughness=3 [card] name=Farrel's Mantle target=creature -auto=@combat(notblocked) source(mytgt):all(mystored) fog && target(creature) damage:storedpower && damage:2 +auto=@combat(notblocked) source(mytgt):all(mysource) fog && target(creature) damage:storedpower && damage:2 text=Enchant creature -- Whenever enchanted creature attacks and isn't blocked, its controller may have it deal damage equal to its power plus 2 to target creature. If that player does, the attacking creature assigns no combat damage this turn. mana={2}{W} type=Enchantment @@ -48476,7 +48479,7 @@ toughness=5 [/card] [card] name=Godless Shrine -auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mysource)!$ controller text=({T}: Add {W} or {B} to your mana pool.) -- As Godless Shrine enters the battlefield, you may pay 2 life. If you don't, Godless Shrine enters the battlefield tapped. type=Land subtype=Plains Swamp @@ -51808,7 +51811,7 @@ type=Sorcery [/card] [card] name=Hallowed Fountain -auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mysource)!$ controller text=({T}: Add {W} or {U} to your mana pool.) -- As Hallowed Fountain enters the battlefield, you may pay 2 life. If you don't, Hallowed Fountain enters the battlefield tapped. type=Land subtype=Plains Island @@ -65576,7 +65579,7 @@ toughness=1 name=Lathnu Hellion abilities=haste auto=alterenergy:2 controller -auto=@each my end:name(pay for effect) ability$!if compare(penergy)~morethan~1 then choice alterenergy:-2 controller _ choice sacrifice all(mystored)!$ controller +auto=@each my end:name(pay for effect) ability$!if compare(penergy)~morethan~1 then choice alterenergy:-2 controller _ choice sacrifice all(mysource)!$ controller text=Haste -- When Lathnu Hellion enters the battlefield, you get {E}{E} (two energy counters). -- At the beginning of your end step, sacrifice Lathnu Hellion unless you pay {E}{E}. mana={2}{R} type=Creature @@ -68719,7 +68722,7 @@ toughness=1 [/card] [card] name=Lumengrid Augur -auto={1}{t}:target(player) draw:1 && ability$! reject notatarget(*|myhand) and!( if cantargetcard(artifact|*) then untap all(mystored) )! !$ targetedplayer +auto={1}{t}:target(player) draw:1 && ability$! reject notatarget(*|myhand) and!( if cantargetcard(artifact|*) then untap all(mysource) )! !$ targetedplayer text={1}, {T}: Target player draws a card, then discards a card. If that player discards an artifact card this way, untap Lumengrid Augur. mana={3}{U} type=Creature @@ -76367,7 +76370,7 @@ subtype=Equipment [/card] [card] name=Mortician Beetle -auto=@sacrificed(creature):name(counter +1/+1) ability$!may counter(1/1,1) all(mystored)!$ controller +auto=@sacrificed(creature):name(counter +1/+1) ability$!may counter(1/1,1) all(mysource)!$ controller text=Whenever a player sacrifices a creature, you may put a +1/+1 counter on Mortician Beetle. mana={B} type=Creature @@ -83041,7 +83044,7 @@ type=Instant [card] name=Ornitharch abilities=flying -auto=ability$!choice name(Tribute 2) all(mystored) counter(1/1,2) _ choice name(Two 1/1 birds) token(Bird,Creature Bird,1/1,flying,white)*2 opponent !$ opponent +auto=ability$!choice name(Tribute 2) all(mysource) counter(1/1,2) _ choice name(Two 1/1 birds) token(Bird,Creature Bird,1/1,flying,white)*2 opponent !$ opponent text=Tribute 2 (As this creature enters the battlefield, an opponent of your choice may place two +1/+1 counters on it.) -- When Ornitharch enters the battlefield, if tribute wasn't paid, put two 1/1 white Bird creature tokens with flying onto the battlefield. mana={3}{W}{W} type=Creature @@ -83380,7 +83383,7 @@ type=Enchantment [/card] [card] name=Overgrown Tomb -auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mysource)!$ controller text=({T}: Add {B} or {G} to your mana pool.) -- As Overgrown Tomb enters the battlefield, you may pay 2 life. If you don't, Overgrown Tomb enters the battlefield tapped. type=Land subtype=Swamp Forest @@ -86541,7 +86544,7 @@ toughness=3 name=Pillar Tombs of Aku auto=@movedTo(other enchantment[world]|battlefield):sacrifice all(this) auto=@each my upkeep restriction{type(creature|mybattlefield)~lessthan~2}:sacrifice && life:-5 controller -auto=@each opponent upkeep restriction{type(creature|opponentbattlefield)~morethan~0}:ability$!choice name(sacrifice creature) notatarget(creature|mybattlefield) sacrifice _ choice name(life loss and sacrifice Tombs) sacrifice all(mystored) && life:-5!$ opponent +auto=@each opponent upkeep restriction{type(creature|opponentbattlefield)~morethan~0}:ability$!choice name(sacrifice creature) notatarget(creature|mybattlefield) sacrifice _ choice name(life loss and sacrifice Tombs) sacrifice all(mysource) && life:-5!$ opponent auto=@each opponent upkeep restriction{type(creature|opponentbattlefield)~lessthan~1}:sacrifice && life:-5 opponent text=At the beginning of each player's upkeep, that player may sacrifice a creature. If that player doesn't, he or she loses 5 life and you sacrifice Pillar Tombs of Aku. mana={2}{B}{B} @@ -89705,7 +89708,7 @@ subtype=Aura [/card] [card] name=Pursuit of Knowledge -auto=replacedraw ability$!name(study counter or draw) choice counter(0/0.1.Study) all(mystored) _ choice draw:1 noreplace!$ controller +auto=replacedraw ability$!name(study counter or draw) choice counter(0/0.1.Study) all(mysource) _ choice draw:1 noreplace!$ controller auto={C(0/0,-3,Study)}{S}:draw:7 controller text=If you would draw a card, you may put a study counter on Pursuit of Knowledge instead. -- Remove three study counters from Pursuit of Knowledge, Sacrifice Pursuit of Knowledge: Draw seven cards. mana={3}{W} @@ -97766,7 +97769,7 @@ type=Artifact [/card] [card] name=Sacred Foundry -auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mysource)!$ controller text=({T}: Add {R} or {W} to your mana pool.) -- As Sacred Foundry enters the battlefield, you may pay 2 life. If you don't, Sacred Foundry enters the battlefield tapped. type=Land subtype=Mountain Plains @@ -104631,7 +104634,7 @@ subtype=Equipment [/card] [card] name=Shyft -auto=@each my upkeep:may name(choose color/s) ability$!name(choose color/s) choice name(white) all(mystored) becomes(,white) forever _ choice name(blue) all(mystored) becomes(,blue) forever _ choice name(black) all(mystored) becomes(,black) forever _ choice name(red) all(mystored) becomes(,red) forever _ choice name(green) all(mystored) becomes(,green) forever _ choice name(white & blue) all(mystored) becomes(,white,blue) forever _ choice name(blue & black) all(mystored) becomes(,black,blue) forever _ choice name(black & red) all(mystored) becomes(,black,red) forever _ choice name(red & green) all(mystored) becomes(,red,green) forever _ choice name(green & white) all(mystored) becomes(,white,green) forever _ choice name(white & black) all(mystored) becomes(,white,black) forever _ choice name(blue & red) all(mystored) becomes(,red,blue) forever _ choice name(black & green) all(mystored) becomes(,black,green) forever _ choice name(red & white) all(mystored) becomes(,white,red) forever _ choice name(green & blue) all(mystored) becomes(,green,blue) forever _ choice name(green & white & blue) all(mystored) becomes(,green,white,blue) forever _ choice name(white & blue & black) all(mystored) becomes(,black,white,blue) forever _ choice name(blue & black & red) all(mystored) becomes(,black,red,blue) forever _ choice name(black & red & green) all(mystored) becomes(,green,black,red) forever _ choice name(red & green & white) all(mystored) becomes(,green,white,red) forever _ choice name(white & black & green) all(mystored) becomes(,green,white,black) forever _ choice name(blue & red & white) all(mystored) becomes(,red,white,blue) forever _ choice name(black & green & blue) all(mystored) becomes(,green,black,blue) forever _ choice name(red & white & black) all(mystored) becomes(,black,white,red) forever _ choice name(green & blue & red) all(mystored) becomes(,green,red,blue) forever _ choice name(green & red & blue & black) all(mystored) becomes(,green,red,blue,black) forever _ choice name(green & red & blue & white) all(mystored) becomes(,green,red,blue,white) forever _ choice name(white & blue & black & red) all(mystored) becomes(,white,red,blue,black) forever _ choice name(white & blue & black & green) all(mystored) becomes(,white,green,blue,black) forever _ choice name(all colors) all(mystored) becomes(,white,red,blue,black,green) forever!$ controller +auto=@each my upkeep:may name(choose color/s) ability$!name(choose color/s) choice name(white) all(mysource) becomes(,white) forever _ choice name(blue) all(mysource) becomes(,blue) forever _ choice name(black) all(mysource) becomes(,black) forever _ choice name(red) all(mysource) becomes(,red) forever _ choice name(green) all(mysource) becomes(,green) forever _ choice name(white & blue) all(mysource) becomes(,white,blue) forever _ choice name(blue & black) all(mysource) becomes(,black,blue) forever _ choice name(black & red) all(mysource) becomes(,black,red) forever _ choice name(red & green) all(mysource) becomes(,red,green) forever _ choice name(green & white) all(mysource) becomes(,white,green) forever _ choice name(white & black) all(mysource) becomes(,white,black) forever _ choice name(blue & red) all(mysource) becomes(,red,blue) forever _ choice name(black & green) all(mysource) becomes(,black,green) forever _ choice name(red & white) all(mysource) becomes(,white,red) forever _ choice name(green & blue) all(mysource) becomes(,green,blue) forever _ choice name(green & white & blue) all(mysource) becomes(,green,white,blue) forever _ choice name(white & blue & black) all(mysource) becomes(,black,white,blue) forever _ choice name(blue & black & red) all(mysource) becomes(,black,red,blue) forever _ choice name(black & red & green) all(mysource) becomes(,green,black,red) forever _ choice name(red & green & white) all(mysource) becomes(,green,white,red) forever _ choice name(white & black & green) all(mysource) becomes(,green,white,black) forever _ choice name(blue & red & white) all(mysource) becomes(,red,white,blue) forever _ choice name(black & green & blue) all(mysource) becomes(,green,black,blue) forever _ choice name(red & white & black) all(mysource) becomes(,black,white,red) forever _ choice name(green & blue & red) all(mysource) becomes(,green,red,blue) forever _ choice name(green & red & blue & black) all(mysource) becomes(,green,red,blue,black) forever _ choice name(green & red & blue & white) all(mysource) becomes(,green,red,blue,white) forever _ choice name(white & blue & black & red) all(mysource) becomes(,white,red,blue,black) forever _ choice name(white & blue & black & green) all(mysource) becomes(,white,green,blue,black) forever _ choice name(all colors) all(mysource) becomes(,white,red,blue,black,green) forever!$ controller text=At the beginning of your upkeep, you may have Shyft become the color or colors of your choice. (This effect lasts indefinitely.) mana={4}{U} type=Creature @@ -108287,7 +108290,7 @@ subtype=Aura [/card] [card] name=Snake of the Golden Grove -auto=ability$!choice name(Tribute 3) all(mystored) counter(1/1,3) _ choice name(4 life opponent) life:4 opponent !$ opponent +auto=ability$!choice name(Tribute 3) all(mysource) counter(1/1,3) _ choice name(4 life opponent) life:4 opponent !$ opponent text=Tribute 3 (As this creature enters the battlefield, an opponent of your choice may place three +1/+1 counters on it.) -- When Snake of the Golden Grove enters the battlefield, if tribute wasn't paid, you gain 4 life. mana={4}{G} type=Creature @@ -108817,7 +108820,7 @@ type=Instant [/card] [card] name=Solitary Confinement -auto=@each my upkeep :name(discard or sacrifice) ability$!if type(*|myhand)~morethan~0 then choice reject notatarget(*|myhand) _ choice sacrifice all(mystored)!$ controller +auto=@each my upkeep :name(discard or sacrifice) ability$!if type(*|myhand)~morethan~0 then choice reject notatarget(*|myhand) _ choice sacrifice all(mysource)!$ controller auto=phasealter(remove,draw,controller) abilities=playershroud auto=preventalldamage to(controller) @@ -112862,7 +112865,7 @@ toughness=5 [/card] [card] name=Steam Vents -auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mysource)!$ controller text=({T}: Add {U} or {R} to your mana pool.) -- As Steam Vents enters the battlefield, you may pay 2 life. If you don't, Steam Vents enters the battlefield tapped. type=Land subtype=Island Mountain @@ -113427,7 +113430,7 @@ toughness=3 [/card] [card] name=Stomping Ground -auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mysource)!$ controller text=({T}: Add {R} or {G} to your mana pool.) -- As Stomping Ground enters the battlefield, you may pay 2 life. If you don't, Stomping Ground enters the battlefield tapped. type=Land subtype=Mountain Forest @@ -118450,7 +118453,7 @@ toughness=2 [/card] [card] name=Temple Garden -auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mysource)!$ controller text=({T}: Add {G} or {W} to your mana pool.) -- As Temple Garden enters the battlefield, you may pay 2 life. If you don't, Temple Garden enters the battlefield tapped. type=Land subtype=Forest Plains @@ -120598,7 +120601,7 @@ toughness=3 name=Thraximundar abilities=haste auto=@combat(attacking) source(this):ability$!name(sacrifice) notatarget(creature|mybattlefield) sacrifice!$ opponent -auto=@sacrificed(creature):name(counter +1/+1) ability$!may counter(1/1,1) all(mystored)!$ controller +auto=@sacrificed(creature):name(counter +1/+1) ability$!may counter(1/1,1) all(mysource)!$ controller text=Haste -- Whenever Thraximundar attacks, defending player sacrifices a creature. -- Whenever a player sacrifices a creature, you may put a +1/+1 counter on Thraximundar. mana={4}{U}{B}{R} type=Legendary Creature @@ -120869,7 +120872,7 @@ type=Artifact [card] name=Thunder Brute abilities=trample -auto=ability$!choice name(Tribute 3) all(mystored) counter(1/1,3) _ choice name(Haste) all(mystored) haste ueot!$ opponent +auto=ability$!choice name(Tribute 3) all(mysource) counter(1/1,3) _ choice name(Haste) all(mysource) haste ueot!$ opponent text=Trample -- Tribute 3 (As this creature enters the battlefield, an opponent of your choice may place three +1/+1 counters on it.) -- When Thunder Brute enters the battlefield, if tribute wasn't paid, it gains haste until end of turn. mana={4}{R}{R} type=Creature @@ -131305,7 +131308,7 @@ type=Sorcery [/card] [card] name=Wand of Denial -auto={t}:target(player) reveal:1 optionone name(Get Creature) target(*|reveal) transforms((,newability[pay[[{L:2}]] name(Pay Life) moveto(ownergraveyard) ])) forever optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerlibrary) optiontwoend revealend +auto={t}:target(player) reveal:1 optionone name(Look top card) target(*|reveal) transforms((,newability[pay[[{L:2}]] name(Pay Life) moveto(ownergraveyard) ])) forever optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerlibrary) optiontwoend revealend text={T}: Look at the top card of target player's library. If it's a nonland card, you may pay 2 life. If you do, put it into that player's graveyard. mana={2} type=Artifact @@ -132241,7 +132244,7 @@ type=Instant [/card] [card] name=Watery Grave -auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mystored)!$ controller +auto=ability$!name(Choose one) choice name(Pay 2 life) life:-2 _ choice name(Tap) tap(noevent) all(mysource)!$ controller text=({T}: Add {U} or {B} to your mana pool.) -- As Watery Grave enters the battlefield, you may pay 2 life. If you don't, Watery Grave enters the battlefield tapped. type=Land subtype=Island Swamp diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index f40a85ff5..1d55b4db4 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -651,44 +651,35 @@ private: } else if (s == "abundantlife")//current life is morethan or equal to starting life { - intValue = 0; - if (target->controller()->life >= target->controller()->initLife) - intValue = 1; + intValue = (target->controller()->life >= target->controller()->initLife)?1:0; } else if (s == "plibrarycount") { - intValue = 0; - if (target->controller()->game->library->nb_cards) - intValue = target->controller()->game->library->nb_cards; + intValue = (target->controller()->game->library->nb_cards)?target->controller()->game->library->nb_cards:0; } else if (s == "olibrarycount") { - intValue = 0; - if (target->controller()->opponent()->game->library->nb_cards) - intValue = target->controller()->opponent()->game->library->nb_cards; + intValue = (target->controller()->opponent()->game->library->nb_cards)?target->controller()->opponent()->game->library->nb_cards:0; } else if (s == "highestlifetotal") { - intValue = target->controller()->life <= target->controller()->opponent()->life? target->controller()->opponent()->life:target->controller()->life; + intValue = target->controller()->life <= target->controller()->opponent()->life?target->controller()->opponent()->life:target->controller()->life; } else if (s == "lowestlifetotal") { - intValue = target->controller()->life <= target->controller()->opponent()->life? target->controller()->life:target->controller()->opponent()->life; + intValue = target->controller()->life <= target->controller()->opponent()->life?target->controller()->life:target->controller()->opponent()->life; } else if (s == "thatmuch") { //the value that much is a variable to be used with triggered abilities. //ie:when ever you gain life, draw that many cards. when used in a trigger draw:thatmuch, will return the value //that the triggered event stored in the card for "that much". - intValue = 0; intValue = target->thatmuch; int checkagain = 0; - if(target->hasSubtype(Subtypes::TYPE_AURA) || target->hasSubtype(Subtypes::TYPE_EQUIPMENT)) - { - if(target->target) - { - checkagain = target->target->thatmuch; - } + if(target->hasSubtype(Subtypes::TYPE_AURA) || target->hasSubtype(Subtypes::TYPE_EQUIPMENT)){ + if(target->target){ + checkagain = target->target->thatmuch; + } } if(checkagain > intValue) intValue = checkagain; @@ -727,16 +718,20 @@ private: { intValue = (s == "pdrewcount")?target->controller()->drawCounter:target->controller()->opponent()->drawCounter; } - else if (s == "epicactivated") + else if (s == "epicactivated" || s == "currentturn") { - intValue = target->controller()->epic; + intValue = (s == "epicactivated")?target->controller()->epic:target->getObserver()->turn; } - else if (s == "snowcount") - {//this is just to count the number of snow mana produced ... just for debugging purposes... - intValue = target->controller()->snowManaG + target->controller()->snowManaU +target->controller()->snowManaR + target->controller()->snowManaB + target->controller()->snowManaW + target->controller()->snowManaC; + else if (s == "canforetellcast") + { + intValue = (target->foretellTurn < 0)?0:(target->getObserver()->turn-target->foretellTurn); // Check if you can use the foretell cost from exile (CurrentTurn > ForetellTurn). } - else if (s == "mypoolcount" || s == "opponentpoolcount") - {//manapool + else if (s == "isflipped" || s == "snowcount") // Return 1 if card has been flipped -- // Snowcount is just to count the number of snow mana produced ... just for debugging purposes... + { + intValue = (s == "isflipped")?card->isFlipped:target->controller()->snowManaG + target->controller()->snowManaU +target->controller()->snowManaR + target->controller()->snowManaB + target->controller()->snowManaW + target->controller()->snowManaC; + } + else if (s == "mypoolcount" || s == "opponentpoolcount") // total manapool + { intValue = (s == "mypoolcount")?target->controller()->getManaPool()->getConvertedCost():target->controller()->opponent()->getManaPool()->getConvertedCost(); } else if (s == "mygreenpoolcount" || s == "opponentgreenpoolcount") @@ -1046,13 +1041,9 @@ private: unique_cards.clear(); } } - else if (s == "mypos") - {//hand,exile,grave & library only (library zpos is inverted so the recent one is always the top) - intValue = card->zpos; - } - else if (s == "bushidopoints") - {//bushido point - intValue = card->bushidoPoints; + else if (s == "mypos" || s == "bushidopoints")//hand,exile,grave & library only (library zpos is inverted so the recent one is always the top) -- bushido point + { + intValue = (s == "mypos")?card->zpos:card->bushidoPoints; } else if (s == "revealedp") { @@ -2461,6 +2452,15 @@ public: const string getMenuText(); AAImprint * clone() const; }; +//AAForetell +class AAForetell: public ActivatedAbility +{ +public: + AAForetell(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target = NULL, ManaCost * _cost = NULL); + int resolve(); + const string getMenuText(); + AAForetell * clone() const; +}; //cloning...this makes a token thats a copy of the target. class AACloner: public ActivatedAbility { @@ -7332,7 +7332,8 @@ public: bool asNormalMadness; bool alternative; int kicked; - AACastCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target,bool restricted,bool copied,bool _asNormal,string nameCard,string abilityName,bool _noEvent, bool putinplay,bool asNormalMadness = false,bool alternative = false,int kicked = 0); + bool flipped; + AACastCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target,bool restricted,bool copied,bool _asNormal,string nameCard,string abilityName,bool _noEvent, bool putinplay,bool asNormalMadness = false,bool alternative = false,int kicked = 0,bool flipped = false); int testDestroy(){return 0;}; void Update(float dt); diff --git a/projects/mtg/include/CardDescriptor.h b/projects/mtg/include/CardDescriptor.h index ac5f1c6cd..cfa938204 100644 --- a/projects/mtg/include/CardDescriptor.h +++ b/projects/mtg/include/CardDescriptor.h @@ -35,6 +35,7 @@ class CardDescriptor: public MTGCardInstance Operator mode; int powerComparisonMode; + int foretoldComparisonMode; int kickedComparisonMode; int toughnessComparisonMode; int manacostComparisonMode; diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index f1486ae9c..2f03a9af4 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -306,6 +306,7 @@ public: int imprintR; int imprintB; int imprintW; + int foretellTurn; int bushidoPoints; int modularPoints; int canproduceMana(int color = -1); diff --git a/projects/mtg/include/MTGDefinitions.h b/projects/mtg/include/MTGDefinitions.h index 1b23fe03f..2011593c7 100644 --- a/projects/mtg/include/MTGDefinitions.h +++ b/projects/mtg/include/MTGDefinitions.h @@ -298,7 +298,8 @@ class Constants GAINEDEXILEDEATH = 171, GAINEDHANDDEATH = 172, CYCLING = 173, - NB_BASIC_ABILITIES = 174, + FORETELL = 174, + NB_BASIC_ABILITIES = 175, RARITY_S = 'S', //Special Rarity RARITY_M = 'M', //Mythics diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index af531d6e0..2b523c0d4 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -2025,6 +2025,44 @@ AAImprint * AAImprint::clone() const return NEW AAImprint(*this); } +//AAForetell +AAForetell::AAForetell(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost) : + ActivatedAbility(observer, _id, _source, _cost, 0) +{ + target = _target; +} + +int AAForetell::resolve() +{ + MTGCardInstance * _target = (MTGCardInstance *) target; + if (_target) + { + if(_target->mutation && _target->parentCards.size() > 0) return 0; // Mutated down cards cannot be foretell, they will follow the fate of top-card + Player * p = _target->controller(); + if(p){ + MTGCardInstance * tmp = p->game->putInExile(_target); + if(tmp) + tmp->foretellTurn = source->getObserver()->turn; + } + + while(_target->next) + _target = _target->next; + + return 1; + } + return 0; +} + +const string AAForetell::getMenuText() +{ + return "Foretell"; +} + +AAForetell * AAForetell::clone() const +{ + return NEW AAForetell(*this); +} + //Counters AACounter::AACounter(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * target,string counterstring, const char * _name, int power, int toughness, int nb,int maxNb, ManaCost * cost) : @@ -4076,7 +4114,7 @@ int AAFlip::resolve() while (_target->next) _target = _target->next; - if(forcetype != "" && _target) // Added to flip Zendikar Rising Modal Double Faced cards. + if(forcetype != "" && _target) // Added to flip Modal Double Faced cards (e.g. Zendikar Rising). { for (int i = ((int)_target->types.size())-1; i >= 0; --i) _target->removeType(_target->types[i]); @@ -4224,7 +4262,7 @@ int AAFlip::resolve() else _target->isFacedown = true; - if(forcetype != "" && _target) // Added to flip Zendikar Rising Modal Double Faced cards. + if(forcetype != "" && _target && _target->isPermanent()) // Added to flip Modal Double Faced cards (e.g. Zendikar Rising). { _target->castMethod = Constants::CAST_NORMALLY; _target->controller()->game->battlefield->addCard(_target); @@ -8849,8 +8887,8 @@ AEquip * AEquip::clone() const } // casting a card for free, or casting a copy of a card. -AACastCard::AACastCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target,bool _restricted,bool _copied,bool asNormal,string _namedCard,string _name,bool _noEvent,bool putinplay,bool madness, bool alternative, int kicked) : - MTGAbility(observer, _id, _source),restricted(_restricted),asCopy(_copied),normal(asNormal),cardNamed(_namedCard),nameThis(_name),noEvent(_noEvent),putinplay(putinplay), asNormalMadness(madness), alternative(alternative), kicked(kicked) +AACastCard::AACastCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target,bool _restricted,bool _copied,bool asNormal,string _namedCard,string _name,bool _noEvent,bool putinplay,bool madness, bool alternative, int kicked, bool flipped) : + MTGAbility(observer, _id, _source),restricted(_restricted),asCopy(_copied),normal(asNormal),cardNamed(_namedCard),nameThis(_name),noEvent(_noEvent),putinplay(putinplay), asNormalMadness(madness), alternative(alternative), kicked(kicked), flipped(flipped) { target = _target; andAbility = NULL; @@ -9148,7 +9186,7 @@ int AACastCard::resolveSpell() spell = NEW Spell(game, 0,copy,NULL,NULL, 1); spell->resolve(); } - else + else if(!flipped) spell = game->mLayers->stackLayer()->addSpell(copy, NULL, NULL, 1, 0); } diff --git a/projects/mtg/src/CardDescriptor.cpp b/projects/mtg/src/CardDescriptor.cpp index 9be168a06..e6e5f61b5 100644 --- a/projects/mtg/src/CardDescriptor.cpp +++ b/projects/mtg/src/CardDescriptor.cpp @@ -13,6 +13,7 @@ CardDescriptor::CardDescriptor() counterToughness = 0; counterNB = 0; mode = CD_AND; + foretoldComparisonMode = COMPARISON_NONE; kickedComparisonMode = COMPARISON_NONE; powerComparisonMode = COMPARISON_NONE; toughnessComparisonMode = COMPARISON_NONE; @@ -159,6 +160,8 @@ MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card) } // Quantified restrictions are always AND-ed: + if (foretoldComparisonMode && !valueInRange(foretoldComparisonMode, card->foretellTurn, foretellTurn)) + return NULL; if (kickedComparisonMode && !valueInRange(kickedComparisonMode, card->kicked, kicked)) return NULL; if (powerComparisonMode && !valueInRange(powerComparisonMode, card->getPower(), power)) @@ -204,6 +207,8 @@ MTGCardInstance * CardDescriptor::match_and(MTGCardInstance * card) match = NULL; } + if (foretoldComparisonMode && !valueInRange(foretoldComparisonMode, card->foretellTurn, foretellTurn)) + match = NULL; if (kickedComparisonMode && !valueInRange(kickedComparisonMode, card->kicked, kicked)) match = NULL; if (powerComparisonMode && !valueInRange(powerComparisonMode, card->getPower(), power)) diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index f950bcbd4..446d071b4 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -257,7 +257,8 @@ void CardGui::Render() if(game) { if((card->has(Constants::CANPLAYFROMEXILE)||card->has(Constants::PAYZERO))|| - ((card->has(Constants::CANPLAYFROMGRAVEYARD) || card->has(Constants::TEMPFLASHBACK) || card->getManaCost()->getFlashback()) && game->isInGrave(card))) + ((card->has(Constants::CANPLAYFROMGRAVEYARD) || card->has(Constants::TEMPFLASHBACK) || card->getManaCost()->getFlashback()) && game->isInGrave(card)) || + (card->has(Constants::FORETELL) && card->foretellTurn > -1 && game->turn > card->foretellTurn && game->isInExile(card))) fakeborder->SetColor(ARGB((int)(actA),7,235,7));//green border else fakeborder->SetColor(ARGB((int)(actA),15,15,15)); @@ -1485,6 +1486,12 @@ bool CardGui::FilterCard(MTGCard * _card,string filter) cd.unsecureSetTapped(1); } } + //Has been foretold + else if (attribute.find("foretold") != string::npos) + { + cd.foretellTurn = comparisonCriterion; + cd.foretoldComparisonMode = comparisonMode; + } //Has been kicked else if (attribute.find("kicked") != string::npos) { @@ -1550,7 +1557,7 @@ bool CardGui::FilterCard(MTGCard * _card,string filter) cd.unsecuresetrecent(1); } } - else if (attribute.find("geared") != string::npos) + else if (attribute.find("geared") != string::npos || attribute.find("equipped") != string::npos) { if (minus) { diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 42857beeb..af9263ada 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -825,19 +825,25 @@ int AbilityFactory::parseCastRestrictions(MTGCardInstance * card, Player * playe if(!found) return 0; } - check = restriction[i].find("can play land"); + check = restriction[i].find("can play"); if(check != string::npos) { - bool isLand = card->hasType("Land"); + if(!card->getId()) + return 0; //Fixed a crash when AI plays. + string type = restriction[i]; + type = type.replace(0,9,""); + MTGCardInstance* cardDummy = card->clone(); + for (int i = ((int)cardDummy->types.size())-1; i >= 0; --i) + cardDummy->removeType(cardDummy->types[i]); + cardDummy->addType(type); bool canplay = true; - if(!isLand) - card->addType("Land"); - if (observer->currentActionPlayer->game->playRestrictions->canPutIntoZone(card, observer->currentActionPlayer->game->inPlay) == PlayRestriction::CANT_PLAY) + if (cardDummy->isLand() && observer->currentActionPlayer->game->playRestrictions->canPutIntoZone(cardDummy, observer->currentActionPlayer->game->inPlay) == PlayRestriction::CANT_PLAY) canplay = false; - if (!card->getObserver() || !card->StackIsEmptyandSorcerySpeed()) + if (!cardDummy->isLand() && observer->currentActionPlayer->game->playRestrictions->canPutIntoZone(cardDummy, observer->currentActionPlayer->game->stack) == PlayRestriction::CANT_PLAY) canplay = false; - if(!isLand) - card->removeType("Land"); + if (!cardDummy->hasType(Subtypes::TYPE_INSTANT) && !cardDummy->StackIsEmptyandSorcerySpeed()) + canplay = false; + SAFE_DELETE(cardDummy); if(!canplay) return 0; } @@ -1780,56 +1786,93 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG vectortransfound = parseBetween(s,"newability[reveal:"," ");//if we are using reveal inside a newability, let transforms remove the string instead. vectorabilfound = parseBetween(s, "ability$!name(reveal) reveal:", " "); if(!abilfound.size()) - abilfound = parseBetween(s, "ability$!reveal:", " ");//see above. this allows us to nest reveals inside these 2 other master classes. while also allowing us to nest them inside reveals. + abilfound = parseBetween(s, "ability$!reveal:", " ");//see above. this allows us to nest reveals inside these 2 other master classes. while also allowing us to nest them inside reveals. found = s.find("pay("); if (found != string::npos && storedPayString.empty() && !transPayfound.size()) { + size_t pos1 = s.find("transforms(("); // Try to handle pay ability inside ability$! or transforms keywords. + size_t pos2 = s.find("ability$!"); vector splitMayPaystr = parseBetween(s, "pay(", ")", true); - if (splitMayPaystr.size()) - { - storedPayString.append(splitMayPaystr[2]); - s = splitMayPaystr[0]; - s.append("pay("); - s.append(splitMayPaystr[1]); - s.append(")"); - } + if((pos1 == string::npos && pos2 == string::npos) || (pos2 != string::npos && pos1 != string::npos && found < pos1 && found < pos2) || + (pos2 == string::npos && pos1 != string::npos && found < pos1) || (pos1 == string::npos && pos2 != string::npos && found < pos2)){ + if (splitMayPaystr.size()){ + storedPayString.append(splitMayPaystr[2]); + s = splitMayPaystr[0]; + s.append("pay("); + s.append(splitMayPaystr[1]); + s.append(")"); + } + } else + storedPayString.clear(); } vector splitGrant = parseBetween(s, "grant ", " grantend", false); if (splitGrant.size() && storedAbilityString.empty()) { storedAbilityString = splitGrant[1]; - s = splitGrant[0]; - s.append("grant "); - s.append(splitGrant[2]); + size_t pos1 = s.find("transforms(("); // Try to handle grant ability inside ability$! or transforms keywords. + size_t pos2 = s.find("ability$!"); + size_t pos3 = s.find(splitGrant[1]); + if((pos1 == string::npos && pos2 == string::npos) || (pos2 != string::npos && pos1 != string::npos && pos3 < pos1 && pos3 < pos2) || + (pos2 == string::npos && pos1 != string::npos && pos3 < pos1) || (pos1 == string::npos && pos2 != string::npos && pos3 < pos2)){ + s = splitGrant[0]; + s.append("grant "); + s.append(splitGrant[2]); + } else + storedAbilityString.clear(); } vector splitRevealx = parseBetween(s, "reveal:", " revealend", false); if (!abilfound.size() && !transfound.size() && splitRevealx.size() && storedAbilityString.empty()) { storedAbilityString = splitRevealx[1]; - s = splitRevealx[0]; - s.append("reveal: "); - s.append(splitRevealx[2]); + size_t pos1 = s.find("transforms(("); // Try to handle reveal ability inside ability$! or transforms keywords. + size_t pos2 = s.find("ability$!"); + size_t pos3 = s.find(splitRevealx[1]); + if((pos1 == string::npos && pos2 == string::npos) || (pos2 != string::npos && pos1 != string::npos && pos3 < pos1 && pos3 < pos2) || + (pos2 == string::npos && pos1 != string::npos && pos3 < pos1) || (pos1 == string::npos && pos2 != string::npos && pos3 < pos2)){ + s = splitRevealx[0]; + s.append("reveal: "); + s.append(splitRevealx[2]); + } else + storedAbilityString.clear(); } vector splitScryx = parseBetween(s, "scry:", " scryend", false); if (splitScryx.size() && storedAbilityString.empty()) { storedAbilityString = splitScryx[1]; - s = splitScryx[0]; - s.append("scry: "); - s.append(splitScryx[2]); + size_t pos1 = s.find("transforms(("); // Try to handle scry ability inside ability$! or transforms keywords. + size_t pos2 = s.find("ability$!"); + size_t pos3 = s.find(splitScryx[1]); + if((pos1 == string::npos && pos2 == string::npos) || (pos2 != string::npos && pos1 != string::npos && pos3 < pos1 && pos3 < pos2) || + (pos2 == string::npos && pos1 != string::npos && pos3 < pos1) || (pos1 == string::npos && pos2 != string::npos && pos3 < pos2)){ + s = splitScryx[0]; + s.append("scry: "); + s.append(splitScryx[2]); + } else + storedAbilityString.clear(); } found = s.find("transforms(("); if (found != string::npos && storedString.empty()) { - size_t real_end = s.find("))", found); - size_t stypesStartIndex = found + 12; - storedString.append(s.substr(stypesStartIndex, real_end - stypesStartIndex).c_str()); - s.erase(stypesStartIndex, real_end - stypesStartIndex); + size_t pos1 = s.find("ability$!"); // Try to handle transforms ability inside ability$! keyword. + if(pos1 == string::npos || found < pos1){ + size_t real_end = s.find("))", found); + size_t stypesStartIndex = found + 12; + for(unsigned int i = stypesStartIndex; i < s.size(); i++){ + size_t pos2 = s.find("transforms((", i); // Try to handle transforms ability inside transforms keyword. + if(pos2 != string::npos && pos2 < real_end){ + i = pos2 + 11; + real_end = s.find("))", real_end + 2); + } else + break; + } + storedString.append(s.substr(stypesStartIndex, real_end - stypesStartIndex).c_str()); + s.erase(stypesStartIndex, real_end - stypesStartIndex); + } } found = s.find("ability$!"); @@ -3099,6 +3142,15 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG } } + //foretell + found = s.find("foretell"); + if (found != string::npos) + { + MTGAbility * a = NEW AAForetell(observer, id, card, target); + a->oneShot = 1; + return a; + } + //phaseout found = s.find("phaseout"); if (found != string::npos) @@ -3267,6 +3319,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG bool sendNoEvent = splitCastCard[1].find("noevent") != string::npos; bool putinplay = splitCastCard[1].find("putinplay") != string::npos; bool alternative = splitCastCard[1].find("alternative") != string::npos; + bool flipped = splitCastCard[1].find("flipped") != string::npos; string nameCard = ""; if(splitCastCard[1].find("named!:") != string::npos) { @@ -3285,7 +3338,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG kicked = atoi(splitCastKicked[1].c_str()); } } - MTGAbility *a = NEW AACastCard(observer, id, card, target,withRestrictions,asCopy,asNormal,nameCard,newName,sendNoEvent,putinplay, asNormalMadness, alternative, kicked); + MTGAbility *a = NEW AACastCard(observer, id, card, target,withRestrictions,asCopy,asNormal,nameCard,newName,sendNoEvent,putinplay, asNormalMadness, alternative, kicked, flipped); a->oneShot = false; if(splitCastCard[1].find("trigger[to]") != string::npos) { @@ -4074,7 +4127,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG string transformsParamsString = ""; transformsParamsString.append(storedString);//the string between found and real end is removed at start. - found = transformsParamsString.find("transforms(("); + found = transformsParamsString.find("transforms(("); // Try to handle transforms ability inside transforms keyword. if (found != string::npos && extraTransforms.empty()) { size_t real_end = transformsParamsString.find("))", found); @@ -4120,10 +4173,16 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG size_t NewSkill = abilities[j].find("newability["); size_t NewSkillEnd = abilities[j].find_last_of("]"); string newAbilities = abilities[j].substr(NewSkill + 11,NewSkillEnd - NewSkill - 11); + size_t pos = newAbilities.find("transforms(())"); // Try to handle transforms ability inside transforms keyword. + if(pos != string::npos) + newAbilities.replace(pos, 14, "transforms((" + storedString + "))"); newAbilitiesList.push_back(newAbilities); newAbilityFound = true; } } + size_t pos = sabilities.find("transforms(())"); // Try to handle transforms ability inside transforms keyword. + if(pos != string::npos) + sabilities.replace(pos, 14, "transforms((" + storedString + "))"); if (oneShot || forceUEOT || forceForever) return NEW ATransformerInstant(observer, id, card, target, stypes, sabilities,newpower,newpowerfound,newtoughness,newtoughnessfound,newAbilitiesList,newAbilityFound,forceForever,untilYourNextTurn,newName); diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index c893c7f5d..eaf0043ab 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -287,6 +287,7 @@ void MTGCardInstance::initMTGCI() imprintR = 0; imprintB = 0; imprintW = 0; + foretellTurn = -1; bushidoPoints = 0; modularPoints = 0; entersBattlefield = 0; diff --git a/projects/mtg/src/MTGDefinitions.cpp b/projects/mtg/src/MTGDefinitions.cpp index 795d0c9f2..dbb66a25b 100644 --- a/projects/mtg/src/MTGDefinitions.cpp +++ b/projects/mtg/src/MTGDefinitions.cpp @@ -204,7 +204,8 @@ const char* Constants::MTGBasicAbilities[] = { "inplaytapdeath", //It goes back in play tapped after death. "gainedexiledeath", //It goes to exile after death (use just to give add ability to instants and sorceries which originally have not, e.g. with transforms keyword) "gainedhanddeath", //It goes to hand after death (use just to give add ability to instants and sorceries which originally have not, e.g. with transforms keyword) - "cycling" //It has cycling ability + "cycling", //It has cycling ability + "foretell" //It has foretell cost }; map Constants::MTGBasicAbilitiesMap; diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index dfd3b9961..316245973 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -524,6 +524,12 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta cd->unsecureSetTapped(1); } } + //Has been foretold + else if (attribute.find("foretold") != string::npos) + { + cd->foretellTurn = comparisonCriterion; + cd->foretoldComparisonMode = comparisonMode; + } //Has been kicked else if (attribute.find("kicked") != string::npos) { @@ -589,7 +595,7 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta cd->unsecuresetrecent(1); } } - else if (attribute.find("geared") != string::npos) + else if (attribute.find("geared") != string::npos || attribute.find("equipped") != string::npos) { if (minus) { @@ -1002,7 +1008,7 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta ctc->setAllZones(); return ctc; } - else if (typeName.compare("mystored") == 0) + else if (typeName.compare("mysource") == 0) { return NEW CardTargetChooser(observer, card->storedSourceCard, card, zones, nbzones); }