From 69db7f73847fe604ccfcd03f39f37aafd0cbde53 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 11 Jul 2016 07:55:12 +0800 Subject: [PATCH] Add support for reducing Hybrid cost it doesn't remove the hybrid icons but it reduces the cost. --- projects/mtg/include/ManaCost.h | 1 + projects/mtg/include/ManaCostHybrid.h | 1 + projects/mtg/src/MTGCardInstance.cpp | 341 ++++++++++++++------------ projects/mtg/src/ManaCost.cpp | 31 +++ projects/mtg/src/ManaCostHybrid.cpp | 18 ++ 5 files changed, 231 insertions(+), 161 deletions(-) diff --git a/projects/mtg/include/ManaCost.h b/projects/mtg/include/ManaCost.h index fc5438d7d..04e7733bb 100644 --- a/projects/mtg/include/ManaCost.h +++ b/projects/mtg/include/ManaCost.h @@ -108,6 +108,7 @@ public: int getManaSymbols(int color); int getManaSymbolsHybridMerged(int color); int countHybridsNoPhyrexian(); + void removeHybrid(ManaCost * _cost); //Returns NULL if i is greater than nbhybrids ManaCostHybrid * getHybridCost(unsigned int i); diff --git a/projects/mtg/include/ManaCostHybrid.h b/projects/mtg/include/ManaCostHybrid.h index 5e799e79c..116e9a15a 100644 --- a/projects/mtg/include/ManaCostHybrid.h +++ b/projects/mtg/include/ManaCostHybrid.h @@ -20,6 +20,7 @@ public: int getConvertedCost(); int getManaSymbols(int color); int getManaSymbolsHybridMerged(int color); + void reduceValue(int color, int value); friend std::ostream& operator<<(std::ostream& out, ManaCostHybrid& m); friend std::ostream& operator<<(std::ostream& out, ManaCostHybrid* m); diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 9fcbee96d..e7fd92ceb 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -966,168 +966,187 @@ JQuadPtr MTGCardInstance::getIcon() ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * Cost, ManaCost * Data, bool noTrinisphere) { - int color = 0; - string type = ""; - ManaCost * original = NEW ManaCost(); - original->copy(Data); - Cost->copy(original); - if (Cost->extraCosts) - { - for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) - { - Cost->extraCosts->costs[i]->setSource(card); - } - } - if (card->getIncreasedManaCost()->getConvertedCost() || card->getReducedManaCost()->getConvertedCost()) - {//start1 - if (card->getIncreasedManaCost()->getConvertedCost()) - original->add(card->getIncreasedManaCost()); - if (card->getReducedManaCost()->getConvertedCost()) - original->remove(card->getReducedManaCost()); - - Cost->copy(original); - if (Cost->extraCosts) - { - for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) - { - Cost->extraCosts->costs[i]->setSource(card); - } - } - }//end1 - int reducem = 0; - bool resetCost = false; - for (unsigned int na = 0; na < card->cardsAbilities.size(); na++) - {//start2 - if (!card->cardsAbilities[na]) - break; - ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); - if (newAff) - { - if (!resetCost) - { - resetCost = true; - Cost->copy(original); - if (Cost->extraCosts) - { - for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) - { - Cost->extraCosts->costs[i]->setSource(card); - } - } - } - TargetChooserFactory tf(getObserver()); - TargetChooser * tcn = tf.createTargetChooser(newAff->tcString, card, NULL); - - for (int w = 0; w < 2; ++w) - { - Player *p = getObserver()->players[w]; - MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; - for (int k = 0; k < 6; k++) - { - MTGGameZone * z = zones[k]; - if (tcn->targetsZone(z)) - { - reducem += z->countByCanTarget(tcn); - } - } - } - SAFE_DELETE(tcn); - ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString); - for (int j = 0; j < reducem; j++) - original->remove(removingCost); - SAFE_DELETE(removingCost); - } - }//end2 - if (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)) - {//start3 - if (card->has(Constants::AFFINITYARTIFACTS)) - { - type = "artifact"; - } - else if (card->has(Constants::AFFINITYSWAMP)) - { - type = "swamp"; - } - else if (card->has(Constants::AFFINITYMOUNTAIN)) - { - type = "mountain"; - } - else if (card->has(Constants::AFFINITYPLAINS)) - { - type = "plains"; - } - else if (card->has(Constants::AFFINITYISLAND)) - { - type = "island"; - } - else if (card->has(Constants::AFFINITYFOREST)) - { - type = "forest"; - } - else if (card->has(Constants::AFFINITYGREENCREATURES)) - { - color = 1; - type = "creature"; - } - - Cost->copy(original); - if (Cost->extraCosts) - { - for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) - { - Cost->extraCosts->costs[i]->setSource(card); - } - } - if (Cost->extraCosts) - { - for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) - { - Cost->extraCosts->costs[i]->setSource(card); - } - } - int reduce = 0; - if (card->has(Constants::AFFINITYGREENCREATURES)) - { - TargetChooserFactory tf(getObserver()); - 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); - } - for (int i = 0; i < reduce; i++) - { - if (Cost->getCost(color) > 0) - Cost->remove(color, 1); - } - }//end3 - //trinisphere... now how to implement kicker recomputation - - if (card->has(Constants::TRINISPHERE)) - { - for (int jj = Cost->getConvertedCost(); jj < 3; jj++) - { - Cost->add(Constants::MTG_COLOR_ARTIFACT, 1); - card->countTrini++; - } - } - else - { - if (card->countTrini) - { - Cost->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini); - card->countTrini = 0; - } - } + int color = 0; + string type = ""; + ManaCost * original = NEW ManaCost(); + ManaCost * excess = NEW ManaCost(); + original->copy(Data); + Cost->copy(original); + if (Cost->extraCosts) + { + for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) + { + Cost->extraCosts->costs[i]->setSource(card); + } + } + if (card->getIncreasedManaCost()->getConvertedCost() || card->getReducedManaCost()->getConvertedCost()) + {//start1 + if (card->getIncreasedManaCost()->getConvertedCost()) + original->add(card->getIncreasedManaCost()); + //before removing get the diff for excess + if(card->getReducedManaCost()->getConvertedCost()) + { + for(int xc = 0; xc < 7;xc++) + {//if the diff is more than 0 + if(card->getReducedManaCost()->getCost(xc) > original->getCost(xc)) + { + int count = card->getReducedManaCost()->getCost(xc) - original->getCost(xc); + excess->add(xc,count); + } + } + } + //apply reduced + if (card->getReducedManaCost()->getConvertedCost()) + original->remove(card->getReducedManaCost()); + //try to reduce hybrid + if (excess->getConvertedCost()) + { + original->removeHybrid(excess); + } + Cost->copy(original); + if (Cost->extraCosts) + { + for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) + { + Cost->extraCosts->costs[i]->setSource(card); + } + } + }//end1 + int reducem = 0; + bool resetCost = false; + for (unsigned int na = 0; na < card->cardsAbilities.size(); na++) + {//start2 + if (!card->cardsAbilities[na]) + break; + ANewAffinity * newAff = dynamic_cast(card->cardsAbilities[na]); + if (newAff) + { + if (!resetCost) + { + resetCost = true; + Cost->copy(original); + if (Cost->extraCosts) + { + for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) + { + Cost->extraCosts->costs[i]->setSource(card); + } + } + } + TargetChooserFactory tf(getObserver()); + TargetChooser * tcn = tf.createTargetChooser(newAff->tcString, card, NULL); + + for (int w = 0; w < 2; ++w) + { + Player *p = getObserver()->players[w]; + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile }; + for (int k = 0; k < 6; k++) + { + MTGGameZone * z = zones[k]; + if (tcn->targetsZone(z)) + { + reducem += z->countByCanTarget(tcn); + } + } + } + SAFE_DELETE(tcn); + ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString); + for (int j = 0; j < reducem; j++) + original->remove(removingCost); + SAFE_DELETE(removingCost); + } + }//end2 + if (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)) + {//start3 + if (card->has(Constants::AFFINITYARTIFACTS)) + { + type = "artifact"; + } + else if (card->has(Constants::AFFINITYSWAMP)) + { + type = "swamp"; + } + else if (card->has(Constants::AFFINITYMOUNTAIN)) + { + type = "mountain"; + } + else if (card->has(Constants::AFFINITYPLAINS)) + { + type = "plains"; + } + else if (card->has(Constants::AFFINITYISLAND)) + { + type = "island"; + } + else if (card->has(Constants::AFFINITYFOREST)) + { + type = "forest"; + } + else if (card->has(Constants::AFFINITYGREENCREATURES)) + { + color = 1; + type = "creature"; + } + + Cost->copy(original); + if (Cost->extraCosts) + { + for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) + { + Cost->extraCosts->costs[i]->setSource(card); + } + } + if (Cost->extraCosts) + { + for (unsigned int i = 0; i < Cost->extraCosts->costs.size(); i++) + { + Cost->extraCosts->costs[i]->setSource(card); + } + } + int reduce = 0; + if (card->has(Constants::AFFINITYGREENCREATURES)) + { + TargetChooserFactory tf(getObserver()); + 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); + } + for (int i = 0; i < reduce; i++) + { + if (Cost->getCost(color) > 0) + Cost->remove(color, 1); + } + }//end3 + //trinisphere... now how to implement kicker recomputation + + if (card->has(Constants::TRINISPHERE)) + { + for (int jj = Cost->getConvertedCost(); jj < 3; jj++) + { + Cost->add(Constants::MTG_COLOR_ARTIFACT, 1); + card->countTrini++; + } + } + else + { + if (card->countTrini) + { + Cost->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini); + card->countTrini = 0; + } + } SAFE_DELETE(original); + SAFE_DELETE(excess); return Cost; } diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index cfb5a4caf..b2c1c3521 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -719,6 +719,37 @@ int ManaCost::countHybridsNoPhyrexian() return result; } +void ManaCost::removeHybrid(ManaCost * _manaCost) +{ + if (!_manaCost) + return; + + vector colors; + int match = 0; + + for(int j = 0; j < 7; j++) + {//populate colors values + colors.push_back(_manaCost->getCost(j)); + } + + for (size_t i = 0; i < hybrids.size(); i++) + { + for(int j = 0; j < 7; j++) + { + if(colors[j]) + { + if(hybrids[i].hasColor(j)) + { + hybrids[i].reduceValue(j, colors[j]); + colors[j] -= 1; + match++; + } + } + } + } + return; +} + int ManaCost::parseManaSymbol(char symbol) { switch (symbol) diff --git a/projects/mtg/src/ManaCostHybrid.cpp b/projects/mtg/src/ManaCostHybrid.cpp index fafddefe0..a2f456479 100644 --- a/projects/mtg/src/ManaCostHybrid.cpp +++ b/projects/mtg/src/ManaCostHybrid.cpp @@ -66,6 +66,24 @@ int ManaCostHybrid::getManaSymbolsHybridMerged(int color) return 0; } +void ManaCostHybrid::reduceValue(int color, int value) +{ + if(((color1 == color) && value1)) + { + if((value1 - value) < 0) + value1 = 0; + else + value1 -= value; + } + else if(((color2 == color) && value2)) + { + if((value2 - value) < 0) + value2 = 0; + else + value2 -= value; + } +} + int ManaCostHybrid::hasColor(int color) { if (((color1 == color) && value1) || ((color2 == color) && value2))