diff --git a/projects/mtg/include/ActionStack.h b/projects/mtg/include/ActionStack.h index 25b101278..bfc3714aa 100644 --- a/projects/mtg/include/ActionStack.h +++ b/projects/mtg/include/ActionStack.h @@ -82,6 +82,7 @@ class Spell: public Interruptible { ManaCost * cost; int payResult; int computeX(MTGCardInstance * card); + int computeXX(MTGCardInstance * card); Spell(MTGCardInstance* _source); Spell(int id, MTGCardInstance* _source, TargetChooser *_tc, ManaCost * _cost, int payResult); ~Spell(); diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index bef91ecac..b875eb2d5 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -35,6 +35,10 @@ public: if (spell) return spell->computeX(card); return 1; //this should only hapen when the ai calls the ability. This is to give it an idea of the "direction" of X (positive/negative) } + int computeXX(Spell * spell, MTGCardInstance * card){ + if (spell) return spell->computeXX(card); + return 1; //this should only hapen when the ai calls the ability. This is to give it an idea of the "direction" of X (positive/negative) + } WParsedInt(int value = 0){ intValue = value; } @@ -49,6 +53,8 @@ public: } if (s == "x" || s == "X"){ intValue = computeX(spell,card); + }else if (s == "xx" || s == "XX"){ + intValue = computeXX(spell,card); }else if (s == "manacost"){ intValue = target->getManaCost()->getConvertedCost(); }else if (s == "lifetotal"){ @@ -834,7 +840,6 @@ public: name = sname; tokenId = 0; if(!multiplier) this->multiplier = NEW WParsedInt(1); - //TODO this is a copy/past of other code that's all around the place, everything should be in a dedicated parser class; for (int j = 0; j < Constants::NB_BASIC_ABILITIES; j++){ diff --git a/projects/mtg/include/ExtraCost.h b/projects/mtg/include/ExtraCost.h index 72242a1f7..9a27ffb35 100644 --- a/projects/mtg/include/ExtraCost.h +++ b/projects/mtg/include/ExtraCost.h @@ -68,7 +68,19 @@ public: virtual int setSource(MTGCardInstance * _source); virtual LifeCost * clone() const; }; - +//Discard a random card cost +class DiscardRandomCost: public ExtraCost{ +public: + MTGCardInstance * target; + DiscardRandomCost(TargetChooser *_tc = NULL); + virtual int setPayment(MTGCardInstance * card); + virtual int isPaymentSet(); + virtual int canPay(); + virtual int doPay(); + virtual void Render(); + virtual int setSource(MTGCardInstance * _source); + virtual DiscardRandomCost * clone() const; +}; //tap other cost class TapTargetCost: public ExtraCost{ public: diff --git a/projects/mtg/include/MTGAbility.h b/projects/mtg/include/MTGAbility.h index bdd04067a..a96cabfa0 100644 --- a/projects/mtg/include/MTGAbility.h +++ b/projects/mtg/include/MTGAbility.h @@ -271,12 +271,13 @@ class AbilityFactory{ int parseRestriction(string s); public: Counter * parseCounter(string s, MTGCardInstance * target, Spell * spell = NULL); - int parsePowerToughness(string s, int *power, int *toughness); + int parsePowerToughness(string s, int *power, int *toughness); int getAbilities(vector * v, Spell * spell, MTGCardInstance * card = NULL, int id = 0,MTGGameZone * dest = NULL); MTGAbility * parseMagicLine(string s, int id, Spell * spell, MTGCardInstance *card, int activated = 0, int forceUEOT = 0,int oneShot = 0,int forceForever = 0, MTGGameZone * dest = NULL); int abilityEfficiency(MTGAbility * a, Player * p, int mode = MODE_ABILITY, TargetChooser * tc = NULL); int magicText(int id, Spell * spell, MTGCardInstance * card = NULL, int mode = MODE_PUTINTOPLAY, TargetChooser * tc = NULL, MTGGameZone * dest = NULL); static int computeX(Spell * spell, MTGCardInstance * card); + static int computeXX(Spell * spell, MTGCardInstance * card); static MTGAbility * getCoreAbility(MTGAbility * a); int destroyAllInPlay(TargetChooser * tc, int bury = 0); int moveAll(TargetChooser * tc, string destinationZone); diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index f3a8e36c0..f6ca2877a 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -44,6 +44,7 @@ class MTGCardInstance: public CardPrimitive, public MTGCard, public Damageable { MTGGameZone * currentZone; Pos* view; int X; + int XX; int boughtback; int flashedback; int paymenttype; diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index 0a483edf7..27d361b94 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -162,6 +162,13 @@ int Spell::computeX(MTGCardInstance * card){ return x; } +int Spell::computeXX(MTGCardInstance * card){ + ManaCost * c = cost->Diff(card->getManaCost()); + int xx = c->getCost(Constants::MTG_NB_COLORS)/2; + delete c; + return xx; +} + bool Spell::kickerWasPaid(){ return (payResult == ManaCost::MANA_PAID_WITH_KICKER); } diff --git a/projects/mtg/src/ExtraCost.cpp b/projects/mtg/src/ExtraCost.cpp index fcace693b..032214373 100644 --- a/projects/mtg/src/ExtraCost.cpp +++ b/projects/mtg/src/ExtraCost.cpp @@ -77,7 +77,67 @@ void LifeCost::Render(){ mFont->DrawString(buffer, 20 ,20, JGETEXT_LEFT); } //endlifecost +//discard a card at random as a cost +//DiscardRandom cost +DiscardRandomCost * DiscardRandomCost::clone() const{ + DiscardRandomCost * ec = NEW DiscardRandomCost(*this); + if (tc) ec->tc = tc->clone(); + return ec; +} +DiscardRandomCost::DiscardRandomCost(TargetChooser *_tc):ExtraCost(_tc){ + if (tc) tc->targetter = NULL; + target = NULL; +} +int DiscardRandomCost::setSource(MTGCardInstance * card){ + ExtraCost::setSource(card); + if (tc) tc->targetter = NULL; + if (!tc) target = card; + return 1; +} +int DiscardRandomCost::setPayment(MTGCardInstance * card){ + if (tc) { + int result = tc->addTarget(card); + if (result) { + target = card; + return result; + } + } + return 0; +} +int DiscardRandomCost::isPaymentSet(){ + if (target) return 1; + return 0; +} + +int DiscardRandomCost::canPay(){ + MTGGameZone * z = target->controller()->game->hand; + int nbcards = z->nb_cards; + if(nbcards < 1) return 0; + return 1; +} +int DiscardRandomCost::doPay(){ + MTGCardInstance * _target = (MTGCardInstance *) target; + if(target){ + _target->controller()->game->discardRandom(_target->controller()->game->hand); + target = NULL; + if (tc) tc->initTargets(); + return 1; + } + return 0; +} + + +void DiscardRandomCost::Render(){ + //TODO : real stuff + WFont * mFont = resources.GetWFont(Constants::MAIN_FONT); + mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); + mFont->SetColor(ARGB(255,255,255,255)); + char buffer[200]; + sprintf(buffer, "%s", _("Discard Random").c_str()); + mFont->DrawString(buffer, 20 ,20, JGETEXT_LEFT); +} +//discardrandomcost //Tap target cost TapTargetCost * TapTargetCost::clone() const{ TapTargetCost * ec = NEW TapTargetCost(*this); diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 2f14ae9cf..b11268167 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -653,7 +653,6 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG WParsedInt * multiplier = NULL; size_t star = s.find("*"); if (star != string::npos) multiplier = NEW WParsedInt(s.substr(star+1),spell,card); - size_t end = s.find(")", found); int tokenId = atoi(s.substr(found + 6,end - found - 6).c_str()); if (tokenId){ @@ -670,11 +669,14 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG previous = end+1; end = s.find(",",previous); string spt = s.substr(previous,end - previous); + int value = 0; int power, toughness; - parsePowerToughness(spt,&power, &toughness); + if(!spt.find("X/X") || !spt.find("x/x")){value = spell->computeX(card);} + if(!spt.find("XX/XX") || !spt.find("xx/xx")){value = spell->computeXX(card);} + parsePowerToughness(spt,&power, &toughness); string sabilities = s.substr(end+1); - ATokenCreator * tok = NEW ATokenCreator(id,card,NULL,sname,stypes,power,toughness,sabilities,0, multiplier); + ATokenCreator * tok = NEW ATokenCreator(id,card,NULL,sname,stypes,power + value,toughness + value,sabilities,0, multiplier); tok->oneShot = 1; return tok; } @@ -1374,6 +1376,12 @@ int AbilityFactory::computeX(Spell * spell, MTGCardInstance * card){ return 0; } +//Returns the "XX" cost that was paid for a spell +int AbilityFactory::computeXX(Spell * spell, MTGCardInstance * card){ + if (spell) return spell->computeXX(card); + return 0; +} + int AbilityFactory::getAbilities(vector * v, Spell * spell, MTGCardInstance * card, int id, MTGGameZone * dest){ diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 7adf7b3a2..dca9066fc 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -85,6 +85,7 @@ int MTGCardInstance::init(){ CardPrimitive::init(); data = this; X = 0; + XX = 0; return 1; } diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 7e5aadd7c..8611de990 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -107,7 +107,8 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card){ } }//end of storm if(!card->has(Constants::STORM)){ - copy->X = spell->computeX(copy); + copy->X = spell->computeX(copy); + copy->XX = spell->computeXX(copy); } } @@ -236,7 +237,8 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card){ } }//end of storm if(!card->has(Constants::STORM)){ - copy->X = spell->computeX(copy); + copy->X = spell->computeX(copy); + copy->XX = spell->computeXX(copy); } } @@ -368,6 +370,7 @@ int MTGBuyBackRule::reactToClick(MTGCardInstance * card){ }//end of storm if(!card->has(Constants::STORM)){ copy->X = spell->computeX(copy); + copy->XX = spell->computeXX(copy); } } @@ -495,6 +498,7 @@ int MTGFlashBackRule::reactToClick(MTGCardInstance * card){ }//end of storm if(!card->has(Constants::STORM)){ copy->X = spell->computeX(copy); + copy->XX = spell->computeXX(copy); } } diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index 6439c5322..793e5b40c 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -122,6 +122,20 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan } manaCost->addExtraCost(NEW LifeCost(tc)); //end life cost + //DiscardRandom cost + }else if (value[0] == 'd'){ + //tap + OutputDebugString("DiscardRandom\n"); + TargetChooserFactory tcf; + TargetChooser * tc = NULL; + size_t target_start = value.find("("); + size_t target_end = value.find(")"); + if (target_start!=string::npos && target_end!=string::npos){ + string target = value.substr(target_start+1, target_end-1 - target_start); + tc = tcf.createTargetChooser(target,c); + } + manaCost->addExtraCost(NEW DiscardRandomCost(tc)); + //DiscardRandom cost }else if (value[0] == 'c'){ //Counters