diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 89426fbb4..4ae33fe36 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -749,10 +749,8 @@ class TrVampired: public TriggeredAbility public: TargetChooser * tc; TargetChooser * fromTc; - vector victems; - int type; - TrVampired(int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL, int type = 0) : - TriggeredAbility(id, source), tc(tc), fromTc(fromTc), type(type) + TrVampired(int id, MTGCardInstance * source, TargetChooser * tc, TargetChooser * fromTc = NULL) : + TriggeredAbility(id, source), tc(tc), fromTc(fromTc) { } @@ -764,64 +762,17 @@ public: int triggerOnEvent(WEvent * event) { if(source->isPhased) return 0; - WEventDamage * e = dynamic_cast (event); - WEventZoneChange * z = dynamic_cast (event); - WEventPhaseChange * pe = dynamic_cast(event); WEventVampire * vamp = dynamic_cast(event); - if (e == event) + if (vamp) { - if (!tc->canTarget(e->damage->target)) return 0; - if (fromTc && !fromTc->canTarget(e->damage->source)) return 0; - - MTGCardInstance * newVictem = (MTGCardInstance*)(e->damage->target); - - victems.push_back(newVictem); - std::sort(victems.begin(), victems.end()); - victems.erase(std::unique(victems.begin(), victems.end()), victems.end()); - } - else if (z == event && !victems.empty()) - { - MTGCardInstance * card = z->card; - - - for(unsigned int k = 0;k < victems.size();k--) - { - if(victems[k] == NULL) - continue; - if(victems[k] != z->card->previous) - { - return 0; - } - } - for(unsigned int w = 0;w < victems.size();w++) - { - if(victems[w] == NULL) - continue; - Player * p = victems[w]->controller(); - if (z->from == p->game->inPlay && z->to == p->game->graveyard) - { - if(victems[w] == z->card->previous) - { - if(!source->isInPlay()) - return 0; - WEvent * e = NEW WEventVampire(victems[w],victems[w],source); - game->receiveEvent(e); - victems[w] = NULL; - return 0; - } - } - } - } - else if (vamp == event) - { - return 1; - } - else if (pe == event) - { - if( pe->from->id == Constants::MTG_PHASE_ENDOFTURN) - { - victems.clear(); - } + if(fromTc && !fromTc->canTarget(vamp->source)) + return 0; + tc->setAllZones(); + //creature that were "vampired" only happens in battlefield, and event sent when they hit a grave. + //setting allzones, as we don't care since we know the preexisting condiations cover the zones. + if(!tc->canTarget(vamp->victem)) + return 0; + return 1; } return 0; } diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index 7447a7a70..22059d5d7 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -253,6 +253,17 @@ public: int testDestroy(); virtual MTGPersistRule * clone() const; }; +/* vampire Rule */ +class MTGVampireRule: public MTGAbility +{ +public: + MTGVampireRule(int _id); + map > victems; + int receiveEvent(WEvent * event); + virtual ostream& toString(ostream& out) const; + int testDestroy(); + virtual MTGVampireRule * clone() const; +}; //unearths destruction if leaves play effect class MTGUnearthRule: public MTGAbility { diff --git a/projects/mtg/src/DuelLayers.cpp b/projects/mtg/src/DuelLayers.cpp index a1a844245..72bd97e18 100644 --- a/projects/mtg/src/DuelLayers.cpp +++ b/projects/mtg/src/DuelLayers.cpp @@ -38,6 +38,7 @@ void DuelLayers::init() action->Add(NEW MTGPlaneWalkerRule(-1)); action->Add(NEW MTGTokensCleanup(-1)); // needs to be before persist action->Add(NEW MTGPersistRule(-1)); + action->Add(NEW MTGVampireRule(-1)); action->Add(NEW MTGUnearthRule(-1)); action->Add(NEW MTGLifelinkRule(-1)); action->Add(NEW MTGDeathtouchRule(-1)); diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index d1f004397..20ea13bd7 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -713,7 +713,7 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string magicText, int fromTc = tcf.createTargetChooser(starget, card); fromTc->targetter = NULL; } - return NEW TrVampired(id, card, tc, fromTc, 0); + return NEW TrVampired(id, card, tc, fromTc); } //when card becomes the target of a spell or ability diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index a70a79fad..0dee78942 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -1819,6 +1819,83 @@ MTGPersistRule * MTGPersistRule::clone() const return a; } +//vampires rule +//handled seperately as a rule since we only want one object to send out events that a card was "vampired". +//otherwise vampire event is sent per instance of @vampired on the battlefield, multipling the results. +MTGVampireRule::MTGVampireRule(int _id) : +MTGAbility(_id, NULL) +{ +} +; + +int MTGVampireRule::receiveEvent(WEvent * event) +{ + WEventDamage * e = dynamic_cast (event); + WEventZoneChange * z = dynamic_cast (event); + WEventPhaseChange * pe = dynamic_cast(event); + if (e) + { + if(!e->damage->damage) + return 0; + if (!e->damage->target) + return 0; + + MTGCardInstance * newVictem = (MTGCardInstance*)(e->damage->target); + MTGCardInstance * vampire = (MTGCardInstance*)(e->damage->source); + + victems[newVictem].push_back(vampire); + + } + else if (z) + { + MTGCardInstance * card = z->card->previous; + if(card && victems[card].empty()) + return 0; + std::sort(victems[card].begin(), victems[card].end()); + victems[card].erase(std::unique(victems[card].begin(), victems[card].end()), victems[card].end()); + //sort and remove duplicates, we only want one event of a vampire damaging a card stored per victem. + for(unsigned int w = 0;w < victems[card].size();w++) + { + if(victems[card].at(w) == NULL) + continue; + Player * p = card->controller(); + if (z->from == p->game->inPlay && z->to == p->game->graveyard) + { + if(card == z->card->previous) + { + WEvent * e = NEW WEventVampire(card,victems[card].at(w),card); + game->receiveEvent(e); + } + } + } + return 0; + } + else if (pe) + { + if( pe->from->id == Constants::MTG_PHASE_ENDOFTURN) + { + victems.clear(); + } + } + return 0; +} + +ostream& MTGVampireRule::toString(ostream& out) const +{ + out << "MTGVampireRule ::: ("; + return MTGAbility::toString(out) << ")"; +} +int MTGVampireRule::testDestroy() +{ + return 0; +} +MTGVampireRule * MTGVampireRule::clone() const +{ + MTGVampireRule * a = NEW MTGVampireRule(*this); + a->isClone = 1; + return a; +} +///////////////////////////////////////////////// //unearth rule---------------------------------- //if the card leaves play, exile it instead. MTGUnearthRule::MTGUnearthRule(int _id) : diff --git a/projects/mtg/src/WEvent.cpp b/projects/mtg/src/WEvent.cpp index b0702a1c6..8a4e74451 100644 --- a/projects/mtg/src/WEvent.cpp +++ b/projects/mtg/src/WEvent.cpp @@ -173,9 +173,9 @@ Targetable * WEventVampire::getTarget(int target) switch (target) { case TARGET_TO: - return source->next; + return victem->next; case TARGET_FROM: - return victem; + return source; } return NULL; }