From afc903e31b237cdff5707c4c04f384c7b9e19774 Mon Sep 17 00:00:00 2001 From: Dmitry Panin Date: Sun, 17 Nov 2013 00:42:34 +0400 Subject: [PATCH 1/2] Added different names for attach and equip + moved implementation of AEquip to .cpp --- projects/mtg/include/AllAbilities.h | 115 ++++------------------------ projects/mtg/src/AllAbilities.cpp | 108 ++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 102 deletions(-) diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index e1b65ab04..64e14ee8f 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -2794,113 +2794,24 @@ public: //equipment class AEquip: public TargetAbility { -public: +private: + bool isAttach; vector currentAbilities; - AEquip(GameObserver* observer, int _id, MTGCardInstance * _source, ManaCost * _cost = NULL, int restrictions = - ActivatedAbility::AS_SORCERY) : - TargetAbility(observer, _id, _source, NULL, _cost, restrictions) - { - aType = MTGAbility::STANDARD_EQUIP; - } + +public: + AEquip(GameObserver* observer, int _id, MTGCardInstance * _source, ManaCost * _cost = NULL, + int restrictions = ActivatedAbility::AS_SORCERY); - int unequip() - { - if (source->target) - { - source->target->equipment -= 1; - source->parentCards.clear(); - for(unsigned int w = 0;w < source->target->childrenCards.size();w++) - { - MTGCardInstance * child = source->target->childrenCards[w]; - if(child == source) - source->target->childrenCards.erase(source->target->childrenCards.begin() + w); - } - } - source->target = NULL; - for (size_t i = 0; i < currentAbilities.size(); ++i) - { - MTGAbility * a = currentAbilities[i]; - if (dynamic_cast (a) || dynamic_cast (a) || dynamic_cast (a) || (a->aType == MTGAbility::STANDARD_TOKENCREATOR && a->oneShot)) - { - SAFE_DELETE(a); - continue; - } - game->removeObserver(currentAbilities[i]); - } - currentAbilities.clear(); - return 1; - } + int unequip(); + int equip(MTGCardInstance * equipped); - int equip(MTGCardInstance * equipped) - { - source->target = equipped; - source->target->equipment += 1; - source->parentCards.push_back(equipped); - source->target->childrenCards.push_back((MTGCardInstance*)source); - AbilityFactory af(game); - af.getAbilities(¤tAbilities, NULL, source); - for (size_t i = 0; i < currentAbilities.size(); ++i) - { - MTGAbility * a = currentAbilities[i]; - if (dynamic_cast (a)) continue; - if (dynamic_cast (a)) continue; - if (dynamic_cast (a)) continue; - if (a->aType == MTGAbility::STANDARD_TOKENCREATOR && a->oneShot) - { - a->forceDestroy = 1; - continue; - } - if (dynamic_cast (af.getCoreAbility(a))) - { - a->forceDestroy = 1; - continue; - } - //we generally dont want to pass oneShot tokencreators to the cards - //we equip... - a->addToGame(); - } - return 1; + int resolve(); + const char * getMenuText(); - } - - int resolve() - { - MTGCardInstance * mTarget = tc->getNextCardTarget(); - if (!mTarget) return 0; - if (mTarget == source) return 0; - unequip(); - equip(mTarget); - return 1; - } - - const char * getMenuText() - { - return "Equip"; - } - - int testDestroy() - { - if (source->target && !game->isInPlay(source->target)) - unequip(); - if(!game->connectRule) - { - if (source->target && TargetAbility::tc && !TargetAbility::tc->canTarget((Targetable *)source->target,true)) - unequip(); - } - return TargetAbility::testDestroy(); - } - - int destroy() - { - unequip(); - return TargetAbility::destroy(); - } - - AEquip * clone() const - { - return NEW AEquip(*this); - } + int testDestroy(); + int destroy(); + AEquip * clone() const; }; class ATokenCreator: public ActivatedAbility diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 00cf88989..ce639bad0 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -5291,6 +5291,114 @@ AAConnect * AAConnect::clone() const return NEW AAConnect(*this); } +AEquip::AEquip(GameObserver* observer, int _id, MTGCardInstance * _source, ManaCost * _cost, int restrictions) : + TargetAbility(observer, _id, _source, NULL, _cost, restrictions) +{ + aType = MTGAbility::STANDARD_EQUIP; + isAttach = restrictions != ActivatedAbility::AS_SORCERY; +} + +int AEquip::unequip() +{ + if (source->target) + { + source->target->equipment -= 1; + source->parentCards.clear(); + for (unsigned int w = 0; w < source->target->childrenCards.size(); w++) + { + MTGCardInstance * child = source->target->childrenCards[w]; + if (child == source) + source->target->childrenCards.erase(source->target->childrenCards.begin() + w); + } + } + source->target = NULL; + for (size_t i = 0; i < currentAbilities.size(); ++i) + { + MTGAbility * a = currentAbilities[i]; + if (dynamic_cast (a) || dynamic_cast (a) || dynamic_cast (a) + || (a->aType == MTGAbility::STANDARD_TOKENCREATOR && a->oneShot)) + { + SAFE_DELETE(a); + continue; + } + game->removeObserver(currentAbilities[i]); + } + currentAbilities.clear(); + return 1; +} + +int AEquip::equip(MTGCardInstance * equipped) +{ + source->target = equipped; + source->target->equipment += 1; + source->parentCards.push_back(equipped); + source->target->childrenCards.push_back((MTGCardInstance*)source); + AbilityFactory af(game); + af.getAbilities(¤tAbilities, NULL, source); + for (size_t i = 0; i < currentAbilities.size(); ++i) + { + MTGAbility * a = currentAbilities[i]; + if (dynamic_cast (a)) continue; + if (dynamic_cast (a)) continue; + if (dynamic_cast (a)) continue; + if (a->aType == MTGAbility::STANDARD_TOKENCREATOR && a->oneShot) + { + a->forceDestroy = 1; + continue; + } + if (dynamic_cast (af.getCoreAbility(a))) + { + a->forceDestroy = 1; + continue; + } + //we generally dont want to pass oneShot tokencreators to the cards + //we equip... + a->addToGame(); + } + return 1; +} + +int AEquip::resolve() +{ + MTGCardInstance * mTarget = tc->getNextCardTarget(); + if (!mTarget) return 0; + if (mTarget == source) return 0; + unequip(); + equip(mTarget); + return 1; +} + +const char * AEquip::getMenuText() +{ + if (isAttach) + return "Attach"; + else + return "Equip"; +} + +int AEquip::testDestroy() +{ + if (source->target && !game->isInPlay(source->target)) + unequip(); + if (!game->connectRule) + { + if (source->target && TargetAbility::tc && !TargetAbility::tc->canTarget((Targetable *)source->target,true)) + unequip(); + } + return TargetAbility::testDestroy(); +} + +int AEquip::destroy() +{ + unequip(); + return TargetAbility::destroy(); +} + +AEquip * AEquip::clone() const +{ + return NEW AEquip(*this); +} + // casting a card for free, or casting a copy of a card. AACastCard::AACastCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target,bool _restricted,bool _copied,bool asNormal,string _namedCard,string _name,bool _noEvent) : MTGAbility(observer, _id, _source),restricted(_restricted),asCopy(_copied),normal(asNormal),cardNamed(_namedCard),nameThis(_name),noEvent(_noEvent) From 2835bdf76726ceab9e3f1e4b673f29c3a2ba0a7a Mon Sep 17 00:00:00 2001 From: Dmitry Panin Date: Sun, 17 Nov 2013 01:49:51 +0400 Subject: [PATCH 2/2] Fixed issue with Cranial Plating. Issue attach then equip: plating will give bonus to both creatures Fix Changed "attach" to "retarget target(creature|mybattlefield)" as this doesnot admit this bug Attach should become deprecated in future --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 10 +++++----- projects/mtg/src/AllAbilities.cpp | 1 + projects/mtg/src/MTGAbility.cpp | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index a1dec7f26..6d356044e 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -17432,7 +17432,7 @@ toughness=4 [card] name=Cranial Plating auto=foreach(artifact|mybattlefield) 1/0 -auto={B}{B}:attach +auto={B}{B}:name(attach) retarget target(creature|mybattlefield) auto={1}:equip text=Equipped creature gets +1/+0 for each artifact you control. -- {B}{B}: Attach Cranial Plating to target creature you control. -- Equip {1} ({1}: Attach to target creature you control. Equip only as a sorcery.) mana={2} @@ -39826,7 +39826,7 @@ name=Healer's Headdress auto={1}:equip auto=0/2 auto=teach(creature) {T}:prevent:1 target(creature,player) -auto={W}{W}:attach +auto={W}{W}:name(attach) retarget target(creature|mybattlefield) text=Equipped creature gets +0/+2 and has "{T}: Prevent the next 1 damage that would be dealt to target creature or player this turn." -- {W}{W}: Attach Healer's Headdress to target creature you control. -- Equip {1} ({1}: Attach to target creature you control. Equip only as a sorcery.) mana={2} type=Artifact @@ -41596,7 +41596,7 @@ toughness=2 name=Horned Helm auto=1/1 auto=trample -auto={G}{G}:attach +auto={G}{G}:name(attach) retarget target(creature|mybattlefield) auto={1}:equip text=Equipped creature gets +1/+1 and has trample. -- {G}{G}: Attach Horned Helm to target creature you control. -- Equip {1} ({1}: Attach to target creature you control. Equip only as a sorcery.) mana={2} @@ -59983,7 +59983,7 @@ toughness=2 [card] name=Neurok Stealthsuit auto=teach(creature) shroud -auto={U}{U}:attach +auto={U}{U}:name(attach) retarget target(creature|mybattlefield) auto={1}:equip text=Equipped creature has shroud. (It can't be the target of spells or abilities.) -- {U}{U}: Attach Neurok Stealthsuit to target creature you control. -- Equip {1} ({1}: Attach to target creature you control. Equip only as a sorcery.) mana={2} @@ -83437,7 +83437,7 @@ toughness=3 [card] name=Sparring Collar auto=first strike -auto={R}{R}:attach +auto={R}{R}:name(attach) retarget target(creature|mybattlefield) auto={1}:equip text=Equipped creature has first strike. -- {R}{R}: Attach Sparring Collar to target creature you control. -- Equip {1} ({1}: Attach to target creature you control. Equip only as a sorcery.) mana={2} diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index ce639bad0..8cbe9742d 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -5341,6 +5341,7 @@ int AEquip::equip(MTGCardInstance * equipped) if (dynamic_cast (a)) continue; if (dynamic_cast (a)) continue; if (dynamic_cast (a)) continue; + if (dynamic_cast (af.getCoreAbility(a))) continue; if (a->aType == MTGAbility::STANDARD_TOKENCREATOR && a->oneShot) { a->forceDestroy = 1; diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 4535f1d13..ff52b934a 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -2163,6 +2163,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG return NEW AEquip(observer, id, card); } + // TODO: deprecate this ability in favor of retarget //Equipment (attach) found = s.find("attach"); if (found != string::npos)