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:
omegablast2002@yahoo.com
2011-04-16 21:16:07 +00:00
parent 16bac823fe
commit 6f070f8cd4
3 changed files with 141 additions and 55 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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++;