From 17fdedb648b68e2bdc0203a57650a1561ab3e7af Mon Sep 17 00:00:00 2001 From: pankdm Date: Tue, 8 Oct 2013 23:17:43 +0000 Subject: [PATCH] Draft of the "fizzle to zone" (credit goes to excessum) --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 25 ++++++++++++++ projects/mtg/include/ActionStack.h | 1 + projects/mtg/include/AllAbilities.h | 9 +++++ projects/mtg/src/ActionStack.cpp | 28 +++++++++++++++ projects/mtg/src/AllAbilities.cpp | 36 ++++++++++++++++++++ projects/mtg/src/MTGAbility.cpp | 32 +++++++++++++++++ 6 files changed, 131 insertions(+) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index f2df1f925..f686c8191 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -30438,6 +30438,31 @@ subtype=Goblin Spellshaper power=1 toughness=1 [/card] +card] +name=Remand +target=*|stack +auto=fizhand +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} +type=Instant +[/card] +[card] +name=Memory Lapse +target=*|stack +auto=fizlibrary +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 +[/card] +[card] +name=Dissipate +target=*|stack +auto=fizexile +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 +[/card] [card] name=Firemane Angel abilities=flying,first strike diff --git a/projects/mtg/include/ActionStack.h b/projects/mtg/include/ActionStack.h index 0e7e52cf2..a57f991e4 100644 --- a/projects/mtg/include/ActionStack.h +++ b/projects/mtg/include/ActionStack.h @@ -217,6 +217,7 @@ public: 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) Interruptible * getAt(int id); void cancelInterruptOffer(InterruptDecision cancelMode = DONT_INTERRUPT, bool log = true); void endOfInterruption(bool log = true); diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 91e2cc98e..0fba6cde7 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -1120,6 +1120,15 @@ public: 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 */ diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index 78ad38ef2..a40a4f00f 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -1165,6 +1165,34 @@ void ActionStack::Fizzle(Interruptible * action) 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: + spell->source->controller()->game->putInGraveyard(spell->source); + break; + case 1: + spell->source->controller()->game->putInHand(spell->source); + break; + case 2: + spell->source->controller()->game->putInExile(spell->source); + break; + case 3: + spell->source->controller()->game->putInLibrary(spell->source); + break; + } + } + action->state = RESOLVED_NOK; +} + void ActionStack::Render() { //This is a hack to avoid rendering the stack above the tuto messages diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index e146f3c8c..296326ced 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -1349,6 +1349,42 @@ 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) + { + //ai is casting a spell from its hand to fizzle. + target = stack->getActionElementFromCard(source->target); + } + else if(MTGCardInstance * cTarget = dynamic_cast(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, targetZone); + return 1; +} +AAOFizzler* AAOFizzler::clone() const +{ + return NEW AAOFizzler(*this); +} + + + // BanishCard implementations // Bury diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 6b1f84aca..210681dfa 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -2026,6 +2026,38 @@ 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;