diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 8e605a980..3b517263d 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -126694,6 +126694,774 @@ subtype=Orc Warrior power=7 toughness=2 [/card] +##### +##### +##unsorted +[card] +name=Autochthon Wurm +abilities=trample +text=Convoke (Each creature you tap while casting this spell reduces its cost by {1} or by one mana of that creature's color.) -- Trample +mana={10}{G}{G}{G}{W}{W} +other={convoke} name(Convoke) +type=Creature +subtype=Wurm +power=9 +toughness=14 +[/card] +[card] +name=Conclave Equenaut +abilities=flying +other={convoke} name(Convoke) +text=Convoke (Each creature you tap while casting this spell reduces its cost by {1} or by one mana of that creature's color.) -- Flying +mana={4}{W}{W} +type=Creature +subtype=Human Soldier +power=3 +toughness=3 +[/card] +[card] +name=Conclave Phalanx +text=Convoke (Each creature you tap while casting this spell reduces its cost by {1} or by one mana of that creature's color.) -- When Conclave Phalanx enters the battlefield, you gain 1 life for each creature you control. +auto=life:type:creature:mybattlefield +other={convoke} name(Convoke) +mana={4}{W} +type=Creature +subtype=Human Soldier +power=2 +toughness=4 +[/card] +[card] +name=Conclave's Blessing +auto=foreach(other creature|myBattlefield) 0/2 +text=Convoke (Each creature you tap while casting this spell reduces its cost by {1} or by one mana of that creature's color.) -- Enchant creature -- Enchanted creature gets +0/+2 for each other creature you control. +other={convoke} name(Convoke) +mana={3}{W} +type=Enchantment +subtype=Aura +[/card] +[card] +name=Covenant of Blood +target=creature,player +auto=damage:4 +auto=life:4 controller +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Covenant of Blood deals 4 damage to target creature or player and you gain 4 life. +other={convoke} name(Convoke) +mana={6}{B} +type=Sorcery +[/card] +[card] +name=Crowd's Favor +target=creature +auto=first strike ueot +auto=+1/+0 ueot +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Target creature gets +1/+0 and gains first strike until end of turn. (It deals combat damage before creatures without first strike.) +other={convoke} name(Convoke) +mana={R} +type=Instant +[/card] +[card] +name=Devouring Light +target=creature[attacking;blocking] +auto=moveto(exile) +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Exile target attacking or blocking creature. +other={convoke} name(Convoke) +mana={1}{W}{W} +type=Instant +[/card] +[card] +name=Endless Obedience +target=creature|mygraveyard +auto=moveto(mybattlefield) +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Put target creature card from a graveyard onto the battlefield under your control. +other={convoke} name(Convoke) +mana={4}{B}{B} +type=Sorcery +[/card] +[card] +name=Will-Forged Golem +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) +other={convoke} name(Convoke) +mana={6} +type=Artifact Creature +subtype=Golem +power=4 +toughness=4 +[/card] +[card] +name=Unmake the Graves +target=creature|mygraveyard +auto=moveto(myhand) +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Return up to two target creature cards from your graveyard to your hand. +other={convoke} name(Convoke) +mana={4}{B} +type=Instant +[/card] +[card] +name=Triplicate Spirits +auto=token(Spirit,Creature Spirit,1/1,white,flying)*3 +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Put three 1/1 white Spirit creature tokens with flying onto the battlefield. (They can't be blocked except by creatures with flying or reach.) +other={convoke} name(Convoke) +mana={4}{W}{W} +type=Sorcery +[/card] +[card] +name=Sundering Vitae +target=*[artifact;enchantment] +auto=destroy +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Destroy target artifact or enchantment. +other={convoke} name(Convoke) +mana={2}{G} +type=Instant +[/card] +[card] +name=Stoke the Flames +target=creature,player +auto=damage:4 +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Stoke the Flames deals 4 damage to target creature or player. +other={convoke} name(Convoke) +mana={2}{R}{R} +type=Instant +[/card] +[card] +name=Siege Wurm +abilities=trample +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Trample (If this creature would assign enough damage to its blockers to destroy them, you may have it assign the rest of its damage to defending player or planeswalker.) +other={convoke} name(Convoke) +mana={5}{G}{G} +type=Creature +subtype=Wurm +power=5 +toughness=5 +[/card] +[card] +name=Seraph of the Masses +abilities=flying +anyzone=type:creature:mybattlefield/type:creature:mybattlefield cdaactive +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Flying -- Seraph of the Masses's power and toughness are each equal to the number of creatures you control. +other={convoke} name(Convoke) +mana={5}{W}{W} +type=Creature +subtype=Angel +power=* +toughness=* +[/card] +[card] +name=Scatter the Seeds +auto=token(saproling,creature saproling,1/1,green)*3 +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Put three 1/1 green Saproling creature tokens onto the battlefield. +other={convoke} name(Convoke) +mana={3}{G}{G} +type=Instant +[/card] +[card] +name=Root-Kin Ally +auto={T(creature|myBattlefield)}{T(creature|myBattlefield)}:+2/+2 ueot +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Tap two untapped creatures you control: Root-Kin Ally gets +2/+2 until end of turn. +other={convoke} name(Convoke) +mana={4}{G}{G} +type=Creature +subtype=Elemental Warrior +power=3 +toughness=3 +[/card] +[card] +name=Obelisk of Urd +auto=chooseatype lord(creature[chosentype]) +2/+2 chooseend +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- As Obelisk of Urd enters the battlefield, choose a creature type. -- Creatures you control of the chosen type get +2/+2. +other={convoke} name(Convoke) +mana={6} +type=Artifact +[/card] +[card] +name=Nissa's Expedition +target=land[basic]|mylibrary +auto=moveto(mybattlefield) +auto=tap +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Search your library for up to two basic land cards, put them onto the battlefield tapped, then shuffle your library. +other={convoke} name(Convoke) +mana={4}{G} +type=Sorcery +[/card] +[card] +name=Nivmagus Elemental +auto={e(*[instant;sorcery]|mystack}:counter(1/1,2) +text=Exile an instant or sorcery spell you control: Put two +1/+1 counters on Nivmagus Elemental. (That spell won't resolve.) +other={convoke} name(Convoke) +mana={UR} +type=Creature +subtype=Elemental +power=1 +toughness=2 +[/card] +[card] +name=Meditation Puzzle +auto=life:8 controller +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- You gain 8 life. +other={convoke} name(Convoke) +mana={3}{W}{W} +type=Instant +[/card] +[card] +name=Ephemeral Shields +target=creature +auto=indestructible ueot +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Target creature gains indestructible until end of turn. (Damage and effects that say "destroy" don't destroy it.) +other={convoke} name(Convoke) +mana={1}{W} +type=Instant +[/card] +[card] +name=Living Totem +auto=may counter(1/1,1) target(other creature) +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- When Living Totem enters the battlefield, you may put a +1/+1 counter on another target creature. +other={convoke} name(Convoke) +mana={3}{G} +type=Creature +subtype=Plant Elemental +power=2 +toughness=3 +[/card] +[card] +name=Hour of Reckoning +auto=all(creature[-token]) destroy +other={convoke} name(Convoke) +text=Convoke (Each creature you tap while casting this spell reduces its cost by {1} or by one mana of that creature's color.) -- Destroy all nontoken creatures. +other={convoke} name(Convoke) +mana={4}{W}{W}{W} +type=Sorcery +[/card] +[card] +name=Guardian of Vitu-Ghazi +abilities=vigilance +text=Convoke (Each creature you tap while casting this spell reduces its cost by {1} or by one mana of that creature's color.) -- Vigilance +other={convoke} name(Convoke) +mana={6}{G}{W} +type=Creature +subtype=Elemental +power=4 +toughness=7 +[/card] +[card] +name=Gather Courage +target=creature +auto=+2/+2 ueot +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Target creature gets +2/+2 until end of turn. +other={convoke} name(Convoke) +mana={G} +type=Instant +[/card] +[card] +name=Feral Incarnation +auto=token(Beast,Creature Beast,3/3,green)*3 +text=Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.) -- Put three 3/3 green Beast creature tokens onto the battlefield. +other={convoke} name(Convoke) +mana={8}{G} +type=Sorcery +[/card] +[card] +name=Sibsig Muckdraggers +auto=target(creature|mygraveyard) moveto(myhand) +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- When Sibsig Muckdraggers enters the battlefield, return target creature card from your graveyard to your hand. +other={delve} name(Delve) +mana={8}{B} +type=Creature +subtype=Zombie +power=3 +toughness=6 +[/card] +[card] +name=Shambling Attendants +abilities=deathtouch +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- Deathtouch (Any amount of damage this deals to a creature is enough to destroy it.) +other={delve} name(Delve) +mana={7}{B} +type=Creature +subtype=Zombie +power=3 +toughness=5 +[/card] +[card] +name=Set Adrift +target=*[-land]|battlefield +auto=moveto(ownerlibrary) +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- Put target nonland permanent on top of its owner's library. +mana={5}{U} +other={delve} name(Delve) +type=Sorcery +[/card] +[card] +name=Murderous Cut +target=creature +auto=destroy +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- Destroy target creature. +mana={4}{B} +other={delve} name(Delve) +type=Instant +[/card] +[card] +name=Hooting Mandrills +abilities=trample +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- Trample +mana={5}{G} +other={delve} name(Delve) +type=Creature +subtype=Ape +power=4 +toughness=4 +[/card] +[card] +name=Gurmag Angler +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) +mana={6}{B} +other={delve} name(Delve) +type=Creature +subtype=Zombie Fish +power=5 +toughness=5 +[/card] +[card] +name=Dig Through Time +auto=reveal:7 optionone name(Get Card) target(<2>*|reveal) moveto(myhand) optiononeend optiontwo name(put on bottom) target(<7>*|reveal) bottomoflibrary optiontwoend revealend +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- Look at the top seven cards of your library. Put two of them into your hand and the rest on the bottom of your library in any order. +mana={6}{U}{U} +other={delve} name(Delve) +type=Instant +[/card] +[card] +name=Death Rattle +target=creature[-green] +auto=cantregen ueot +auto=destroy +text=Delve (You may exile any number of cards from your graveyard as you cast this spell. It costs {1} less to cast for each card exiled this way.) -- Destroy target nongreen creature. It can't be regenerated. +mana={5}{B} +other={delve} name(Delve) +type=Instant +[/card] +[card] +name=Dead Drop +target=player +auto=ability$! sacrifice notatarget(<2>creature|mybattlefield) !$ targetedplayer +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- Target player sacrifices two creatures. +mana={9}{B} +other={delve} name(Delve) +type=Sorcery +[/card] +[card] +name=Become Immense +target=creature +auto=+6/+6 ueot +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- Target creature gets +6/+6 until end of turn. +mana={5}{G} +other={delve} name(Delve) +type=Instant +[/card] +[card] +name=Will of the Naga +target=creature|battlefield +auto=tap +auto=frozen +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- Tap up to two target creatures. Those creatures don't untap during their controller's next untap step. +mana={4}{U}{U} +other={delve} name(Delve) +type=Instant +[/card] +[card] +name=Wildwood Geist +auto=this(variable{controllerturn}>0) +2/+2 +text=Wildwood Geist gets +2/+2 as long as it's your turn. +mana={4}{G} +type=Creature +subtype=Spirit +power=3 +toughness=3 +[/card] +[card] +name=Marang River Prowler +abilities=cantblock,unblockable +autograveyard=aslongas(*[black;green]|myBattlefield) CanPlayFromGraveyard +text=Marang River Prowler can't block and can't be blocked. -- You may cast Marang River Prowler from your graveyard as long as you control a black or green permanent. +mana={2}{U} +type=Creature +subtype=Human Rogue +power=2 +toughness=1 +[/card] +[card] +name=Treasure Cruise +auto=draw:3 +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- Draw three cards. +mana={7}{U} +other={delve} name(Delve) +type=Sorcery +[/card] +[card] +name=Scout the Borders +auto=reveal:5 optionone name(Get creature or land) target(creature,land|reveal) moveto(myhand) optiononeend optiontwo name(put in grave) all(*|reveal) moveto(mygraveyard) optiontwoend revealend +text=Reveal the top five cards of your library. You may put a creature or land card from among them into your hand. Put the rest into your graveyard. +mana={2}{G} +type=Sorcery +[/card] +[card] +name=Tombstalker +abilities=flying +text=Flying -- Delve (You may exile any number of cards from your graveyard as you cast this spell. It costs {1} less to cast for each card exiled this way.) +mana={6}{B}{B} +other={delve} name(Delve) +type=Creature +subtype=Demon +power=5 +toughness=5 +[/card] +[card] +name=Temporal Trespass +auto=turns:+1 controller +auto=moveto(exile) all(this) +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- Take an extra turn after this one. Exile Temporal Trespass. +mana={8}{U}{U}{U} +other={delve} name(Delve) +type=Sorcery +[/card] +[card] +name=Tasigur's Cruelty +auto=ability$!name(discard 2 cards) target(*|myhand) reject!$ opponent +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- Each opponent discards two cards. +mana={5}{B} +other={delve} name(Delve) +type=Sorcery +[/card] +[card] +name=Sultai Scavenger +abilities=flying +text=Delve (Each card you exile from your graveyard while casting this spell pays for {1}.) -- Flying +other={delve} name(Delve) +mana={5}{B} +other={delve} name(Delve) +type=Creature +subtype=Bird Warrior +power=3 +toughness=3 +[/card] +[card] +name=Marchesa's Smuggler +abilities=dethrone +auto={1}{u}{r}:target(creature|mybattlefield) transforms((,newability[haste ueot],newability[unblockable ueot])) ueot +text=Dethrone (Whenever this creature attacks the player with the most life or tied for most life, put a +1/+1 counter on it.) -- {1}{U}{R}: Target creature you control gains haste until end of turn and can't be blocked this turn. +mana={U}{R} +type=Creature +subtype=Human Rogue +power=1 +toughness=1 +[/card] +[card] +name=Marchesa, the Black Rose +abilities=dethrone +auto=lord(creature|mybattlefield) dethrone +auto=@movedto(graveyard) from(creature[counter{1/1.1}]|mybattlefield):all(trigger[to]) transforms((,haste,newability[@my next endofturn:moveTo(mybattlefield)])) forever +text=Dethrone (Whenever this creature attacks the player with the most life or tied for most life, put a +1/+1 counter on it.) -- Other creatures you control have dethrone. -- Whenever a creature you control with a +1/+1 counter on it dies, return that card to the battlefield under your control at the beginning of the next end step. +mana={1}{U}{B}{R} +type=Legendary Creature +subtype=Human Wizard +power=3 +toughness=3 +[/card] +[card] +name=Marchesa's Infiltrator +abilities=dethrone +auto=@combatdamaged(player) from(this):draw:1 controller +text=Dethrone (Whenever this creature attacks the player with the most life or tied for most life, put a +1/+1 counter on it.) -- Whenever Marchesa's Infiltrator deals combat damage to a player, draw a card. +mana={2}{U} +type=Creature +subtype=Human Rogue +power=1 +toughness=1 +[/card] +[card] +name=Marchesa's Emissary +abilities=dethrone,opponantshroud +text=Hexproof (This creature can't be the target of spells or abilities your opponents control.) -- Dethrone (Whenever this creature attacks the player with the most life or tied for most life, put a +1/+1 counter on it.) +mana={3}{U} +type=Creature +subtype=Human Rogue +power=2 +toughness=2 +[/card] +[card] +name=Grenzo's Cutthroat +abilities=dethrone,first strike +text=First strike -- Dethrone (Whenever this creature attacks the player with the most life or tied for most life, put a +1/+1 counter on it.) +mana={1}{R} +type=Creature +subtype=Goblin Rogue +power=1 +toughness=1 +[/card] +[card] +name=Enraged Revolutionary +abilities=dethrone +text=Dethrone (Whenever this creature attacks the player with the most life or tied for most life, put a +1/+1 counter on it.) +mana={2}{R} +type=Creature +subtype=Human Warrior +power=2 +toughness=1 +[/card] +[card] +name=Treasonous Ogre +abilities=dethrone +auto={L:3}:add{r} +text=Dethrone (Whenever this creature attacks the player with the most life or tied for most life, put a +1/+1 counter on it.) -- Pay 3 life: Add {R} to your mana pool. +mana={3}{R} +type=Creature +subtype=Ogre Shaman +power=2 +toughness=3 +[/card] +[card] +name=Scourge of the Throne +abilities=dethrone,flying +auto=@combat(attackedalone) source(this) turnlimited restriction{compare(lifetotal)~equalto~compare(opponentlifetotal)}: all(creature[attacking]) untap && nextphasealter(add,combatphases,controller,after) +auto=@combat(attackedalone) source(this) turnlimited restriction{compare(lifetotal)~lessthan~compare(opponentlifetotal)}: all(creature[attacking]) untap && nextphasealter(add,combatphases,controller,after) +text=Flying -- Dethrone (Whenever this creature attacks the player with the most life or tied for most life, put a +1/+1 counter on it.) -- Whenever Scourge of the Throne attacks for the first time each turn, if it's attacking the player with the most life or tied for most life, untap all attacking creatures. After this phase, there is an additional combat phase. +mana={4}{R}{R} +type=Creature +subtype=Dragon +power=5 +toughness=5 +[/card] +[card] +name=Amber Prison +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={4}{t}:target(*[creature;land;artifact]) grant transforms((,newability[tap],newability[doesnotuntap])) grantend +text=You may choose not to untap Amber Prison during your untap step. -- {4}, {T}: Tap target artifact, creature, or land. That permanent doesn't untap during its controller's untap step for as long as Amber Prison remains tapped. +mana={4} +type=Artifact +[/card] +[card] +name=Ashnod's Battle Gear +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={2}{t}:target(*[creature]) grant 2/2 grantend +text=You may choose not to untap Ashnod's Battle Gear during your untap step. -- {2}, {T}: Target creature you control gets +2/-2 for as long as Ashnod's Battle Gear remains tapped. +mana={2} +type=Artifact +[/card] +[card] +name=Deserter's Quarters +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={6}{t}:target(*[creature]) grant transforms((,newability[tap],newability[doesnotuntap])) grantend +text=You may choose not to untap Deserter's Quarters during your untap step. -- {6}, {T}: Tap target creature. It doesn't untap during its controller's untap step for as long as Deserter's Quarters remains tapped. +mana={2} +type=Artifact +[/card] +[card] +name=Endoskeleton +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={2}{t}:target(*[creature]) grant +0/+3 grantend +text=You may choose not to untap Endoskeleton during your untap step. -- {2}, {T}: Target creature gets +0/+3 for as long as Endoskeleton remains tapped. +mana={2} +type=Artifact +[/card] +[card] +name=Everglove Courier +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={2}{g}{t}:target(elf) grant +2/+2 grantend +text=You may choose not to untap Everglove Courier during your untap step. -- {2}{G}, {T}: Target Elf creature gets +2/+2 and has trample for as long as Everglove Courier remains tapped. +mana={2}{G} +type=Creature +subtype=Elf +power=2 +toughness=1 +[/card] +[card] +name=Flamestick Courier +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={2}{r}{t}:target(goblin) grant transforms((,newability[2/2],newability[haste])) grantend +text=You may choose not to untap Flamestick Courier during your untap step. -- {2}{R}, {T}: Target Goblin creature gets +2/+2 and has haste for as long as Flamestick Courier remains tapped. +mana={2}{R} +type=Creature +subtype=Goblin +power=2 +toughness=1 +[/card] +[card] +name=Flowstone Armor +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={3}{t}:target(creature) grant +1/-1 grantend +text=You may choose not to untap Flowstone Armor during your untap step. -- {3}, {T}: Target creature gets +1/-1 for as long as Flowstone Armor remains tapped. +mana={3} +type=Artifact +[/card] +[card] +name=Frightshroud Courier +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={2}{b}{t}:target(zombie) grant transforms((,newability[2/2],newability[fear])) grantend +text=You may choose not to untap Frightshroud Courier during your untap step. -- {2}{B}, {T}: Target Zombie creature gets +2/+2 and has fear for as long as Frightshroud Courier remains tapped. (It can't be blocked except by artifact creatures and/or black creatures.) +mana={2}{B} +type=Creature +subtype=Zombie +power=2 +toughness=1 +[/card] +[card] +name=Ghosthelm Courier +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={2}{u}{t}:target(wizard) grant transforms((,newability[2/2],newability[shroud])) grantend +text=You may choose not to untap Ghosthelm Courier during your untap step. -- {2}{U}, {T}: Target Wizard creature gets +2/+2 and has shroud for as long as Ghosthelm Courier remains tapped. (It can't be the target of spells or abilities.) +mana={2}{U} +type=Creature +subtype=Human Wizard +power=2 +toughness=1 +[/card] +[card] +name=Hisoka's Guard +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={1}{u}{t}:target(other creature|mybattlefield) grant shroud grantend +text=You may choose not to untap Hisoka's Guard during your untap step. -- {1}{U}, {T}: Target creature you control other than Hisoka's Guard has shroud for as long as Hisoka's Guard remains tapped. (It can't be the target of spells or abilities.) +mana={1}{U} +type=Creature +subtype=Human Wizard +power=1 +toughness=1 +[/card] +[card] +name=Ice Floe +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={t}:target(creature[-flying&attacking]|opponentbattlefield) grant transforms((,newability[tap],newability[doesnotuntap])) grantend +text=You may choose not to untap Ice Floe during your untap step. -- {T}: Tap target creature without flying that's attacking you. It doesn't untap during its controller's untap step for as long as Ice Floe remains tapped. +type=Land +[/card] +[card] +name=Mana Leech +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={t}:target(land) grant transforms((,newability[tap],newability[doesnotuntap])) grantend +text=You may choose not to untap Mana Leech during your untap step. -- {T}: Tap target land. It doesn't untap during its controller's untap step for as long as Mana Leech remains tapped. +mana={2}{B} +type=Creature +subtype=Leech +power=1 +toughness=1 +[/card] +[card] +name=Mole Worms +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={t}:target(land) grant transforms((,newability[tap],newability[doesnotuntap])) grantend +text=You may choose not to untap Mole Worms during your untap step. -- {T}: Tap target land. It doesn't untap during its controller's untap step for as long as Mole Worms remains tapped. +mana={2}{B} +type=Creature +subtype=Worm +power=1 +toughness=1 +[/card] +[card] +name=Pearlspear Courier +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={2}{w}{t}:target(Soldier) grant transforms((,newability[2/2],newability[vigilance])) grantend +text=You may choose not to untap Pearlspear Courier during your untap step. -- {2}{W}, {T}: Target Soldier creature gets +2/+2 and has vigilance for as long as Pearlspear Courier remains tapped. +mana={2}{W} +type=Creature +subtype=Human Soldier +power=2 +toughness=1 +[/card] +[card] +name=Phyrexian Gremlins +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={t}:target(artifact) grant transforms((,newability[tap],newability[doesnotuntap])) grantend +text=You may choose not to untap Phyrexian Gremlins during your untap step. -- {T}: Tap target artifact. It doesn't untap during its controller's untap step for as long as Phyrexian Gremlins remains tapped. +mana={2}{B} +type=Creature +subtype=Gremlin +power=1 +toughness=1 +[/card] +[card] +name=Rust Tick +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={t}:target(artifact) grant transforms((,newability[tap],newability[doesnotuntap])) grantend +text=You may choose not to untap Rust Tick during your untap step. -- {1}, {T}: Tap target artifact. It doesn't untap during its controller's untap step for as long as Rust Tick remains tapped. +mana={3} +type=Artifact Creature +subtype=Insect +power=1 +toughness=3 +[/card] +[card] +name=Sand Squid +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={t}:target(creature) grant transforms((,newability[tap],newability[doesnotuntap])) grantend +text=Islandwalk -- You may choose not to untap Sand Squid during your untap step. -- {T}: Tap target creature. That creature doesn't untap during its controller's untap step for as long as Sand Squid remains tapped. +mana={3}{U} +type=Creature +subtype=Squid Beast +power=2 +toughness=2 +[/card] +[card] +name=Spirit Shield +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={2}{t}:target(creature) grant +0/+2 grantend +text=You may choose not to untap Spirit Shield during your untap step. -- {2}, {T}: Target creature gets +0/+2 for as long as Spirit Shield remains tapped. +mana={3} +type=Artifact +[/card] +[card] +name=Tawnos's Weaponry +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={2}{t}:target(creature) grant +1/+1 grantend +text=You may choose not to untap Tawnos's Weaponry during your untap step. -- {2}, {T}: Target creature gets +1/+1 for as long as Tawnos's Weaponry remains tapped. +mana={2} +type=Artifact +[/card] +[card] +name=Thalakos Dreamsower +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto=@damagefoeof(player) from(this):target(creature) grant transforms((,newability[tap],newability[doesnotuntap])) grantend +text=Shadow (This creature can block or be blocked by only creatures with shadow.) -- You may choose not to untap Thalakos Dreamsower during your untap step. -- Whenever Thalakos Dreamsower deals damage to an opponent, tap target creature. That creature doesn't untap during its controller's untap step for as long as Thalakos Dreamsower remains tapped. +mana={2}{U} +type=Creature +subtype=Thalakos Wizard +power=1 +toughness=1 +[/card] +[card] +name=Thran Weaponry +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto=upcost[{4}{G};next upkeep] sacrifice +auto={2}{t}:all(this) grant transforms((,newability[lord(creature) +2/+2])) grantend +text=Echo {4} (At the beginning of your upkeep, if this came under your control since the beginning of your last upkeep, sacrifice it unless you pay its echo cost.) -- You may choose not to untap Thran Weaponry during your untap step. -- {2}, {T}: All creatures get +2/+2 for as long as Thran Weaponry remains tapped. +mana={4} +type=Artifact +[/card] +[card] +name=Zelyon Sword +abilities=doesnotuntap +auto=@each my untap sourcetap:may untap +auto={3}{t}:target(creature) grant +2/+0 grantend +text=You may choose not to untap Zelyon Sword during your untap step. -- {3}, {T}: Target creature gets +2/+0 for as long as Zelyon Sword remains tapped. +mana={3} +type=Artifact +[/card] ##due to card type association dryad arbor is placed at the end. any other card that associates 2 super types in this manner should also ##be in the end of the primitive to avoid abilities like changling thinking that "forest" is a creature type. [card] diff --git a/projects/mtg/bin/Res/test/Blink_and_X_counters.txt b/projects/mtg/bin/Res/test/Blink_and_X_counters.txt index 9e12ff2eb..00d91d82e 100644 --- a/projects/mtg/bin/Res/test/Blink_and_X_counters.txt +++ b/projects/mtg/bin/Res/test/Blink_and_X_counters.txt @@ -17,6 +17,7 @@ manapool:{3}{G} [PLAYER2] [DO] Ivy Elemental +choice 3 # add mana to pool plains mountain diff --git a/projects/mtg/bin/Res/test/Distorting_Wake.txt b/projects/mtg/bin/Res/test/Distorting_Wake.txt index 3e80292fd..948d1b8ad 100644 --- a/projects/mtg/bin/Res/test/Distorting_Wake.txt +++ b/projects/mtg/bin/Res/test/Distorting_Wake.txt @@ -9,9 +9,11 @@ manapool:{3}{U}{U}{U} [PLAYER2] [DO] Distorting Wake +choice 3 Mox Pearl Ornithopter Grizzly Bears +Distorting Wake [ASSERT] FIRSTMAIN [PLAYER1] diff --git a/projects/mtg/bin/Res/test/Distorting_Wake2.txt b/projects/mtg/bin/Res/test/Distorting_Wake2.txt index 6a862371a..0ecf1733d 100644 --- a/projects/mtg/bin/Res/test/Distorting_Wake2.txt +++ b/projects/mtg/bin/Res/test/Distorting_Wake2.txt @@ -9,6 +9,7 @@ manapool:{3}{U}{U}{U} [PLAYER2] [DO] Distorting Wake +choice 3 choice 0 Mox Pearl Ornithopter diff --git a/projects/mtg/bin/Res/test/counter_unless_pay_x.txt b/projects/mtg/bin/Res/test/counter_unless_pay_x.txt index e68e3a0fd..474c932e3 100644 --- a/projects/mtg/bin/Res/test/counter_unless_pay_x.txt +++ b/projects/mtg/bin/Res/test/counter_unless_pay_x.txt @@ -14,7 +14,9 @@ think twice no yes syncopate +choice 3 think twice +syncopate choice 0 [ASSERT] firstmain diff --git a/projects/mtg/bin/Res/test/death_grasp.txt b/projects/mtg/bin/Res/test/death_grasp.txt index 4c3bcd370..bcb78804d 100644 --- a/projects/mtg/bin/Res/test/death_grasp.txt +++ b/projects/mtg/bin/Res/test/death_grasp.txt @@ -10,7 +10,9 @@ manapool:{W}{B}{10} [PLAYER2] [DO] Death Grasp +choice 10 p2 +Death Grasp [ASSERT] firstmain [PLAYER1] diff --git a/projects/mtg/bin/Res/test/decree_of_justice.txt b/projects/mtg/bin/Res/test/decree_of_justice.txt index 99f69e540..a1214a66f 100644 --- a/projects/mtg/bin/Res/test/decree_of_justice.txt +++ b/projects/mtg/bin/Res/test/decree_of_justice.txt @@ -8,6 +8,7 @@ manapool:{8}{W}{W} [DO] Decree of Justice choice 0 +choice 6 [ASSERT] FIRSTMAIN [PLAYER1] diff --git a/projects/mtg/bin/Res/test/drain_life.txt b/projects/mtg/bin/Res/test/drain_life.txt index 2c7d01a11..a62582cf5 100644 --- a/projects/mtg/bin/Res/test/drain_life.txt +++ b/projects/mtg/bin/Res/test/drain_life.txt @@ -9,7 +9,9 @@ inplay:1099 life:20 [DO] 1156 +choice 3 1099 +1156 [ASSERT] FIRSTMAIN [PLAYER1] diff --git a/projects/mtg/bin/Res/test/fault_line.txt b/projects/mtg/bin/Res/test/fault_line.txt index 360ff761a..fb1c3695d 100644 --- a/projects/mtg/bin/Res/test/fault_line.txt +++ b/projects/mtg/bin/Res/test/fault_line.txt @@ -8,6 +8,7 @@ manapool:{1}{R}{R} inplay:grizzly bears [DO] fault line +choice 1 [ASSERT] FIRSTMAIN [PLAYER1] diff --git a/projects/mtg/bin/Res/test/feral_hydra.txt b/projects/mtg/bin/Res/test/feral_hydra.txt index d1db67c5f..a021fd29a 100644 --- a/projects/mtg/bin/Res/test/feral_hydra.txt +++ b/projects/mtg/bin/Res/test/feral_hydra.txt @@ -6,6 +6,7 @@ hand:Feral Hydra [player2] [do] Feral Hydra +choice 5 eot eot next diff --git a/projects/mtg/bin/Res/test/fireball_i583.txt b/projects/mtg/bin/Res/test/fireball_i583.txt index 4675e87d9..cc5fe90cf 100644 --- a/projects/mtg/bin/Res/test/fireball_i583.txt +++ b/projects/mtg/bin/Res/test/fireball_i583.txt @@ -10,6 +10,7 @@ inplay:raging goblin,Akrasan Squire,Alpha Myr,Ambush Party,Apprentice Wizard,Arb [PLAYER2] [DO] fireball +choice 14 raging goblin Akrasan Squire Alpha Myr @@ -19,6 +20,7 @@ Arbor Elf Aven Squire Bay Falcon Alpha Myr +next fireball [ASSERT] FIRSTMAIN diff --git a/projects/mtg/bin/Res/test/flowstone_slide.txt b/projects/mtg/bin/Res/test/flowstone_slide.txt index 064c2321c..a8662e584 100644 --- a/projects/mtg/bin/Res/test/flowstone_slide.txt +++ b/projects/mtg/bin/Res/test/flowstone_slide.txt @@ -8,6 +8,7 @@ hand:Flowstone slide [PLAYER2] [DO] Flowstone slide +choice 1 next #begin next diff --git a/projects/mtg/bin/Res/test/gelatinous_genesis.txt b/projects/mtg/bin/Res/test/gelatinous_genesis.txt index 63e62a814..2654ff8da 100644 --- a/projects/mtg/bin/Res/test/gelatinous_genesis.txt +++ b/projects/mtg/bin/Res/test/gelatinous_genesis.txt @@ -8,6 +8,7 @@ manapool:{6}{G} [PLAYER2] [DO] Gelatinous Genesis +choice 6 Mox Ruby Mox Emerald Pyroclasm diff --git a/projects/mtg/bin/Res/test/goblin_offensive.txt b/projects/mtg/bin/Res/test/goblin_offensive.txt index 009ad0bf9..4c78cad0c 100644 --- a/projects/mtg/bin/Res/test/goblin_offensive.txt +++ b/projects/mtg/bin/Res/test/goblin_offensive.txt @@ -7,6 +7,7 @@ hand:goblin offensive [PLAYER2] [DO] goblin offensive +choice 5 [ASSERT] FIRSTMAIN [PLAYER1] diff --git a/projects/mtg/bin/Res/test/howl_from_beyond.txt b/projects/mtg/bin/Res/test/howl_from_beyond.txt index ccb5815aa..73fb4fcb1 100644 --- a/projects/mtg/bin/Res/test/howl_from_beyond.txt +++ b/projects/mtg/bin/Res/test/howl_from_beyond.txt @@ -8,7 +8,9 @@ hand:howl from beyond [PLAYER2] [DO] howl from beyond +choice 5 grizzly bears +howl from beyond next #begin next diff --git a/projects/mtg/bin/Res/test/hurricane.txt b/projects/mtg/bin/Res/test/hurricane.txt index 8aabae80e..b46456ca0 100644 --- a/projects/mtg/bin/Res/test/hurricane.txt +++ b/projects/mtg/bin/Res/test/hurricane.txt @@ -9,6 +9,7 @@ manapool:{4}{G} inplay:serra angel [DO] hurricane +choice 4 [ASSERT] FIRSTMAIN [PLAYER1] diff --git a/projects/mtg/bin/Res/test/ivy_elemental.txt b/projects/mtg/bin/Res/test/ivy_elemental.txt index f29b74eb0..1a5b78b41 100644 --- a/projects/mtg/bin/Res/test/ivy_elemental.txt +++ b/projects/mtg/bin/Res/test/ivy_elemental.txt @@ -9,6 +9,7 @@ manapool:{G}{G}{G}{G} [PLAYER2] [DO] Ivy Elemental +choice 3 next #begin next diff --git a/projects/mtg/bin/Res/test/leyline_of_the_void.txt b/projects/mtg/bin/Res/test/leyline_of_the_void.txt index 48bf357b2..0439dbf38 100644 --- a/projects/mtg/bin/Res/test/leyline_of_the_void.txt +++ b/projects/mtg/bin/Res/test/leyline_of_the_void.txt @@ -13,6 +13,7 @@ library:Mountain Forbidden Orchard choice 2 Black Sun's Zenith +choice 13 [ASSERT] FIRSTMAIN [PLAYER1] diff --git a/projects/mtg/bin/Res/test/prosperity.txt b/projects/mtg/bin/Res/test/prosperity.txt index cc4eeacec..10cb4b07b 100644 --- a/projects/mtg/bin/Res/test/prosperity.txt +++ b/projects/mtg/bin/Res/test/prosperity.txt @@ -9,6 +9,7 @@ manapool:{2}{U} library:plains,forest,mountain [DO] prosperity +choice 2 [ASSERT] FIRSTMAIN [PLAYER1] diff --git a/projects/mtg/bin/Res/test/unwilling_recruit.txt b/projects/mtg/bin/Res/test/unwilling_recruit.txt index 44af4b9be..af5f2d879 100644 --- a/projects/mtg/bin/Res/test/unwilling_recruit.txt +++ b/projects/mtg/bin/Res/test/unwilling_recruit.txt @@ -21,7 +21,9 @@ next plains swamp Unwilling Recruit +choice 2 grizzly bears +Unwilling Recruit next #begin next diff --git a/projects/mtg/bin/Res/test/volcanic_eruption.txt b/projects/mtg/bin/Res/test/volcanic_eruption.txt index 595ac13fe..c875a9881 100644 --- a/projects/mtg/bin/Res/test/volcanic_eruption.txt +++ b/projects/mtg/bin/Res/test/volcanic_eruption.txt @@ -8,6 +8,7 @@ manapool:{U}{U}{U}{W}{W} inplay:1389,1390,1391 [DO] 1231 +choice 2 1389 1390 1231 diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 9be81630a..5a652b823 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -166,8 +166,11 @@ private: { if(!s.size()) return; - if(!card) - return; + if (!card) + { + intValue = atoi(s.c_str());//if there is no card, try parsing a number. + return; + } MTGCardInstance * target = card->target; if(!card->storedCard) card->storedCard = card->storedSourceCard; @@ -272,9 +275,16 @@ private: } if(s == "prex") { - ManaCost * cX = card->controller()->getManaPool()->Diff(card->getManaCost()); - intValue = cX->getCost(Constants::NB_Colors); - delete cX; + if (card->setX > -1) + { + intValue = card->setX; + } + else + { + ManaCost * cX = card->controller()->getManaPool()->Diff(card->getManaCost()); + intValue = cX->getCost(Constants::NB_Colors); + delete cX; + } } else if (s == "x" || s == "X") { @@ -4355,6 +4365,22 @@ public: AAUntapper * clone() const; }; +/*announce card X*/ +class AAWhatsX : public ActivatedAbility +{ +public: + int value; + MTGAbility * costRule; + AAWhatsX(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * source, int value = 0, MTGAbility * costRule = NULL); + int resolve(); + const string getMenuText() + { + sprintf(menuText, "%i", value); + return menuText; + }; + AAWhatsX * clone() const; +}; + /* set max level up on a levelup creature this is an Ai hint ability, no effect for players.*/ class AAWhatsMax: public ActivatedAbility { @@ -5166,7 +5192,38 @@ public: ~AShackleWrapper(); }; +//Grant +class AGrant : public MTGAbility +{ +public: + MTGCardInstance * Blessed; + bool resolved; + MTGAbility * Granted; + MTGAbility * toGrant; + AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant); + void Update(float dt); + void resolveGrant(); + int resolve(); + const string getMenuText(); + AGrant * clone() const; + ~AGrant(); +private: + void removeGranted(MTGCardInstance *_target); +}; +//GrantWrapper +class AGrantWrapper : public InstantAbility +{ +public: + AGrant * ability; + MTGAbility * Granted; + AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant); + int resolve(); + const string getMenuText(); + AGrantWrapper * clone() const; + ~AGrantWrapper(); + +}; //ABlink class ABlink: public MTGAbility { diff --git a/projects/mtg/include/ExtraCost.h b/projects/mtg/include/ExtraCost.h index a42a3f779..8d8e8f2b1 100644 --- a/projects/mtg/include/ExtraCost.h +++ b/projects/mtg/include/ExtraCost.h @@ -274,7 +274,27 @@ public: virtual int doPay(); virtual Ninja * clone() const; }; - +//Convoke +class Convoke : public ExtraCost +{ +public: + ManaCost * getReduction(); + Convoke(TargetChooser *_tc = NULL); + virtual int canPay(); + virtual int isPaymentSet(); + virtual int doPay(); + virtual Convoke * clone() const; +}; +//delve +class Delve : public ExtraCost +{ +public: + Delve(TargetChooser *_tc = NULL); + virtual int canPay(); + virtual int isPaymentSet(); + virtual int doPay(); + virtual Delve * clone() const; +}; //offering cost class Offering : public ExtraCost { diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 2f1923635..cefa5a5d4 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -55,6 +55,7 @@ public: Pos* view; int X; int castX; + int setX; int alternateCostPaid[ManaCost::MANA_PAID_WITH_BESTOW + 1]; int paymenttype; int castMethod; /* Tells if the card reached its current zone by being cast or not (brought into the zone by an effect). non 0 == cast, 0 == not cast */ diff --git a/projects/mtg/include/MTGDefinitions.h b/projects/mtg/include/MTGDefinitions.h index ff19c6e15..e1bdca9cb 100644 --- a/projects/mtg/include/MTGDefinitions.h +++ b/projects/mtg/include/MTGDefinitions.h @@ -251,7 +251,8 @@ class Constants MENACE = 129, NOSOLO = 130,//cant attack alone MUSTBLOCK = 131,//blocks each turn - NB_BASIC_ABILITIES = 132, + DETHRONE = 132, + NB_BASIC_ABILITIES = 133, RARITY_S = 'S', //Special Rarity RARITY_M = 'M', //Mythics diff --git a/projects/mtg/src/ActionLayer.cpp b/projects/mtg/src/ActionLayer.cpp index cc68deee9..06162dd1a 100644 --- a/projects/mtg/src/ActionLayer.cpp +++ b/projects/mtg/src/ActionLayer.cpp @@ -105,6 +105,11 @@ bool ActionLayer::CheckUserInput(JButton key) //being cancelled. currently only menuability and paidability will care. } } + if (observer->mExtraPayment->costs.size() && observer->mExtraPayment->costs[0]->tc) + { + //if we cancel, clear the targets list so that when you try again you dont already have targets from before. + observer->mExtraPayment->costs[0]->tc->initTargets(); + } observer->mExtraPayment = NULL; return 1; } @@ -462,6 +467,10 @@ void ActionLayer::doReactTo(int menuIndex) { int controlid = abilitiesMenu->mObjects[menuIndex]->GetId(); DebugTrace("ActionLayer::doReactTo " << controlid); + if (abilitiesMenu && abilitiesMenu->isMultipleChoice) + { + return ButtonPressedOnMultipleChoice(menuIndex); + } ButtonPressed(0, controlid); } } diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index b4088a9f4..a5b673f3a 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -4412,6 +4412,27 @@ AAWhatsMax * AAWhatsMax::clone() const { return NEW AAWhatsMax(*this); } +//set X value +AAWhatsX::AAWhatsX(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance *, int value, MTGAbility * _costRule) : + ActivatedAbility(observer, id, card, NULL, 0), value(value),costRule(_costRule) +{ +} + +int AAWhatsX::resolve() +{ + if (source) + { + source->setX = value; + + } + costRule->reactToClick(source); + return 1; +} + +AAWhatsX * AAWhatsX::clone() const +{ + return NEW AAWhatsX(*this); +} //count objects on field before doing an effect AACountObject::AACountObject(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance *, ManaCost * _cost, string value) : ActivatedAbility(observer, id, card, _cost, 0), value(value) @@ -6581,6 +6602,112 @@ AShackleWrapper::~AShackleWrapper() SAFE_DELETE(ability); } +//grant +AGrant::AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * _Grant) : + MTGAbility(observer, _id, card) +{ + Granted = _Grant; + target = _target; + Blessed = NULL; + resolved = false; + toGrant = NULL; +} + +void AGrant::Update(float dt) +{ + if (resolved == false) + { + resolved = true; + resolveGrant(); + } + + if (!source->isTapped() || !source->isInPlay(game)) + { + if (Blessed == NULL || !Blessed->isInPlay(game)) + MTGAbility::Update(dt); + MTGCardInstance * _target = Blessed; + removeGranted(_target); + } + else + resolveGrant(); + MTGAbility::Update(dt); +} + +void AGrant::resolveGrant() +{ + if (toGrant) return; + MTGCardInstance * _target = (MTGCardInstance *)target; + if (_target) + { + toGrant = Granted->clone(); + toGrant->target = _target; + toGrant->addToGame(); + Blessed = _target; + } +} + +void AGrant::removeGranted(MTGCardInstance* _target) +{ + if (!toGrant) return; + game->removeObserver(toGrant); + game->removeObserver(this); + Blessed = NULL; + return; +} + +int AGrant::resolve() +{ + return 0; +} +const string AGrant::getMenuText() +{ + return Granted->getMenuText(); +} + +AGrant * AGrant::clone() const +{ + AGrant * a = NEW AGrant(*this); + a->forceDestroy = -1; + a->Granted = Granted->clone(); + return a; +}; +AGrant::~AGrant() +{ + SAFE_DELETE(Granted); +} + +AGrantWrapper::AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * _Grant) : + InstantAbility(observer, _id, source, _target), Granted(_Grant) +{ + ability = NEW AGrant(observer, _id, card, _target,_Grant); +} + +int AGrantWrapper::resolve() +{ + AGrant * a = ability->clone(); + a->target = target; + a->addToGame(); + return 1; +} + +const string AGrantWrapper::getMenuText() +{ + return "Grant"; +} + +AGrantWrapper * AGrantWrapper::clone() const +{ + AGrantWrapper * a = NEW AGrantWrapper(*this); + a->ability = this->ability->clone(); + a->oneShot = 1; + return a; +} + +AGrantWrapper::~AGrantWrapper() +{ + SAFE_DELETE(ability); +} + //a blink ABlink::ABlink(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, bool blinkueot, bool blinkForSource, bool blinkhand, MTGAbility * stored) : MTGAbility(observer, _id, card),blinkueot(blinkueot),blinkForSource(blinkForSource),blinkhand(blinkhand),stored(stored) diff --git a/projects/mtg/src/ExtraCost.cpp b/projects/mtg/src/ExtraCost.cpp index a0c5ca1b8..d8fc5dd65 100644 --- a/projects/mtg/src/ExtraCost.cpp +++ b/projects/mtg/src/ExtraCost.cpp @@ -72,6 +72,10 @@ int ExtraCost::setPayment(MTGCardInstance * card) if (tc) { result = tc->addTarget(card); + //this is flawed logic, we need to fix. if there is a target in list + //we return targetready instead, the card is not pushed back into list + //how ever, it is made the target becuase the result is 1 even if we couldnt + //target it with the targetchooser. if (result) { target = card; @@ -922,6 +926,195 @@ int Ninja::doPay() //endbouncetargetcostforninja +//Convoke +Convoke * Convoke::clone() const +{ + Convoke * ec = NEW Convoke(*this); + if (tc) + ec->tc = tc->clone(); + return ec; +} + +Convoke::Convoke(TargetChooser *_tc) : + ExtraCost("Select Cards To Tap", _tc) +{ +} + +int Convoke::canPay() +{ + return isPaymentSet(); +} + +int Convoke::isPaymentSet() +{ + if (target && target->isTapped()) + { + tc->removeTarget(target); + target->isExtraCostTarget = false; + target = NULL; + return 0; + } + ManaCost * toReduce = getReduction(); + if (target && (!source->controller()->getManaPool()->canAfford(toReduce))) + { + target = NULL; + SAFE_DELETE(toReduce); + return 0; + } + if (target && (source->controller()->getManaPool()->canAfford(toReduce))) + { + SAFE_DELETE(toReduce); + return 1; + } + SAFE_DELETE(toReduce); + return 0; +} + +ManaCost * Convoke::getReduction() +{ + ManaCost * toReduce = NEW ManaCost(source->getManaCost()); + tc->maxtargets = source->getManaCost()->getConvertedCost(); + if (tc->getNbTargets()) + { + vectortargetlist = tc->getTargetsFrom(); + for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) + { + bool next = false; + for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i) + { + if (next == true) + break; + MTGCardInstance * targetCard = dynamic_cast(*it); + if ((targetCard->getManaCost()->hasColor(i) || targetCard->hasColor(i)) && toReduce->hasColor(i)) + { + toReduce->remove(i, 1); + next = true; + } + else + { + toReduce->remove(Constants::MTG_COLOR_ARTIFACT, 1); + next = true; + } + } + } + //if we didnt find it payable one way, lets try again backwards. + if (!source->controller()->getManaPool()->canAfford(toReduce)) + { + SAFE_DELETE(toReduce); + toReduce = NEW ManaCost(source->getManaCost()); + for (vector::reverse_iterator it = targetlist.rbegin(); it != targetlist.rend(); it++) + { + bool next = false; + for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i) + { + if (next == true) + break; + MTGCardInstance * targetCard = dynamic_cast(*it); + if ((targetCard->getManaCost()->hasColor(i) || targetCard->hasColor(i)) && toReduce->hasColor(i)) + { + toReduce->remove(i, 1); + next = true; + } + else + { + toReduce->remove(Constants::MTG_COLOR_ARTIFACT, 1); + next = true; + } + } + } + } + } + return toReduce; +} + +int Convoke::doPay() +{ + if (target && tc->getNbTargets()) + { + ManaCost * toReduce = getReduction(); + target->controller()->getManaPool()->pay(toReduce); + SAFE_DELETE(toReduce); + vectortargetlist = tc->getTargetsFrom(); + for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) + { + MTGCardInstance * targetCard = dynamic_cast(*it); + source->storedCard = targetCard->createSnapShot(); + targetCard->tap(); + } + if (tc) + tc->initTargets(); + return 1; + } + return 0; +} + +//DELVE +Delve * Delve::clone() const +{ + Delve * ec = NEW Delve(*this); + if (tc) + ec->tc = tc->clone(); + return ec; +} + +Delve::Delve(TargetChooser *_tc) : + ExtraCost("Select Cards To Exile", _tc) +{ +} + +int Delve::canPay() +{ + return isPaymentSet(); +} + +int Delve::isPaymentSet() +{ + ManaCost * toReduce = NEW ManaCost(source->getManaCost()); + tc->maxtargets = source->getManaCost()->getCost(Constants::MTG_COLOR_ARTIFACT); + if (tc->getNbTargets()) + { + toReduce->remove(Constants::MTG_COLOR_ARTIFACT, tc->getNbTargets()); + } + if (target && (!source->controller()->getManaPool()->canAfford(toReduce))) + { + target = NULL; + SAFE_DELETE(toReduce); + return 0; + } + if (target && (source->controller()->getManaPool()->canAfford(toReduce))) + { + SAFE_DELETE(toReduce); + return 1; + } + SAFE_DELETE(toReduce); + return 0; +} + +int Delve::doPay() +{ + if (target && tc->getNbTargets()) + { + ManaCost * toReduce = NEW ManaCost(source->getManaCost()); + + toReduce->remove(Constants::MTG_COLOR_ARTIFACT, tc->getNbTargets()); + + target->controller()->getManaPool()->pay(toReduce); + SAFE_DELETE(toReduce); + vectortargetlist = tc->getTargetsFrom(); + for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) + { + MTGCardInstance * targetCard = dynamic_cast(*it); + source->storedCard = targetCard->createSnapShot(); + targetCard->controller()->game->putInExile(targetCard); + } + if (tc) + tc->initTargets(); + return 1; + } + return 0; +} + +/////////////// //Sacrifice target as cost for Offering Offering * Offering::clone() const { @@ -1209,12 +1402,45 @@ int ExtraCosts::tryToSetPayment(MTGCardInstance * card) { for(size_t k = 0; k < costs.size(); k++) { - if(card == costs[k]->target) - return 0; + if (card == costs[k]->target) + { + //tapping or sacrificing a target to pay for its own cost + //is allowed, unless the source is already being tapped and contains a tap target + //or sacced and contains a sactarget + //cost like {t}{s(creature)} the source is allowed to be targeted for this + //if it is a creature. these cases below should be added whenever we a need + //for extra cost that have both a source and target version used on cards. + if (dynamic_cast(costs[k])) + { + for (size_t tapCheck = 0; tapCheck < costs.size(); tapCheck++) + { + if (dynamic_cast(costs[tapCheck])) + { + return 0;//{t}{t(creature)} + } + } + + } + else if (SacrificeCost * checking = dynamic_cast(costs[k])) + { + for (size_t sacCheck = 0; sacCheck < costs.size(); sacCheck++) + { + SacrificeCost * checking2 = dynamic_cast(costs[sacCheck]); + if (checking2) + if ((checking->tc != NULL && checking2->tc == NULL) + || (checking->tc == NULL && checking2->tc != NULL)) + { + return 0; //{s}{s(creature)} + } + } + } + else + return 0; + } } if (int result = costs[i]->setPayment(card)) { - card->isExtraCostTarget = true; + //card->isExtraCostTarget = true;//moved to gameobserver, flawed logic was setting this to true even when it wasnt really a target return result; } } @@ -1251,10 +1477,20 @@ int ExtraCosts::doPay() int result = 0; for (size_t i = 0; i < costs.size(); i++) { - if(costs[i]->target) + if(costs[i]->target)//todo deprecate this let gameobserver control this. { costs[i]->target->isExtraCostTarget = false; } + if (costs[i]->tc) + { + vectortargetlist = costs[i]->tc->getTargetsFrom(); + for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) + { + costs[i]->target = dynamic_cast(*it); + costs[i]->doPay(); + } + } + else result += costs[i]->doPay(); } return result; diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index f3c4bf2ab..693b232c2 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -715,6 +715,27 @@ void GameObserver::gameStateBasedEffects() } } card->bypassTC = false; //turn off bypass + /////////////////////////// + //reset extracost shadows// + /////////////////////////// + card->isExtraCostTarget = false; + if (mExtraPayment != NULL) + { + for (unsigned int ec = 0; ec < mExtraPayment->costs.size(); ec++) + { + + if (mExtraPayment->costs[ec]->tc) + { + vectortargetlist = mExtraPayment->costs[ec]->tc->getTargetsFrom(); + for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) + { + Targetable * cardMasked = *it; + dynamic_cast(cardMasked)->isExtraCostTarget = true; + } + + } + } + } //////////////////////////////////////////////////// //Unattach Equipments that dont have valid targets// //////////////////////////////////////////////////// @@ -733,6 +754,7 @@ void GameObserver::gameStateBasedEffects() } } } + /////////////////////////////////////////////////////// //Remove auras that don't have a valid target anymore// /////////////////////////////////////////////////////// @@ -773,18 +795,7 @@ void GameObserver::gameStateBasedEffects() { card->playerTarget->curses.push_back(card); } - /////////////////////////// - //reset extracost shadows// - /////////////////////////// - card->isExtraCostTarget = false; - if(mExtraPayment != NULL) - { - for(unsigned int ec = 0;ec < mExtraPayment->costs.size();ec++) - { - if( mExtraPayment->costs[ec]->target) - mExtraPayment->costs[ec]->target->isExtraCostTarget = true; - } - } + ////////////////////// //reset morph hiding// ////////////////////// @@ -1046,6 +1057,28 @@ void GameObserver::Affinity() if (!card) continue; + /////////////////////////// + //reset extracost shadows// + /////////////////////////// + card->isExtraCostTarget = false; + if (mExtraPayment != NULL) + { + for (unsigned int ec = 0; ec < mExtraPayment->costs.size(); ec++) + { + + if (mExtraPayment->costs[ec]->tc) + { + vectortargetlist = mExtraPayment->costs[ec]->tc->getTargetsFrom(); + for (vector::iterator it = targetlist.begin(); it != targetlist.end(); it++) + { + Targetable * cardMasked = *it; + dynamic_cast(cardMasked)->isExtraCostTarget = true; + } + + } + } + } + //////////////////////////// bool NewAffinityFound = false; for (unsigned int na = 0; na < card->cardsAbilities.size(); na++) { diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index f6f147ae4..fffb8ae10 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -1374,6 +1374,15 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG } } + 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]); + } + vector splitRevealx = parseBetween(s, "reveal:", " revealend", false); if (!abilfound.size() && !transfound.size() && splitRevealx.size() && storedAbilityString.empty()) { @@ -2242,6 +2251,16 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG return a; } + //grant ability until source is untapped or leaves battlefield + found = s.find("grant "); + if (found != string::npos) + { + MTGAbility * toGrant = parseMagicLine(storedAbilityString, id, spell, card); + MTGAbility * a = NEW AGrantWrapper(observer, id, card, target,toGrant); + a->oneShot = 1; + return a; + } + //momentary blink found = s.find("(blink)"); if (found != string::npos) diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index eb20e1bb3..1c89311f5 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -153,12 +153,14 @@ int MTGCardInstance::init() data = this; X = 0; castX = 0; + setX = -1; return 1; } void MTGCardInstance::initMTGCI() { X = 0; + setX = -1; sample = ""; model = NULL; isToken = false; @@ -779,11 +781,13 @@ int MTGCardInstance::getCurrentToughness() //check stack bool MTGCardInstance::StackIsEmptyandSorcerySpeed() { + Player * whoInterupts = getObserver()->isInterrupting;//leave this so we can actually debug who is interupting/current. + Player * whoCurrent = getObserver()->currentPlayer; if((getObserver()->mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0) && (getObserver()->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN || getObserver()->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN) && - controller() == getObserver()->currentPlayer && - !getObserver()->isInterrupting) + controller() == whoCurrent && + (!whoInterupts || whoInterupts == whoCurrent)) { return true; } @@ -972,6 +976,7 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * new string type = ""; ManaCost * original = NEW ManaCost(); original->copy(newCost); + int reducem = 0; bool resetCost = false; for(unsigned int na = 0; na < card->cardsAbilities.size();na++) diff --git a/projects/mtg/src/MTGDefinitions.cpp b/projects/mtg/src/MTGDefinitions.cpp index d2c76c05f..7c3178dcc 100644 --- a/projects/mtg/src/MTGDefinitions.cpp +++ b/projects/mtg/src/MTGDefinitions.cpp @@ -162,7 +162,8 @@ const char* Constants::MTGBasicAbilities[] = { "skulk", "menace", "nosolo", - "mustblock" + "mustblock", + "dethrone", }; map Constants::MTGBasicAbilitiesMap; diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 37b609f06..753cf3a1f 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -329,7 +329,6 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost *) #ifdef WIN32 cost->Dump(); #endif - //cost of card. if (playerMana->canAfford(cost)) { //------- @@ -351,9 +350,8 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost *) card->sunburst += 1; } } - } - //------- - } + }//if (player->getManaPool()->hasColor(i)) + }//for (int i = 1; i != 6; i++) } return 1;//play if you can afford too. } @@ -367,6 +365,65 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) return 0; Player * player = game->currentlyActing(); ManaCost * cost = card->getManaCost(); + ManaCost * playerMana = player->getManaPool(); + ///////announce X cost/////// + if ((cost->hasX() || cost->hasSpecificX()) && card->setX == -1) + { + vectorselection; + int options = cost->hasSpecificX() ? 20 : (playerMana->getConvertedCost() - cost->getConvertedCost()) + 1; + //you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would + //give me the correct amount sorry. + for (int i = 0; i < options; ++i) + { + + MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this); + MTGAbility * setCardX = setX->clone(); + setCardX->oneShot = true; + selection.push_back(setCardX); + SAFE_DELETE(setX); + } + if (selection.size()) + { + MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection); + game->mLayers->actionLayer()->currentActionCard = card; + a1->resolve(); + } + return 0; + } + /////////////////////////////////////////////////////////////////////////////////////// + //////X is set, below we set sunburst for X if needed and cast or reset the card.////// + //////107.3a If a spell or activated ability has a mana cost, alternative cost, ////// + //////additional cost, and / or activation cost with an{ X }, [-X], or X in it, ////// + //////and the value of X isn’t defined by the text of that spell or ability, the ////// + //////controller of that spell or ability chooses and announces the value of X as////// + //////part of casting the spell or activating the ability. ////// + //////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in ////// + //////its mana cost or in any alternative cost or additional cost it has equals ////// + //////the announced value.While an activated ability is on the stack, any X in ////// + //////its activation cost equals the announced value. ////// + /////////////////////////////////////////////////////////////////////////////////////// + if (card->setX > -1) + { + ManaCost * Xcost = NEW ManaCost(); + Xcost->copy(cost); + Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX); + Xcost->remove(7, 1); + if (playerMana->canAfford(Xcost)) + { + cost->copy(Xcost); + SAFE_DELETE(Xcost); + } + else + { + if (card->setX > -1) + card->setX = -1; + SAFE_DELETE(Xcost); + return 0; + } + } + ////////////////////////////////////////// + ////cards without X contenue from here//// + ////////////////////////////////////////// //this handles extra cost payments at the moment a card is played. if (cost->isExtraPaymentSet()) { @@ -685,7 +742,6 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * ManaCost * cost = card->getManaCost(); cost->Dump(); #endif - //cost of card. if (playerMana->canAfford(alternateManaCost)) { return 1; @@ -713,6 +769,62 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter Player * player = game->currentlyActing(); ManaPool * playerMana = player->getManaPool(); + ///////announce X cost/////// + if ((alternateCost->hasX() || alternateCost->hasSpecificX()) && card->setX == -1) + { + vectorselection; + int options = alternateCost->hasSpecificX()? 20 : (playerMana->getConvertedCost() - alternateCost->getConvertedCost()) + 1; + //you can set up to 20 for specific X, if you cant afford it, it cancels. I couldnt think of a equation that would + //give me the correct amount sorry. + for (int i = 0; i < options; ++i) + { + + MTGAbility * setX = NEW AAWhatsX(game, game->mLayers->actionLayer()->getMaxId(), card, card, i, this); + MTGAbility * setCardX = setX->clone(); + setCardX->oneShot = true; + selection.push_back(setCardX); + SAFE_DELETE(setX); + } + if (selection.size()) + { + MTGAbility * a1 = NEW MenuAbility(game, this->GetId(), card, card, false, selection); + game->mLayers->actionLayer()->currentActionCard = card; + a1->resolve(); + } + return 0; + } + /////////////////////////////////////////////////////////////////////////////////////// + //////X is set, below we set sunburst for X if needed and cast or reset the card.////// + //////107.3a If a spell or activated ability has a mana cost, alternative cost, ////// + //////additional cost, and / or activation cost with an{ X }, [-X], or X in it, ////// + //////and the value of X isn’t defined by the text of that spell or ability, the ////// + //////controller of that spell or ability chooses and announces the value of X as////// + //////part of casting the spell or activating the ability. ////// + //////(See rule 601, “Casting Spells.”) While a spell is on the stack, any X in ////// + //////its mana cost or in any alternative cost or additional cost it has equals ////// + //////the announced value.While an activated ability is on the stack, any X in ////// + //////its activation cost equals the announced value. ////// + /////////////////////////////////////////////////////////////////////////////////////// + if (card->setX > -1) + { + ManaCost * Xcost = NEW ManaCost(); + Xcost->copy(alternateCost); + Xcost->add(Constants::MTG_COLOR_ARTIFACT, card->setX); + Xcost->remove(7, 1);//remove the X + if (playerMana->canAfford(Xcost)) + { + alternateCost->copy(Xcost); + SAFE_DELETE(Xcost); + } + else + { + if (card->setX > -1) + card->setX = -1; + SAFE_DELETE(Xcost); + return 0; + } + } + //this handles extra cost payments at the moment a card is played. if(overload) @@ -766,8 +878,9 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter }//end of storm else { + ManaCost * c = spellCost->Diff(alternateCost); - copy->X = c->getCost(Constants::NB_Colors); + copy->X = card->setX; copy->castX = copy->X; delete c; } @@ -1605,6 +1718,11 @@ int MTGAttackRule::receiveEvent(WEvent *e) if (Check <2) card->initAttackersDefensers(); } + if (card->isAttacker() && card->has(Constants::DETHRONE)) + { + if (p->opponent()->life >= p->life) + card->counters->addCounter(1, 1); + } if (!card->isAttacker() && !event->from->isExtra && card->has(Constants::MUSTATTACK))//cards are only required to attack in the real attack phase of a turn. reactToClick(card); if (!card->isAttacker() && card->has(Constants::TREASON) && p->isAI()) diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index e9af2bd43..de9991d65 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -179,7 +179,13 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan } break; case 'd': //DiscardRandom cost - if (value == "d") + if (value.find("delve") != string::npos) + { + if(!tc) + tc = tcf.createTargetChooser("*|mygraveyard", c); + manaCost->addExtraCost(NEW Delve(tc)); + } + else if (value == "d") { manaCost->addExtraCost(NEW DiscardRandomCost(tc)); } @@ -253,7 +259,13 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan break; case 'c': //Counters or cycle { - if(value == "chosencolor") + if (value.find("convoke") != string::npos) + { + if (!tc) + tc = tcf.createTargetChooser("creature|mybattlefield", c); + manaCost->addExtraCost(NEW Convoke(tc)); + } + else if(value == "chosencolor") { if(c) manaCost->add(c->chooseacolor, 1); diff --git a/projects/mtg/src/TargetsList.cpp b/projects/mtg/src/TargetsList.cpp index 0a55009ec..54d4bad57 100644 --- a/projects/mtg/src/TargetsList.cpp +++ b/projects/mtg/src/TargetsList.cpp @@ -20,9 +20,15 @@ int TargetsList::addTarget(Targetable * target) { if (!alreadyHasTarget(target)) { + TargetChooser * tc = target->getObserver()->getCurrentTargetChooser(); if(!tc || (tc && tc->maxtargets == 1)) { + if (dynamic_cast(this)->maxtargets > int(getNbTargets())) + { + targets.push_back(target); + return 1; + } //because this was originally coded with targets as an array //we have to add this conditional to insure that cards with single target effects //and abilities that seek the nextcardtarget still work correctly.