convoke
other={convoke} name(Convoke)
delve
other={delve}
they might be able to be added directly to the real manacost.
added an ability that grants an ability while the source remains tapped
grant ability grantend...
added dethrone
abilities=dethrone
added support of multitargeting to extra cost, it acts the same as normal multitargeting, repeats dopay() the effects for each.
This commit is contained in:
@@ -166,8 +166,11 @@ private:
|
|||||||
{
|
{
|
||||||
if(!s.size())
|
if(!s.size())
|
||||||
return;
|
return;
|
||||||
if(!card)
|
if (!card)
|
||||||
return;
|
{
|
||||||
|
intValue = atoi(s.c_str());//if there is no card, try parsing a number.
|
||||||
|
return;
|
||||||
|
}
|
||||||
MTGCardInstance * target = card->target;
|
MTGCardInstance * target = card->target;
|
||||||
if(!card->storedCard)
|
if(!card->storedCard)
|
||||||
card->storedCard = card->storedSourceCard;
|
card->storedCard = card->storedSourceCard;
|
||||||
@@ -5166,7 +5169,38 @@ public:
|
|||||||
~AShackleWrapper();
|
~AShackleWrapper();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
//Grant
|
||||||
|
class AGrant : public MTGAbility
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MTGCardInstance * Blessed;
|
||||||
|
bool resolved;
|
||||||
|
MTGAbility * Granted;
|
||||||
|
MTGAbility * toGrant;
|
||||||
|
AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant);
|
||||||
|
void Update(float dt);
|
||||||
|
void resolveGrant();
|
||||||
|
int resolve();
|
||||||
|
const string getMenuText();
|
||||||
|
AGrant * clone() const;
|
||||||
|
~AGrant();
|
||||||
|
private:
|
||||||
|
void removeGranted(MTGCardInstance *_target);
|
||||||
|
};
|
||||||
|
|
||||||
|
//GrantWrapper
|
||||||
|
class AGrantWrapper : public InstantAbility
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AGrant * ability;
|
||||||
|
MTGAbility * Granted;
|
||||||
|
AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * toGrant);
|
||||||
|
int resolve();
|
||||||
|
const string getMenuText();
|
||||||
|
AGrantWrapper * clone() const;
|
||||||
|
~AGrantWrapper();
|
||||||
|
|
||||||
|
};
|
||||||
//ABlink
|
//ABlink
|
||||||
class ABlink: public MTGAbility
|
class ABlink: public MTGAbility
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -274,7 +274,27 @@ public:
|
|||||||
virtual int doPay();
|
virtual int doPay();
|
||||||
virtual Ninja * clone() const;
|
virtual Ninja * clone() const;
|
||||||
};
|
};
|
||||||
|
//Convoke
|
||||||
|
class Convoke : public ExtraCost
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ManaCost * getReduction();
|
||||||
|
Convoke(TargetChooser *_tc = NULL);
|
||||||
|
virtual int canPay();
|
||||||
|
virtual int isPaymentSet();
|
||||||
|
virtual int doPay();
|
||||||
|
virtual Convoke * clone() const;
|
||||||
|
};
|
||||||
|
//delve
|
||||||
|
class Delve : public ExtraCost
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Delve(TargetChooser *_tc = NULL);
|
||||||
|
virtual int canPay();
|
||||||
|
virtual int isPaymentSet();
|
||||||
|
virtual int doPay();
|
||||||
|
virtual Delve * clone() const;
|
||||||
|
};
|
||||||
//offering cost
|
//offering cost
|
||||||
class Offering : public ExtraCost
|
class Offering : public ExtraCost
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -251,7 +251,8 @@ class Constants
|
|||||||
MENACE = 129,
|
MENACE = 129,
|
||||||
NOSOLO = 130,//cant attack alone
|
NOSOLO = 130,//cant attack alone
|
||||||
MUSTBLOCK = 131,//blocks each turn
|
MUSTBLOCK = 131,//blocks each turn
|
||||||
NB_BASIC_ABILITIES = 132,
|
DETHRONE = 132,
|
||||||
|
NB_BASIC_ABILITIES = 133,
|
||||||
|
|
||||||
RARITY_S = 'S', //Special Rarity
|
RARITY_S = 'S', //Special Rarity
|
||||||
RARITY_M = 'M', //Mythics
|
RARITY_M = 'M', //Mythics
|
||||||
|
|||||||
@@ -105,6 +105,11 @@ bool ActionLayer::CheckUserInput(JButton key)
|
|||||||
//being cancelled. currently only menuability and paidability will care.
|
//being cancelled. currently only menuability and paidability will care.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (observer->mExtraPayment->costs.size() && observer->mExtraPayment->costs[0]->tc)
|
||||||
|
{
|
||||||
|
//if we cancel, clear the targets list so that when you try again you dont already have targets from before.
|
||||||
|
observer->mExtraPayment->costs[0]->tc->initTargets();
|
||||||
|
}
|
||||||
observer->mExtraPayment = NULL;
|
observer->mExtraPayment = NULL;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6581,6 +6581,113 @@ AShackleWrapper::~AShackleWrapper()
|
|||||||
SAFE_DELETE(ability);
|
SAFE_DELETE(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//grant
|
||||||
|
AGrant::AGrant(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * _Grant) :
|
||||||
|
MTGAbility(observer, _id, card)
|
||||||
|
{
|
||||||
|
Granted = _Grant;
|
||||||
|
target = _target;
|
||||||
|
Blessed = NULL;
|
||||||
|
resolved = false;
|
||||||
|
toGrant = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGrant::Update(float dt)
|
||||||
|
{
|
||||||
|
if (resolved == false)
|
||||||
|
{
|
||||||
|
resolved = true;
|
||||||
|
resolveGrant();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!source->isTapped() || !source->isInPlay(game))
|
||||||
|
{
|
||||||
|
if (Blessed == NULL || !Blessed->isInPlay(game))
|
||||||
|
MTGAbility::Update(dt);
|
||||||
|
MTGCardInstance * _target = Blessed;
|
||||||
|
removeGranted(_target);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
resolveGrant();
|
||||||
|
MTGAbility::Update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGrant::resolveGrant()
|
||||||
|
{
|
||||||
|
if (toGrant) return;
|
||||||
|
MTGCardInstance * _target = (MTGCardInstance *)target;
|
||||||
|
if (_target)
|
||||||
|
{
|
||||||
|
toGrant = Granted->clone();
|
||||||
|
toGrant->target = _target;
|
||||||
|
toGrant->addToGame();
|
||||||
|
Blessed = _target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AGrant::removeGranted(MTGCardInstance* _target)
|
||||||
|
{
|
||||||
|
if (!toGrant) return;
|
||||||
|
MTGCardInstance * cardToReturn = _target;
|
||||||
|
game->removeObserver(toGrant);
|
||||||
|
game->removeObserver(this);
|
||||||
|
Blessed = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AGrant::resolve()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const string AGrant::getMenuText()
|
||||||
|
{
|
||||||
|
return Granted->getMenuText();
|
||||||
|
}
|
||||||
|
|
||||||
|
AGrant * AGrant::clone() const
|
||||||
|
{
|
||||||
|
AGrant * a = NEW AGrant(*this);
|
||||||
|
a->forceDestroy = -1;
|
||||||
|
a->Granted = Granted->clone();
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
AGrant::~AGrant()
|
||||||
|
{
|
||||||
|
SAFE_DELETE(Granted);
|
||||||
|
}
|
||||||
|
|
||||||
|
AGrantWrapper::AGrantWrapper(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, MTGAbility * _Grant) :
|
||||||
|
InstantAbility(observer, _id, source, _target), Granted(_Grant)
|
||||||
|
{
|
||||||
|
ability = NEW AGrant(observer, _id, card, _target,_Grant);
|
||||||
|
}
|
||||||
|
|
||||||
|
int AGrantWrapper::resolve()
|
||||||
|
{
|
||||||
|
AGrant * a = ability->clone();
|
||||||
|
a->target = target;
|
||||||
|
a->addToGame();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const string AGrantWrapper::getMenuText()
|
||||||
|
{
|
||||||
|
return "Grant";
|
||||||
|
}
|
||||||
|
|
||||||
|
AGrantWrapper * AGrantWrapper::clone() const
|
||||||
|
{
|
||||||
|
AGrantWrapper * a = NEW AGrantWrapper(*this);
|
||||||
|
a->ability = this->ability->clone();
|
||||||
|
a->oneShot = 1;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
AGrantWrapper::~AGrantWrapper()
|
||||||
|
{
|
||||||
|
SAFE_DELETE(ability);
|
||||||
|
}
|
||||||
|
|
||||||
//a blink
|
//a blink
|
||||||
ABlink::ABlink(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, bool blinkueot, bool blinkForSource, bool blinkhand, MTGAbility * stored) :
|
ABlink::ABlink(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, bool blinkueot, bool blinkForSource, bool blinkhand, MTGAbility * stored) :
|
||||||
MTGAbility(observer, _id, card),blinkueot(blinkueot),blinkForSource(blinkForSource),blinkhand(blinkhand),stored(stored)
|
MTGAbility(observer, _id, card),blinkueot(blinkueot),blinkForSource(blinkForSource),blinkhand(blinkhand),stored(stored)
|
||||||
|
|||||||
@@ -72,6 +72,10 @@ int ExtraCost::setPayment(MTGCardInstance * card)
|
|||||||
if (tc)
|
if (tc)
|
||||||
{
|
{
|
||||||
result = tc->addTarget(card);
|
result = tc->addTarget(card);
|
||||||
|
//this is flawed logic, we need to fix. if there is a target in list
|
||||||
|
//we return targetready instead, the card is not pushed back into list
|
||||||
|
//how ever, it is made the target becuase the result is 1 even if we couldnt
|
||||||
|
//target it with the targetchooser.
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
target = card;
|
target = card;
|
||||||
@@ -748,7 +752,7 @@ int TapTargetCost::isPaymentSet()
|
|||||||
target = NULL;
|
target = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (target)
|
if (target && (tc->getNbTargets() == tc->maxtargets || tc->done))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -922,6 +926,193 @@ int Ninja::doPay()
|
|||||||
|
|
||||||
//endbouncetargetcostforninja
|
//endbouncetargetcostforninja
|
||||||
|
|
||||||
|
//Convoke
|
||||||
|
Convoke * Convoke::clone() const
|
||||||
|
{
|
||||||
|
Convoke * ec = NEW Convoke(*this);
|
||||||
|
if (tc)
|
||||||
|
ec->tc = tc->clone();
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
Convoke::Convoke(TargetChooser *_tc) :
|
||||||
|
ExtraCost("Select Cards To Tap", _tc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int Convoke::canPay()
|
||||||
|
{
|
||||||
|
return isPaymentSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Convoke::isPaymentSet()
|
||||||
|
{
|
||||||
|
if (target && target->isTapped())
|
||||||
|
{
|
||||||
|
tc->removeTarget(target);
|
||||||
|
target->isExtraCostTarget = false;
|
||||||
|
target = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ManaCost * toReduce = getReduction();
|
||||||
|
if (target && (!source->controller()->getManaPool()->canAfford(toReduce)))
|
||||||
|
{
|
||||||
|
target = NULL;
|
||||||
|
SAFE_DELETE(toReduce);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (target && (source->controller()->getManaPool()->canAfford(toReduce)))
|
||||||
|
{
|
||||||
|
SAFE_DELETE(toReduce);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ManaCost * Convoke::getReduction()
|
||||||
|
{
|
||||||
|
ManaCost * toReduce = NEW ManaCost(source->getManaCost());
|
||||||
|
tc->maxtargets = source->getManaCost()->getConvertedCost();
|
||||||
|
if (tc->getNbTargets())
|
||||||
|
{
|
||||||
|
vector<Targetable*>targetlist = tc->getTargetsFrom();
|
||||||
|
for (vector<Targetable*>::iterator it = targetlist.begin(); it != targetlist.end(); it++)
|
||||||
|
{
|
||||||
|
bool next = false;
|
||||||
|
for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i)
|
||||||
|
{
|
||||||
|
if (next == true)
|
||||||
|
break;
|
||||||
|
MTGCardInstance * targetCard = dynamic_cast<MTGCardInstance*>(*it);
|
||||||
|
if ((targetCard->getManaCost()->hasColor(i) || targetCard->hasColor(i)) && toReduce->hasColor(i))
|
||||||
|
{
|
||||||
|
toReduce->remove(i, 1);
|
||||||
|
next = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
toReduce->remove(Constants::MTG_COLOR_ARTIFACT, 1);
|
||||||
|
next = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if we didnt find it payable one way, lets try again backwards.
|
||||||
|
if (!source->controller()->getManaPool()->canAfford(toReduce))
|
||||||
|
{
|
||||||
|
SAFE_DELETE(toReduce);
|
||||||
|
toReduce = NEW ManaCost(source->getManaCost());
|
||||||
|
for (vector<Targetable*>::reverse_iterator it = targetlist.rbegin(); it != targetlist.rend(); it++)
|
||||||
|
{
|
||||||
|
bool next = false;
|
||||||
|
for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i)
|
||||||
|
{
|
||||||
|
if (next == true)
|
||||||
|
break;
|
||||||
|
MTGCardInstance * targetCard = dynamic_cast<MTGCardInstance*>(*it);
|
||||||
|
if ((targetCard->getManaCost()->hasColor(i) || targetCard->hasColor(i)) && toReduce->hasColor(i))
|
||||||
|
{
|
||||||
|
toReduce->remove(i, 1);
|
||||||
|
next = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
toReduce->remove(Constants::MTG_COLOR_ARTIFACT, 1);
|
||||||
|
next = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return toReduce;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Convoke::doPay()
|
||||||
|
{
|
||||||
|
if (target && tc->getNbTargets())
|
||||||
|
{
|
||||||
|
ManaCost * toReduce = getReduction();
|
||||||
|
target->controller()->getManaPool()->pay(toReduce);
|
||||||
|
SAFE_DELETE(toReduce);
|
||||||
|
vector<Targetable*>targetlist = tc->getTargetsFrom();
|
||||||
|
for (vector<Targetable*>::iterator it = targetlist.begin(); it != targetlist.end(); it++)
|
||||||
|
{
|
||||||
|
MTGCardInstance * targetCard = dynamic_cast<MTGCardInstance*>(*it);
|
||||||
|
source->storedCard = targetCard->createSnapShot();
|
||||||
|
targetCard->tap();
|
||||||
|
}
|
||||||
|
if (tc)
|
||||||
|
tc->initTargets();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//DELVE
|
||||||
|
Delve * Delve::clone() const
|
||||||
|
{
|
||||||
|
Delve * ec = NEW Delve(*this);
|
||||||
|
if (tc)
|
||||||
|
ec->tc = tc->clone();
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
Delve::Delve(TargetChooser *_tc) :
|
||||||
|
ExtraCost("Select Cards To Exile", _tc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int Delve::canPay()
|
||||||
|
{
|
||||||
|
return isPaymentSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Delve::isPaymentSet()
|
||||||
|
{
|
||||||
|
ManaCost * toReduce = NEW ManaCost(source->getManaCost());
|
||||||
|
tc->maxtargets = source->getManaCost()->getCost(Constants::MTG_COLOR_ARTIFACT);
|
||||||
|
if (tc->getNbTargets())
|
||||||
|
{
|
||||||
|
toReduce->remove(Constants::MTG_COLOR_ARTIFACT, tc->getNbTargets());
|
||||||
|
}
|
||||||
|
if (target && (!source->controller()->getManaPool()->canAfford(toReduce)))
|
||||||
|
{
|
||||||
|
target = NULL;
|
||||||
|
SAFE_DELETE(toReduce);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (target && (source->controller()->getManaPool()->canAfford(toReduce)))
|
||||||
|
{
|
||||||
|
SAFE_DELETE(toReduce);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Delve::doPay()
|
||||||
|
{
|
||||||
|
if (target && tc->getNbTargets())
|
||||||
|
{
|
||||||
|
ManaCost * toReduce = NEW ManaCost(source->getManaCost());
|
||||||
|
|
||||||
|
toReduce->remove(Constants::MTG_COLOR_ARTIFACT, tc->getNbTargets());
|
||||||
|
|
||||||
|
target->controller()->getManaPool()->pay(toReduce);
|
||||||
|
SAFE_DELETE(toReduce);
|
||||||
|
vector<Targetable*>targetlist = tc->getTargetsFrom();
|
||||||
|
for (vector<Targetable*>::iterator it = targetlist.begin(); it != targetlist.end(); it++)
|
||||||
|
{
|
||||||
|
MTGCardInstance * targetCard = dynamic_cast<MTGCardInstance*>(*it);
|
||||||
|
source->storedCard = targetCard->createSnapShot();
|
||||||
|
targetCard->controller()->game->putInExile(targetCard);
|
||||||
|
}
|
||||||
|
if (tc)
|
||||||
|
tc->initTargets();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////
|
||||||
//Sacrifice target as cost for Offering
|
//Sacrifice target as cost for Offering
|
||||||
Offering * Offering::clone() const
|
Offering * Offering::clone() const
|
||||||
{
|
{
|
||||||
@@ -1214,7 +1405,7 @@ int ExtraCosts::tryToSetPayment(MTGCardInstance * card)
|
|||||||
}
|
}
|
||||||
if (int result = costs[i]->setPayment(card))
|
if (int result = costs[i]->setPayment(card))
|
||||||
{
|
{
|
||||||
card->isExtraCostTarget = true;
|
//card->isExtraCostTarget = true;//moved to gameobserver, flawed logic was setting this to true even when it wasnt really a target
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1251,10 +1442,20 @@ int ExtraCosts::doPay()
|
|||||||
int result = 0;
|
int result = 0;
|
||||||
for (size_t i = 0; i < costs.size(); i++)
|
for (size_t i = 0; i < costs.size(); i++)
|
||||||
{
|
{
|
||||||
if(costs[i]->target)
|
if(costs[i]->target)//todo deprecate this let gameobserver control this.
|
||||||
{
|
{
|
||||||
costs[i]->target->isExtraCostTarget = false;
|
costs[i]->target->isExtraCostTarget = false;
|
||||||
}
|
}
|
||||||
|
if (costs[i]->tc)
|
||||||
|
{
|
||||||
|
vector<Targetable*>targetlist = costs[i]->tc->getTargetsFrom();
|
||||||
|
for (vector<Targetable*>::iterator it = targetlist.begin(); it != targetlist.end(); it++)
|
||||||
|
{
|
||||||
|
costs[i]->target = dynamic_cast<MTGCardInstance*>(*it);
|
||||||
|
costs[i]->doPay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
result += costs[i]->doPay();
|
result += costs[i]->doPay();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -715,6 +715,27 @@ void GameObserver::gameStateBasedEffects()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
card->bypassTC = false; //turn off bypass
|
card->bypassTC = false; //turn off bypass
|
||||||
|
///////////////////////////
|
||||||
|
//reset extracost shadows//
|
||||||
|
///////////////////////////
|
||||||
|
card->isExtraCostTarget = false;
|
||||||
|
if (mExtraPayment != NULL)
|
||||||
|
{
|
||||||
|
for (unsigned int ec = 0; ec < mExtraPayment->costs.size(); ec++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (mExtraPayment->costs[ec]->tc)
|
||||||
|
{
|
||||||
|
vector<Targetable*>targetlist = mExtraPayment->costs[ec]->tc->getTargetsFrom();
|
||||||
|
for (vector<Targetable*>::iterator it = targetlist.begin(); it != targetlist.end(); it++)
|
||||||
|
{
|
||||||
|
Targetable * cardMasked = *it;
|
||||||
|
dynamic_cast<MTGCardInstance*>(cardMasked)->isExtraCostTarget = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
//Unattach Equipments that dont have valid targets//
|
//Unattach Equipments that dont have valid targets//
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
@@ -733,6 +754,7 @@ void GameObserver::gameStateBasedEffects()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
//Remove auras that don't have a valid target anymore//
|
//Remove auras that don't have a valid target anymore//
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
@@ -773,18 +795,7 @@ void GameObserver::gameStateBasedEffects()
|
|||||||
{
|
{
|
||||||
card->playerTarget->curses.push_back(card);
|
card->playerTarget->curses.push_back(card);
|
||||||
}
|
}
|
||||||
///////////////////////////
|
|
||||||
//reset extracost shadows//
|
|
||||||
///////////////////////////
|
|
||||||
card->isExtraCostTarget = false;
|
|
||||||
if(mExtraPayment != NULL)
|
|
||||||
{
|
|
||||||
for(unsigned int ec = 0;ec < mExtraPayment->costs.size();ec++)
|
|
||||||
{
|
|
||||||
if( mExtraPayment->costs[ec]->target)
|
|
||||||
mExtraPayment->costs[ec]->target->isExtraCostTarget = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//////////////////////
|
//////////////////////
|
||||||
//reset morph hiding//
|
//reset morph hiding//
|
||||||
//////////////////////
|
//////////////////////
|
||||||
@@ -1046,6 +1057,28 @@ void GameObserver::Affinity()
|
|||||||
if (!card)
|
if (!card)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
//reset extracost shadows//
|
||||||
|
///////////////////////////
|
||||||
|
card->isExtraCostTarget = false;
|
||||||
|
if (mExtraPayment != NULL)
|
||||||
|
{
|
||||||
|
for (unsigned int ec = 0; ec < mExtraPayment->costs.size(); ec++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (mExtraPayment->costs[ec]->tc)
|
||||||
|
{
|
||||||
|
vector<Targetable*>targetlist = mExtraPayment->costs[ec]->tc->getTargetsFrom();
|
||||||
|
for (vector<Targetable*>::iterator it = targetlist.begin(); it != targetlist.end(); it++)
|
||||||
|
{
|
||||||
|
Targetable * cardMasked = *it;
|
||||||
|
dynamic_cast<MTGCardInstance*>(cardMasked)->isExtraCostTarget = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////////////////////////////
|
||||||
bool NewAffinityFound = false;
|
bool NewAffinityFound = false;
|
||||||
for (unsigned int na = 0; na < card->cardsAbilities.size(); na++)
|
for (unsigned int na = 0; na < card->cardsAbilities.size(); na++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1374,6 +1374,15 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<string> splitGrant = parseBetween(s, "grant ", " grantend", false);
|
||||||
|
if (splitGrant.size() && storedAbilityString.empty())
|
||||||
|
{
|
||||||
|
storedAbilityString = splitGrant[1];
|
||||||
|
s = splitGrant[0];
|
||||||
|
s.append("grant ");
|
||||||
|
s.append(splitGrant[2]);
|
||||||
|
}
|
||||||
|
|
||||||
vector<string> splitRevealx = parseBetween(s, "reveal:", " revealend", false);
|
vector<string> splitRevealx = parseBetween(s, "reveal:", " revealend", false);
|
||||||
if (!abilfound.size() && !transfound.size() && splitRevealx.size() && storedAbilityString.empty())
|
if (!abilfound.size() && !transfound.size() && splitRevealx.size() && storedAbilityString.empty())
|
||||||
{
|
{
|
||||||
@@ -2242,6 +2251,16 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//grant ability until source is untapped or leaves battlefield
|
||||||
|
found = s.find("grant ");
|
||||||
|
if (found != string::npos)
|
||||||
|
{
|
||||||
|
MTGAbility * toGrant = parseMagicLine(storedAbilityString, id, spell, card);
|
||||||
|
MTGAbility * a = NEW AGrantWrapper(observer, id, card, target,toGrant);
|
||||||
|
a->oneShot = 1;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
//momentary blink
|
//momentary blink
|
||||||
found = s.find("(blink)");
|
found = s.find("(blink)");
|
||||||
if (found != string::npos)
|
if (found != string::npos)
|
||||||
|
|||||||
@@ -972,6 +972,7 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * new
|
|||||||
string type = "";
|
string type = "";
|
||||||
ManaCost * original = NEW ManaCost();
|
ManaCost * original = NEW ManaCost();
|
||||||
original->copy(newCost);
|
original->copy(newCost);
|
||||||
|
|
||||||
int reducem = 0;
|
int reducem = 0;
|
||||||
bool resetCost = false;
|
bool resetCost = false;
|
||||||
for(unsigned int na = 0; na < card->cardsAbilities.size();na++)
|
for(unsigned int na = 0; na < card->cardsAbilities.size();na++)
|
||||||
|
|||||||
@@ -162,7 +162,8 @@ const char* Constants::MTGBasicAbilities[] = {
|
|||||||
"skulk",
|
"skulk",
|
||||||
"menace",
|
"menace",
|
||||||
"nosolo",
|
"nosolo",
|
||||||
"mustblock"
|
"mustblock",
|
||||||
|
"dethrone",
|
||||||
};
|
};
|
||||||
|
|
||||||
map<string,int> Constants::MTGBasicAbilitiesMap;
|
map<string,int> Constants::MTGBasicAbilitiesMap;
|
||||||
|
|||||||
@@ -1605,6 +1605,11 @@ int MTGAttackRule::receiveEvent(WEvent *e)
|
|||||||
if (Check <2)
|
if (Check <2)
|
||||||
card->initAttackersDefensers();
|
card->initAttackersDefensers();
|
||||||
}
|
}
|
||||||
|
if (card->isAttacker() && card->has(Constants::DETHRONE))
|
||||||
|
{
|
||||||
|
if (p->opponent()->life >= p->life)
|
||||||
|
card->counters->addCounter(1, 1);
|
||||||
|
}
|
||||||
if (!card->isAttacker() && !event->from->isExtra && card->has(Constants::MUSTATTACK))//cards are only required to attack in the real attack phase of a turn.
|
if (!card->isAttacker() && !event->from->isExtra && card->has(Constants::MUSTATTACK))//cards are only required to attack in the real attack phase of a turn.
|
||||||
reactToClick(card);
|
reactToClick(card);
|
||||||
if (!card->isAttacker() && card->has(Constants::TREASON) && p->isAI())
|
if (!card->isAttacker() && card->has(Constants::TREASON) && p->isAI())
|
||||||
|
|||||||
@@ -179,7 +179,13 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'd': //DiscardRandom cost
|
case 'd': //DiscardRandom cost
|
||||||
if (value == "d")
|
if (value.find("delve") != string::npos)
|
||||||
|
{
|
||||||
|
if(!tc)
|
||||||
|
tc = tcf.createTargetChooser("*|mygraveyard", c);
|
||||||
|
manaCost->addExtraCost(NEW Delve(tc));
|
||||||
|
}
|
||||||
|
else if (value == "d")
|
||||||
{
|
{
|
||||||
manaCost->addExtraCost(NEW DiscardRandomCost(tc));
|
manaCost->addExtraCost(NEW DiscardRandomCost(tc));
|
||||||
}
|
}
|
||||||
@@ -253,7 +259,13 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
|
|||||||
break;
|
break;
|
||||||
case 'c': //Counters or cycle
|
case 'c': //Counters or cycle
|
||||||
{
|
{
|
||||||
if(value == "chosencolor")
|
if (value.find("convoke") != string::npos)
|
||||||
|
{
|
||||||
|
if (!tc)
|
||||||
|
tc = tcf.createTargetChooser("creature|mybattlefield", c);
|
||||||
|
manaCost->addExtraCost(NEW Convoke(tc));
|
||||||
|
}
|
||||||
|
else if(value == "chosencolor")
|
||||||
{
|
{
|
||||||
if(c)
|
if(c)
|
||||||
manaCost->add(c->chooseacolor, 1);
|
manaCost->add(c->chooseacolor, 1);
|
||||||
|
|||||||
@@ -20,9 +20,15 @@ int TargetsList::addTarget(Targetable * target)
|
|||||||
{
|
{
|
||||||
if (!alreadyHasTarget(target))
|
if (!alreadyHasTarget(target))
|
||||||
{
|
{
|
||||||
|
|
||||||
TargetChooser * tc = target->getObserver()->getCurrentTargetChooser();
|
TargetChooser * tc = target->getObserver()->getCurrentTargetChooser();
|
||||||
if(!tc || (tc && tc->maxtargets == 1))
|
if(!tc || (tc && tc->maxtargets == 1))
|
||||||
{
|
{
|
||||||
|
if (dynamic_cast<TargetChooser*>(this)->maxtargets > int(getNbTargets()))
|
||||||
|
{
|
||||||
|
targets.push_back(target);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
//because this was originally coded with targets as an array
|
//because this was originally coded with targets as an array
|
||||||
//we have to add this conditional to insure that cards with single target effects
|
//we have to add this conditional to insure that cards with single target effects
|
||||||
//and abilities that seek the nextcardtarget still work correctly.
|
//and abilities that seek the nextcardtarget still work correctly.
|
||||||
|
|||||||
Reference in New Issue
Block a user