diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index b24b088cd..74b3dfb9c 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -2515,6 +2515,15 @@ public: }; // +/* assign a creature to block a target */ +class AABlock: public InstantAbility +{ +public: + AABlock(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost = NULL); + int resolve(); + AABlock * clone() const; +}; + /* create a parent child association between cards */ class AAConnect: public InstantAbility { diff --git a/projects/mtg/include/TargetChooser.h b/projects/mtg/include/TargetChooser.h index f0579f4bb..493fb46e3 100644 --- a/projects/mtg/include/TargetChooser.h +++ b/projects/mtg/include/TargetChooser.h @@ -260,6 +260,25 @@ public: virtual bool equals(TargetChooser * tc); }; +class BlockableChooser: public TypeTargetChooser +{ +public: + bool withoutProtections; + BlockableChooser(GameObserver *observer, int * _zones, int _nbzones, MTGCardInstance * card = NULL, int _maxtargets = 1, bool other = false, bool targetMin = false) : + TypeTargetChooser(observer, "creature",_zones, _nbzones, card, _maxtargets, other, targetMin) + { + } + ; + BlockableChooser(GameObserver *observer, MTGCardInstance * card = NULL, int _maxtargets = 1, bool other = false,bool targetMin = false) : + TypeTargetChooser(observer, "creature", card, _maxtargets, other,targetMin) + { + } + ; + virtual bool canTarget(Targetable * target, bool withoutProtections = false); + virtual BlockableChooser * clone() const; + virtual bool equals(TargetChooser * tc); +}; + class myCursesChooser: public TypeTargetChooser { public: diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 76b596139..b574e04e1 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -4798,6 +4798,31 @@ ABlinkGeneric::~ABlinkGeneric() SAFE_DELETE(ability); } +// target becomes blocked by source +AABlock::AABlock(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost) : +InstantAbility(observer, id, card, target) +{ + target = _target; +} + +int AABlock::resolve() +{ + MTGCardInstance * _target = (MTGCardInstance *) target; + source = (MTGCardInstance*)source; + if (_target && source->canBlock(_target)) + { + source->toggleDefenser(_target); + source->getObserver()->isInterrupting = NULL; + } + return 1; +} + +AABlock * AABlock::clone() const +{ + return NEW AABlock(*this); +} + + // target becomes a parent of card(source) AAConnect::AAConnect(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost) : InstantAbility(observer, id, card, target) diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 29c781144..d3618afe8 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -1012,13 +1012,24 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG } found = s.find("ability$!"); - if (found != string::npos && storedString.empty()) + if (found != string::npos && storedAbilityString.empty()) { size_t real_end = s.find("!$", found); size_t sIndex = found + 9; storedAbilityString.append(s.substr(sIndex, real_end - sIndex).c_str()); s.erase(sIndex, real_end - sIndex); } + else + { + found = unchangedS.find("ability$!");//did find it in a changed s, try unchanged. + if (found != string::npos && storedAbilityString.empty()) + { + size_t real_end = unchangedS.find("!$", found); + size_t sIndex = found + 9; + storedAbilityString.append(unchangedS.substr(sIndex, real_end - sIndex).c_str()); + unchangedS.erase(sIndex, real_end - sIndex); + } + } found = s.find("and!("); if (found != string::npos && found + 6 != ')' && storedAndAbility.empty()) @@ -2756,6 +2767,15 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG observer->connectRule = true; return NULL; } + //standard block + found = s.find("block"); + if (found != string::npos) + { + MTGAbility * a = NEW AABlock(observer, id, card, target); + a->oneShot = 1; + return a; + } + //create an association between cards. found = s.find("connect"); if (found != string::npos) diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index e03314c0a..44c5a1428 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -18,6 +18,13 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta size_t found; bool other = false; + found = s.find("blockable"); + if (found != string::npos) + { + int maxtargets = 1; + return NEW BlockableChooser(observer, card, maxtargets); + } + found = s.find("mytgt"); if (found == 0) { @@ -1511,6 +1518,35 @@ bool myCursesChooser::equals(TargetChooser * tc) return TypeTargetChooser::equals(tc); } +/*display cards blockable by source */ +bool BlockableChooser::canTarget(Targetable * target,bool withoutProtections) +{ + if (MTGCardInstance * card = dynamic_cast(target)) + { + if(!card->isAttacker() || !source->canBlock(card)) + return false; + return true; + } + return TypeTargetChooser::canTarget(target,withoutProtections); +} + +BlockableChooser* BlockableChooser::clone() const +{ + BlockableChooser * a = NEW BlockableChooser(*this); + return a; +} + +bool BlockableChooser::equals(TargetChooser * tc) +{ + + BlockableChooser * dtc = dynamic_cast (tc); + if (!dtc) + return false; + + return TypeTargetChooser::equals(tc); +} + +//----------- /*Proliferate Target */ bool ProliferateChooser::canTarget(Targetable * target,bool withoutProtections) {