few things here,
first, tweaked some ai checks a bit. small changes. 2nd, i removed the following classes, APowerToughnessModifierUntilEndOfTurn APowerToughnessModifierUntilEOT ADragonWhelp i replaced these with soft coded support for dragon whelps "sideffects" of using a ability more then a certain number of times... syntax limit^the effect you want^the use it triggers on. replaced both powertoughnessueot classes with a class which falls more along the lines of how we handle ueot abilitys...PTInstant, creates the wrapper with the ability and adds it to the game, rather then that jumbled mess that was previous version. added support for "phaseaction[" phase words "my" and "opponent" so you can denote which players phases it will happen on. by default it automatically happens on both players turns when the phase matches. modified a few things in phaseaction class...which correct a memory leak which could be created if the source of the phaseaction is destroyed before the phase action resolved. rather then storing an ability which is left floating in memory if phaseaction is destroy...i took a much safer route of passing the string of the ability directly to the phaseaction class...and i build the ability right when it is being used instead. makes much more sense. angry mob is now fully supported. yay to removing nasty ugly workarounds!!!! and i mean UGLY. dragon whelp is now fully soft coded. added the 5 or six other cards which do similar effects.
This commit is contained in:
@@ -954,7 +954,7 @@ public:
|
|||||||
MTGGameZone * activeZone;
|
MTGGameZone * activeZone;
|
||||||
string newName;
|
string newName;
|
||||||
|
|
||||||
GenericActivatedAbility(string newName,int _id, MTGCardInstance * card, MTGAbility * a, ManaCost * _cost, int _tap = 0, string limit = "",
|
GenericActivatedAbility(string newName,int _id, MTGCardInstance * card, MTGAbility * a, ManaCost * _cost, int _tap = 0, string limit = "",MTGAbility * sideEffects = NULL,string usesBeforeSideEffects = "",
|
||||||
int restrictions = 0, MTGGameZone * dest = NULL);
|
int restrictions = 0, MTGGameZone * dest = NULL);
|
||||||
int resolve();
|
int resolve();
|
||||||
const char * getMenuText();
|
const char * getMenuText();
|
||||||
@@ -1083,7 +1083,7 @@ public:
|
|||||||
string newName;
|
string newName;
|
||||||
|
|
||||||
GenericTargetAbility(string newName,int _id, MTGCardInstance * _source, TargetChooser * _tc, MTGAbility * a, ManaCost * _cost = NULL,
|
GenericTargetAbility(string newName,int _id, MTGCardInstance * _source, TargetChooser * _tc, MTGAbility * a, ManaCost * _cost = NULL,
|
||||||
int _tap = 0, string limit = "", int restrictions = 0, MTGGameZone * dest = NULL);
|
int _tap = 0, string limit = "",MTGAbility * sideEffects = NULL,string usesBeforeSideEffects = "", int restrictions = 0, MTGGameZone * dest = NULL);
|
||||||
const char * getMenuText();
|
const char * getMenuText();
|
||||||
~GenericTargetAbility();
|
~GenericTargetAbility();
|
||||||
GenericTargetAbility * clone() const;
|
GenericTargetAbility * clone() const;
|
||||||
@@ -1802,7 +1802,7 @@ public:
|
|||||||
if(PT.size())
|
if(PT.size())
|
||||||
{
|
{
|
||||||
SAFE_DELETE(wppt);
|
SAFE_DELETE(wppt);
|
||||||
wppt = NEW WParsedPT(PT,NULL,(MTGCardInstance *) target);
|
wppt = NEW WParsedPT(PT,NULL,(MTGCardInstance *) source);
|
||||||
}
|
}
|
||||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||||
_target->power += wppt->power.getValue();
|
_target->power += wppt->power.getValue();
|
||||||
@@ -1827,7 +1827,16 @@ public:
|
|||||||
((MTGCardInstance *) target)->addToToughness(-wppt->toughness.getValue());
|
((MTGCardInstance *) target)->addToToughness(-wppt->toughness.getValue());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
const char * getMenuText()
|
||||||
|
{
|
||||||
|
if(PT.size())
|
||||||
|
{
|
||||||
|
SAFE_DELETE(wppt);
|
||||||
|
wppt = NEW WParsedPT(PT,NULL,(MTGCardInstance *) source);
|
||||||
|
}
|
||||||
|
sprintf(menuText, "%i/%i", wppt->power.getValue(), wppt->toughness.getValue());
|
||||||
|
return menuText;
|
||||||
|
}
|
||||||
APowerToughnessModifier * clone() const
|
APowerToughnessModifier * clone() const
|
||||||
{
|
{
|
||||||
APowerToughnessModifier * a = NEW APowerToughnessModifier(*this);
|
APowerToughnessModifier * a = NEW APowerToughnessModifier(*this);
|
||||||
@@ -1843,132 +1852,6 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Alteration of Power and toughness until end of turn (instant)
|
|
||||||
class AInstantPowerToughnessModifierUntilEOT: public InstantAbility
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WParsedPT * wppt;
|
|
||||||
string s;
|
|
||||||
AInstantPowerToughnessModifierUntilEOT(int _id, MTGCardInstance * _source, MTGCardInstance * _target, WParsedPT * wppt) :
|
|
||||||
InstantAbility(_id, _source, _target), wppt(wppt)
|
|
||||||
{
|
|
||||||
aType = MTGAbility::STANDARD_PUMP;
|
|
||||||
}
|
|
||||||
|
|
||||||
int resolve()
|
|
||||||
{
|
|
||||||
((MTGCardInstance *) target)->power += wppt->power.getValue();
|
|
||||||
((MTGCardInstance *) target)->addToToughness(wppt->toughness.getValue());
|
|
||||||
if(((MTGCardInstance *) target)->has(Constants::INDESTRUCTIBLE) && wppt->toughness.getValue() < 0 && ((MTGCardInstance *) target)->toughness <= 0)
|
|
||||||
{
|
|
||||||
((MTGCardInstance *) target)->controller()->game->putInGraveyard(((MTGCardInstance *) target));
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int destroy()
|
|
||||||
{
|
|
||||||
((MTGCardInstance *) target)->power -= wppt->power.getValue();
|
|
||||||
((MTGCardInstance *) target)->addToToughness(-wppt->toughness.getValue());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * getMenuText()
|
|
||||||
{
|
|
||||||
sprintf(menuText, "%i/%i", wppt->power.getValue(), wppt->toughness.getValue());
|
|
||||||
return menuText;
|
|
||||||
}
|
|
||||||
|
|
||||||
AInstantPowerToughnessModifierUntilEOT * clone() const
|
|
||||||
{
|
|
||||||
AInstantPowerToughnessModifierUntilEOT * a = NEW AInstantPowerToughnessModifierUntilEOT(*this);
|
|
||||||
a->wppt = NEW WParsedPT(*(a->wppt));
|
|
||||||
a->isClone = 1;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
~AInstantPowerToughnessModifierUntilEOT()
|
|
||||||
{
|
|
||||||
delete wppt;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//Alteration of Power and Toughness until end of turn (Aura)
|
|
||||||
class APowerToughnessModifierUntilEndOfTurn: public ActivatedAbility
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AInstantPowerToughnessModifierUntilEOT * ability;
|
|
||||||
int counters;
|
|
||||||
int maxcounters;
|
|
||||||
APowerToughnessModifierUntilEndOfTurn(int id, MTGCardInstance * _source, MTGCardInstance * _target, WParsedPT * wppt,
|
|
||||||
ManaCost * _cost = NULL, int _maxcounters = 0) :
|
|
||||||
ActivatedAbility(id, _source, _cost, 0, 0), maxcounters(_maxcounters)
|
|
||||||
{
|
|
||||||
counters = 0;
|
|
||||||
target = _target;
|
|
||||||
ability = NEW AInstantPowerToughnessModifierUntilEOT(id, _source, _target, wppt);
|
|
||||||
aType = MTGAbility::STANDARD_PUMP;
|
|
||||||
}
|
|
||||||
|
|
||||||
int isReactingToClick(MTGCardInstance * card, ManaCost * cost = NULL)
|
|
||||||
{
|
|
||||||
//The upper level "GenericTargetAbility" takes care of the click so we always return 0 here
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update(float dt)
|
|
||||||
{
|
|
||||||
if (newPhase != currentPhase && newPhase == Constants::MTG_PHASE_AFTER_EOT)
|
|
||||||
{
|
|
||||||
counters = 0;
|
|
||||||
}
|
|
||||||
ActivatedAbility::Update(dt);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fireAbility()
|
|
||||||
{
|
|
||||||
return resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * getMenuText()
|
|
||||||
{
|
|
||||||
return ability->getMenuText();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL){
|
|
||||||
if (!ActivatedAbility::isReactingToClick(card,mana)) return 0;
|
|
||||||
return (!maxcounters || (counters < maxcounters));
|
|
||||||
}*/
|
|
||||||
|
|
||||||
int resolve()
|
|
||||||
{
|
|
||||||
MTGAbility * a = ability->clone();
|
|
||||||
a->target = target;
|
|
||||||
a->addToGame();
|
|
||||||
counters++;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int addToGame()
|
|
||||||
{
|
|
||||||
resolve();
|
|
||||||
return ActivatedAbility::addToGame();
|
|
||||||
}
|
|
||||||
|
|
||||||
APowerToughnessModifierUntilEndOfTurn * clone() const
|
|
||||||
{
|
|
||||||
APowerToughnessModifierUntilEndOfTurn * a = NEW APowerToughnessModifierUntilEndOfTurn(*this);
|
|
||||||
a->isClone = 1;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
~APowerToughnessModifierUntilEndOfTurn()
|
|
||||||
{
|
|
||||||
if (!isClone)
|
|
||||||
SAFE_DELETE(ability);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class GenericInstantAbility: public InstantAbility, public NestedAbility
|
class GenericInstantAbility: public InstantAbility, public NestedAbility
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -3879,6 +3762,22 @@ public:
|
|||||||
~ATransformerInstant();
|
~ATransformerInstant();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Adds types/abilities/changes color to a card (generally until end of turn)
|
||||||
|
class PTInstant: public InstantAbility
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
APowerToughnessModifier * ability;
|
||||||
|
WParsedPT * wppt;
|
||||||
|
string s;
|
||||||
|
bool nonstatic;
|
||||||
|
WParsedPT * newWppt;
|
||||||
|
PTInstant(int id, MTGCardInstance * source, MTGCardInstance * target, WParsedPT * wppt,string s = "",bool nonstatic = false);
|
||||||
|
int resolve();
|
||||||
|
const char * getMenuText();
|
||||||
|
PTInstant * clone() const;
|
||||||
|
~PTInstant();
|
||||||
|
};
|
||||||
|
|
||||||
//switch p/t ueot
|
//switch p/t ueot
|
||||||
class ASwapPTUEOT: public InstantAbility
|
class ASwapPTUEOT: public InstantAbility
|
||||||
{
|
{
|
||||||
@@ -3960,19 +3859,24 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//phase based actions
|
//phase based actions
|
||||||
class APhaseAction: public MTGAbility, public NestedAbility
|
class APhaseAction: public MTGAbility
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
string psMenuText;
|
||||||
|
int abilityId;
|
||||||
|
string sAbility;
|
||||||
int phase;
|
int phase;
|
||||||
|
MTGAbility * ability;
|
||||||
bool forcedestroy;
|
bool forcedestroy;
|
||||||
bool next;
|
bool next;
|
||||||
|
bool myturn;
|
||||||
|
bool opponentturn;
|
||||||
Player * abilityOwner;
|
Player * abilityOwner;
|
||||||
|
|
||||||
APhaseAction(int _id, MTGCardInstance * card, MTGCardInstance * target, MTGAbility * a, int _tap = 0, int restrictions = 0, int _phase =
|
APhaseAction(int _id, MTGCardInstance * card, MTGCardInstance * target, string sAbility, int _tap = 0, int restrictions = 0, int _phase =
|
||||||
Constants::MTG_PHASE_UPKEEP,bool forcedestroy = false,bool next = true);
|
Constants::MTG_PHASE_UPKEEP,bool forcedestroy = false,bool next = true,bool myturn = true,bool opponentturn = true);
|
||||||
void Update(float dt);
|
void Update(float dt);
|
||||||
int resolve();
|
int resolve();
|
||||||
int removeAbility();
|
|
||||||
const char * getMenuText();
|
const char * getMenuText();
|
||||||
APhaseAction * clone() const;
|
APhaseAction * clone() const;
|
||||||
~APhaseAction();
|
~APhaseAction();
|
||||||
@@ -3982,9 +3886,10 @@ public:
|
|||||||
class APhaseActionGeneric: public InstantAbility
|
class APhaseActionGeneric: public InstantAbility
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
string sAbility;
|
||||||
APhaseAction * ability;
|
APhaseAction * ability;
|
||||||
APhaseActionGeneric(int _id, MTGCardInstance * card, MTGCardInstance * target, MTGAbility * a, int _tap = 0, int restrictions = 0, int _phase =
|
APhaseActionGeneric(int _id, MTGCardInstance * card, MTGCardInstance * target, string sAbility, int _tap = 0, int restrictions = 0, int _phase =
|
||||||
Constants::MTG_PHASE_UPKEEP,bool forcedestroy = false,bool next = true);
|
Constants::MTG_PHASE_UPKEEP,bool forcedestroy = false,bool next = true,bool myturn = false,bool opponentturn = false);
|
||||||
int resolve();
|
int resolve();
|
||||||
const char * getMenuText();
|
const char * getMenuText();
|
||||||
APhaseActionGeneric * clone() const;
|
APhaseActionGeneric * clone() const;
|
||||||
@@ -4831,44 +4736,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//1284 Dragon Whelp
|
|
||||||
class ADragonWhelp: public APowerToughnessModifierUntilEndOfTurn
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ADragonWhelp(int id, MTGCardInstance * card) :
|
|
||||||
APowerToughnessModifierUntilEndOfTurn(id, card, card, NEW WParsedPT(1, 0), NEW ManaCost())
|
|
||||||
{
|
|
||||||
cost->add(Constants::MTG_COLOR_RED, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL)
|
|
||||||
{
|
|
||||||
if (!ActivatedAbility::isReactingToClick(card, mana)) return 0;
|
|
||||||
return (!maxcounters || (counters < maxcounters));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update(float dt)
|
|
||||||
{
|
|
||||||
if (newPhase != currentPhase && newPhase == Constants::MTG_PHASE_AFTER_EOT && counters > 3)
|
|
||||||
{
|
|
||||||
source->controller()->game->putInGraveyard(source);
|
|
||||||
}
|
|
||||||
APowerToughnessModifierUntilEndOfTurn::Update(dt);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ostream& toString(ostream& out) const
|
|
||||||
{
|
|
||||||
out << "ADragonWhelp ::: (";
|
|
||||||
return APowerToughnessModifierUntilEndOfTurn::toString(out) << ")";
|
|
||||||
}
|
|
||||||
ADragonWhelp * clone() const
|
|
||||||
{
|
|
||||||
ADragonWhelp * a = NEW ADragonWhelp(*this);
|
|
||||||
a->isClone = 1;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//1288 EarthBind
|
//1288 EarthBind
|
||||||
class AEarthbind: public ABasicAbilityModifier
|
class AEarthbind: public ABasicAbilityModifier
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -257,7 +257,11 @@ class ActivatedAbility:public MTGAbility{
|
|||||||
int counters;
|
int counters;
|
||||||
int needsTapping;
|
int needsTapping;
|
||||||
string limit;
|
string limit;
|
||||||
ActivatedAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _restrictions = NO_RESTRICTION,int tap = 1,string limit = "");
|
MTGAbility * sideEffect;
|
||||||
|
MTGAbility * sa;
|
||||||
|
string usesBeforeSideEffects;
|
||||||
|
int uses;
|
||||||
|
ActivatedAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _restrictions = NO_RESTRICTION,int tap = 1,string limit = "",MTGAbility * sideEffect = NULL,string usesBeforeSideEffects = "");
|
||||||
virtual ~ActivatedAbility();
|
virtual ~ActivatedAbility();
|
||||||
virtual void Update(float dt)
|
virtual void Update(float dt)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -386,25 +386,32 @@ int AIAction::getEfficiency()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MTGAbility::STANDARD_PUMP:
|
case MTGAbility::STANDARD_PUMP:
|
||||||
{
|
{
|
||||||
MTGCardInstance * _target = (MTGCardInstance *) (a->target);
|
MTGCardInstance * _target = (MTGCardInstance *) (a->target);
|
||||||
efficiency = 0;
|
efficiency = 0;
|
||||||
if (!target && !dynamic_cast<ALord*> (a))
|
if(!target && !dynamic_cast<ALord*> (a) && (((MTGCardInstance *)a->source)->hasSubtype(Subtypes::TYPE_AURA) || ((MTGCardInstance *)a->source)->hasSubtype(Subtypes::TYPE_EQUIPMENT)))
|
||||||
break;
|
{
|
||||||
|
if(((MTGCardInstance *)a->source)->target)
|
||||||
|
_target = ((MTGCardInstance *)a->source)->target;
|
||||||
|
target = (MTGCardInstance *)a->source;
|
||||||
|
}
|
||||||
|
if (!target && !dynamic_cast<ALord*> (a))
|
||||||
|
break;
|
||||||
if(dynamic_cast<ALord*> (a) && !target)
|
if(dynamic_cast<ALord*> (a) && !target)
|
||||||
{
|
{
|
||||||
target = a->source;
|
target = a->source;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbilityFactory af;
|
AbilityFactory af;
|
||||||
int suggestion = af.abilityEfficiency(a, p, MODE_ABILITY);
|
int suggestion = af.abilityEfficiency(a, p, MODE_ABILITY);
|
||||||
//i do not set a starting eff. on this ability, this allows Ai to sometimes randomly do it as it normally does.
|
//i do not set a starting eff. on this ability, this allows Ai to sometimes randomly do it as it normally does.
|
||||||
if (g->getCurrentGamePhase() == Constants::MTG_PHASE_COMBATBLOCKERS)
|
int currentPhase = g->getCurrentGamePhase();
|
||||||
|
if ((currentPhase == Constants::MTG_PHASE_COMBATBLOCKERS) || (currentPhase == Constants::MTG_PHASE_COMBATATTACKERS))
|
||||||
{
|
{
|
||||||
if (suggestion == BAKA_EFFECT_GOOD && target->controller()->isAI())
|
if (suggestion == BAKA_EFFECT_GOOD && target->controller()->isAI())
|
||||||
{
|
{
|
||||||
if ((_target->defenser || _target->blockers.size()) && ((_target->power < _target->getNextOpponent()->toughness
|
if ((_target->defenser || _target->blockers.size()) && ((_target->power < _target->getNextOpponent()->toughness
|
||||||
|| _target->toughness < _target->getNextOpponent()->power) || (_target->has(Constants::TRAMPLE))))
|
|| _target->toughness < _target->getNextOpponent()->power) || (_target->has(Constants::TRAMPLE))))
|
||||||
{
|
{
|
||||||
//this pump is based on a start eff. of 20 multiplied by how good the creature is.
|
//this pump is based on a start eff. of 20 multiplied by how good the creature is.
|
||||||
efficiency = 20 * _target->DangerRanking();
|
efficiency = 20 * _target->DangerRanking();
|
||||||
@@ -413,13 +420,14 @@ int AIAction::getEfficiency()
|
|||||||
{
|
{
|
||||||
//this means im heading directly for the player, pump this creature as much as possible.
|
//this means im heading directly for the player, pump this creature as much as possible.
|
||||||
efficiency = 100;
|
efficiency = 100;
|
||||||
|
if(_target->power > 50)
|
||||||
|
efficiency -= _target->power;//we don't need to go overboard. better to not put all your eggs in a single basket.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (suggestion == BAKA_EFFECT_BAD && !target->controller()->isAI())
|
}
|
||||||
{
|
if (suggestion == BAKA_EFFECT_BAD && !target->controller()->isAI())
|
||||||
efficiency = 100;
|
{
|
||||||
}
|
efficiency = 100;
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -736,7 +744,8 @@ int AIPlayer::selectAbility()
|
|||||||
int chance = 1;
|
int chance = 1;
|
||||||
if (!forceBestAbilityUse)
|
if (!forceBestAbilityUse)
|
||||||
chance = 1 + WRand() % 100;
|
chance = 1 + WRand() % 100;
|
||||||
if (action.getEfficiency() >= chance)
|
int actionScore = action.getEfficiency();
|
||||||
|
if (actionScore >= chance)
|
||||||
{
|
{
|
||||||
if (!clickstream.size())
|
if (!clickstream.size())
|
||||||
{
|
{
|
||||||
@@ -1464,9 +1473,13 @@ int AIPlayerBaka::computeActions()
|
|||||||
switch (currentGamePhase)
|
switch (currentGamePhase)
|
||||||
{
|
{
|
||||||
case Constants::MTG_PHASE_COMBATBLOCKERS:
|
case Constants::MTG_PHASE_COMBATBLOCKERS:
|
||||||
chooseBlockers();
|
{
|
||||||
break;
|
chooseBlockers();
|
||||||
|
selectAbility();
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
|
selectAbility();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -186,7 +186,10 @@ ostream& StackAbility::toString(ostream& out) const
|
|||||||
const string StackAbility::getDisplayName() const
|
const string StackAbility::getDisplayName() const
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
|
if(ability->source)
|
||||||
stream << "StackAbility. (Source: " << ability->source->getDisplayName() << ")";
|
stream << "StackAbility. (Source: " << ability->source->getDisplayName() << ")";
|
||||||
|
else
|
||||||
|
stream << "StackAbility. (Source: " << ability->getMenuText() << ")";
|
||||||
|
|
||||||
return stream.str();
|
return stream.str();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
//Generic Activated Abilities
|
//Generic Activated Abilities
|
||||||
GenericActivatedAbility::GenericActivatedAbility(string newName,int _id, MTGCardInstance * card, MTGAbility * a, ManaCost * _cost, int _tap,
|
GenericActivatedAbility::GenericActivatedAbility(string newName,int _id, MTGCardInstance * card, MTGAbility * a, ManaCost * _cost, int _tap,
|
||||||
string limit, int restrictions, MTGGameZone * dest) :
|
string limit,MTGAbility * sideEffects,string usesBeforeSideEffects, int restrictions, MTGGameZone * dest) :
|
||||||
ActivatedAbility(_id, card, _cost, restrictions, _tap,limit), NestedAbility(a), activeZone(dest),newName(newName)
|
ActivatedAbility(_id, card, _cost, restrictions, _tap,limit,sideEffects,usesBeforeSideEffects), NestedAbility(a), activeZone(dest),newName(newName)
|
||||||
{
|
{
|
||||||
counters = 0;
|
counters = 0;
|
||||||
target = ability->target;
|
target = ability->target;
|
||||||
@@ -1089,14 +1089,14 @@ int AADynamic::resolve()
|
|||||||
activateStored();
|
activateStored();
|
||||||
if(tosrc == false)
|
if(tosrc == false)
|
||||||
{
|
{
|
||||||
AInstantPowerToughnessModifierUntilEOT * a = NEW AInstantPowerToughnessModifierUntilEOT(this->GetId(), source, (MTGCardInstance*)_target,NEW WParsedPT(sourceamount,0));
|
PTInstant * a = NEW PTInstant(this->GetId(), source, (MTGCardInstance*)_target,NEW WParsedPT(sourceamount,0));
|
||||||
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source,(MTGCardInstance*)_target, a);
|
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source,(MTGCardInstance*)_target, a);
|
||||||
wrapper->addToGame();
|
wrapper->addToGame();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AInstantPowerToughnessModifierUntilEOT * a = NEW AInstantPowerToughnessModifierUntilEOT(this->GetId(), source, OriginalSrc,NEW WParsedPT(sourceamount,0));
|
PTInstant * a = NEW PTInstant(this->GetId(), source, OriginalSrc,NEW WParsedPT(sourceamount,0));
|
||||||
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source,OriginalSrc, a);
|
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source,OriginalSrc, a);
|
||||||
wrapper->addToGame();
|
wrapper->addToGame();
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1109,14 +1109,14 @@ int AADynamic::resolve()
|
|||||||
activateStored();
|
activateStored();
|
||||||
if(tosrc == false)
|
if(tosrc == false)
|
||||||
{
|
{
|
||||||
AInstantPowerToughnessModifierUntilEOT * a = NEW AInstantPowerToughnessModifierUntilEOT(this->GetId(), source, (MTGCardInstance*)_target,NEW WParsedPT(0,sourceamount));
|
PTInstant * a = NEW PTInstant(this->GetId(), source, (MTGCardInstance*)_target,NEW WParsedPT(0,sourceamount));
|
||||||
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source,(MTGCardInstance*)_target, a);
|
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source,(MTGCardInstance*)_target, a);
|
||||||
wrapper->addToGame();
|
wrapper->addToGame();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AInstantPowerToughnessModifierUntilEOT * a = NEW AInstantPowerToughnessModifierUntilEOT(this->GetId(), source, OriginalSrc,NEW WParsedPT(0,sourceamount));
|
PTInstant * a = NEW PTInstant(this->GetId(), source, OriginalSrc,NEW WParsedPT(0,sourceamount));
|
||||||
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source,OriginalSrc, a);
|
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source,OriginalSrc, a);
|
||||||
wrapper->addToGame();
|
wrapper->addToGame();
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1129,14 +1129,14 @@ int AADynamic::resolve()
|
|||||||
activateStored();
|
activateStored();
|
||||||
if(tosrc == false)
|
if(tosrc == false)
|
||||||
{
|
{
|
||||||
AInstantPowerToughnessModifierUntilEOT * a = NEW AInstantPowerToughnessModifierUntilEOT(this->GetId(), source, (MTGCardInstance*)_target,NEW WParsedPT(sourceamount,sourceamount));
|
PTInstant * a = NEW PTInstant(this->GetId(), source, (MTGCardInstance*)_target,NEW WParsedPT(sourceamount,sourceamount));
|
||||||
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source,(MTGCardInstance*)_target, a);
|
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source,(MTGCardInstance*)_target, a);
|
||||||
wrapper->addToGame();
|
wrapper->addToGame();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AInstantPowerToughnessModifierUntilEOT * a = NEW AInstantPowerToughnessModifierUntilEOT(this->GetId(), source, OriginalSrc,NEW WParsedPT(sourceamount,sourceamount));
|
PTInstant * a = NEW PTInstant(this->GetId(), source, OriginalSrc,NEW WParsedPT(sourceamount,sourceamount));
|
||||||
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source,OriginalSrc, a);
|
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source,OriginalSrc, a);
|
||||||
wrapper->addToGame();
|
wrapper->addToGame();
|
||||||
return 1;
|
return 1;
|
||||||
@@ -2001,7 +2001,7 @@ MultiAbility::~MultiAbility()
|
|||||||
|
|
||||||
//Generic Target Ability
|
//Generic Target Ability
|
||||||
GenericTargetAbility::GenericTargetAbility(string newName,int _id, MTGCardInstance * _source, TargetChooser * _tc, MTGAbility * a,
|
GenericTargetAbility::GenericTargetAbility(string newName,int _id, MTGCardInstance * _source, TargetChooser * _tc, MTGAbility * a,
|
||||||
ManaCost * _cost, int _tap, string limit, int restrictions, MTGGameZone * dest) :
|
ManaCost * _cost, int _tap, string limit,MTGAbility * sideEffects,string usesBeforeSideEffects, int restrictions, MTGGameZone * dest) :
|
||||||
TargetAbility(_id, _source, _tc, _cost, restrictions, _tap), limit(limit), activeZone(dest),newName(newName)
|
TargetAbility(_id, _source, _tc, _cost, restrictions, _tap), limit(limit), activeZone(dest),newName(newName)
|
||||||
{
|
{
|
||||||
ability = a;
|
ability = a;
|
||||||
@@ -2532,6 +2532,38 @@ ATransformerInstant::~ATransformerInstant()
|
|||||||
{
|
{
|
||||||
SAFE_DELETE(ability);
|
SAFE_DELETE(ability);
|
||||||
}
|
}
|
||||||
|
//P/t ueot
|
||||||
|
PTInstant::PTInstant(int id, MTGCardInstance * source, MTGCardInstance * target, WParsedPT * wppt,string s,bool nonstatic) :
|
||||||
|
InstantAbility(id, source, target), wppt(wppt),s(s),nonstatic(nonstatic)
|
||||||
|
{
|
||||||
|
ability = NEW APowerToughnessModifier(id, source, target, wppt,s,nonstatic);
|
||||||
|
aType = MTGAbility::STANDARD_PUMP;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PTInstant::resolve()
|
||||||
|
{
|
||||||
|
APowerToughnessModifier * a = ability->clone();
|
||||||
|
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source, (Damageable *) (this->target), a);
|
||||||
|
wrapper->addToGame();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
const char * PTInstant::getMenuText()
|
||||||
|
{
|
||||||
|
return ability->getMenuText();
|
||||||
|
}
|
||||||
|
|
||||||
|
PTInstant * PTInstant::clone() const
|
||||||
|
{
|
||||||
|
PTInstant * a = NEW PTInstant(*this);
|
||||||
|
a->ability = this->ability->clone();
|
||||||
|
a->isClone = 1;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
PTInstant::~PTInstant()
|
||||||
|
{
|
||||||
|
SAFE_DELETE(ability);
|
||||||
|
}
|
||||||
|
|
||||||
// ASwapPTUEOT
|
// ASwapPTUEOT
|
||||||
ASwapPTUEOT::ASwapPTUEOT(int id, MTGCardInstance * source, MTGCardInstance * target) :
|
ASwapPTUEOT::ASwapPTUEOT(int id, MTGCardInstance * source, MTGCardInstance * target) :
|
||||||
@@ -2830,33 +2862,58 @@ AUpkeep::~AUpkeep()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//A Phase based Action
|
//A Phase based Action
|
||||||
APhaseAction::APhaseAction(int _id, MTGCardInstance * card, MTGCardInstance * target, MTGAbility * a, int _tap, int restrictions, int _phase,bool forcedestroy,bool next) :
|
APhaseAction::APhaseAction(int _id, MTGCardInstance * card, MTGCardInstance * target, string sAbility, int _tap, int restrictions, int _phase,bool forcedestroy,bool next,bool myturn,bool opponentturn) :
|
||||||
MTGAbility(_id, card), NestedAbility(a), phase(_phase),forcedestroy(forcedestroy),next(next)
|
MTGAbility(_id, card),sAbility(sAbility), phase(_phase),forcedestroy(forcedestroy),next(next),myturn(myturn),opponentturn(opponentturn)
|
||||||
{
|
{
|
||||||
|
abilityId = _id;
|
||||||
abilityOwner = card->controller();
|
abilityOwner = card->controller();
|
||||||
|
psMenuText = "";
|
||||||
|
AbilityFactory af;
|
||||||
|
ability = af.parseMagicLine(sAbility, abilityId, NULL, NULL);
|
||||||
|
if(ability)
|
||||||
|
psMenuText = ability->getMenuText();
|
||||||
|
else
|
||||||
|
psMenuText = sAbility.c_str();
|
||||||
|
delete (ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
void APhaseAction::Update(float dt)
|
void APhaseAction::Update(float dt)
|
||||||
{
|
{
|
||||||
if (newPhase != currentPhase)
|
if (newPhase != currentPhase)
|
||||||
{
|
{
|
||||||
if(newPhase == phase && next )
|
if((myturn && game->currentPlayer == source->controller())||
|
||||||
|
(opponentturn && game->currentPlayer != source->controller())/*||*/
|
||||||
|
/*(myturn && opponentturn)*/)
|
||||||
{
|
{
|
||||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
if(newPhase == phase && next )
|
||||||
if (_target)
|
|
||||||
{
|
{
|
||||||
while (_target->next)
|
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||||
_target = _target->next;
|
if (_target)
|
||||||
|
{
|
||||||
|
while (_target->next)
|
||||||
|
_target = _target->next;
|
||||||
|
}
|
||||||
|
if(!sAbility.size())
|
||||||
|
{
|
||||||
|
this->forceDestroy = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AbilityFactory af;
|
||||||
|
MTGAbility * ability = af.parseMagicLine(sAbility, abilityId, NULL, _target);
|
||||||
|
|
||||||
|
MTGAbility * a = ability->clone();
|
||||||
|
a->target = _target;
|
||||||
|
a->resolve();
|
||||||
|
delete (a);
|
||||||
|
delete (ability);
|
||||||
|
if(this->oneShot)
|
||||||
|
{
|
||||||
|
this->forceDestroy = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ability->target = _target;
|
else if(newPhase == phase && next == false)
|
||||||
ability->source = _target;
|
next = true;
|
||||||
ability->oneShot = 1;
|
|
||||||
ability->resolve();
|
|
||||||
this->forceDestroy = 1;
|
|
||||||
removeAbility();
|
|
||||||
}
|
}
|
||||||
else if(newPhase == phase && next == false)
|
|
||||||
next = true;
|
|
||||||
}
|
}
|
||||||
MTGAbility::Update(dt);
|
MTGAbility::Update(dt);
|
||||||
}
|
}
|
||||||
@@ -2868,7 +2925,10 @@ int APhaseAction::resolve()
|
|||||||
|
|
||||||
const char * APhaseAction::getMenuText()
|
const char * APhaseAction::getMenuText()
|
||||||
{
|
{
|
||||||
return ability->getMenuText();
|
if(psMenuText.size())
|
||||||
|
return psMenuText.c_str();
|
||||||
|
else
|
||||||
|
return "Phase Based Action";
|
||||||
}
|
}
|
||||||
|
|
||||||
APhaseAction * APhaseAction::clone() const
|
APhaseAction * APhaseAction::clone() const
|
||||||
@@ -2879,23 +2939,18 @@ APhaseAction * APhaseAction::clone() const
|
|||||||
a->isClone = 1;
|
a->isClone = 1;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
int APhaseAction::removeAbility()
|
|
||||||
{
|
|
||||||
if (!isClone)
|
|
||||||
SAFE_DELETE(ability);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
APhaseAction::~APhaseAction()
|
APhaseAction::~APhaseAction()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the main ability
|
// the main ability
|
||||||
APhaseActionGeneric::APhaseActionGeneric(int _id, MTGCardInstance * card, MTGCardInstance * target, MTGAbility * a, int _tap, int restrictions, int _phase,bool forcedestroy,bool next) :
|
APhaseActionGeneric::APhaseActionGeneric(int _id, MTGCardInstance * card, MTGCardInstance * target, string sAbility, int _tap, int restrictions, int _phase,bool forcedestroy,bool next,bool myturn,bool opponentturn) :
|
||||||
InstantAbility(_id, source, target)
|
InstantAbility(_id, source, target)
|
||||||
{
|
{
|
||||||
MTGCardInstance * _target = target;
|
MTGCardInstance * _target = target;
|
||||||
ability = NEW APhaseAction(_id, card,_target, a,_tap, restrictions, _phase,forcedestroy,next);
|
ability = NEW APhaseAction(_id, card,_target, sAbility,_tap, restrictions, _phase,forcedestroy,next,myturn,opponentturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
int APhaseActionGeneric::resolve()
|
int APhaseActionGeneric::resolve()
|
||||||
|
|||||||
+110
-33
@@ -929,7 +929,23 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
if (doTap || cost)
|
if (doTap || cost)
|
||||||
{
|
{
|
||||||
string s1 = sWithoutTc.substr(delimiter + 2);
|
string s1 = sWithoutTc.substr(delimiter + 2);
|
||||||
|
//grabbing the sideffect string and amount before parsing abilities.
|
||||||
|
//side effect ei:dragond whelp.
|
||||||
|
MTGAbility * sideEffect = NULL;
|
||||||
|
string usesBeforeSideEffect = "";
|
||||||
|
size_t limiteffect_str = s1.find("limit^");
|
||||||
|
if (limiteffect_str != string::npos)
|
||||||
|
{
|
||||||
|
size_t end = s1.rfind("^");
|
||||||
|
string sideEffectStr = s1.substr(limiteffect_str + 6,end - limiteffect_str - 6);
|
||||||
|
s1.erase(limiteffect_str,end - limiteffect_str);
|
||||||
|
end = s1.find("^");
|
||||||
|
usesBeforeSideEffect = s1.substr(end+1);
|
||||||
|
s1.erase(end-1);
|
||||||
|
sideEffect = parseMagicLine(sideEffectStr, id, spell, card, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MTGAbility * a = parseMagicLine(s1, id, spell, card, 1);
|
MTGAbility * a = parseMagicLine(s1, id, spell, card, 1);
|
||||||
if (!a)
|
if (!a)
|
||||||
{
|
{
|
||||||
@@ -955,7 +971,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
{
|
{
|
||||||
limit = sWithoutTc.substr(limit_str + 6);
|
limit = sWithoutTc.substr(limit_str + 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
AEquip *ae = dynamic_cast<AEquip*> (a);
|
AEquip *ae = dynamic_cast<AEquip*> (a);
|
||||||
if (ae)
|
if (ae)
|
||||||
{
|
{
|
||||||
@@ -969,8 +985,8 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
return ae;
|
return ae;
|
||||||
}
|
}
|
||||||
if (tc)
|
if (tc)
|
||||||
return NEW GenericTargetAbility(newName,id, card, tc, a, cost, doTap, limit, restrictions, dest);
|
return NEW GenericTargetAbility(newName,id, card, tc, a, cost, doTap, limit,sideEffect,usesBeforeSideEffect, restrictions, dest);
|
||||||
return NEW GenericActivatedAbility(newName,id, card, a, cost, doTap, limit, restrictions, dest);
|
return NEW GenericActivatedAbility(newName,id, card, a, cost, doTap, limit,sideEffect,usesBeforeSideEffect,restrictions, dest);
|
||||||
}
|
}
|
||||||
SAFE_DELETE(cost);
|
SAFE_DELETE(cost);
|
||||||
}
|
}
|
||||||
@@ -1136,19 +1152,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
next = false;
|
next = false;
|
||||||
}
|
}
|
||||||
string sAbility = s.substr(end + 1);
|
string sAbility = s.substr(end + 1);
|
||||||
MTGAbility * a = parseMagicLine(sAbility, id, spell, card);
|
|
||||||
|
|
||||||
if (!a)
|
|
||||||
{
|
|
||||||
DebugTrace("MTGABILITY: Parsing Error: " << s);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
MTGCardInstance * _target = NULL;
|
MTGCardInstance * _target = NULL;
|
||||||
if (spell)
|
if (spell)
|
||||||
_target = spell->getNextCardTarget();
|
_target = spell->getNextCardTarget();
|
||||||
if(!_target)
|
if(!_target)
|
||||||
_target = target;
|
_target = target;
|
||||||
return NEW APhaseActionGeneric(id, card,_target, a, doTap, restrictions, phase,sourceinPlay,next);
|
return NEW APhaseActionGeneric(id, card,_target,sAbility, doTap, restrictions, phase,sourceinPlay,next);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Multiple abilities for ONE cost
|
//Multiple abilities for ONE cost
|
||||||
@@ -1594,6 +1603,15 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
phase = i;
|
phase = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool opponentturn = true,myturn = true;
|
||||||
|
if(s1.find("my") != string::npos)
|
||||||
|
{
|
||||||
|
opponentturn = false;
|
||||||
|
}
|
||||||
|
if(s1.find("opponent") != string::npos)
|
||||||
|
{
|
||||||
|
myturn = false;
|
||||||
|
}
|
||||||
if (s1.find("combatends") != string::npos)
|
if (s1.find("combatends") != string::npos)
|
||||||
{
|
{
|
||||||
phase = Constants::MTG_PHASE_COMBATEND;
|
phase = Constants::MTG_PHASE_COMBATEND;
|
||||||
@@ -1621,19 +1639,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
next = false;
|
next = false;
|
||||||
}
|
}
|
||||||
string sAbility = s.substr(end + 1);
|
string sAbility = s.substr(end + 1);
|
||||||
MTGAbility * a = parseMagicLine(sAbility, id, spell, card);
|
|
||||||
|
|
||||||
if (!a)
|
|
||||||
{
|
|
||||||
DebugTrace("MTGABILITY: Parsing Error: " << s);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
MTGCardInstance * _target = NULL;
|
MTGCardInstance * _target = NULL;
|
||||||
if (spell)
|
if (spell)
|
||||||
_target = spell->getNextCardTarget();
|
_target = spell->getNextCardTarget();
|
||||||
if(!_target)
|
if(!_target)
|
||||||
_target = target;
|
_target = target;
|
||||||
return NEW APhaseActionGeneric(id, card,_target, a, doTap, restrictions, phase,sourceinPlay,next);
|
return NEW APhaseActionGeneric(id, card,_target, sAbility, doTap, restrictions, phase,sourceinPlay,next,myturn,opponentturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Upkeep Cost
|
//Upkeep Cost
|
||||||
@@ -2639,11 +2650,11 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
{
|
{
|
||||||
if (card->hasType(Subtypes::TYPE_INSTANT) || card->hasType(Subtypes::TYPE_SORCERY) || forceUEOT)
|
if (card->hasType(Subtypes::TYPE_INSTANT) || card->hasType(Subtypes::TYPE_SORCERY) || forceUEOT)
|
||||||
{
|
{
|
||||||
return NEW AInstantPowerToughnessModifierUntilEOT(id, card, target, wppt);
|
return NEW PTInstant(id, card, target, wppt,s,nonstatic);
|
||||||
}
|
}
|
||||||
return NEW APowerToughnessModifier(id, card, target, wppt,s,nonstatic);
|
return NEW APowerToughnessModifier(id, card, target, wppt,s,nonstatic);
|
||||||
}
|
}
|
||||||
return NEW APowerToughnessModifierUntilEndOfTurn(id, card, target, wppt);
|
return NEW PTInstant(id, card, target, wppt,s,nonstatic);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2952,11 +2963,11 @@ int AbilityFactory::abilityEfficiency(MTGAbility * a, Player * p, int mode, Targ
|
|||||||
return BAKA_EFFECT_GOOD;
|
return BAKA_EFFECT_GOOD;
|
||||||
if (dynamic_cast<ABushidoAbility *> (a))
|
if (dynamic_cast<ABushidoAbility *> (a))
|
||||||
return BAKA_EFFECT_GOOD;
|
return BAKA_EFFECT_GOOD;
|
||||||
if (AInstantPowerToughnessModifierUntilEOT * abi = dynamic_cast<AInstantPowerToughnessModifierUntilEOT *>(a))
|
if (PTInstant * abi = dynamic_cast<PTInstant *>(a))
|
||||||
return (abi->wppt->power.getValue() >= 0 && abi->wppt->toughness.getValue() >= 0) ? BAKA_EFFECT_GOOD : BAKA_EFFECT_BAD;
|
return (abi->wppt->power.getValue() >= 0 && abi->wppt->toughness.getValue() >= 0) ? BAKA_EFFECT_GOOD : BAKA_EFFECT_BAD;
|
||||||
if (APowerToughnessModifier * abi = dynamic_cast<APowerToughnessModifier *>(a))
|
if (APowerToughnessModifier * abi = dynamic_cast<APowerToughnessModifier *>(a))
|
||||||
return (abi->wppt->power.getValue() >= 0 && abi->wppt->toughness.getValue() >= 0) ? BAKA_EFFECT_GOOD : BAKA_EFFECT_BAD;
|
return (abi->wppt->power.getValue() >= 0 && abi->wppt->toughness.getValue() >= 0) ? BAKA_EFFECT_GOOD : BAKA_EFFECT_BAD;
|
||||||
if (APowerToughnessModifierUntilEndOfTurn * abi = dynamic_cast<APowerToughnessModifierUntilEndOfTurn *>(a))
|
if (PTInstant * abi = dynamic_cast<PTInstant *>(a))
|
||||||
return abilityEfficiency(abi->ability, p, mode, tc);
|
return abilityEfficiency(abi->ability, p, mode, tc);
|
||||||
|
|
||||||
if (dynamic_cast<ACantBeBlockedBy *> (a))
|
if (dynamic_cast<ACantBeBlockedBy *> (a))
|
||||||
@@ -3320,11 +3331,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1284: //Dragon Whelp
|
|
||||||
{
|
|
||||||
game->addObserver(NEW ADragonWhelp(_id, card));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 1345: //Farmstead
|
case 1345: //Farmstead
|
||||||
{
|
{
|
||||||
@@ -3972,12 +3978,13 @@ NestedAbility::NestedAbility(MTGAbility * _ability)
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
ActivatedAbility::ActivatedAbility(int id, MTGCardInstance * card, ManaCost * _cost, int restrictions, int tap,string limit) :
|
ActivatedAbility::ActivatedAbility(int id, MTGCardInstance * card, ManaCost * _cost, int restrictions, int tap,string limit,MTGAbility * sideEffect,string usesBeforeSideEffects) :
|
||||||
MTGAbility(id, card), restrictions(restrictions), needsTapping(tap),limit(limit)
|
MTGAbility(id, card), restrictions(restrictions), needsTapping(tap),limit(limit),sideEffect(sideEffect),usesBeforeSideEffects(usesBeforeSideEffects)
|
||||||
{
|
{
|
||||||
counters = 0;
|
counters = 0;
|
||||||
cost = _cost;
|
cost = _cost;
|
||||||
abilityCost = 0;
|
abilityCost = 0;
|
||||||
|
sa = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ActivatedAbility::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
int ActivatedAbility::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
||||||
@@ -4077,8 +4084,31 @@ int ActivatedAbility::reactToClick(MTGCardInstance * card)
|
|||||||
}
|
}
|
||||||
if (needsTapping && source->isInPlay())
|
if (needsTapping && source->isInPlay())
|
||||||
source->tap();
|
source->tap();
|
||||||
fireAbility();
|
|
||||||
counters++;
|
counters++;
|
||||||
|
if(sideEffect && usesBeforeSideEffects.size())
|
||||||
|
{
|
||||||
|
WParsedInt * use = NEW WParsedInt(usesBeforeSideEffects.c_str(),NULL,source);
|
||||||
|
uses = use->getValue();
|
||||||
|
delete use;
|
||||||
|
if(counters == uses)
|
||||||
|
{
|
||||||
|
sa = sideEffect->clone();
|
||||||
|
sa->target = this->target;
|
||||||
|
sa->source = this->source;
|
||||||
|
if(sa->oneShot)
|
||||||
|
{
|
||||||
|
sa->fireAbility();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source, (Damageable *) (this->target), sa);
|
||||||
|
wrapper->addToGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fireAbility();
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4107,7 +4137,7 @@ int ActivatedAbility::reactToTargetClick(Targetable * object)
|
|||||||
AManaProducer * amp = dynamic_cast<AManaProducer *> (this);
|
AManaProducer * amp = dynamic_cast<AManaProducer *> (this);
|
||||||
if(amp)
|
if(amp)
|
||||||
{
|
{
|
||||||
needsTapping = amp->tap;
|
needsTapping = amp->tap;
|
||||||
}
|
}
|
||||||
if (needsTapping && source->isInPlay())
|
if (needsTapping && source->isInPlay())
|
||||||
{
|
{
|
||||||
@@ -4121,9 +4151,54 @@ int ActivatedAbility::reactToTargetClick(Targetable * object)
|
|||||||
}
|
}
|
||||||
if (amp)
|
if (amp)
|
||||||
{
|
{
|
||||||
|
counters++;
|
||||||
|
if(sideEffect && usesBeforeSideEffects.size())
|
||||||
|
{
|
||||||
|
WParsedInt * use = NEW WParsedInt(usesBeforeSideEffects.c_str(),NULL,source);
|
||||||
|
uses = use->getValue();
|
||||||
|
delete use;
|
||||||
|
if(counters == uses)
|
||||||
|
{
|
||||||
|
sa = sideEffect->clone();
|
||||||
|
sa->target = this->target;
|
||||||
|
sa->source = this->source;
|
||||||
|
if(sa->oneShot)
|
||||||
|
{
|
||||||
|
sa->fireAbility();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source, (Damageable *) (this->target), sa);
|
||||||
|
wrapper->addToGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
this->resolve();
|
this->resolve();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
counters++;
|
||||||
|
if(sideEffect && usesBeforeSideEffects.size())
|
||||||
|
{
|
||||||
|
WParsedInt * use = NEW WParsedInt(usesBeforeSideEffects.c_str(),NULL,source);
|
||||||
|
uses = use->getValue();
|
||||||
|
delete use;
|
||||||
|
if(counters == uses)
|
||||||
|
{
|
||||||
|
sa = sideEffect->clone();
|
||||||
|
sa->target = this->target;
|
||||||
|
sa->source = this->source;
|
||||||
|
if(sa->oneShot)
|
||||||
|
{
|
||||||
|
sa->fireAbility();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GenericInstantAbility * wrapper = NEW GenericInstantAbility(1, source, (Damageable *) (this->target), sa);
|
||||||
|
wrapper->addToGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
fireAbility();
|
fireAbility();
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@@ -4136,6 +4211,8 @@ ActivatedAbility::~ActivatedAbility()
|
|||||||
// Erwan 2004/04/25
|
// Erwan 2004/04/25
|
||||||
//if (!isClone){
|
//if (!isClone){
|
||||||
SAFE_DELETE(abilityCost);
|
SAFE_DELETE(abilityCost);
|
||||||
|
SAFE_DELETE(sideEffect);
|
||||||
|
SAFE_DELETE(sa);
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user