From 99da45f40073f806c02f7a5d2fb4d3c44e9138ee Mon Sep 17 00:00:00 2001 From: "omegablast2002@yahoo.com" Date: Fri, 10 Sep 2010 18:00:37 +0000 Subject: [PATCH] Added support for "buyback" and "flashback" with optional auto=buyback/flashback line support. --- projects/mtg/include/ActionStack.h | 2 + projects/mtg/include/AllAbilities.h | 2 + projects/mtg/include/MTGAbility.h | 5 + projects/mtg/include/MTGCardInstance.h | 3 + projects/mtg/include/MTGRules.h | 22 ++ projects/mtg/include/ManaCost.h | 7 +- projects/mtg/src/ActionStack.cpp | 9 +- projects/mtg/src/DuelLayers.cpp | 2 + projects/mtg/src/ExtraCost.cpp | 2 +- projects/mtg/src/GameObserver.cpp | 39 +++- projects/mtg/src/GameOptions.cpp | 2 +- projects/mtg/src/MTGAbility.cpp | 30 ++- projects/mtg/src/MTGCardInstance.cpp | 3 + projects/mtg/src/MTGDeck.cpp | 18 ++ projects/mtg/src/MTGRules.cpp | 266 ++++++++++++++++++++++++- projects/mtg/src/ManaCost.cpp | 16 ++ 16 files changed, 417 insertions(+), 11 deletions(-) diff --git a/projects/mtg/include/ActionStack.h b/projects/mtg/include/ActionStack.h index e5676e836..25b101278 100644 --- a/projects/mtg/include/ActionStack.h +++ b/projects/mtg/include/ActionStack.h @@ -89,6 +89,8 @@ class Spell: public Interruptible { void Render(); bool kickerWasPaid(); bool AlternativeWasPaid(); + bool BuyBackWasPaid(); + bool FlashBackWasPaid(); const string getDisplayName() const; virtual ostream& toString(ostream& out) const; MTGCardInstance * getNextCardTarget(MTGCardInstance * previous = 0); diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index a93508ca8..846d12502 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -2634,6 +2634,8 @@ public: _target->getManaCost()->add(type,amount); if(_target->getManaCost()->alternative > 0){ _target->getManaCost()->alternative->add(type,amount);} + if(_target->getManaCost()->BuyBack > 0){ + _target->getManaCost()->BuyBack->add(type,amount);} return MTGAbility::addToGame(); } AManaRedux * clone() const{ diff --git a/projects/mtg/include/MTGAbility.h b/projects/mtg/include/MTGAbility.h index 82824567d..bdd04067a 100644 --- a/projects/mtg/include/MTGAbility.h +++ b/projects/mtg/include/MTGAbility.h @@ -50,6 +50,8 @@ class MTGAbility: public ActionElement{ int forceDestroy; ManaCost * cost; ManaCost * alternative; + ManaCost * BuyBack; + ManaCost * FlashBack; Targetable * target; int aType; @@ -83,6 +85,9 @@ class MTGAbility: public ActionElement{ MOMIR = 6, MTG_BLOCK_RULE = 7, ALTERNATIVE_COST = 8, + BUYBACK_COST = 9, + FLASHBACK_COST = 10, + }; }; diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 4514da488..f3a8e36c0 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -44,6 +44,9 @@ class MTGCardInstance: public CardPrimitive, public MTGCard, public Damageable { MTGGameZone * currentZone; Pos* view; int X; + int boughtback; + int flashedback; + int paymenttype; int frozen; int regenerateTokens; int isToken; diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index cd46ac8af..61e09ba4c 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -39,6 +39,28 @@ class MTGAlternativeCostRule:public MTGAbility{ virtual MTGAlternativeCostRule * clone() const; }; +class MTGBuyBackRule:public MTGAbility{ + public: + int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL); + int reactToClick(MTGCardInstance * card); + int testDestroy(); + virtual ostream& toString(ostream& out) const; + MTGBuyBackRule(int _id); + const char * getMenuText(){return "Cast And Buy Back";} + virtual MTGBuyBackRule * clone() const; +}; + +class MTGFlashBackRule:public MTGAbility{ + public: + int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL); + int reactToClick(MTGCardInstance * card); + int testDestroy(); + virtual ostream& toString(ostream& out) const; + MTGFlashBackRule(int _id); + const char * getMenuText(){return "Flash Back";} + virtual MTGFlashBackRule * clone() const; +}; + class MTGAttackRule:public MTGAbility, public Limitor{ public: virtual bool select(Target*); diff --git a/projects/mtg/include/ManaCost.h b/projects/mtg/include/ManaCost.h index 76cd27256..f17eff491 100644 --- a/projects/mtg/include/ManaCost.h +++ b/projects/mtg/include/ManaCost.h @@ -23,11 +23,16 @@ class ManaCost{ enum{ MANA_PAID = 1, MANA_PAID_WITH_KICKER = 2, - MANA_PAID_WITH_ALTERNATIVE = 3 + MANA_PAID_WITH_ALTERNATIVE = 3, + MANA_PAID_WITH_BUYBACK = 4, + MANA_PAID_WITH_FLASHBACK = 5 + }; ExtraCosts * extraCosts; ManaCost * kicker; ManaCost * alternative; + ManaCost * BuyBack; + ManaCost * FlashBack; static ManaCost * parseManaCost(string value, ManaCost * _manacost = NULL, MTGCardInstance * c = NULL); virtual void init(); void x(); diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index a51e15dfa..0a483edf7 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -170,6 +170,14 @@ bool Spell::AlternativeWasPaid(){ return (payResult == ManaCost::MANA_PAID_WITH_ALTERNATIVE); } +bool Spell::BuyBackWasPaid(){ + return (payResult == ManaCost::MANA_PAID_WITH_BUYBACK); +} + +bool Spell::FlashBackWasPaid(){ + return (payResult == ManaCost::MANA_PAID_WITH_FLASHBACK); +} + const string Spell::getDisplayName() const { return source->getName(); } @@ -181,7 +189,6 @@ Spell::~Spell(){ int Spell::resolve(){ GameObserver * game = GameObserver::GetInstance(); - if (!source->hasType("instant") && !source->hasType("sorcery")){ Player * p = source->controller(); source = p->game->putInZone(source,from,p->game->battlefield); diff --git a/projects/mtg/src/DuelLayers.cpp b/projects/mtg/src/DuelLayers.cpp index 0d7a89f8f..c6e294ce9 100644 --- a/projects/mtg/src/DuelLayers.cpp +++ b/projects/mtg/src/DuelLayers.cpp @@ -22,6 +22,8 @@ void DuelLayers::init(){ //Add Magic Specific Rules action->Add(NEW MTGPutInPlayRule(-1)); action->Add(NEW MTGAlternativeCostRule(-1)); + action->Add(NEW MTGBuyBackRule(-1)); + action->Add(NEW MTGFlashBackRule(-1)); action->Add(NEW MTGAttackRule(-1)); action->Add(NEW MTGBlockRule(-1)); action->Add(NEW MTGLegendRule(-1)); diff --git a/projects/mtg/src/ExtraCost.cpp b/projects/mtg/src/ExtraCost.cpp index c1fa93335..fcace693b 100644 --- a/projects/mtg/src/ExtraCost.cpp +++ b/projects/mtg/src/ExtraCost.cpp @@ -292,7 +292,7 @@ int SacrificeCost::setPayment(MTGCardInstance * card){ if (result) { target = card; return result; - } + } } return 0; } diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 3ad19dd60..973047c55 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -478,7 +478,7 @@ void GameObserver::cardClick (MTGCardInstance * card, Targetable * object){ return; } - if (card){ + if (card && card->paymenttype <= 0){//card played as normal. /* Fix for Issue http://code.google.com/p/wagic/issues/detail?id=270 put into play is hopefully the only ability causing that kind of trouble @@ -492,7 +492,42 @@ void GameObserver::cardClick (MTGCardInstance * card, Targetable * object){ reaction = mLayers->actionLayer()->isReactingToClick(card); if (reaction == -1) mLayers->actionLayer()->reactToClick(card); - }else{ + } + /* added same fix for buyback and alternative cost, the varible "paymenttype = int" only serves one purpose, to tell this bug fix what menu item you clicked on...all alternative cost or play methods suffered from the fix because if the card contained "target=" it would automatically force the play method to putinplayrule...even charge you the original mana cost.*/ + else if (card && card->paymenttype == 1){//this is alternitive cost + if (targetChooser) { + MTGAbility * a = mLayers->actionLayer()->getAbility(MTGAbility::ALTERNATIVE_COST); + a->reactToClick(card); + return; + } + + reaction = mLayers->actionLayer()->isReactingToClick(card); + if (reaction == -1) mLayers->actionLayer()->reactToClick(card); + } +//-------------- + else if (card && card->paymenttype == 2){//this is buyback + if (targetChooser) { + MTGAbility * a = mLayers->actionLayer()->getAbility(MTGAbility::BUYBACK_COST); + a->reactToClick(card); + return; + } + + reaction = mLayers->actionLayer()->isReactingToClick(card); + if (reaction == -1) mLayers->actionLayer()->reactToClick(card); + } + //===================== + else if (card && card->paymenttype == 3){//this is Flashback + if (targetChooser) { + MTGAbility * a = mLayers->actionLayer()->getAbility(MTGAbility::FLASHBACK_COST); + a->reactToClick(card); + return; + } + + reaction = mLayers->actionLayer()->isReactingToClick(card); + if (reaction == -1) mLayers->actionLayer()->reactToClick(card); + } + //===================== + else{//this handles abilities on a menu...not just when card is being played reaction = mLayers->actionLayer()->isReactingToTargetClick(object); if (reaction == -1) mLayers->actionLayer()->reactToTargetClick(object); } diff --git a/projects/mtg/src/GameOptions.cpp b/projects/mtg/src/GameOptions.cpp index 7c70d6411..ea5bcfe12 100644 --- a/projects/mtg/src/GameOptions.cpp +++ b/projects/mtg/src/GameOptions.cpp @@ -280,7 +280,7 @@ bool GameOption::write(std::ofstream * file, string name){ GameOptions::GameOptions(string filename){ mFilename = filename; - load(); + GameOptions::load(); } int GameOptions::load(){ diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 141b386ad..2b5906194 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -353,6 +353,27 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG } return NULL; } + + //buyback cost + found = s.find("buyback "); + if (found == 0){ + if (spell && spell->BuyBackWasPaid()){ + string s1 = s.substr(found+7); + return parseMagicLine(s1,id,spell, card); + } + return NULL; + } + + //buyback cost + found = s.find("flashback "); + if (found == 0){ + if (spell && spell->FlashBackWasPaid()){ + string s1 = s.substr(found+7); + return parseMagicLine(s1,id,spell, card); + } + return NULL; + } + //When...comes into play, you may... found = s.find("may "); if (found == 0){ @@ -2048,7 +2069,14 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){ if (card->hasType("instant") || card->hasType("sorcery")){ MTGPlayerCards * zones = card->controller()->game; - zones->putInZone(card,zones->stack,zones->graveyard); + if(card->boughtback > 0){ + zones->putInZone(card,zones->stack,zones->hand); + } + else if(card->flashedback > 0){ + zones->putInZone(card,zones->stack,zones->exile); + } + else{ + zones->putInZone(card,zones->stack,zones->graveyard);} } diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index e6f9380a7..7adf7b3a2 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -98,6 +98,9 @@ void MTGCardInstance::initMTGCI(){ tapped = 0; untapping = 0; frozen = 0; + boughtback = 0; + flashedback = 0; + paymenttype = 0; summoningSickness = 1; preventable = 0; target = NULL; diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index 605002393..33678dcff 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -116,6 +116,24 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi std::transform(value.begin(), value.end(), value.begin(), ::tolower); cost->alternative = ManaCost::parseManaCost(value); } + break; + case 'b': //buyback + if (!primitive) primitive = NEW CardPrimitive(); + if (ManaCost * cost = primitive->getManaCost()) + { + string value = val; + std::transform(value.begin(), value.end(), value.begin(), ::tolower); + cost->BuyBack = ManaCost::parseManaCost(value); + } + break; + case 'f': //flashback + if (!primitive) primitive = NEW CardPrimitive(); + if (ManaCost * cost = primitive->getManaCost()) + { + string value = val; + std::transform(value.begin(), value.end(), value.begin(), ::tolower); + cost->FlashBack = ManaCost::parseManaCost(value); + } break; case 'i': //id diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index bcbfd5bfc..7e5aadd7c 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -4,6 +4,8 @@ #include "../include/Subtypes.h" #include "../include/GameOptions.h" + + MTGPutInPlayRule::MTGPutInPlayRule(int _id):MTGAbility(_id, NULL){ aType=MTGAbility::PUT_INTO_PLAY; } @@ -32,6 +34,7 @@ int cardsinhand = game->players[0]->game->hand->nb_cards; ManaCost * playerMana = player->getManaPool(); ManaCost * cost = card->getManaCost(); ManaCost * alternative = card->getManaCost()->alternative; + ManaCost * BuyBack = card->getManaCost()->BuyBack; #ifdef WIN32 cost->Dump(); @@ -72,7 +75,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card){ card->getManaCost()->doPayExtra(); ManaCost * spellCost = previousManaPool->Diff(player->getManaPool()); - + delete previousManaPool; if (card->hasType("land")){ MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->temp); @@ -94,6 +97,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card){ player->castedspellsthisturn += 1; if(player->onlyonecast > 0 || player->onlyoneinstant > 0){player->castcount += 1;} } + if(card->has(Constants::STORM)){ int storm = player->castedspellsthisturn; ManaCost * spellCost = player->getManaPool(); @@ -128,7 +132,6 @@ ostream& MTGPutInPlayRule::toString(ostream& out) const } //cast from anywhere possible with this?? - //Alternative cost rules //------------------------------------------------------------------------- //------------------------------------------------------------------------- @@ -179,19 +182,21 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card){ //this handles extra cost payments at the moment a card is played. if(playerMana->canAfford(alternative)){ if (cost->alternative->isExtraPaymentSet()){ + card->paymenttype = 1; if (!game->targetListIsSet(card)){ return 0; } }else{ cost->alternative->setExtraCostsAction(this, card); game->waitForExtraPayment = cost->alternative->extraCosts; + card->paymenttype = 1; return 0; } } //------------------------------------------------------------------------ ManaCost * previousManaPool = NEW ManaCost(player->getManaPool()); int payResult = player->getManaPool()->pay(card->getManaCost()->alternative); - card->getManaCost()->doPayExtra(); + 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){ @@ -259,11 +264,264 @@ ostream& MTGAlternativeCostRule::toString(ostream& out) const //------------------------------------------------------------------------- //------------------------------------------------------------------------- +//buyback follows its own resolving rules +MTGBuyBackRule::MTGBuyBackRule(int _id):MTGAbility(_id, NULL){ + aType=MTGAbility::BUYBACK_COST; +} +int MTGBuyBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){ +int cardsinhand = game->players[0]->game->hand->nb_cards; + 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 * cost = card->getManaCost(); + ManaCost * BuyBack = card->getManaCost()->BuyBack; + +#ifdef WIN32 + cost->Dump(); +#endif + if(player->castrestrictedspell > 0 && !card->hasType("land")){ return 0;} + if(player->onlyonecast > 0 && player->castcount >= 1){return 0;} + if(player->nospellinstant > 0){return 0;} + if(player->onlyoneinstant > 0){ if(player->castcount >= 1){return 0;}} + if(player->nocreatureinstant > 0 && card->hasType("creature")){return 0;} + if(player->castrestrictedcreature > 0 && 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){ + if (!isReactingToClick(card)) return 0; + Player * player = game->currentlyActing(); + ManaCost * cost = card->getManaCost(); + ManaCost * BuyBack = card->getManaCost()->BuyBack; + ManaCost * playerMana = player->getManaPool(); +//this handles extra cost payments at the moment a card is played. + if(playerMana->canAfford(BuyBack)){ + if (cost->BuyBack->isExtraPaymentSet()){ + card->paymenttype = 2; + if (!game->targetListIsSet(card)){ + return 0; + } + }else{ + cost->BuyBack->setExtraCostsAction(this, card); + game->waitForExtraPayment = cost->BuyBack->extraCosts; + card->paymenttype = 2; + 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->canPutLandsIntoPlay--; + 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; + if(player->onlyonecast > 0 || player->onlyoneinstant > 0){player->castcount += 1;} + }else{ + spell = game->mLayers->stackLayer()->addSpell(copy,NULL, spellCost, payResult,0); + player->castedspellsthisturn += 1; + if(player->onlyonecast > 0 || player->onlyoneinstant > 0){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); + } + } + + return 1; +} + +//The Put into play rule is never destroyed +int MTGBuyBackRule::testDestroy(){ + return 0; +} + +ostream& MTGBuyBackRule::toString(ostream& out) const +{ + out << "MTGBuyBackRule ::: ("; + return MTGAbility::toString(out) << ")"; +} + MTGBuyBackRule * MTGBuyBackRule::clone() const{ + MTGBuyBackRule * a = NEW MTGBuyBackRule(*this); + a->isClone = 1; + return a; + } + //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + //------------------------------------------------------------------------- +//flashback follows its own resolving rules +MTGFlashBackRule::MTGFlashBackRule(int _id):MTGAbility(_id, NULL){ + aType=MTGAbility::FLASHBACK_COST; +} +int MTGFlashBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){ +int cardsingraveyard = game->players[0]->game->graveyard->nb_cards; + 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 * playerMana = player->getManaPool(); + ManaCost * cost = card->getManaCost(); + ManaCost * FlashBack = card->getManaCost()->FlashBack; + +#ifdef WIN32 + cost->Dump(); +#endif + if(player->castrestrictedspell > 0 && !card->hasType("land")){ return 0;} + if(player->onlyonecast > 0 && player->castcount >= 1){return 0;} + if(player->nospellinstant > 0){return 0;} + if(player->onlyoneinstant > 0){ if(player->castcount >= 1){return 0;}} + if(player->nocreatureinstant > 0 && card->hasType("creature")){return 0;} + if(player->castrestrictedcreature > 0 && 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){ + 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 = 3; + if (!game->targetListIsSet(card)){ + return 0; + } + }else{ + cost->FlashBack->setExtraCostsAction(this, card); + game->waitForExtraPayment = cost->FlashBack->extraCosts; + card->paymenttype = 3; + 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->canPutLandsIntoPlay--; + 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; + if(player->onlyonecast > 0 || player->onlyoneinstant > 0){player->castcount += 1;} + }else{ + spell = game->mLayers->stackLayer()->addSpell(copy,NULL, spellCost, payResult,0); + player->castedspellsthisturn += 1; + if(player->onlyonecast > 0 || player->onlyoneinstant > 0){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); + } + } + + return 1; +} + +//The Put into play rule is never destroyed +int MTGFlashBackRule::testDestroy(){ + return 0; +} + +ostream& MTGFlashBackRule::toString(ostream& out) const +{ + out << "MTGFlashBackRule ::: ("; + return MTGAbility::toString(out) << ")"; +} + MTGFlashBackRule * MTGFlashBackRule::clone() const{ + MTGFlashBackRule * a = NEW MTGFlashBackRule(*this); + a->isClone = 1; + return a; + } - + //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + //------------------------------------------------------------------------- bool MTGAttackRule::select(Target* t) diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index 8673ebf01..6439c5322 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -215,6 +215,10 @@ ManaCost::~ManaCost(){ SAFE_DELETE(kicker); SAFE_DELETE(alternative); + + SAFE_DELETE(BuyBack); + + SAFE_DELETE(FlashBack); } void ManaCost::x(){ @@ -235,6 +239,8 @@ void ManaCost::init(){ extraCostsIsCopy = 0; kicker = NULL; alternative = NULL; + BuyBack = NULL; + FlashBack = NULL; } @@ -266,6 +272,16 @@ void ManaCost::copy(ManaCost * _manaCost){ alternative = NEW ManaCost(); alternative->copy(_manaCost->alternative); } + SAFE_DELETE(BuyBack); + if (_manaCost->BuyBack){ + BuyBack = NEW ManaCost(); + BuyBack->copy(_manaCost->BuyBack); + } + SAFE_DELETE(FlashBack); + if (_manaCost->FlashBack){ + FlashBack = NEW ManaCost(); + FlashBack->copy(_manaCost->FlashBack); + } } int ManaCost::getCost(int color){