From 494bcf3315c554a8ec4d78b035a354ceae2fbc96 Mon Sep 17 00:00:00 2001 From: "wagic.the.homebrew" Date: Wed, 4 May 2011 01:33:34 +0000 Subject: [PATCH] Adding a "loseAbilities" keyword per Dr.Solomat's request. The Goal was to code Evil Presence, but I think there is still some work to do to achieve this. The main concern is that (according to the Miki), neither transforms(( nor "becomes(" allow to lose some subtypes. A land enchanted with Evil Presence is supposed to lose its land subtypes. Since we don't support subtypes that good, I don't think this is possible. Additionally, Evil PResence would require to move "{T}:Add{X}" from the basic lands primitives into the rules (which sounds quite easy to do). I've nevertheless tested this on Gaea's Cradle, and it works. (Gaea's Cradle loses its abilities) --- .../bin/Res/sets/primitives/unsupported.txt | 5 ++ projects/mtg/include/ActionLayer.h | 2 + projects/mtg/include/AllAbilities.h | 11 ++++ projects/mtg/src/ActionLayer.cpp | 23 ++++--- projects/mtg/src/AllAbilities.cpp | 60 +++++++++++++++++++ projects/mtg/src/MTGAbility.cpp | 6 ++ 6 files changed, 100 insertions(+), 7 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/unsupported.txt b/projects/mtg/bin/Res/sets/primitives/unsupported.txt index 4ea003788..c49238b80 100644 --- a/projects/mtg/bin/Res/sets/primitives/unsupported.txt +++ b/projects/mtg/bin/Res/sets/primitives/unsupported.txt @@ -6574,8 +6574,13 @@ power=2 toughness=2 [/card] [card] +#Need a way for the target to lose its land subtypes. +#Need to move the {T}:Add{X} rules for basic lands outside of the cards and into the rules <-- easy? name=Evil Presence text=Enchant land -- Enchanted land is a Swamp. +target=land +auto=loseabilities +auto=transforms((swamp,)) mana={B} type=Enchantment subtype=Aura diff --git a/projects/mtg/include/ActionLayer.h b/projects/mtg/include/ActionLayer.h index cde484400..7f7cf059e 100644 --- a/projects/mtg/include/ActionLayer.h +++ b/projects/mtg/include/ActionLayer.h @@ -46,6 +46,8 @@ public: TargetChooser * getCurrentTargetChooser(); void setCurrentWaitingAction(ActionElement * ae); MTGAbility * getAbility(int type); + //Removes from game but does not move the element to garbage. The caller must take care of deleting the element. + int removeFromGame(ActionElement * e); int moveToGarbage(ActionElement * e); int cleanGarbage(); protected: diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index e711deeb0..4b84f923f 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -3606,6 +3606,17 @@ public: ~APreventDamageTypes(); }; +//Remove all abilities from target +class ALoseAbilities: public MTGAbility +{ +public: + vector storedAbilities; + ALoseAbilities(int id, MTGCardInstance * source, MTGCardInstance * target); + int addToGame(); + int destroy(); + ALoseAbilities * clone() const; +}; + //Adds types/abilities/P/T to a card (until end of turn) class APreventDamageTypesUEOT: public InstantAbility { diff --git a/projects/mtg/src/ActionLayer.cpp b/projects/mtg/src/ActionLayer.cpp index 0097115fa..05793a57d 100644 --- a/projects/mtg/src/ActionLayer.cpp +++ b/projects/mtg/src/ActionLayer.cpp @@ -18,17 +18,26 @@ MTGAbility* ActionLayer::getAbility(int type) return NULL; } -int ActionLayer::moveToGarbage(ActionElement * e) +int ActionLayer::removeFromGame(ActionElement * e) { mReactions.erase(e); int i = getIndexOf(e); - if (i != -1) + if (i == -1) + return 0; + + if (isWaitingForAnswer() == e) + setCurrentWaitingAction(NULL); + e->destroy(); + mObjects.erase(mObjects.begin() + i); + mCount--; + return 1; + +} + +int ActionLayer::moveToGarbage(ActionElement * e) +{ + if (removeFromGame(e)) { - if (isWaitingForAnswer() == e) - setCurrentWaitingAction(NULL); - e->destroy(); - mObjects.erase(mObjects.begin() + i); - mCount--; garbage.push_back(e); return 1; } diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 80df19d08..eeed6bee9 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -2797,6 +2797,66 @@ ASwapPTUEOT::~ASwapPTUEOT() SAFE_DELETE(ability); } + +//ALoseAbilities +ALoseAbilities::ALoseAbilities(int id, MTGCardInstance * source, MTGCardInstance * _target) : + MTGAbility(id, source) +{ + target = _target; +} + +int ALoseAbilities::addToGame() +{ + if (storedAbilities.size()) + { + DebugTrace("FATAL:storedAbilities shouldn't be already set inALoseAbilitie\n"); + return 0; + } + MTGCardInstance * _target = (MTGCardInstance *)target; + + ActionLayer * al = game->mLayers->actionLayer(); + + for (int i = al->mCount - 1; i > 0; i--) //0 is not a mtgability...hackish + { + if (al->mObjects[i]) + { + MTGAbility * currentAction = (MTGAbility *) al->mObjects[i]; + if (currentAction->source == _target) + { + storedAbilities.push_back(currentAction); + al->removeFromGame(currentAction); + } + } + } + + return MTGAbility::addToGame(); +} + +int ALoseAbilities::destroy() +{ + for (size_t i = 0; i < storedAbilities.size(); ++i) + { + MTGAbility * a = storedAbilities[i]; + //OneShot abilities are not supposed to stay in the game for long. + // If we copied one, something wrong probably happened + if (a->oneShot) + { + DebugTrace("ALL_ABILITIES: Ability should not be one shot"); + continue; + } + a->addToGame(); + } + storedAbilities.clear(); + return 1; +} + +ALoseAbilities * ALoseAbilities::clone() const +{ + ALoseAbilities * a = NEW ALoseAbilities(*this); + a->isClone = 1; + return a; +} + //APreventDamageTypes APreventDamageTypes::APreventDamageTypes(int id, MTGCardInstance * source, string to, string from, int type) : MTGAbility(id, source), to(to), from(from), type(type) diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index d593f2ae4..8ac0c21b3 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -1896,6 +1896,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG return NEW ABushidoAbility(id, card, power, toughness); } + //loseAbilities + if (s.find("loseabilities") != string::npos) + { + return NEW ALoseAbilities(id, card, target); + } + //counter vector splitCounter = parseBetween(s, "counter(", ")"); if (splitCounter.size())