diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 969ac57ce..0614bfef0 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -2271,7 +2271,8 @@ public: { if (skills.find(card) != skills.end()) { - game->removeObserver(skills[card]); + if(!game->removeObserver(skills[card])) + skills[card]->destroy(); skills.erase(card); } return 1; @@ -3538,6 +3539,18 @@ public: ACounterShroud * clone() const; ~ACounterShroud(); }; +//track an effect using counters. +class ACounterTracker: public MTGAbility +{ +public: + Counter * counter; + int removed; + ACounterTracker(int id, MTGCardInstance * source, MTGCardInstance * target, Counter * counter = NULL); + int addToGame(); + int destroy(); + ACounterTracker * clone() const; + ~ACounterTracker(); +}; //Remove all abilities from target class ALoseAbilities: public MTGAbility { diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 58f13d174..4eceb5efa 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -91,6 +91,7 @@ public: int fresh; int MaxLevelUp; int kicked; + bool isDualWielding; Player * lastController; MTGGameZone * getCurrentZone(); MTGGameZone * previousZone; diff --git a/projects/mtg/include/ThisDescriptor.h b/projects/mtg/include/ThisDescriptor.h index acd66330e..1dfb29ea9 100644 --- a/projects/mtg/include/ThisDescriptor.h +++ b/projects/mtg/include/ThisDescriptor.h @@ -133,6 +133,14 @@ class ThisDamaged:public ThisDescriptor{ ThisDamaged * clone() const; }; +class ThisDualWield:public ThisDescriptor{ + public: + virtual int match(MTGCardInstance * card); + + ThisDualWield(int dualWield); + ThisDualWield * clone() const; +}; + class ThisPower:public ThisDescriptor{ public: virtual int match(MTGCardInstance * card); diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index cd75f35f7..6c0832edc 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -416,6 +416,60 @@ ACounterShroud::~ACounterShroud() SAFE_DELETE(counter); } +//sheild a card from a certain type of counter. +ACounterTracker::ACounterTracker(int id, MTGCardInstance * source, MTGCardInstance * target, Counter * counter) : +MTGAbility(id, source, target),counter(counter) +{ + removed = 0; +} + +int ACounterTracker::addToGame() +{ + MTGCardInstance * _target = (MTGCardInstance*)target; + if(_target && !removed) + { + if(_target->counters->hasCounter(counter->name.c_str(),counter->power,counter->toughness) && _target->counters->hasCounter(counter->name.c_str(),counter->power,counter->toughness)->nb >= counter->nb) + { + for(int nb = 0;nb < counter->nb;nb++) + { + _target->counters->removeCounter(counter->name.c_str(),counter->power,counter->toughness); + removed++; + } + } + return 1; + } + return 0; +} + +int ACounterTracker::destroy() +{ + MTGCardInstance * _target = (MTGCardInstance*)target; + if(_target) + { + if(removed == counter->nb) + { + for(int nb = 0;nb < counter->nb;nb++) + { + _target->counters->addCounter(counter->name.c_str(),counter->power,counter->toughness); + } + } + } + removeFromGame(); + return 1; +} + +ACounterTracker * ACounterTracker::clone() const +{ + ACounterTracker * a = NEW ACounterTracker(*this); + a->counter = this->counter; + return a; +} + +ACounterTracker::~ACounterTracker() +{ + SAFE_DELETE(counter); +} + //removeall counters of a certain type or all. AARemoveAllCounter::AARemoveAllCounter(int id, MTGCardInstance * source, MTGCardInstance * target, const char * _name, int power, int toughness, int nb,bool all, ManaCost * cost) : diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index c7871a9a0..0405e58eb 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -462,6 +462,29 @@ void GameObserver::gameStateBasedEffects() card->graveEffects = false; card->exileEffects = false; } + + if(card->childrenCards.size()) + { + MTGCardInstance * check = NULL; + MTGCardInstance * matched = NULL; + sort(card->childrenCards.begin(),card->childrenCards.end()); + for(unsigned int wC = 0; wC < int(card->childrenCards.size());wC++) + { + check = card->childrenCards[wC]; + for(unsigned int wCC = 0; wCC < int(card->childrenCards.size());wCC++) + { + if(check->getName() == card->childrenCards[wCC]->getName() && check != card->childrenCards[wCC]) + { + card->isDualWielding = true; + matched = card->childrenCards[wCC]; + } + } + if(matched) + wC = card->childrenCards.size(); + } + if(!matched) + card->isDualWielding = false; + } } } //------------------------------------- @@ -539,7 +562,6 @@ void GameObserver::gameStateBasedEffects() c->wasDealtDamage = false; c->damageToController = false; c->damageToOpponent = false; - } for (int t = 0; t < nbcards; t++) { diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 1178057d6..23965bac2 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -2062,7 +2062,20 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG MTGAbility * a = NEW ACounterShroud(id, card, target,counter); return a; } - + //use counters to track by counters to track an efect by counter name. + vector splitCounterTracking = parseBetween(s, "countertrack(", ")"); + if (splitCounterTracking.size()) + { + string splitCounterTrack = splitCounterTracking[1]; + Counter * counter = NULL; + counter = parseCounter(splitCounterTrack, target, spell); + if (!counter) + { + DebugTrace("MTGAbility: can't parse counter:" << s); + return NULL; + } + return NEW ACounterTracker(id, card, target,counter); + } //removes all counters of the specifified type. vector splitRemoveCounter = parseBetween(s, "removeallcounters(", ")"); if (splitRemoveCounter.size()) @@ -4293,9 +4306,20 @@ TriggerAtPhase::TriggerAtPhase(int id, MTGCardInstance * source, Targetable * ta result = 1; break; } + if(castRestriction.size()) + { + if(!source) + result = 1;//can't check these restrictions without a source aka:in a rule.txt + AbilityFactory af; + int checkCond = af.parseCastRestrictions(source,source->controller(),castRestriction); + if(!checkCond) + result = 0; + } + } if(once && activeTrigger) activeTrigger = false; + return result; } diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 0de21f2c7..c72fc8b09 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -138,6 +138,7 @@ void MTGCardInstance::initMTGCI() damageToOpponent = false; damageToController = false; wasDealtDamage = false; + isDualWielding = false; suspended = false; castMethod = Constants::NOT_CAST; mPropertiesChangedSinceLastUpdate = false; diff --git a/projects/mtg/src/ThisDescriptor.cpp b/projects/mtg/src/ThisDescriptor.cpp index fb4c5c11e..84bae62c2 100644 --- a/projects/mtg/src/ThisDescriptor.cpp +++ b/projects/mtg/src/ThisDescriptor.cpp @@ -253,6 +253,19 @@ ThisDescriptor * ThisDescriptorFactory::createThisDescriptor(string s) return NULL; } + //this creature has 2 of the same weapons in its children vector + found = s.find("dualwielding"); + if (found != string::npos) + { + ThisDualWield * td = NEW ThisDualWield(criterion); + if (td) + { + td->comparisonMode = mode; + return td; + } + return NULL; + } + //controller life found = s.find("opponentlife"); if (found != string::npos) @@ -561,6 +574,25 @@ ThisDamaged* ThisDamaged::clone() const return NEW ThisDamaged(*this); } +ThisDualWield::ThisDualWield(int dualWield) +{ + + comparisonCriterion = dualWield; +} + +int ThisDualWield::match(MTGCardInstance * card) +{ +int result = 0; +if(card->isDualWielding) +result = 1; + return matchValue(result); +} + +ThisDualWield* ThisDualWield::clone() const +{ + return NEW ThisDualWield(*this); +} + ThisToughness::ThisToughness(int toughness) { comparisonCriterion = toughness;