diff --git a/projects/mtg/bin/Res/sets/primitives/borderline.txt b/projects/mtg/bin/Res/sets/primitives/borderline.txt index c275b622a..ef7d388b0 100644 --- a/projects/mtg/bin/Res/sets/primitives/borderline.txt +++ b/projects/mtg/bin/Res/sets/primitives/borderline.txt @@ -1030,6 +1030,13 @@ power=2 toughness=2 [/card] [card] +name=Alpine Moon +auto=chooseaname transforms((,newability[lord(land[chosenname]|opponentbattlefield) loseabilities],newability[lord(land[chosenname]|opponentbattlefield) losesubtypesof(land)],newability[lord(land[chosenname]|opponentbattlefield) transforms((,newability[{T}:add{G}],newability[{T}:add{R}],newability[{T}:add{U}],newability[{T}:add{B}],newability[{T}:add{W}]))])) forever chooseend nonbasicland +text=As Alpine Moon enters the battlefield, choose a nonbasic land card name. -- Lands your opponents control with the chosen name lose all land types and abilities, and they gain "{T}: Add one mana of any color." +mana={R} +type=Enchantment +[/card] +[card] name=Alpine Watchdog abilities=vigilance text=Vigilance (Attacking doesn't cause this creature to tap.) @@ -6298,6 +6305,17 @@ text={T}: Add {C}. -- {3}, {T}: Add {B} for each basic Swamp you control. type=Land [/card] [card] +name=Cabal Therapist +abilities=menace +auto=@each my firstmain:may name(Sacrifice a creature) target(creature|mybattlefield) transforms((,newability[sacrifice],newability[chooseanameopp name(Look hand) target(*|opponenthand) moveto(opponenthand) and!( all(*[chosenname]|opponenthand) reject)! chooseend nonland])) oneshot +text=Menace -- At the beginning of your precombat main phase, you may sacrifice a creature. When you do, choose a nonland card name, then target player reveals their hand and discards all cards with that name. +mana={B} +type=Creature +subtype=Horror +power=1 +toughness=1 +[/card] +[card] name=Cacophodon auto=@damaged(this):untap target(*) text=Enrage — Whenever Cacophodon is dealt damage, untap target permanent. @@ -12435,6 +12453,13 @@ power=2 toughness=3 [/card] [card] +name=Dispossess +auto=chooseanameopp name(Search that artifact) target(artifact[chosenname]|opponentgraveyard,opponentlibrary,opponenthand) moveto(exile) and!( shuffle opponent )! chooseend +text=Choose an artifact card name. Search target opponent's graveyard, hand, and library for any number of cards with the chosen name and exile them. Then that player shuffles their library. +mana={2}{B} +type=Sorcery +[/card] +[card] name=Disrupt Decorum auto=mustattack all(creature|opponentBattlefield) uynt text=Goad all creatures you don't control. (Until your next turn, those creatures attack each combat if able and attack a player other than you if able.) @@ -12513,6 +12538,13 @@ mana={3}{W}{W} type=Enchantment [/card] [card] +name=Diviner's Lockbox +auto={1}{T}:ability$!chooseaname transforms((,newability[name(Look top card) if type(*[chosenname;zpos=1]|mylibrary)~equalto~0 then reveal:1 optionone name(Look top card) target(*|reveal) donothing optiononeend optiontwo all(*|reveal) placefromthetop(1) optiontwoend revealend],newability[if type(*[chosenname;zpos=1]|mylibrary)~morethan~0 then reveal:1 optionone name(Look top card) target(*|reveal) moveto(myhand) and!( draw:2 controller)! optiononeend afterrevealed sacrifice all(mysource) afterrevealedend revealend])) oneshot chooseend!$ controller asSorcery +text={1}, {T}: Choose a card name, then reveal the top card of your library. If that card has the chosen name, sacrifice Diviner's Lockbox and draw three cards. Activate this ability only any time you could cast a sorcery. +mana={4} +type=Artifact +[/card] +[card] name=Djeru's Renunciation abilities=cycling target=creature @@ -14892,7 +14924,7 @@ toughness=6 [/card] [card] name=Etchings of the Chosen -auto=chooseatype lord(creature[chosentype]) 1/1 && transforms((,newability[{1}{S(creature[chosentype]|mybattlefield)}:name(creature) indestructible ueot target(creature)])) chooseend +auto=chooseatype transforms((,newability[lord(creature[chosentype]|mybattlefield) 1/1],newability[{1}{S(creature[chosentype]|mybattlefield)}:name(Creature gains indestructible) target(creature) indestructible ueot])) chooseend text=As Etchings of the Chosen enters the battlefield, choose a creature type. -- Creatures you control of the chosen type get +1/+1. -- {1}, Sacrifice a creature of the chosen type: Target creature you control gains indestructible until end of turn. mana={1}{W}{B} type=Enchantment @@ -15569,6 +15601,15 @@ power=1 toughness=2 [/card] [card] +name=Failure // Comply +auto=ifnot paid(alternative) then target(*|stack) fizzleto(hand) +auto=if paid(alternative) then chooseanameopp maxcast(*[chosenname])0 opponent ueot && phaseaction[upkeep once] maxcast(*[lastnamechosen])0 opponent ueot chooseend nonland +autograveyard={W}{E}:name(Comply) activate castcard(alternative) asSorcery +text=Return target spell to its owner's hand. -- Aftermath (Cast this spell only from your graveyard. Then exile it.) Choose a card name. Until your next turn, your opponents can't cast spells with the chosen name. +mana={1}{U} +type=Instant +[/card] +[card] name=Fairgrounds Trumpeter auto=@counteradded(1/1) from(*|mybattlefield):counter(1/1) text=At the beginning of each end step, if a +1/+1 counter was placed on a permanent under your control this turn, put a +1/+1 counter on Fairgrounds Trumpeter. @@ -18705,6 +18746,13 @@ mana={W} type=Instant [/card] [card] +name=Gideon's Intervention +auto=chooseanameopp lord(*|mybattlefield) transforms((,newability[maxcast(*[chosenname])0 opponent],newability[protection from (*[chosenname])],newability[preventalldamage to(controller) from(*[chosenname])])) chooseend nonland +text=As Gideon's Intervention enters the battlefield, choose a card name. -- Your opponents can't cast spells with the chosen name. -- Prevent all damage that would be dealt to you and permanents you control by sources with the chosen name. +mana={2}{W}{W} +type=Enchantment +[/card] +[card] name=Gideon's Resolve auto=may moveto(myhand) target(Gideon^ Martial Paragon|mylibrary) auto=lord(creature|mybattlefield) 1/1 @@ -30318,6 +30366,21 @@ power=2 toughness=1 [/card] [card] +name=Medomai's Prophecy +auto=counter(0/0,1,Lore) +auto=@each my firstmain:counter(0/0,1,Lore) +auto=scry:2 scrycore delayed dontshow donothing scrycoreend scryend +auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.2.Lore}=) chooseaname donothing chooseend +auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.3.Lore}) transforms((,newability[@movedto(*[lastnamechosen]|mystack) once:draw:1 controller])) ueot +auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.4.Lore}) name(Look your top card) reveal:1 optionone name(Look your top card) target(*|reveal) doNothing optiononeend optiontwo all(*|reveal) moveto(mylibrary) optiontwoend revealend +auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.4.Lore}) name(Look opponent's top card) reveal:1 revealzone(opponentlibrary) optionone name(Look opponent's top card) target(*|reveal) doNothing optiononeend optiontwo all(*|reveal) moveto(opponentlibrary) optiontwoend revealend +auto=@counteradded(0/0,1,Lore) from(this):this(counter{0/0.4.Lore}) sacrifice(this) +text=(As this Saga enters and after your draw step, add a lore counter. Sacrifice after IV.) -- I — Scry 2. -- II — Choose a card name. -- III — When you cast a spell with the chosen name for the first time this turn, draw two cards. -- IV — Look at the top card of each player's library. +mana={1}{U} +type=Enchantment +subtype=Saga +[/card] +[card] name=Melting auto=all(land[snow]|battlefield) transforms((removetypes,newability[becomes(Land)])) forever text=All lands are no longer snow. @@ -32263,6 +32326,13 @@ mana={4}{B}{B}{B} type=Sorcery [/card] [card] +name=Necromentia +auto=chooseanameopp name(Search that cards) target(*[chosenname]|opponentgraveyard,opponentlibrary,opponenthand) moveto(exile) and!( token(Zombie,Creature Zombie,2/2,black) opponent and!( shuffle opponent )! )! chooseend nonbasicland +text=Choose a card name other than a basic land card name. Search target opponent's graveyard, hand, and library for any number of cards with that name and exile them. That player shuffles their library, then creates a 2/2 black Zombie creature token for each card exiled from their hand this way. +mana={1}{B}{B} +type=Sorcery +[/card] +[card] name=Necropanther abilities=mutate otherrestriction=type(creature[-human]|mybattlefield)~morethan~0 @@ -45476,6 +45546,13 @@ type=Artifact subtype=Equipment [/card] [card] +name=Sorcerous Spyglass +auto=name(Look opponent hand) target(*|opponenthand) moveto(opponenthand) and!( chooseanameopp lord(*[chosenname]) noactivatedability chooseend )! +text=As Sorcerous Spyglass enters the battlefield, look at an opponent's hand, then choose any card name. -- Activated abilities of sources with the chosen name can't be activated unless they're mana abilities. +mana={2} +type=Artifact +[/card] +[card] name=Sorin's Guide auto=may moveto(myhand) target(Sorin^ Vampire Lord|mylibrary) auto=may moveto(myhand) target(Sorin^ Vampire Lord|mygraveyard) @@ -52954,6 +53031,13 @@ power=0 toughness=4 [/card] [card] +name=Unmoored Ego +auto=chooseanameopp name(Search that cards) target(*[chosenname]|opponentgraveyard,opponentlibrary,opponenthand) moveto(exile) and!( draw:1 opponent and!( shuffle opponent )! )! chooseend +text=Choose a card name. Search target opponent's graveyard, hand, and library for up to four cards with that name and exile them. That player shuffles their library, then draws a card for each card exiled from their hand this way. +mana={1}{U}{B} +type=Sorcery +[/card] +[card] name=Unnatural Aggression abilities=devoid target=creature|mybattlefield diff --git a/projects/mtg/bin/Res/sets/primitives/unsupported.txt b/projects/mtg/bin/Res/sets/primitives/unsupported.txt index f68835a86..994d650ac 100644 --- a/projects/mtg/bin/Res/sets/primitives/unsupported.txt +++ b/projects/mtg/bin/Res/sets/primitives/unsupported.txt @@ -249,14 +249,6 @@ mana={6}{R}{R} type=Sorcery [/card] [card] -name=Alpine Moon -auto=may counter(0/0,1,Alpine) target(land[-basic]|opponentBattlefield) -auto=lord(land[counter{0/0,1,Alpine};share!name!]|opponentBattlefield) loseabilities && losesubtypesof(land) && transforms((newability[{T}:add{G}],newability[{T}:add{R}],newability[{T}:add{U}],newability[{T}:add{B}],newability[{T}:add{W}])) forever -text=As Alpine Moon enters the battlefield, choose a nonbasic land card name. -- Lands your opponents control with the chosen name lose all land types and abilities, and they gain “{T}: Add one mana of any color.” -mana={R} -type=Enchantment -[/card] -[card] name=Alter Reality text=Change the text of target spell or permanent by replacing all instances of one color word with another. (This effect lasts indefinitely.) -- Flashback {1}{U} (You may cast this card from your graveyard for its flashback cost. Then exile it.) mana={1}{U} @@ -1532,15 +1524,6 @@ mana={2}{W} type=Enchantment [/card] [card] -name=Cabal Therapist -text=Menace -- At the beginning of your precombat main phase, you may sacrifice a creature. When you do, choose a nonland card name, then target player reveals their hand and discards all cards with that name. -mana={B} -type=Creature -subtype=Horror -power=1 -toughness=1 -[/card] -[card] name=Cabal Therapy text=Name a nonland card. Target player reveals his or her hand and discards all cards with that name. -- Flashback—Sacrifice a creature. (You may cast this card from your graveyard for its flashback cost. Then exile it.) mana={B} @@ -3061,12 +3044,6 @@ type=Artifact subtype=Contraption [/card] [card] -name=Dispossess -text=Choose an artifact card name. Search target opponent's graveyard, hand, and library for any number of cards with the chosen name and exile them. Then that player shuffles their library. -mana={2}{B} -type=Sorcery -[/card] -[card] name=Disruption Aura text=Enchant artifact -- Enchanted artifact has "At the beginning of your upkeep, sacrifice this artifact unless you pay its mana cost." mana={2}{U} @@ -3116,12 +3093,6 @@ mana={2}{W}{W} type=Sorcery [/card] [card] -name=Diviner's Lockbox -text={1}, {T}: Choose a card name, then reveal the top card of your library. If that card has the chosen name, sacrifice Diviner's Lockbox and draw three cards. Activate this ability only any time you could cast a sorcery. -mana={4} -type=Artifact -[/card] -[card] name=Divining Witch text={1}{B}, {T}, Discard a card: Name a card. Exile the top six cards of your library. Reveal cards from the top of your library until you reveal the named card, then put that card into your hand. Exile all other cards revealed this way. mana={1}{B} @@ -3885,12 +3856,6 @@ type=Artifact subtype=Contraption [/card] [card] -name=Failure // Comply -text=Return target spell to its owner's hand. -- Aftermath (Cast this spell only from your graveyard. Then exile it.) Choose a card name. Until your next turn, your opponents can't cast spells with the chosen name. -mana={1}{U} -type=Instant -[/card] -[card] name=Faith's Shield auto=this(controllerlife > 5) ability$! choice name(protection from white) target(*|myBattlefield) protection from white ueot _ choice name(protection from blue) target(*|myBattlefield) protection from blue ueot _ choice name(protection from black) target(*|myBattlefield) protection from black ueot _ choice name(protection from red) target(*|myBattlefield) protection from red ueot _ choice name(protection from green) target(*|myBattlefield) protection from green ueot !$ controller auto=this(controllerlife < 6) ability$! choice name(protection from white) all(*|myBattlefield) protection from white ueot _ choice name(protection from blue) all(*|myBattlefield) protection from blue ueot _ choice name(protection from black) all(*|myBattlefield) protection from black ueot _ choice name(protection from red) all(*|myBattlefield) protection from red ueot _ choice name(protection from green) all(*|myBattlefield) protection from green ueot !$ controller @@ -4627,12 +4592,6 @@ power=0 toughness=3 [/card] [card] -name=Gideon's Intervention -text=As Gideon's Intervention enters the battlefield, choose a card name. -- Your opponents can't cast spells with the chosen name. -- Prevent all damage that would be dealt to you and permanents you control by sources with the chosen name. -mana={2}{W}{W} -type=Enchantment -[/card] -[card] name=Gideon's Sacrifice text=Choose a creature or planeswalker you control. All damage that would be dealt this turn to you and permanents you control is dealt to the chosen permanent instead (if it's still on the battlefield) . mana={W} @@ -7439,13 +7398,6 @@ power=4 toughness=4 [/card] [card] -name=Medomai's Prophecy -text=(As this Saga enters and after your draw step, add a lore counter. Sacrifice after IV.) -- I — Scry 2. -- II — Choose a card name. -- III — When you cast a spell with the chosen name for the first time this turn, draw two cards. -- IV — Look at the top card of each player's library. -mana={1}{U} -type=Enchantment -subtype=Saga -[/card] -[card] name=Melee text=Cast Melee only during your turn and only during combat before blockers are declared. -- You choose which creatures block this combat and how those creatures block. -- Whenever a creature attacks and isn't blocked this combat, untap it and remove it from combat. mana={4}{R} @@ -8240,12 +8192,6 @@ mana={2}{B} type=Enchantment [/card] [card] -name=Necromentia -text=Choose a card name other than a basic land card name. Search target opponent's graveyard, hand, and library for any number of cards with that name and exile them. That player shuffles their library, then creates a 2/2 black Zombie creature token for each card exiled from their hand this way. -mana={1}{B}{B} -type=Sorcery -[/card] -[card] name=Necrotic Ooze text=As long as Necrotic Ooze is on the battlefield, it has all activated abilities of all creature cards in all graveyards. mana={2}{B}{B} @@ -11328,12 +11274,6 @@ power=2 toughness=2 [/card] [card] -name=Sorcerous Spyglass -text=As Sorcerous Spyglass enters the battlefield, look at an opponent's hand, then choose any card name. -- Activated abilities of sources with the chosen name can't be activated unless they're mana abilities. -mana={2} -type=Artifact -[/card] -[card] name=Sorrow's Path text={T}: Choose two target blocking creatures an opponent controls. If each of those creatures could block all creatures that the other is blocking, remove both of them from combat. Each one then blocks all creatures the other was blocking. -- Whenever Sorrow's Path becomes tapped, it deals 2 damage to you and each creature you control. type=Land @@ -13160,12 +13100,6 @@ text=Black legendary creatures you control have "bands with other legendary crea type=Land [/card] [card] -name=Unmoored Ego -text=Choose a card name. Search target opponent's graveyard, hand, and library for up to four cards with that name and exile them. That player shuffles their library, then draws a card for each card exiled from their hand this way. -mana={1}{U}{B} -type=Sorcery -[/card] -[card] name=Unpredictable Cyclone text=If a cycling ability of another nonland card would cause you to draw a card, instead exile cards from the top of your library until you exile a card that shares a card type with the cycled card. You may cast that card without paying its mana cost. Then put the exiled cards that weren't cast this way on the bottom of your library in a random order. -- Cycling {2} ({2}, Discard this card: Draw a card.) mana={3}{R}{R} diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 0b09b154a..94c221083 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -6469,19 +6469,37 @@ public: AASetTypeChosen * clone() const; ~AASetTypeChosen(); }; -class GenericChooseTypeColor: public ActivatedAbility +class AASetNameChosen: public InstantAbility +{ +public: + string name; + string abilityToAlter; + string menutext; + MTGAbility * abilityAltered; + AASetNameChosen(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * target, string _name = "",string menu = "error" ,string toAdd = ""); + int resolve(); + const string getMenuText(); + AASetNameChosen * clone() const; + ~AASetNameChosen(); +}; +class GenericChooseTypeColorName: public ActivatedAbility { public: string baseAbility; bool chooseColor; + bool chooseName; + bool chooseOppName; AASetColorChosen * setColor; AASetTypeChosen * setType; + AASetNameChosen * setName; bool ANonWall; - GenericChooseTypeColor(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string toAdd = "",bool chooseColor = false,bool nonwall = false, ManaCost * cost = NULL); + bool ANonBasicLand; + bool ANonLand; + GenericChooseTypeColorName(GameObserver* observer, int id, MTGCardInstance * source, Targetable * target, string toAdd = "", bool chooseColor = false,bool chooseName = false, bool chooseOppName = false, bool nonwall = false, bool nonbasicland = false, bool nonland = false, ManaCost * cost = NULL); int resolve(); const string getMenuText(); - GenericChooseTypeColor * clone() const; - ~GenericChooseTypeColor(); + GenericChooseTypeColorName * clone() const; + ~GenericChooseTypeColorName(); }; //------------------------------------------------ diff --git a/projects/mtg/include/CardDescriptor.h b/projects/mtg/include/CardDescriptor.h index 020deaa72..d7e36e421 100644 --- a/projects/mtg/include/CardDescriptor.h +++ b/projects/mtg/include/CardDescriptor.h @@ -78,6 +78,7 @@ class CardDescriptor: public MTGCardInstance int CDcontrollerDamaged; int CDdamager; int CDgeared; + int CDattached; int CDblocked; int CDcanProduceC; int CDcanProduceG; diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index 2f03a9af4..7e49b2115 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -112,6 +112,7 @@ public: bool isFacedown; int chooseacolor; string chooseasubtype; + string chooseaname; int coinSide;//1 = tails int lastFlipResult; int dieSide; diff --git a/projects/mtg/include/Player.h b/projects/mtg/include/Player.h index ab0e3dac9..e2c2fcc19 100644 --- a/projects/mtg/include/Player.h +++ b/projects/mtg/include/Player.h @@ -60,6 +60,7 @@ public: int snowManaU; int snowManaW; int snowManaC; + string lastChosenName; vector prowledTypes; vectorcurses; Player(GameObserver *observer, string deckFile, string deckFileSmall, MTGDeck * deck = NULL); diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index cd3caa802..3844b22ea 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -2739,14 +2739,15 @@ AAProliferate::~AAProliferate() { } // -//choosing a type or color -GenericChooseTypeColor::GenericChooseTypeColor(GameObserver* observer, int id, MTGCardInstance * source, Targetable *,string _toAdd,bool chooseColor,bool nonwall, ManaCost * cost) : -ActivatedAbility(observer, id, source, cost, 0), baseAbility(_toAdd),chooseColor(chooseColor),ANonWall(nonwall) +//choosing a type or color or name +GenericChooseTypeColorName::GenericChooseTypeColorName(GameObserver* observer, int id, MTGCardInstance * source, Targetable *, string _toAdd, bool chooseColor, bool chooseName, bool chooseOppName, bool nonwall, bool nonbasicland, bool nonland, ManaCost * cost) : +ActivatedAbility(observer, id, source, cost, 0), baseAbility(_toAdd),chooseColor(chooseColor),chooseName(chooseName),chooseOppName(chooseOppName),ANonWall(nonwall),ANonBasicLand(nonbasicland),ANonLand(nonland) { this->GetId(); setColor = NULL; + setName = NULL; } -int GenericChooseTypeColor::resolve() +int GenericChooseTypeColorName::resolve() { if (!target) return 0; @@ -2762,6 +2763,33 @@ int GenericChooseTypeColor::resolve() SAFE_DELETE(setColor); } } + else if(chooseName || chooseOppName) + { + vector names; + Player* p = (chooseName)?source->controller():source->controller()->opponent(); + MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->stack, p->game->exile, p->game->commandzone, p->game->sideboard, p->game->reveal }; + for (int k = 0; k < 9; k++){ + MTGGameZone * zone = zones[k]; + for (int j = zone->nb_cards - 1; j >= 0; --j){ + if ((!ANonBasicLand || (!zone->cards[j]->hasType(Subtypes::TYPE_BASIC) && !zone->cards[j]->hasType(Subtypes::TYPE_LAND))) && (!ANonLand || !zone->cards[j]->hasType(Subtypes::TYPE_LAND))){ + bool added = false; + for (int i = names.size() - 1; i >= 0; --i) + if(names[i] == zone->cards[j]->name) + added = true; + if(!added) + names.push_back(zone->cards[j]->name); + } + } + } + for (size_t i = 0; i < names.size(); ++i){ + string menu = names[i]; + setName = NEW AASetNameChosen(game, game->mLayers->actionLayer()->getMaxId(), source, (MTGCardInstance*)target, names[i], menu, baseAbility); + MTGAbility * set = setName->clone(); + set->oneShot = true; + selection.push_back(set); + SAFE_DELETE(setName); + } + } else { vector values = MTGAllCards::getCreatureValuesById(); @@ -2789,21 +2817,23 @@ int GenericChooseTypeColor::resolve() } -const string GenericChooseTypeColor::getMenuText() +const string GenericChooseTypeColorName::getMenuText() { if(chooseColor) return "Choose a color"; + if(chooseName || chooseOppName) + return "Choose a name"; else return "Choose a type"; } -GenericChooseTypeColor * GenericChooseTypeColor::clone() const +GenericChooseTypeColorName * GenericChooseTypeColorName::clone() const { - GenericChooseTypeColor * a = NEW GenericChooseTypeColor(*this); + GenericChooseTypeColorName * a = NEW GenericChooseTypeColorName(*this); return a; } -GenericChooseTypeColor::~GenericChooseTypeColor() +GenericChooseTypeColorName::~GenericChooseTypeColorName() { } @@ -2922,6 +2952,64 @@ AASetTypeChosen::~AASetTypeChosen() { } +//set name choosen + AASetNameChosen::AASetNameChosen(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * _target,string _name ,string _menu,string toAlter): + InstantAbility(observer, id, source),name(_name), abilityToAlter(toAlter), menutext(_menu) +{ + this->target = _target; + abilityAltered = NULL; +} +int AASetNameChosen::resolve() +{ + MTGCardInstance * _target = (MTGCardInstance *)target; + string nameChoosen = menutext; + _target->chooseaname = nameChoosen; + _target->controller()->lastChosenName = nameChoosen; + + if(abilityToAlter.size()) + { + AbilityFactory af(game); + abilityAltered = af.parseMagicLine(abilityToAlter, 0, NULL, _target); + if(abilityAltered->oneShot) + { + abilityAltered->resolve(); + SAFE_DELETE(abilityAltered); + } + else + { + abilityAltered->target = _target; + MayAbility * dontAdd = dynamic_cast(abilityAltered); + if (!dontAdd) + { + _target->cardsAbilities.push_back(abilityAltered); + for(unsigned int j = 0;j < _target->cardsAbilities.size();++j) + { + if(_target->cardsAbilities[j] == this) + _target->cardsAbilities.erase(_target->cardsAbilities.begin() + j); + } + } + + abilityAltered->addToGame(); + } + _target->skipDamageTestOnce = true;//some cards rely on this ability updating before damage test are run. otherwise they die before toughnes bonus applies. + } + return 1; +} + +const string AASetNameChosen::getMenuText() +{ + return menutext.c_str(); +} + +AASetNameChosen * AASetNameChosen::clone() const +{ + return NEW AASetNameChosen(*this); +} + +AASetNameChosen::~AASetNameChosen() +{ +} + // //choosing flip coin GenericFlipACoin::GenericFlipACoin(GameObserver* observer, int id, MTGCardInstance * source, Targetable *,string _toAdd, ManaCost * cost) : @@ -4261,6 +4349,8 @@ int AAFlip::resolve() { if(flipStats == "myorigname" && _target->nameOrig != "") flipStats = _target->nameOrig; // Added to undo the copy effect at end of turn for a generic card (es. Shapeshifter transformations). + else if(flipStats == "chosenname" && _target->chooseaname != "") + flipStats = _target->chooseaname; // Added to allow the transformation of a card in a choosen name. MTGCard * fcard = MTGCollection()->getCardByName(flipStats); if(!fcard) return 0; MTGCardInstance * myFlip = NEW MTGCardInstance(fcard, _target->controller()->game); diff --git a/projects/mtg/src/CardDescriptor.cpp b/projects/mtg/src/CardDescriptor.cpp index 5b9ee2f17..4c70db8ba 100644 --- a/projects/mtg/src/CardDescriptor.cpp +++ b/projects/mtg/src/CardDescriptor.cpp @@ -31,6 +31,7 @@ CardDescriptor::CardDescriptor() CDcontrollerDamaged = 0; CDdamager = 0; CDgeared = 0; + CDattached = 0; CDblocked = 0; CDcanProduceC = 0; CDcanProduceG = 0; @@ -293,7 +294,12 @@ MTGCardInstance * CardDescriptor::match(MTGCardInstance * card) { match = NULL; } - + + if ((CDattached == -1 && card->parentCards.size() > 0) || (CDattached == 1 && card->parentCards.size() < 1)) + { + match = NULL; + } + if (CDblocked == -1) { if(!card->isAttacker()) diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index 446d071b4..6ea9e32a9 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -512,6 +512,16 @@ void CardGui::Render() mFont->DrawString(buffer, actX - 10 * actZ, actY - (25.3f * actZ)); mFont->SetScale(1); } + if(card->chooseaname.size() && !alternate && game) + { + mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); + char buffer[200]; + sprintf(buffer, "%s", card->chooseaname.c_str()); + mFont->SetColor(ARGB(static_cast(actA),255,215,0));//Gold indicator + mFont->SetScale(0.8f); + mFont->DrawString(buffer, actX - 10 * actZ, actY - (25.3f * actZ)); + mFont->SetScale(1); + } if(!alternate && buff != "" && game) { mFont->SetScale(DEFAULT_MAIN_FONT_SCALE); @@ -1568,6 +1578,17 @@ bool CardGui::FilterCard(MTGCard * _card,string filter) cd.CDgeared = 1; } } + else if (attribute.find("attached") != string::npos) + { + if (minus) + { + cd.CDattached = -1; + } + else + { + cd.CDattached = 1; + } + } //creature is a level up creature else if (attribute.find("leveler") != string::npos) { diff --git a/projects/mtg/src/Damage.cpp b/projects/mtg/src/Damage.cpp index 3b416dfaa..a616e4d65 100644 --- a/projects/mtg/src/Damage.cpp +++ b/projects/mtg/src/Damage.cpp @@ -278,7 +278,7 @@ int Damage::resolve() } } - if (target->type_as_damageable == Damageable::DAMAGEABLE_MTGCARDINSTANCE && ((MTGCardInstance*)target)->hasType(Subtypes::TYPE_PLANESWALKER)){ // Fix life calculation for planeswalker damage. + if (target->type_as_damageable == Damageable::DAMAGEABLE_MTGCARDINSTANCE && ((MTGCardInstance*)target)->hasType(Subtypes::TYPE_PLANESWALKER)){ // Fix life calculation for planeswalker damage. if (((MTGCardInstance*)target)->counters){ Counters * counters = ((MTGCardInstance*)target)->counters; for(size_t i = 0; i < counters->counters.size(); ++i){ diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index af5889242..91d33ef02 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -1778,7 +1778,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG } - if (StartsWith(s, "chooseacolor ") || StartsWith(s, "chooseatype ")) + if (StartsWith(s, "chooseacolor ") || StartsWith(s, "chooseatype ") || StartsWith(s, "chooseaname")) { MTGAbility * choose = parseChooseActionAbility(s,card,spell,target,0,id); choose = NEW GenericActivatedAbility(observer, "","",id, card,choose,NULL); @@ -4807,7 +4807,7 @@ MTGAbility * AbilityFactory::parseChooseActionAbility(string s,MTGCardInstance * if (splitChooseAColor2.size()) { string a1 = splitChooseAColor2[1]; - MTGAbility * a = NEW GenericChooseTypeColor(observer, id, card, target,a1,true); + MTGAbility * a = NEW GenericChooseTypeColorName(observer, id, card, target,a1,true); a->oneShot = 1; a->canBeInterrupted = false; return a; @@ -4817,7 +4817,7 @@ MTGAbility * AbilityFactory::parseChooseActionAbility(string s,MTGCardInstance * if (splitChooseAType2.size()) { string a1 = splitChooseAType2[1]; - MTGAbility * a = NEW GenericChooseTypeColor(observer, id, card, target,a1,false,s.find("nonwall")!=string::npos); + MTGAbility * a = NEW GenericChooseTypeColorName(observer, id, card, target,a1,false,false,false,s.find("nonwall")!=string::npos); a->oneShot = 1; a->canBeInterrupted = false; return a; @@ -4827,7 +4827,7 @@ MTGAbility * AbilityFactory::parseChooseActionAbility(string s,MTGCardInstance * if (splitChooseAColor.size()) { string a1 = splitChooseAColor[1]; - MTGAbility * a = NEW GenericChooseTypeColor(observer, id, card, target,a1,true); + MTGAbility * a = NEW GenericChooseTypeColorName(observer, id, card, target,a1,true); a->oneShot = 1; a->canBeInterrupted = false; return a; @@ -4837,7 +4837,19 @@ MTGAbility * AbilityFactory::parseChooseActionAbility(string s,MTGCardInstance * if (splitChooseAType.size()) { string a1 = splitChooseAType[1]; - MTGAbility * a = NEW GenericChooseTypeColor(observer, id, card, target,a1,false,s.find("nonwall")!=string::npos); + MTGAbility * a = NEW GenericChooseTypeColorName(observer, id, card, target,a1,false,false,false,s.find("nonwall")!=string::npos); + a->oneShot = 1; + a->canBeInterrupted = false; + return a; + } + //choose a name + vector splitChooseAName = parseBetween(s, "chooseaname ", " chooseend"); + vector splitChooseAOppName = parseBetween(s, "chooseanameopp ", " chooseend"); + if (splitChooseAName.size() || splitChooseAOppName.size()) + { + bool oppName = (splitChooseAOppName.size() > 0); + string a1 = oppName?splitChooseAOppName[1]:splitChooseAName[1]; + MTGAbility * a = NEW GenericChooseTypeColorName(observer, id, card, target,a1,false,!oppName,oppName,false,s.find("nonbasicland")!=string::npos,s.find("nonland")!=string::npos); a->oneShot = 1; a->canBeInterrupted = false; return a; diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index eaf0043ab..ff7d8589f 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -261,6 +261,7 @@ void MTGCardInstance::initMTGCI() zpos = 0; chooseacolor = -1; chooseasubtype = ""; + chooseaname = ""; coinSide = -1; lastFlipResult = -1; dieSide = 0; diff --git a/projects/mtg/src/Player.cpp b/projects/mtg/src/Player.cpp index f0d1d70da..f1ab0767d 100644 --- a/projects/mtg/src/Player.cpp +++ b/projects/mtg/src/Player.cpp @@ -51,6 +51,7 @@ Player::Player(GameObserver *observer, string file, string fileSmall, MTGDeck * snowManaU = 0; snowManaW = 0; snowManaC = 0; + lastChosenName = ""; prowledTypes.clear(); doesntEmpty = NEW ManaCost(); poolDoesntEmpty = NEW ManaCost(); diff --git a/projects/mtg/src/Rules.cpp b/projects/mtg/src/Rules.cpp index 66c68a2f4..6783de77e 100644 --- a/projects/mtg/src/Rules.cpp +++ b/projects/mtg/src/Rules.cpp @@ -607,6 +607,7 @@ void Rules::initGame(GameObserver *g, bool currentPlayerSet) p->monarch = initState.playerData[i].player->monarch; p->surveilOffset = initState.playerData[i].player->surveilOffset; p->devotionOffset = initState.playerData[i].player->devotionOffset; + p->lastChosenName = initState.playerData[i].player->lastChosenName; if (initState.playerData[i].player->mAvatarName.size()) { p->mAvatarName = initState.playerData[i].player->mAvatarName; diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index 317df0b69..0c9558537 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -607,6 +607,17 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta cd->CDgeared = 1; } } + else if (attribute.find("attached") != string::npos) + { + if (minus) + { + cd->CDattached = -1; + } + else + { + cd->CDattached = 1; + } + } //creature is a level up creature else if (attribute.find("leveler") != string::npos) { @@ -953,6 +964,26 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta } } + if (attribute.find("chosenname") != string::npos && card->chooseaname != "") + { + attributefound = 1; + cd->compareName = card->chooseaname; + if (minus) + cd->nameComparisonMode = COMPARISON_UNEQUAL; + else + cd->nameComparisonMode = COMPARISON_EQUAL; + } + + if (attribute.find("lastnamechosen") != string::npos && card->controller()->lastChosenName != "") + { + attributefound = 1; + cd->compareName = card->controller()->lastChosenName; + if (minus) + cd->nameComparisonMode = COMPARISON_UNEQUAL; + else + cd->nameComparisonMode = COMPARISON_EQUAL; + } + if (attribute.find("evictname") != string::npos && card->imprintedCards.size()) { attributefound = 1;