diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 492e005a9..4f4b02962 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -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 { diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 3471392c9..8759caa2e 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -155,6 +155,11 @@ class MTGCardInstance: public CardPrimitive, public MTGCard, public Damageable { int removeProtection(TargetChooser *tc, int erase = 0); int protectedAgainst(MTGCardInstance * card); + vectorcanttarget; + int addCantBeTarget(TargetChooser * tc); + int removeCantBeTarget(TargetChooser *tc, int erase = 0); + int CantBeTargetby(MTGCardInstance * card); + vectorcantBeBlockedBys; int addCantBeBlockedBy(TargetChooser * tc); int removeCantBeBlockedBy(TargetChooser *tc, int erase = 0); diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 4ea99de7f..9d8fc5c61 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -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) diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index adb4bd9e9..5d6138562 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -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); diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index 2245df19e..11059d5ff 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -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;