couple things here,
first enum'ed the variables of ADynamic class to make them easier to understand at a glance. 2nd added stack resolves for the abilities in ADynamic, sword to Plowshare bug fixed 3rd removing foreach mana producers from the stack, didn't realize they used the top portion of activated ability resolves, also added event sending for @tappedformana for foreach manaproducers. 4th, in getcoreability if we're getting the core of a foreach, send the foreach->ability itself otherwise we go one layer too deep and end up throwing off the core completely.
This commit is contained in:
@@ -3387,6 +3387,45 @@ public:
|
||||
class AADynamic: public ActivatedAbility
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
DYNAMIC_SOURCE_AMOUNT = 1,
|
||||
DYNAMIC_MYTGT_AMOUNT = 2,
|
||||
DYNAMIC_MYSELF_AMOUNT = 3,
|
||||
DYNAMIC_MYFOE_AMOUNT = 4,
|
||||
DYNAMIC_NB_AMOUNT = 5,
|
||||
|
||||
DYNAMIC_ABILITY_TYPE_POWER = 0,
|
||||
DYNAMIC_ABILITY_TYPE_TOUGHNESS = 1,
|
||||
DYNAMIC_ABILITY_TYPE_MANACOST = 2,
|
||||
DYNAMIC_ABILITY_TYPE_COLORS = 3,
|
||||
DYNAMIC_ABILITY_TYPE_AGE = 4,
|
||||
DYNAMIC_ABILITY_TYPE_CHARGE = 5,
|
||||
DYNAMIC_ABILITY_TYPE_ONEONECOUNTERS = 6,
|
||||
DYNAMIC_ABILITY_TYPE_THATMUCH = 7,
|
||||
DYNAMIC_ABILITY_TYPE_NB = 8,
|
||||
|
||||
DYNAMIC_ABILITY_EFFECT_STRIKE = 0,
|
||||
DYNAMIC_ABILITY_EFFECT_DRAW = 1,
|
||||
DYNAMIC_ABILITY_EFFECT_LIFEGAIN = 2,
|
||||
DYNAMIC_ABILITY_EFFECT_PUMPPOWER = 3,
|
||||
DYNAMIC_ABILITY_EFFECT_PUMPTOUGHNESS = 4,
|
||||
DYNAMIC_ABILITY_EFFECT_PUMPBOTH = 5,
|
||||
DYNAMIC_ABILITY_EFFECT_LIFELOSS = 6,
|
||||
DYNAMIC_ABILITY_EFFECT_DEPLETE = 7,
|
||||
DYNAMIC_ABILITY_EFFECT_COUNTERSONEONE = 8,
|
||||
DYNAMIC_ABILITY_EFFECT_NB = 9,
|
||||
|
||||
DYNAMIC_ABILITY_WHO_EACHOTHER = 1,
|
||||
DYNAMIC_ABILITY_WHO_ITSELF = 2,
|
||||
DYNAMIC_ABILITY_WHO_TARGETCONTROLLER = 3,
|
||||
DYNAMIC_ABILITY_WHO_TARGETOPPONENT = 4,
|
||||
DYNAMIC_ABILITY_WHO_TOSOURCE = 5,
|
||||
DYNAMIC_ABILITY_WHO_SOURCECONTROLLER = 6,
|
||||
DYNAMIC_ABILITY_WHO_SOURCEOPPONENT = 7,
|
||||
DYNAMIC_ABILITY_WHO_NB = 8,
|
||||
|
||||
};
|
||||
int type;
|
||||
int effect;
|
||||
int who;
|
||||
|
||||
@@ -897,38 +897,38 @@ int AADynamic::resolve()
|
||||
source = (MTGCardInstance * )_target;
|
||||
switch(who)
|
||||
{
|
||||
case 1://each other, both take the effect
|
||||
case DYNAMIC_ABILITY_WHO_EACHOTHER://each other, both take the effect
|
||||
eachother = true;
|
||||
break;
|
||||
case 2:
|
||||
case DYNAMIC_ABILITY_WHO_ITSELF:
|
||||
source = ((MTGCardInstance *) _target);
|
||||
_target = _target;
|
||||
break;
|
||||
case 3:
|
||||
case DYNAMIC_ABILITY_WHO_TARGETCONTROLLER:
|
||||
_target = _target;
|
||||
secondaryTarget = ((MTGCardInstance *) _target)->controller();
|
||||
break;
|
||||
case 4:
|
||||
case DYNAMIC_ABILITY_WHO_TARGETOPPONENT:
|
||||
_target = _target;
|
||||
secondaryTarget = ((MTGCardInstance *) _target)->controller()->opponent();
|
||||
break;
|
||||
case 5:
|
||||
case DYNAMIC_ABILITY_WHO_TOSOURCE:
|
||||
tosrc = true;
|
||||
break;
|
||||
case 6:
|
||||
case DYNAMIC_ABILITY_WHO_SOURCECONTROLLER:
|
||||
_target = _target;
|
||||
secondaryTarget = ((MTGCardInstance *) OriginalSrc)->controller();
|
||||
break;
|
||||
case 7:
|
||||
case DYNAMIC_ABILITY_WHO_SOURCEOPPONENT:
|
||||
secondaryTarget = OriginalSrc->controller()->opponent();
|
||||
break;
|
||||
default:
|
||||
_target = _target;
|
||||
break;
|
||||
}
|
||||
if(amountsource == 3)
|
||||
if(amountsource == DYNAMIC_MYSELF_AMOUNT)
|
||||
_target = OriginalSrc->controller();//looking at controller for amount
|
||||
if(amountsource == 4)
|
||||
if(amountsource == DYNAMIC_MYFOE_AMOUNT)
|
||||
_target = OriginalSrc->controller()->opponent();//looking at controllers opponent for amount
|
||||
if(!_target)
|
||||
return 0;
|
||||
@@ -941,25 +941,25 @@ int AADynamic::resolve()
|
||||
int colored = 0;
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
case DYNAMIC_ABILITY_TYPE_POWER:
|
||||
sourceamount = ((MTGCardInstance *) source)->power;
|
||||
targetamount = ((MTGCardInstance *) _target)->power;
|
||||
if(eachother )
|
||||
sourceamount = ((MTGCardInstance *) source)->power;
|
||||
break;
|
||||
case 1:
|
||||
case DYNAMIC_ABILITY_TYPE_TOUGHNESS:
|
||||
sourceamount = ((MTGCardInstance *) source)->toughness;
|
||||
targetamount = ((MTGCardInstance *) _target)->toughness;
|
||||
if(eachother )
|
||||
sourceamount = ((MTGCardInstance *) source)->toughness;
|
||||
break;
|
||||
case 2:
|
||||
case DYNAMIC_ABILITY_TYPE_MANACOST:
|
||||
if(amountsource == 1)
|
||||
sourceamount = ((MTGCardInstance *) source)->getManaCost()->getConvertedCost();
|
||||
else
|
||||
sourceamount = ((MTGCardInstance *) _target)->getManaCost()->getConvertedCost();
|
||||
break;
|
||||
case 3:
|
||||
case DYNAMIC_ABILITY_TYPE_COLORS:
|
||||
for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i)
|
||||
{
|
||||
if (amountsource == 1 && ((MTGCardInstance *)source)->hasColor(i))
|
||||
@@ -970,7 +970,7 @@ int AADynamic::resolve()
|
||||
}
|
||||
sourceamount = colored;
|
||||
break;
|
||||
case 4:
|
||||
case DYNAMIC_ABILITY_TYPE_AGE:
|
||||
{
|
||||
Counter * targetCounter = NULL;
|
||||
if(amountsource == 2)
|
||||
@@ -991,7 +991,7 @@ int AADynamic::resolve()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
case DYNAMIC_ABILITY_TYPE_CHARGE:
|
||||
{
|
||||
Counter * targetCounter = NULL;
|
||||
if(amountsource == 2)
|
||||
@@ -1012,7 +1012,7 @@ int AADynamic::resolve()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
case DYNAMIC_ABILITY_TYPE_ONEONECOUNTERS:
|
||||
{
|
||||
Counter * targetCounter = NULL;
|
||||
if(amountsource == 2)
|
||||
@@ -1033,7 +1033,7 @@ int AADynamic::resolve()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
case DYNAMIC_ABILITY_TYPE_THATMUCH:
|
||||
{
|
||||
sourceamount = _target->thatmuch;
|
||||
break;
|
||||
@@ -1058,32 +1058,41 @@ int AADynamic::resolve()
|
||||
//negitive, if then used as the amount, would cuase weird side effects on resolves.
|
||||
switch(effect)
|
||||
{
|
||||
case 0://deal damage
|
||||
case DYNAMIC_ABILITY_EFFECT_STRIKE://deal damage
|
||||
if(storedAbility)
|
||||
activateStored();
|
||||
if(tosrc == false)
|
||||
{
|
||||
game->mLayers->stackLayer()->addDamage((MTGCardInstance *)source, _target, sourceamount);
|
||||
game->mLayers->stackLayer()->resolve();
|
||||
}
|
||||
else
|
||||
{
|
||||
game->mLayers->stackLayer()->addDamage((MTGCardInstance *)source, OriginalSrc, sourceamount);
|
||||
game->mLayers->stackLayer()->resolve();
|
||||
}
|
||||
if(eachother )
|
||||
{
|
||||
game->mLayers->stackLayer()->addDamage((MTGCardInstance *)_target, source, targetamount);
|
||||
game->mLayers->stackLayer()->resolve();
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
case 1://draw cards
|
||||
case DYNAMIC_ABILITY_EFFECT_DRAW://draw cards
|
||||
if(storedAbility)
|
||||
activateStored();
|
||||
game->mLayers->stackLayer()->addDraw((Player *)_target,sourceamount);
|
||||
game->mLayers->stackLayer()->resolve();
|
||||
return 1;
|
||||
break;
|
||||
case 2://gain life
|
||||
case DYNAMIC_ABILITY_EFFECT_LIFEGAIN://gain life
|
||||
if(storedAbility)
|
||||
activateStored();
|
||||
game->mLayers->stackLayer()->addLife(_target,sourceamount);
|
||||
game->mLayers->stackLayer()->resolve();
|
||||
return 1;
|
||||
break;
|
||||
case 3://pump power
|
||||
case DYNAMIC_ABILITY_EFFECT_PUMPPOWER://pump power
|
||||
{
|
||||
if(storedAbility)
|
||||
activateStored();
|
||||
@@ -1103,7 +1112,7 @@ int AADynamic::resolve()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4://pump toughness
|
||||
case DYNAMIC_ABILITY_EFFECT_PUMPTOUGHNESS://pump toughness
|
||||
{
|
||||
if(storedAbility)
|
||||
activateStored();
|
||||
@@ -1123,7 +1132,7 @@ int AADynamic::resolve()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5://pump both
|
||||
case DYNAMIC_ABILITY_EFFECT_PUMPBOTH://pump both
|
||||
{
|
||||
if(storedAbility)
|
||||
activateStored();
|
||||
@@ -1143,13 +1152,15 @@ int AADynamic::resolve()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 6://lose life
|
||||
case DYNAMIC_ABILITY_EFFECT_LIFELOSS://lose life
|
||||
if(storedAbility)
|
||||
activateStored();
|
||||
game->mLayers->stackLayer()->addLife(_target,(sourceamount * -1));
|
||||
game->mLayers->stackLayer()->addLife(_target,(sourceamount * -1));
|
||||
game->mLayers->stackLayer()->resolve();
|
||||
|
||||
return 1;
|
||||
break;
|
||||
case 7://deplete cards
|
||||
case DYNAMIC_ABILITY_EFFECT_DEPLETE://deplete cards
|
||||
{
|
||||
if(storedAbility)
|
||||
activateStored();
|
||||
@@ -1163,7 +1174,7 @@ int AADynamic::resolve()
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
case 8:
|
||||
case DYNAMIC_ABILITY_EFFECT_COUNTERSONEONE:
|
||||
{
|
||||
if(_target->typeAsTarget() != TARGET_CARD)
|
||||
_target = OriginalSrc;
|
||||
|
||||
@@ -815,6 +815,9 @@ int AbilityFactory::parseRestriction(string s)
|
||||
// When abilities encapsulate each other, gets the deepest one (it is the one likely to have the most relevant information)
|
||||
MTGAbility * AbilityFactory::getCoreAbility(MTGAbility * a)
|
||||
{
|
||||
if (AForeach * fea = dynamic_cast<AForeach*>(a))
|
||||
return fea->ability;
|
||||
|
||||
GenericTargetAbility * gta = dynamic_cast<GenericTargetAbility*> (a);
|
||||
if (gta)
|
||||
return getCoreAbility(gta->ability);
|
||||
@@ -1441,147 +1444,147 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
size_t abilityamountsource = s1.find("source");
|
||||
if (abilityamountsource != string::npos)
|
||||
{
|
||||
amountsource = 1;
|
||||
amountsource = AADynamic::DYNAMIC_SOURCE_AMOUNT;
|
||||
}
|
||||
abilityamountsource = s1.find("mytgt");
|
||||
if (abilityamountsource != string::npos)
|
||||
{
|
||||
amountsource = 2;
|
||||
amountsource = AADynamic::DYNAMIC_MYTGT_AMOUNT;
|
||||
}
|
||||
abilityamountsource = s1.find("myself");
|
||||
if (abilityamountsource != string::npos)
|
||||
{
|
||||
amountsource = 3;
|
||||
amountsource = AADynamic::DYNAMIC_MYSELF_AMOUNT;
|
||||
}
|
||||
abilityamountsource = s1.find("myfoe");
|
||||
if (abilityamountsource != string::npos)
|
||||
{
|
||||
amountsource = 4;
|
||||
amountsource = AADynamic::DYNAMIC_MYFOE_AMOUNT;
|
||||
}
|
||||
//what will be main variable used or type
|
||||
size_t abilitytype = s1.find("power");
|
||||
if (abilitytype != string::npos)
|
||||
{
|
||||
type = 0;
|
||||
type = AADynamic::DYNAMIC_ABILITY_TYPE_POWER;
|
||||
}
|
||||
abilitytype = s1.find("toughness");
|
||||
if (abilitytype != string::npos)
|
||||
{
|
||||
type = 1;
|
||||
type = AADynamic::DYNAMIC_ABILITY_TYPE_TOUGHNESS;
|
||||
}
|
||||
abilitytype = s1.find("manacost");
|
||||
if (abilitytype != string::npos)
|
||||
{
|
||||
type = 2;
|
||||
type = AADynamic::DYNAMIC_ABILITY_TYPE_MANACOST;
|
||||
}
|
||||
abilitytype = s1.find("colors");
|
||||
if (abilitytype != string::npos)
|
||||
{
|
||||
type = 3;
|
||||
type = AADynamic::DYNAMIC_ABILITY_TYPE_COLORS;
|
||||
}
|
||||
abilitytype = s1.find("age");
|
||||
if (abilitytype != string::npos)
|
||||
{
|
||||
type = 4;
|
||||
type = AADynamic::DYNAMIC_ABILITY_TYPE_AGE;
|
||||
}
|
||||
abilitytype = s1.find("charge");
|
||||
if (abilitytype != string::npos)
|
||||
{
|
||||
type = 5;
|
||||
type = AADynamic::DYNAMIC_ABILITY_TYPE_CHARGE;
|
||||
}
|
||||
|
||||
abilitytype = s1.find("oneonecounters");
|
||||
if (abilitytype != string::npos)
|
||||
{
|
||||
type = 6;
|
||||
type = AADynamic::DYNAMIC_ABILITY_TYPE_ONEONECOUNTERS;
|
||||
}
|
||||
abilitytype = s1.find("thatmuch");
|
||||
if (abilitytype != string::npos)
|
||||
{
|
||||
type = 7;
|
||||
type = AADynamic::DYNAMIC_ABILITY_TYPE_THATMUCH;
|
||||
}
|
||||
//what the effect will be
|
||||
size_t abilityeffect = s1.find("strike");
|
||||
if (abilityeffect != string::npos)
|
||||
{
|
||||
effect = 0;
|
||||
effect = AADynamic::DYNAMIC_ABILITY_EFFECT_STRIKE;
|
||||
}
|
||||
abilityeffect = s1.find("draw");
|
||||
if (abilityeffect != string::npos)
|
||||
{
|
||||
effect = 1;
|
||||
effect = AADynamic::DYNAMIC_ABILITY_EFFECT_DRAW;
|
||||
}
|
||||
abilityeffect = s1.find("lifeloss");
|
||||
if (abilityeffect != string::npos)
|
||||
{
|
||||
effect = 6;
|
||||
effect = AADynamic::DYNAMIC_ABILITY_EFFECT_LIFELOSS;
|
||||
}
|
||||
abilityeffect = s1.find("lifegain");
|
||||
if (abilityeffect != string::npos)
|
||||
{
|
||||
effect = 2;
|
||||
effect = AADynamic::DYNAMIC_ABILITY_EFFECT_LIFEGAIN;
|
||||
}
|
||||
abilityeffect = s1.find("pumppow");
|
||||
if (abilityeffect != string::npos)
|
||||
{
|
||||
effect = 3;
|
||||
effect = AADynamic::DYNAMIC_ABILITY_EFFECT_PUMPPOWER;
|
||||
}
|
||||
abilityeffect = s1.find("pumptough");
|
||||
if (abilityeffect != string::npos)
|
||||
{
|
||||
effect = 4;
|
||||
effect = AADynamic::DYNAMIC_ABILITY_EFFECT_PUMPTOUGHNESS;
|
||||
}
|
||||
abilityeffect = s1.find("pumpboth");
|
||||
if (abilityeffect != string::npos)
|
||||
{
|
||||
effect = 5;
|
||||
effect = AADynamic::DYNAMIC_ABILITY_EFFECT_PUMPBOTH;
|
||||
}
|
||||
abilityeffect = s1.find("deplete");
|
||||
if (abilityeffect != string::npos)
|
||||
{
|
||||
effect = 7;
|
||||
effect = AADynamic::DYNAMIC_ABILITY_EFFECT_DEPLETE;
|
||||
}
|
||||
abilityeffect = s1.find("countersoneone");
|
||||
if (abilityeffect != string::npos)
|
||||
{
|
||||
effect = 8;
|
||||
effect = AADynamic::DYNAMIC_ABILITY_EFFECT_COUNTERSONEONE;
|
||||
}
|
||||
//what the target will be
|
||||
size_t abilitywho = s1.find("eachother");
|
||||
if (abilitywho != string::npos)
|
||||
{
|
||||
who = 1;
|
||||
who = AADynamic::DYNAMIC_ABILITY_WHO_EACHOTHER;
|
||||
}
|
||||
abilitywho = s1.find("itself");
|
||||
if (abilitywho != string::npos)
|
||||
{
|
||||
who = 2;
|
||||
who = AADynamic::DYNAMIC_ABILITY_WHO_ITSELF;
|
||||
}
|
||||
abilitywho = s1.find("targetcontroller");
|
||||
if (abilitywho != string::npos)
|
||||
{
|
||||
who = 3;
|
||||
who = AADynamic::DYNAMIC_ABILITY_WHO_TARGETCONTROLLER;
|
||||
}
|
||||
|
||||
abilitywho = s1.find("targetopponent");
|
||||
if (abilitywho != string::npos)
|
||||
{
|
||||
who = 4;
|
||||
who = AADynamic::DYNAMIC_ABILITY_WHO_TARGETOPPONENT;
|
||||
}
|
||||
abilitywho = s1.find("tosrc");
|
||||
if (abilitywho != string::npos)
|
||||
{
|
||||
who = 5;
|
||||
who = AADynamic::DYNAMIC_ABILITY_WHO_TOSOURCE;
|
||||
}
|
||||
abilitywho = s1.find("srccontroller");
|
||||
if (abilitywho != string::npos)
|
||||
{
|
||||
who = 6;
|
||||
who = AADynamic::DYNAMIC_ABILITY_WHO_SOURCECONTROLLER;
|
||||
}
|
||||
abilitywho = s1.find("srcopponent");
|
||||
if (abilitywho != string::npos)
|
||||
{
|
||||
who = 7;
|
||||
who = AADynamic::DYNAMIC_ABILITY_WHO_SOURCEOPPONENT;
|
||||
}
|
||||
string sAbility = s.substr(end + 1);
|
||||
MTGAbility * stored = NULL;
|
||||
@@ -4088,6 +4091,39 @@ int ActivatedAbility::reactToClick(MTGCardInstance * card)
|
||||
abilityCost = previousManaPool->Diff(player->getManaPool());
|
||||
delete previousManaPool;
|
||||
}
|
||||
MTGAbility * fmp = NULL;
|
||||
if(GenericActivatedAbility * gaa = dynamic_cast<GenericActivatedAbility*>(this))
|
||||
{
|
||||
AForeach * fea = dynamic_cast<AForeach*>(gaa->ability);
|
||||
if(fea)
|
||||
fmp = fea->ability;
|
||||
}
|
||||
//taking foreach manaproducers off the stack and sending tapped for mana events.
|
||||
AManaProducer * amp = dynamic_cast<AManaProducer *> (fmp);
|
||||
if(amp)
|
||||
{
|
||||
needsTapping = amp->tap;
|
||||
}
|
||||
if (needsTapping && source->isInPlay())
|
||||
{
|
||||
if (amp)
|
||||
{
|
||||
GameObserver *g = GameObserver::GetInstance();
|
||||
WEvent * e = NEW WEventCardTappedForMana(source, 0, 1);
|
||||
g->receiveEvent(e);
|
||||
}
|
||||
source->tap();
|
||||
}
|
||||
if (amp)
|
||||
{
|
||||
counters++;
|
||||
if(sideEffect && usesBeforeSideEffects.size())
|
||||
{
|
||||
activeSideEffect();
|
||||
}
|
||||
this->resolve();
|
||||
return 1;
|
||||
}
|
||||
if (needsTapping && source->isInPlay())
|
||||
source->tap();
|
||||
counters++;
|
||||
|
||||
Reference in New Issue
Block a user