From d4e1d809f398c2e3dc7d970804f831623b022759 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 16 Mar 2017 16:58:56 +0800 Subject: [PATCH] Bushido & Modular add Bushido and Modular points --- projects/mtg/bin/Res/sets/primitives/mtg.txt | 90 ++++++++++----- .../bin/Res/sets/primitives/unsupported.txt | 27 ----- projects/mtg/include/AllAbilities.h | 103 +++++++++++++++--- projects/mtg/include/CardPrimitive.h | 3 + projects/mtg/include/MTGCardInstance.h | 2 + projects/mtg/include/MTGDefinitions.h | 3 +- projects/mtg/src/CardPrimitive.cpp | 12 ++ projects/mtg/src/MTGAbility.cpp | 8 +- projects/mtg/src/MTGCardInstance.cpp | 3 + projects/mtg/src/MTGDeck.cpp | 13 ++- projects/mtg/src/MTGDefinitions.cpp | 3 +- 11 files changed, 192 insertions(+), 75 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index f587d21c0..cf689bb4b 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -5029,7 +5029,8 @@ type=Instant [/card] [card] name=Arcbound Bruiser -auto=counter(1/1,3) +abilities=trample,modular +modular=3 auto=@movedTo(this|mygraveyard) from(myBattlefield):may thisforeach(counter{1/1.1}) counter(1/1,1) target(creature[artifact]) text=Modular 3 (This enters the battlefield with three +1/+1 counters on it. When it's put into a graveyard, you may put its +1/+1 counters on target artifact creature.) mana={5} @@ -5040,10 +5041,10 @@ toughness=0 [/card] [card] name=Arcbound Crusher -abilities=trample -auto=@movedTo(other artifact|battlefield):counter(1/1,1) -auto=counter(1/1,1) +abilities=trample,modular +modular=1 auto=@movedTo(this|mygraveyard) from(myBattlefield):may thisforeach(counter{1/1.1}) counter(1/1,1) target(creature[artifact]) +auto=@movedTo(other artifact|battlefield):counter(1/1,1) text=Trample -- Whenever another artifact enters the battlefield, put a +1/+1 counter on Arcbound Crusher. -- Modular 1 (This enters the battlefield with a +1/+1 counter on it. When it's put into a graveyard, you may put its +1/+1 counters on target artifact creature.) mana={4} type=Artifact Creature @@ -5053,10 +5054,9 @@ toughness=0 [/card] [card] name=Arcbound Fiend -abilities=fear -auto=@each my upkeep:counter(1/1,-1) target(creature) -auto=@each my upkeep:counter(1/1,1) all(this) -auto=counter(1/1,3) +abilities=fear,modular +auto=@each my upkeep:may counter(1/1,-1) target(creature[counter{1/1.1}]) && counter(1/1,1) all(this) +modular=3 auto=@movedTo(this|mygraveyard) from(myBattlefield):may thisforeach(counter{1/1.1}) counter(1/1,1) target(creature[artifact]) text=Fear (This creature can't be blocked except by artifact creatures and/or black creatures.) -- At the beginning of your upkeep, you may move a +1/+1 counter from target creature onto Arcbound Fiend. -- Modular 3 (This enters the battlefield with three +1/+1 counters on it. When it's put into a graveyard, you may put its +1/+1 counters on target artifact creature.) mana={6} @@ -5067,8 +5067,8 @@ toughness=0 [/card] [card] name=Arcbound Hybrid -abilities=haste -auto=counter(1/1,2) +abilities=haste,modular +modular=2 auto=@movedTo(this|mygraveyard) from(myBattlefield):may thisforeach(counter{1/1.1}) counter(1/1,1) target(creature[artifact]) text=Haste -- Modular 2 (This enters the battlefield with two +1/+1 counters on it. When it's put into a graveyard, you may put its +1/+1 counters on target artifact creature.) mana={4} @@ -5079,8 +5079,8 @@ toughness=0 [/card] [card] name=Arcbound Lancer -abilities=first strike -auto=counter(1/1,4) +abilities=first strike,modular +modular=4 auto=@movedTo(this|mygraveyard) from(myBattlefield):may thisforeach(counter{1/1.1}) counter(1/1,1) target(creature[artifact]) text=First strike -- Modular 4 (This enters the battlefield with four +1/+1 counters on it. When it's put into a graveyard, you may put its +1/+1 counters on target artifact creature.) mana={7} @@ -5090,10 +5090,24 @@ power=0 toughness=0 [/card] [card] -name=Arcbound Ravager -auto=counter(1/1,1) -auto={S(artifact|myBattlefield)}:counter(1/1,1) +name=Arcbound Overseer +abilities=modular +modular=6 auto=@movedTo(this|mygraveyard) from(myBattlefield):may thisforeach(counter{1/1.1}) counter(1/1,1) target(creature[artifact]) +auto=@each my upkeep:counter(1/1) all(creature[modular]|mybattlefield) +text=At the beginning of your upkeep, put a +1/+1 counter on each creature with modular you control. -- Modular 6 (This enters the battlefield with six +1/+1 counters on it. When it dies, you may put its +1/+1 counters on target artifact creature.) +mana={8} +type=Artifact Creature +subtype=Golem +power=0 +toughness=0 +[/card] +[card] +name=Arcbound Ravager +abilities=modular +modular=1 +auto=@movedTo(this|mygraveyard) from(myBattlefield):may thisforeach(counter{1/1.1}) counter(1/1,1) target(creature[artifact]) +auto={S(artifact|myBattlefield)}:counter(1/1,1) text=Sacrifice an artifact: Put a +1/+1 counter on Arcbound Ravager. -- Modular 1 (This enters the battlefield with a +1/+1 counter on it. When it's put into a graveyard, you may put its +1/+1 counters on target artifact creature.) mana={2} type=Artifact Creature @@ -5103,9 +5117,10 @@ toughness=0 [/card] [card] name=Arcbound Reclaimer -auto=counter(1/1,2) -auto={C(1/1,-1)}:moveTo(myLibrary) target(artifact|mygraveyard) +abilities=modular +modular=2 auto=@movedTo(this|mygraveyard) from(myBattlefield):may thisforeach(counter{1/1.1}) counter(1/1,1) target(creature[artifact]) +auto={C(1/1,-1)}:moveTo(myLibrary) target(artifact|mygraveyard) text=Remove a +1/+1 counter from Arcbound Reclaimer: Put target artifact card from your graveyard on top of your library. -- Modular 2 (This enters the battlefield with two +1/+1 counters on it. When it's put into a graveyard, you may put its +1/+1 counters on target artifact creature.) mana={4} type=Artifact Creature @@ -5115,9 +5130,10 @@ toughness=0 [/card] [card] name=Arcbound Slith -auto=counter(1/1,1) -auto=@combatdamaged(player) from(this):counter(1/1,1) +abilities=modular +modular=1 auto=@movedTo(this|mygraveyard) from(myBattlefield):may thisforeach(counter{1/1.1}) counter(1/1,1) target(creature[artifact]) +auto=@combatdamaged(player) from(this):counter(1/1,1) text=Whenever Arcbound Slith deals combat damage to a player, put a +1/+1 counter on it. -- Modular 1 (This enters the battlefield with a +1/+1 counter on it. When it's put into a graveyard, you may put its +1/+1 counters on target artifact creature.) mana={2} type=Artifact Creature @@ -5127,8 +5143,8 @@ toughness=0 [/card] [card] name=Arcbound Stinger -abilities=flying -auto=counter(1/1,1) +abilities=flying,modular +modular=1 auto=@movedTo(this|mygraveyard) from(myBattlefield):may thisforeach(counter{1/1.1}) counter(1/1,1) target(creature[artifact]) text=Flying -- Modular 1 (This enters the battlefield with a +1/+1 counter on it. When it's put into a graveyard, you may put its +1/+1 counters on target artifact creature.) mana={2} @@ -5139,8 +5155,8 @@ toughness=0 [/card] [card] name=Arcbound Wanderer -abilities=sunburst -auto=counter(1/1,sunburst) +abilities=sunburst,modular +modular=sunburst auto=@movedTo(this|mygraveyard) from(myBattlefield):may thisforeach(counter{1/1.1}) counter(1/1,1) target(creature[artifact]) text=Modular - Sunburst (This enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it. When it's put into a graveyard, you may put its +1/+1 counters on target artifact creature.) mana={6} @@ -5151,7 +5167,8 @@ toughness=0 [/card] [card] name=Arcbound Worker -auto=counter(1/1,1) +abilities=modular +modular=1 auto=@movedTo(this|mygraveyard) from(myBattlefield):may thisforeach(counter{1/1.1}) counter(1/1,1) target(creature[artifact]) text=Modular 1 (This enters the battlefield with a +1/+1 counter on it. When it's put into a graveyard, you may put its +1/+1 counters on target artifact creature.) mana={1} @@ -44051,7 +44068,8 @@ type=Sorcery [/card] [card] name=Fumiko the Lowblood -auto=aslongas(creature[attacking]) bushido(type:creature[attacking]:battlefield/type:creature[attacking]:battlefield) +alias=74534 +auto=bushido(type:creature[attacking]:battlefield/type:creature[attacking]:battlefield) auto=lord(creature|opponentBattlefield) mustattack text=Fumiko the Lowblood has bushido X, where X is the number of attacking creatures. (When this blocks or becomes blocked, it gets +X/+X until end of turn.) -- Creatures your opponents control attack each turn if able. mana={2}{R}{R} @@ -62707,6 +62725,17 @@ power=3 toughness=3 [/card] [card] +name=Kentaro, the Smiling Cat +auto=bushido(1/1) +auto=lord(*[samurai]|mycastingzone) anytypeofmana +text=Bushido 1 (When this blocks or becomes blocked, it gets +1/+1 until end of turn.) -- You may pay {X} rather than pay the mana cost for Samurai spells you cast, where X is that spell's converted mana cost. +mana={1}{W} +type=Legendary Creature +subtype=Human Samurai +power=2 +toughness=1 +[/card] +[card] name=Kenzo the Hardhearted doublefaced=kamiflip abilities=double strike @@ -117782,6 +117811,17 @@ power=1 toughness=1 [/card] [card] +name=Takeno, Samurai General +auto=bushido(2/2) +auto=lord(other creature[samurai]|mybattlefield) transforms((,newability[bushidopoints/bushidopoints nonstatic])) +text=Bushido 2 (When this blocks or becomes blocked, it gets +2/+2 until end of turn.) -- Each other Samurai creature you control gets +1/+1 for each point of bushido it has. +mana={5}{W} +type=Legendary Creature +subtype=Human Samurai +power=3 +toughness=3 +[/card] +[card] name=Takenuma Bleeder auto=@combat(attacking) source(this) restriction{type(demon|myBattlefield)~lessthan~1}:life:-1 controller auto=@combat(blocking) source(this) restriction{type(demon|myBattlefield)~lessthan~1}:life:-1 controller diff --git a/projects/mtg/bin/Res/sets/primitives/unsupported.txt b/projects/mtg/bin/Res/sets/primitives/unsupported.txt index 678c5f4db..88edcd69d 100644 --- a/projects/mtg/bin/Res/sets/primitives/unsupported.txt +++ b/projects/mtg/bin/Res/sets/primitives/unsupported.txt @@ -556,15 +556,6 @@ type=Enchantment subtype=Aura [/card] [card] -name=Arcbound Overseer -text=At the beginning of your upkeep, put a +1/+1 counter on each creature with modular you control. -- Modular 6 (This enters the battlefield with six +1/+1 counters on it. When it dies, you may put its +1/+1 counters on target artifact creature.) -mana={8} -type=Artifact Creature -subtype=Golem -power=0 -toughness=0 -[/card] -[card] name=Archangel of Strife abilities=flying text=Flying -- As Archangel of Strife enters the battlefield, each player chooses war or peace. -- Creatures controlled by players who chose war get +3/+0. -- Creatures controlled by players who chose peace get +0/+3. @@ -9343,15 +9334,6 @@ power=4 toughness=6 [/card] [card] -name=Kentaro, the Smiling Cat -text=Bushido 1 (When this blocks or becomes blocked, it gets +1/+1 until end of turn.) -- You may pay {X} rather than pay the mana cost for Samurai spells you cast, where X is that spell's converted mana cost. -mana={1}{W} -type=Legendary Creature -subtype=Human Samurai -power=2 -toughness=1 -[/card] -[card] name=Keranos, God of Storms abilities=indestructible text=Indestructible -- As long as your devotion to blue and red is less than seven, Keranos isn't a creature. -- Reveal the first card you draw on each of your turns. Whenever you reveal a land card this way, draw a card. Whenever you reveal a nonland card this way, Keranos deals 3 damage to target creature or player. @@ -18057,15 +18039,6 @@ mana={G} type=Sorcery [/card] [card] -name=Takeno, Samurai General -text=Bushido 2 (When this blocks or becomes blocked, it gets +2/+2 until end of turn.) -- Each other Samurai creature you control gets +1/+1 for each point of bushido it has. -mana={5}{W} -type=Legendary Creature -subtype=Human Samurai -power=3 -toughness=3 -[/card] -[card] name=Takklemaggot text=Enchant creature -- At the beginning of the upkeep of enchanted creature's controller, put a -0/-1 counter on that creature. -- When enchanted creature dies, that creature's controller chooses a creature that Takklemaggot could enchant. If he or she does, return Takklemaggot to the battlefield under your control attached to that creature. If he or she doesn't, return Takklemaggot to the battlefield under your control as a non-Aura enchantment. It loses "enchant creature" and gains "At the beginning of that player's upkeep, Takklemaggot deals 1 damage to him or her." mana={2}{B}{B} diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index d25fa0615..f079e9e7d 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -1001,6 +1001,10 @@ private: {//hand,exile,grave & library only (library zpos is inverted so the recent one is always the top) intValue = card->zpos; } + else if (s == "bushidopoints") + {//bushido point + intValue = card->bushidoPoints; + } else if (s == "revealedp") { if (card->revealedLast) @@ -6843,30 +6847,50 @@ public: } }; -//Bushido ability todo:add bushido count. +//Bushido ability class ABushidoAbility: public MTGAbility { public: string PowerToughnessModifier; - - ABushidoAbility(GameObserver* observer, int _id, MTGCardInstance * _source, string _PowerToughnessModifier) : - MTGAbility(observer, _id, _source) + string bpoints; + ABushidoAbility(GameObserver* observer, int _id, MTGCardInstance * _source, string PowerToughnessModifier, string bpoints) : + MTGAbility(observer, _id, _source),PowerToughnessModifier(PowerToughnessModifier),bpoints(bpoints) { - PowerToughnessModifier = _PowerToughnessModifier; } - int receiveEvent(WEvent * event) - { - if (dynamic_cast (event)) - { - MTGCardInstance * opponent = source->getNextOpponent(); - if (!opponent) return 0; - PTInstant * a = NEW PTInstant(game, this->GetId(), source, source,NEW WParsedPT(PowerToughnessModifier,NULL,source)); - GenericInstantAbility * wrapper = NEW GenericInstantAbility(game, 1, source,source, a); - wrapper->addToGame(); - } - return 1; + void Update(float dt) + { + if(source->alias == 74534) + {//fumiko the lowblood has dynamic bushido + source->bushidoPoints = 0; + WParsedInt bushidoPoint(bpoints, NULL, source); + source->bushidoPoints += bushidoPoint.getValue(); } - + MTGAbility::Update(dt); + } + int receiveEvent(WEvent * event) + { + if (dynamic_cast (event)) + { + MTGCardInstance * opponent = source->getNextOpponent(); + if (!opponent) return 0; + PTInstant * a = NEW PTInstant(game, this->GetId(), source, source,NEW WParsedPT(PowerToughnessModifier,NULL,source)); + GenericInstantAbility * wrapper = NEW GenericInstantAbility(game, 1, source,source, a); + wrapper->addToGame(); + } + return 1; + } + int addToGame() + { + WParsedInt bushidoPoint(bpoints, NULL, source); + source->bushidoPoints += bushidoPoint.getValue(); + return MTGAbility::addToGame(); + } + int destroy() + { + WParsedInt bushidoPoint(bpoints, NULL, source); + source->attackCost -= bushidoPoint.getValue(); + return 1; + } ABushidoAbility * clone() const { return NEW ABushidoAbility(*this); @@ -7337,6 +7361,51 @@ public: return NEW ATriggerTotem(*this); } }; +//Modular Ability +class AModularAbility: public InstantAbility +{ +public: + string modularpoint; + AModularAbility(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target, string modularpoint) : + InstantAbility(observer, _id, _source),modularpoint(modularpoint) + { + target = _target; + } + + int resolve() + { + MTGCardInstance * card = (MTGCardInstance *) target; + if (card) + { + if(modularpoint == "") + modularpoint = "0"; + string counterString = "counter(1/1,"; + counterString.append(modularpoint); + counterString.append(")"); + AbilityFactory af(card->getObserver()); + MTGAbility * modCounter = af.parseMagicLine(counterString,this->GetId(),NULL,card); + modCounter->oneShot = true; + modCounter->canBeInterrupted = false; + modCounter->resolve(); + SAFE_DELETE(modCounter); + card->modularPoints += atoi(modularpoint.c_str()); + } + return 1; + } + const string getMenuText() + { + return "Modular"; + } + virtual ostream& toString(ostream& out) const + { + out << "AAModularAbility ::: ("; + return InstantAbility::toString(out) << ")"; + } + AModularAbility * clone() const + { + return NEW AModularAbility(*this); + } +}; // utility functions void PopulateColorIndexVector(list& colors, const string& colorsString, char delimiter = ','); diff --git a/projects/mtg/include/CardPrimitive.h b/projects/mtg/include/CardPrimitive.h index 0c2081dbe..763b99adc 100644 --- a/projects/mtg/include/CardPrimitive.h +++ b/projects/mtg/include/CardPrimitive.h @@ -80,6 +80,9 @@ public: string PhasedOutAbility; void setPhasedOutAbility(const string& value); const string& getPhasedOutAbility() const; + string ModularValue; + void setModularValue(const string& value); + const string& getModularValue() const; vectortypes; CardPrimitive(); diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 6023d3525..67e6efd5d 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -296,6 +296,8 @@ public: int imprintR; int imprintB; int imprintW; + int bushidoPoints; + int modularPoints; int canproduceMana(int color = -1); int entersBattlefield; string currentimprintName; diff --git a/projects/mtg/include/MTGDefinitions.h b/projects/mtg/include/MTGDefinitions.h index 33e528756..c614d39d0 100644 --- a/projects/mtg/include/MTGDefinitions.h +++ b/projects/mtg/include/MTGDefinitions.h @@ -276,7 +276,8 @@ class Constants SHOWOPPONENTTOPLIBRARY = 154, TOTEMARMOR = 155, DISCARDTOPLAYBYOPPONENT = 156, - NB_BASIC_ABILITIES = 157, + MODULAR = 157, + NB_BASIC_ABILITIES = 158, RARITY_S = 'S', //Special Rarity RARITY_M = 'M', //Mythics diff --git a/projects/mtg/src/CardPrimitive.cpp b/projects/mtg/src/CardPrimitive.cpp index 9a3a458e2..49910a602 100644 --- a/projects/mtg/src/CardPrimitive.cpp +++ b/projects/mtg/src/CardPrimitive.cpp @@ -60,6 +60,7 @@ CardPrimitive::CardPrimitive(CardPrimitive * source) setAICustomCode(source->AICustomCode); setCrewAbility(source->CrewAbility); setPhasedOutAbility(source->PhasedOutAbility); + setModularValue(source->ModularValue); power = source->power; toughness = source->toughness; restrictions = source->restrictions ? source->restrictions->clone() : NULL; @@ -381,6 +382,17 @@ const string& CardPrimitive::getPhasedOutAbility() const return PhasedOutAbility; } +void CardPrimitive::setModularValue(const string& value) +{ + ModularValue = value; + std::transform(ModularValue.begin(), ModularValue.end(), ModularValue.begin(), ::tolower); +} + +const string& CardPrimitive::getModularValue() const +{ + return ModularValue; +} + void CardPrimitive::setName(const string& value) { name = value; diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 24e9e57cf..db4919bc6 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -3501,7 +3501,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG vectorsplitPT = split(splitBushido[1],'/'); if(!splitPT.size()) return NULL; - return NEW ABushidoAbility(observer, id, card,splitBushido[1]); + return NEW ABushidoAbility(observer, id, card,splitBushido[1],splitPT[0]); } vector splitPhaseAlter = parseBetween(s, "phasealter(", ")"); if (splitPhaseAlter.size()) @@ -5327,6 +5327,12 @@ void AbilityFactory::addAbilities(int _id, Spell * spell) observer->addObserver(NEW AFlankerAbility(observer, _id, card)); } + if(card->basicAbilities[(int)Constants::MODULAR]) + { + AModularAbility * ability = NEW AModularAbility(observer, _id, card, card, card->getModularValue()); + observer->addObserver(ability); + } + const int HomeAbilities[] = {(int)Constants::FORESTHOME, (int)Constants::ISLANDHOME, (int)Constants::MOUNTAINHOME, (int)Constants::SWAMPHOME, (int)Constants::PLAINSHOME}; const char * HomeLands[] = {"forest", "island", "mountain", "swamp", "plains"}; diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index aa8fbd89a..397aec705 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -154,6 +154,7 @@ void MTGCardInstance::copy(MTGCardInstance * card) doubleFaced = data->doubleFaced; AICustomCode = data->AICustomCode; CrewAbility = data->CrewAbility; + ModularValue = data->ModularValue; PhasedOutAbility = data->PhasedOutAbility; origpower = card->origpower;//for flip origtoughness = card->origtoughness;//for flip @@ -279,6 +280,8 @@ void MTGCardInstance::initMTGCI() imprintR = 0; imprintB = 0; imprintW = 0; + bushidoPoints = 0; + modularPoints = 0; entersBattlefield = 0; currentimprintName = ""; imprintedNames.clear(); diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index b778a0b4f..83c9c8bd7 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -224,9 +224,16 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi case 'm': //mana if (!primitive) primitive = NEW CardPrimitive(); { - string value = val; - std::transform(value.begin(), value.end(), value.begin(), ::tolower); - primitive->setManaCost(value); + if( key == "modular")//modular + { + primitive->setModularValue(val); + } + else + { + string value = val; + std::transform(value.begin(), value.end(), value.begin(), ::tolower); + primitive->setManaCost(value); + } } break; diff --git a/projects/mtg/src/MTGDefinitions.cpp b/projects/mtg/src/MTGDefinitions.cpp index 2b3c09e78..2de6d8da5 100644 --- a/projects/mtg/src/MTGDefinitions.cpp +++ b/projects/mtg/src/MTGDefinitions.cpp @@ -187,7 +187,8 @@ const char* Constants::MTGBasicAbilities[] = { "showfromtoplibrary", "showopponenttoplibrary", "totemarmor", - "discardtoplaybyopponent" + "discardtoplaybyopponent", + "modular" }; map Constants::MTGBasicAbilitiesMap;