2 things here, bug fixes, aphaseaction used in a trigger is set to oneshot = 0, for the purpose of reusing the ability. so on combat triggers the event would contenue to activate as tho it was not a oneshot, this would cause a crash if the target of the ability was killed before the effect resolved, so i set the target to NULL after the effect resolves if the target was not the source.
also restricted it to _target->isInPlay() i read through all the cards which use this and none of them targetted a source that was not in play, or not being moved to inplay...
2nd, found out today that certain activated abilities can use either target click or object click, find the difference between the 2 was impossible, exsample, {2}{t}:foreach(blah) add{b}
{t}:foreach(blah) add{b}
so i figured i would need to remove those foreach mana abilities from the stack and add that same code for the bottom half...after noticing that both the reactToClick and reactToTargetClick did EXACTLY the same things after the "cost" portion...i decided to create a new virtual int activateAbility the activatedAbility parent. this way incase i need to change any further code in there, both functions resolve the same. This was a nice lesson in why copy paste coding is stupid. you think you solved the bug becuase it works in one function call, but you actually didnt.
This commit is contained in:
@@ -274,8 +274,9 @@ class ActivatedAbility:public MTGAbility{
|
||||
virtual int reactToClick(MTGCardInstance * card);
|
||||
virtual int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
|
||||
virtual int reactToTargetClick(Targetable * object);
|
||||
virtual int activateAbility();
|
||||
virtual int resolve() = 0;
|
||||
void activeSideEffect();
|
||||
void activateSideEffect();
|
||||
virtual ActivatedAbility* clone() const = 0;
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
};
|
||||
|
||||
@@ -2938,14 +2938,22 @@ void APhaseAction::Update(float dt)
|
||||
{
|
||||
if(newPhase == phase && next )
|
||||
{
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
MTGCardInstance * _target = NULL;
|
||||
if(target)
|
||||
_target = (MTGCardInstance *) target;
|
||||
if (_target)
|
||||
{
|
||||
while (_target->next)
|
||||
_target = _target->next;
|
||||
}
|
||||
if(!sAbility.size())
|
||||
if(!sAbility.size() || !target || !_target->isInPlay())
|
||||
{
|
||||
//im aware that adding the isinplay check restricts this ability to having targets
|
||||
//which are in play..however after reviewing all the coded cards which use this
|
||||
//none of them targeted this effect at something that is not inplay.
|
||||
//the reason for this abilities that use this are generally combat abilities, and
|
||||
//without this check, the ability contenues on forever, when used in a trigger which
|
||||
//sets its ability to oneshot=0.
|
||||
this->forceDestroy = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4091,49 +4091,7 @@ int ActivatedAbility::reactToClick(MTGCardInstance * card)
|
||||
abilityCost = previousManaPool->Diff(player->getManaPool());
|
||||
delete previousManaPool;
|
||||
}
|
||||
MTGAbility * fmp = NULL;
|
||||
if(GenericActivatedAbility * gaa = dynamic_cast<GenericActivatedAbility*>(this))
|
||||
{
|
||||
AForeach * fea = dynamic_cast<AForeach*>(gaa->ability);
|
||||
if(fea)
|
||||
fmp = fea->ability;
|
||||
}
|
||||
//taking foreach manaproducers off the stack and sending tapped for mana events.
|
||||
AManaProducer * amp = dynamic_cast<AManaProducer *> (fmp);
|
||||
if(amp)
|
||||
{
|
||||
needsTapping = amp->tap;
|
||||
}
|
||||
if (needsTapping && source->isInPlay())
|
||||
{
|
||||
if (amp)
|
||||
{
|
||||
GameObserver *g = GameObserver::GetInstance();
|
||||
WEvent * e = NEW WEventCardTappedForMana(source, 0, 1);
|
||||
g->receiveEvent(e);
|
||||
}
|
||||
source->tap();
|
||||
}
|
||||
if (amp)
|
||||
{
|
||||
counters++;
|
||||
if(sideEffect && usesBeforeSideEffects.size())
|
||||
{
|
||||
activeSideEffect();
|
||||
}
|
||||
this->resolve();
|
||||
return 1;
|
||||
}
|
||||
if (needsTapping && source->isInPlay())
|
||||
source->tap();
|
||||
counters++;
|
||||
if(sideEffect && usesBeforeSideEffects.size())
|
||||
{
|
||||
activeSideEffect();
|
||||
}
|
||||
fireAbility();
|
||||
return 1;
|
||||
|
||||
return ActivatedAbility::activateAbility();
|
||||
}
|
||||
|
||||
int ActivatedAbility::reactToTargetClick(Targetable * object)
|
||||
@@ -4157,7 +4115,20 @@ int ActivatedAbility::reactToTargetClick(Targetable * object)
|
||||
abilityCost = previousManaPool->Diff(player->getManaPool());
|
||||
delete previousManaPool;
|
||||
}
|
||||
AManaProducer * amp = dynamic_cast<AManaProducer *> (this);
|
||||
return ActivatedAbility::activateAbility();
|
||||
}
|
||||
|
||||
int ActivatedAbility::activateAbility()
|
||||
{
|
||||
MTGAbility * fmp = NULL;
|
||||
if(GenericActivatedAbility * gaa = dynamic_cast<GenericActivatedAbility*>(this))
|
||||
{
|
||||
AForeach * fea = dynamic_cast<AForeach*>(gaa->ability);
|
||||
if(fea)
|
||||
fmp = fea->ability;
|
||||
}
|
||||
//taking foreach manaproducers off the stack and sending tapped for mana events.
|
||||
AManaProducer * amp = dynamic_cast<AManaProducer *> (fmp);
|
||||
if(amp)
|
||||
{
|
||||
needsTapping = amp->tap;
|
||||
@@ -4177,22 +4148,23 @@ int ActivatedAbility::reactToTargetClick(Targetable * object)
|
||||
counters++;
|
||||
if(sideEffect && usesBeforeSideEffects.size())
|
||||
{
|
||||
activeSideEffect();
|
||||
activateSideEffect();
|
||||
}
|
||||
this->resolve();
|
||||
return 1;
|
||||
}
|
||||
if (needsTapping && source->isInPlay())
|
||||
source->tap();
|
||||
counters++;
|
||||
if(sideEffect && usesBeforeSideEffects.size())
|
||||
{
|
||||
activeSideEffect();
|
||||
activateSideEffect();
|
||||
}
|
||||
fireAbility();
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
void ActivatedAbility::activeSideEffect()
|
||||
void ActivatedAbility::activateSideEffect()
|
||||
{
|
||||
WParsedInt * use = NEW WParsedInt(usesBeforeSideEffects.c_str(),NULL,source);
|
||||
uses = use->getValue();
|
||||
|
||||
Reference in New Issue
Block a user