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

View File

@@ -37348,6 +37348,16 @@ mana={1}{G}{G}
type=Enchantment type=Enchantment
[/card] [/card]
[card] [card]
name=Gray Merchant of Asphodel
auto=life:-type:manab:mybattlefield opponent && life:type:manab controller
text=When Gray Merchant of Asphodel enters the battlefield, each opponent loses X life, where X is your devotion to black. You gain life equal to the life lost this way. (Each {B} in the mana costs of permanents you control counts toward your devotion to black.)
mana={3}{B}{B}
type=Creature
subtype=Zombie
power=2
toughness=4
[/card]
[card]
name=Gray Ogre name=Gray Ogre
mana={2}{R} mana={2}{R}
type=Creature type=Creature

View File

@@ -14,6 +14,7 @@ generic/changeling_i501.txt
generic/cycling.txt generic/cycling.txt
generic/cycling2.txt generic/cycling2.txt
generic/deathtouch.txt generic/deathtouch.txt
generic/devotion.txt
generic/doesnotuntap.txt generic/doesnotuntap.txt
generic/doesnotuntap2.txt generic/doesnotuntap2.txt
generic/double_strike.txt generic/double_strike.txt

View File

@@ -0,0 +1,30 @@
# Testing Devotion mechanic
# also checking that hybrid cost and phyrexian cost are handled correctly
# total devotion should be 2 + 1 + 1 = 4
# Gray Merchant of Asphodel
# When Gray Merchant of Asphodel enters the battlefield, each opponent loses X life, where X is your devotion to black. You gain life equal to the life lost this way. (Each {B} in the mana costs of permanents you control counts toward your devotion to black.)
# Reaper King
# mana={2W}{2U}{2B}{2R}{2G}
# Vault Skirge
# mana={1}{p(B)}
[INIT]
firstmain
[PLAYER1]
hand:gray merchant of asphodel
inplay:Reaper King,Vault Skirge
manapool:{3}{B}{B}
[PLAYER2]
[DO]
gray merchant of asphodel
[ASSERT]
firstmain
[PLAYER1]
life:24
inplay:gray merchant of asphodel,Reaper King,Vault Skirge
[PLAYER2]
life:16
[END]

View File

@@ -183,7 +183,12 @@ private:
} }
else else
{ {
replace(theType.begin(), theType.end(), ':', '|'); replace(theType.begin(), theType.end(), ':', '|');
}
int color = 0;
if (theType.find("mana") != string::npos) {
color = ManaCost::parseManaSymbol(theType[4]);
theType.replace(0, 5, "*");
} }
TargetChooserFactory tf(card->getObserver()); TargetChooserFactory tf(card->getObserver());
TargetChooser * tc = tf.createTargetChooser(theType.c_str(),NULL); TargetChooser * tc = tf.createTargetChooser(theType.c_str(),NULL);
@@ -194,8 +199,17 @@ private:
for (int k = 0; k < 4; k++) for (int k = 0; k < 4; k++)
{ {
MTGGameZone * zone = zones[k]; MTGGameZone * zone = zones[k];
if(tc->targetsZone(zone,target)) if (tc->targetsZone(zone, target))
intValue += zone->countByCanTarget(tc); {
if (color)
{
intValue += zone->countTotalManaSymbols(tc, color);
}
else
{
intValue += zone->countByCanTarget(tc);
}
}
} }
} }
SAFE_DELETE(tc); SAFE_DELETE(tc);

View File

