Fixed the memleaks caused by computeNewCost, moved them to gameobserver where affinity takes place, removed repeative code that was in game observer, moved the game observer components into computenewcost, removed the calls for "new mana" in all alternative play type that were added with this function.

This commit is contained in:
zethfoxster
2016-07-06 00:02:15 -04:00
parent 4e048f775d
commit 861366dd71
4 changed files with 266 additions and 325 deletions
+44 -137
View File
@@ -1111,154 +1111,61 @@ void GameObserver::Affinity()
//memory snapshot shots pointed to this as such a heavy load that games with many cards inplay
//would slow to a crawl.
//only do any of the following if a card with the stated ability is in your hand.
int color = 0;
string type = "";
ManaCost * original = NEW ManaCost();
original->copy(card->model->data->getManaCost());
if(card->getIncreasedManaCost()->getConvertedCost()||card->getReducedManaCost()->getConvertedCost())
{//start1
if(card->getIncreasedManaCost()->getConvertedCost())
original->add(card->getIncreasedManaCost());
if(card->getReducedManaCost()->getConvertedCost())
original->remove(card->getReducedManaCost());
if(card->getManaCost())
card->getManaCost()->copy(original);
if(card->getManaCost()->extraCosts)
//kicker is an addon to normal cost, suspend is not casting. add cost as needed EXACTLY as seen below.
card->getManaCost()->resetCosts();
ManaCost * newCost = NEW ManaCost();
newCost->copy(card->computeNewCost(card, card->getManaCost(), card->model->data->getManaCost()));
card->getManaCost()->copy(newCost);
SAFE_DELETE(newCost);
if (card->getManaCost()->getAlternative())
{
for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++)
{
card->getManaCost()->extraCosts->costs[i]->setSource(card);
card->getManaCost()->getAlternative()->resetCosts();
ManaCost * newCost = NEW ManaCost();
newCost->copy(card->computeNewCost(card, card->getManaCost()->getAlternative(), card->model->data->getManaCost()->getAlternative()));
card->getManaCost()->getAlternative()->copy(newCost);
SAFE_DELETE(newCost);
}
}
}//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 (card->getManaCost()->getBestow())
{
if(!resetCost)
{
resetCost = true;
card->getManaCost()->copy(original);
if(card->getManaCost()->extraCosts)
{
for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++)
{
card->getManaCost()->extraCosts->costs[i]->setSource(card);
card->getManaCost()->getBestow()->resetCosts();
ManaCost * newCost = NEW ManaCost();
newCost->copy(card->computeNewCost(card, card->getManaCost()->getBestow(), card->model->data->getManaCost()->getBestow()));
card->getManaCost()->getBestow()->copy(newCost);
SAFE_DELETE(newCost);
}
}
}
TargetChooserFactory tf(this);
TargetChooser * tcn = tf.createTargetChooser(newAff->tcString,card,NULL);
for (int w = 0; w < 2; ++w)
if (card->getManaCost()->getRetrace())
{
Player *p = this->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++)
card->getManaCost()->getRetrace()->resetCosts();
ManaCost * newCost = NEW ManaCost();
newCost->copy(card->computeNewCost(card, card->getManaCost()->getRetrace(), card->model->data->getManaCost()->getRetrace()));
card->getManaCost()->getRetrace()->copy(newCost);
SAFE_DELETE(newCost);
}
if (card->getManaCost()->getBuyback())
{
MTGGameZone * z = zones[k];
if (tcn->targetsZone(z))
card->getManaCost()->getBuyback()->resetCosts();
ManaCost * newCost = NEW ManaCost();
newCost->copy(card->computeNewCost(card, card->getManaCost()->getBuyback(), card->model->data->getManaCost()->getBuyback()));
card->getManaCost()->getBuyback()->copy(newCost);
SAFE_DELETE(newCost);
}
if (card->getManaCost()->getFlashback())
{
reducem += z->countByCanTarget(tcn);
card->getManaCost()->getFlashback()->resetCosts();
ManaCost * newCost = NEW ManaCost();
newCost->copy(card->computeNewCost(card, card->getManaCost()->getFlashback(), card->model->data->getManaCost()->getFlashback()));
card->getManaCost()->getFlashback()->copy(newCost);
SAFE_DELETE(newCost);
}
}
}
SAFE_DELETE(tcn);
ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString);
for(int j = 0; j < reducem; j++)
card->getManaCost()->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))
if (card->getManaCost()->getMorph())
{
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";
}
card->getManaCost()->copy(original);
if(card->getManaCost()->extraCosts)
{
for(unsigned int i = 0; i < card->getManaCost()->extraCosts->costs.size();i++)
{
card->getManaCost()->extraCosts->costs[i]->setSource(card);
}
}
int reduce = 0;
if(card->has(Constants::AFFINITYGREENCREATURES))
{
TargetChooserFactory tf(this);
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(card->getManaCost()->getCost(color) > 0)
card->getManaCost()->remove(color,1);
}
}//end3
//trinisphere... now how to implement kicker recomputation
if(card->has(Constants::TRINISPHERE))
{
for(int jj = card->getManaCost()->getConvertedCost(); jj < 3; jj++)
{
card->getManaCost()->add(Constants::MTG_COLOR_ARTIFACT, 1);
card->countTrini++;
}
}
else
{
if(card->countTrini)
{
card->getManaCost()->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini);
card->countTrini=0;
}
card->getManaCost()->getMorph()->resetCosts();
ManaCost * newCost = NEW ManaCost();
newCost->copy(card->computeNewCost(card, card->getManaCost()->getMorph(), card->model->data->getManaCost()->getMorph()));
card->getManaCost()->getMorph()->copy(newCost);
SAFE_DELETE(newCost);
}
SAFE_DELETE(original);
}//end
}
}
+67 -34
View File
@@ -960,55 +960,69 @@ JQuadPtr MTGCardInstance::getIcon()
return WResourceManager::Instance()->RetrieveCard(this, CACHE_THUMB);
}
ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * newCost, ManaCost * refCost, bool noTrinisphere)
ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * Cost, ManaCost * Data, bool noTrinisphere)
{
//this function introduces a nasty memleak, it also cant be safe_deleted at the locations if its not used as it leads to a wild nullpointer crash.
if(!card)
return NULL;
ManaCost * cardUnchangedCost = NEW ManaCost();
cardUnchangedCost->copy(newCost);
if(card->getIncreasedManaCost()->getConvertedCost())
cardUnchangedCost->add(card->getIncreasedManaCost());
if(card->getReducedManaCost()->getConvertedCost())
cardUnchangedCost->remove(card->getReducedManaCost());
if(refCost->extraCosts)
cardUnchangedCost->extraCosts = refCost->extraCosts;
//affinity
int color = 0;
string type = "";
ManaCost * original = NEW ManaCost();
original->copy(cardUnchangedCost);
original->copy(Data);
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;
cardUnchangedCost->copy(original);
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(observer);
}
}
TargetChooserFactory tf(getObserver());
TargetChooser * tcn = tf.createTargetChooser(newAff->tcString, card, NULL);
for (int w = 0; w < 2; ++w)
{
Player *p = observer->players[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++)
cardUnchangedCost->remove(removingCost);
original->remove(removingCost);
SAFE_DELETE(removingCost);
}
}//end2
@@ -1021,46 +1035,68 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * new
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";
}
cardUnchangedCost->copy(original);
Cost->copy(original);
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(observer);
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(cardUnchangedCost->getCost(color) > 0)
cardUnchangedCost->remove(color,1);
}//end3
if(!noTrinisphere)
{
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 = cardUnchangedCost->getConvertedCost(); jj < 3; jj++)
for (int jj = Cost->getConvertedCost(); jj < 3; jj++)
{
cardUnchangedCost->add(Constants::MTG_COLOR_ARTIFACT, 1);
Cost->add(Constants::MTG_COLOR_ARTIFACT, 1);
card->countTrini++;
}
}
@@ -1068,15 +1104,12 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * new
{
if (card->countTrini)
{
cardUnchangedCost->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini);
Cost->remove(Constants::MTG_COLOR_ARTIFACT, card->countTrini);
card->countTrini = 0;
}
}
}
SAFE_DELETE(original);
return cardUnchangedCost;
return Cost;
}
MTGCardInstance * MTGCardInstance::getNextPartner()
+14 -14
View File
@@ -709,7 +709,7 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
return 0;//overload has its own rule
if(!card->getManaCost()->getAlternative())
return 0;
ManaCost * alternateCost = card->computeNewCost(card,card->model->data->getManaCost()->getAlternative(),card->getManaCost()->getAlternative());
ManaCost * alternateCost = card->getManaCost()->getAlternative();
if(alternateCost->extraCosts)
for(unsigned int i = 0; i < alternateCost->extraCosts->costs.size();i++)
{
@@ -773,7 +773,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card)
if ( !isReactingToClick(card))
return 0;
ManaCost * alternateCost = card->computeNewCost(card,card->model->data->getManaCost()->getAlternative(),card->getManaCost()->getAlternative());
ManaCost * alternateCost = card->getManaCost()->getAlternative();
card->paymenttype = MTGAbility::ALTERNATIVE_COST;
if(alternateCost->extraCosts)
for(unsigned int i = 0; i < alternateCost->extraCosts->costs.size();i++)
@@ -942,7 +942,7 @@ int MTGBuyBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
return 0;
if(!card->getManaCost()->getBuyback())
return 0;
ManaCost * buybackCost = card->computeNewCost(card,card->model->data->getManaCost()->getBuyback(),card->getManaCost()->getBuyback());
ManaCost * buybackCost = card->getManaCost()->getBuyback();
if(buybackCost->extraCosts)
for(unsigned int i = 0; i < buybackCost->extraCosts->costs.size();i++)
{
@@ -956,7 +956,7 @@ int MTGBuyBackRule::reactToClick(MTGCardInstance * card)
if (!isReactingToClick(card))
return 0;
ManaCost * buybackCost = card->computeNewCost(card,card->model->data->getManaCost()->getBuyback(),card->getManaCost()->getBuyback());
ManaCost * buybackCost = card->getManaCost()->getBuyback();
if(buybackCost->extraCosts)
for(unsigned int i = 0; i < buybackCost->extraCosts->costs.size();i++)
{
@@ -996,7 +996,7 @@ int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
return 0;
if(!card->getManaCost()->getFlashback())
return 0;
ManaCost * flashbackCost = card->computeNewCost(card,card->model->data->getManaCost()->getFlashback(),card->getManaCost()->getFlashback());
ManaCost * flashbackCost = card->getManaCost()->getFlashback();
if(flashbackCost->extraCosts)
for(unsigned int i = 0; i < flashbackCost->extraCosts->costs.size();i++)
{
@@ -1007,7 +1007,7 @@ int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
int MTGFlashBackRule::reactToClick(MTGCardInstance * card)
{
ManaCost * flashbackCost = card->computeNewCost(card,card->model->data->getManaCost()->getFlashback(),card->getManaCost()->getFlashback());
ManaCost * flashbackCost = card->getManaCost()->getFlashback();
if(flashbackCost->extraCosts)
for(unsigned int i = 0; i < flashbackCost->extraCosts->costs.size();i++)
{
@@ -1053,7 +1053,7 @@ int MTGRetraceRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
{
return 0;
}
auto retraceCost = card->computeNewCost(card, card->model->data->getManaCost()->getRetrace(), card->getManaCost()->getRetrace());
auto retraceCost = card->getManaCost()->getRetrace();
if(retraceCost->extraCosts)
for(unsigned int i = 0; i < retraceCost->extraCosts->costs.size();i++)
{
@@ -1068,7 +1068,7 @@ int MTGRetraceRule::reactToClick(MTGCardInstance * card)
if (!isReactingToClick(card))
return 0;
ManaCost * retraceCost = card->computeNewCost(card,card->model->data->getManaCost()->getRetrace(),card->getManaCost()->getRetrace());
ManaCost * retraceCost = card->getManaCost()->getRetrace();
if(retraceCost->extraCosts)
for(unsigned int i = 0; i < retraceCost->extraCosts->costs.size();i++)
{
@@ -1245,7 +1245,7 @@ int MTGMorphCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
if (card->controller()->game->playRestrictions->canPutIntoZone(card, card->controller()->game->stack) == PlayRestriction::CANT_PLAY)
return 0;
ManaCost * playerMana = player->getManaPool();
ManaCost * morph = card->computeNewCost(card,card->model->data->getManaCost()->getMorph(),card->getManaCost()->getMorph());
ManaCost * morph = card->getManaCost()->getMorph();
if(morph->extraCosts)
for(unsigned int i = 0; i < morph->extraCosts->costs.size();i++)
{
@@ -1274,7 +1274,7 @@ int MTGMorphCostRule::reactToClick(MTGCardInstance * card)
Player * player = game->currentlyActing();
ManaCost * cost = card->getManaCost();
ManaCost * playerMana = player->getManaPool();
ManaCost * morph = card->computeNewCost(card,card->model->data->getManaCost()->getMorph(),card->getManaCost()->getMorph());
ManaCost * morph = card->getManaCost()->getMorph();
if(morph->extraCosts)
for(unsigned int i = 0; i < morph->extraCosts->costs.size();i++)
{
@@ -1446,7 +1446,7 @@ int MTGOverloadRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
{
return 0;
}
ManaCost * newCost = card->computeNewCost(card, card->model->data->getManaCost()->getAlternative(), card->getManaCost()->getAlternative());
ManaCost * newCost = card->getManaCost()->getAlternative();
if(newCost->extraCosts)
for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++)
{
@@ -1462,7 +1462,7 @@ int MTGOverloadRule::reactToClick(MTGCardInstance * card)
return 0;
ManaCost * cost = NEW ManaCost(card->model->data->getManaCost()->getAlternative());
ManaCost * newCost = card->computeNewCost(card, card->model->data->getManaCost()->getAlternative(), card->getManaCost()->getAlternative());
ManaCost * newCost = card->getManaCost()->getAlternative();
if(newCost->extraCosts)
for(unsigned int i = 0; i < newCost->extraCosts->costs.size();i++)
{
@@ -1508,7 +1508,7 @@ int MTGBestowRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
{
return 0;
}
ManaCost * newCost = card->computeNewCost(card, card->model->data->getManaCost()->getBestow(), card->getManaCost()->getBestow());
ManaCost * newCost = card->getManaCost()->getBestow();
if (newCost->extraCosts)
for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++)
{
@@ -1523,7 +1523,7 @@ int MTGBestowRule::reactToClick(MTGCardInstance * card)
return 0;
//this new method below in all alternative cost type causes a memleak, however, you cant safedelete the cost here as it cause a crash
//TODO::::we need to get to the source of this leak and fix it.
ManaCost * newCost = card->computeNewCost(card, card->model->data->getManaCost()->getBestow(), card->getManaCost()->getBestow());
ManaCost * newCost = card->getManaCost()->getBestow();
if (newCost->extraCosts)
for (unsigned int i = 0; i < newCost->extraCosts->costs.size(); i++)
+1
View File
@@ -601,6 +601,7 @@ void ManaCost::copy(ManaCost * _manaCost)
hybrids = _manaCost->hybrids;
SAFE_DELETE(extraCosts);
if (_manaCost->extraCosts)
{
extraCosts = _manaCost->extraCosts->clone();