diff --git a/CHANGELOG.md b/CHANGELOG.md index a22d05eb6..d6877bbbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,11 @@ ## [master] (https://github.com/WagicProject/wagic/tree/master) +### 03/11/21 +- *Committed:* Fixed primitives, added new ability "exploits" to sacrifice a creature, added new trigger "exploited" and improved all primitives with Exploit ability, improved "tokencreated" and "sacrificed" triggers to allow "turnlimited" option, improved "flip" ability in order to keep track of current zone before flip. ([Vitty85](https://github.com/Vitty85)) + ### 31/10/21 -- *Committed:* Fixed primitives, added new macro "_TRAINING_" for new ability "Training", added new trigger "trained", added "trainer" restriction to check if player controls an attacking creature with greater power than the current one, improved "ninjutsu" ability when the targeted card is already in play (e.g. "Olivia, Crimson Bride"), improved "flip" ability in order to add the "andability" option and in ordeer to prevent flipped auras go to graveyard, improved "andability" option for "imprint", "haunt" and "conjure" ability, improved "retarget" and "newtarget" keywords with "fromplay" option (to use with flipped auras e.g. "Vengeful Strangler"), replaced old "praidcount" and "oraidcount" with new keywords "pattackedcount" and "oattackedcount". ([Vitty85](https://github.com/Vitty85)) +- *Committed:* Fixed primitives, added new macro "_TRAINING_" for new ability "Training", added new trigger "trained", added "trainer" restriction to check if player controls an attacking creature with greater power than the current one, improved "ninjutsu" ability when the targeted card is already in play (e.g. "Olivia, Crimson Bride"), improved "flip" ability in order to add the "andability" option and in ordeer to prevent flipped auras go to graveyard, improved "andability" option for "imprint", "haunt" and "conjure" ability, improved "retarget" and "newtarget" keywords with "fromplay" option (to use with flipped auras e.g. "Vengeful Strangler"), replaced old "praidcount" and "oraidcount" with new keywords "pattackedcount" and "oattackedcount". https://github.com/WagicProject/wagic/commit/3baa6acaaf8a994b0fea3c142d14d99d20246da5 ([Vitty85](https://github.com/Vitty85)) ### 27/10/21 - *Committed:* Fixed "Mindbreak Trap", "Summary Dismissa" and "Obeka, Brute Chronologis" primitives. https://github.com/WagicProject/wagic/commit/051f498e54b186bf71c44d7b6595754fbf0d6ab1 ([Vitty85](https://github.com/Vitty85)) diff --git a/projects/mtg/bin/Res/sets/primitives/borderline.txt b/projects/mtg/bin/Res/sets/primitives/borderline.txt index e420bef8b..ec2a4dc3d 100644 --- a/projects/mtg/bin/Res/sets/primitives/borderline.txt +++ b/projects/mtg/bin/Res/sets/primitives/borderline.txt @@ -110,8 +110,8 @@ toughness=* [/card] [card] name=Abrade -auto=choice damage:3 target(creature) -auto=choice destroy target(artifact) +auto=if type(creature|battlefield)~morethan~0 then choice name(Deals 3 damage) name(Deals 3 damage) damage:3 target(creature) +auto=if type(artifact|battlefield)~morethan~0 then choice name(Destroy artifact) name(Destroy artifact) destroy target(artifact) text=Choose one -- Abrade deals 3 damage to target creature. -- Destroy target artifact. mana={1}{R} type=Instant @@ -13139,8 +13139,9 @@ type=Sorcery [/card] [card] name=Conspicuous Snoop +#MISSING: has all activated abilities abilities=showfromtoplibrary -auto=if type(goblin[zpos=1]|mylibrary)~morethan~0 then may activate castcard(normal) all(*[zpos=1]|mylibrary) +auto=aslongas(goblin[zpos=1]|mylibrary) canplayfromlibrarytop >0 text=Play with the top card of your library revealed. -- You may cast Goblin spells from the top of your library. -- As long as the top card of your library is a Goblin card, Conspicuous Snoop has all activated abilities of that card. mana={R}{R} type=Creature @@ -30200,7 +30201,7 @@ toughness=6 [card] name=Gurmag Drowner aicode=activate transforms((,newability[target(*[zpos<=4]|mylibrary) moveto(myhand) and!( all(*[zpos<=4]|mylibrary) moveto(mygraveyard) )!])) ueot -auto=may name(Exploit) sacrifice target(creature|mybattlefield) && name(look) reveal:4 optionone name(Get a card) target(*|reveal) moveto(myhand) optiononeend optiontwo name(put in graveyard) all(*|reveal) moveto(graveyard) optiontwoend revealend +auto=may name(Exploit) exploits target(creature|mybattlefield) && name(look) reveal:4 optionone name(Get a card) target(*|reveal) moveto(myhand) optiononeend optiontwo name(put in graveyard) all(*|reveal) moveto(graveyard) optiontwoend revealend text=Exploit (When this creature enters the battlefield, you may sacrifice a creature.) -- When Gurmag Drowner exploits a creature, look at the top four cards of your library. Put one of them into your hand and the rest into your graveyard. mana={3}{U} type=Creature @@ -40378,7 +40379,7 @@ toughness=1 [card] name=Loathsome Curator abilities=menace -auto=may name(Exploit) target(creature|mybattlefield) transforms((,newability[sacrifice],newability[name(Destroy creature) target(creature[manacost<=3]|opponentbattlefield) destroy])) oneshot +auto=may name(Exploit) target(creature|mybattlefield) exploits and!( transforms((,newability[name(Destroy creature) target(creature[manacost<=3]|opponentbattlefield) destroy])) oneshot )! text=Exploit (When this creature enters the battlefield, you may sacrifice a creature.) -- Menace -- When Loathsome Curator exploits a creature, destroy target creature you don't control with mana value 3 or less. mana={4}{B} type=Creature @@ -51613,7 +51614,7 @@ color=black [/card] [card] name=Profaner of the Dead -auto=may name(Exploit) target(creature|mybattlefield) sacrifice and!( transforms((,newability[name(Return creatures) all(creature[toughness<=tminus1minusend]|opponentbattlefield) moveto(ownerhand)])) oneshot )! +auto=may name(Exploit) target(creature|mybattlefield) exploits and!( transforms((,newability[name(Return creatures) all(creature[toughness<=tminus1minusend]|opponentbattlefield) moveto(ownerhand)])) oneshot )! text=Exploit (When this creature enters the battlefield, you may sacrifice a creature.) -- When Profaner of the Dead exploits a creature, return to their owners' hands all creatures your opponents control with toughness less than the exploited creature's toughness. mana={3}{U} type=Creature @@ -61541,7 +61542,7 @@ toughness=1 [card] name=Silumgar Scavenger abilities=flying -auto=may name(Exploit) sacrifice target(creature|mybattlefield) && all(this) transforms((,newability[haste])) ueot +auto=may name(Exploit) exploits target(creature|mybattlefield) && all(this) transforms((,newability[haste])) ueot auto=@movedto(other creature|graveyard) from(mybattlefield):counter(1/1) text=Flying -- Exploit (When this creature enters the battlefield, you may sacrifice a creature.) -- Whenever another creature you control dies, put a +1/+1 counter on Silumgar Scavenger. It gains haste until end of turn if it exploited that creature. mana={4}{B} diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 25565a533..0bd9487c0 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -6709,9 +6709,10 @@ type=Artifact [/card] [card] name=Asylum Visitor +abilities=madness auto=@each myupkeep restriction{type(*|myhand)~lessthan~1}:draw:1 && life:-1 auto=@each opponent upkeep restriction{type(*|opponenthand)~lessthan~1}:draw:1 && life:-1 -autohand=@discarded(this):may pay[[{1}{B}]] moveto(mystack) && exiledeath ueot +autoexile=restriction{discarded} pay({1}{B}) name(pay 1B to cast) activate name(pay 1B to cast) castcard(normal)?name(put in graveyard) moveto(ownergraveyard) text=At the beginning of each player's upkeep, if that player has no cards in hand, you draw a card and you lose 1 life. -- Madness {1}{B} (If you discard this card, discard it into exile. When you do, cast it for its madness cost or put it into your graveyard.) mana={1}{B} type=Creature @@ -46235,7 +46236,7 @@ toughness=1 [/card] [card] name=Giant Trap Door Spider -auto={1}{R}{G}{T}:moveTo(exile) all(this) && moveTo(exile) target(creature[attacking;-flying|opponentBattlefield) +auto={1}{R}{G}{T}:moveTo(exile) all(this) && moveTo(exile) target(creature[attacking;-flying]|opponentBattlefield) text={1}{R}{G}, {T}: Exile Giant Trap Door Spider and target creature without flying that's attacking you. mana={1}{R}{G} type=Creature @@ -56409,7 +56410,7 @@ type=Enchantment [/card] [card] name=Hunting Kavu -auto={1}{R}{G}{T}:moveTo(exile) all(this) && moveTo(exile) target(creature[attacking;-flying|opponentBattlefield) +auto={1}{R}{G}{T}:moveTo(exile) all(this) && moveTo(exile) target(creature[attacking;-flying]|opponentBattlefield) text={1}{R}{G}, {T}: Exile Hunting Kavu and target creature without flying that's attacking you. mana={1}{R}{G} type=Creature @@ -74416,7 +74417,7 @@ toughness=2 [/card] [card] name=Minister of Pain -auto=may name(Exploit) sacrifice notatarget(creature|mybattlefield) && all(creature|opponentbattlefield) -1/-1 ueot +auto=may name(Exploit) exploits notatarget(creature|mybattlefield) && all(creature|opponentbattlefield) -1/-1 ueot text=Exploit (When this creature enters the battlefield, you may sacrifice a creature.) -- When Minister of Pain exploits a creature, creatures your opponents control get -1/-1 until end of turn. mana={2}{B} type=Creature @@ -90291,7 +90292,7 @@ toughness=2 [/card] [card] name=Qarsi Sadist -auto=may name(Exploit) sacrifice notatarget(creature|mybattlefield) && transforms((,newability[target(opponent) life:-2],newability[life:2 controller])) forever +auto=may name(Exploit) exploits notatarget(creature|mybattlefield) && transforms((,newability[target(opponent) life:-2],newability[life:2 controller])) forever text=Exploit (When this creature enters the battlefield, you may sacrifice a creature.) -- When Qarsi Sadist exploits a creature, target opponent loses 2 life and you gain 2 life. mana={1}{B} type=Creature @@ -91598,7 +91599,7 @@ toughness=2 [/card] [card] name=Rakshasa Gravecaller -auto=may name(Exploit) sacrifice notatarget(creature|mybattlefield) && token(Zombie,Creature Zombie,2/2,black)*2 +auto=may name(Exploit) exploits notatarget(creature|mybattlefield) && token(Zombie,Creature Zombie,2/2,black)*2 text=Exploit (When this creature enters the battlefield, you may sacrifice a creature.) -- When Rakshasa Gravecaller exploits a creature, put two 2/2 black Zombie creature tokens onto the battlefield. mana={4}{B} type=Creature @@ -105019,7 +105020,7 @@ toughness=1 name=Sidisi, Undead Vizier abilities=deathtouch,hiddenface aicode=activate moveto(myhand) notatarget(*|mylibrary) -auto=may name(Exploit) sacrifice notatarget(creature|mybattlefield) and!( reveal:plibrarycount optionone name(choose card) target(*|reveal) moveto(ownerlibrary) and!( becomes(tobecast) ueot )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerlibrary) and!( all(*|reveal) moveto(ownerlibrary) and!(shuffle)! )! optiontwoend afterrevealed all(tobecast|mylibrary) moveto(ownerlibrary) and!(moveTo(myhand))! afterrevealedend revealend )! +auto=may name(Exploit) exploits notatarget(creature|mybattlefield) and!( reveal:plibrarycount optionone name(choose card) target(*|reveal) moveto(ownerlibrary) and!( becomes(tobecast) ueot )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerlibrary) and!( all(*|reveal) moveto(ownerlibrary) and!(shuffle)! )! optiontwoend afterrevealed all(tobecast|mylibrary) moveto(ownerlibrary) and!(moveTo(myhand))! afterrevealedend revealend )! text=Deathtouch -- Exploit (When this creature enters the battlefield, you may sacrifice a creature.) -- When Sidisi, Undead Vizier exploits a creature, you may search your library for a card, put it into your hand, then shuffle your library. mana={3}{B}{B} type=Legendary Creature @@ -105029,7 +105030,7 @@ toughness=6 [/card] [card] name=Sidisi's Faithful -auto=may name(Exploit) sacrifice notatarget(creature|mybattlefield) && transforms((,newability[moveto(myhand) target(creature|battlefield)])) forever +auto=may name(Exploit) exploits notatarget(creature|mybattlefield) && transforms((,newability[moveto(myhand) target(creature|battlefield)])) forever text=Exploit (When this creature enters the battlefield, you may sacrifice a creature.) -- When Sidisi's Faithful exploits a creature, return target creature to its owner's hand. mana={U} type=Creature @@ -105637,7 +105638,7 @@ toughness=1 [/card] [card] name=Silumgar Butcher -auto=may name(Exploit) sacrifice notatarget(creature|mybattlefield) && transforms((,newability[target(creature|battlefield) -3/-3 ueot])) forever +auto=may name(Exploit) exploits notatarget(creature|mybattlefield) && transforms((,newability[target(creature|battlefield) -3/-3 ueot])) forever text=Exploit (When this creature enters the battlefield, you may sacrifice a creature.) -- When Silumgar Butcher exploits a creature, target creature gets -3/-3 until end of turn. mana={4}{B} type=Creature @@ -105657,7 +105658,7 @@ type=Artifact [card] name=Silumgar Sorcerer abilities=flash,flying -auto=may name(Exploit) sacrifice notatarget(creature|mybattlefield) && transforms((,newability[target(creature|stack) fizzle])) forever +auto=may name(Exploit) exploits notatarget(creature|mybattlefield) && transforms((,newability[target(creature|stack) fizzle])) forever text=Flash (You may cast this spell any time you could cast an instant.) -- Flying -- Exploit (When this creature enters the battlefield, you may sacrifice a creature.) -- When Silumgar Sorcerer exploits a creature, counter target creature spell. mana={1}{U}{U} type=Creature @@ -112830,27 +112831,8 @@ type=Instant [/card] [card] name=Starfield of Nyx -auto=@each my upkeep:may target(enchantment|mygraveyard) castcard(putinplay) -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=1]) transforms((,newability[becomes(Creature)],setpower=1,settoughness=1)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=2]) transforms((,newability[becomes(Creature)],setpower=2,settoughness=2)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=3]) transforms((,newability[becomes(Creature)],setpower=3,settoughness=3)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=4]) transforms((,newability[becomes(Creature)],setpower=4,settoughness=4)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=5]) transforms((,newability[becomes(Creature)],setpower=5,settoughness=5)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=6]) transforms((,newability[becomes(Creature)],setpower=6,settoughness=6)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=7]) transforms((,newability[becomes(Creature)],setpower=7,settoughness=7)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=8]) transforms((,newability[becomes(Creature)],setpower=8,settoughness=8)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=9]) transforms((,newability[becomes(Creature)],setpower=9,settoughness=9)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=10]) transforms((,newability[becomes(Creature)],setpower=10,settoughness=10)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=11]) transforms((,newability[becomes(Creature)],setpower=11,settoughness=11)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=12]) transforms((,newability[becomes(Creature)],setpower=12,settoughness=12)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=13]) transforms((,newability[becomes(Creature)],setpower=13,settoughness=13)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=14]) transforms((,newability[becomes(Creature)],setpower=14,settoughness=14)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=15]) transforms((,newability[becomes(Creature)],setpower=15,settoughness=15)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=16]) transforms((,newability[becomes(Creature)],setpower=16,settoughness=16)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=17]) transforms((,newability[becomes(Creature)],setpower=17,settoughness=17)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=18]) transforms((,newability[becomes(Creature)],setpower=18,settoughness=18)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=19]) transforms((,newability[becomes(Creature)],setpower=19,settoughness=19)) >4 -auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura;manacost=20]) transforms((,newability[becomes(Creature)],setpower=20,settoughness=20)) >4 +auto=@each my upkeep:may name(Return enchantment) target(enchantment|mygraveyard) moveto(mybattlefield) +auto=aslongas(enchantment|mybattlefield) lord(other enchantment[-aura]) transforms((Creature,setpower=manacost,settoughness=manacost)) >4 text=At the beginning of your upkeep, you may return target enchantment card from your graveyard to the battlefield. As long as you control five or more enchantments, each other non-Aura enchantment you control is a creature in addition to its other types and has base power and base toughness each equal to its converted mana cost. mana={4}{W} type=Enchantment @@ -130843,7 +130825,7 @@ toughness=5 [card] name=Vulturous Aven abilities=flying -auto=may name(Exploit) sacrifice notatarget(creature|mybattlefield) && draw:2 controller && life:-2 controller +auto=may name(Exploit) exploits notatarget(creature|mybattlefield) && draw:2 controller && life:-2 controller text=Flying -- Exploit (When this creature enters the battlefield, you may sacrifice a creature.) -- When Vulturous Aven exploits a creature, you draw two cards and you lose 2 life. mana={3}{B} type=Creature diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 5273a85b8..70d22175e 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -937,7 +937,9 @@ class TrTokenCreated: public Trigger { public: bool thiscontroller, thisopponent; - TrTokenCreated(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc, bool once = false) : + bool limitOnceATurn; + int triggeredTurn; + TrTokenCreated(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc, bool once = false, bool limitOnceATurn = false) : Trigger(observer, id, source,once, tc) { } @@ -946,7 +948,10 @@ public: { WEventTokenCreated * e = dynamic_cast (event); if (!e) return 0; + if (limitOnceATurn && triggeredTurn == game->turn) + return 0; if (!tc->canTarget(e->card)) return 0; + triggeredTurn = game->turn; return 1; } @@ -959,7 +964,9 @@ public: class TrCardSacrificed: public Trigger { public: - TrCardSacrificed(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc, bool once = false) : + bool limitOnceATurn; + int triggeredTurn; + TrCardSacrificed(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc, bool once = false, bool limitOnceATurn = false) : Trigger(observer, id, source, once, tc) { } @@ -968,6 +975,8 @@ public: { WEventCardSacrifice * e = dynamic_cast (event); if (!e) return 0; + if (limitOnceATurn && triggeredTurn == game->turn) + return 0; MTGCardInstance * check = e->cardAfter; MTGGameZone * oldZone = e->cardAfter->currentZone; check->currentZone = check->previousZone; @@ -983,6 +992,7 @@ public: return 0; } check->currentZone = oldZone; + triggeredTurn = game->turn; return 1; } @@ -992,6 +1002,47 @@ public: } }; +class TrCardExploited: public Trigger +{ +public: + bool limitOnceATurn; + int triggeredTurn; + TrCardExploited(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc, bool once = false, bool limitOnceATurn = false) : + Trigger(observer, id, source, once, tc) + { + } + + int triggerOnEventImpl(WEvent * event) + { + WEventCardExploited * e = dynamic_cast (event); + if (!e) return 0; + if (limitOnceATurn && triggeredTurn == game->turn) + return 0; + MTGCardInstance * check = e->cardAfter; + MTGGameZone * oldZone = e->cardAfter->currentZone; + check->currentZone = check->previousZone; + if (check->next && (check->next->currentZone|| check->isToken)) + { + check = e->cardAfter->next; + oldZone = e->cardAfter->next->currentZone; + check->currentZone = e->cardAfter->next->previousZone; + } + if (!tc->canTarget(check,true)) + { + check->currentZone = oldZone; + return 0; + } + check->currentZone = oldZone; + triggeredTurn = game->turn; + return 1; + } + + TrCardExploited * clone() const + { + return NEW TrCardExploited(*this); + } +}; + class TrCardDiscarded: public Trigger { public: @@ -1732,6 +1783,7 @@ class AASacrificeCard: public ActivatedAbility { public: MTGAbility * andAbility; + bool isExploited; AASacrificeCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target); int resolve(); const string getMenuText(); diff --git a/projects/mtg/include/WEvent.h b/projects/mtg/include/WEvent.h index 256a47183..85e344806 100644 --- a/projects/mtg/include/WEvent.h +++ b/projects/mtg/include/WEvent.h @@ -195,6 +195,13 @@ struct WEventCardSacrifice : public WEventCardUpdate { virtual Targetable * getTarget(int target); }; +//event when card is exploited. +struct WEventCardExploited : public WEventCardUpdate { + MTGCardInstance * cardAfter; + WEventCardExploited(MTGCardInstance * card,MTGCardInstance * afterCard); + virtual Targetable * getTarget(int target); +}; + //event when card is discarded. struct WEventCardDiscard : public WEventCardUpdate { WEventCardDiscard(MTGCardInstance * card); diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index df843c9d3..fedb88eaa 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -4133,6 +4133,7 @@ AASacrificeCard::AASacrificeCard(GameObserver* observer, int _id, MTGCardInstanc { target = _target; andAbility = NULL; + isExploited = false; } int AASacrificeCard::resolve() @@ -4140,14 +4141,18 @@ int AASacrificeCard::resolve() MTGCardInstance * _target = (MTGCardInstance *) target; if (_target) { - if(_target->mutation && _target->parentCards.size() > 0) return 0; // Mutated down cards cannot be sacrificed, they will follow the fate of top-card + if(_target->mutation && _target->parentCards.size() > 0) return 0; // Mutated down cards cannot be sacrificed or exploited, they will follow the fate of top-card Player * p = _target->controller(); MTGCardInstance * beforeCard = _target; p->game->putInGraveyard(_target); while(_target->next) _target = _target->next; - WEvent * e = NEW WEventCardSacrifice(beforeCard,_target); + WEvent * e = NEW WEventCardSacrifice(beforeCard, _target); game->receiveEvent(e); + if(isExploited){ + WEvent * e = NEW WEventCardExploited(beforeCard, _target); + game->receiveEvent(e); + } if(andAbility) { MTGAbility * andAbilityClone = andAbility->clone(); @@ -4169,7 +4174,10 @@ int AASacrificeCard::resolve() const string AASacrificeCard::getMenuText() { - return "Sacrifice"; + if(isExploited) + return "Exploit"; + else + return "Sacrifice"; } AASacrificeCard * AASacrificeCard::clone() const @@ -4802,10 +4810,12 @@ int AAFlip::resolve() } while (_target->next) - _target = _target->next; + _target = _target->next; + MTGGameZone * currentZone = NULL; if(forcetype != "" && _target) // Added to flip Modal Double Faced cards (e.g. Zendikar Rising). { + currentZone = _target->currentZone; // Added to keep track of current zone before flip. for (int i = ((int)_target->types.size())-1; i >= 0; --i) _target->removeType(_target->types[i]); list typesToAdd; @@ -4994,9 +5004,10 @@ int AAFlip::resolve() if(forcetype != "" && _target && _target->isPermanent()) // Added to flip Modal Double Faced cards (e.g. Zendikar Rising). { + if(!currentZone) currentZone = _target->controller()->game->hand; // If NULL, we consider hand as the default currentZone. _target->castMethod = Constants::CAST_NORMALLY; _target->controller()->game->battlefield->addCard(_target); - WEvent * e = NEW WEventZoneChange(_target, _target->controller()->game->hand, _target->controller()->game->battlefield); + WEvent * e = NEW WEventZoneChange(_target, currentZone, _target->controller()->game->battlefield); game->receiveEvent(e); } else { WEvent * e = NEW WEventCardTransforms(_target); diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index a81158149..33c09b4b0 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -1363,11 +1363,15 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string, int id, Spell //Token has been created if (TargetChooser * tc = parseSimpleTC(s, "tokencreated", card)) - return NEW TrTokenCreated(observer, id, card, tc, once); + return NEW TrTokenCreated(observer, id, card, tc, once, limitOnceATurn); //Card is sacrificed if (TargetChooser * tc = parseSimpleTC(s, "sacrificed", card)) - return NEW TrCardSacrificed(observer, id, card, tc, once); + return NEW TrCardSacrificed(observer, id, card, tc, once, limitOnceATurn); + + //Card is exploited + if (TargetChooser * tc = parseSimpleTC(s, "exploited", card)) + return NEW TrCardExploited(observer, id, card, tc, once, limitOnceATurn); //Card is Discarded if (TargetChooser * tc = parseSimpleTC(s, "discarded", card)) @@ -3626,10 +3630,11 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG return a; } - if (s.find("sacrifice") != string::npos) + if (s.find("sacrifice") != string::npos || s.find("exploits") != string::npos) { MTGAbility *a = NEW AASacrificeCard(observer, id, card, target); a->oneShot = 1; + ((AASacrificeCard*)a)->isExploited = (s.find("exploits") != string::npos)?true:false; // added to allow the Exploit trigger. if(storedAndAbility.size()) { string stored = storedAndAbility; @@ -7004,6 +7009,13 @@ int TriggeredAbility::receiveEvent(WEvent * e) resolve(); return 1; } + if(dynamic_cast(e)) + { + //exploited event must resolve instantly or by the time they do the cards that triggered them + //have already been put in graveyard. + resolve(); + return 1; + } if(dynamic_cast(e)) { //discard event must resolve instantly or by the time they do the cards that triggered them diff --git a/projects/mtg/src/WEvent.cpp b/projects/mtg/src/WEvent.cpp index 4689e6b71..bf39827ed 100644 --- a/projects/mtg/src/WEvent.cpp +++ b/projects/mtg/src/WEvent.cpp @@ -110,6 +110,11 @@ WEventCardSacrifice::WEventCardSacrifice(MTGCardInstance * card, MTGCardInstance { } +WEventCardExploited::WEventCardExploited(MTGCardInstance * card, MTGCardInstance * after) : + WEventCardUpdate(card),cardAfter(after) +{ +} + WEventCardDiscard::WEventCardDiscard(MTGCardInstance * card) : WEventCardUpdate(card) { @@ -440,6 +445,15 @@ Targetable * WEventCardSacrifice::getTarget(int target) return NULL; } +Targetable * WEventCardExploited::getTarget(int target) +{ + if (target) + { + return cardAfter; + } + return NULL; +} + Targetable * WEventCardDiscard::getTarget(int target) { if (target) return card;