- some dangerous casts Player/MTGCardInstance fixed
- removed typeAsTarget function and replaced with dynamic casting - The test suite passes, but it is possible that I busted some of AI's features :(
This commit is contained in:
@@ -98,6 +98,7 @@ class AIPlayerBaka: public AIPlayer{
|
||||
|
||||
//used by MomirPlayer, hence protected instead of private
|
||||
virtual int getEfficiency(OrderedAIAction * action);
|
||||
virtual int getEfficiency(MTGAbility * ability);
|
||||
virtual bool payTheManaCost(ManaCost * cost, MTGCardInstance * card = NULL,vector<MTGAbility*> gotPayment = vector<MTGAbility*>());
|
||||
virtual int getCreaturesInfo(Player * player, int neededInfo = INFO_NBCREATURES , int untapMode = 0, int canAttack = 0);
|
||||
virtual ManaCost * getPotentialMana(MTGCardInstance * card = NULL);
|
||||
|
||||
@@ -77,11 +77,6 @@ public:
|
||||
virtual void Render()
|
||||
{
|
||||
}
|
||||
|
||||
int typeAsTarget()
|
||||
{
|
||||
return TARGET_STACKACTION;
|
||||
}
|
||||
|
||||
Interruptible(GameObserver* observer, int inID = 0, bool hasFocus = false)
|
||||
: PlayGuiObject(40, x, y, inID, hasFocus), Targetable(observer), state(NOT_RESOLVED), display(0), source(NULL)
|
||||
@@ -139,7 +134,7 @@ public:
|
||||
Interruptible * getNextInterruptible(Interruptible * previous, int type);
|
||||
Spell * getNextSpellTarget(Spell * previous = 0);
|
||||
Damage * getNextDamageTarget(Damage * previous = 0);
|
||||
Targetable * getNextTarget(Targetable * previous = 0, int type = -1);
|
||||
Targetable * getNextTarget(Targetable * previous = 0);
|
||||
int getNbTargets();
|
||||
};
|
||||
|
||||
|
||||
@@ -113,7 +113,6 @@ public:
|
||||
MTGCardInstance * changeController(Player * newcontroller);
|
||||
Player * owner;
|
||||
Counters * counters;
|
||||
int typeAsTarget(){return TARGET_CARD;}
|
||||
const string getDisplayName() const;
|
||||
MTGCardInstance * target;
|
||||
vector<Targetable *> backupTargets;
|
||||
|
||||
@@ -250,7 +250,7 @@ class MTGVampireRule: public PermanentAbility
|
||||
{
|
||||
public:
|
||||
MTGVampireRule(GameObserver* observer, int _id);
|
||||
map<MTGCardInstance*,vector<MTGCardInstance*> > victems;
|
||||
map<MTGCardInstance*,vector<MTGCardInstance*> > victims;
|
||||
int receiveEvent(WEvent * event);
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
virtual MTGVampireRule * clone() const;
|
||||
|
||||
@@ -48,10 +48,6 @@ public:
|
||||
return 1;
|
||||
}
|
||||
const string getDisplayName() const;
|
||||
int typeAsTarget()
|
||||
{
|
||||
return TARGET_PLAYER;
|
||||
}
|
||||
|
||||
int afterDamage();
|
||||
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
#ifndef _TARGETABLE_H_
|
||||
#define _TARGETABLE_H_
|
||||
|
||||
#define TARGET_CARD 1
|
||||
#define TARGET_PLAYER 2
|
||||
#define TARGET_STACKACTION 3
|
||||
|
||||
class Targetable
|
||||
{
|
||||
protected:
|
||||
GameObserver* observer;
|
||||
public:
|
||||
Targetable(GameObserver* observer) : observer(observer) {};
|
||||
virtual int typeAsTarget() = 0;
|
||||
virtual const string getDisplayName() const = 0;
|
||||
inline GameObserver* getObserver() { return observer; };
|
||||
virtual void setObserver(GameObserver*g) { observer = g; };
|
||||
|
||||
@@ -14,6 +14,8 @@ using std::vector;
|
||||
|
||||
class TargetsList
|
||||
{
|
||||
private:
|
||||
size_t iterateTarget(Targetable * previous);
|
||||
public:
|
||||
TargetsList();
|
||||
TargetsList(Targetable * _targets[], int nbtargets);
|
||||
@@ -28,7 +30,7 @@ public:
|
||||
Interruptible * getNextInterruptible(Interruptible * previous, int type);
|
||||
Spell * getNextSpellTarget(Spell * previous = 0);
|
||||
Damage * getNextDamageTarget(Damage * previous = 0);
|
||||
Targetable * getNextTarget(Targetable * previous = 0, int type = -1);
|
||||
Targetable * getNextTarget(Targetable * previous = 0);
|
||||
void initTargets()
|
||||
{
|
||||
targets.clear();
|
||||
|
||||
@@ -98,24 +98,17 @@ int AIAction::clickMultiAct(vector<Targetable*>& actionTargets)
|
||||
}
|
||||
ite++;
|
||||
}
|
||||
owner->getRandomGenerator()->random_shuffle(actionTargets.begin(), actionTargets.end());
|
||||
|
||||
//shuffle to make it less predictable, otherwise ai will always seem to target from right to left. making it very obvious.
|
||||
for(int k = 0;k < int(actionTargets.size());k++)
|
||||
owner->getRandomGenerator()->random_shuffle(actionTargets.begin(), actionTargets.end());
|
||||
|
||||
for(int k = 0 ;k < int(actionTargets.size()) && k < tc->maxtargets; k++)
|
||||
{
|
||||
int type = actionTargets[k]->typeAsTarget();
|
||||
switch (type)
|
||||
if (MTGCardInstance * card = dynamic_cast<MTGCardInstance *>(actionTargets[k]))
|
||||
{
|
||||
case TARGET_CARD:
|
||||
{
|
||||
if(k < tc->maxtargets)
|
||||
{
|
||||
MTGCardInstance * card = ((MTGCardInstance *) actionTargets[k]);
|
||||
if(k+1 == int(actionTargets.size()))
|
||||
tc->done = true;
|
||||
g->cardClick(card);
|
||||
}
|
||||
}
|
||||
break;
|
||||
if(k+1 == int(actionTargets.size()))
|
||||
tc->done = true;
|
||||
g->cardClick(card);
|
||||
}
|
||||
}
|
||||
tc->attemptsToFill++;
|
||||
@@ -158,16 +151,15 @@ int AIPlayer::clickMultiTarget(TargetChooser * tc, vector<Targetable*>& potentia
|
||||
vector<Targetable*>::iterator ite = potentialTargets.begin();
|
||||
while(ite != potentialTargets.end())
|
||||
{
|
||||
MTGCardInstance * card = ((MTGCardInstance *) (*ite));
|
||||
Player * pTarget = (Player*)(*ite);
|
||||
if(card && card == (MTGCardInstance*)tc->source)//if the source is part of the targetting deal with it first. second click is "confirming click".
|
||||
MTGCardInstance * card = dynamic_cast<MTGCardInstance *>(*ite);
|
||||
if(card && card == tc->source)//if the source is part of the targetting deal with it first. second click is "confirming click".
|
||||
{
|
||||
clickstream.push(NEW AIAction(this, card));
|
||||
DebugTrace("Ai clicked source as a target: " << (card ? card->name : "None" ) << endl );
|
||||
ite = potentialTargets.erase(ite);
|
||||
continue;
|
||||
}
|
||||
if(pTarget && pTarget->typeAsTarget() == TARGET_PLAYER)
|
||||
else if(Player * pTarget = dynamic_cast<Player *>(*ite))
|
||||
{
|
||||
clickstream.push(NEW AIAction(this, pTarget));
|
||||
DebugTrace("Ai clicked Player as a target");
|
||||
@@ -192,26 +184,18 @@ int AIPlayer::clickMultiTarget(TargetChooser * tc, vector<Targetable*>& potentia
|
||||
|
||||
int AIPlayer::clickSingleTarget(TargetChooser * tc, vector<Targetable*>& potentialTargets, MTGCardInstance * chosenCard)
|
||||
{
|
||||
int i = randomGenerator.random() % potentialTargets.size();
|
||||
int type = potentialTargets[i]->typeAsTarget();
|
||||
switch (type)
|
||||
{
|
||||
case TARGET_CARD:
|
||||
{
|
||||
if(!chosenCard)
|
||||
{
|
||||
MTGCardInstance * card = ((MTGCardInstance *) potentialTargets[i]);
|
||||
clickstream.push(NEW AIAction(this, card));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TARGET_PLAYER:
|
||||
{
|
||||
Player * player = ((Player *) potentialTargets[i]);
|
||||
clickstream.push(NEW AIAction(this, player));
|
||||
break;
|
||||
}
|
||||
}
|
||||
int i = randomGenerator.random() % potentialTargets.size();
|
||||
|
||||
if(MTGCardInstance * card = dynamic_cast<MTGCardInstance *>(potentialTargets[i]))
|
||||
{
|
||||
if (!chosenCard)
|
||||
clickstream.push(NEW AIAction(this, card));
|
||||
}
|
||||
else if(Player * player = dynamic_cast<Player *>(potentialTargets[i]))
|
||||
{
|
||||
clickstream.push(NEW AIAction(this, player));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,6 @@ Player * OrderedAIAction::getPlayerTarget()
|
||||
if (playerAbilityTarget)
|
||||
return (Player *)playerAbilityTarget;
|
||||
|
||||
if (target && target->typeAsTarget() == TARGET_PLAYER)
|
||||
return (Player *)target;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -408,9 +405,9 @@ int OrderedAIAction::getEfficiency()
|
||||
AbilityFactory af(g);
|
||||
int suggestion = af.abilityEfficiency(a, p, MODE_ABILITY);
|
||||
|
||||
if(_t->typeAsTarget() == TARGET_CARD)
|
||||
if(MTGCardInstance * cTarget = dynamic_cast<MTGCardInstance *>(_t))
|
||||
{
|
||||
if((suggestion == BAKA_EFFECT_BAD && ((MTGCardInstance*)_t)->controller() == p) || (suggestion == BAKA_EFFECT_GOOD && ((MTGCardInstance*)_t)->controller() != p))
|
||||
if((suggestion == BAKA_EFFECT_BAD && (cTarget)->controller() == p) || (suggestion == BAKA_EFFECT_GOOD && (cTarget)->controller() != p))
|
||||
efficiency = 0;
|
||||
}
|
||||
else if ((suggestion == BAKA_EFFECT_BAD && _t == p) || (suggestion == BAKA_EFFECT_GOOD && _t != p))
|
||||
@@ -549,16 +546,16 @@ int OrderedAIAction::getEfficiency()
|
||||
}
|
||||
else if (AAProliferate * aap = dynamic_cast<AAProliferate *>(a))
|
||||
{
|
||||
if (aap && target && target->typeAsTarget() == TARGET_PLAYER && (Player*)target != p)
|
||||
if (playerAbilityTarget && playerAbilityTarget != p)
|
||||
{
|
||||
efficiency = 60;//ai determines if the counters are good or bad on menu check.
|
||||
}
|
||||
else if (aap)
|
||||
else
|
||||
efficiency = 90;
|
||||
}
|
||||
else if (AAAlterPoison * aaap = dynamic_cast<AAAlterPoison *>(a))
|
||||
{
|
||||
if (aaap && target && target->typeAsTarget() == TARGET_PLAYER && (Player*)target != p)
|
||||
if (playerAbilityTarget && playerAbilityTarget != p)
|
||||
{
|
||||
efficiency = 90;
|
||||
}
|
||||
@@ -566,7 +563,7 @@ int OrderedAIAction::getEfficiency()
|
||||
else if (ATokenCreator * atc = dynamic_cast<ATokenCreator *>(a))
|
||||
{
|
||||
efficiency = 80;
|
||||
if(atc && atc->name.length() && atc->sabilities.length() && atc->types.size() && p->game->inPlay->findByName(atc->name))
|
||||
if(atc->name.length() && atc->sabilities.length() && atc->types.size() && p->game->inPlay->findByName(atc->name))
|
||||
{
|
||||
list<int>::iterator it;
|
||||
for (it = atc->types.begin(); it != atc->types.end(); it++)
|
||||
@@ -1196,23 +1193,22 @@ int AIPlayerBaka::createAbilityTargets(MTGAbility * a, MTGCardInstance * c, Rank
|
||||
a->getActionTc()->done = true;
|
||||
return 0;
|
||||
}
|
||||
int targetThis = 0;
|
||||
while(potentialTargets.size())
|
||||
{
|
||||
OrderedAIAction * check = NULL;
|
||||
|
||||
MTGCardInstance * targeting = dynamic_cast<MTGCardInstance*>(potentialTargets[0]);
|
||||
if(targeting && targeting->typeAsTarget() == TARGET_CARD)
|
||||
check = NEW OrderedAIAction(this, a,c,targeting);
|
||||
MTGCardInstance * cTargeting = dynamic_cast<MTGCardInstance*>(potentialTargets[0]);
|
||||
if(cTargeting)
|
||||
check = NEW OrderedAIAction(this, a,c,cTargeting);
|
||||
|
||||
Player * ptargeting = dynamic_cast<Player*>(potentialTargets[0]);
|
||||
if(ptargeting && ptargeting->typeAsTarget() == TARGET_PLAYER)
|
||||
check = NEW OrderedAIAction(this, a,ptargeting,c);
|
||||
Player * pTargeting = dynamic_cast<Player*>(potentialTargets[0]);
|
||||
if(pTargeting)
|
||||
check = NEW OrderedAIAction(this, a,pTargeting,c);
|
||||
|
||||
targetThis = getEfficiency(check);
|
||||
if(targetThis && ptargeting && ptargeting->typeAsTarget() == TARGET_PLAYER)
|
||||
int targetThis = getEfficiency(check);
|
||||
if(targetThis && pTargeting)
|
||||
{
|
||||
OrderedAIAction aiAction(this, a,ptargeting,c);
|
||||
OrderedAIAction aiAction(this, a,pTargeting,c);
|
||||
ranking[aiAction] = 1;
|
||||
}
|
||||
if(targetThis)
|
||||
@@ -1223,7 +1219,9 @@ int AIPlayerBaka::createAbilityTargets(MTGAbility * a, MTGCardInstance * c, Rank
|
||||
if(!realTargets.size() || (int(realTargets.size()) < a->getActionTc()->maxtargets && a->getActionTc()->targetMin))
|
||||
return 0;
|
||||
OrderedAIAction aiAction(this, a, c,realTargets);
|
||||
|
||||
aiAction.target = dynamic_cast<MTGCardInstance*>(realTargets[0]);
|
||||
aiAction.playerAbilityTarget = dynamic_cast<Player*>(realTargets[0]);
|
||||
ranking[aiAction] = 1;
|
||||
}
|
||||
return 1;
|
||||
@@ -1508,6 +1506,29 @@ int AIPlayerBaka::chooseTarget(TargetChooser * _tc, Player * forceTarget,MTGCard
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Returns -1 if error, a number between 0 and 100 otherwise
|
||||
int AIPlayerBaka::getEfficiency(MTGAbility * ability)
|
||||
{
|
||||
if (!ability)
|
||||
return -1;
|
||||
|
||||
OrderedAIAction * check = NULL;
|
||||
|
||||
if(MTGCardInstance * cTarget = dynamic_cast<MTGCardInstance *>(ability->target))
|
||||
check = NEW OrderedAIAction(this, ability, ability->source, cTarget);
|
||||
else if(Player * pTarget = dynamic_cast<Player *>(ability->target))
|
||||
check = NEW OrderedAIAction(this, ability, pTarget, ability->source);
|
||||
else
|
||||
check = NEW OrderedAIAction(this, ability, ability->source);
|
||||
|
||||
if (!check)
|
||||
return -1;
|
||||
|
||||
int result = getEfficiency(check);
|
||||
SAFE_DELETE(check);
|
||||
return result;
|
||||
}
|
||||
|
||||
int AIPlayerBaka::selectMenuOption()
|
||||
{
|
||||
ActionLayer * object = observer->mLayers->actionLayer();
|
||||
@@ -1515,10 +1536,10 @@ int AIPlayerBaka::selectMenuOption()
|
||||
if (object->menuObject)
|
||||
{
|
||||
int checkedLast = 0;
|
||||
int checked = 0;
|
||||
MenuAbility * currentMenu = NULL;
|
||||
|
||||
if(object->abilitiesMenu->isMultipleChoice && object->currentActionCard)
|
||||
{
|
||||
MenuAbility * currentMenu = NULL;
|
||||
for(size_t m = object->mObjects.size()-1;m > 0;m--)
|
||||
{
|
||||
MenuAbility * ability = dynamic_cast<MenuAbility *>(object->mObjects[m]);
|
||||
@@ -1531,60 +1552,28 @@ int AIPlayerBaka::selectMenuOption()
|
||||
if(currentMenu)
|
||||
for(unsigned int mk = 0;mk < currentMenu->abilities.size();mk++)
|
||||
{
|
||||
MTGAbility * checkEff = NULL;
|
||||
OrderedAIAction * check = NULL;
|
||||
checkEff = currentMenu->abilities[mk];
|
||||
if(checkEff)
|
||||
{
|
||||
if(checkEff->target && checkEff->target->typeAsTarget() == TARGET_CARD)
|
||||
check = NEW OrderedAIAction(this, checkEff,checkEff->source,(MTGCardInstance*)checkEff->target);
|
||||
else if(checkEff->target && checkEff->target->typeAsTarget() == TARGET_PLAYER)
|
||||
check = NEW OrderedAIAction(this, checkEff,(Player*)checkEff->target,checkEff->source);
|
||||
else
|
||||
check = NEW OrderedAIAction(this, checkEff,checkEff->source);
|
||||
}
|
||||
if(check)
|
||||
{
|
||||
checked = getEfficiency(check);
|
||||
SAFE_DELETE(check);
|
||||
}
|
||||
int checked = getEfficiency(currentMenu->abilities[mk]);
|
||||
if(checked > 60 && checked > checkedLast)
|
||||
{
|
||||
doThis = mk;
|
||||
checkedLast = checked;
|
||||
}
|
||||
checked = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(unsigned int k = 0;k < object->abilitiesMenu->mObjects.size();k++)
|
||||
{
|
||||
MTGAbility * checkEff = NULL;
|
||||
OrderedAIAction * check = NULL;
|
||||
if(object->abilitiesMenu->mObjects[k]->GetId() >= 0)
|
||||
checkEff = (MTGAbility *)object->mObjects[object->abilitiesMenu->mObjects[k]->GetId()];
|
||||
if(checkEff)
|
||||
{
|
||||
Targetable * checkTarget = checkEff->target;
|
||||
if(checkTarget && checkTarget->typeAsTarget() == TARGET_CARD)
|
||||
check = NEW OrderedAIAction(this, checkEff,checkEff->source,(MTGCardInstance*)checkTarget);
|
||||
else if(checkTarget && checkTarget->typeAsTarget() == TARGET_PLAYER)
|
||||
check = NEW OrderedAIAction(this, checkEff,(Player*)checkTarget,checkEff->source);
|
||||
else
|
||||
check = NEW OrderedAIAction(this, checkEff,checkEff->source);
|
||||
}
|
||||
if(check)
|
||||
{
|
||||
checked = getEfficiency(check);
|
||||
SAFE_DELETE(check);
|
||||
}
|
||||
if(object->abilitiesMenu->mObjects[k]->GetId() <= 0)
|
||||
continue;
|
||||
|
||||
MTGAbility * checkEff = (MTGAbility *)object->mObjects[object->abilitiesMenu->mObjects[k]->GetId()];
|
||||
int checked = getEfficiency(checkEff);
|
||||
if(checked > 60 && checked > checkedLast)
|
||||
{
|
||||
doThis = k;
|
||||
checkedLast = checked;
|
||||
}
|
||||
checked = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,14 +39,14 @@ int ActionElement::getActivity()
|
||||
|
||||
int ActionElement::isReactingToTargetClick(Targetable * object)
|
||||
{
|
||||
if (object && object->typeAsTarget() == TARGET_CARD)
|
||||
return isReactingToClick((MTGCardInstance *) object);
|
||||
if (MTGCardInstance * cObject = dynamic_cast<MTGCardInstance *>(object))
|
||||
return isReactingToClick(cObject);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ActionElement::reactToTargetClick(Targetable * object)
|
||||
{
|
||||
if (object->typeAsTarget() == TARGET_CARD)
|
||||
return reactToClick((MTGCardInstance *) object);
|
||||
if (MTGCardInstance * cObject = dynamic_cast<MTGCardInstance *>(object))
|
||||
return reactToClick(cObject);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -148,8 +148,7 @@ void StackAbility::Render()
|
||||
_target = t;
|
||||
}
|
||||
Damageable * target = NULL;
|
||||
if (_target != ability->source && (_target->typeAsTarget() == TARGET_CARD || _target->typeAsTarget()
|
||||
== TARGET_PLAYER))
|
||||
if (_target != ability->source && (dynamic_cast<MTGCardInstance *>(_target) || dynamic_cast<Player *>(_target)))
|
||||
{
|
||||
target = (Damageable *) _target;
|
||||
}
|
||||
@@ -346,11 +345,11 @@ Damage * Spell::getNextDamageTarget(Damage * previous)
|
||||
return NULL;
|
||||
return tc->getNextDamageTarget(previous);
|
||||
}
|
||||
Targetable * Spell::getNextTarget(Targetable * previous, int type)
|
||||
Targetable * Spell::getNextTarget(Targetable * previous)
|
||||
{
|
||||
if (!tc)
|
||||
return NULL;
|
||||
return tc->getNextTarget(previous, type);
|
||||
return tc->getNextTarget(previous);
|
||||
}
|
||||
|
||||
int Spell::getNbTargets()
|
||||
|
||||
@@ -568,19 +568,23 @@ int AAProliferate::resolve()
|
||||
return 0;
|
||||
|
||||
vector<MTGAbility*>pcounters;
|
||||
if(target->typeAsTarget() == TARGET_PLAYER && ((Player*)target)->poisonCount && target != source->controller())
|
||||
|
||||
Player * pTarget = dynamic_cast<Player *>(target);
|
||||
MTGCardInstance * cTarget = dynamic_cast<MTGCardInstance *>(target);
|
||||
|
||||
if(pTarget && pTarget->poisonCount && pTarget != source->controller())
|
||||
{
|
||||
MTGAbility * a = NEW AAAlterPoison(game, game->mLayers->actionLayer()->getMaxId(), source, target, 1, NULL);
|
||||
a->oneShot = true;
|
||||
pcounters.push_back(a);
|
||||
}
|
||||
else if (target->typeAsTarget() == TARGET_CARD && ((MTGCardInstance*)target)->counters)
|
||||
else if (cTarget && cTarget->counters)
|
||||
{
|
||||
Counters * counters = ((MTGCardInstance*)target)->counters;
|
||||
Counters * counters = cTarget->counters;
|
||||
for(size_t i = 0; i < counters->counters.size(); ++i)
|
||||
{
|
||||
Counter * counter = counters->counters[i];
|
||||
MTGAbility * a = NEW AACounter(game, game->mLayers->actionLayer()->getMaxId(), source, (MTGCardInstance*)target,"", counter->name.c_str(), counter->power, counter->toughness, 1,0);
|
||||
MTGAbility * a = NEW AACounter(game, game->mLayers->actionLayer()->getMaxId(), source, cTarget,"", counter->name.c_str(), counter->power, counter->toughness, 1,0);
|
||||
a->oneShot = true;
|
||||
pcounters.push_back(a);
|
||||
}
|
||||
@@ -651,13 +655,13 @@ int AAFizzler::resolve()
|
||||
//ai is casting a spell from its hand to fizzle.
|
||||
target = stack->getActionElementFromCard(source->target);
|
||||
}
|
||||
else if(target->typeAsTarget() == TARGET_CARD)
|
||||
else if(MTGCardInstance * cTarget = dynamic_cast<MTGCardInstance *>(target))
|
||||
{
|
||||
//ai targeted using an ability on a card to fizzle.
|
||||
target = stack->getActionElementFromCard((MTGCardInstance*)target);
|
||||
target = stack->getActionElementFromCard(cTarget);
|
||||
}
|
||||
Spell * sTarget = (Spell *) target;
|
||||
MTGCardInstance* sCard = (MTGCardInstance*)sTarget->source;
|
||||
MTGCardInstance* sCard = sTarget->source;
|
||||
if(!sCard || !sTarget || sCard->has(Constants::NOFIZZLE))
|
||||
return 0;
|
||||
stack->Fizzle(sTarget);
|
||||
@@ -1062,7 +1066,7 @@ int AADynamic::resolve()
|
||||
_target = OriginalSrc->controller()->opponent();//looking at controllers opponent for amount
|
||||
if(!_target)
|
||||
return 0;
|
||||
while (_target->typeAsTarget() == TARGET_CARD && ((MTGCardInstance *)_target)->next)
|
||||
while (dynamic_cast<MTGCardInstance *>(_target) && ((MTGCardInstance *)_target)->next)
|
||||
_target = ((MTGCardInstance *)_target)->next;
|
||||
|
||||
//find the amount variables that will be used
|
||||
@@ -1178,7 +1182,7 @@ int AADynamic::resolve()
|
||||
}
|
||||
if (_target)
|
||||
{
|
||||
while (_target->typeAsTarget() == TARGET_CARD && ((MTGCardInstance *)_target)->next)
|
||||
while (dynamic_cast<MTGCardInstance *>(_target) && ((MTGCardInstance *)_target)->next)
|
||||
_target = ((MTGCardInstance *)_target)->next;
|
||||
if(sourceamount < 0)
|
||||
sourceamount = 0;
|
||||
@@ -1306,7 +1310,7 @@ int AADynamic::resolve()
|
||||
}
|
||||
case DYNAMIC_ABILITY_EFFECT_COUNTERSONEONE:
|
||||
{
|
||||
if(_target->typeAsTarget() != TARGET_CARD)
|
||||
if(!dynamic_cast<MTGCardInstance *>(_target))
|
||||
_target = OriginalSrc;
|
||||
for(int j = 0;j < sourceamount;j++)
|
||||
((MTGCardInstance*)_target)->counters->addCounter(1,1);
|
||||
@@ -2168,8 +2172,10 @@ int IfThenAbility::resolve()
|
||||
MTGAbility * a1 = delayedAbility->clone();
|
||||
if (!a1)
|
||||
return 0;
|
||||
if(a1->target && a1->target->typeAsTarget() != TARGET_PLAYER)
|
||||
a1->target = aTarget;
|
||||
|
||||
if(a1->target && !dynamic_cast<Player *>(a1->target))
|
||||
a1->target = aTarget;
|
||||
|
||||
if(a1->oneShot)
|
||||
{
|
||||
a1->resolve();
|
||||
|
||||
@@ -1043,7 +1043,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
if (amp)
|
||||
{
|
||||
amp->setCost(cost);
|
||||
if (cost && card->typeAsTarget() == TARGET_CARD)
|
||||
if (cost)
|
||||
cost->setExtraCostsAction(a, card);
|
||||
amp->oneShot = 0;
|
||||
amp->tap = doTap;
|
||||
@@ -3620,10 +3620,13 @@ Player * MTGAbility::getPlayerFromTarget(Targetable * target)
|
||||
if (!target)
|
||||
return NULL;
|
||||
|
||||
if (target->typeAsTarget() == TARGET_CARD)
|
||||
return ((MTGCardInstance *) target)->controller();
|
||||
if (MTGCardInstance * cTarget = dynamic_cast<MTGCardInstance *>(target))
|
||||
return cTarget->controller();
|
||||
|
||||
return (Player *) target;
|
||||
if (Player * cPlayer = dynamic_cast<Player *>(target))
|
||||
return cPlayer;
|
||||
|
||||
return ((Interruptible *) target)->source->controller();
|
||||
}
|
||||
|
||||
Player * MTGAbility::getPlayerFromDamageable(Damageable * target)
|
||||
@@ -3770,8 +3773,8 @@ int ActivatedAbility::reactToTargetClick(Targetable * object)
|
||||
ManaCost * cost = getCost();
|
||||
if (cost)
|
||||
{
|
||||
if (object->typeAsTarget() == TARGET_CARD)
|
||||
cost->setExtraCostsAction(this, (MTGCardInstance *) object);
|
||||
if (MTGCardInstance * cObject = dynamic_cast<MTGCardInstance *>(object))
|
||||
cost->setExtraCostsAction(this, cObject);
|
||||
if (!cost->isExtraPaymentSet())
|
||||
{
|
||||
game->mExtraPayment = cost->extraCosts;
|
||||
@@ -3891,8 +3894,9 @@ TargetAbility::TargetAbility(GameObserver* observer, int id, MTGCardInstance * c
|
||||
|
||||
int TargetAbility::reactToTargetClick(Targetable * object)
|
||||
{
|
||||
if (object->typeAsTarget() == TARGET_CARD)
|
||||
return reactToClick((MTGCardInstance *) object);
|
||||
if (MTGCardInstance * cObject = dynamic_cast<MTGCardInstance *>(object))
|
||||
return reactToClick(cObject);
|
||||
|
||||
if (waitingForAnswer)
|
||||
{
|
||||
if (tc->toggleTarget(object) == TARGET_OK_FULL)
|
||||
@@ -3976,7 +3980,7 @@ int TargetAbility::resolve()
|
||||
|
||||
ability->target = t;
|
||||
//do nothing if the target controller responded by phasing out the target.
|
||||
if (t->typeAsTarget() == TARGET_CARD && ((MTGCardInstance*)t)->isPhased)
|
||||
if (dynamic_cast<MTGCardInstance *>(t) && ((MTGCardInstance*)t)->isPhased)
|
||||
return 0;
|
||||
if (ability->oneShot)
|
||||
{
|
||||
@@ -4575,21 +4579,12 @@ int AManaProducer::isReactingToClick(MTGCardInstance * _card, ManaCost * mana)
|
||||
int AManaProducer::resolve()
|
||||
{
|
||||
Targetable * _target = getTarget();
|
||||
Player * player;
|
||||
if (_target)
|
||||
{
|
||||
if (_target->typeAsTarget() == TARGET_CARD)
|
||||
{
|
||||
player = ((MTGCardInstance *) _target)->controller();
|
||||
}
|
||||
else
|
||||
{
|
||||
player = (Player *) _target;
|
||||
}
|
||||
player->getManaPool()->add(output, source);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
Player * player = getPlayerFromTarget(_target);
|
||||
if (!player)
|
||||
return 0;
|
||||
|
||||
player->getManaPool()->add(output, source);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int AManaProducer::reactToClick(MTGCardInstance * _card)
|
||||
@@ -4672,19 +4667,7 @@ Targetable * AbilityTP::getTarget()
|
||||
switch (who)
|
||||
{
|
||||
case TargetChooser::TARGET_CONTROLLER:
|
||||
if (target)
|
||||
{
|
||||
switch (target->typeAsTarget())
|
||||
{
|
||||
case TARGET_CARD:
|
||||
return ((MTGCardInstance *) target)->controller();
|
||||
case TARGET_STACKACTION:
|
||||
return ((Interruptible *) target)->source->controller();
|
||||
default:
|
||||
return (Player *) target;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return getPlayerFromTarget(target);
|
||||
case TargetChooser::CONTROLLER:
|
||||
return source->controller();
|
||||
case TargetChooser::OPPONENT:
|
||||
@@ -4709,19 +4692,7 @@ Targetable * ActivatedAbilityTP::getTarget()
|
||||
switch (who)
|
||||
{
|
||||
case TargetChooser::TARGET_CONTROLLER:
|
||||
if (target)
|
||||
{
|
||||
switch (target->typeAsTarget())
|
||||
{
|
||||
case TARGET_CARD:
|
||||
return ((MTGCardInstance *) target)->controller();
|
||||
case TARGET_STACKACTION:
|
||||
return ((Interruptible *) target)->source->controller();
|
||||
default:
|
||||
return (Player *) target;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return getPlayerFromTarget(target);
|
||||
case TargetChooser::CONTROLLER:
|
||||
return source->controller();
|
||||
case TargetChooser::OPPONENT:
|
||||
@@ -4747,19 +4718,7 @@ Targetable * InstantAbilityTP::getTarget()
|
||||
switch (who)
|
||||
{
|
||||
case TargetChooser::TARGET_CONTROLLER:
|
||||
if (target)
|
||||
{
|
||||
switch (target->typeAsTarget())
|
||||
{
|
||||
case TARGET_CARD:
|
||||
return ((MTGCardInstance *) target)->controller();
|
||||
case TARGET_STACKACTION:
|
||||
return ((Interruptible *) target)->source->controller();
|
||||
default:
|
||||
return (Player *) target;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return getPlayerFromTarget(target);
|
||||
case TargetChooser::CONTROLLER:
|
||||
return source->controller();
|
||||
case TargetChooser::OPPONENT:
|
||||
|
||||
@@ -1877,52 +1877,53 @@ PermanentAbility(observer, _id)
|
||||
|
||||
int MTGVampireRule::receiveEvent(WEvent * event)
|
||||
{
|
||||
WEventDamage * e = dynamic_cast<WEventDamage *> (event);
|
||||
WEventZoneChange * z = dynamic_cast<WEventZoneChange *> (event);
|
||||
WEventPhaseChange * pe = dynamic_cast<WEventPhaseChange*>(event);
|
||||
if (e)
|
||||
if (WEventDamage * e = dynamic_cast<WEventDamage *> (event))
|
||||
{
|
||||
if(!e->damage->damage)
|
||||
return 0;
|
||||
if (!e->damage->target)
|
||||
return 0;
|
||||
if(e->damage->target->typeAsTarget() != TARGET_CARD)
|
||||
|
||||
MTGCardInstance * newVictim = dynamic_cast<MTGCardInstance*>(e->damage->target);
|
||||
if(!newVictim)
|
||||
return 0;
|
||||
MTGCardInstance * newVictem = (MTGCardInstance*)(e->damage->target);
|
||||
|
||||
MTGCardInstance * vampire = (MTGCardInstance*)(e->damage->source);
|
||||
|
||||
victems[newVictem].push_back(vampire);
|
||||
victims[newVictim].push_back(vampire);
|
||||
|
||||
}
|
||||
else if (z)
|
||||
else if ( WEventZoneChange * z = dynamic_cast<WEventZoneChange *> (event))
|
||||
{
|
||||
MTGCardInstance * card = z->card->previous;
|
||||
if(card && victems[card].empty())
|
||||
if(card && victims[card].empty())
|
||||
return 0;
|
||||
std::sort(victems[card].begin(), victems[card].end());
|
||||
victems[card].erase(std::unique(victems[card].begin(), victems[card].end()), victems[card].end());
|
||||
|
||||
//sort and remove duplicates, we only want one event of a vampire damaging a card stored per victem.
|
||||
for(unsigned int w = 0;w < victems[card].size();w++)
|
||||
std::sort(victims[card].begin(), victims[card].end());
|
||||
victims[card].erase(std::unique(victims[card].begin(), victims[card].end()), victims[card].end());
|
||||
|
||||
for(unsigned int w = 0;w < victims[card].size();w++)
|
||||
{
|
||||
if(victems[card].at(w) == NULL)
|
||||
if(victims[card].at(w) == NULL)
|
||||
continue;
|
||||
Player * p = card->controller();
|
||||
if (z->from == p->game->inPlay && z->to == p->game->graveyard)
|
||||
{
|
||||
if(card == z->card->previous)
|
||||
{
|
||||
WEvent * e = NEW WEventVampire(card,victems[card].at(w),card);
|
||||
WEvent * e = NEW WEventVampire(card,victims[card].at(w),card);
|
||||
game->receiveEvent(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if (pe)
|
||||
else if (WEventPhaseChange * pe = dynamic_cast<WEventPhaseChange*>(event))
|
||||
{
|
||||
if( pe->from->id == Constants::MTG_PHASE_ENDOFTURN)
|
||||
{
|
||||
victems.clear();
|
||||
victims.clear();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -467,16 +467,17 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
|
||||
size_t start = attribute.find("share!");
|
||||
size_t end = attribute.rfind("!");
|
||||
string CDtype = attribute.substr(start + 6,end - start);
|
||||
if( card && card->isSpell() && card->backupTargets.size() && card->backupTargets[0]->typeAsTarget() == TARGET_STACKACTION)
|
||||
|
||||
if( card && card->isSpell() && card->backupTargets.size())
|
||||
{
|
||||
//spells always store their targets in :targets[]
|
||||
//however they are all erased as the spell resolves
|
||||
//added a array to store these backups incase theyre needed
|
||||
//again for effects such as these.
|
||||
Spell * spell;
|
||||
spell = (Spell*)card->backupTargets[0];
|
||||
if(spell)
|
||||
card->target = spell->source;
|
||||
if (Spell * targetSpell = dynamic_cast<Spell *>(card->backupTargets[0]))
|
||||
{
|
||||
//spells always store their targets in :targets[]
|
||||
//however they are all erased as the spell resolves
|
||||
//added a array to store these backups incase theyre needed
|
||||
//again for effects such as these.
|
||||
card->target = targetSpell->source;
|
||||
}
|
||||
}
|
||||
if( CDtype.find("name") != string::npos )
|
||||
{
|
||||
@@ -715,9 +716,8 @@ TargetChooser::TargetChooser(GameObserver *observer, MTGCardInstance * card, int
|
||||
bool TargetChooser::canTarget(Targetable * target,bool withoutProtections)
|
||||
{
|
||||
if (!target) return false;
|
||||
if (target->typeAsTarget() == TARGET_CARD)
|
||||
if (MTGCardInstance * card = dynamic_cast<MTGCardInstance *>(target))
|
||||
{
|
||||
MTGCardInstance * card = (MTGCardInstance *) target;
|
||||
if (other)
|
||||
{
|
||||
MTGCardInstance * tempcard = card;
|
||||
@@ -747,7 +747,9 @@ bool TargetChooser::canTarget(Targetable * target,bool withoutProtections)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (target->typeAsTarget() == TARGET_STACKACTION) return true;
|
||||
else if (dynamic_cast<Interruptible *>(target))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -875,10 +877,12 @@ CardTargetChooser::CardTargetChooser(GameObserver *observer, MTGCardInstance * _
|
||||
bool CardTargetChooser::canTarget(Targetable * target,bool withoutProtections)
|
||||
{
|
||||
if (!target) return false;
|
||||
if (target->typeAsTarget() != TARGET_CARD) return false;
|
||||
|
||||
MTGCardInstance * card = dynamic_cast<MTGCardInstance *>(target);
|
||||
if (!card) return false;
|
||||
if (!nbzones && !TargetChooser::canTarget(target,withoutProtections)) return false;
|
||||
if (nbzones && !TargetZoneChooser::canTarget(target,withoutProtections)) return false;
|
||||
MTGCardInstance * card = (MTGCardInstance *) target;
|
||||
|
||||
while (card)
|
||||
{
|
||||
if (card == validTarget) return true;
|
||||
@@ -953,9 +957,8 @@ void TypeTargetChooser::addType(int type)
|
||||
bool TypeTargetChooser::canTarget(Targetable * target,bool withoutProtections)
|
||||
{
|
||||
if (!TargetZoneChooser::canTarget(target,withoutProtections)) return false;
|
||||
if (target->typeAsTarget() == TARGET_CARD)
|
||||
if (MTGCardInstance * card = dynamic_cast<MTGCardInstance *>(target))
|
||||
{
|
||||
MTGCardInstance * card = (MTGCardInstance *) target;
|
||||
for (int i = 0; i < nbtypes; i++)
|
||||
{
|
||||
|
||||
@@ -967,9 +970,9 @@ bool TypeTargetChooser::canTarget(Targetable * target,bool withoutProtections)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (target->typeAsTarget() == TARGET_STACKACTION)
|
||||
else if (Interruptible * action = dynamic_cast<Interruptible *>(target))
|
||||
{
|
||||
Interruptible * action = (Interruptible *) target;
|
||||
|
||||
if (action->type == ACTION_SPELL && action->state == NOT_RESOLVED)
|
||||
{
|
||||
Spell * spell = (Spell *) action;
|
||||
@@ -1049,15 +1052,13 @@ DescriptorTargetChooser::DescriptorTargetChooser(GameObserver *observer, CardDes
|
||||
bool DescriptorTargetChooser::canTarget(Targetable * target,bool withoutProtections)
|
||||
{
|
||||
if (!TargetZoneChooser::canTarget(target,withoutProtections)) return false;
|
||||
if (target->typeAsTarget() == TARGET_CARD)
|
||||
if (MTGCardInstance * _target = dynamic_cast<MTGCardInstance *>(target))
|
||||
{
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
if (cd->match(_target))
|
||||
return true;
|
||||
}
|
||||
else if (target->typeAsTarget() == TARGET_STACKACTION)
|
||||
else if (Interruptible * action = dynamic_cast<Interruptible *>(target))
|
||||
{
|
||||
Interruptible * action = (Interruptible *) target;
|
||||
if (action->type == ACTION_SPELL && action->state == NOT_RESOLVED)
|
||||
{
|
||||
Spell * spell = (Spell *) action;
|
||||
@@ -1126,22 +1127,19 @@ int TargetZoneChooser::setAllZones()
|
||||
bool TargetZoneChooser::canTarget(Targetable * target,bool withoutProtections)
|
||||
{
|
||||
if (!TargetChooser::canTarget(target,withoutProtections)) return false;
|
||||
if (target->typeAsTarget() == TARGET_CARD)
|
||||
if (MTGCardInstance * card = dynamic_cast<MTGCardInstance *>(target))
|
||||
{
|
||||
MTGCardInstance * card = (MTGCardInstance *) target;
|
||||
for (int i = 0; i < nbzones; i++)
|
||||
{
|
||||
if (zones[i] == MTGGameZone::ALL_ZONES) return true;
|
||||
if (MTGGameZone::intToZone(observer, zones[i], source, card)->hasCard(card)) return true;
|
||||
}
|
||||
}
|
||||
else if (target->typeAsTarget() == TARGET_STACKACTION)
|
||||
else if (Spell * spell = dynamic_cast<Spell *>(target))
|
||||
{
|
||||
DebugTrace("CHECKING INTERRUPTIBLE\n");
|
||||
Interruptible * action = (Interruptible *) target;
|
||||
if (action->type == ACTION_SPELL && action->state == NOT_RESOLVED)
|
||||
DebugTrace("CHECKING Spell\n");
|
||||
if (spell->state == NOT_RESOLVED)
|
||||
{
|
||||
Spell * spell = (Spell *) action;
|
||||
MTGCardInstance * card = spell->source;
|
||||
for (int i = 0; i < nbzones; i++)
|
||||
if (MTGGameZone::intToZone(Owner->getObserver(), zones[i], source, card)->hasCard(card)) return true;
|
||||
@@ -1217,7 +1215,9 @@ bool PlayerTargetChooser::canTarget(Targetable * target,bool withoutProtections)
|
||||
if (source && targetter && (targetter->controller() == targetter->controller())
|
||||
&& (targetter->controller()->game->inPlay->hasAbility(Constants::PLAYERSHROUD)) && targetter->controller()
|
||||
== target) return false;
|
||||
return (target->typeAsTarget() == TARGET_PLAYER) && (!p || p == (Player*) target);
|
||||
|
||||
Player * pTarget = dynamic_cast<Player *>(target);
|
||||
return (pTarget && (!p || p == pTarget));
|
||||
}
|
||||
|
||||
PlayerTargetChooser* PlayerTargetChooser::clone() const
|
||||
@@ -1251,7 +1251,7 @@ bool DamageableTargetChooser::canTarget(Targetable * target,bool withoutProtecti
|
||||
if (source && targetter && (targetter->controller() == targetter->controller())
|
||||
&& (targetter->controller()->game->inPlay->hasAbility(Constants::PLAYERSHROUD)) && targetter->controller()
|
||||
== target) return false;
|
||||
if (target->typeAsTarget() == TARGET_PLAYER)
|
||||
if (dynamic_cast<Player *>(target))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1284,16 +1284,14 @@ SpellTargetChooser::SpellTargetChooser(GameObserver *observer, MTGCardInstance *
|
||||
|
||||
bool SpellTargetChooser::canTarget(Targetable * target,bool withoutProtections)
|
||||
{
|
||||
MTGCardInstance * card = NULL;
|
||||
if (target->typeAsTarget() == TARGET_STACKACTION)
|
||||
Spell * spell = dynamic_cast<Spell *>(target);
|
||||
if (!spell)
|
||||
return false;
|
||||
|
||||
if (spell->state == NOT_RESOLVED)
|
||||
{
|
||||
Interruptible * action = (Interruptible *) target;
|
||||
if (action->type == ACTION_SPELL && action->state == NOT_RESOLVED)
|
||||
{
|
||||
Spell * spell = (Spell *) action;
|
||||
card = spell->source;
|
||||
if (card && (color == -1 || card->hasColor(color))) return true;
|
||||
}
|
||||
MTGCardInstance * card = spell->source;
|
||||
if (card && (color == -1 || card->hasColor(color))) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -1329,19 +1327,16 @@ SpellOrPermanentTargetChooser::SpellOrPermanentTargetChooser(GameObserver *obser
|
||||
|
||||
bool SpellOrPermanentTargetChooser::canTarget(Targetable * target,bool withoutProtections)
|
||||
{
|
||||
MTGCardInstance * card = NULL;
|
||||
if (target->typeAsTarget() == TARGET_CARD)
|
||||
|
||||
if (MTGCardInstance * card = dynamic_cast<MTGCardInstance *>(target))
|
||||
{
|
||||
card = (MTGCardInstance *) target;
|
||||
if (color == -1 || card->hasColor(color)) return TargetZoneChooser::canTarget(target,withoutProtections);
|
||||
}
|
||||
else if (target->typeAsTarget() == TARGET_STACKACTION)
|
||||
else if (Spell * spell = dynamic_cast<Spell *>(target))
|
||||
{
|
||||
Interruptible * action = (Interruptible *) target;
|
||||
if (action->type == ACTION_SPELL && action->state == NOT_RESOLVED)
|
||||
if (spell->state == NOT_RESOLVED)
|
||||
{
|
||||
Spell * spell = (Spell *) action;
|
||||
card = spell->source;
|
||||
MTGCardInstance * card = spell->source;
|
||||
if (card && (color == -1 || card->hasColor(color))) return true;
|
||||
}
|
||||
}
|
||||
@@ -1377,14 +1372,11 @@ DamageTargetChooser::DamageTargetChooser(GameObserver *observer, MTGCardInstance
|
||||
|
||||
bool DamageTargetChooser::canTarget(Targetable * target,bool withoutProtections)
|
||||
{
|
||||
MTGCardInstance * card = NULL;
|
||||
if (target->typeAsTarget() == TARGET_STACKACTION)
|
||||
if ( Damage * damage = dynamic_cast<Damage *>(target))
|
||||
{
|
||||
Interruptible * action = (Interruptible *) target;
|
||||
if (action->type == ACTION_DAMAGE && (action->state == state || state == -1))
|
||||
if (damage->state == state || state == -1)
|
||||
{
|
||||
Damage * damage = (Damage *) action;
|
||||
card = damage->source;
|
||||
MTGCardInstance * card = damage->source;
|
||||
if (card && (color == -1 || card->hasColor(color))) return true;
|
||||
}
|
||||
}
|
||||
@@ -1450,16 +1442,14 @@ bool TriggerTargetChooser::equals(TargetChooser * tc)
|
||||
/*Proliferate Target */
|
||||
bool ProliferateChooser::canTarget(Targetable * target,bool withoutProtections)
|
||||
{
|
||||
if (target->typeAsTarget() == TARGET_CARD)
|
||||
if (MTGCardInstance * card = dynamic_cast<MTGCardInstance*>(target))
|
||||
{
|
||||
MTGCardInstance * card = (MTGCardInstance*)target;
|
||||
if(card->counters && card->counters->counters.empty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if (target->typeAsTarget() == TARGET_PLAYER)
|
||||
else if (Player * p = dynamic_cast<Player*>(target))
|
||||
{
|
||||
Player * p = (Player*)target;
|
||||
if(!p->poisonCount)
|
||||
return false;
|
||||
return true;
|
||||
@@ -1486,9 +1476,8 @@ bool ProliferateChooser::equals(TargetChooser * tc)
|
||||
/*parents or children Target */
|
||||
bool ParentChildChooser::canTarget(Targetable * target,bool withoutProtections)
|
||||
{
|
||||
if (target->typeAsTarget() == TARGET_CARD)
|
||||
{
|
||||
MTGCardInstance * card = (MTGCardInstance*)target;
|
||||
if (MTGCardInstance * card = dynamic_cast<MTGCardInstance*>(target))
|
||||
{
|
||||
if(type == 1)
|
||||
{
|
||||
if(!source->childrenCards.size())
|
||||
|
||||
@@ -24,7 +24,7 @@ int TargetsList::addTarget(Targetable * target)
|
||||
if(!tc || (tc && tc->maxtargets == 1))
|
||||
{
|
||||
//because this was originally coded with targets as an array
|
||||
//we have to add this condiational to insure that cards with single target effects
|
||||
//we have to add this conditional to insure that cards with single target effects
|
||||
//and abilities that seek the nextcardtarget still work correctly.
|
||||
targets.clear();
|
||||
targets.push_back(target);
|
||||
@@ -76,46 +76,66 @@ int TargetsList::toggleTarget(Targetable * target)
|
||||
}
|
||||
}
|
||||
|
||||
Targetable * TargetsList::getNextTarget(Targetable * previous, int type)
|
||||
{
|
||||
int found = 0;
|
||||
if (!previous) found = 1;
|
||||
for (size_t i = 0; i < targets.size(); i++)
|
||||
{
|
||||
if (found && (type == -1 || targets[i]->typeAsTarget() == type))
|
||||
{
|
||||
return targets[i];
|
||||
}
|
||||
if (targets[i] == previous) found = 1;
|
||||
size_t TargetsList::iterateTarget(Targetable * previous){
|
||||
if (!previous)
|
||||
return 0;
|
||||
|
||||
for (size_t i = 0; i < targets.size(); i++) {
|
||||
if (targets[i] == previous)
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
return targets.size() + 1;
|
||||
|
||||
}
|
||||
|
||||
Targetable * TargetsList::getNextTarget(Targetable * previous)
|
||||
{
|
||||
size_t nextIndex = iterateTarget(previous);
|
||||
|
||||
if (nextIndex < targets.size())
|
||||
return targets[nextIndex];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MTGCardInstance * TargetsList::getNextCardTarget(MTGCardInstance * previous)
|
||||
{
|
||||
return ((MTGCardInstance *) getNextTarget(previous, TARGET_CARD));
|
||||
size_t nextIndex = iterateTarget(previous);
|
||||
for (size_t i = nextIndex; i < targets.size(); ++i)
|
||||
{
|
||||
if (MTGCardInstance * c = dynamic_cast<MTGCardInstance *>(targets[i]))
|
||||
return c;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Player * TargetsList::getNextPlayerTarget(Player * previous)
|
||||
{
|
||||
return ((Player *) getNextTarget(previous, TARGET_PLAYER));
|
||||
size_t nextIndex = iterateTarget(previous);
|
||||
for (size_t i = nextIndex; i < targets.size(); ++i)
|
||||
{
|
||||
if (Player * p = dynamic_cast<Player *>(targets[i]))
|
||||
return p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Interruptible * TargetsList::getNextInterruptible(Interruptible * previous, int type)
|
||||
{
|
||||
int found = 0;
|
||||
if (!previous) found = 1;
|
||||
for (size_t i = 0; i < targets.size(); i++)
|
||||
size_t nextIndex = iterateTarget(previous);
|
||||
|
||||
for (size_t i = nextIndex; i < targets.size(); i++)
|
||||
{
|
||||
if (found && targets[i]->typeAsTarget() == TARGET_STACKACTION)
|
||||
if (Interruptible * action = dynamic_cast<Interruptible *>(targets[i]))
|
||||
{
|
||||
Interruptible * action = (Interruptible *) targets[i];
|
||||
if (action->type == type)
|
||||
{
|
||||
return action;
|
||||
}
|
||||
}
|
||||
if (targets[i] == previous) found = 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -135,32 +155,17 @@ Damage * TargetsList::getNextDamageTarget(Damage * previous)
|
||||
|
||||
Damageable * TargetsList::getNextDamageableTarget(Damageable * previous)
|
||||
{
|
||||
int found = 0;
|
||||
if (!previous) found = 1;
|
||||
for (size_t i = 0; i < targets.size(); i++)
|
||||
size_t nextIndex = iterateTarget(previous);
|
||||
for (size_t i = nextIndex; i < targets.size(); i++)
|
||||
{
|
||||
|
||||
if (targets[i]->typeAsTarget() == TARGET_PLAYER)
|
||||
if (Player * pTarget = dynamic_cast<Player *>(targets[i]))
|
||||
{
|
||||
if (found)
|
||||
{
|
||||
return ((Player *) targets[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((Player *) targets[i] == previous) found = 1;
|
||||
}
|
||||
return pTarget;
|
||||
}
|
||||
else if (targets[i]->typeAsTarget() == TARGET_CARD)
|
||||
else if (MTGCardInstance * cTarget = dynamic_cast<MTGCardInstance *>(targets[i]))
|
||||
{
|
||||
if (found)
|
||||
{
|
||||
return ((MTGCardInstance *) targets[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((MTGCardInstance *) targets[i] == previous) found = 1;
|
||||
}
|
||||
return cTarget;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
Reference in New Issue
Block a user