From 7d986283552840edd5df47dbe9321eee9ceed922 Mon Sep 17 00:00:00 2001 From: "omegablast2002@yahoo.com" Date: Sun, 27 Mar 2011 14:37:12 +0000 Subject: [PATCH] added a "while " tag for aslongas effects which are not supposed to be treated as oneshot abilities. adding it as a tag allows for maximum flexibility in the code. while i was at it reworked the aslongas class completely, i promised myself if another bug popped up with aslongas i would rewrite it. 20 hours later, we have an aslongas which does not care about when cards come or go. aslongas should never have used the added/removed to determine the validity of its effect. i allow update to sort it out now in the update function of aslongas...also added a new function to it called sorterfunction tho it looks as it could be reduced in code i would appreciate that it remains as it is, simply because of the nightmare i went through fixing the previous 7 bugs or more reported for aslongas. the logic was far to jumbled up. this i hope is atleast cleaner and easier to understand for the future devs that might work on it. note: all test passed, all manual testing also passed. new while tag is used as follows. [card] name=Emperor Crocodile auto=aslongas(other creature|myBattlefield) all(this) sacrifice while <1 text=When you control no other creatures, sacrifice Emperor Crocodile. mana={3}{G} type=Creature subtype=Crocodile power=5 toughness=5 [/card] this will denote that the ability is NOT a oneshot ability and should remain effective for the entire time the card is in the field. Issue: 613 --- projects/mtg/include/AllAbilities.h | 127 ++++++++++++++++------------ projects/mtg/src/MTGAbility.cpp | 19 ++++- 2 files changed, 92 insertions(+), 54 deletions(-) diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index e52b38fef..cb528fd6b 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -2347,9 +2347,10 @@ public: MTGAbility * a; int includeSelf; int mini, maxi; + bool miniFound, maxiFound; AAsLongAs(int _id, MTGCardInstance * _source, Damageable * _target, TargetChooser * _tc, int _includeSelf, - MTGAbility * ability, int mini = 0, int maxi = 0) : - ListMaintainerAbility(_id, _source, _target), NestedAbility(ability), mini(mini), maxi(maxi) + MTGAbility * ability, int mini = 0, int maxi = 0,bool miniFound = false,bool maxiFound = false) : + ListMaintainerAbility(_id, _source, _target), NestedAbility(ability), mini(mini), maxi(maxi),miniFound(miniFound),maxiFound(maxiFound) { tc = _tc; includeSelf = _includeSelf; @@ -2359,34 +2360,70 @@ public: a = NULL; } - int canBeInList(MTGCardInstance * card) - { - if(card->isPhased || source->isPhased) - return 0; - int size = 0; - size = (int) cards.size(); - if (includeSelf && maxi && card == source && size > maxi) - { - removed(card); - } - if ((includeSelf || card != source) && tc->canTarget(card)) - return 1; - - return 0; - } - - int resolve() + void Update(float dt) + { + ListMaintainerAbility::Update(dt); + if(!ability->oneShot) + SorterFunction(); + + } + + int SorterFunction() { - //TODO check if ability is oneShot ? updateTargets(); - int size = (int) cards.size(); - if (maxi && size < maxi && (!mini || size > mini)) addAbilityToGame(); //special case for 0 - if (ability->oneShot) a = NULL; //allows to call the effect several times + int size = 0; + size = (int) cards.size(); + /////////////////DO NOT REFACTOR THIS SECTION///////////////////////////////////////// + //these were seperated becuase previous methods were far too confusing to understand// + ////////////////////////////////////////////////////////////////////////////////////// + if (miniFound) + { + if (size > mini) + { + addAbilityToGame(); + } + else + { + removeAbilityFromGame(); + } + } + if (maxiFound) + { + if (size < maxi) + { + addAbilityToGame(); + } + else + { + removeAbilityFromGame(); + } + } + ///////////////////////////////////////////////////////////////////////// cards.clear(); players.clear(); return 1; } + int canBeInList(MTGCardInstance * card) + { + if(card->isPhased || source->isPhased) + return 0; + if ((includeSelf || card != source) && tc->canTarget(card)) + return 1; + + return 0; + } + //////////resolve is used when the aslongas is nested, or used on instants and sorceries///////// + int resolve() + { + SorterFunction(); + if (ability->oneShot) + { + a = NULL; //allows to call the effect several times + } + return 1; + } + int addAbilityToGame() { if (a) return 0; @@ -2410,52 +2447,36 @@ public: a = NULL; return 1; } - - int _added(Damageable * d) - { - int size = (int) cards.size(); - if (maxi && size >= maxi) return removeAbilityFromGame(); - if (maxi) return 0; - if (size <= mini) return 0; - return addAbilityToGame(); - } - + /////////////////section required///////////////////// int added(MTGCardInstance * card) { - return _added(card); + return 1; } - int added(Player * p) { - return _added(p); + return 1; } - int removed(MTGCardInstance * card) { - size_t size = cards.size(); - if (maxi && (int) size < maxi) return addAbilityToGame(); - if (mini && (int) size > mini) return 0; - if (mini && (int) size <= mini) return removeAbilityFromGame(); - if (!mini && !maxi && size != 0) return 0; - return removeAbilityFromGame(); + return 1; } - + /////////////////////////////////////////////////////// ~AAsLongAs() { if (!isClone) - SAFE_DELETE(ability); + SAFE_DELETE(ability); } const char * getMenuText() { - if(ability) - { - return ability->getMenuText(); - } - else - { - return "Ability"; - } + if(ability) + { + return ability->getMenuText(); + } + else + { + return "Ability"; + } } AAsLongAs * clone() const diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index bd2e37bd4..1d77f0c78 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -1291,6 +1291,9 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG oneShot = 1; if (a->oneShot) oneShot = 1; + found = s.find("while "); + if (found != string::npos) + oneShot = 0; Damageable * _target = NULL; if (spell) _target = spell->getNextDamageableTarget(); @@ -1299,14 +1302,22 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG int mini = 0; int maxi = 0; + bool miniFound = false; + bool maxiFound = false; found = s.find(" >"); if (found != string::npos) + { mini = atoi(s.substr(found + 2, 3).c_str()); + miniFound = true; + } found = s.find(" <"); if (found != string::npos) + { maxi = atoi(s.substr(found + 2, 3).c_str()); + maxiFound = true; + } switch (i) { @@ -1317,7 +1328,13 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG result = NEW AForeach(id, card, _target, lordTargets, lordIncludeSelf, a, mini, maxi); break; case 2: - result = NEW AAsLongAs(id, card, _target, lordTargets, lordIncludeSelf, a, mini, maxi); + { + if (!miniFound && !maxiFound)//for code without an operator treat as a mini. + { + miniFound = true; + } + result = NEW AAsLongAs(id, card, _target, lordTargets, lordIncludeSelf, a, mini, maxi,miniFound,maxiFound); + } break; case 3: result = NEW ATeach(id, card, lordTargets, lordIncludeSelf, a);