diff --git a/projects/mtg/bin/daily_build/template.exe b/projects/mtg/bin/daily_build/template.exe index 544e7c75b..e5500f8f3 100644 Binary files a/projects/mtg/bin/daily_build/template.exe and b/projects/mtg/bin/daily_build/template.exe differ diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 772bf5630..3d0ddf5d9 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -2504,6 +2504,61 @@ public: }; +//Upkeep Cost +class AUpkeep:public ActivatedAbility, public NestedAbility{ +public: + int paidThisTurn; + int phase; + int once; + + AUpkeep(int _id, MTGCardInstance * card, MTGAbility * a, ManaCost * _cost, int _tap = 0, int restrictions = 0, int _phase = Constants::MTG_PHASE_UPKEEP, int _once = 0):ActivatedAbility(_id, card,_cost,restrictions,_tap),NestedAbility(a),phase(_phase),once(_once){ + paidThisTurn = 0; + } + + void Update(float dt){ + // once: 0 means always go off, 1 means go off only once, 2 means go off only once and already has. + if (newPhase != currentPhase && source->controller() == game->currentPlayer && once < 2){ + if (newPhase == Constants::MTG_PHASE_UNTAP){ + paidThisTurn = 0; + }else if( newPhase == phase + 1 && !paidThisTurn){ + ability->resolve(); + } + if(newPhase == phase + 1 && once) once = 2; + } + ActivatedAbility::Update(dt); + } + + int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL){ + if (currentPhase != phase || paidThisTurn || once >= 2) return 0; + return ActivatedAbility::isReactingToClick(card,mana); + } + + int resolve(){ + paidThisTurn = 1; + return 1; + } + + const char * getMenuText(){ + return "Upkeep"; + } + + virtual ostream& toString(ostream& out) const + { + out << "AUpkeep ::: paidThisTurn : " << paidThisTurn + << " ("; + return ActivatedAbility::toString(out) << ")"; + } + + ~AUpkeep(){ + if(!isClone) SAFE_DELETE(ability); + } + + AUpkeep * clone() const{ + AUpkeep * a = NEW AUpkeep(*this); + a->isClone = 1; + return a; + } +}; /* Specific Classes @@ -2979,6 +3034,7 @@ class ALordOfThePit: public TargetAbility{ return a; } }; + //1143 Animate Dead class AAnimateDead:public MTGAbility{ public: diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 608e806e5..951b095bd 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -526,7 +526,45 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG SAFE_DELETE(tc); - + //Upkeep Cost + found = s.find("upcost"); + if (found != string::npos){ + size_t start = s.find("["); + size_t end = s.find("]",start); + string s1 = s.substr(start + 1,end - start - 1); + size_t seperator = s1.find(","); + int phase = Constants::MTG_PHASE_UPKEEP; + int once = 0; + if (seperator != string::npos){ + for (int i = 0; i < Constants::NB_MTG_PHASES; i++){ + if (s1.find("next") != string::npos) once = 1; + if(s1.find(Constants::MTGPhaseCodeNames[i]) != string::npos){ + phase = i; + } + } + s1 = s1.substr(0,seperator - 1); + } + ManaCost * cost = ManaCost::parseManaCost(s1); + + if (!cost){ + OutputDebugString("MTGABILITY: Parsing Error:"); + OutputDebugString(s.c_str()); + OutputDebugString("\n"); + return NULL; + } + + string sAbility = s.substr(end + 1); + MTGAbility * a = parseMagicLine(sAbility,id,spell,card); + + if (!a){ + OutputDebugString("MTGABILITY: Parsing Error:"); + OutputDebugString(s.c_str()); + OutputDebugString("\n"); + return NULL; + } + + return NEW AUpkeep(id,card,a,cost,doTap,restrictions,phase,once); + } //Cycling found = s.find("cycling"); @@ -945,6 +983,8 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG return a; } + + return NULL; }