diff --git a/projects/mtg/bin/Res/sets/RV/_cards.dat b/projects/mtg/bin/Res/sets/RV/_cards.dat index 7b4ca8379..ffcdcff85 100644 --- a/projects/mtg/bin/Res/sets/RV/_cards.dat +++ b/projects/mtg/bin/Res/sets/RV/_cards.dat @@ -30,6 +30,7 @@ mana={8} [card] text=Enchant artifact Enchanted artifact is a creature with power and toughness each equal to its converted mana cost. It's still an artifact. target=artifact +auto=becomes(Creature,manacost/manacost) id=1190 name=Animate Artifact rarity=U diff --git a/projects/mtg/bin/Res/test/_tests.txt b/projects/mtg/bin/Res/test/_tests.txt index dd847ac1e..7d8d14239 100644 --- a/projects/mtg/bin/Res/test/_tests.txt +++ b/projects/mtg/bin/Res/test/_tests.txt @@ -33,6 +33,8 @@ akron_legionnaire.txt Amugaba.txt anarchy.txt ancestors_chosen.txt +animate_artifact.txt +animate_artifact2.txt animate_dead.txt animate_dead2.txt animate_dead3.txt diff --git a/projects/mtg/bin/Res/test/animate_artifact.txt b/projects/mtg/bin/Res/test/animate_artifact.txt new file mode 100644 index 000000000..b768e2404 --- /dev/null +++ b/projects/mtg/bin/Res/test/animate_artifact.txt @@ -0,0 +1,29 @@ +#Test: "Becomes" functionnality parser +[INIT] +FIRSTMAIN +[PLAYER1] +inplay:the rack +hand:animate artifact +manapool:{3}{U} +[PLAYER2] +[DO] +animate artifact +the rack +next +#begin +next +#attackers +the rack +next +#blockers +next +#damage +next +#combat ends +[ASSERT] +COMBATEND +[PLAYER1] +inplay:the rack,animate artifact +[PLAYER2] +life:19 +[END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/animate_artifact2.txt b/projects/mtg/bin/Res/test/animate_artifact2.txt new file mode 100644 index 000000000..816290d1d --- /dev/null +++ b/projects/mtg/bin/Res/test/animate_artifact2.txt @@ -0,0 +1,27 @@ +#Test: "Becomes" functionnality parser +[INIT] +FIRSTMAIN +[PLAYER1] +inplay:the rack +hand:animate artifact,disenchant +manapool:{3}{U}{1}{W} +[PLAYER2] +[DO] +animate artifact +the rack +disenchant +animate artifact +next +#begin +next +#attackers +the rack +next +#combat ends +[ASSERT] +COMBATEND +[PLAYER1] +inplay:the rack +graveyard:animate artifact,disenchant +[PLAYER2] +[END] \ No newline at end of file diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index b7b5e6f39..5f5a36f68 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -38,6 +38,8 @@ public: } WParsedInt(string s, Spell * spell, MTGCardInstance * card){ + MTGCardInstance * target = card->target; + if (!target) target = card; int multiplier = 1; if (s[0] == '-'){ s = s.substr(1); @@ -45,6 +47,12 @@ public: } if (s == "x" || s == "X"){ intValue = computeX(spell,card); + }else if (s == "manacost"){ + intValue = target->getManaCost()->getConvertedCost(); + }else if (s == "p"){ + intValue = target->power; + }else if (s == "t"){ + intValue = target->toughness; }else{ intValue = atoi(s.c_str()); } @@ -1989,36 +1997,132 @@ class AOldSchoolDeathtouch:public MTGAbility{ } }; -//Converts a card to a creature (Aura) -class AConvertToCreatureAura:public MTGAbility{ - public: - AConvertToCreatureAura(int _id, MTGCardInstance * _source, MTGCardInstance * _target, int _power, int _toughness):MTGAbility(_id, _source, _target){ - _target->setSubtype("creature"); - _target->power = _power; - _target->toughness = _toughness; - _target->life = _toughness; - //_target->afterDamage(); - _target->doDamageTest = 1; +//Adds types/abilities/P/T to a card (aura) +class ABecomes:public MTGAbility{ +public: + listabilities; + listtypes; + listcolors; + WParsedPT * wppt; + ABecomes(int id, MTGCardInstance * source, MTGCardInstance * target, string stypes, WParsedPT * wppt, string sabilities):MTGAbility(id,source,target),wppt(wppt){ + //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++){ + unsigned int found = sabilities.find(Constants::MTGBasicAbilities[j]); + if (found != string::npos){ + abilities.push_back(j); + } + } + + for (int j = 0; j < Constants::MTG_NB_COLORS; j++){ + unsigned int found = sabilities.find(Constants::MTGColorStrings[j]); + if (found != string::npos){ + colors.push_back(j); + } + } + + string s = stypes; + while (s.size()){ + unsigned int found = s.find(" "); + if (found != string::npos){ + int id = Subtypes::subtypesList->Add(s.substr(0,found)); + types.push_back(id); + s = s.substr(found+1); + }else{ + int id = Subtypes::subtypesList->Add(s); + types.push_back(id); + s = ""; + } + } } + int addToGame(){ + MTGCardInstance * _target = (MTGCardInstance *)target; + list::iterator it; + for ( it=types.begin() ; it != types.end(); it++ ){ + _target->addType(*it); + } + for ( it=colors.begin() ; it != colors.end(); it++ ){ + _target->setColor(*it); + } + for ( it=abilities.begin() ; it != abilities.end(); it++ ){ + _target->basicAbilities[*it]++; + } + + if (wppt){ + _target->power = wppt->power.getValue(); + _target->toughness = wppt->toughness.getValue(); + _target->life = _target->toughness; + } + return MTGAbility::addToGame(); + } + int destroy(){ - MTGCardInstance * _target = (MTGCardInstance *) target; - _target->removeType("creature"); + MTGCardInstance * _target = (MTGCardInstance *)target; + list::iterator it; + for ( it=types.begin() ; it != types.end(); it++ ){ + _target->removeType(*it); + } + for ( it=colors.begin() ; it != colors.end(); it++ ){ + _target->removeColor(*it); + } + for ( it=abilities.begin() ; it != abilities.end(); it++ ){ + _target->basicAbilities[*it]--; + } return 1; } - virtual ostream& toString(ostream& out) const - { - out << "AConvertToCreatureAura ::: ("; - return MTGAbility::toString(out) << ")"; - } - AConvertToCreatureAura * clone() const{ - AConvertToCreatureAura * a = NEW AConvertToCreatureAura(*this); + ABecomes * clone() const{ + ABecomes * a = NEW ABecomes(*this); + a->wppt = NEW WParsedPT(*(a->wppt)); a->isClone = 1; return a; } + + ~ABecomes(){ + delete(wppt); + } + }; + +//Adds types/abilities/P/T to a card (until end of turn) +class ABecomesUEOT: public InstantAbility{ +public: + ABecomes * ability; + ABecomesUEOT(int id, MTGCardInstance * source, MTGCardInstance * target, string types, WParsedPT * wpt, string abilities):InstantAbility(id,source,target){ + ability = NEW ABecomes(id,source,target,types,wpt,abilities); + } + + int resolve(){ + ability->addToGame(); + return 1; + } + + int destroy(){ + ability->destroy(); + return 1; + } + + const char * getMenuText(){ + return ability->getMenuText(); + } + + + ABecomesUEOT * clone() const{ + ABecomesUEOT * a = NEW ABecomesUEOT(*this); + a->ability = this->ability->clone(); + a->isClone = 1; + return a; + } + + ~ABecomesUEOT(){ + delete ability; + } + +}; + + /* Specific Classes */ diff --git a/projects/mtg/include/MTGCard.h b/projects/mtg/include/MTGCard.h index d3637d908..49e481ab5 100644 --- a/projects/mtg/include/MTGCard.h +++ b/projects/mtg/include/MTGCard.h @@ -51,6 +51,7 @@ class MTGCard { void setColor(int _color, int removeAllOthers = 0); void setColor(string _color, int removeAllOthers = 0); + void removeColor(int color); int getColor(); int hasColor(int _color); const char * colorToString(); diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index a809a0892..a359b6558 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -575,6 +575,39 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG found = s.find("ueot"); if (found!= string::npos) forceUEOT = 1; + + //Becomes... (animate artifact...: becomes(Creature, manacost/manacost) + found = s.find("becomes("); + if (found != string::npos){ + size_t real_end = s.find(")", found); + size_t end = s.find(",", found); + if (end == string::npos) end = real_end; + string stypes = s.substr(found + 8,end - found - 8); + WParsedPT * pt = NULL; + string sabilities; + if (end != real_end){ + int previous = end+1; + end = s.find(",",previous); + if (end == string::npos) end = real_end; + string temp = s.substr(previous, end - previous); + pt = NEW WParsedPT(temp,spell,card); + if (!pt->ok){ + SAFE_DELETE(pt); + sabilities = temp; + } + } + if (pt && end != real_end){ + sabilities = s.substr(end+1, real_end - end); + } + MTGAbility * ab; + if (forceUEOT){ + ab = NEW ABecomesUEOT(id,card,target,stypes,pt,sabilities); + }else{ + ab = NEW ABecomes(id,card,target,stypes,pt,sabilities); + } + return ab; + } + //Change Power/Toughness WParsedPT * wppt = NEW WParsedPT(s,spell,card); if (wppt->ok){ @@ -793,12 +826,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){ game->addObserver(ability); break; } - case 1190: //Animate Artifact - { - int x = card->target->getManaCost()->getConvertedCost(); - game->addObserver(NEW AConvertToCreatureAura(_id, card,card->target,x,x)); - break; - } case 1095: //Armageddon clock { AArmageddonClock * ability = NEW AArmageddonClock(_id,card); diff --git a/projects/mtg/src/MTGCard.cpp b/projects/mtg/src/MTGCard.cpp index aecfe3e31..113f1993a 100644 --- a/projects/mtg/src/MTGCard.cpp +++ b/projects/mtg/src/MTGCard.cpp @@ -146,6 +146,10 @@ void MTGCard::setColor(int _color, int removeAllOthers){ colors[_color] = 1; } +void MTGCard::removeColor(int _color){ + colors[_color] = 0; +} + int MTGCard::getColor(){ for (int i=0; i