Devotion mechanics (thanks to excessum for patch)
+ some refactoring: extrManaCost --> ExtraManaCost unattachCost --> UnattachCost
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
30
projects/mtg/bin/Res/test/generic/devotion.txt
Normal file
30
projects/mtg/bin/Res/test/generic/devotion.txt
Normal 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]
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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++)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
Reference in New Issue
Block a user