Add support for reducing Hybrid cost

it doesn't remove the hybrid icons but it reduces the cost.
This commit is contained in:
Anthony Calosa
2016-07-11 07:55:12 +08:00
parent a72fb6f01a
commit 69db7f7384
5 changed files with 231 additions and 161 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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<ANewAffinity*>(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<ANewAffinity*>(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;
}

View File

@@ -719,6 +719,37 @@ int ManaCost::countHybridsNoPhyrexian()
return result;
}
void ManaCost::removeHybrid(ManaCost * _manaCost)
{
if (!_manaCost)
return;
vector<int> 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)

View File

@@ -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))