Merge branch 'master' into cmake
This commit is contained in:
@@ -482,6 +482,7 @@ int AACopier::resolve()
|
||||
source->copiedID = _target->getMTGId();
|
||||
source->modifiedbAbi = _target->modifiedbAbi;
|
||||
source->origbasicAbilities = _target->origbasicAbilities;
|
||||
source->basicAbilities = _target->basicAbilities;
|
||||
if(_target->isMorphed)
|
||||
{
|
||||
source->power = 2;
|
||||
@@ -510,7 +511,7 @@ AACopier * AACopier::clone() const
|
||||
return NEW AACopier(*this);
|
||||
}
|
||||
|
||||
//phaser
|
||||
//phaseout
|
||||
AAPhaseOut::AAPhaseOut(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost) :
|
||||
ActivatedAbility(observer, _id, _source, _cost, 0)
|
||||
{
|
||||
@@ -543,6 +544,60 @@ AAPhaseOut * AAPhaseOut::clone() const
|
||||
return NEW AAPhaseOut(*this);
|
||||
}
|
||||
|
||||
//AAImprint
|
||||
AAImprint::AAImprint(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost) :
|
||||
ActivatedAbility(observer, _id, _source, _cost, 0)
|
||||
{
|
||||
target = _target;
|
||||
}
|
||||
|
||||
int AAImprint::resolve()
|
||||
{
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
if (_target)
|
||||
{
|
||||
Player * p = _target->controller();
|
||||
if(p)
|
||||
p->game->putInExile(_target);
|
||||
|
||||
while(_target->next)
|
||||
_target = _target->next;
|
||||
|
||||
source->imprintedCards.push_back(_target);
|
||||
|
||||
if (source->imprintedCards.size())
|
||||
{
|
||||
if (source->imprintedCards.back()->hasColor(Constants::MTG_COLOR_GREEN))
|
||||
source->imprintG += 1;
|
||||
if (source->imprintedCards.back()->hasColor(Constants::MTG_COLOR_BLUE))
|
||||
source->imprintU += 1;
|
||||
if (source->imprintedCards.back()->hasColor(Constants::MTG_COLOR_RED))
|
||||
source->imprintR += 1;
|
||||
if (source->imprintedCards.back()->hasColor(Constants::MTG_COLOR_BLACK))
|
||||
source->imprintB += 1;
|
||||
if (source->imprintedCards.back()->hasColor(Constants::MTG_COLOR_WHITE))
|
||||
source->imprintW += 1;
|
||||
if (source->imprintedCards.back()->getName().size())
|
||||
{
|
||||
source->currentimprintName = source->imprintedCards.back()->getName();
|
||||
source->imprintedNames.push_back(source->imprintedCards.back()->getName());
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const string AAImprint::getMenuText()
|
||||
{
|
||||
return "Imprint";
|
||||
}
|
||||
|
||||
AAImprint * AAImprint::clone() const
|
||||
{
|
||||
return NEW AAImprint(*this);
|
||||
}
|
||||
|
||||
//Counters
|
||||
AACounter::AACounter(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * target,string counterstring, const char * _name, int power, int toughness,
|
||||
int nb,int maxNb, ManaCost * cost) :
|
||||
@@ -1312,6 +1367,16 @@ int GenericPaidAbility::resolve()
|
||||
optionalCost->extraCosts->costs[i]->setSource(((MTGCardInstance *)target));
|
||||
}
|
||||
}
|
||||
if (source && source->previous && source->basicAbilities[(int)Constants::MADNESS])
|
||||
{
|
||||
must = true;
|
||||
optionalCost = source->computeNewCost(source->previous,optionalCost,optionalCost);
|
||||
if(optionalCost->extraCosts)
|
||||
{
|
||||
for(unsigned int i = 0; i < optionalCost->extraCosts->costs.size();i++)
|
||||
optionalCost->extraCosts->costs[i]->setSource(source);
|
||||
}
|
||||
}
|
||||
if(asAlternate && nomenu && optionalCost->getConvertedCost() < 1)
|
||||
nomenuAbility->resolve();
|
||||
else
|
||||
@@ -2945,7 +3010,7 @@ int AAMover::resolve()
|
||||
//inplay is a special zone !
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (destZone == game->players[i]->game->inPlay && fromZone != game->players[i]->game->inPlay && fromZone
|
||||
if (!_target->hasSubtype(Subtypes::TYPE_AURA) && destZone == game->players[i]->game->inPlay && fromZone != game->players[i]->game->inPlay && fromZone
|
||||
!= game->players[i]->opponent()->game->inPlay)
|
||||
{
|
||||
MTGCardInstance * copy = game->players[i]->game->putInZone(_target, fromZone, game->players[i]->game->temp);
|
||||
@@ -2973,21 +3038,45 @@ int AAMover::resolve()
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
p->game->putInZone(_target, fromZone, destZone);
|
||||
while(_target->next)
|
||||
_target = _target->next;
|
||||
if(andAbility)
|
||||
{
|
||||
MTGAbility * andAbilityClone = andAbility->clone();
|
||||
andAbilityClone->target = _target;
|
||||
if(andAbility->oneShot)
|
||||
{
|
||||
andAbilityClone->resolve();
|
||||
SAFE_DELETE(andAbilityClone);
|
||||
if(_target->hasSubtype(Subtypes::TYPE_AURA) && (destZone == game->players[0]->game->inPlay || destZone == game->players[1]->game->inPlay))
|
||||
{//put into play aura if there is no valid targets then it will be in its current zone
|
||||
MTGAbility *a = NEW AACastCard(game, game->mLayers->actionLayer()->getMaxId(), _target, _target,false,false,false,"","Put in play",false,true);
|
||||
a->oneShot = false;
|
||||
a->canBeInterrupted = false;
|
||||
a->addToGame();
|
||||
if(andAbility && _target->next)
|
||||
{//if successful target->next should be valid
|
||||
MTGAbility * andAbilityClone = andAbility->clone();
|
||||
andAbilityClone->target = _target->next;
|
||||
if(andAbility->oneShot)
|
||||
{
|
||||
andAbilityClone->resolve();
|
||||
SAFE_DELETE(andAbilityClone);
|
||||
}
|
||||
else
|
||||
{
|
||||
andAbilityClone->addToGame();
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
p->game->putInZone(_target, fromZone, destZone);
|
||||
while(_target->next)
|
||||
_target = _target->next;
|
||||
if(andAbility)
|
||||
{
|
||||
andAbilityClone->addToGame();
|
||||
MTGAbility * andAbilityClone = andAbility->clone();
|
||||
andAbilityClone->target = _target;
|
||||
if(andAbility->oneShot)
|
||||
{
|
||||
andAbilityClone->resolve();
|
||||
SAFE_DELETE(andAbilityClone);
|
||||
}
|
||||
else
|
||||
{
|
||||
andAbilityClone->addToGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@@ -5356,6 +5445,106 @@ APhaseActionGeneric::~APhaseActionGeneric()
|
||||
SAFE_DELETE(ability);
|
||||
}
|
||||
|
||||
//AAttackSetCost
|
||||
AAttackSetCost::AAttackSetCost(GameObserver* observer, int _id, MTGCardInstance * _source, string number, bool pw) :
|
||||
MTGAbility(observer, _id, _source), number(number), pw(pw)
|
||||
{
|
||||
}
|
||||
|
||||
void AAttackSetCost::Update(float dt)
|
||||
{
|
||||
if(game->getCurrentGamePhase() != MTG_PHASE_COMBATATTACKERS)
|
||||
{
|
||||
source->attackCost = source->attackCostBackup;
|
||||
if(pw)
|
||||
source->attackPlaneswalkerCost = source->attackPlaneswalkerCostBackup;
|
||||
MTGAbility::Update(dt);
|
||||
}
|
||||
}
|
||||
|
||||
int AAttackSetCost::addToGame()
|
||||
{
|
||||
WParsedInt attackcost(number, NULL, source);
|
||||
source->attackCost += attackcost.getValue();
|
||||
source->attackCostBackup += attackcost.getValue();
|
||||
if(pw)
|
||||
{
|
||||
source->attackPlaneswalkerCost += attackcost.getValue();
|
||||
source->attackPlaneswalkerCostBackup += attackcost.getValue();
|
||||
}
|
||||
|
||||
return MTGAbility::addToGame();
|
||||
}
|
||||
|
||||
int AAttackSetCost::destroy()
|
||||
{
|
||||
|
||||
WParsedInt attackcost(number, NULL, source);
|
||||
source->attackCost -= attackcost.getValue();
|
||||
source->attackCostBackup -= attackcost.getValue();
|
||||
if(pw)
|
||||
{
|
||||
source->attackPlaneswalkerCost -= attackcost.getValue();
|
||||
source->attackPlaneswalkerCostBackup -= attackcost.getValue();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const string AAttackSetCost::getMenuText()
|
||||
{
|
||||
return "Attack Cost";
|
||||
}
|
||||
|
||||
AAttackSetCost * AAttackSetCost::clone() const
|
||||
{
|
||||
return NEW AAttackSetCost(*this);
|
||||
}
|
||||
|
||||
//ABlockSetCost
|
||||
ABlockSetCost::ABlockSetCost(GameObserver* observer, int _id, MTGCardInstance * _source, string number) :
|
||||
MTGAbility(observer, _id, _source), number(number)
|
||||
{
|
||||
}
|
||||
|
||||
void ABlockSetCost::Update(float dt)
|
||||
{
|
||||
if(game->getCurrentGamePhase() != MTG_PHASE_COMBATBLOCKERS)
|
||||
{
|
||||
source->blockCost = source->blockCostBackup;
|
||||
MTGAbility::Update(dt);
|
||||
}
|
||||
}
|
||||
|
||||
int ABlockSetCost::addToGame()
|
||||
{
|
||||
WParsedInt blockCost(number, NULL, source);
|
||||
source->blockCost += blockCost.getValue();
|
||||
source->blockCostBackup += blockCost.getValue();
|
||||
|
||||
return MTGAbility::addToGame();
|
||||
}
|
||||
|
||||
int ABlockSetCost::destroy()
|
||||
{
|
||||
|
||||
WParsedInt blockCost(number, NULL, source);
|
||||
source->blockCost -= blockCost.getValue();
|
||||
source->blockCostBackup -= blockCost.getValue();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const string ABlockSetCost::getMenuText()
|
||||
{
|
||||
return "Block Cost";
|
||||
}
|
||||
|
||||
ABlockSetCost * ABlockSetCost::clone() const
|
||||
{
|
||||
return NEW ABlockSetCost(*this);
|
||||
}
|
||||
|
||||
//a blink
|
||||
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)
|
||||
|
||||
@@ -248,7 +248,9 @@ LifeCost::LifeCost(TargetChooser *_tc)
|
||||
int LifeCost::canPay()
|
||||
{
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
if(_target->controller()->life <= 0 || _target->controller()->inPlay()->hasAbility(Constants::CANTCHANGELIFE))
|
||||
if (_target->controller()->life <= 0 || _target->controller()->inPlay()->hasAbility(Constants::CANTCHANGELIFE) ||
|
||||
_target->controller()->opponent()->game->battlefield->hasAbility(Constants::CANTPAYLIFE) ||
|
||||
_target->controller()->game->battlefield->hasAbility(Constants::CANTPAYLIFE))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -286,7 +288,9 @@ SpecificLifeCost::SpecificLifeCost(TargetChooser *_tc, int slc)
|
||||
int SpecificLifeCost::canPay()
|
||||
{
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
if(_target->controller()->life >= slc && !_target->controller()->inPlay()->hasAbility(Constants::CANTCHANGELIFE))
|
||||
if(_target->controller()->life >= slc && !_target->controller()->inPlay()->hasAbility(Constants::CANTCHANGELIFE) &&
|
||||
!_target->controller()->opponent()->game->battlefield->hasAbility(Constants::CANTPAYLIFE) &&
|
||||
!_target->controller()->game->battlefield->hasAbility(Constants::CANTPAYLIFE))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -334,7 +338,16 @@ LifeorManaCost::LifeorManaCost(TargetChooser *_tc, string manaType)
|
||||
int LifeorManaCost::canPay()
|
||||
{
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
if (_target->controller()->getManaPool()->canAfford(getManaCost()) || _target->controller()->life > 1)
|
||||
if ( _target->controller()->life <= 1 || _target->controller()->inPlay()->hasAbility(Constants::CANTCHANGELIFE) ||
|
||||
_target->controller()->opponent()->game->battlefield->hasAbility(Constants::CANTPAYLIFE) ||
|
||||
_target->controller()->game->battlefield->hasAbility(Constants::CANTPAYLIFE))
|
||||
{
|
||||
return _target->controller()->getManaPool()->canAfford(getManaCost());
|
||||
}
|
||||
else if((_target->controller()->life > 1 || _target->controller()->getManaPool()->canAfford(getManaCost())) &&
|
||||
(!_target->controller()->inPlay()->hasAbility(Constants::CANTCHANGELIFE) &&
|
||||
!_target->controller()->opponent()->game->battlefield->hasAbility(Constants::CANTPAYLIFE) &&
|
||||
!_target->controller()->game->battlefield->hasAbility(Constants::CANTPAYLIFE)))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -926,6 +939,9 @@ ExtraCost("Select creature to offer", _tc)
|
||||
|
||||
int Offering::canPay()
|
||||
{
|
||||
if (target && target->has(Constants::CANTBESACRIFIED))
|
||||
return 0;
|
||||
|
||||
if (target && (!source->controller()->getManaPool()->canAfford(source->getManaCost()->Diff(target->getManaCost()))))
|
||||
{
|
||||
tc->removeTarget(target);
|
||||
@@ -983,6 +999,13 @@ SacrificeCost::SacrificeCost(TargetChooser *_tc)
|
||||
{
|
||||
}
|
||||
|
||||
int SacrificeCost::canPay()
|
||||
{
|
||||
if (target && target->has(Constants::CANTBESACRIFIED))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SacrificeCost::doPay()
|
||||
{
|
||||
if (target)
|
||||
|
||||
@@ -687,6 +687,24 @@ void GameObserver::gameStateBasedEffects()
|
||||
card->myPair->myPair = NULL;
|
||||
card->myPair = NULL;
|
||||
}
|
||||
///clear imprints
|
||||
if(isInPlay(card) && card->imprintedCards.size())
|
||||
{
|
||||
for(size_t ic = 0; ic < card->imprintedCards.size(); ic++)
|
||||
{
|
||||
if(!isInExile(card->imprintedCards[ic]))
|
||||
{
|
||||
card->imprintG = 0;
|
||||
card->imprintU = 0;
|
||||
card->imprintR = 0;
|
||||
card->imprintB = 0;
|
||||
card->imprintW = 0;
|
||||
card->currentimprintName = "";
|
||||
card->imprintedNames.clear();
|
||||
card->imprintedCards.erase(card->imprintedCards.begin() + ic);
|
||||
}
|
||||
}
|
||||
}
|
||||
card->bypassTC = false; //turn off bypass
|
||||
////////////////////////////////////////////////////
|
||||
//Unattach Equipments that dont have valid targets//
|
||||
|
||||
@@ -1179,6 +1179,13 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
observer->addObserver(NEW MTGAttackRule(observer, -1));
|
||||
return NULL;
|
||||
}
|
||||
//this rule handles attacking cost ability during attacker phase
|
||||
found = s.find("attackcostrule");
|
||||
if(found != string::npos)
|
||||
{
|
||||
observer->addObserver(NEW MTGAttackCostRule(observer, -1));
|
||||
return NULL;
|
||||
}
|
||||
//this rule handles blocking ability during blocker phase
|
||||
found = s.find("blockrule");
|
||||
if(found != string::npos)
|
||||
@@ -1186,6 +1193,13 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
observer->addObserver(NEW MTGBlockRule(observer, -1));
|
||||
return NULL;
|
||||
}
|
||||
//this rule handles blocking cost ability during blocker phase
|
||||
found = s.find("blockcostrule");
|
||||
if(found != string::npos)
|
||||
{
|
||||
observer->addObserver(NEW MTGBlockCostRule(observer, -1));
|
||||
return NULL;
|
||||
}
|
||||
//this rule handles cards that have soulbond
|
||||
found = s.find("soulbondrule");
|
||||
if(found != string::npos)
|
||||
@@ -2361,6 +2375,15 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
}
|
||||
|
||||
//imprint
|
||||
found = s.find("imprint");
|
||||
if (found != string::npos)
|
||||
{
|
||||
MTGAbility * a = NEW AAImprint(observer, id, card, target);
|
||||
a->oneShot = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
//phaseout
|
||||
found = s.find("phaseout");
|
||||
if (found != string::npos)
|
||||
{
|
||||
@@ -2820,6 +2843,24 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
return NEW AReduceToAbility(observer, id, card,s.substr(9));
|
||||
}
|
||||
|
||||
//attack cost
|
||||
if (s.find("attackcost:") != string::npos)
|
||||
{
|
||||
return NEW AAttackSetCost(observer, id, card, s.substr(11));
|
||||
}
|
||||
|
||||
//attack cost + planeswalker
|
||||
if (s.find("attackpwcost:") != string::npos)
|
||||
{
|
||||
return NEW AAttackSetCost(observer, id, card, s.substr(13),true);
|
||||
}
|
||||
|
||||
//block cost
|
||||
if (s.find("blockcost:") != string::npos)
|
||||
{
|
||||
return NEW ABlockSetCost(observer, id, card, s.substr(10));
|
||||
}
|
||||
|
||||
//flanking
|
||||
if (s.find("flanker") != string::npos)
|
||||
{
|
||||
|
||||
@@ -100,8 +100,10 @@ void MTGCardInstance::copy(MTGCardInstance * card)
|
||||
setText(""); //The text is retrieved from the data anyways
|
||||
setName(data->name);
|
||||
|
||||
power = data->power;
|
||||
toughness = data->toughness;
|
||||
power = data->power;//layer 7a
|
||||
toughness = data->toughness;//layer 7a
|
||||
power += pbonus;//layer 7b
|
||||
toughness += tbonus;//layer 7b
|
||||
life = toughness;
|
||||
lifeOrig = life;
|
||||
magicText = data->magicText;
|
||||
@@ -206,6 +208,20 @@ void MTGCardInstance::initMTGCI()
|
||||
myPair = NULL;
|
||||
miracle = false;
|
||||
countTrini = 0;
|
||||
imprintedCards.clear();
|
||||
attackCost = 0;
|
||||
attackCostBackup = 0;
|
||||
attackPlaneswalkerCost = 0;
|
||||
attackPlaneswalkerCostBackup = 0;
|
||||
blockCost = 0;
|
||||
blockCostBackup = 0;
|
||||
imprintG = 0;
|
||||
imprintU = 0;
|
||||
imprintR = 0;
|
||||
imprintB = 0;
|
||||
imprintW = 0;
|
||||
currentimprintName = "";
|
||||
imprintedNames.clear();
|
||||
|
||||
for (int i = 0; i < ManaCost::MANA_PAID_WITH_SUSPEND +1; i++)
|
||||
alternateCostPaid[i] = 0;
|
||||
@@ -1525,12 +1541,13 @@ const string& MTGCardInstance::getSample()
|
||||
|
||||
int MTGCardInstance::stepPower(CombatStep step)
|
||||
{
|
||||
int damage = has(Constants::COMBATTOUGHNESS) ? toughness : power;
|
||||
switch (step)
|
||||
{
|
||||
case FIRST_STRIKE:
|
||||
case END_FIRST_STRIKE:
|
||||
if (has(Constants::FIRSTSTRIKE) || has(Constants::DOUBLESTRIKE))
|
||||
return MAX(0, power);
|
||||
return MAX(0, damage);
|
||||
else
|
||||
return 0;
|
||||
case DAMAGE:
|
||||
@@ -1539,7 +1556,7 @@ int MTGCardInstance::stepPower(CombatStep step)
|
||||
if (has(Constants::FIRSTSTRIKE) && !has(Constants::DOUBLESTRIKE))
|
||||
return 0;
|
||||
else
|
||||
return MAX(0, power);
|
||||
return MAX(0, damage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +154,10 @@ const char* Constants::MTGBasicAbilities[] = {
|
||||
"canplayfromexile",
|
||||
"libraryeater",
|
||||
"devoid",
|
||||
"cantchangelife"
|
||||
"cantchangelife",
|
||||
"combattoughness",
|
||||
"cantpaylife",
|
||||
"cantbesacrified"
|
||||
};
|
||||
|
||||
map<string,int> Constants::MTGBasicAbilitiesMap;
|
||||
|
||||
@@ -642,7 +642,7 @@ unsigned int MTGGameZone::countTotalManaSymbols(TargetChooser * tc, int color)
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int MTGGameZone::countDevotion(TargetChooser * tc, int color)
|
||||
unsigned int MTGGameZone::countDevotion(TargetChooser * tc, int color1, int color2)
|
||||
{
|
||||
if (!tc) {
|
||||
return 0;
|
||||
@@ -654,8 +654,13 @@ unsigned int MTGGameZone::countDevotion(TargetChooser * tc, int color)
|
||||
{
|
||||
if (tc->canTarget(cards[i], withoutProtections))
|
||||
{
|
||||
result += cards[i]->getManaCost()->getManaSymbolsHybridMerged(color);
|
||||
result += cards[i]->getManaCost()->getManaSymbolsHybridMerged(color1);
|
||||
}
|
||||
if (tc->canTarget(cards[i], withoutProtections))
|
||||
{
|
||||
result += cards[i]->getManaCost()->getManaSymbolsHybridMerged(color2);
|
||||
}
|
||||
result -= cards[i]->getManaCost()->countHybridsNoPhyrexian();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1348,12 +1348,154 @@ MTGOverloadRule * MTGOverloadRule::clone() const
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//ATTACK COST
|
||||
MTGAttackCostRule::MTGAttackCostRule(GameObserver* observer, int _id) :
|
||||
PermanentAbility(observer, _id)
|
||||
{
|
||||
aType = MTGAbility::ATTACK_COST;
|
||||
scost = "Pay to attack";
|
||||
}
|
||||
|
||||
int MTGAttackCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
|
||||
{
|
||||
|
||||
if (currentPhase == MTG_PHASE_COMBATATTACKERS && card->controller() == game->currentPlayer && card->controller() == game->currentlyActing())//on my turn and when I am the acting player.
|
||||
{
|
||||
if(card->isPhased)
|
||||
return 0;
|
||||
if(card->attackCost < 1)
|
||||
return 0;
|
||||
ManaCost * playerMana = card->controller()->getManaPool();
|
||||
ManaCost * attackcost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL));
|
||||
attackcost->add(0,card->attackCostBackup);
|
||||
if(attackcost->extraCosts)
|
||||
for(unsigned int i = 0; i < attackcost->extraCosts->costs.size();i++)
|
||||
{
|
||||
attackcost->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
scost = attackcost->getConvertedCost();
|
||||
if (playerMana->canAfford(attackcost))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MTGAttackCostRule::reactToClick(MTGCardInstance * card)
|
||||
{
|
||||
if (!isReactingToClick(card))
|
||||
return 0;
|
||||
Player * player = game->currentlyActing();
|
||||
ManaCost * attackcost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL));
|
||||
attackcost->add(0,card->attackCostBackup);
|
||||
ManaCost * playerMana = player->getManaPool();
|
||||
playerMana->pay(attackcost);//I think you can't pay partial cost to attack cost so you pay full (508.1i)
|
||||
card->attackCost = 0;
|
||||
card->attackPlaneswalkerCost = 0;
|
||||
return 1;
|
||||
/*
|
||||
508.1g: If any of the chosen creatures require paying costs to attack, the active player determines the total cost to attack.
|
||||
Costs may include paying mana, tapping permanents, sacrificing permanents, discarding cards, and so on. Once the total cost is determined, it becomes “locked in.”
|
||||
If effects would change the total cost after this time, ignore this change.
|
||||
508.1h: If any of the costs require mana, the active player then has a chance to activate mana abilities (see rule 605, “Mana Abilities”).
|
||||
508.1i: Once the player has enough mana in his or her mana pool, he or she pays all costs in any order. Partial payments are not allowed.
|
||||
*/
|
||||
}
|
||||
|
||||
ostream& MTGAttackCostRule::toString(ostream& out) const
|
||||
{
|
||||
out << "MTGAttackCostRule ::: (";
|
||||
return MTGAbility::toString(out) << ")";
|
||||
}
|
||||
|
||||
const string MTGAttackCostRule::getMenuText()
|
||||
{
|
||||
sprintf(menuText, "Pay to attack");
|
||||
return menuText;
|
||||
}
|
||||
|
||||
MTGAttackCostRule * MTGAttackCostRule::clone() const
|
||||
{
|
||||
return NEW MTGAttackCostRule(*this);
|
||||
}
|
||||
|
||||
//BLOCK COST
|
||||
MTGBlockCostRule::MTGBlockCostRule(GameObserver* observer, int _id) :
|
||||
PermanentAbility(observer, _id)
|
||||
{
|
||||
aType = MTGAbility::BLOCK_COST;
|
||||
scost = "Pay to block";
|
||||
}
|
||||
|
||||
int MTGBlockCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
|
||||
{
|
||||
if (currentPhase == MTG_PHASE_COMBATBLOCKERS && !game->isInterrupting
|
||||
&& card->controller() != game->currentPlayer
|
||||
)
|
||||
{
|
||||
if(card->isPhased)
|
||||
return 0;
|
||||
if(card->blockCost < 1)
|
||||
return 0;
|
||||
|
||||
ManaCost * playerMana = card->controller()->getManaPool();
|
||||
ManaCost * blockcost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL));
|
||||
blockcost->add(0,card->blockCostBackup);
|
||||
if(blockcost->extraCosts)
|
||||
for(unsigned int i = 0; i < blockcost->extraCosts->costs.size();i++)
|
||||
{
|
||||
blockcost->extraCosts->costs[i]->setSource(card);
|
||||
}
|
||||
scost = blockcost->getConvertedCost();
|
||||
if (playerMana->canAfford(blockcost))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MTGBlockCostRule::reactToClick(MTGCardInstance * card)
|
||||
{
|
||||
if (!isReactingToClick(card))
|
||||
return 0;
|
||||
Player * player = game->currentlyActing();
|
||||
ManaCost * blockcost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL));
|
||||
blockcost->add(0,card->blockCostBackup);
|
||||
ManaCost * playerMana = player->getManaPool();
|
||||
playerMana->pay(blockcost);//I think you can't pay partial cost to block cost so you pay full (509.1f)
|
||||
card->blockCost = 0;
|
||||
return 1;
|
||||
/*
|
||||
509.1d: If any of the chosen creatures require paying costs to block, the defending player determines the total cost to block.
|
||||
Costs may include paying mana, tapping permanents, sacrificing permanents, discarding cards, and so on.
|
||||
Once the total cost is determined, it becomes “locked in.” If effects would change the total cost after this time, ignore this change.
|
||||
509.1e: If any of the costs require mana, the defending player then has a chance to activate mana abilities (see rule 605, “Mana Abilities”).
|
||||
509.1f: Once the player has enough mana in his or her mana pool, he or she pays all costs in any order. Partial payments are not allowed.
|
||||
*/
|
||||
}
|
||||
|
||||
ostream& MTGBlockCostRule::toString(ostream& out) const
|
||||
{
|
||||
out << "MTGBlockCostRule ::: (";
|
||||
return MTGAbility::toString(out) << ")";
|
||||
}
|
||||
|
||||
const string MTGBlockCostRule::getMenuText()
|
||||
{
|
||||
sprintf(menuText, "Pay to block");
|
||||
return menuText;
|
||||
}
|
||||
|
||||
MTGBlockCostRule * MTGBlockCostRule::clone() const
|
||||
{
|
||||
return NEW MTGBlockCostRule(*this);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool MTGAttackRule::select(Target* t)
|
||||
{
|
||||
if (CardView* c = dynamic_cast<CardView*>(t))
|
||||
{
|
||||
MTGCardInstance * card = c->getCard();
|
||||
if (card->canAttack() && !card->isPhased)
|
||||
if (card->canAttack() && !card->isPhased && card->attackCost < 1)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -1377,7 +1519,7 @@ int MTGAttackRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
|
||||
return 0;
|
||||
if (card->isAttacker())
|
||||
return 1;
|
||||
if (card->canAttack())
|
||||
if (card->canAttack() && card->attackCost < 1)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -1453,7 +1595,7 @@ int MTGPlaneswalkerAttackRule::isReactingToClick(MTGCardInstance * card, ManaCos
|
||||
return 0;
|
||||
if (card->isAttacker())
|
||||
return 1;
|
||||
if (card->canAttack())
|
||||
if (card->canAttack() && card->attackPlaneswalkerCost < 1)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -1718,7 +1860,7 @@ int MTGBlockRule::receiveEvent(WEvent *e)
|
||||
{
|
||||
MTGCardInstance * card = z->cards[i];
|
||||
if ((card->defenser && !card->defenser->has(Constants::LURE))||!card->defenser)
|
||||
if(card->canBlock(lurer))
|
||||
if(card->canBlock(lurer) && card->blockCost < 1)
|
||||
card->setDefenser(lurer);
|
||||
//force a block on a lurer, the player has a chance to set his own choice on multiple lures
|
||||
//but this action can not be ignored.
|
||||
@@ -1736,7 +1878,7 @@ int MTGBlockRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
|
||||
&& card->controller() != game->currentPlayer
|
||||
)
|
||||
{
|
||||
if (card->canBlock() && !card->isPhased)
|
||||
if (card->canBlock() && !card->isPhased && card->blockCost < 1)
|
||||
{
|
||||
if(card->isDefenser())
|
||||
blockmenu = "Remove Blocker";
|
||||
|
||||
@@ -667,7 +667,7 @@ int ManaCost::getManaSymbolsHybridMerged(int color)
|
||||
int result = cost[color];
|
||||
for (size_t i = 0; i < hybrids.size(); ++i)
|
||||
{
|
||||
result = hybrids[i].getManaSymbolsHybridMerged(color);//removed +
|
||||
result += hybrids[i].getManaSymbolsHybridMerged(color);
|
||||
}
|
||||
if (extraCosts && extraCosts->costs.size())
|
||||
{
|
||||
@@ -683,6 +683,14 @@ int ManaCost::getManaSymbolsHybridMerged(int color)
|
||||
return result;
|
||||
}
|
||||
|
||||
int ManaCost::countHybridsNoPhyrexian()
|
||||
{
|
||||
int result = 0;
|
||||
for (size_t i = 0; i < hybrids.size(); i++)
|
||||
result ++;
|
||||
return result;
|
||||
}
|
||||
|
||||
int ManaCost::parseManaSymbol(char symbol)
|
||||
{
|
||||
switch (symbol)
|
||||
|
||||
@@ -253,7 +253,9 @@ bool Player::hasPossibleAttackers()
|
||||
for (int j = 0; j < nbcards; ++j)
|
||||
{
|
||||
MTGCardInstance * c = z->cards[j];
|
||||
if (c->canAttack())
|
||||
if (!c->isTapped() &&
|
||||
!c->hasSummoningSickness() &&
|
||||
c->isCreature())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user