diff --git a/projects/mtg/include/GameObserver.h b/projects/mtg/include/GameObserver.h index bc6ed24c2..de8fbcff4 100644 --- a/projects/mtg/include/GameObserver.h +++ b/projects/mtg/include/GameObserver.h @@ -73,6 +73,7 @@ class GameObserver{ ~GameObserver(); void gameStateBasedEffects(); void enchantmentStatus(); + void Affinity(); void eventOccured(); void addObserver(MTGAbility * observer); void removeObserver(ActionElement * observer); diff --git a/projects/mtg/include/MTGGameZones.h b/projects/mtg/include/MTGGameZones.h index 932941a28..ed76f7526 100644 --- a/projects/mtg/include/MTGGameZones.h +++ b/projects/mtg/include/MTGGameZones.h @@ -6,6 +6,7 @@ using std::map; #include "MTGDeck.h" #include "MTGCardInstance.h" +#include "TargetChooser.h" #define MTG_MAX_PLAYER_CARDS 100 @@ -80,6 +81,7 @@ class MTGGameZone { MTGCardInstance * hasCard(MTGCardInstance * card); void cleanupPhase(); int countByType(const char * value); + int countByCanTarget(TargetChooser * tc); MTGCardInstance * findByName(string name); int hasAbility(int ability); //returns 1 if one of the cards in the zone has the ability, 0 otherwise int hasType(const char * value); //returns 1 if one of the cards in the zone has the type, 0 otherwise diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index 202918127..770af1b89 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -170,16 +170,6 @@ public: int testDestroy(); virtual MTGPersistRule * clone() const; }; -//affinity rules -class MTGAffinityRule: public MTGAbility -{ -public: - MTGAffinityRule(int _id); - int receiveEvent(WEvent * event); - virtual ostream& toString(ostream& out) const; - int testDestroy(); - virtual MTGAffinityRule * 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 bf08210ad..b5d78dfd5 100644 --- a/projects/mtg/src/DuelLayers.cpp +++ b/projects/mtg/src/DuelLayers.cpp @@ -35,7 +35,6 @@ 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 MTGAffinityRule(-1)); action->Add(NEW MTGUnearthRule(-1)); action->Add(NEW MTGLifelinkRule(-1)); action->Add(NEW MTGDeathtouchRule(-1)); diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index be483813b..38ff0dc86 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -692,6 +692,10 @@ void GameObserver::gameStateBasedEffects() // Check auras on a card// ////////////////////////// enchantmentStatus(); + ///////////////////////////// + // Check affinity on a card// + ///////////////////////////// + Affinity(); ///////////////////////////////////// // Check colored statuses on cards // ///////////////////////////////////// @@ -791,6 +795,78 @@ void GameObserver::enchantmentStatus() } } } + +void GameObserver::Affinity() +{ + for (int i = 0; i < 2; i++) + { + MTGGameZone * zone = players[i]->game->hand; + for (int k = zone->nb_cards - 1; k >= 0; k--) + { + MTGCardInstance * card = zone->cards[k]; + int color = 0; + string type = ""; + //only do any of the following if a card with the stated ability is in your hand. + if(card && + (card->has(Constants::AFFINITYARTIFACTS)|| + card->has(Constants::AFFINITYFOREST)|| + card->has(Constants::AFFINITYGREENCREATURES)|| + card->has(Constants::AFFINITYISLAND)|| + card->has(Constants::AFFINITYMOUNTAIN)|| + card->has(Constants::AFFINITYPLAINS)|| + card->has(Constants::AFFINITYSWAMP))){ + if (card && card->has(Constants::AFFINITYARTIFACTS)) + { + type = "artifact"; + } + else if (card && card->has(Constants::AFFINITYSWAMP)) + { + type = "swamp"; + } + else if (card && card->has(Constants::AFFINITYMOUNTAIN)) + { + type = "mountain"; + } + else if (card && card->has(Constants::AFFINITYPLAINS)) + { + type = "plains"; + } + else if (card && card->has(Constants::AFFINITYISLAND)) + { + type = "island"; + } + else if (card && card->has(Constants::AFFINITYFOREST)) + { + type = "forest"; + } + else if (card && card->has(Constants::AFFINITYGREENCREATURES)) + { + color = 1; + type = "creature"; + } + ManaCost * original = card->model->data->getManaCost(); + card->getManaCost()->copy(original); + int reduce = 0; + if(card->has(Constants::AFFINITYGREENCREATURES)) + { + TargetChooserFactory tf; + TargetChooser * tc = tf.createTargetChooser("creature[green]",NULL); + reduce = card->controller()->game->battlefield->countByCanTarget(tc); + SAFE_DELETE(tc); + } + else + { + reduce = card->controller()->game->battlefield->countByType(type.c_str()); + } + for(int i = 0; i < reduce;i++) + { + if(card->getManaCost()->getCost(color) > 0) + card->getManaCost()->remove(color,1); + } + } + } + } +} void GameObserver::Render() { mLayers->Render(); diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 098d2c9ef..171e8c9ce 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -2926,6 +2926,7 @@ int AbilityFactory::getAbilities(vector * v, Spell * spell, MTGCar MTGCardInstance * target = card->target; if (!target) target = card; + card->getManaCost()->copy(card->model->data->getManaCost()); string magicText; card->graveEffects = false; card->exileEffects = false; diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 9d6eee14e..df755bed5 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -460,9 +460,21 @@ int MTGGameZone::countByType(const char * value) } } return result; - } - +int MTGGameZone::countByCanTarget(TargetChooser * tc) +{ +if(!tc) +return 0; + int result = 0; + for (int i = 0; i < (nb_cards); i++) + { + if (tc->canTarget(cards[i])) + { + result++; + } + } + return result; +} MTGCardInstance * MTGGameZone::findByName(string name) { for (int i = 0; i < (nb_cards); i++) diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index f806ebded..0333d6260 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -1457,294 +1457,7 @@ MTGUnearthRule * MTGUnearthRule::clone() const a->isClone = 1; return a; } -//---------------------------------------------------------------------- -//Affinity rule------------------------------------------------------ -//this rule is for Affinity cards. - -MTGAffinityRule::MTGAffinityRule(int _id) : -MTGAbility(_id, NULL) -{ -} -; -int MTGAffinityRule::receiveEvent(WEvent * event) -{ - if (event->type == WEvent::CHANGE_ZONE) - { - WEventZoneChange * e = (WEventZoneChange *) event; - MTGCardInstance * card = e->card->previous; - if (e && card) - { - int color = -1; - string type = ""; - int ok = 0; - for (int i = 0; i < 2; i++) - { - Player * p = game->players[i]; - if (e->to == p->game->hand) - ok = 1;//affinity card enters hand - //--------- - //when cards with affinity enter you hand from anywhere a redux is applied to them for the artifacts in play. - if (ok == 1) - {//enters play from anywhere - if (e->from == p->game->graveyard - || e->from == p->game->hand - || e->from == p->game->library - || e->from == p->game->exile - || e->from == p->game->stack - || e->from == p->opponent()->game->battlefield - || e->from == p->game->temp - || e->from == p->game->battlefield - ) - { - // TODO: - // what happens if there are any cards with two or more affinity abilities? If no such card exist - // then could this block be changed to use else if? That will save on the number of operations. - MTGCardInstance * card = e->card->previous; - if (card && card->has(Constants::AFFINITYARTIFACTS)) - { - color = 0; - type = "artifact"; - } - if (card && card->has(Constants::AFFINITYSWAMP)) - { - color = 0; - type = "swamp"; - } - if (card && card->has(Constants::AFFINITYMOUNTAIN)) - { - color = 0; - type = "mountain"; - } - if (card && card->has(Constants::AFFINITYPLAINS)) - { - color = 0; - type = "plains"; - } - if (card && card->has(Constants::AFFINITYISLAND)) - { - color = 0; - type = "island"; - } - if (card && card->has(Constants::AFFINITYFOREST)) - { - color = 0; - type = "forest"; - } - if (card && card->has(Constants::AFFINITYGREENCREATURES)) - { - color = 1; - type = "creature"; - } - //--redux effect - MTGGameZone * z = card->controller()->game->battlefield; - int nbcards = z->nb_cards; - for (int j = 0; j < nbcards; ++j) - { - MTGCardInstance * c = z->cards[j]; - int check = e->card->getManaCost()->getConvertedCost(); - if ((e->card->has(Constants::AFFINITYARTIFACTS) && c->hasSubtype("artifact")) - || (e->card->has(Constants::AFFINITYSWAMP) && c->hasSubtype("swamp")) - || (e->card->has(Constants::AFFINITYMOUNTAIN) && c->hasSubtype("moutain")) - || (e->card->has(Constants::AFFINITYPLAINS) && c->hasSubtype("plains")) - || (e->card->has(Constants::AFFINITYISLAND) && c->hasSubtype("island")) - || (e->card->has(Constants::AFFINITYFOREST) && c->hasSubtype("forest")) - || (e->card->has(Constants::AFFINITYGREENCREATURES) && c->hasColor(1) && c->isCreature()) - ) - { - if (check > 0) - { - if (color > 0 && !e->card->getManaCost()->hasColor(color)) - {//do nothing if its colored redux and the cards dont have the color - } - else - { - //do normal redux - e->card->getManaCost()->remove(color, 1); - }//one less colorless to cast - } - else - { - e->card->reduxamount += 1; - } - } - }//--end of redux bracket - } - }//if ok == 1 - //-------------maintaining cost---------------------------------------------------------------- - ok = 0; - if (e->to == p->game->battlefield) - ok = 2;//card enters play - if (ok == 2) - {//enters play from anywhere - if (e->from == p->game->graveyard - || e->from == p->game->hand - || e->from == p->game->library - || e->from == p->game->exile - || e->from == p->game->stack - || e->from == p->game->temp - ) - { - //--redux effect - MTGGameZone * z = card->controller()->game->hand; - int nbcards = z->nb_cards; - int colored = 0; - string etype = ""; - MTGCardInstance * card = e->card->previous; - if (card && card->hasSubtype("artifact")) - { - etype.append("art"); - } - if (card && card->hasSubtype("swamp")) - { - etype.append("swa"); - } - if (card && card->hasSubtype("mountain")) - { - etype.append("mou"); - } - if (card && card->hasSubtype("plains")) - { - etype.append("pla"); - } - if (card && card->hasSubtype("island")) - { - etype.append("isl"); - } - if (card && card->hasSubtype("forest")) - { - etype.append("for"); - } - if (card && card->hasSubtype("creature") && card->hasColor(1)) - { - etype.append("cre"); - colored = 1; - } - for (int j = 0; j < nbcards; ++j) - { - MTGCardInstance * c = z->cards[j]; - if ((c->has(Constants::AFFINITYARTIFACTS) && etype.find("art") != string::npos) - || (c->has(Constants::AFFINITYSWAMP) && etype.find("swa") != string::npos) - || (c->has(Constants::AFFINITYMOUNTAIN) && etype.find("mou") != string::npos) - || (c->has(Constants::AFFINITYPLAINS) && etype.find("pla") != string::npos) - || (c->has(Constants::AFFINITYISLAND) && etype.find("isl") != string::npos) - || (c->has(Constants::AFFINITYFOREST) && etype.find("for") != string::npos) - || (c->has(Constants::AFFINITYGREENCREATURES) && etype.find("cre") != string::npos) - ) - { - if (c->getManaCost()->getConvertedCost() > 0) - { - c->getManaCost()->remove(colored, 1);//one less colorless to cast - } - else - { - c->reduxamount += 1; - } - } - } - } - }//--end of redux bracket ok == 2 - //--------- - ok = 0; - if (e->to == p->game->graveyard - || e->to == p->game->hand - || e->to == p->game->library - || e->to == p->game->exile - || e->to == p->game->stack - || e->to == p->opponent()->game->battlefield - ) - ok = 3;//card leaves play - - if (ok == 3) - {//leave play from your battlefield - if (e->from == p->game->battlefield) - { - int colored = 0; - MTGGameZone * z = card->controller()->game->hand; - int nbcards = z->nb_cards; - string etype = ""; - MTGCardInstance * card = e->card->previous; - if (card && card->hasSubtype("artifact")) - { - etype.append("art"); - } - if (card && card->hasSubtype("swamp")) - { - etype.append("swa"); - } - if (card && card->hasSubtype("mountain")) - { - etype.append("mou"); - } - if (card && card->hasSubtype("plains")) - { - etype.append("pla"); - } - if (card && card->hasSubtype("island")) - { - etype.append("isl"); - } - if (card && card->hasSubtype("forest")) - { - etype.append("for"); - } - if (card && card->hasSubtype("creature") && card->hasColor(1)) - { - etype.append("cre"); - colored = 1; - } - for (int j = 0; j < nbcards; ++j) - { - MTGCardInstance * c = z->cards[j]; - if (c && ((c->has(Constants::AFFINITYARTIFACTS) && etype.find("art") != string::npos) - || (c->has(Constants::AFFINITYSWAMP) && etype.find("swa") != string::npos) - || (c->has(Constants::AFFINITYMOUNTAIN) && etype.find("mou") != string::npos) - || (c->has(Constants::AFFINITYPLAINS) && etype.find("pla") != string::npos) - || (c->has(Constants::AFFINITYISLAND) && etype.find("isl") != string::npos) - || (c->has(Constants::AFFINITYFOREST) && etype.find("for") != string::npos) - || (c->has(Constants::AFFINITYGREENCREATURES) && etype.find("cre") != string::npos)) - ) - { - if (c->reduxamount > 0) - { - c->reduxamount -= 1; - } - else - { - c->getManaCost()->add(colored, 1); - } - } - } - //------------------------------- - } - }//---ok == 3 - //---------------------------------------- - } - } - return 0; - } - return 0; -} - -ostream& MTGAffinityRule::toString(ostream& out) const -{ - out << "MTGAffinityRule ::: ("; - return MTGAbility::toString(out) << ")"; -} - -int MTGAffinityRule::testDestroy() -{ - return 0; -} - -MTGAffinityRule * MTGAffinityRule::clone() const -{ - MTGAffinityRule * a = NEW MTGAffinityRule(*this); - a->isClone = 1; - return a; -} - -//------------------------------------------------------------------- - +//token clean up MTGTokensCleanup::MTGTokensCleanup(int _id) : MTGAbility(_id, NULL) {