- refactor of MTGRules.cpp (buyback/flashback/retrace/alternative).
This change has been reviewed by myself, Wil, and Mike. The test suite passes.
More cleanup can be done, I will work on that later on.
This commit is contained in:
wagic.the.homebrew@gmail.com
2011-01-21 10:27:45 +00:00
parent b6713c02ec
commit 6d3d4c1792
6 changed files with 204 additions and 597 deletions
+1 -2
View File
@@ -45,8 +45,7 @@ class MTGCardInstance: public CardPrimitive, public MTGCard, public Damageable {
Pos* view;
int X;
int XX;
int boughtback;
int flashedback;
int alternateCostPaid[ManaCost::MANA_PAID_WITH_RETRACE + 1];
int paymenttype;
int frozen;
int sunburst;
+8 -3
View File
@@ -8,6 +8,7 @@
#include "Counters.h"
#include "WEvent.h"
#include "CardSelector.h"
#include "ManaCost.h"
class OtherAbilitiesEventReceiver: public MTGAbility
{
@@ -37,7 +38,11 @@ class MTGAlternativeCostRule: public MTGAbility
{
public:
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
int isReactingToClick(MTGCardInstance * card, ManaCost * mana, ManaCost *alternateManaCost);
int reactToClick(MTGCardInstance * card, ManaCost * alternateManaCost, int paymentType = ManaCost::MANA_PAID);
int reactToClick(MTGCardInstance * card);
int testDestroy();
virtual ostream& toString(ostream& out) const;
MTGAlternativeCostRule(int _id);
@@ -48,7 +53,7 @@ public:
virtual MTGAlternativeCostRule * clone() const;
};
class MTGBuyBackRule: public MTGAbility
class MTGBuyBackRule: public MTGAlternativeCostRule
{
public:
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
@@ -63,7 +68,7 @@ public:
virtual MTGBuyBackRule * clone() const;
};
class MTGFlashBackRule: public MTGAbility
class MTGFlashBackRule: public MTGAlternativeCostRule
{
public:
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
@@ -78,7 +83,7 @@ public:
virtual MTGFlashBackRule * clone() const;
};
class MTGRetraceRule: public MTGAbility
class MTGRetraceRule: public MTGAlternativeCostRule
{
public:
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
+1
View File
@@ -21,6 +21,7 @@ class ManaCost{
public:
enum{
MANA_UNPAID = 0,
MANA_PAID = 1,
MANA_PAID_WITH_KICKER = 2,
MANA_PAID_WITH_ALTERNATIVE = 3,
+2 -2
View File
@@ -2827,11 +2827,11 @@ void AbilityFactory::addAbilities(int _id, Spell * spell)
if (card->hasType("instant") || card->hasType("sorcery"))
{
MTGPlayerCards * zones = card->controller()->game;
if (card->boughtback > 0)
if (card->alternateCostPaid[ManaCost::MANA_PAID_WITH_BUYBACK] > 0)
{
zones->putInZone(card, zones->stack, zones->hand);
}
else if (card->flashedback > 0)
else if (card->alternateCostPaid[ManaCost::MANA_PAID_WITH_FLASHBACK] > 0)
{
zones->putInZone(card, zones->stack, zones->exile);
}
+4 -2
View File
@@ -122,8 +122,10 @@ void MTGCardInstance::initMTGCI()
notblocked = 0;
sunburst = NULL;
equipment = NULL;
boughtback = 0;
flashedback = 0;
for (int i = 0; i < ManaCost::MANA_PAID_WITH_RETRACE +1; i++)
alternateCostPaid[i] = 0;
paymenttype = MTGAbility::PUT_INTO_PLAY;
reduxamount = 0;
summoningSickness = 1;
+101 -501
View File
@@ -7,7 +7,7 @@
#include "GameOptions.h"
MTGPutInPlayRule::MTGPutInPlayRule(int _id) :
MTGAbility(_id, NULL)
MTGAbility(_id, NULL)
{
aType = MTGAbility::PUT_INTO_PLAY;
}
@@ -229,20 +229,27 @@ MTGPutInPlayRule * MTGPutInPlayRule::clone() const
//-------------------------------------------------------------------------
MTGAlternativeCostRule::MTGAlternativeCostRule(int _id) :
MTGAbility(_id, NULL)
MTGAbility(_id, NULL)
{
aType = MTGAbility::ALTERNATIVE_COST;
}
int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
{
ManaCost * alternateCost = card->getManaCost()->alternative;
if (!game->currentlyActing()->game->hand->hasCard(card))
return 0;
return isReactingToClick( card, mana, alternateCost );
}
int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana, ManaCost *alternateManaCost)
{
Player * player = game->currentlyActing();
Player * currentPlayer = game->currentPlayer;
if (!player->game->hand->hasCard(card))
return 0;
if (!card->getManaCost()->alternative)
if (!alternateManaCost)
return 0;
if (card->hasType("land"))
{
if (player == currentPlayer && currentPlayer->canPutLandsIntoPlay
@@ -251,14 +258,13 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
)
return 1;
}
else if ((card->hasType("instant")) || card->has(Constants::FLASH) || (player == currentPlayer
&& !game->isInterrupting
else if ((card->hasType("instant")) || card->has(Constants::FLASH)
|| (player == currentPlayer && !game->isInterrupting
&& (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN
|| game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))
)
{
ManaCost * playerMana = player->getManaPool();
ManaCost * alternative = card->getManaCost()->alternative;
#ifdef WIN32
ManaCost * cost = card->getManaCost();
@@ -292,7 +298,7 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
return 0;
}
//cost of card.
if (alternative && playerMana->canAfford(alternative))
if (alternateManaCost && playerMana->canAfford(alternateManaCost))
{
return 1;
}
@@ -302,99 +308,95 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card)
{
if (!isReactingToClick(card))
if ( !isReactingToClick(card))
return 0;
ManaCost *alternateCost = card->getManaCost()->alternative;
Player * player = game->currentlyActing();
ManaCost * playerMana = player->getManaPool();
if (playerMana->canAfford( alternateCost ) )
card->paymenttype = MTGAbility::ALTERNATIVE_COST;
return reactToClick(card, card->getManaCost()->alternative, ManaCost::MANA_PAID_WITH_ALTERNATIVE);
}
int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alternateCost, int alternateCostType){
Player * player = game->currentlyActing();
ManaCost * cost = card->getManaCost();
ManaCost * alternative = card->getManaCost()->alternative;
ManaCost * playerMana = player->getManaPool();
//this handles extra cost payments at the moment a card is played.
if (playerMana->canAfford(alternative))
if (playerMana->canAfford(alternateCost))
{
if (cost->alternative->isExtraPaymentSet())
if (alternateCost->isExtraPaymentSet() )
{
card->paymenttype = MTGAbility::ALTERNATIVE_COST;
if (!game->targetListIsSet(card))
{
return 0;
}
}
else
{
cost->alternative->setExtraCostsAction(this, card);
game->mExtraPayment = cost->alternative->extraCosts;
card->paymenttype = MTGAbility::ALTERNATIVE_COST;
alternateCost->setExtraCostsAction(this, card);
game->mExtraPayment = alternateCost->extraCosts;
return 0;
}
}
//------------------------------------------------------------------------
ManaCost * previousManaPool = NEW ManaCost(player->getManaPool());
int payResult = player->getManaPool()->pay(card->getManaCost()->alternative);
card->getManaCost()->alternative->doPayExtra();
payResult = ManaCost::MANA_PAID_WITH_ALTERNATIVE;
//if alternative has a extra payment thats set, this code pays it.the if statement is 100% needed as it would cause a crash on cards that dont have the alternative cost.
if (alternative)
ManaCost * previousManaPool = NEW ManaCost(playerMana);
int payResult = playerMana->pay(alternateCost);
alternateCost->doPayExtra();
payResult = alternateCostType;
//if alternate cost has a extra payment thats set, this code pays it.
// the if statement is 100% needed as it would cause a crash on cards that dont have the BuyBack cost.
if (alternateCost)
{
card->getManaCost()->alternative->doPayExtra();
alternateCost->doPayExtra();
}
//---------------------------------------------------------------------------
ManaCost * spellCost = previousManaPool->Diff(player->getManaPool());
delete previousManaPool;
Spell * spell = NULL;
card->alternateCostPaid[alternateCostType] = 1;
if (card->hasType("land"))
{
MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->temp);
Spell * spell = NEW Spell(copy);
spell = NEW Spell(copy);
copy->alternateCostPaid[alternateCostType] = 1;
spell->resolve();
delete spellCost;
delete spell;
SAFE_DELETE(spell);
player->landsPlayerCanStillPlay--;
payResult = ManaCost::MANA_PAID_WITH_ALTERNATIVE;
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 1);
payResult = alternateCostType;
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, NULL, payResult, 1);
}
else
{
Spell * spell = NULL;
MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->stack);
if (game->targetChooser)
{
ManaCost *spellCost = previousManaPool->Diff(player->getManaPool());
MTGCardInstance * copy = player->game->putInZone(card, player->game->graveyard, player->game->stack);
copy->alternateCostPaid[alternateCostType] = 1;
spell = game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, spellCost, payResult, 0);
game->targetChooser = NULL;
player->castedspellsthisturn += 1;
player->opponent()->castedspellsthisturn += 1;
if (player->onlyonecast == true || player->onlyoneinstant == true)
{
player->castcount += 1;
}
}
else
{
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 0);
player->castedspellsthisturn += 1;
player->opponent()->castedspellsthisturn += 1;
if (player->onlyonecast == true || player->onlyoneinstant == true)
{
player->castcount += 1;
}
}
if (card->has(Constants::STORM))
{
int storm = player->castedspellsthisturn;
ManaCost * spellCost = player->getManaPool();
for (int i = storm; i > 1; i--)
{
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 1);
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, playerMana, payResult, 1);
}
}//end of storm
if (!card->has(Constants::STORM))
else
{
copy->X = spell->computeX(copy);
copy->XX = spell->computeXX(copy);
}
}
SAFE_DELETE(previousManaPool);
return 1;
}
//The Put into play rule is never destroyed
int MTGAlternativeCostRule::testDestroy()
{
@@ -421,174 +423,33 @@ MTGAlternativeCostRule * MTGAlternativeCostRule::clone() const
//buyback follows its own resolving rules
MTGBuyBackRule::MTGBuyBackRule(int _id) :
MTGAbility(_id, NULL)
MTGAlternativeCostRule(_id)
{
aType = MTGAbility::BUYBACK_COST;
}
int MTGBuyBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
{
Player * player = game->currentlyActing();
Player * currentPlayer = game->currentPlayer;
if (!player->game->hand->hasCard(card))
return 0;
if (!card->getManaCost()->BuyBack)
return 0;
if (card->hasType("land"))
{
if (player == currentPlayer && currentPlayer->canPutLandsIntoPlay
&& (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN
|| game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN)
)
{
return 1;
}
}
else if ((card->hasType("instant")) || card->has(Constants::FLASH) || (player == currentPlayer && !game->isInterrupting
&& (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN || game->currentGamePhase
== Constants::MTG_PHASE_SECONDMAIN)))
{
ManaCost * playerMana = player->getManaPool();
ManaCost * BuyBack = card->getManaCost()->BuyBack;
#ifdef WIN32
ManaCost * cost = card->getManaCost();
cost->Dump();
#endif
if (player->castrestrictedspell == true && !card->hasType("land"))
{
return 0;
}
if (player->onlyonecast == true && player->castcount >= 1)
{
return 0;
}
if (player->nospellinstant == true)
{
return 0;
}
if (player->onlyoneinstant == true)
{
if (player->castcount >= 1)
{
return 0;
}
}
if (player->nocreatureinstant == true && card->hasType("creature"))
{
return 0;
}
if (player->castrestrictedcreature == true && card->hasType("creature"))
{
return 0;
}
//cost of card.
if (BuyBack && playerMana->canAfford(BuyBack))
{
return 1;
}
}
return 0;//dont play if you cant afford it.
return MTGAlternativeCostRule::isReactingToClick( card, mana, card->getManaCost()->BuyBack );
}
int MTGBuyBackRule::reactToClick(MTGCardInstance * card)
{
if (!isReactingToClick(card))
return 0;
Player * player = game->currentlyActing();
ManaCost * cost = card->getManaCost();
ManaCost * BuyBack = card->getManaCost()->BuyBack;
ManaCost * playerMana = player->getManaPool();
ManaCost * playerMana = game->currentlyActing()->getManaPool();
ManaCost * alternateCost = card->getManaCost()->BuyBack;
//this handles extra cost payments at the moment a card is played.
if (playerMana->canAfford(BuyBack))
{
if (cost->BuyBack->isExtraPaymentSet())
{
if (playerMana->canAfford(alternateCost))
card->paymenttype = MTGAbility::BUYBACK_COST;
if (!game->targetListIsSet(card))
{
return 0;
}
}
else
{
cost->BuyBack->setExtraCostsAction(this, card);
game->mExtraPayment = cost->BuyBack->extraCosts;
card->paymenttype = MTGAbility::BUYBACK_COST;
return 0;
}
}
//------------------------------------------------------------------------
ManaCost * previousManaPool = NEW ManaCost(player->getManaPool());
int payResult = player->getManaPool()->pay(card->getManaCost()->BuyBack);
card->getManaCost()->doPayExtra();
payResult = ManaCost::MANA_PAID_WITH_BUYBACK;
//if BuyBack has a extra payment thats set, this code pays it.the if statement is 100% needed as it would cause a crash on cards that dont have the BuyBack cost.
if (BuyBack)
{
card->getManaCost()->BuyBack->doPayExtra();
}
//---------------------------------------------------------------------------
ManaCost * spellCost = previousManaPool->Diff(player->getManaPool());
card->boughtback = 1;
delete previousManaPool;
if (card->hasType("land"))
{
MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->temp);
Spell * spell = NEW Spell(copy);
copy->boughtback = 1;
spell->resolve();
delete spellCost;
delete spell;
player->landsPlayerCanStillPlay--;
payResult = ManaCost::MANA_PAID_WITH_BUYBACK;
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 1);
}
else
{
Spell * spell = NULL;
card->boughtback = 1;
MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->stack);
copy->boughtback = 1;
if (game->targetChooser)
{
spell = game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, spellCost, payResult, 0);
game->targetChooser = NULL;
player->castedspellsthisturn += 1;
player->opponent()->castedspellsthisturn += 1;
if (player->onlyonecast == true || player->onlyoneinstant == true)
{
player->castcount += 1;
}
}
else
{
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 0);
player->castedspellsthisturn += 1;
player->opponent()->castedspellsthisturn += 1;
if (player->onlyonecast == true || player->onlyoneinstant == true)
{
player->castcount += 1;
}
}
if (card->has(Constants::STORM))
{
int storm = player->castedspellsthisturn;
ManaCost * spellCost = player->getManaPool();
for (int i = storm; i > 1; i--)
{
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 1);
}
}//end of storm
if (!card->has(Constants::STORM))
{
copy->X = spell->computeX(copy);
copy->XX = spell->computeXX(copy);
}
}
return MTGAlternativeCostRule::reactToClick(card, alternateCost, ManaCost::MANA_PAID_WITH_BUYBACK);
return 1;
}
//The Put into play rule is never destroyed
@@ -616,166 +477,30 @@ MTGBuyBackRule * MTGBuyBackRule::clone() const
//-------------------------------------------------------------------------
//flashback follows its own resolving rules
MTGFlashBackRule::MTGFlashBackRule(int _id) :
MTGAbility(_id, NULL)
MTGAlternativeCostRule(_id)
{
aType = MTGAbility::FLASHBACK_COST;
}
int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
{
Player * player = game->currentlyActing();
Player * currentPlayer = game->currentPlayer;
if (!player->game->graveyard->hasCard(card))
return 0;
if (!card->getManaCost()->FlashBack)
return 0;
if ((card->hasType("instant")) || card->has(Constants::FLASH)
|| (player == currentPlayer && !game->isInterrupting
&& (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN
|| game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))
)
{
ManaCost * FlashBack = card->getManaCost()->FlashBack;
ManaCost * playerMana = player->getManaPool();
#ifdef WIN32
ManaCost * cost = card->getManaCost();
cost->Dump();
#endif
if (player->castrestrictedspell == true && !card->hasType("land"))
{
return 0;
}
if (player->onlyonecast == true && player->castcount >= 1)
{
return 0;
}
if (player->nospellinstant == true)
{
return 0;
}
if (player->onlyoneinstant == true)
{
if (player->castcount >= 1)
{
return 0;
}
}
if (player->nocreatureinstant == true && card->hasType("creature"))
{
return 0;
}
if (player->castrestrictedcreature == true && card->hasType("creature"))
{
return 0;
}
//cost of card.
if (FlashBack && playerMana->canAfford(FlashBack))
{
return 1;
}
}
return 0;//dont play if you cant afford it.
return MTGAlternativeCostRule::isReactingToClick(card, mana, card->getManaCost()->FlashBack );
}
int MTGFlashBackRule::reactToClick(MTGCardInstance * card)
{
ManaCost * alternateCost = card->getManaCost()->FlashBack;
ManaCost * playerMana = game->currentlyActing()->getManaPool();
if (!isReactingToClick(card))
return 0;
Player * player = game->currentlyActing();
ManaCost * cost = card->getManaCost();
ManaCost * FlashBack = card->getManaCost()->FlashBack;
ManaCost * playerMana = player->getManaPool();
//this handles extra cost payments at the moment a card is played.
if (playerMana->canAfford(FlashBack))
{
if (cost->FlashBack->isExtraPaymentSet())
{
card->paymenttype = MTGAbility::FLASHBACK_COST;
if (!game->targetListIsSet(card))
{
return 0;
}
}
else
{
cost->FlashBack->setExtraCostsAction(this, card);
game->mExtraPayment = cost->FlashBack->extraCosts;
card->paymenttype = MTGAbility::FLASHBACK_COST;
return 0;
}
}
//------------------------------------------------------------------------
ManaCost * previousManaPool = NEW ManaCost(player->getManaPool());
int payResult = player->getManaPool()->pay(card->getManaCost()->FlashBack);
card->getManaCost()->doPayExtra();
payResult = ManaCost::MANA_PAID_WITH_FLASHBACK;
//if flashBack has a extra payment thats set, this code pays it.the if statement is 100% needed as it would cause a crash on cards that dont have the flashBack cost.
if (FlashBack)
{
card->getManaCost()->FlashBack->doPayExtra();
}
//---------------------------------------------------------------------------
ManaCost * spellCost = previousManaPool->Diff(player->getManaPool());
card->flashedback = 1;
delete previousManaPool;
if (card->hasType("land"))
{
MTGCardInstance * copy = player->game->putInZone(card, player->game->graveyard, player->game->temp);
Spell * spell = NEW Spell(copy);
copy->flashedback = 1;
spell->resolve();
delete spellCost;
delete spell;
player->landsPlayerCanStillPlay--;
payResult = ManaCost::MANA_PAID_WITH_FLASHBACK;
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 1);
}
else
{
Spell * spell = NULL;
card->flashedback = 1;
MTGCardInstance * copy = player->game->putInZone(card, player->game->graveyard, player->game->stack);
copy->flashedback = 1;
if (game->targetChooser)
{
spell = game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, spellCost, payResult, 0);
game->targetChooser = NULL;
player->castedspellsthisturn += 1;
player->opponent()->castedspellsthisturn += 1;
if (player->onlyonecast == true || player->onlyoneinstant == true)
{
player->castcount += 1;
}
}
else
{
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 0);
player->castedspellsthisturn += 1;
player->opponent()->castedspellsthisturn += 1;
if (player->onlyonecast == true || player->onlyoneinstant == true)
{
player->castcount += 1;
}
}
if (card->has(Constants::STORM))
{
int storm = player->castedspellsthisturn;
ManaCost * spellCost = player->getManaPool();
for (int i = storm; i > 1; i--)
{
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 1);
}
}//end of storm
if (!card->has(Constants::STORM))
{
copy->X = spell->computeX(copy);
copy->XX = spell->computeXX(copy);
}
}
if ( playerMana->canAfford(alternateCost) )
card->paymenttype = MTGAbility::FLASHBACK_COST;
return MTGAlternativeCostRule::reactToClick(card, alternateCost, ManaCost::MANA_PAID_WITH_FLASHBACK);
return 1;
}
//The Put into play rule is never destroyed
@@ -803,164 +528,39 @@ MTGFlashBackRule * MTGFlashBackRule::clone() const
//retrace
MTGRetraceRule::MTGRetraceRule(int _id) :
MTGAbility(_id, NULL)
MTGAlternativeCostRule(_id)
{
aType = MTGAbility::RETRACE_COST;
}
int MTGRetraceRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
{
Player * player = game->currentlyActing();
Player * currentPlayer = game->currentPlayer;
ManaCost * alternateManaCost = card->getManaCost()->Retrace;
if (!player->game->graveyard->hasCard(card))
return 0;
if (!card->getManaCost()->Retrace)
return 0;
if ((card->hasType("instant")) || card->has(Constants::FLASH)
|| (player == currentPlayer && !game->isInterrupting
&& (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN
|| game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))
)
{
ManaCost * playerMana = player->getManaPool();
ManaCost * Retrace = card->getManaCost()->Retrace;
#ifdef WIN32
ManaCost * cost = card->getManaCost();
cost->Dump();
#endif
if (player->castrestrictedspell == true && !card->hasType("land"))
{
return 0;
}
if (player->onlyonecast == true && player->castcount >= 1)
{
return 0;
}
if (player->nospellinstant == true)
{
return 0;
}
if (player->onlyoneinstant == true)
{
if (player->castcount >= 1)
{
return 0;
}
}
if (player->nocreatureinstant == true && card->hasType("creature"))
{
return 0;
}
if (player->castrestrictedcreature == true && card->hasType("creature"))
{
return 0;
}
//cost of card.
if (Retrace && playerMana->canAfford(Retrace))
{
return 1;
}
}
return 0;//dont play if you cant afford it.
return MTGAlternativeCostRule::isReactingToClick( card, mana, alternateManaCost );
}
int MTGRetraceRule::reactToClick(MTGCardInstance * card)
{
if (!isReactingToClick(card))
return 0;
Player * player = game->currentlyActing();
ManaCost * cost = card->getManaCost();
ManaCost * Retrace = card->getManaCost()->Retrace;
ManaCost * playerMana = player->getManaPool();
ManaCost * playerMana = game->currentlyActing()->getManaPool();
ManaCost * alternateCost = card->getManaCost()->Retrace;
//this handles extra cost payments at the moment a card is played.
if (playerMana->canAfford(Retrace))
{
if (cost->Retrace->isExtraPaymentSet())
{
if (playerMana->canAfford(alternateCost))
card->paymenttype = MTGAbility::RETRACE_COST;
if (!game->targetListIsSet(card))
{
return 0;
}
}
else
{
cost->Retrace->setExtraCostsAction(this, card);
game->mExtraPayment = cost->Retrace->extraCosts;
card->paymenttype = MTGAbility::RETRACE_COST;
;
return 0;
}
}
//------------------------------------------------------------------------
ManaCost * previousManaPool = NEW ManaCost(player->getManaPool());
int payResult = player->getManaPool()->pay(card->getManaCost()->Retrace);
card->getManaCost()->doPayExtra();
payResult = ManaCost::MANA_PAID_WITH_RETRACE;
//if Retrace has a extra payment thats set, this code pays it.the if statement is 100% needed as it would cause a crash on cards that dont have the Retrace cost.
if (Retrace)
{
card->getManaCost()->Retrace->doPayExtra();
}
//---------------------------------------------------------------------------
ManaCost * spellCost = previousManaPool->Diff(player->getManaPool());
delete previousManaPool;
if (card->hasType("land"))
{
MTGCardInstance * copy = player->game->putInZone(card, player->game->graveyard, player->game->temp);
Spell * spell = NEW Spell(copy);
spell->resolve();
delete spellCost;
delete spell;
player->landsPlayerCanStillPlay--;
payResult = ManaCost::MANA_PAID_WITH_RETRACE;
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 1);
}
else
{
Spell * spell = NULL;
MTGCardInstance * copy = player->game->putInZone(card, player->game->graveyard, player->game->stack);
if (game->targetChooser)
{
spell = game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, spellCost, payResult, 0);
game->targetChooser = NULL;
player->castedspellsthisturn += 1;
player->opponent()->castedspellsthisturn += 1;
if (player->onlyonecast == true || player->onlyoneinstant == true)
{
player->castcount += 1;
}
}
else
{
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 0);
player->castedspellsthisturn += 1;
player->opponent()->castedspellsthisturn += 1;
if (player->onlyonecast == true || player->onlyoneinstant == true)
{
player->castcount += 1;
}
}
if (card->has(Constants::STORM))
{
int storm = player->castedspellsthisturn;
ManaCost * spellCost = player->getManaPool();
for (int i = storm; i > 1; i--)
{
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 1);
}
}//end of storm
if (!card->has(Constants::STORM))
{
copy->X = spell->computeX(copy);
copy->XX = spell->computeXX(copy);
}
}
return 1;
return MTGAlternativeCostRule::reactToClick(card, alternateCost, ManaCost::MANA_PAID_WITH_RETRACE);
}
//The Put into play rule is never destroyed
int MTGRetraceRule::testDestroy()
{
@@ -999,7 +599,7 @@ bool MTGAttackRule::greyout(Target* t)
}
MTGAttackRule::MTGAttackRule(int _id) :
MTGAbility(_id, NULL)
MTGAbility(_id, NULL)
{
aType = MTGAbility::MTG_ATTACK_RULE;
}
@@ -1081,7 +681,7 @@ MTGAttackRule * MTGAttackRule::clone() const
//this rules handles returning cards to combat triggers for activations.
MTGCombatTriggersRule::MTGCombatTriggersRule(int _id) :
MTGAbility(_id, NULL)
MTGAbility(_id, NULL)
{
aType = MTGAbility::MTG_COMBATTRIGGERS_RULE;
}
@@ -1195,7 +795,7 @@ MTGCombatTriggersRule * MTGCombatTriggersRule::clone() const
///------------
OtherAbilitiesEventReceiver::OtherAbilitiesEventReceiver(int _id) :
MTGAbility(_id, NULL)
MTGAbility(_id, NULL)
{
}
@@ -1232,7 +832,7 @@ OtherAbilitiesEventReceiver * OtherAbilitiesEventReceiver::clone() const
}
MTGBlockRule::MTGBlockRule(int _id) :
MTGAbility(_id, NULL)
MTGAbility(_id, NULL)
{
aType = MTGAbility::MTG_BLOCK_RULE;
}
@@ -1299,7 +899,7 @@ int MTGMomirRule::initialized = 0;
vector<int> MTGMomirRule::pool[20];
MTGMomirRule::MTGMomirRule(int _id, MTGAllCards * _collection) :
MTGAbility(_id, NULL)
MTGAbility(_id, NULL)
{
collection = _collection;
if (!initialized)
@@ -1540,7 +1140,7 @@ void HUDDisplay::Render()
}
}
HUDDisplay::HUDDisplay(int _id) :
MTGAbility(_id, NULL)
MTGAbility(_id, NULL)
{
timestamp = 0;
popdelay = 2;
@@ -1568,7 +1168,7 @@ HUDDisplay * HUDDisplay::clone() const
/* Persist */
MTGPersistRule::MTGPersistRule(int _id) :
MTGAbility(_id, NULL)
MTGAbility(_id, NULL)
{
}
;
@@ -1627,7 +1227,7 @@ MTGPersistRule * MTGPersistRule::clone() const
//unearth rule----------------------------------
//if the card leaves play, exile it instead.
MTGUnearthRule::MTGUnearthRule(int _id) :
MTGAbility(_id, NULL)
MTGAbility(_id, NULL)
{
}
;
@@ -1692,7 +1292,7 @@ MTGUnearthRule * MTGUnearthRule::clone() const
//this rule is for Affinity cards.
MTGAffinityRule::MTGAffinityRule(int _id) :
MTGAbility(_id, NULL)
MTGAbility(_id, NULL)
{
}
;
@@ -1976,7 +1576,7 @@ MTGAffinityRule * MTGAffinityRule::clone() const
//-------------------------------------------------------------------
MTGTokensCleanup::MTGTokensCleanup(int _id) :
MTGAbility(_id, NULL)
MTGAbility(_id, NULL)
{
}
@@ -2011,7 +1611,7 @@ MTGTokensCleanup * MTGTokensCleanup::clone() const
/* Legend Rule */
MTGLegendRule::MTGLegendRule(int _id) :
ListMaintainerAbility(_id)
ListMaintainerAbility(_id)
{
}
;
@@ -2068,7 +1668,7 @@ MTGLegendRule * MTGLegendRule::clone() const
/* Lifelink */
MTGLifelinkRule::MTGLifelinkRule(int _id) :
MTGAbility(_id, NULL)
MTGAbility(_id, NULL)
{
}
;
@@ -2108,7 +1708,7 @@ MTGLifelinkRule * MTGLifelinkRule::clone() const
/* Deathtouch */
MTGDeathtouchRule::MTGDeathtouchRule(int _id) :
MTGAbility(_id, NULL)
MTGAbility(_id, NULL)
{
}
;