From c078af5f24910c943d8198d3905b5b05ed59b841 Mon Sep 17 00:00:00 2001 From: "omegablast2002@yahoo.com" Date: Wed, 30 Jan 2013 03:51:16 +0000 Subject: [PATCH] fix for crash from not having a playerTarget when ability$! is used on targetedPlayer by an instant. --- projects/mtg/include/AllAbilities.h | 27 +++++++++ projects/mtg/src/ActionStack.cpp | 3 + projects/mtg/src/AllAbilities.cpp | 94 +++++++++++++++++++++++++++++ projects/mtg/src/GameObserver.cpp | 2 + projects/mtg/src/MTGAbility.cpp | 2 + 5 files changed, 128 insertions(+) diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 92c8faa03..ac4b91b96 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -1077,6 +1077,33 @@ public: ~IfThenAbility(); }; +//MayPayAbility: May do ... +class MayPayAbility: public MTGAbility, public NestedAbility +{ +public: + int triggered; + bool must; + string Cond; + Player * previousInterrupter; + MTGAbility * mClone; + ManaCost * optionalCost; + + MayPayAbility(GameObserver* observer, int _id, MTGAbility * _ability, MTGCardInstance * _source, bool must = false, string restriction = ""); + + void Update(float dt); + + const char * getMenuText(); + int testDestroy(); + + int isReactingToTargetClick(Targetable * card); + + int reactToTargetClick(Targetable * object); + + MayPayAbility * clone() const; + ~MayPayAbility(); + +}; + //MayAbility: May do ... class MayAbility: public MTGAbility, public NestedAbility { diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index 73b504bd4..d7829f9ad 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -302,10 +302,12 @@ Spell::~Spell() int Spell::resolve() { MTGCardInstance * oldStored = source->storedCard; + Player * playerT = source->playerTarget; if (!source->hasType(Subtypes::TYPE_INSTANT) && !source->hasType(Subtypes::TYPE_SORCERY) && source->name.size()) { Player * p = source->controller(); int castMethod = source->castMethod; + Player * playerT = source->playerTarget; vectorbackupTgt = source->backupTargets; source = p->game->putInZone(source, from, p->game->battlefield); @@ -315,6 +317,7 @@ int Spell::resolve() source->backupTargets = backupTgt; from = p->game->battlefield; } + source->playerTarget = playerT; source->storedCard = oldStored; //Play SFX if (options[Options::SFXVOLUME].number > 0) diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index e938b8b6f..e1d4f010f 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -3095,6 +3095,100 @@ IfThenAbility::~IfThenAbility() SAFE_DELETE(delayedElseAbility); } // +//May Abilities +MayPayAbility::MayPayAbility(GameObserver* observer, int _id, MTGAbility * _ability, MTGCardInstance * _source, bool must,string _cond) : + MTGAbility(observer, _id, _source), NestedAbility(_ability), must(must), Cond(_cond) +{ + triggered = 0; + mClone = NULL; + optionalCost = NULL; +} + +void MayPayAbility::Update(float dt) +{ + MTGAbility::Update(dt); + if (!triggered && !game->getCurrentTargetChooser() && (!game->mLayers->actionLayer()->menuObject||game->mLayers->actionLayer()->menuObject == source)) + { + triggered = 1; + if(optionalCost && !source->controller()->getManaPool()->canAfford(optionalCost)) + return; + if(Cond.size()) + { + AbilityFactory af(game); + int checkCond = af.parseCastRestrictions(source,source->controller(),Cond); + if(!checkCond) + { + return; + } + } + if (TargetAbility * ta = dynamic_cast(ability)) + { + if (!ta->getActionTc()->validTargetsExist()) + return; + } + game->mLayers->actionLayer()->setMenuObject(source, must); + previousInterrupter = game->isInterrupting; + game->mLayers->stackLayer()->setIsInterrupting(source->controller(), false); + } +} + +const char * MayPayAbility::getMenuText() +{ + return ability->getMenuText(); +} + +int MayPayAbility::testDestroy() +{ + if (!triggered) + return 0; + if (game->mLayers->actionLayer()->menuObject) + return 0; + if (game->mLayers->actionLayer()->getIndexOf(mClone) != -1) + return 0; + if(game->currentPlayer == source->controller() && game->isInterrupting == source->controller() && dynamic_cast(AbilityFactory::getCoreAbility(ability))) + //if its my turn, and im interrupting myself(why?) then set interrupting to previous interrupter if the ability was a manaability + //special case since they don't use the stack. + game->mLayers->stackLayer()->setIsInterrupting(previousInterrupter, false); + return 1; +} + +int MayPayAbility::isReactingToTargetClick(Targetable * card) +{ + if (card == source) + { + if(!optionalCost || source->controller()->getManaPool()->canAfford(optionalCost)) + return 1; + } + return 0; +} + +int MayPayAbility::reactToTargetClick(Targetable * object) +{ + mClone = ability->clone(); + if(optionalCost) + { + source->controller()->getManaPool()->pay(optionalCost); + optionalCost->setExtraCostsAction(this, source); + optionalCost->doPayExtra(); + } + mClone->addToGame(); + mClone->forceDestroy = 1; + return mClone->reactToTargetClick(object); +} + +MayPayAbility * MayPayAbility::clone() const +{ + MayPayAbility * a = NEW MayPayAbility(*this); + a->ability = ability->clone(); + a->optionalCost = this->optionalCost; + return a; +} + +MayPayAbility::~MayPayAbility() +{ + SAFE_DELETE(ability); + SAFE_DELETE(optionalCost); +} //May Abilities MayAbility::MayAbility(GameObserver* observer, int _id, MTGAbility * _ability, MTGCardInstance * _source, bool must,string _cond) : diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 57c9ceb24..e07b3ba10 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -1256,6 +1256,8 @@ int GameObserver::cardClick(MTGCardInstance * card, Targetable * object, bool lo result = targetChooser->toggleTarget(clickedPlayer); if(card) card->playerTarget = clickedPlayer; + else + targetChooser->source->playerTarget = clickedPlayer; } if (result == TARGET_OK_FULL) card = cardWaitingForTargets; diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 044e24f70..fd73dd369 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -3534,6 +3534,8 @@ void AbilityFactory::addAbilities(int _id, Spell * spell) } card->playerTarget = spell->getNextPlayerTarget(); } + if(!card->playerTarget && card->previous && card->previous->playerTarget) + card->playerTarget = card->previous->playerTarget;//instants seem to forget as they travel from zone to zone. _id = magicText(_id, spell); MTGPlayerCards * zones = card->controller()->game;