diff --git a/projects/mtg/bin/Res/test/_tests.txt b/projects/mtg/bin/Res/test/_tests.txt index 00ed373fe..241618f06 100644 --- a/projects/mtg/bin/Res/test/_tests.txt +++ b/projects/mtg/bin/Res/test/_tests.txt @@ -83,6 +83,7 @@ elvish_piper.txt elvish_promenade.txt fastbond.txt fault_line.txt +fists_of_ironwood.txt flare.txt fledgling_imp.txt fledgling_imp2.txt diff --git a/projects/mtg/bin/Res/test/fists_of_ironwood.txt b/projects/mtg/bin/Res/test/fists_of_ironwood.txt new file mode 100644 index 000000000..68e2ace36 --- /dev/null +++ b/projects/mtg/bin/Res/test/fists_of_ironwood.txt @@ -0,0 +1,26 @@ +#Bug: fists of ironwood and swords to plowshares +[INIT] +FIRSTMAIN +[PLAYER1] +hand:fists of ironwood +inplay:grizzly bears +manapool:{1}{G} +[PLAYER2] +hand:swords to plowshares +manapool:{W} +[DO] +fists of ironwood +grizzly bears +no +yes +swords to plowshares +grizzly bears +endinterrupt +[ASSERT] +FIRSTMAIN +[PLAYER1] +graveyard:fists of ironwood +life:22 +[PLAYER2] +graveyard:swords to plowshares +[END] \ No newline at end of file diff --git a/projects/mtg/include/ActionStack.h b/projects/mtg/include/ActionStack.h index 15d728ecc..cab1f31cc 100644 --- a/projects/mtg/include/ActionStack.h +++ b/projects/mtg/include/ActionStack.h @@ -37,6 +37,7 @@ class MTGAbility; class Targetable; class DamageStack; class ManaCost; +class TargetChooser; #define ACTIONSTACK_STANDARD 0 @@ -67,18 +68,27 @@ class NextGamePhase: public Interruptible { NextGamePhase(int id); }; -class Spell: public Interruptible, public TargetsList { +class Spell: public Interruptible { protected: public: + TargetChooser * tc; ManaCost * cost; Spell(MTGCardInstance* _source); - Spell(int id, MTGCardInstance* _source, Targetable * _targets[], int _nbtargets, ManaCost * _cost); + Spell(int id, MTGCardInstance* _source, TargetChooser *_tc, ManaCost * _cost); ~Spell(); int resolve(); void Render(); const char *getDisplayName(); virtual ostream& toString(ostream& out) const; + MTGCardInstance * getNextCardTarget(MTGCardInstance * previous = 0); + Player * getNextPlayerTarget(Player * previous = 0); + Damageable * getNextDamageableTarget(Damageable * previous = 0); + Interruptible * getNextInterruptible(Interruptible * previous, int type); + Spell * getNextSpellTarget(Spell * previous = 0); + Damage * getNextDamageTarget(Damage * previous = 0); + Targetable * getNextTarget(Targetable * previous = 0, int type = -1); + int getNbTargets(); }; class StackAbility: public Interruptible { @@ -146,7 +156,7 @@ class ActionStack :public GuiLayer{ Player * askIfWishesToInterrupt; int garbageCollect(); int addAction(Interruptible * interruptible); - Spell * addSpell(MTGCardInstance* card, Targetable * targets[], int nbtargets, ManaCost * mana); + Spell * addSpell(MTGCardInstance* card, TargetChooser * tc, ManaCost * mana); int AddNextGamePhase(); int addPutInGraveyard(MTGCardInstance * card); int addDraw(Player * player, int nbcards = 1); diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 8e41cb3d8..8555ca6be 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -3369,7 +3369,7 @@ class AEarthbind:public ABasicAbilityModifier{ class AFireball:public InstantAbility{ public: AFireball(int _id, MTGCardInstance * card, Spell * spell, int x):InstantAbility(_id, card){ - int nbtargets = spell->cursor; + int nbtargets = spell->getNbTargets(); int totaldamage = x+1-nbtargets; int individualdamage = 0; if (nbtargets) individualdamage = totaldamage / nbtargets; diff --git a/projects/mtg/include/GameObserver.h b/projects/mtg/include/GameObserver.h index 2c0718ff7..9a3144678 100644 --- a/projects/mtg/include/GameObserver.h +++ b/projects/mtg/include/GameObserver.h @@ -79,9 +79,6 @@ class GameObserver{ void draw(); int isInPlay(MTGCardInstance * card); int isACreature(MTGCardInstance * card); - int tryToTapOrUntap(MTGCardInstance * card); - - int checkManaCost(MTGCardInstance * card); void Update(float dt); void Render(); diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index 8d9e9dad0..aac82cb71 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -8,6 +8,7 @@ #include "../include/Damage.h" #include "../include/ManaCost.h" #include "../include/GameOptions.h" +#include "../include/TargetChooser.h" // WALDORF - added to support drawing big cards during interrupts #include "../include/CardGui.h" #include "../include/Translate.h" @@ -98,15 +99,16 @@ ostream& StackAbility::toString(ostream& out) const /* Spell Cast */ -Spell::Spell(MTGCardInstance * _source): Interruptible(0), TargetsList(){ +Spell::Spell(MTGCardInstance * _source): Interruptible(0){ source = _source; mHeight= 40; type = ACTION_SPELL; cost = NEW ManaCost(); + tc = NULL; } -Spell::Spell(int id, MTGCardInstance * _source, Targetable * _targets[], int nb_targets, ManaCost * _cost): Interruptible(id), TargetsList(_targets, nb_targets),cost(_cost){ +Spell::Spell(int id, MTGCardInstance * _source, TargetChooser * tc, ManaCost * _cost): Interruptible(id), tc(tc),cost(_cost){ source = _source; mHeight = 40; type = ACTION_SPELL; @@ -119,6 +121,7 @@ const char * Spell::getDisplayName(){ Spell::~Spell(){ SAFE_DELETE(cost); + SAFE_DELETE(tc); } int Spell::resolve(){ @@ -145,6 +148,40 @@ int Spell::resolve(){ return 1; } +MTGCardInstance * Spell::getNextCardTarget(MTGCardInstance * previous){ + if (!tc) return NULL; + return tc->getNextCardTarget(previous); +} + Player * Spell::getNextPlayerTarget(Player * previous){ + if (!tc) return NULL; + return tc->getNextPlayerTarget(previous); +} + Damageable * Spell::getNextDamageableTarget(Damageable * previous){ + if (!tc) return NULL; + return tc->getNextDamageableTarget(previous); +} + Interruptible * Spell::getNextInterruptible(Interruptible * previous, int type){ + if (!tc) return NULL; + return tc->getNextInterruptible(previous,type); +} + Spell * Spell::getNextSpellTarget(Spell * previous){ + if (!tc) return NULL; + return tc->getNextSpellTarget(previous); +} + Damage * Spell::getNextDamageTarget(Damage * previous){ + if (!tc) return NULL; + return tc->getNextDamageTarget(previous); +} + Targetable * Spell::getNextTarget(Targetable * previous, int type ){ + if (!tc) return NULL; + return tc->getNextTarget(previous,type); +} + + int Spell::getNbTargets(){ + if (!tc) return 0; + return tc->cursor; + } + void Spell::Render(){ JLBFont * mFont = GameApp::CommonRes->GetJLBFont(Constants::MAIN_FONT); mFont->SetBase(0); @@ -343,13 +380,13 @@ int ActionStack::addAction(Interruptible * action){ return 1; } -Spell * ActionStack::addSpell(MTGCardInstance * _source, Targetable * _targets[], int _nbtargets, ManaCost * mana){ +Spell * ActionStack::addSpell(MTGCardInstance * _source, TargetChooser * tc, ManaCost * mana){ #if defined (WIN32) || defined (LINUX) char buf[4096], *p = buf; sprintf(buf, "Add spell\n"); OutputDebugString(buf); #endif - Spell * spell = NEW Spell(mCount,_source,_targets,_nbtargets, mana); + Spell * spell = NEW Spell(mCount,_source,tc, mana); addAction(spell); if (!game->players[0]->isAI() && _source->controller()==game->players[0] && diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 7df4ddf4a..ba06a02d5 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -478,29 +478,6 @@ Player * GameObserver::currentlyActing(){ return currentActionPlayer; } -int GameObserver::tryToTapOrUntap(MTGCardInstance * card){ - - int reaction = mLayers->actionLayer()->isReactingToClick(card); - if (reaction){ - if (reaction == 1){ - mLayers->actionLayer()->reactToClick(card); - }else{ - //TODO, what happens when several abilities react to the click ? - } - return reaction; - }else{ - if (card->isTapped() && card->controller() == currentPlayer){ - int a = ConstraintResolver::untap(this, card); - return a; - }else{ - //TODO Check Spells - //card->tap(); - return 0; - } - return 0; - } -} - //TODO CORRECT THIS MESS int GameObserver::targetListIsSet(MTGCardInstance * card){ if (targetChooser == NULL){ @@ -514,12 +491,3 @@ int GameObserver::targetListIsSet(MTGCardInstance * card){ return (targetChooser->targetListSet()); } - -int GameObserver::checkManaCost(MTGCardInstance * card){ - ManaCost * playerMana = currentlyActing()->getManaPool(); - ManaCost * cost = card->getManaCost(); - if (playerMana->canAfford(cost)){ - return 1; - } - return 0; -} diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 68b469acf..fe9a9c876 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -838,7 +838,14 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){ MTGCardInstance * card = spell->source; - if (spell->cursor==1) card->target = spell->getNextCardTarget(); + if (spell->getNbTargets()==1){ + card->target = spell->getNextCardTarget(); + if (card->target && !spell->tc->canTarget(card->target)){ + MTGPlayerCards * zones = card->controller()->game; + zones->putInGraveyard(card); + return; //fizzle + } + } _id = magicText(_id, spell); GameObserver * game = GameObserver::GetInstance(); @@ -1242,7 +1249,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){ } case 1192: //BrainGeyser { - Player * player = ((Player * )spell->targets[0]); + Player * player = spell->getNextPlayerTarget(); int x = spell->cost->getConvertedCost() - 2; for (int i = 0; i < x ; i++){ player->game->drawFromLibrary(); diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index fe5ff490f..5ab5ee3f1 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -62,10 +62,10 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card){ }else{ Spell * spell = NULL; if (game->targetChooser){ - spell = game->mLayers->stackLayer()->addSpell(card,game->targetChooser->targets,game->targetChooser->cursor, spellCost); - SAFE_DELETE(game->targetChooser); + spell = game->mLayers->stackLayer()->addSpell(card,game->targetChooser, spellCost); + game->targetChooser = NULL; }else{ - spell = game->mLayers->stackLayer()->addSpell(card,NULL,0, spellCost); + spell = game->mLayers->stackLayer()->addSpell(card,NULL, spellCost); } MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->stack); spell->source = copy;