Refactored FizzleToZone

Get rid of common code
Better naming of zone (where we put spell after countering)
More generic syntax: fizzleto(X) where X in [hand, exile, librarytop]
which will give more flexibility later
This commit is contained in:
pankdm
2013-10-08 23:18:42 +00:00
parent 4341e23210
commit 0c6d77daa0
6 changed files with 63 additions and 115 deletions

View File

@@ -30441,7 +30441,7 @@ toughness=1
card]
name=Remand
target=*|stack
auto=fizhand
auto=fizzleto(hand)
auto=draw:1 controller
text=Counter target spell. If that spell is countered this way, put it into its owner's hand instead of into that player's graveyard. -- Draw a card.
mana={1}{U}
@@ -30450,7 +30450,7 @@ type=Instant
[card]
name=Memory Lapse
target=*|stack
auto=fizlibrary
auto=fizzleto(librarytop)
text=Counter target spell. If that spell is countered this way, put it on top of its owner's library instead of into that player's graveyard.
mana={1}{U}
type=Instant
@@ -30458,7 +30458,7 @@ type=Instant
[card]
name=Dissipate
target=*|stack
auto=fizexile
auto=fizzleto(exile)
text=Counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard.
mana={1}{U}{U}
type=Instant

View File

@@ -194,6 +194,14 @@ public:
DONT_INTERRUPT_ALL = 2
} InterruptDecision;
typedef enum
{
PUT_IN_GRAVEARD,
PUT_IN_HAND,
PUT_IN_LIBRARY_TOP,
PUT_IN_EXILE
} FizzleMode;
protected:
JQuadPtr pspIcons[8];
InterruptDecision interruptDecision[2];
@@ -216,8 +224,7 @@ public:
int getPreviousIndex(Interruptible * next, int type = 0, int state = 0 , int display = -1);
Interruptible * getNext(Interruptible * previous, int type = 0, int state = 0 , int display = -1);
int getNextIndex(Interruptible * previous, int type = 0, int state = 0 , int display = -1);
void Fizzle(Interruptible * action);
void Fizzle(Interruptible * action, int targetZone); //Overloaded fizzle (0 - 3: graveyard, hand, exile, librarytop)
void Fizzle(Interruptible * action, FizzleMode fizzleMode = PUT_IN_GRAVEARD);
Interruptible * getAt(int id);
void cancelInterruptOffer(InterruptDecision cancelMode = DONT_INTERRUPT, bool log = true);
void endOfInterruption(bool log = true);

View File

@@ -1112,23 +1112,15 @@ public:
class AAFizzler: public ActivatedAbility
{
public:
ActionStack::FizzleMode fizzleMode; // action to do after fizzling
AAFizzler(GameObserver* observer, int _id, MTGCardInstance * card, Spell * _target, ManaCost * _cost = NULL);
int resolve();
const char * getMenuText();
AAFizzler* clone() const;
};
class AAOFizzler: public AAFizzler
{
public:
AAOFizzler( GameObserver* observer, int _id, MTGCardInstance * card, Spell * _target, int tgtZone, ManaCost * _cost );
int targetZone;
int resolve();
AAOFizzler* clone() const;
};
/*
Generic classes
*/

View File

