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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user