- 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; Pos* view;
int X; int X;
int XX; int XX;
int boughtback; int alternateCostPaid[ManaCost::MANA_PAID_WITH_RETRACE + 1];
int flashedback;
int paymenttype; int paymenttype;
int frozen; int frozen;
int sunburst; int sunburst;
+8 -3
View File
@@ -8,6 +8,7 @@
#include "Counters.h" #include "Counters.h"
#include "WEvent.h" #include "WEvent.h"
#include "CardSelector.h" #include "CardSelector.h"
#include "ManaCost.h"
class OtherAbilitiesEventReceiver: public MTGAbility class OtherAbilitiesEventReceiver: public MTGAbility
{ {
@@ -37,7 +38,11 @@ class MTGAlternativeCostRule: public MTGAbility
{ {
public: public:
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL); 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 reactToClick(MTGCardInstance * card);
int testDestroy(); int testDestroy();
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
MTGAlternativeCostRule(int _id); MTGAlternativeCostRule(int _id);
@@ -48,7 +53,7 @@ public:
virtual MTGAlternativeCostRule * clone() const; virtual MTGAlternativeCostRule * clone() const;
}; };
class MTGBuyBackRule: public MTGAbility class MTGBuyBackRule: public MTGAlternativeCostRule
{ {
public: public:
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL); int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
@@ -63,7 +68,7 @@ public:
virtual MTGBuyBackRule * clone() const; virtual MTGBuyBackRule * clone() const;
}; };
class MTGFlashBackRule: public MTGAbility class MTGFlashBackRule: public MTGAlternativeCostRule
{ {
public: public:
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL); int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
@@ -78,7 +83,7 @@ public:
virtual MTGFlashBackRule * clone() const; virtual MTGFlashBackRule * clone() const;
}; };
class MTGRetraceRule: public MTGAbility class MTGRetraceRule: public MTGAlternativeCostRule
{ {
public: public:
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL); int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
+1
View File
@@ -21,6 +21,7 @@ class ManaCost{
public: public:
enum{ enum{
MANA_UNPAID = 0,
MANA_PAID = 1, MANA_PAID = 1,
MANA_PAID_WITH_KICKER = 2, MANA_PAID_WITH_KICKER = 2,
MANA_PAID_WITH_ALTERNATIVE = 3, 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")) if (card->hasType("instant") || card->hasType("sorcery"))
{ {
MTGPlayerCards * zones = card->controller()->game; 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); 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); zones->putInZone(card, zones->stack, zones->exile);
} }
+4 -2
View File
@@ -122,8 +122,10 @@ void MTGCardInstance::initMTGCI()
notblocked = 0; notblocked = 0;
sunburst = NULL; sunburst = NULL;
equipment = 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; paymenttype = MTGAbility::PUT_INTO_PLAY;
reduxamount = 0; reduxamount = 0;
summoningSickness = 1; summoningSickness = 1;
+84 -484
View File
@@ -236,13 +236,20 @@ MTGAlternativeCostRule::MTGAlternativeCostRule(int _id) :
int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) 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 * player = game->currentlyActing();
Player * currentPlayer = game->currentPlayer; Player * currentPlayer = game->currentPlayer;
if (!player->game->hand->hasCard(card))
return 0; if (!alternateManaCost)
if (!card->getManaCost()->alternative)
return 0; return 0;
if (card->hasType("land")) if (card->hasType("land"))
{ {
if (player == currentPlayer && currentPlayer->canPutLandsIntoPlay if (player == currentPlayer && currentPlayer->canPutLandsIntoPlay
@@ -251,14 +258,13 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
) )
return 1; return 1;
} }
else if ((card->hasType("instant")) || card->has(Constants::FLASH) || (player == currentPlayer else if ((card->hasType("instant")) || card->has(Constants::FLASH)
&& !game->isInterrupting || (player == currentPlayer && !game->isInterrupting
&& (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN && (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN
|| game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN)) || game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))
) )
{ {
ManaCost * playerMana = player->getManaPool(); ManaCost * playerMana = player->getManaPool();
ManaCost * alternative = card->getManaCost()->alternative;
#ifdef WIN32 #ifdef WIN32
ManaCost * cost = card->getManaCost(); ManaCost * cost = card->getManaCost();
@@ -292,7 +298,7 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
return 0; return 0;
} }
//cost of card. //cost of card.
if (alternative && playerMana->canAfford(alternative)) if (alternateManaCost && playerMana->canAfford(alternateManaCost))
{ {
return 1; return 1;
} }
@@ -304,97 +310,93 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card)
{ {
if ( !isReactingToClick(card)) if ( !isReactingToClick(card))
return 0; 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(); Player * player = game->currentlyActing();
ManaCost * cost = card->getManaCost();
ManaCost * alternative = card->getManaCost()->alternative;
ManaCost * playerMana = player->getManaPool(); ManaCost * playerMana = player->getManaPool();
//this handles extra cost payments at the moment a card is played. //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)) if (!game->targetListIsSet(card))
{
return 0; return 0;
} }
}
else else
{ {
cost->alternative->setExtraCostsAction(this, card); alternateCost->setExtraCostsAction(this, card);
game->mExtraPayment = cost->alternative->extraCosts; game->mExtraPayment = alternateCost->extraCosts;
card->paymenttype = MTGAbility::ALTERNATIVE_COST;
return 0; return 0;
} }
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
ManaCost * previousManaPool = NEW ManaCost(player->getManaPool()); ManaCost * previousManaPool = NEW ManaCost(playerMana);
int payResult = player->getManaPool()->pay(card->getManaCost()->alternative); int payResult = playerMana->pay(alternateCost);
card->getManaCost()->alternative->doPayExtra(); alternateCost->doPayExtra();
payResult = ManaCost::MANA_PAID_WITH_ALTERNATIVE; payResult = alternateCostType;
//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 alternate cost has a extra payment thats set, this code pays it.
if (alternative) // 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()); Spell * spell = NULL;
delete previousManaPool; card->alternateCostPaid[alternateCostType] = 1;
if (card->hasType("land")) if (card->hasType("land"))
{ {
MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->temp); 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(); spell->resolve();
delete spellCost; SAFE_DELETE(spell);
delete spell;
player->landsPlayerCanStillPlay--; player->landsPlayerCanStillPlay--;
payResult = ManaCost::MANA_PAID_WITH_ALTERNATIVE; payResult = alternateCostType;
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 1); spell = game->mLayers->stackLayer()->addSpell(copy, NULL, NULL, payResult, 1);
} }
else else
{ {
Spell * spell = NULL; ManaCost *spellCost = previousManaPool->Diff(player->getManaPool());
MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->stack); MTGCardInstance * copy = player->game->putInZone(card, player->game->graveyard, player->game->stack);
if (game->targetChooser) copy->alternateCostPaid[alternateCostType] = 1;
{
spell = game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, spellCost, payResult, 0); spell = game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, spellCost, payResult, 0);
game->targetChooser = NULL; game->targetChooser = NULL;
player->castedspellsthisturn += 1; player->castedspellsthisturn += 1;
player->opponent()->castedspellsthisturn += 1; player->opponent()->castedspellsthisturn += 1;
if (player->onlyonecast == true || player->onlyoneinstant == true) if (player->onlyonecast == true || player->onlyoneinstant == true)
{
player->castcount += 1; 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)) if (card->has(Constants::STORM))
{ {
int storm = player->castedspellsthisturn; int storm = player->castedspellsthisturn;
ManaCost * spellCost = player->getManaPool();
for (int i = storm; i > 1; i--) 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 }//end of storm
if (!card->has(Constants::STORM)) else
{ {
copy->X = spell->computeX(copy); copy->X = spell->computeX(copy);
copy->XX = spell->computeXX(copy); copy->XX = spell->computeXX(copy);
} }
} }
SAFE_DELETE(previousManaPool);
return 1; return 1;
} }
//The Put into play rule is never destroyed //The Put into play rule is never destroyed
int MTGAlternativeCostRule::testDestroy() int MTGAlternativeCostRule::testDestroy()
{ {
@@ -421,174 +423,33 @@ MTGAlternativeCostRule * MTGAlternativeCostRule::clone() const
//buyback follows its own resolving rules //buyback follows its own resolving rules
MTGBuyBackRule::MTGBuyBackRule(int _id) : MTGBuyBackRule::MTGBuyBackRule(int _id) :
MTGAbility(_id, NULL) MTGAlternativeCostRule(_id)
{ {
aType = MTGAbility::BUYBACK_COST; aType = MTGAbility::BUYBACK_COST;
} }
int MTGBuyBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) int MTGBuyBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
{ {
Player * player = game->currentlyActing(); Player * player = game->currentlyActing();
Player * currentPlayer = game->currentPlayer;
if (!player->game->hand->hasCard(card)) if (!player->game->hand->hasCard(card))
return 0; return 0;
if (!card->getManaCost()->BuyBack) return MTGAlternativeCostRule::isReactingToClick( card, mana, 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.
} }
int MTGBuyBackRule::reactToClick(MTGCardInstance * card) int MTGBuyBackRule::reactToClick(MTGCardInstance * card)
{ {
if (!isReactingToClick(card)) if (!isReactingToClick(card))
return 0; return 0;
Player * player = game->currentlyActing();
ManaCost * cost = card->getManaCost(); ManaCost * playerMana = game->currentlyActing()->getManaPool();
ManaCost * BuyBack = card->getManaCost()->BuyBack; ManaCost * alternateCost = card->getManaCost()->BuyBack;
ManaCost * playerMana = player->getManaPool();
//this handles extra cost payments at the moment a card is played. //this handles extra cost payments at the moment a card is played.
if (playerMana->canAfford(BuyBack)) if (playerMana->canAfford(alternateCost))
{
if (cost->BuyBack->isExtraPaymentSet())
{
card->paymenttype = MTGAbility::BUYBACK_COST; 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;
} return MTGAlternativeCostRule::reactToClick(card, alternateCost, ManaCost::MANA_PAID_WITH_BUYBACK);
}
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;
} }
//The Put into play rule is never destroyed //The Put into play rule is never destroyed
@@ -616,166 +477,30 @@ MTGBuyBackRule * MTGBuyBackRule::clone() const
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
//flashback follows its own resolving rules //flashback follows its own resolving rules
MTGFlashBackRule::MTGFlashBackRule(int _id) : MTGFlashBackRule::MTGFlashBackRule(int _id) :
MTGAbility(_id, NULL) MTGAlternativeCostRule(_id)
{ {
aType = MTGAbility::FLASHBACK_COST; aType = MTGAbility::FLASHBACK_COST;
} }
int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
{ {
Player * player = game->currentlyActing(); Player * player = game->currentlyActing();
Player * currentPlayer = game->currentPlayer;
if (!player->game->graveyard->hasCard(card)) if (!player->game->graveyard->hasCard(card))
return 0; return 0;
if (!card->getManaCost()->FlashBack) return MTGAlternativeCostRule::isReactingToClick(card, mana, 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.
}
int MTGFlashBackRule::reactToClick(MTGCardInstance * card) int MTGFlashBackRule::reactToClick(MTGCardInstance * card)
{ {
ManaCost * alternateCost = card->getManaCost()->FlashBack;
ManaCost * playerMana = game->currentlyActing()->getManaPool();
if (!isReactingToClick(card)) if (!isReactingToClick(card))
return 0; 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 ( playerMana->canAfford(alternateCost) )
} card->paymenttype = MTGAbility::FLASHBACK_COST;
if (card->has(Constants::STORM))
{ return MTGAlternativeCostRule::reactToClick(card, alternateCost, ManaCost::MANA_PAID_WITH_FLASHBACK);
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;
} }
//The Put into play rule is never destroyed //The Put into play rule is never destroyed
@@ -803,163 +528,38 @@ MTGFlashBackRule * MTGFlashBackRule::clone() const
//retrace //retrace
MTGRetraceRule::MTGRetraceRule(int _id) : MTGRetraceRule::MTGRetraceRule(int _id) :
MTGAbility(_id, NULL) MTGAlternativeCostRule(_id)
{ {
aType = MTGAbility::RETRACE_COST; aType = MTGAbility::RETRACE_COST;
} }
int MTGRetraceRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) int MTGRetraceRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
{ {
Player * player = game->currentlyActing(); Player * player = game->currentlyActing();
Player * currentPlayer = game->currentPlayer; ManaCost * alternateManaCost = card->getManaCost()->Retrace;
if (!player->game->graveyard->hasCard(card)) if (!player->game->graveyard->hasCard(card))
return 0; 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 return MTGAlternativeCostRule::isReactingToClick( card, mana, alternateManaCost );
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.
} }
int MTGRetraceRule::reactToClick(MTGCardInstance * card) int MTGRetraceRule::reactToClick(MTGCardInstance * card)
{ {
if (!isReactingToClick(card)) if (!isReactingToClick(card))
return 0; return 0;
Player * player = game->currentlyActing();
ManaCost * cost = card->getManaCost(); ManaCost * playerMana = game->currentlyActing()->getManaPool();
ManaCost * Retrace = card->getManaCost()->Retrace; ManaCost * alternateCost = card->getManaCost()->Retrace;
ManaCost * playerMana = player->getManaPool();
//this handles extra cost payments at the moment a card is played. //this handles extra cost payments at the moment a card is played.
if (playerMana->canAfford(Retrace)) if (playerMana->canAfford(alternateCost))
{
if (cost->Retrace->isExtraPaymentSet())
{
card->paymenttype = MTGAbility::RETRACE_COST; 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;
} return MTGAlternativeCostRule::reactToClick(card, alternateCost, ManaCost::MANA_PAID_WITH_RETRACE);
}
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;
}
//The Put into play rule is never destroyed //The Put into play rule is never destroyed
int MTGRetraceRule::testDestroy() int MTGRetraceRule::testDestroy()