corrected my logic for emerge, originally I thought the cost was the same as the original cost, while coding i noticed it can have a completely different cost than the real manacost.

moved the extra cost check for "offerings" to a location before canafford in alternative reacttoclick, the reason for this is that the 2 offering cost we have handle the can afford calls, and even cast the card in the dopay. not placing this before it causes the card to not react to click if there is a different manacost attached to the emerge/kill 
test codes below.
mana={g}{g}{g}
other={emerge}(r}{4} name(emerge)

mana={6}
other={k(giant|mybattlefield)}

fixed memleaks in killoffering code.

note to devs, remember to make diff costs a variable that you can safe_delete, it creates a manacost object that will become a leak otherwise.
do not use it directly as a function.
source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))
this will leave a memleak every single time ai checks this cost, or a player accesses the cost even if you cant pay it.
This commit is contained in:
zethfoxster
2016-07-22 19:10:06 -04:00
parent 2d76c8ff0d
commit bc2d8dab31
2 changed files with 63 additions and 16 deletions

View File

@@ -1141,7 +1141,8 @@ int Offering::canPay()
{
if (target)
{
ManaCost * reduced = NEW ManaCost(source->getManaCost());
ManaCost * reduced = NEW ManaCost(source->getManaCost()->getAlternative());
reduced->extraCosts = NULL;
reduced->remove(Constants::MTG_COLOR_ARTIFACT, target->getManaCost()->getConvertedCost());
if (target && (!source->controller()->getManaPool()->canAfford(reduced)))
@@ -1161,14 +1162,22 @@ int Offering::canPay()
}
else
{
if (target && (!source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
if (target)
{
tc->removeTarget(target);
target = NULL;
return 0;
ManaCost * diff = source->getManaCost()->Diff(target->getManaCost());
if (target && (!source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
{
SAFE_DELETE(diff);
tc->removeTarget(target);
target = NULL;
return 0;
}
if (target && (source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
{
SAFE_DELETE(diff);
return 1;
}
}
if (target && (source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
return 1;
}
return 0;
}
@@ -1179,7 +1188,8 @@ int Offering::isPaymentSet()
{
if (target)
{
ManaCost * reduced = NEW ManaCost(source->getManaCost());
ManaCost * reduced = NEW ManaCost(source->getManaCost()->getAlternative());
reduced->extraCosts = NULL;
reduced->remove(Constants::MTG_COLOR_ARTIFACT, target->getManaCost()->getConvertedCost());
if (target && (!source->controller()->getManaPool()->canAfford(reduced)))
@@ -1199,14 +1209,22 @@ int Offering::isPaymentSet()
}
else
{
if (target && (!source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
if (target)
{
tc->removeTarget(target);
target = NULL;
return 0;
ManaCost * diff = source->getManaCost()->Diff(target->getManaCost());
if (target && (!source->controller()->getManaPool()->canAfford(diff)))
{
SAFE_DELETE(diff);
tc->removeTarget(target);
target = NULL;
return 0;
}
if (target && (source->controller()->getManaPool()->canAfford(diff)))
{
SAFE_DELETE(diff);
return 1;
}
}
if (target && (source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
return 1;
}
return 0;
}
@@ -1217,13 +1235,18 @@ int Offering::doPay()
{
if (emerge)
{
ManaCost * reduced = NEW ManaCost(source->getManaCost());
ManaCost * reduced = NEW ManaCost(source->getManaCost()->getAlternative());
reduced->extraCosts = NULL;
reduced->remove(Constants::MTG_COLOR_ARTIFACT, target->getManaCost()->getConvertedCost());
target->controller()->getManaPool()->pay(reduced);
SAFE_DELETE(reduced);
}
else
target->controller()->getManaPool()->pay(source->getManaCost()->Diff(target->getManaCost()));
{
ManaCost * diff = source->getManaCost()->Diff(target->getManaCost());
target->controller()->getManaPool()->pay(diff);
SAFE_DELETE(diff);
}
MTGCardInstance * beforeCard = target;
source->storedCard = target->createSnapShot();
target->controller()->game->putInGraveyard(target);

View File

@@ -760,6 +760,30 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
ManaCost * cost = card->getManaCost();
cost->Dump();
#endif
if (alternateManaCost->extraCosts)
{
//offerings handle thier own casting and cost payments.
//we add this condiational here because offering can also have a completely different
//manacost from orginal cost, this allows us to simulate reacting to click for cards that
//would be able to afford the cost AFTER the sacrifice is made, we use isPaymentSet to determine
//legality of casting.
if (alternateManaCost->getExtraCost(0) == dynamic_cast<Offering*>(alternateManaCost->getExtraCost(0)))
{
if (alternateManaCost->isExtraPaymentSet())//cant get past this section without doing it. you either pay the cost or dont
{
if (!game->targetListIsSet(card))
return 0;
}
else
{
alternateManaCost->setExtraCostsAction(this, card);
game->mExtraPayment = alternateManaCost->extraCosts;
return 0;
}
return 1;
}
}
if (playerMana->canAfford(alternateManaCost))
{
return 1;