diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 489b0e02d..6d42a7682 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -278,6 +278,7 @@ public: int triggerOnEvent(WEvent * event) { + if(!activeTrigger) return 0; if(source->isPhased) return 0; WEventZoneChange * e = dynamic_cast (event); if (!e) return 0; @@ -285,8 +286,6 @@ public: return 0; if(isSuspended && !source->suspended) return 0; - if(activeTrigger == false) - return 0; if (!toTcZone->targetsZone(e->to)) return 0; if (!toTcCard->canTarget(e->card)) return 0; if (fromTcZone && !fromTcZone->targetsZone(e->from)) return 0; @@ -325,9 +324,11 @@ class TrCardTapped: public TriggeredAbility public: TargetChooser * tc; bool tap; - TrCardTapped(int id, MTGCardInstance * source, TargetChooser * tc, bool tap = true) : - TriggeredAbility(id, source), tc(tc), tap(tap) + bool once,activeTrigger; + TrCardTapped(int id, MTGCardInstance * source, TargetChooser * tc, bool tap = true, bool once = false) : + TriggeredAbility(id, source), tc(tc), tap(tap), once(once) { + activeTrigger = true; } int resolve() @@ -337,12 +338,15 @@ public: int triggerOnEvent(WEvent * event) { + if(!activeTrigger) return 0; if(source->isPhased) return 0; WEventCardTap * e = dynamic_cast (event); if (!e) return 0; if (e->before == e->after) return 0; if (e->after != tap) return 0; if (!tc->canTarget(e->card)) return 0; + if (once && activeTrigger) + activeTrigger = false; return 1; } @@ -364,9 +368,11 @@ class TrCardTappedformana: public TriggeredAbility public: TargetChooser * tc; bool tap; - TrCardTappedformana(int id, MTGCardInstance * source, TargetChooser * tc, bool tap = true) : - TriggeredAbility(id, source), tc(tc), tap(tap) + bool once,activeTrigger; + TrCardTappedformana(int id, MTGCardInstance * source, TargetChooser * tc, bool tap = true, bool once = false) : + TriggeredAbility(id, source), tc(tc), tap(tap), once(once) { + activeTrigger = true; } int resolve() @@ -376,12 +382,15 @@ public: int triggerOnEvent(WEvent * event) { + if(!activeTrigger) return 0; if(source->isPhased) return 0; WEventCardTappedForMana * e = dynamic_cast (event); if (!e) return 0; if (e->before == e->after) return 0; if (e->after != tap) return 0; if (!tc->canTarget(e->card)) return 0; + if (once && activeTrigger) + activeTrigger = false; return 1; } @@ -539,9 +548,11 @@ class TrcardDrawn: public TriggeredAbility { public: TargetChooser * tc; - TrcardDrawn(int id, MTGCardInstance * source, TargetChooser * tc) : - TriggeredAbility(id, source), tc(tc) + bool once,activeTrigger; + TrcardDrawn(int id, MTGCardInstance * source, TargetChooser * tc,bool once = false) : + TriggeredAbility(id, source), tc(tc), once(once) { + activeTrigger = true; } int resolve() @@ -551,10 +562,13 @@ public: int triggerOnEvent(WEvent * event) { + if(!activeTrigger) return 0; if(source->isPhased) return 0; WEventcardDraw * e = dynamic_cast (event); if (!e) return 0; if (!tc->canTarget(e->player)) return 0; + if (once && activeTrigger) + activeTrigger = false; return 1; } @@ -575,9 +589,11 @@ class TrCardSacrificed: public TriggeredAbility { public: TargetChooser * tc; - TrCardSacrificed(int id, MTGCardInstance * source, TargetChooser * tc) : - TriggeredAbility(id, source), tc(tc) + bool once,activeTrigger; + TrCardSacrificed(int id, MTGCardInstance * source, TargetChooser * tc,bool once = false) : + TriggeredAbility(id, source), tc(tc), once(once) { + activeTrigger = true; } int resolve() @@ -587,10 +603,13 @@ public: int triggerOnEvent(WEvent * event) { + if(!activeTrigger) return 0; if(source->isPhased) return 0; WEventCardSacrifice * e = dynamic_cast (event); if (!e) return 0; if (!tc->canTarget(e->card)) return 0; + if (once && activeTrigger) + activeTrigger = false; return 1; } @@ -611,9 +630,11 @@ class TrCardDiscarded: public TriggeredAbility { public: TargetChooser * tc; - TrCardDiscarded(int id, MTGCardInstance * source, TargetChooser * tc) : + bool once,activeTrigger; + TrCardDiscarded(int id, MTGCardInstance * source, TargetChooser * tc,bool once = false) : TriggeredAbility(id, source), tc(tc) { + activeTrigger = true; } int resolve() @@ -622,10 +643,13 @@ public: } int triggerOnEvent(WEvent * event) { + if(!activeTrigger) return 0; if(source->isPhased) return 0; WEventCardDiscard * e = dynamic_cast (event); if (!e) return 0; if (!tc->canTarget(e->card)) return 0; + if (once && activeTrigger) + activeTrigger = false; return 1; } ~TrCardDiscarded() @@ -649,10 +673,12 @@ public: bool sourceUntapped; bool limitOnceATurn; int triggeredTurn; - TrDamaged(int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL, int type = 0,bool sourceUntapped = false,bool limitOnceATurn = false) : - TriggeredAbility(id, source), tc(tc), fromTc(fromTc), type(type) , sourceUntapped(sourceUntapped),limitOnceATurn(limitOnceATurn) + bool once,activeTrigger; + TrDamaged(int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL, int type = 0,bool sourceUntapped = false,bool limitOnceATurn = false,bool once = false) : + TriggeredAbility(id, source), tc(tc), fromTc(fromTc), type(type) , sourceUntapped(sourceUntapped),limitOnceATurn(limitOnceATurn),once(once) { triggeredTurn = -1; + activeTrigger = true; } int resolve() @@ -662,6 +688,7 @@ public: int triggerOnEvent(WEvent * event) { + if(!activeTrigger) return 0; if(source->isPhased) return 0; WEventDamage * e = dynamic_cast (event); if (!e) return 0; @@ -678,6 +705,8 @@ public: e->damage->source->thatmuch = e->damage->damage; this->source->thatmuch = e->damage->damage; triggeredTurn = g->turn; + if (once && activeTrigger) + activeTrigger = false; return 1; } @@ -702,9 +731,11 @@ public: TargetChooser * fromTc; int type;//this allows damagenoncombat and combatdamage to share this trigger bool sourceUntapped; - TrLifeGained(int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL, int type = 0,bool sourceUntapped = false) : - TriggeredAbility(id, source), tc(tc), fromTc(fromTc), type(type) , sourceUntapped(sourceUntapped) + bool once,activeTrigger; + TrLifeGained(int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL, int type = 0,bool sourceUntapped = false,bool once = false) : + TriggeredAbility(id, source), tc(tc), fromTc(fromTc), type(type) , sourceUntapped(sourceUntapped), once(once) { + activeTrigger = true; } int resolve() @@ -714,6 +745,7 @@ public: int triggerOnEvent(WEvent * event) { + if(!activeTrigger) return 0; if(source->isPhased) return 0; WEventLife * e = dynamic_cast (event); if (!e) return 0; @@ -725,6 +757,8 @@ public: if (type == 0 && (e->amount < 0)) return 0; e->player->thatmuch = abs(e->amount); this->source->thatmuch = abs(e->amount); + if (once && activeTrigger) + activeTrigger = false; return 1; } @@ -748,9 +782,11 @@ class TrVampired: public TriggeredAbility public: TargetChooser * tc; TargetChooser * fromTc; - TrVampired(int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL) : - TriggeredAbility(id, source), tc(tc), fromTc(fromTc) + bool once,activeTrigger; + TrVampired(int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL,bool once = false) : + TriggeredAbility(id, source), tc(tc), fromTc(fromTc), once(once) { + activeTrigger = true; } int resolve() @@ -760,6 +796,7 @@ public: int triggerOnEvent(WEvent * event) { + if(!activeTrigger) return 0; if(source->isPhased) return 0; WEventVampire * vamp = dynamic_cast(event); if (vamp) @@ -771,6 +808,8 @@ public: //setting allzones, as we don't care since we know the preexisting condiations cover the zones. if(!tc->canTarget(vamp->victem)) return 0; + if (once && activeTrigger) + activeTrigger = false; return 1; } return 0; @@ -797,9 +836,11 @@ public: TargetChooser * tc; TargetChooser * fromTc; int type; - TrTargeted(int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL, int type = 0) : - TriggeredAbility(id, source), tc(tc), fromTc(fromTc), type(type) + bool once,activeTrigger; + TrTargeted(int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL, int type = 0,bool once = false) : + TriggeredAbility(id, source), tc(tc), fromTc(fromTc), type(type), once(once) { + activeTrigger = true; } int resolve() @@ -809,11 +850,14 @@ public: int triggerOnEvent(WEvent * event) { + if(!activeTrigger) return 0; if(source->isPhased) return 0; WEventTarget * e = dynamic_cast (event); if (!e) return 0; if (!tc->canTarget(e->card)) return 0; if (fromTc && !fromTc->canTarget(e->source)) return 0; + if (once && activeTrigger) + activeTrigger = false; return 1; } diff --git a/projects/mtg/include/MTGAbility.h b/projects/mtg/include/MTGAbility.h index 5aae3acb8..4ccf1c805 100644 --- a/projects/mtg/include/MTGAbility.h +++ b/projects/mtg/include/MTGAbility.h @@ -424,7 +424,8 @@ public: bool sourceTap; bool lifelost; int lifeamount; - TriggerAtPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId, int who = 0,bool sourceUntapped = false,bool sourceTap = false,bool lifelost = false, int lifeamount = 0); + bool once,activeTrigger; + TriggerAtPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId, int who = 0,bool sourceUntapped = false,bool sourceTap = false,bool lifelost = false, int lifeamount = 0, bool once = false); virtual int trigger(); int resolve(){return 0;}; virtual TriggerAtPhase* clone() const; @@ -436,7 +437,8 @@ public: int destroyActivated; bool sourceUntapped; bool sourceTap; - TriggerNextPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId, int who = 0,bool sourceUntapped = false,bool sourceTap = false); + bool once,activeTrigger; + TriggerNextPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId, int who = 0,bool sourceUntapped = false,bool sourceTap = false,bool once = false); virtual TriggerNextPhase* clone() const; virtual int testDestroy(); diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 2653e6a2e..7ef3364ef 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -481,15 +481,15 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string magicText, int //Card unTapped if (TargetChooser *tc = parseSimpleTC(s,"untapped", card)) - return NEW TrCardTapped(id, card, tc, false); + return NEW TrCardTapped(id, card, tc, false,once); //Card Tapped if (TargetChooser *tc = parseSimpleTC(s,"tapped", card)) - return NEW TrCardTapped(id, card, tc, true); + return NEW TrCardTapped(id, card, tc, true,once); //Card Tapped for mana if (TargetChooser *tc = parseSimpleTC(s,"tappedformana", card)) - return NEW TrCardTappedformana(id, card, tc, true); + return NEW TrCardTappedformana(id, card, tc, true,once); //CombatTrigger //Card card attacked and is blocked @@ -531,63 +531,63 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string magicText, int //Card card is drawn if (TargetChooser * tc = parseSimpleTC(s, "drawn", card)) - return NEW TrcardDrawn(id, card, tc); + return NEW TrcardDrawn(id, card, tc,once); //Card is sacrificed if (TargetChooser * tc = parseSimpleTC(s, "sacrificed", card)) - return NEW TrCardSacrificed(id, card, tc); + return NEW TrCardSacrificed(id, card, tc,once); //Card is Discarded if (TargetChooser * tc = parseSimpleTC(s, "discarded", card)) - return NEW TrCardDiscarded(id, card, tc); + return NEW TrCardDiscarded(id, card, tc,once); //Card Damaging non combat if (TargetChooser * tc = parseSimpleTC(s, "noncombatdamaged", card)) { TargetChooser *fromTc = parseSimpleTC(s, "from", card); - return NEW TrDamaged(id, card, tc, fromTc, 2); + return NEW TrDamaged(id, card, tc, fromTc, 2,once); } //Card Damaging combat if (TargetChooser * tc = parseSimpleTC(s, "combatdamaged", card)) { TargetChooser *fromTc = parseSimpleTC(s, "from", card); - return NEW TrDamaged(id, card, tc, fromTc, 1,sourceUntapped,limitOnceATurn); + return NEW TrDamaged(id, card, tc, fromTc, 1,sourceUntapped,limitOnceATurn,once); } //Card Damaging if (TargetChooser * tc = parseSimpleTC(s, "damaged", card)) { TargetChooser *fromTc = parseSimpleTC(s, "from", card); - return NEW TrDamaged(id, card, tc, fromTc, 0,sourceUntapped,limitOnceATurn); + return NEW TrDamaged(id, card, tc, fromTc, 0,sourceUntapped,limitOnceATurn,once); } //Lifed if (TargetChooser * tc = parseSimpleTC(s, "lifed", card)) { TargetChooser *fromTc = parseSimpleTC(s, "from", card); - return NEW TrLifeGained(id, card, tc, fromTc, 0,sourceUntapped); + return NEW TrLifeGained(id, card, tc, fromTc, 0,sourceUntapped,once); } //Life Loss if (TargetChooser * tc = parseSimpleTC(s, "lifeloss", card)) { TargetChooser *fromTc = parseSimpleTC(s, "from", card); - return NEW TrLifeGained(id, card, tc, fromTc,1,sourceUntapped); + return NEW TrLifeGained(id, card, tc, fromTc,1,sourceUntapped,once); } //Card Damaged and killed by a creature this turn if (TargetChooser * tc = parseSimpleTC(s, "vampired", card)) { TargetChooser *fromTc = parseSimpleTC(s, "from", card); - return NEW TrVampired(id, card, tc, fromTc); + return NEW TrVampired(id, card, tc, fromTc,once); } //when card becomes the target of a spell or ability if (TargetChooser * tc = parseSimpleTC(s, "targeted", card)) { TargetChooser *fromTc = parseSimpleTC(s, "from", card); - return NEW TrTargeted(id, card, tc, fromTc, 0); + return NEW TrTargeted(id, card, tc, fromTc, 0,once); } int who = 0; @@ -607,7 +607,7 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string magicText, int found = s.find(Constants::MTGPhaseCodeNames[i]); if (found != string::npos) { - return NEW TriggerNextPhase(id, card, target, i, who,sourceUntapped); + return NEW TriggerNextPhase(id, card, target, i, who,sourceUntapped,once); } } } @@ -621,7 +621,7 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string magicText, int found = s.find(Constants::MTGPhaseCodeNames[i]); if (found != string::npos) { - return NEW TriggerAtPhase(id, card, target, i, who,sourceUntapped,sourceTap,lifelost,lifeamount); + return NEW TriggerAtPhase(id, card, target, i, who,sourceUntapped,sourceTap,lifelost,lifeamount,once); } } } @@ -3901,9 +3901,10 @@ ostream& ListMaintainerAbility::toString(ostream& out) const return MTGAbility::toString(out) << ")"; } -TriggerAtPhase::TriggerAtPhase(int id, MTGCardInstance * source, Targetable * target, int _phaseId, int who, bool sourceUntapped, bool sourceTap,bool lifelost,int lifeamount) : - TriggeredAbility(id, source, target), phaseId(_phaseId), who(who), sourceUntapped(sourceUntapped), sourceTap(sourceTap),lifelost(lifelost),lifeamount(lifeamount) +TriggerAtPhase::TriggerAtPhase(int id, MTGCardInstance * source, Targetable * target, int _phaseId, int who, bool sourceUntapped, bool sourceTap,bool lifelost,int lifeamount,bool once) : + TriggeredAbility(id, source, target), phaseId(_phaseId), who(who), sourceUntapped(sourceUntapped), sourceTap(sourceTap),lifelost(lifelost),lifeamount(lifeamount),once(once) { + activeTrigger = true; GameObserver * g = GameObserver::GetInstance(); if (g) { @@ -3914,6 +3915,7 @@ TriggerAtPhase::TriggerAtPhase(int id, MTGCardInstance * source, Targetable * ta int TriggerAtPhase::trigger() { + if(!activeTrigger) return 0; if(source->isPhased) return 0; if(lifelost) { @@ -3959,6 +3961,8 @@ TriggerAtPhase::TriggerAtPhase(int id, MTGCardInstance * source, Targetable * ta break; } } + if(once && activeTrigger) + activeTrigger = false; return result; } @@ -3969,10 +3973,11 @@ TriggerAtPhase* TriggerAtPhase::clone() const return a; } -TriggerNextPhase::TriggerNextPhase(int id, MTGCardInstance * source, Targetable * target, int _phaseId, int who,bool sourceUntapped, bool sourceTap) : - TriggerAtPhase(id, source, target, _phaseId, who, sourceUntapped, sourceTap) +TriggerNextPhase::TriggerNextPhase(int id, MTGCardInstance * source, Targetable * target, int _phaseId, int who,bool sourceUntapped, bool sourceTap,bool once) : + TriggerAtPhase(id, source, target, _phaseId, who, sourceUntapped, sourceTap, once) { destroyActivated = 0; + activeTrigger = true; } int TriggerNextPhase::testDestroy()