@@ -1150,7 +1150,8 @@ int ActionStack::garbageCollect()
return 1;
}
void ActionStack::Fizzle(Interruptible * action)
// Fizzle action and put it in targetZone
void ActionStack::Fizzle(Interruptible * action, FizzleMode fizzleMode)
{
if (!action)
{
@@ -1160,32 +1161,17 @@ void ActionStack::Fizzle(Interruptible * action)
if (action->type == ACTION_SPELL)
{
Spell * spell = (Spell *) action;
spell->source->controller()->game->putInGraveyard(spell->source);
}
action->state = RESOLVED_NOK;
}
void ActionStack::Fizzle(Interruptible * action,int targetZone)
{
if (!action)
{
DebugTrace("ACTIONSTACK ==ERROR==: action is NULL in ActionStack::Fizzle");
return;
}
if (action->type == ACTION_SPELL)
{
Spell * spell = (Spell *) action;
switch ( targetZone ) {
case 0:
switch (fizzleMode) {
case PUT_IN_GRAVEARD:
spell->source->controller()->game->putInGraveyard(spell->source);
break;
case 1:
case PUT_IN_HAND:
spell->source->controller()->game->putInHand(spell->source);
break;
case 2:
case PUT_IN_EXILE:
spell->source->controller()->game->putInExile(spell->source);
break;
case 3:
case PUT_IN_LIBRARY_TOP:
spell->source->controller()->game->putInLibrary(spell->source);
break;
}

View File

@@ -1314,52 +1314,16 @@ ActivatedAbility(observer, _id, card, _cost, 0)
{
aType = MTGAbility::STANDARD_FIZZLER;
target = _target;
// by default we put the spell to graveyard after fizzling
fizzleMode = ActionStack::PUT_IN_GRAVEARD;
}
int AAFizzler::resolve()
{
ActionStack * stack = game->mLayers->stackLayer();
//the next section helps Ai correctly recieve its targets for this effect
if(!target && source->target)
{
//ai is casting a spell from its hand to fizzle.
target = stack->getActionElementFromCard(source->target);
}
else if(MTGCardInstance * cTarget = dynamic_cast<MTGCardInstance *>(target))
{
//ai targeted using an ability on a card to fizzle.
target = stack->getActionElementFromCard(cTarget);
}
Spell * sTarget = (Spell *) target;
MTGCardInstance* sCard = NULL;
if(sTarget)
sCard = sTarget->source;
if(!sCard || !sTarget || sCard->has(Constants::NOFIZZLE))
return 0;
stack->Fizzle(sTarget);
return 1;
}
const char * AAFizzler::getMenuText()
{
return "Fizzle";
}
AAFizzler* AAFizzler::clone() const
{
return NEW AAFizzler(*this);
}
AAOFizzler::AAOFizzler( GameObserver* observer, int _id, MTGCardInstance * card, Spell * _target, int tgtZone, ManaCost * _cost ) :
AAFizzler( observer, _id, card, _target, _cost )
{
targetZone = tgtZone;
}
int AAOFizzler::resolve()
{
ActionStack * stack = game->mLayers->stackLayer();
//the next section helps Ai correctly recieve its targets for this effect
if(!target && source->target)
if (!target && source->target)
{
//ai is casting a spell from its hand to fizzle.
target = stack->getActionElementFromCard(source->target);
@@ -1371,19 +1335,23 @@ int AAOFizzler::resolve()
}
Spell * sTarget = (Spell *) target;
MTGCardInstance* sCard = NULL;
if(sTarget)
sCard = sTarget->source;
if(!sCard || !sTarget || sCard->has(Constants::NOFIZZLE))
if (sTarget)
sCard = sTarget->source;
if (!sCard || !sTarget || sCard->has(Constants::NOFIZZLE))
return 0;
stack->Fizzle(sTarget, targetZone);
stack->Fizzle(sTarget, fizzleMode);
return 1;
}
AAOFizzler* AAOFizzler::clone() const
const char * AAFizzler::getMenuText()
{
return NEW AAOFizzler(*this);
return "Fizzle";
}
AAFizzler* AAFizzler::clone() const
{
return NEW AAFizzler(*this);
}
// BanishCard implementations
// Bury

View File

@@ -2015,6 +2015,33 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
return a;
}
// Fizzle (counterspell...) and put to zone
// This should always be above "fizzle" section
vector<string> splitFizzle = parseBetween(s, "fizzleto(", ")");
if (splitFizzle.size())
{
// currently only hand, exile and library are supported
string zone = splitFizzle[1];
ActionStack::FizzleMode fizzleMode = ActionStack::PUT_IN_GRAVEARD;
if (zone == "hand")
{
fizzleMode = ActionStack::PUT_IN_HAND;
} else if (zone == "exile")
{
fizzleMode = ActionStack::PUT_IN_EXILE;
} else if (zone == "librarytop")
{
fizzleMode = ActionStack::PUT_IN_LIBRARY_TOP;
}
Spell * starget = NULL;
if (spell)
starget = spell->getNextSpellTarget();
AAFizzler * a = NEW AAFizzler(observer, id, card, starget);
a->fizzleMode = fizzleMode;
a->oneShot = 1;
return a;
}
//Fizzle (counterspell...)
found = s.find("fizzle");
if (found != string::npos)
@@ -2026,38 +2053,6 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
a->oneShot = 1;
return a;
}
found = s.find("fizhand");
if (found != string::npos)
{
Spell * starget = NULL;
if (spell)
starget = spell->getNextSpellTarget();
MTGAbility * a = NEW AAOFizzler( observer, id, card, starget, 1, NULL );
a->oneShot = 1;
return a;
}
//Fizzle to exile
found = s.find("fizexile");
if (found != string::npos)
{
Spell * starget = NULL;
if (spell)
starget = spell->getNextSpellTarget();
MTGAbility * a = NEW AAOFizzler( observer, id, card, starget, 2, NULL );
a->oneShot = 1;
return a;
}
//Fizzle to top of library
found = s.find("fizlibrary");
if (found != string::npos)
{
Spell * starget = NULL;
if (spell)
starget = spell->getNextSpellTarget();
MTGAbility * a = NEW AAOFizzler( observer, id, card, starget, 3, NULL );
a->oneShot = 1;
return a;
}
//Describes a player target in many abilities
int who = TargetChooser::UNSET;