@@ -61,15 +61,15 @@ public:
}; };
//extraextra //extraextra
class extraManaCost : public ExtraCost class ExtraManaCost : public ExtraCost
{ {
public: public:
extraManaCost(ManaCost * cost = NULL); ExtraManaCost(ManaCost * cost = NULL);
virtual int tryToSetPayment(MTGCardInstance * card); virtual int tryToSetPayment(MTGCardInstance * card);
virtual int isPaymentSet(); virtual int isPaymentSet();
virtual int canPay(); virtual int canPay();
virtual int doPay(); virtual int doPay();
virtual extraManaCost * clone() const; virtual ExtraManaCost * clone() const;
}; };
class SacrificeCost : public ExtraCost class SacrificeCost : public ExtraCost
@@ -90,15 +90,18 @@ public:
virtual LifeCost * clone() const; virtual LifeCost * clone() const;
}; };
//pyrhaixa mana //phyrexian mana
class LifeorManaCost : public ExtraCost class LifeorManaCost : public ExtraCost
{ {
public: private:
LifeorManaCost(TargetChooser *_tc = NULL,string manaType = "");
string manaType; string manaType;
public:
LifeorManaCost(TargetChooser *_tc = NULL, string manaType = "");
virtual int canPay(); virtual int canPay();
virtual int doPay(); virtual int doPay();
virtual LifeorManaCost * clone() const; virtual LifeorManaCost * clone() const;
ManaCost * getManaCost();
}; };
//Discard a random card cost //Discard a random card cost
@@ -157,15 +160,15 @@ public:
}; };
//unattach cost //unattach cost
class unattachCost : public ExtraCost class UnattachCost : public ExtraCost
{ {
public: public:
unattachCost(MTGCardInstance * realSource = NULL); UnattachCost(MTGCardInstance * realSource = NULL);
MTGCardInstance * rSource; MTGCardInstance * rSource;
virtual int isPaymentSet(); virtual int isPaymentSet();
virtual int canPay(); virtual int canPay();
virtual int doPay(); virtual int doPay();
virtual unattachCost * clone() const; virtual UnattachCost * clone() const;
}; };
//tap cost //tap cost
class TapCost : public ExtraCost class TapCost : public ExtraCost

View File

