Devotion mechanics (thanks to excessum for patch)

+ some refactoring:
extrManaCost --> ExtraManaCost
unattachCost --> UnattachCost
This commit is contained in:
pankdm
2013-10-18 06:37:09 +00:00
parent d5b089f86b
commit f7eded7417
16 changed files with 203 additions and 66 deletions
+4 -4
View File
@@ -1356,8 +1356,8 @@ int AIPlayerBaka::selectAbility()
{
if(observer->mExtraPayment && observer->mExtraPayment->source->controller() == this)
{
extraManaCost * check = NULL;
check = dynamic_cast<extraManaCost*>(observer->mExtraPayment->costs[0]);
ExtraManaCost * check = NULL;
check = dynamic_cast<ExtraManaCost*>(observer->mExtraPayment->costs[0]);
if(check)
{
vector<MTGAbility*> CostToPay = canPayMana(observer->mExtraPayment->source,check->costToPay);
@@ -2564,8 +2564,8 @@ int AIPlayerBaka::Act(float dt)
{
if(observer->mExtraPayment && observer->mExtraPayment->source->controller() == this)
{
extraManaCost * check = NULL;
check = dynamic_cast<extraManaCost*>(observer->mExtraPayment->costs[0]);
ExtraManaCost * check = NULL;
check = dynamic_cast<ExtraManaCost*>(observer->mExtraPayment->costs[0]);
if(check)
{
vector<MTGAbility*> CostToPay = canPayMana(observer->mExtraPayment->source,check->costToPay);
+1 -1
View File
@@ -3516,7 +3516,7 @@ int MenuAbility::reactToChoiceClick(Targetable * object,int choice,int control)
toPay = NEW ManaCost();
if(optionalCosts[i]->extraCosts)
toPay->extraCosts = optionalCosts[i]->extraCosts->clone();
toPay->addExtraCost(NEW extraManaCost(NEW ManaCost(optionalCosts[i])));
toPay->addExtraCost(NEW ExtraManaCost(NEW ManaCost(optionalCosts[i])));
toPay->setExtraCostsAction(this,source);
game->mExtraPayment = toPay->extraCosts;
return 0;
+30 -28
View File
@@ -7,6 +7,7 @@
#include "Player.h"
#include "Counters.h"
#include "AllAbilities.h"
#include <boost/scoped_ptr.hpp>
SUPPORT_OBJECT_ANALYTICS(ExtraCost)
@@ -69,23 +70,23 @@ int ExtraCost::setPayment(MTGCardInstance * card)
return result;
}
//extra added manacost, or add a manacost as the cost of extra
extraManaCost * extraManaCost::clone() const
ExtraManaCost * ExtraManaCost::clone() const
{
extraManaCost * ec = NEW extraManaCost(*this);
ExtraManaCost * ec = NEW ExtraManaCost(*this);
return ec;
}
extraManaCost::extraManaCost(ManaCost * costToPay)
ExtraManaCost::ExtraManaCost(ManaCost * costToPay)
: ExtraCost("Pay The Cost",NULL, costToPay)
{
}
int extraManaCost::tryToSetPayment(MTGCardInstance * card)
int ExtraManaCost::tryToSetPayment(MTGCardInstance * card)
{
return 1;
}
int extraManaCost::isPaymentSet()
int ExtraManaCost::isPaymentSet()
{
if (!source->controller()->getManaPool()->canAfford(costToPay))
{
@@ -94,7 +95,7 @@ int extraManaCost::isPaymentSet()
return 1;
}
int extraManaCost::canPay()
int ExtraManaCost::canPay()
{
if(!source->controller()->getManaPool()->canAfford(costToPay))
{
@@ -103,7 +104,7 @@ int extraManaCost::canPay()
return 1;
}
int extraManaCost::doPay()
int ExtraManaCost::doPay()
{
if (!source->controller()->getManaPool()->canAfford(costToPay))
return 0;
@@ -159,7 +160,15 @@ LifeorManaCost * LifeorManaCost::clone() const
return ec;
}
LifeorManaCost::LifeorManaCost(TargetChooser *_tc,string manaType)
ManaCost * LifeorManaCost::getManaCost()
{
string buildType ="{";
buildType.append(manaType);
buildType.append("}");
return ManaCost::parseManaCost(buildType);
}
LifeorManaCost::LifeorManaCost(TargetChooser *_tc, string manaType)
: ExtraCost("Phyrexian Mana", _tc), manaType(manaType)
{
}
@@ -167,16 +176,11 @@ LifeorManaCost::LifeorManaCost(TargetChooser *_tc,string manaType)
int LifeorManaCost::canPay()
{
MTGCardInstance * _target = (MTGCardInstance *) target;
string buildType ="{";
buildType.append(manaType);
buildType.append("}");
ManaCost * newCost = ManaCost::parseManaCost(buildType);
if(_target->controller()->getManaPool()->canAfford(newCost) || _target->controller()->life > 1)
boost::scoped_ptr<ManaCost> manaCost(getManaCost());
if (_target->controller()->getManaPool()->canAfford(manaCost.get()) || _target->controller()->life > 1)
{
SAFE_DELETE(newCost);
return 1;
}
SAFE_DELETE(newCost);
return 0;
}
@@ -186,24 +190,22 @@ int LifeorManaCost::doPay()
return 0;
MTGCardInstance * _target = (MTGCardInstance *) target;
string buildType ="{";
buildType.append(manaType);
buildType.append("}");
ManaCost * newCost = ManaCost::parseManaCost(buildType);
if(_target->controller()->getManaPool()->canAfford(newCost))
ManaCost * manaCost = getManaCost();
if (_target->controller()->getManaPool()->canAfford(manaCost))
{
_target->controller()->getManaPool()->pay(newCost);
_target->controller()->getManaPool()->pay(manaCost);
}
else
{
_target->controller()->loseLife(2);
}
SAFE_DELETE(newCost);
SAFE_DELETE(manaCost);
target = NULL;
if (tc)
tc->initTargets();
return 1;
}
//discard a card at random as a cost
//DiscardRandom cost
DiscardRandomCost * DiscardRandomCost::clone() const
@@ -404,18 +406,18 @@ int MillExileCost::doPay()
}
//unattach cost
unattachCost * unattachCost::clone() const
UnattachCost * UnattachCost::clone() const
{
unattachCost * ec = NEW unattachCost(*this);
UnattachCost * ec = NEW UnattachCost(*this);
return ec;
}
unattachCost::unattachCost(MTGCardInstance * realSource)
UnattachCost::UnattachCost(MTGCardInstance * realSource)
: ExtraCost("Unattach"),rSource(realSource)
{
}
int unattachCost::isPaymentSet()
int UnattachCost::isPaymentSet()
{
if (rSource && !rSource->target)
{
@@ -424,12 +426,12 @@ int unattachCost::isPaymentSet()
return 1;
}
int unattachCost::canPay()
int UnattachCost::canPay()
{
return isPaymentSet();
}
int unattachCost::doPay()
int UnattachCost::doPay()
{
MTGCardInstance * _source = (MTGCardInstance *) source;
if(_source != rSource)
+2 -2
View File
@@ -1275,9 +1275,9 @@ int GameObserver::cardClick(MTGCardInstance * card, Targetable * object, bool lo
break;
}
}
extraManaCost * costType = NULL;
ExtraManaCost * costType = NULL;
if( mExtraPayment && mExtraPayment->costs.size())
costType = dynamic_cast<extraManaCost*>(mExtraPayment->costs[0]);
costType = dynamic_cast<ExtraManaCost*>(mExtraPayment->costs[0]);
if (WaitForExtraPayment(card) && !costType)
{
+22 -2
View File
@@ -549,17 +549,37 @@ unsigned int MTGGameZone::countByCanTarget(TargetChooser * tc)
{
if(!tc)
return 0;
tc->targetter = NULL;//becuase we are counting what can be targeted by this TC, we don't care if cards have protection.
// we don't care if cards have protection.
bool withoutProtections = true;
int result = 0;
for (int i = 0; i < (nb_cards); i++)
{
if (tc->canTarget(cards[i]))
if (tc->canTarget(cards[i]), withoutProtections)
{
result++;
}
}
return result;
}
unsigned int MTGGameZone::countTotalManaSymbols(TargetChooser * tc, int color)
{
if (!tc) {
return 0;
}
// we don't care if cards have protection.
bool withoutProtections = true;
int result = 0;
for (int i = 0; i < nb_cards; i++)
{
if (tc->canTarget(cards[i]), withoutProtections)
{
result += cards[i]->getManaCost()->getManaSymbols(color);
}
}
return result;
}
MTGCardInstance * MTGGameZone::findByName(string name)
{
for (int i = 0; i < (nb_cards); i++)
+56 -13
View File
@@ -8,6 +8,7 @@
#include "WEvent.h"
#include "MTGAbility.h"
#include "iterator"
#include <boost/scoped_ptr.hpp>
SUPPORT_OBJECT_ANALYTICS(ManaCost)
@@ -238,7 +239,7 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
{
if(value == "unattach")
{
manaCost->addExtraCost(NEW unattachCost(c));
manaCost->addExtraCost(NEW UnattachCost(c));
break;
}
int intvalue = atoi(value.c_str());
@@ -431,6 +432,7 @@ void ManaCost::specificX(int color)
xColor = color;
cost[Constants::NB_Colors] = 1;
}
int ManaCost::hasSpecificX()
{
if (cost.size() <= (size_t)Constants::NB_Colors)
@@ -578,6 +580,47 @@ int ManaCost::getCost(int color)
return cost[color];
}
int ManaCost::getManaSymbols(int color)
{
int result = cost[color];
for (size_t i = 0; i < hybrids.size(); ++i)
{
result += hybrids[i].getManaSymbols(color);
}
if (extraCosts && extraCosts->costs.size())
{
for (size_t i = 0; i < extraCosts->costs.size(); ++i)
{
LifeorManaCost * phyrexianMana = dynamic_cast<LifeorManaCost*>(extraCosts->costs[i]);
if (phyrexianMana)
{
boost::scoped_ptr<ManaCost> manaCost(phyrexianMana->getManaCost());
result += manaCost->getManaSymbols(color);
}
}
}
return result;
}
int ManaCost::parseManaSymbol(char symbol)
{
switch (symbol)
{
case 'g':
return Constants::MTG_COLOR_GREEN;
case 'u':
return Constants::MTG_COLOR_BLUE;
case 'r':
return Constants::MTG_COLOR_RED;
case 'b':
return Constants::MTG_COLOR_BLACK;
case 'w':
return Constants::MTG_COLOR_WHITE;
}
DebugTrace( "Failed to parse mana symbol" );
return -1;
}
ManaCostHybrid * ManaCost::getHybridCost(unsigned int i)
{
if (hybrids.size() <= i)
@@ -620,7 +663,7 @@ int ManaCost::isNull()
int ManaCost::getConvertedCost()
{
int result = 0;
for ( int i = 0; i < Constants::NB_Colors; i++)
for (int i = 0; i < Constants::NB_Colors; i++)
{
result += cost[i];
}
@@ -628,15 +671,15 @@ int ManaCost::getConvertedCost()
{
result += hybrids[i].getConvertedCost();
}
if(extraCosts && extraCosts->costs.size())
{
for(unsigned int i = 0; i < extraCosts->costs.size();i++)
{
ExtraCost * pMana = dynamic_cast<LifeorManaCost*>(extraCosts->costs[i]);
if(pMana)
result++;
}
}
if (extraCosts && extraCosts->costs.size())
{
for (unsigned int i = 0; i < extraCosts->costs.size(); i++)
{
ExtraCost * pMana = dynamic_cast<LifeorManaCost*>(extraCosts->costs[i]);
if (pMana)
result++;
}
}
return result;
}
@@ -801,12 +844,12 @@ void ManaCost::randomDiffHybrids(ManaCost * _cost, std::vector<int16_t>& diff)
/**
starting from the end of the array (diff)
*/
int ManaCost::tryToPayHybrids(std::vector<ManaCostHybrid>& _hybrids, int _nbhybrids, std::vector<int16_t>& diff)
int ManaCost::tryToPayHybrids(const std::vector<ManaCostHybrid>& _hybrids, int _nbhybrids, std::vector<int16_t>& diff)
{
if (!_nbhybrids)
return 1;
int result = 0;
ManaCostHybrid& h = _hybrids[_nbhybrids - 1];
const ManaCostHybrid& h = _hybrids[_nbhybrids - 1];
if (diff[h.color1 * 2 + 1] >= h.value1)
{
diff[h.color1 * 2 + 1] -= h.value1;
+8
View File
@@ -50,6 +50,14 @@ int ManaCostHybrid::getConvertedCost()
return value1;
}
int ManaCostHybrid::getManaSymbols(int color)
{
// we assume that color1 and color2 are different
if (color1 == color) return value1;
if (color2 == color) return value2;
return 0;
}
int ManaCostHybrid::hasColor(int color)
{
if (((color1 == color) && value1) || ((color2 == color) && value2))
+1 -1
View File
@@ -813,7 +813,7 @@ TargetChooser::TargetChooser(GameObserver *observer, MTGCardInstance * card, int
//Default targetter : every card can be targetted, unless it is protected from the targetter card
// For spells that do not "target" a specific card, set targetter to NULL
bool TargetChooser::canTarget(Targetable * target,bool withoutProtections)
bool TargetChooser::canTarget(Targetable * target, bool withoutProtections)
{
if (!target) return false;
if (MTGCardInstance * card = dynamic_cast<MTGCardInstance *>(target))