fix for crash from not having a playerTarget when ability$! is used on targetedPlayer by an instant.
This commit is contained in:
@@ -1077,6 +1077,33 @@ public:
|
|||||||
~IfThenAbility();
|
~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 ...
|
//MayAbility: May do ...
|
||||||
class MayAbility: public MTGAbility, public NestedAbility
|
class MayAbility: public MTGAbility, public NestedAbility
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -302,10 +302,12 @@ Spell::~Spell()
|
|||||||
int Spell::resolve()
|
int Spell::resolve()
|
||||||
{
|
{
|
||||||
MTGCardInstance * oldStored = source->storedCard;
|
MTGCardInstance * oldStored = source->storedCard;
|
||||||
|
Player * playerT = source->playerTarget;
|
||||||
if (!source->hasType(Subtypes::TYPE_INSTANT) && !source->hasType(Subtypes::TYPE_SORCERY) && source->name.size())
|
if (!source->hasType(Subtypes::TYPE_INSTANT) && !source->hasType(Subtypes::TYPE_SORCERY) && source->name.size())
|
||||||
{
|
{
|
||||||
Player * p = source->controller();
|
Player * p = source->controller();
|
||||||
int castMethod = source->castMethod;
|
int castMethod = source->castMethod;
|
||||||
|
Player * playerT = source->playerTarget;
|
||||||
vector<Targetable*>backupTgt = source->backupTargets;
|
vector<Targetable*>backupTgt = source->backupTargets;
|
||||||
source = p->game->putInZone(source, from, p->game->battlefield);
|
source = p->game->putInZone(source, from, p->game->battlefield);
|
||||||
|
|
||||||
@@ -315,6 +317,7 @@ int Spell::resolve()
|
|||||||
source->backupTargets = backupTgt;
|
source->backupTargets = backupTgt;
|
||||||
from = p->game->battlefield;
|
from = p->game->battlefield;
|
||||||
}
|
}
|
||||||
|
source->playerTarget = playerT;
|
||||||
source->storedCard = oldStored;
|
source->storedCard = oldStored;
|
||||||
//Play SFX
|
//Play SFX
|
||||||
if (options[Options::SFXVOLUME].number > 0)
|
if (options[Options::SFXVOLUME].number > 0)
|
||||||
|
|||||||
@@ -3095,6 +3095,100 @@ IfThenAbility::~IfThenAbility()
|
|||||||
SAFE_DELETE(delayedElseAbility);
|
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<TargetAbility *>(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<AManaProducer*>(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
|
//May Abilities
|
||||||
MayAbility::MayAbility(GameObserver* observer, int _id, MTGAbility * _ability, MTGCardInstance * _source, bool must,string _cond) :
|
MayAbility::MayAbility(GameObserver* observer, int _id, MTGAbility * _ability, MTGCardInstance * _source, bool must,string _cond) :
|
||||||
|
|||||||
@@ -1256,6 +1256,8 @@ int GameObserver::cardClick(MTGCardInstance * card, Targetable * object, bool lo
|
|||||||
result = targetChooser->toggleTarget(clickedPlayer);
|
result = targetChooser->toggleTarget(clickedPlayer);
|
||||||
if(card)
|
if(card)
|
||||||
card->playerTarget = clickedPlayer;
|
card->playerTarget = clickedPlayer;
|
||||||
|
else
|
||||||
|
targetChooser->source->playerTarget = clickedPlayer;
|
||||||
}
|
}
|
||||||
if (result == TARGET_OK_FULL)
|
if (result == TARGET_OK_FULL)
|
||||||
card = cardWaitingForTargets;
|
card = cardWaitingForTargets;
|
||||||
|
|||||||
@@ -3534,6 +3534,8 @@ void AbilityFactory::addAbilities(int _id, Spell * spell)
|
|||||||
}
|
}
|
||||||
card->playerTarget = spell->getNextPlayerTarget();
|
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);
|
_id = magicText(_id, spell);
|
||||||
|
|
||||||
MTGPlayerCards * zones = card->controller()->game;
|
MTGPlayerCards * zones = card->controller()->game;
|
||||||
|
|||||||
Reference in New Issue
Block a user