From 1c8852a7a255eb7667a83e287f62b563e6be01de Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 5 Nov 2015 23:25:39 +0800 Subject: [PATCH] Manacost Changes todo: kicker (other possible additional costs?) and change rule keyword to payzerorule... --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 2 +- projects/mtg/include/MTGCardInstance.h | 19 +---- projects/mtg/include/MTGRules.h | 11 ++- projects/mtg/src/AIPlayerBaka.cpp | 2 +- projects/mtg/src/MTGAbility.cpp | 2 +- projects/mtg/src/MTGCardInstance.cpp | 19 +++++ projects/mtg/src/MTGDefinitions.cpp | 2 +- projects/mtg/src/MTGRules.cpp | 83 +++++++++++++------- 8 files changed, 86 insertions(+), 54 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 257c81f05..16080c3b0 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -41603,7 +41603,7 @@ toughness=3 [card] name=Gravecrawler abilities=cantblock -autograveyard=aslongas(zombie|myBattlefield) transforms((,newability[CanPlayFromGraveyard])) +autograveyard=aslongas(zombie|myBattlefield) CanPlayFromGraveyard text=Gravecrawler can't block. -- You may cast Gravecrawler from your graveyard as long as you control a Zombie. mana={B} type=Creature diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 9eb7a64da..8c1882e91 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -254,24 +254,7 @@ public: bool isTargetter(); int cardistargetter; int myconvertedcost; - ManaCost * computeNewCost(MTGCardInstance * card,ManaCost * oldCost) - { - if(card->isLand()) - return oldCost; - - if(!card) - return NULL; - //i don't know why this method doesn't affect cards in hand, but is working on other zones....// - //pay zero costs// - //kicker???...// - //morph cost todo// - //trinisphere must be here below// - if(card->has(Constants::TRINISPHERE)) - for(int jj = oldCost->getConvertedCost(); jj < 3; jj++) - oldCost->add(Constants::MTG_COLOR_ARTIFACT, 1); - - return oldCost; - }; + ManaCost * computeNewCost(MTGCardInstance * card,ManaCost * oldCost); void eventattacked(); void eventattackedAlone(); diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index f99bdb7d4..f617f556a 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -175,18 +175,21 @@ public: virtual MTGMorphCostRule * clone() const; }; -class MTGPlayFromGraveyardRule: public MTGAlternativeCostRule +class MTGPayZeroRule: public MTGAlternativeCostRule { public: int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL); int reactToClick(MTGCardInstance * card); + string CustomName; virtual ostream& toString(ostream& out) const; - MTGPlayFromGraveyardRule(GameObserver* observer, int _id); + MTGPayZeroRule(GameObserver* observer, int _id); const string getMenuText() { - return "Cast Card From This Zone"; + if(CustomName.size()) + return CustomName.c_str(); + return "Pay Zero To Cast"; } - virtual MTGPlayFromGraveyardRule * clone() const; + virtual MTGPayZeroRule * clone() const; }; diff --git a/projects/mtg/src/AIPlayerBaka.cpp b/projects/mtg/src/AIPlayerBaka.cpp index 4c54c565d..e0d269e69 100644 --- a/projects/mtg/src/AIPlayerBaka.cpp +++ b/projects/mtg/src/AIPlayerBaka.cpp @@ -631,7 +631,7 @@ int OrderedAIAction::getEfficiency() { efficiency += 55; } - else if (dynamic_cast(a)) + else if (dynamic_cast(a)) { efficiency += 45; } diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 6b157fb32..10e9d30cc 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -1159,7 +1159,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG found = s.find("playfromgraveyardrule"); if(found != string::npos) { - observer->addObserver(NEW MTGPlayFromGraveyardRule(observer, -1)); + observer->addObserver(NEW MTGPayZeroRule(observer, -1)); return NULL; } //this rule handles attacking ability during attacker phase diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index a70ef93b6..a56247912 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -918,6 +918,25 @@ JQuadPtr MTGCardInstance::getIcon() return WResourceManager::Instance()->RetrieveCard(this, CACHE_THUMB); } +ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * oldCost) +{ + if(card->isLand()) + return oldCost; + + if(!card) + return oldCost; + //use forcedalive// + //pay zero costs// + //kicker???...// + //morph cost todo// + //trinisphere must be here below// + if(card->has(Constants::TRINISPHERE)) + for(int jj = oldCost->getConvertedCost(); jj < 3; jj++) + oldCost->add(Constants::MTG_COLOR_ARTIFACT, 1); + + return oldCost; +} + MTGCardInstance * MTGCardInstance::getNextPartner() { MTGInPlay * inplay = controller()->game->inPlay; diff --git a/projects/mtg/src/MTGDefinitions.cpp b/projects/mtg/src/MTGDefinitions.cpp index a1645eb0a..7728bd1d2 100644 --- a/projects/mtg/src/MTGDefinitions.cpp +++ b/projects/mtg/src/MTGDefinitions.cpp @@ -148,7 +148,7 @@ const char* Constants::MTGBasicAbilities[] = { "protectionfromcoloredspells", "mygcreatureexiler", "oppgcreatureexiler", - "payzero", + "zerocast", "trinisphere", "canplayfromexile", "libraryeater" diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index bb62985fd..03b6dc136 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -284,8 +284,10 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost *) { int cardsinhand = game->players[0]->game->hand->nb_cards; Player * player = game->currentlyActing(); - if (!player->game->hand->hasCard(card)) - return 0; + if (!player->game->hand->hasCard(card) && !player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card)) + return 0; + if ((player->game->graveyard->hasCard(card) && !card->has(Constants::CANPLAYFROMGRAVEYARD)) || (player->game->exile->hasCard(card) && !card->has(Constants::CANPLAYFROMEXILE))) + return 0; if ((game->turn < 1) && (cardsinhand != 0) && (card->basicAbilities[(int)Constants::LEYLINE]) && game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN && game->players[0]->game->graveyard->nb_cards == 0 @@ -295,7 +297,7 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost *) if (card->basicAbilities[(int)Constants::LEYLINE]) { - MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->temp); + MTGCardInstance * copy = player->game->putInZone(card, card->currentZone, player->game->temp); Spell * spell = NEW Spell(game, copy); spell->resolve(); delete spell; @@ -412,7 +414,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) delete previousManaPool; if (card->isLand()) { - MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->temp); + MTGCardInstance * copy = player->game->putInZone(card, card->currentZone, player->game->temp); Spell * spell = NEW Spell(game, 0,copy,NULL,NULL, payResult); spell->resolve(); delete spellCost; @@ -421,7 +423,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) else { Spell * spell = NULL; - MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->stack); + MTGCardInstance * copy = player->game->putInZone(card, card->currentZone, player->game->stack); if (game->targetChooser) { spell = game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, spellCost, payResult, 0); @@ -475,8 +477,10 @@ int MTGKickerRule::isReactingToClick(MTGCardInstance * card, ManaCost *) if(OptionKicker::KICKER_ALWAYS == options[Options::KICKERPAYMENT].number) return 0; Player * player = game->currentlyActing(); - if(!player->game->hand->hasCard(card)) - return 0; + if (!player->game->hand->hasCard(card) && !player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card)) + return 0; + if ((player->game->graveyard->hasCard(card) && !card->has(Constants::CANPLAYFROMGRAVEYARD)) || (player->game->exile->hasCard(card) && !card->has(Constants::CANPLAYFROMEXILE))) + return 0; ManaCost * kicker = card->getManaCost()->getKicker(); if(!kicker) { @@ -484,7 +488,7 @@ int MTGKickerRule::isReactingToClick(MTGCardInstance * card, ManaCost *) return 0; } ManaCost * playerMana = player->getManaPool(); - ManaCost * withKickerCost= NEW ManaCost(card->getManaCost()); + ManaCost * withKickerCost= NEW ManaCost(card->model->data->getManaCost()); withKickerCost->add(withKickerCost->getKicker()); if(!playerMana->canAfford(withKickerCost)) { @@ -503,7 +507,7 @@ int MTGKickerRule::reactToClick(MTGCardInstance * card) return 0; Player * player = game->currentlyActing(); - ManaCost * withKickerCost= NEW ManaCost(card->getManaCost());//using pointers here alters the real cost of the card. + ManaCost * withKickerCost= NEW ManaCost(card->model->data->getManaCost());//using pointers here alters the real cost of the card. if (card->getManaCost()->getKicker()->isMulti) { while(player->getManaPool()->canAfford(withKickerCost)) @@ -545,7 +549,7 @@ int MTGKickerRule::reactToClick(MTGCardInstance * card) delete previousManaPool; if (card->isLand()) { - MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->temp); + MTGCardInstance * copy = player->game->putInZone(card, card->currentZone, player->game->temp); Spell * spell = NEW Spell(game, 0,copy,NULL,NULL, ManaCost::MANA_PAID_WITH_KICKER); spell->resolve(); delete spellCost; @@ -554,7 +558,7 @@ int MTGKickerRule::reactToClick(MTGCardInstance * card) else { Spell * spell = NULL; - MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->stack); + MTGCardInstance * copy = player->game->putInZone(card, card->currentZone, player->game->stack); if (game->targetChooser) { spell = game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, spellCost, ManaCost::MANA_PAID_WITH_KICKER, 0); @@ -616,7 +620,9 @@ PermanentAbility(observer, _id) int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { ManaCost * alternateCost = card->getManaCost()->getAlternative(); - if (!game->currentlyActing()->game->hand->hasCard(card)) + if (!game->currentlyActing()->game->hand->hasCard(card) && !game->currentlyActing()->game->graveyard->hasCard(card) && !game->currentlyActing()->game->exile->hasCard(card)) + return 0; + if ((game->currentlyActing()->game->graveyard->hasCard(card) && !card->has(Constants::CANPLAYFROMGRAVEYARD)) || (game->currentlyActing()->game->exile->hasCard(card) && !card->has(Constants::CANPLAYFROMEXILE))) return 0; return isReactingToClick( card, mana, alternateCost ); } @@ -630,7 +636,12 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * if(!allowedToAltCast(card,player)) return 0; - if(card->model->data->getManaCost()->getAlternative() && card->model->data->getManaCost()->getAlternative()->alternativeName.size()) + + if(card->has(Constants::CANPLAYFROMGRAVEYARD)) + alternativeName = "Alternate Cast Card From Graveyard"; + else if(card->has(Constants::CANPLAYFROMEXILE)) + alternativeName = "Alternate Cast Card From Exile"; + else if(card->model->data->getManaCost()->getAlternative() && card->model->data->getManaCost()->getAlternative()->alternativeName.size()) alternativeName = card->model->data->getManaCost()->getAlternative()->alternativeName; if (card->isLand()) @@ -763,8 +774,10 @@ MTGAlternativeCostRule(observer, _id) int MTGBuyBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { Player * player = game->currentlyActing(); - if (!player->game->hand->hasCard(card)) - return 0; + if (!player->game->hand->hasCard(card) && !player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card)) + return 0; + if ((player->game->graveyard->hasCard(card) && !card->has(Constants::CANPLAYFROMGRAVEYARD)) || (player->game->exile->hasCard(card) && !card->has(Constants::CANPLAYFROMEXILE))) + return 0; if(!allowedToCast(card,player)) return 0; return MTGAlternativeCostRule::isReactingToClick( card, mana, card->getManaCost()->getBuyback() ); @@ -1129,46 +1142,60 @@ MTGMorphCostRule * MTGMorphCostRule::clone() const //------------------------------------------------------------------------- //------------------------------------------------------------------------- -MTGPlayFromGraveyardRule::MTGPlayFromGraveyardRule(GameObserver* observer, int _id) : +MTGPayZeroRule::MTGPayZeroRule(GameObserver* observer, int _id) : MTGAlternativeCostRule(observer, _id) { aType = MTGAbility::CASTINGRAVEEXILE_COST; } -int MTGPlayFromGraveyardRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) +int MTGPayZeroRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) { Player * player = game->currentlyActing(); - ManaCost * cost = card->getManaCost(); + ManaCost * cost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL)); + if(card->getIncreasedManaCost()->getConvertedCost()) + cost->add(card->getIncreasedManaCost()); + if(card->getReducedManaCost()->getConvertedCost()) + cost->remove(card->getReducedManaCost()); - if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card)) + if(card->isLand()) + return 0; + if(!card->has(Constants::PAYZERO)) + return 0; + if (!player->game->graveyard->hasCard(card) && !player->game->exile->hasCard(card) && !player->game->hand->hasCard(card)) return 0; if ((!card->has(Constants::CANPLAYFROMGRAVEYARD) && player->game->graveyard->hasCard(card))||(!card->has(Constants::CANPLAYFROMEXILE) && player->game->exile->hasCard(card))) return 0; - + if(card->has(Constants::CANPLAYFROMGRAVEYARD)) + CustomName = "Pay Zero To Cast From Graveyard"; + else if(card->has(Constants::CANPLAYFROMEXILE)) + CustomName = "Pay Zero To Cast From Exile"; + else + CustomName = "Pay Zero To Cast"; + return MTGAlternativeCostRule::isReactingToClick(card, mana, cost); } -int MTGPlayFromGraveyardRule::reactToClick(MTGCardInstance * card) +int MTGPayZeroRule::reactToClick(MTGCardInstance * card) { if (!isReactingToClick(card)) return 0; - ManaCost * cost = card->getManaCost(); + ManaCost * cost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL)); card->paymenttype = MTGAbility::CASTINGRAVEEXILE_COST; - return MTGAlternativeCostRule::reactToClick(card, cost, ManaCost::MANA_PAID_WITH_OTHERCOST); + return MTGAlternativeCostRule::reactToClick(card, cost, ManaCost::MANA_PAID); } -ostream& MTGPlayFromGraveyardRule::toString(ostream& out) const +ostream& MTGPayZeroRule::toString(ostream& out) const { - out << "MTGPlayFromGraveyardRule ::: ("; + out << "MTGPayZeroRule ::: ("; return MTGAbility::toString(out) << ")"; } -MTGPlayFromGraveyardRule * MTGPlayFromGraveyardRule::clone() const +MTGPayZeroRule * MTGPayZeroRule::clone() const { - return NEW MTGPlayFromGraveyardRule(*this); + return NEW MTGPayZeroRule(*this); } /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1718,7 +1745,7 @@ int MTGMomirRule::reactToClick(MTGCardInstance * card_to_discard, int cardId) ManaCost * cost = player->getManaPool(); player->getManaPool()->pay(cost); MTGCardInstance * card = genCreature(cardId); - player->game->putInZone(card_to_discard, player->game->hand, player->game->graveyard); + player->game->putInZone(card_to_discard, card_to_discard->currentZone, player->game->graveyard); player->game->stack->addCard(card); Spell * spell = NEW Spell(game, card);