added support for cantbetargetof(something[optional])
for "this card cant be the target of green spells or abilities" style cards. added poisoned status trigger for attacking, so far its the only place this is checked. we will see what the next set does with this keyword
This commit is contained in:
@@ -425,7 +425,8 @@ class TrCardAttacked: public TriggeredAbility
|
||||
public:
|
||||
TargetChooser * tc;
|
||||
bool sourceUntapped;
|
||||
TrCardAttacked(int id, MTGCardInstance * source, TargetChooser * tc,bool sourceUntapped) :
|
||||
bool opponentPoisoned;
|
||||
TrCardAttacked(int id, MTGCardInstance * source, TargetChooser * tc,bool sourceUntapped,bool opponentPoisoned) :
|
||||
TriggeredAbility(id, source), tc(tc), sourceUntapped(sourceUntapped)
|
||||
{
|
||||
}
|
||||
@@ -444,6 +445,7 @@ public:
|
||||
return 0;
|
||||
if (e->card->didattacked < 1) return 0;
|
||||
if (!tc->canTarget(e->card)) return 0;
|
||||
if (opponentPoisoned && !source->controller()->opponent()->isPoisoned) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1984,6 +1986,44 @@ public:
|
||||
|
||||
};
|
||||
|
||||
//cant be target of...
|
||||
class ACantBeTargetFrom: public MTGAbility
|
||||
{
|
||||
public:
|
||||
TargetChooser * fromTc;
|
||||
ACantBeTargetFrom(int id, MTGCardInstance * _source, MTGCardInstance * _target, TargetChooser *fromTc) :
|
||||
MTGAbility(id, _source, _target), fromTc(fromTc)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int addToGame()
|
||||
{
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
_target->addCantBeTarget(fromTc);
|
||||
return MTGAbility::addToGame();
|
||||
}
|
||||
|
||||
int destroy()
|
||||
{
|
||||
((MTGCardInstance *) target)->removeCantBeTarget(fromTc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ACantBeTargetFrom * clone() const
|
||||
{
|
||||
ACantBeTargetFrom * a = NEW ACantBeTargetFrom(*this);
|
||||
a->fromTc = fromTc->clone();
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
~ACantBeTargetFrom()
|
||||
{
|
||||
SAFE_DELETE(fromTc);
|
||||
}
|
||||
|
||||
};
|
||||
//Can't be blocked by...
|
||||
class ACantBeBlockedBy: public MTGAbility
|
||||
{
|
||||
|
||||
@@ -155,6 +155,11 @@ class MTGCardInstance: public CardPrimitive, public MTGCard, public Damageable {
|
||||
int removeProtection(TargetChooser *tc, int erase = 0);
|
||||
int protectedAgainst(MTGCardInstance * card);
|
||||
|
||||
vector<TargetChooser *>canttarget;
|
||||
int addCantBeTarget(TargetChooser * tc);
|
||||
int removeCantBeTarget(TargetChooser *tc, int erase = 0);
|
||||
int CantBeTargetby(MTGCardInstance * card);
|
||||
|
||||
vector<TargetChooser *>cantBeBlockedBys;
|
||||
int addCantBeBlockedBy(TargetChooser * tc);
|
||||
int removeCantBeBlockedBy(TargetChooser *tc, int erase = 0);
|
||||
|
||||
@@ -288,6 +288,7 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string magicText, int
|
||||
bool once = false;
|
||||
bool sourceUntapped = false;
|
||||
bool sourceTap = false;
|
||||
bool opponentPoisoned = false;
|
||||
bool lifelost = false;
|
||||
int lifeamount = 0;
|
||||
found = s.find("once");
|
||||
@@ -317,6 +318,11 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string magicText, int
|
||||
lifelost = true;
|
||||
lifeamount = 2;
|
||||
}
|
||||
found = s.find("opponentpoisoned");
|
||||
if ( found != string::npos)
|
||||
{
|
||||
opponentPoisoned = true;
|
||||
}
|
||||
//Card Changed Zone
|
||||
found = s.find("movedto(");
|
||||
if (found != string::npos)
|
||||
@@ -419,7 +425,7 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string magicText, int
|
||||
TargetChooser *tc = tcf.createTargetChooser(starget, card);
|
||||
tc->targetter = NULL;
|
||||
|
||||
return NEW TrCardAttacked(id, card, tc,sourceUntapped);
|
||||
return NEW TrCardAttacked(id, card, tc,sourceUntapped,opponentPoisoned);
|
||||
}
|
||||
//Card is attacking alone
|
||||
found = s.find("attackedalone(");
|
||||
@@ -2524,7 +2530,28 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
}
|
||||
return NULL; //TODO
|
||||
}
|
||||
|
||||
//targetter can not target...
|
||||
found = s.find("cantbetargetof(");
|
||||
if (found == 0)
|
||||
{
|
||||
size_t end = s.find(")", found);
|
||||
string targets = s.substr(found + 15, end - found - 15);
|
||||
TargetChooserFactory tcf;
|
||||
TargetChooser * fromTc = tcf.createTargetChooser(targets, card);
|
||||
if (!fromTc)
|
||||
return NULL;
|
||||
fromTc->setAllZones();
|
||||
if (!activated)
|
||||
{
|
||||
if (card->hasType("instant") || card->hasType("sorcery") || forceUEOT)
|
||||
{
|
||||
return NULL; //TODO
|
||||
}
|
||||
return NEW ACantBeTargetFrom(id, card, target, fromTc);
|
||||
}
|
||||
return NULL; //TODO
|
||||
}
|
||||
|
||||
//Can't be blocked by...
|
||||
found = s.find("cantbeblockedby(");
|
||||
if (found == 0)
|
||||
|
||||
@@ -932,6 +932,38 @@ int MTGCardInstance::protectedAgainst(MTGCardInstance * card)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MTGCardInstance::addCantBeTarget(TargetChooser * tc)
|
||||
{
|
||||
tc->targetter = NULL;
|
||||
canttarget.push_back(tc);
|
||||
return canttarget.size();
|
||||
}
|
||||
|
||||
int MTGCardInstance::removeCantBeTarget(TargetChooser * tc, int erase)
|
||||
{
|
||||
for (size_t i = 0; i < canttarget.size(); i++)
|
||||
{
|
||||
if (canttarget[i] == tc)
|
||||
{
|
||||
if (erase)
|
||||
delete (canttarget[i]);
|
||||
canttarget.erase(canttarget.begin() + i);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MTGCardInstance::CantBeTargetby(MTGCardInstance * card)
|
||||
{
|
||||
for (size_t i = 0; i < canttarget.size(); i++)
|
||||
{
|
||||
if (canttarget[i]->canTarget(card))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MTGCardInstance::addCantBeBlockedBy(TargetChooser * tc)
|
||||
{
|
||||
cantBeBlockedBys.push_back(tc);
|
||||
|
||||
@@ -728,6 +728,7 @@ bool TargetChooser::canTarget(Targetable * target)
|
||||
{
|
||||
if (card->has(Constants::SHROUD)) return false;
|
||||
if (card->protectedAgainst(targetter)) return false;
|
||||
if (card->CantBeTargetby(targetter)) return false;
|
||||
if ((targetter->controller() != card->controller()) && card->has(Constants::OPPONENTSHROUD)) return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user