diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 3dc4b52c8..da3c7ebd9 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -549,16 +549,28 @@ public: class TrCardDiscarded: public Trigger { public: - TrCardDiscarded(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc,bool once = false) : - Trigger(observer, id, source, once, tc) + bool cycledTrigger; + TrCardDiscarded(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc,bool once = false, bool cycledTrigger = false) : + Trigger(observer, id, source, once, tc) { } int triggerOnEventImpl(WEvent * event) { - WEventCardDiscard * e = dynamic_cast (event); - if (!e) return 0; - if (!tc->canTarget(e->card)) return 0; + MTGCardInstance * targetCard = NULL; + if(cycledTrigger) + { + WEventCardCycle * c = dynamic_cast (event); + if (!c) return 0; + targetCard = c->card; + } + else + { + WEventCardDiscard * e = dynamic_cast (event); + if (!e) return 0; + targetCard = e->card; + } + if (!targetCard || !tc->canTarget(targetCard)) return 0; return 1; } @@ -1067,38 +1079,6 @@ public: }; -//Cycling - -class ACycle: public ActivatedAbility -{ -public: - ACycle(GameObserver* observer, int _id, MTGCardInstance * card, Targetable * _target) : - ActivatedAbility(observer, _id, card) - { - target = _target; - } - - int resolve() - { - WEvent * e = NEW WEventCardDiscard(source); - game->receiveEvent(e); - source->controller()->game->putInGraveyard(source); - source->controller()->game->drawFromLibrary(); - return 1; - } - - const char * getMenuText() - { - return "Cycling"; - } - - ACycle * clone() const - { - return NEW ACycle(*this); - } - -}; - //ninjutsu class ANinja: public ActivatedAbility diff --git a/projects/mtg/include/ExtraCost.h b/projects/mtg/include/ExtraCost.h index 6d98ebdbb..a3eb18347 100644 --- a/projects/mtg/include/ExtraCost.h +++ b/projects/mtg/include/ExtraCost.h @@ -106,6 +106,15 @@ public: virtual DiscardCost * clone() const; }; +//cycle +class CycleCost : public ExtraCost +{ +public: + CycleCost(TargetChooser *_tc = NULL); + virtual int doPay(); + virtual CycleCost * clone() const; +}; + //tolibrary cost class ToLibraryCost : public ExtraCost { diff --git a/projects/mtg/include/WEvent.h b/projects/mtg/include/WEvent.h index c33a6f8ad..13cb9a4b8 100644 --- a/projects/mtg/include/WEvent.h +++ b/projects/mtg/include/WEvent.h @@ -183,6 +183,12 @@ struct WEventCardDiscard : public WEventCardUpdate { virtual Targetable * getTarget(int target); }; +//event when card is cycled. +struct WEventCardCycle : public WEventCardUpdate { + WEventCardCycle(MTGCardInstance * card); + virtual Targetable * getTarget(int target); +}; + //Event when a card's "defenser" status changes //before : attacker that card was blocking previously //after: attacker that card is blocking now diff --git a/projects/mtg/src/ExtraCost.cpp b/projects/mtg/src/ExtraCost.cpp index 128ac37a6..711fb8f79 100644 --- a/projects/mtg/src/ExtraCost.cpp +++ b/projects/mtg/src/ExtraCost.cpp @@ -225,8 +225,40 @@ int DiscardCost::doPay() } return 0; } -//to library cost +//cycling +CycleCost * CycleCost::clone() const +{ + CycleCost * ec = NEW CycleCost(*this); + if (tc) + ec->tc = tc->clone(); + return ec; +} + +CycleCost::CycleCost(TargetChooser *_tc) : +ExtraCost("Cycle", _tc) +{ +} + +int CycleCost::doPay() +{ + MTGCardInstance * _source = (MTGCardInstance *) source; + if (_source) + { + WEvent * e = NEW WEventCardDiscard(target);//cycling sends 2 events one for the discard and one for the specific cycle trigger + GameObserver * game = _source->owner->getObserver(); + game->receiveEvent(e); + WEvent * e2 = NEW WEventCardCycle(_source); + game->receiveEvent(e2); + _source->controller()->game->putInGraveyard(_source); + if (tc) + tc->initTargets(); + return 1; + } + return 0; +} + +//to library cost ToLibraryCost * ToLibraryCost::clone() const { ToLibraryCost * ec = NEW ToLibraryCost(*this); diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 87c7fd5e5..d132b3673 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -598,6 +598,10 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string magicText, int if (TargetChooser * tc = parseSimpleTC(s, "discarded", card)) return NEW TrCardDiscarded(observer, id, card, tc,once); + //Card is cycled + if (TargetChooser * tc = parseSimpleTC(s, "cycled", card)) + return NEW TrCardDiscarded(observer, id, card, tc,once,true); + //Card Damaging non combat if (TargetChooser * tc = parseSimpleTC(s, "noncombatdamaged", card)) { @@ -1510,14 +1514,6 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG { return AbilityFactory::parseUpkeepAbility(s,card,spell,restrictions,id); } - //Cycling - found = s.find("cycling"); - if (found != string::npos) - { - MTGAbility * a = NEW ACycle(observer, id, card, target); - a->oneShot = 1; - return a; - } //ninjutsu found = s.find("ninjutsu"); diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index 0cdcd1d5d..a616dd4e6 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -163,34 +163,41 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan manaCost->addExtraCost(NEW UnTapCost); break; } - case 'c': //Counters - { - size_t counter_start = value.find("("); - size_t counter_end = value.find(")", counter_start); - AbilityFactory abf(g); - string counterString = value.substr(counter_start + 1, counter_end - counter_start - 1); - Counter * counter = abf.parseCounter(counterString, c); - size_t separator = value.find(",", counter_start); - size_t separator2 = string::npos; - if (separator != string::npos) + case 'c': //Counters or cycle { - separator2 = value.find(",", counter_end + 1); + if(value == "cycle") + { + manaCost->addExtraCost(NEW CycleCost(tc)); + } + else + { + size_t counter_start = value.find("("); + size_t counter_end = value.find(")", counter_start); + AbilityFactory abf(g); + string counterString = value.substr(counter_start + 1, counter_end - counter_start - 1); + Counter * counter = abf.parseCounter(counterString, c); + size_t separator = value.find(",", counter_start); + size_t separator2 = string::npos; + if (separator != string::npos) + { + separator2 = value.find(",", counter_end + 1); + } + SAFE_DELETE(tc); + size_t target_start = string::npos; + if (separator2 != string::npos) + { + target_start = value.find(",", counter_end + 1); + } + size_t target_end = value.length(); + if (target_start != string::npos && target_end != string::npos) + { + string target = value.substr(target_start + 1, target_end - 1 - target_start); + tc = tcf.createTargetChooser(target, c); + } + manaCost->addExtraCost(NEW CounterCost(counter, tc)); + } + break; } - SAFE_DELETE(tc); - size_t target_start = string::npos; - if (separator2 != string::npos) - { - target_start = value.find(",", counter_end + 1); - } - size_t target_end = value.length(); - if (target_start != string::npos && target_end != string::npos) - { - string target = value.substr(target_start + 1, target_end - 1 - target_start); - tc = tcf.createTargetChooser(target, c); - } - manaCost->addExtraCost(NEW CounterCost(counter, tc)); - break; - } default: //uncolored cost and hybrid costs { int intvalue = atoi(value.c_str()); diff --git a/projects/mtg/src/WEvent.cpp b/projects/mtg/src/WEvent.cpp index 54fd793db..5869c9dfb 100644 --- a/projects/mtg/src/WEvent.cpp +++ b/projects/mtg/src/WEvent.cpp @@ -97,6 +97,11 @@ WEventCardDiscard::WEventCardDiscard(MTGCardInstance * card) : { } +WEventCardCycle::WEventCardCycle(MTGCardInstance * card) : +WEventCardUpdate(card) +{ +} + WEventVampire::WEventVampire(MTGCardInstance * card,MTGCardInstance * source,MTGCardInstance * victem) : WEventCardUpdate(card),source(source),victem(victem) { @@ -232,6 +237,12 @@ Targetable * WEventCardDiscard::getTarget(int target) return NULL; } +Targetable * WEventCardCycle::getTarget(int target) +{ + if (target) return card; + return NULL; +} + Targetable * WEventCardAttackedNotBlocked::getTarget(int target) { if (target) return card;