@@ -97,6 +97,7 @@ class MTGGameZone {
unsigned int countByType(const char * value); unsigned int countByType(const char * value);
unsigned int countByCanTarget(TargetChooser * tc); unsigned int countByCanTarget(TargetChooser * tc);
unsigned int countTotalManaSymbols(TargetChooser * tc, int color);
MTGCardInstance * findByName(string name); MTGCardInstance * findByName(string name);
//returns true if one of the cards in the zone has the ability //returns true if one of the cards in the zone has the ability

View File

@@ -56,6 +56,8 @@ public:
string alternativeName; string alternativeName;
bool isMulti; bool isMulti;
static ManaCost * parseManaCost(string value, ManaCost * _manacost = NULL, MTGCardInstance * c = NULL); static ManaCost * parseManaCost(string value, ManaCost * _manacost = NULL, MTGCardInstance * c = NULL);
static int parseManaSymbol(char symbol);
virtual void resetCosts(); virtual void resetCosts();
void x(); void x();
int hasX(); int hasX();
@@ -69,15 +71,17 @@ public:
ManaCost(ManaCost * _manaCost); ManaCost(ManaCost * _manaCost);
ManaCost(const ManaCost& manaCost); ManaCost(const ManaCost& manaCost);
ManaCost& operator= (const ManaCost& manaCost); ManaCost& operator= (const ManaCost& manaCost);
void copy (ManaCost * _manaCost); void copy(ManaCost * _manaCost);
int isNull(); int isNull();
int getConvertedCost(); int getConvertedCost();
string toString(); string toString();
int getCost(int color); int getCost(int color);
int getManaSymbols(int color);
//Returns NULL if i is greater than nbhybrids //Returns NULL if i is greater than nbhybrids
ManaCostHybrid * getHybridCost(unsigned int i); ManaCostHybrid * getHybridCost(unsigned int i);
int hasColor(int color); int hasColor(int color);
int remove (int color, int value); int remove(int color, int value);
int add(int color, int value); int add(int color, int value);
// //
@@ -92,7 +96,7 @@ public:
ExtraCost * getExtraCost(unsigned int i); ExtraCost * getExtraCost(unsigned int i);
int addHybrid(int c1, int v1, int c2, int v2); int addHybrid(int c1, int v1, int c2, int v2);
int tryToPayHybrids(std::vector<ManaCostHybrid>& _hybrids, int _nbhybrids,std::vector<int16_t>& diff); int tryToPayHybrids(const std::vector<ManaCostHybrid> &_hybrids, int _nbhybrids, std::vector<int16_t>& diff);
void randomDiffHybrids(ManaCost * _cost, std::vector<int16_t>& diff); void randomDiffHybrids(ManaCost * _cost, std::vector<int16_t>& diff);
int add(ManaCost * _cost); int add(ManaCost * _cost);
int remove(ManaCost * _cost); int remove(ManaCost * _cost);

View File

@@ -18,6 +18,7 @@ public:
int hasColor(int color); int hasColor(int color);
string toString(); string toString();
int getConvertedCost(); int getConvertedCost();
int getManaSymbols(int color);
friend std::ostream& operator<<(std::ostream& out, ManaCostHybrid& m); friend std::ostream& operator<<(std::ostream& out, ManaCostHybrid& m);
friend std::ostream& operator<<(std::ostream& out, ManaCostHybrid* m); friend std::ostream& operator<<(std::ostream& out, ManaCostHybrid* m);

View File

@@ -1356,8 +1356,8 @@ int AIPlayerBaka::selectAbility()
{ {
if(observer->mExtraPayment && observer->mExtraPayment->source->controller() == this) if(observer->mExtraPayment && observer->mExtraPayment->source->controller() == this)
{ {
extraManaCost * check = NULL; ExtraManaCost * check = NULL;
check = dynamic_cast<extraManaCost*>(observer->mExtraPayment->costs[0]); check = dynamic_cast<ExtraManaCost*>(observer->mExtraPayment->costs[0]);
if(check) if(check)
{ {
vector<MTGAbility*> CostToPay = canPayMana(observer->mExtraPayment->source,check->costToPay); 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) if(observer->mExtraPayment && observer->mExtraPayment->source->controller() == this)
{ {
extraManaCost * check = NULL; ExtraManaCost * check = NULL;
check = dynamic_cast<extraManaCost*>(observer->mExtraPayment->costs[0]); check = dynamic_cast<ExtraManaCost*>(observer->mExtraPayment->costs[0]);
if(check) if(check)
{ {
vector<MTGAbility*> CostToPay = canPayMana(observer->mExtraPayment->source,check->costToPay); vector<MTGAbility*> CostToPay = canPayMana(observer->mExtraPayment->source,check->costToPay);

View File

@@ -3516,7 +3516,7 @@ int MenuAbility::reactToChoiceClick(Targetable * object,int choice,int control)
toPay = NEW ManaCost(); toPay = NEW ManaCost();
if(optionalCosts[i]->extraCosts) if(optionalCosts[i]->extraCosts)
toPay->extraCosts = optionalCosts[i]->extraCosts->clone(); 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); toPay->setExtraCostsAction(this,source);
game->mExtraPayment = toPay->extraCosts; game->mExtraPayment = toPay->extraCosts;
return 0; return 0;

View File

@@ -7,6 +7,7 @@
#include "Player.h" #include "Player.h"
#include "Counters.h" #include "Counters.h"
#include "AllAbilities.h" #include "AllAbilities.h"
#include <boost/scoped_ptr.hpp>
SUPPORT_OBJECT_ANALYTICS(ExtraCost) SUPPORT_OBJECT_ANALYTICS(ExtraCost)
@@ -69,23 +70,23 @@ int ExtraCost::setPayment(MTGCardInstance * card)
return result; return result;
} }
//extra added manacost, or add a manacost as the cost of extra //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; return ec;
} }
extraManaCost::extraManaCost(ManaCost * costToPay) ExtraManaCost::ExtraManaCost(ManaCost * costToPay)
: ExtraCost("Pay The Cost",NULL, costToPay) : ExtraCost("Pay The Cost",NULL, costToPay)
{ {
} }
int extraManaCost::tryToSetPayment(MTGCardInstance * card) int ExtraManaCost::tryToSetPayment(MTGCardInstance * card)
{ {
return 1; return 1;
} }
int extraManaCost::isPaymentSet() int ExtraManaCost::isPaymentSet()
{ {
if (!source->controller()->getManaPool()->canAfford(costToPay)) if (!source->controller()->getManaPool()->canAfford(costToPay))
{ {
@@ -94,7 +95,7 @@ int extraManaCost::isPaymentSet()
return 1; return 1;
} }
int extraManaCost::canPay() int ExtraManaCost::canPay()
{ {
if(!source->controller()->getManaPool()->canAfford(costToPay)) if(!source->controller()->getManaPool()->canAfford(costToPay))
{ {
@@ -103,7 +104,7 @@ int extraManaCost::canPay()
return 1; return 1;
} }
int extraManaCost::doPay() int ExtraManaCost::doPay()
{ {
if (!source->controller()->getManaPool()->canAfford(costToPay)) if (!source->controller()->getManaPool()->canAfford(costToPay))
return 0; return 0;
@@ -159,7 +160,15 @@ LifeorManaCost * LifeorManaCost::clone() const
return ec; 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) : ExtraCost("Phyrexian Mana", _tc), manaType(manaType)
{ {
} }
@@ -167,16 +176,11 @@ LifeorManaCost::LifeorManaCost(TargetChooser *_tc,string manaType)
int LifeorManaCost::canPay() int LifeorManaCost::canPay()
{ {
MTGCardInstance * _target = (MTGCardInstance *) target; MTGCardInstance * _target = (MTGCardInstance *) target;
string buildType ="{"; boost::scoped_ptr<ManaCost> manaCost(getManaCost());
buildType.append(manaType); if (_target->controller()->getManaPool()->canAfford(manaCost.get()) || _target->controller()->life > 1)
buildType.append("}");
ManaCost * newCost = ManaCost::parseManaCost(buildType);
if(_target->controller()->getManaPool()->canAfford(newCost) || _target->controller()->life > 1)
{ {
SAFE_DELETE(newCost);
return 1; return 1;
} }
SAFE_DELETE(newCost);
return 0; return 0;
} }
@@ -186,24 +190,22 @@ int LifeorManaCost::doPay()
return 0; return 0;
MTGCardInstance * _target = (MTGCardInstance *) target; MTGCardInstance * _target = (MTGCardInstance *) target;
string buildType ="{"; ManaCost * manaCost = getManaCost();
buildType.append(manaType); if (_target->controller()->getManaPool()->canAfford(manaCost))
buildType.append("}");
ManaCost * newCost = ManaCost::parseManaCost(buildType);
if(_target->controller()->getManaPool()->canAfford(newCost))
{ {
_target->controller()->getManaPool()->pay(newCost); _target->controller()->getManaPool()->pay(manaCost);
} }
else else
{ {
_target->controller()->loseLife(2); _target->controller()->loseLife(2);
} }
SAFE_DELETE(newCost); SAFE_DELETE(manaCost);
target = NULL; target = NULL;
if (tc) if (tc)
tc->initTargets(); tc->initTargets();
return 1; return 1;
} }
//discard a card at random as a cost //discard a card at random as a cost
//DiscardRandom cost //DiscardRandom cost
DiscardRandomCost * DiscardRandomCost::clone() const DiscardRandomCost * DiscardRandomCost::clone() const
@@ -404,18 +406,18 @@ int MillExileCost::doPay()
} }
//unattach cost //unattach cost
unattachCost * unattachCost::clone() const UnattachCost * UnattachCost::clone() const
{ {
unattachCost * ec = NEW unattachCost(*this); UnattachCost * ec = NEW UnattachCost(*this);
return ec; return ec;
} }
unattachCost::unattachCost(MTGCardInstance * realSource) UnattachCost::UnattachCost(MTGCardInstance * realSource)
: ExtraCost("Unattach"),rSource(realSource) : ExtraCost("Unattach"),rSource(realSource)
{ {
} }
int unattachCost::isPaymentSet() int UnattachCost::isPaymentSet()
{ {
if (rSource && !rSource->target) if (rSource && !rSource->target)
{ {
@@ -424,12 +426,12 @@ int unattachCost::isPaymentSet()
return 1; return 1;
} }
int unattachCost::canPay() int UnattachCost::canPay()
{ {
return isPaymentSet(); return isPaymentSet();
} }
int unattachCost::doPay() int UnattachCost::doPay()
{ {
MTGCardInstance * _source = (MTGCardInstance *) source; MTGCardInstance * _source = (MTGCardInstance *) source;
if(_source != rSource) if(_source != rSource)

View File

@@ -1275,9 +1275,9 @@ int GameObserver::cardClick(MTGCardInstance * card, Targetable * object, bool lo
break; break;
} }
} }
extraManaCost * costType = NULL; ExtraManaCost * costType = NULL;
if( mExtraPayment && mExtraPayment->costs.size()) if( mExtraPayment && mExtraPayment->costs.size())
costType = dynamic_cast<extraManaCost*>(mExtraPayment->costs[0]); costType = dynamic_cast<ExtraManaCost*>(mExtraPayment->costs[0]);
if (WaitForExtraPayment(card) && !costType) if (WaitForExtraPayment(card) && !costType)
{ {

View File

@@ -549,17 +549,37 @@ unsigned int MTGGameZone::countByCanTarget(TargetChooser * tc)
{ {
if(!tc) if(!tc)
return 0; 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; int result = 0;
for (int i = 0; i < (nb_cards); i++) for (int i = 0; i < (nb_cards); i++)
{ {
if (tc->canTarget(cards[i])) if (tc->canTarget(cards[i]), withoutProtections)
{ {
result++; result++;
} }
} }
return 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) MTGCardInstance * MTGGameZone::findByName(string name)
{ {
for (int i = 0; i < (nb_cards); i++) for (int i = 0; i < (nb_cards); i++)

View File

@@ -8,6 +8,7 @@
#include "WEvent.h" #include "WEvent.h"
#include "MTGAbility.h" #include "MTGAbility.h"
#include "iterator" #include "iterator"
#include <boost/scoped_ptr.hpp>
SUPPORT_OBJECT_ANALYTICS(ManaCost) SUPPORT_OBJECT_ANALYTICS(ManaCost)
@@ -238,7 +239,7 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
{ {
if(value == "unattach") if(value == "unattach")
{ {
manaCost->addExtraCost(NEW unattachCost(c)); manaCost->addExtraCost(NEW UnattachCost(c));
break; break;
} }
int intvalue = atoi(value.c_str()); int intvalue = atoi(value.c_str());
@@ -431,6 +432,7 @@ void ManaCost::specificX(int color)
xColor = color; xColor = color;
cost[Constants::NB_Colors] = 1; cost[Constants::NB_Colors] = 1;
} }
int ManaCost::hasSpecificX() int ManaCost::hasSpecificX()
{ {
if (cost.size() <= (size_t)Constants::NB_Colors) if (cost.size() <= (size_t)Constants::NB_Colors)
@@ -578,6 +580,47 @@ int ManaCost::getCost(int color)
return cost[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) ManaCostHybrid * ManaCost::getHybridCost(unsigned int i)
{ {
if (hybrids.size() <= i) if (hybrids.size() <= i)
@@ -620,7 +663,7 @@ int ManaCost::isNull()
int ManaCost::getConvertedCost() int ManaCost::getConvertedCost()
{ {
int result = 0; int result = 0;
for ( int i = 0; i < Constants::NB_Colors; i++) for (int i = 0; i < Constants::NB_Colors; i++)
{ {
result += cost[i]; result += cost[i];
} }
@@ -628,15 +671,15 @@ int ManaCost::getConvertedCost()
{ {
result += hybrids[i].getConvertedCost(); result += hybrids[i].getConvertedCost();
} }
if(extraCosts && extraCosts->costs.size()) if (extraCosts && extraCosts->costs.size())
{ {
for(unsigned int i = 0; i < extraCosts->costs.size();i++) for (unsigned int i = 0; i < extraCosts->costs.size(); i++)
{ {
ExtraCost * pMana = dynamic_cast<LifeorManaCost*>(extraCosts->costs[i]); ExtraCost * pMana = dynamic_cast<LifeorManaCost*>(extraCosts->costs[i]);
if(pMana) if (pMana)
result++; result++;
} }
} }
return 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) 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) if (!_nbhybrids)
return 1; return 1;
int result = 0; int result = 0;
ManaCostHybrid& h = _hybrids[_nbhybrids - 1]; const ManaCostHybrid& h = _hybrids[_nbhybrids - 1];
if (diff[h.color1 * 2 + 1] >= h.value1) if (diff[h.color1 * 2 + 1] >= h.value1)
{ {
diff[h.color1 * 2 + 1] -= h.value1; diff[h.color1 * 2 + 1] -= h.value1;

View File

@@ -50,6 +50,14 @@ int ManaCostHybrid::getConvertedCost()
return value1; 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) int ManaCostHybrid::hasColor(int color)
{ {
if (((color1 == color) && value1) || ((color2 == color) && value2)) if (((color1 == color) && value1) || ((color2 == color) && value2))

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 //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 // 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 (!target) return false;
if (MTGCardInstance * card = dynamic_cast<MTGCardInstance *>(target)) if (MTGCardInstance * card = dynamic_cast<MTGCardInstance *>(target))