From bbc25e2727b1007ecb28888ce26482d856187298 Mon Sep 17 00:00:00 2001 From: Vittorio Alfieri Date: Wed, 25 Aug 2021 15:30:44 +0200 Subject: [PATCH] Added/fixed primitives, Improved AI: now it can plays cards using morph cost too. --- CHANGELOG.md | 7 +- .../bin/Res/sets/primitives/borderline.txt | 91 +++++++++++++++++++ .../bin/Res/sets/primitives/unsupported.txt | 64 +------------ projects/mtg/include/AIPlayerBaka.h | 8 +- projects/mtg/src/AIPlayerBaka.cpp | 60 +++++++++--- 5 files changed, 149 insertions(+), 81 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 411c97222..f11ffa3cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,14 @@ ## [master] (https://github.com/WagicProject/wagic/tree/master) +### 25/08/21 +- *Committed:* Added/fixed primitives, Improved AI: now it can plays cards using morph cost too. ([Vitty85](https://github.com/Vitty85)) + ### 24/08/21 -- *Committed:* Added/fixed primitives, improved "TurnSide", "Morph" and "Flip" abilities when dealing with Commanders, added "fresh" attribute to cards just put in Sideboard, added a put back rule when a Commander is put in Sideboard, allowed to cast a card with kicker or alternative or morph cost from the CommandZone: in case of Morphed or DoubleFace cards (e.g. "Tergrid, God of Fright"), they will be put in play but they won't be Commander, but when they will be put elsewhere (e.g. destroyed) they may be back to the CommandZone with the usual Commander put back rule. ([Vitty85](https://github.com/Vitty85)) +- *Committed:* Added/fixed primitives, improved "TurnSide", "Morph" and "Flip" abilities when dealing with Commanders, added "fresh" attribute to cards just put in Sideboard, added a put back rule when a Commander is put in Sideboard, allowed to cast a card with kicker or alternative or morph cost from the CommandZone: in case of Morphed or DoubleFace cards (e.g. "Tergrid, God of Fright"), they will be put in play but they won't be Commander, but when they will be put elsewhere (e.g. destroyed) they may be back to the CommandZone with the usual Commander put back rule. https://github.com/WagicProject/wagic/commit/c7c2025fc9d44c4583a3e23a263824c3dcc62f59 ([Vitty85](https://github.com/Vitty85)) ### 23/08/21 -- *Committed:* Updated changelog with last 3 years of modifications (issue #1067 by @remigiusz-suwalski), added tokens in ELD set, improved Android downloader for ELD set, fixed primitives with "asflash" ability, improved all cards with adventure: now they become instants or sorceries in stack to activate the correct trigger (e.g. with Magecraft combos), added "nomovetrigger" ability for all the "fake" cards (e.g. cards which are simple abilities) in order to don't trigger any event on their cast since they are not real cards. (https://github.com/WagicProject/wagic/commit/6331b1daf43eb508ef1f9c54160ee5f4c4ac4ac9) ([Vitty85](https://github.com/Vitty85)) +- *Committed:* Updated changelog with last 3 years of modifications (issue #1067 by @remigiusz-suwalski), added tokens in ELD set, improved Android downloader for ELD set, fixed primitives with "asflash" ability, improved all cards with adventure: now they become instants or sorceries in stack to activate the correct trigger (e.g. with Magecraft combos), added "nomovetrigger" ability for all the "fake" cards (e.g. cards which are simple abilities) in order to don't trigger any event on their cast since they are not real cards. https://github.com/WagicProject/wagic/commit/c978223b10f629f2b36f2e677254e293ec6aa39b ([Vitty85](https://github.com/Vitty85)) ### 20/08/21 - *Committed:* Fixed "Cunning Rhetoric". (https://github.com/WagicProject/wagic/commit/cd9e5fb2e53e82dfb128b9a6110c76567af0ba0c) ([Vitty85](https://github.com/Vitty85)) diff --git a/projects/mtg/bin/Res/sets/primitives/borderline.txt b/projects/mtg/bin/Res/sets/primitives/borderline.txt index 02487b252..4cc7d731e 100644 --- a/projects/mtg/bin/Res/sets/primitives/borderline.txt +++ b/projects/mtg/bin/Res/sets/primitives/borderline.txt @@ -47910,6 +47910,16 @@ power=3 toughness=3 [/card] [card] +name=Psychic Transfer +other={4}{U} name(Psychic Transfer) +otherrestriction=compare(lifetotalminusopponentlifetotalminusend)~morethan~4 +restriction=compare(opponentlifetotalminuslifetotalminusend)~morethan~4 +auto=exchangelife opponent +text=If the difference between your life total and target player's life total is 5 or less, exchange life totals with that player. +mana={4}{U} +type=Sorcery +[/card] +[card] name=Psychotic Episode abilities=madness auto=if type(*|opponenthand)~morethan~0 then choice name(Look opponent's hand) target(*|opponenthand) bottomoflibrary @@ -47948,6 +47958,14 @@ power=3 toughness=3 [/card] [card] +name=Pull from Eternity +target=*|exile +auto=moveto(ownergraveyard) +text=Put target face-up exiled card into its owner's graveyard. +mana={W} +type=Instant +[/card] +[card] name=Pull from Tomorrow auto=draw:X && reject notatarget(*|myhand) text=Draw X cards, then discard a card. @@ -47990,6 +48008,14 @@ mana={1}{R}{G} type=Sorcery [/card] [card] +name=Purgatory +auto=@movedto(creature[-token]|mygraveyard) from(battlefield):name(Exile creature) all(trigger[to]) moveto(myexile) and!( counter(0/0.1.PurgatoryExile) )! +auto=@each my upkeep restriction{type(creature|myexile)~morethan~0}:may pay({4}) name(Return exiled creature) target(creature[counter{0/0.1.PurgatoryExile}]|myexile) moveto(myBattlefield) and!( life:-2 controller )! +text=Whenever a nontoken creature is put into your graveyard from the battlefield, exile that card. -- At the beginning of your upkeep, you may pay {4} and 2 life. If you do, return a card exiled with Purgatory to the battlefield. +mana={2}{W}{B} +type=Enchantment +[/card] +[card] name=Purphoros's Intervention auto=choice name(Create elemental token) token(Elemental,Creature Elemental,X/1,red,trample,haste,unearth) auto=choice name(Deals twice X damage) damage:X target(creature,planeswalker) && damage:X target(creature,planeswalker) @@ -48136,6 +48162,41 @@ mana={4}{R}{R} type=Instant [/card] [card] +name=Pyromancer's Gauntlet +auto=@damaged(*|opponentBattlefield) from(instant[red]|myzones):all(trigger[to]) transforms((,newability[damage:2])) oneshot +auto=@damaged(*|opponentBattlefield) from(sorcery[red]|myzones):all(trigger[to]) transforms((,newability[damage:2])) oneshot +auto=@damaged(*|opponentBattlefield) from(planeswalker[red]|myzones):all(trigger[to]) transforms((,newability[damage:2])) oneshot +auto=@damagefoeof(player) from(instant[red]|myzones):name(Damage opponent) damage:2 opponent +auto=@damagefoeof(player) from(sorcery[red]|myzones):name(Damage opponent) damage:2 opponent +auto=@damagefoeof(player) from(planeswalker[red]|myzones):name(Damage opponent) damage:2 opponent +text=If a red instant or sorcery spell you control or a red planeswalker you control would deal damage to a permanent or player, it deals that much damage plus 2 to that permanent or player instead. +mana={5} +type=Artifact +[/card] +[card] +name=Pyromancer's Goggles +auto={T}:name(Add red mana) transforms((,newability[add{R}],newability[@movedto(*[sorcery;instant;red]|mystack) turnlimited:all(trigger[to]) activate castcard(copied noevent)])) ueot +text={T}: Add {R} to your mana pool. When that mana is spent to cast a red instant or sorcery spell, copy that spell and you may choose new targets for the copy. +mana={5} +type=Legendary Artifact +[/card] +[card] +name=Pyromancer's Swath +auto=@damaged(*|opponentBattlefield) from(*[instant;sorcery]|myzones):all(trigger[to]) transforms((,newability[damage:2])) oneshot +auto=@damagefoeof(player) from(*[instant;sorcery]|myzones):name(Damage opponent) damage:2 opponent +auto=@each endofturn:name(Discard hand) all(*|myhand) reject +text=If an instant or sorcery source you control would deal damage to a creature or player, it deals that much damage plus 2 to that creature or player instead. -- At the beginning of each end step, discard your hand. +mana={2}{R} +type=Enchantment +[/card] +[card] +name=Pyromancy +auto={D}{3}:name(Deal damage) transforms((,newability[all(*[zpos=type:*:mygraveyard]|mygraveyard) transforms((,newability[name(Damage creature or player) damage:manacost target(player^creature)])) oneshot])) oneshot +text={3}, Discard a card at random: Pyromancy deals damage to target creature or player equal to the converted mana cost of the discarded card. +mana={2}{R}{R} +type=Enchantment +[/card] +[card] name=Pyromantic Pilgrim abilities=haste text=Haste (This creature can attack and {T} as soon as it comes under your control.) @@ -48187,6 +48248,14 @@ mana={4}{R} type=Sorcery [/card] [card] +name=Pyxis of Pandemonium +auto={T}:name(Exile top cards) all(*[zpos=1]|library) moveto(ownerexile) and!( counter(0/0.1.PyxisExiled) )! +auto={7}{T}:name(Put permanents in play) all(*[-instant;-sorcery;counter{0/0.1.PyxisExiled}]|exile) moveto(ownerbattlefield) +text={T}: Each player exiles the top card of his or her library face down. -- {7}, {T}, Sacrifice Pyxis of Pandemonium: Each player turns face up all cards he or she owns exiled with Pyxis of Pandemonium, then puts all permanent cards among them onto the battlefield. +mana={1} +type=Artifact +[/card] +[card] name=Qarsi Deceiver auto={T}:add{C} text={T}: Add {1} to your mana pool. Spend this mana only to cast a face-down creature spell, pay a mana cost to turn a manifested creature face up, or pay a morph cost. (A megamorph cost is a morph cost.) @@ -48445,6 +48514,17 @@ mana={3}{R} type=Sorcery [/card] [card] +name=Quest for Pure Flame +auto=@damagefoeof(player) from(*[instant;sorcery]|stack,Graveyard):name(Put Quest counter) counter(0/0.1.quest) +auto=@damagefoeof(player) from(*[enchantment;artifact;land;planeswalker]|battlefield,Graveyard):name(Put Quest counter) counter(0/0.1.quest) +auto=@damagefoeof(player) from(creature[-Fiendish Duo]|battlefield,Graveyard):name(Put Quest counter) counter(0/0.1.quest) +auto=@combatdamagefoeof(player) from(this):damage:name(Put Quest counter) counter(0/0.1.quest) +auto={S} restriction{compare(hascntquest)~morethan~3}:name(Sacrifice and double damage) emblem transforms((,newability[@damagefoeof(player) from(*[instant;sorcery]|myzones):damage:thatmuch all(trigger[to])],newability[@damagefoeof(player) from(*[creature;artifact;land;planeswalker]|myzones):damage:thatmuch all(trigger[to])],newability[@damagefoeof(player) from(enchantment[-Quest for Pure Flame]|myzones):damage:thatmuch all(trigger[to])])) ueot dontremove +text=Whenever a source you control deals damage to an opponent, you may put a quest counter on Quest for Pure Flame. -- Remove four quest counters from Quest for Pure Flame and sacrifice it: If any source you control would deal damage to a creature or player this turn, it deals double that damage to that creature or player instead. +mana={R} +type=Enchantment +[/card] +[card] name=Questing Beast abilities=vigilance,deathtouch,haste auto=cantbeblockedby(creature[power<=2]) @@ -48627,6 +48707,17 @@ power=4 toughness=2 [/card] [card] +name=Rag Man +auto=this(variable{ishuman}>0) {B}{B}{B}{T}:name(Look opponent hand) name(Look opponent hand) target(*|opponenthand) transforms((,newability[name(Discard creature) target(creature|myhand) reject])) oneshot myturnonly +auto=this(variable{ishuman}<1) {B}{B}{B}{T}:name(Look opponent hand) name(Look opponent hand) target(*|opponenthand) transforms((,newability[ability$!name(Discard creature) name(Discard creature) target(creature|opponenthand) reject!$ opponent])) oneshot myturnonly +text={B}{B}{B}, {T}: Target opponent reveals his or her hand and discards a creature card at random. Activate this ability only during your turn. +mana={2}{B}{B} +type=Creature +subtype=Human Minion +power=2 +toughness=1 +[/card] +[card] name=Ragavan, Nimble Pilferer other={R}{2} name(Dash) auto=if paid(alternative) then transforms((,newability[haste],newability[phaseaction[endofturn sourceinplay] moveto(ownerhand) all(this)])) forever diff --git a/projects/mtg/bin/Res/sets/primitives/unsupported.txt b/projects/mtg/bin/Res/sets/primitives/unsupported.txt index 8f2e00101..32e6aeef4 100644 --- a/projects/mtg/bin/Res/sets/primitives/unsupported.txt +++ b/projects/mtg/bin/Res/sets/primitives/unsupported.txt @@ -8663,12 +8663,6 @@ mana={1}{U} type=Sorcery [/card] [card] -name=Psychic Transfer -text=If the difference between your life total and target player's life total is 5 or less, exchange life totals with that player. -mana={4}{U} -type=Sorcery -[/card] -[card] name=Psychogenic Probe text=Whenever a spell or ability causes a player to shuffle his or her library, Psychogenic Probe deals 2 damage to him or her. mana={2} @@ -8681,12 +8675,6 @@ mana={3}{U} type=Enchantment [/card] [card] -name=Pull from Eternity -text=Put target face-up exiled card into its owner's graveyard. -mana={W} -type=Instant -[/card] -[card] name=Pulling Teeth text=Clash with an opponent. If you win, target player discards two cards. Otherwise, that player discards a card. (Each clashing player reveals the top card of his or her library, then puts that card on the top or bottom. A player wins if his or her card had a higher converted mana cost.) mana={1}{B} @@ -8713,14 +8701,9 @@ type=Instant subtype=Arcane [/card] [card] -name=Purgatory -text=Whenever a nontoken creature is put into your graveyard from the battlefield, exile that card. -- At the beginning of your upkeep, you may pay {4} and 2 life. If you do, return a card exiled with Purgatory to the battlefield. -mana={2}{W}{B} -type=Enchantment -[/card] -[card] name=Purity abilities=flying +auto=@movedto(this|mygraveyard):name(Shuffle in library) all(trigger[to]) moveto(ownerlibrary) and!( shuffle )! text=Flying -- If noncombat damage would be dealt to you, prevent that damage. You gain life equal to the damage prevented this way. -- When Purity is put into a graveyard from anywhere, shuffle it into its owner's library. mana={3}{W}{W}{W} type=Creature @@ -8768,42 +8751,6 @@ mana={1}{R} type=Enchantment [/card] [card] -name=Pyromancer's Gauntlet -text=If a red instant or sorcery spell you control or a red planeswalker you control would deal damage to a permanent or player, it deals that much damage plus 2 to that permanent or player instead. -mana={5} -type=Artifact -[/card] -[card] -name=Pyromancer's Goggles -text={T}: Add {R} to your mana pool. When that mana is spent to cast a red instant or sorcery spell, copy that spell and you may choose new targets for the copy. -mana={5} -type=Legendary Artifact -[/card] -[card] -name=Pyromancer's Swath -text=If an instant or sorcery source you control would deal damage to a creature or player, it deals that much damage plus 2 to that creature or player instead. -- At the beginning of each end step, discard your hand. -mana={2}{R} -type=Enchantment -[/card] -[card] -name=Pyromancy -text={3}, Discard a card at random: Pyromancy deals damage to target creature or player equal to the converted mana cost of the discarded card. -mana={2}{R}{R} -type=Enchantment -[/card] -[card] -name=Pyxis of Pandemonium -text={T}: Each player exiles the top card of his or her library face down. -- {7}, {T}, Sacrifice Pyxis of Pandemonium: Each player turns face up all cards he or she owns exiled with Pyxis of Pandemonium, then puts all permanent cards among them onto the battlefield. -mana={1} -type=Artifact -[/card] -[card] -name=Quest for Pure Flame -text=Whenever a source you control deals damage to an opponent, you may put a quest counter on Quest for Pure Flame. -- Remove four quest counters from Quest for Pure Flame and sacrifice it: If any source you control would deal damage to a creature or player this turn, it deals double that damage to that creature or player instead. -mana={R} -type=Enchantment -[/card] -[card] name=Question Elemental? abilities=flying text=Flying -- Are you aware that when you say something that isn't a question, the player who first points out this fact gains control of Question Elemental? @@ -8880,15 +8827,6 @@ mana={3}{R}{R} type=Instant [/card] [card] -name=Rag Man -text={B}{B}{B}, {T}: Target opponent reveals his or her hand and discards a creature card at random. Activate this ability only during your turn. -mana={2}{B}{B} -type=Creature -subtype=Human Minion -power=2 -toughness=1 -[/card] -[card] name=Rage Extractor text=({PR} can be paid with either {R} or 2 life.) -- Whenever you cast a spell with Phyrexian in its mana cost, Rage Extractor deals damage equal to that spell's converted mana cost to target creature or player. mana={4}{PR} diff --git a/projects/mtg/include/AIPlayerBaka.h b/projects/mtg/include/AIPlayerBaka.h index 11aa80322..462f230db 100644 --- a/projects/mtg/include/AIPlayerBaka.h +++ b/projects/mtg/include/AIPlayerBaka.h @@ -93,7 +93,7 @@ class AIPlayerBaka: public AIPlayer{ virtual AIStats * getStats(); - bool payAlternative; + int payAlternative; MTGCardInstance * nextCardToPlay; MTGCardInstance * activateCombo(); TargetChooser * GetComboTc(GameObserver * observer, TargetChooser * tc = NULL); @@ -122,6 +122,12 @@ class AIPlayerBaka: public AIPlayer{ INFO_CREATURESATTACKINGPOWER }; + enum { + NONE, + OTHER, + MORPH + }; // Possbile alternative costs to be used for AI. + vectorgotPayments; AIPlayerBaka(GameObserver *observer, string deckFile, string deckfileSmall, string avatarFile, MTGDeck * deck = NULL); diff --git a/projects/mtg/src/AIPlayerBaka.cpp b/projects/mtg/src/AIPlayerBaka.cpp index a26984ea2..0dec25b22 100644 --- a/projects/mtg/src/AIPlayerBaka.cpp +++ b/projects/mtg/src/AIPlayerBaka.cpp @@ -2750,7 +2750,7 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty cd.init(); cd.setType(type); card = NULL; - payAlternative = false; + payAlternative = NONE; gotPayments = vector(); //canplayfromgraveyard while ((card = cd.nextmatch(game->graveyard, card))) @@ -3237,7 +3237,7 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty card = NULL; // fixed bug causing AI never play a card there are one or more cards in exile or other zones... while ((card = cd.nextmatch(game->hand, card))) { - bool localpayAlternative = false; + int localpayAlternative = NONE; if (!CanHandleCost(card->getManaCost(),card)) continue; @@ -3293,11 +3293,11 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty ManaCost* manaToPay = card->getManaCost(); if((!pMana->canAfford(card->getManaCost(),0) || card->getManaCost()->getKicker())) gotPayments = canPayMana(card,card->getManaCost(),card->has(Constants::ANYTYPEOFMANA)); + bool hasConvoke = false; //Fix a crash when AI try to pay convoke cost. + bool hasOffering = card->basicAbilities[Constants::OFFERING]; //Fix a hang when AI try to pay emerge cost. + bool hasDelve = false; //Fix a hang when AI try to pay delve cost. if(card->getManaCost()->getAlternative() && !gotPayments.size() && !pMana->canAfford(card->getManaCost(),0) && !card->getManaCost()->getKicker()){ //Now AI can cast cards using alternative cost. ManaCost * extra = card->getManaCost()->getAlternative(); - bool hasConvoke = false; //Fix a crash when AI try to pay convoke cost. - bool hasOffering = card->basicAbilities[Constants::OFFERING]; //Fix a hang when AI try to pay emerge cost. - bool hasDelve = false; //Fix a hang when AI try to pay delve cost. if(extra->extraCosts){ for(unsigned int i = 0; i < extra->extraCosts->costs.size() && !hasConvoke && !hasOffering && !hasDelve; i++){ if(dynamic_cast (extra->extraCosts->costs[i])) @@ -3309,12 +3309,18 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty } } if(!hasOffering && !hasConvoke && !hasDelve){ - localpayAlternative = true; + localpayAlternative = OTHER; manaToPay = card->getManaCost()->getAlternative(); if(!pMana->canAfford(manaToPay,0)) gotPayments = canPayMana(card,card->getManaCost()->getAlternative(),card->has(Constants::ANYTYPEOFMANA)); } - } + } + if(card->getManaCost()->getMorph() && !gotPayments.size() && !pMana->canAfford(card->getManaCost(),0) && !card->getManaCost()->getKicker() && !card->getManaCost()->getAlternative()){ //Now AI can cast cards using morph cost. + localpayAlternative = MORPH; + manaToPay = card->getManaCost()->getMorph(); + if(!pMana->canAfford(manaToPay,0)) + gotPayments = canPayMana(card,card->getManaCost()->getMorph(),card->has(Constants::ANYTYPEOFMANA)); + } //for preformence reason we only look for specific mana if the payment couldn't be made with pmana. if ((currentCost > maxCost || hasX) && (gotPayments.size() || pMana->canAfford(manaToPay,card->has(Constants::ANYTYPEOFMANA)))) { @@ -3394,13 +3400,13 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty } DebugTrace("Should I play from hand" << (card ? card->name : "Nothing" ) << "?" << endl <<"shouldPlayPercentage = "<< shouldPlayPercentage); - if(localpayAlternative){ + if(localpayAlternative != NONE){ if(card->getOtherRestrictions().size()) { AbilityFactory af(observer); int canPlay = af.parseCastRestrictions(card,card->controller(),card->getOtherRestrictions()); if(!canPlay){ - localpayAlternative = false; + localpayAlternative = NONE; canPlay = true; if(card->getRestrictions().size()) canPlay = af.parseCastRestrictions(card,card->controller(),card->getRestrictions()); //Check if card can be casted at least with normal cost. @@ -3413,11 +3419,18 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty { AbilityFactory af(observer); int canPlay = af.parseCastRestrictions(card,card->controller(),card->getRestrictions()); - if(!canPlay && card->getManaCost()->getAlternative()){ + if(!canPlay && (card->getManaCost()->getAlternative() || card->getManaCost()->getMorph())){ canPlay = true; if(card->getOtherRestrictions().size()) - canPlay = af.parseCastRestrictions(card,card->controller(),card->getOtherRestrictions()); //Check if card can be casted at least with other cost. - if(canPlay) localpayAlternative = true; + canPlay = af.parseCastRestrictions(card,card->controller(),card->getOtherRestrictions()); //Check if card can be casted at least with alternative costs (e.g. other or morph). + if(canPlay) { + if(card->getManaCost()->getAlternative() && !hasOffering && !hasConvoke && !hasDelve) + localpayAlternative = OTHER; + else if(card->getManaCost()->getMorph()) + localpayAlternative = MORPH; + else + canPlay = false; + } } if(!canPlay) continue; @@ -3448,9 +3461,12 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty if(!pMana->canAfford(nextCardToPlay->getManaCost()->getRetrace(),0)) gotPayments = canPayMana(nextCardToPlay,nextCardToPlay->getManaCost()->getRetrace(),nextCardToPlay->has(Constants::ANYTYPEOFMANA)); } - } else if(payAlternative){ + } else if(payAlternative == OTHER){ if(!pMana->canAfford(nextCardToPlay->getManaCost()->getAlternative(),0)) // Now AI can cast cards using alternative cost. gotPayments = canPayMana(nextCardToPlay,nextCardToPlay->getManaCost()->getAlternative(),nextCardToPlay->has(Constants::ANYTYPEOFMANA)); + } else if(payAlternative == MORPH){ + if(!pMana->canAfford(nextCardToPlay->getManaCost()->getMorph(),0)) // Now AI can cast cards using morph cost. + gotPayments = canPayMana(nextCardToPlay,nextCardToPlay->getManaCost()->getMorph(),nextCardToPlay->has(Constants::ANYTYPEOFMANA)); } else { if(!pMana->canAfford(nextCardToPlay->getManaCost(),0) || nextCardToPlay->getManaCost()->getKicker()) gotPayments = canPayMana(nextCardToPlay,nextCardToPlay->getManaCost(),nextCardToPlay->has(Constants::ANYTYPEOFMANA)); @@ -3655,13 +3671,20 @@ int AIPlayerBaka::computeActions() gotPayments.clear(); } } - } else if(payAlternative){ // Now AI can cast cards using alternative cost. + } else if(payAlternative == OTHER){ // Now AI can cast cards using other cost. if(payTheManaCost(nextCardToPlay->getManaCost()->getAlternative(),nextCardToPlay->has(Constants::ANYTYPEOFMANA),nextCardToPlay,gotPayments)) { AIAction * a = NEW AIAction(this, nextCardToPlay); clickstream.push(a); gotPayments.clear(); } + } else if(payAlternative == MORPH){ // Now AI can cast cards using morph cost. + if(payTheManaCost(nextCardToPlay->getManaCost()->getMorph(),nextCardToPlay->has(Constants::ANYTYPEOFMANA),nextCardToPlay,gotPayments)) + { + AIAction * a = NEW AIAction(this, nextCardToPlay); + clickstream.push(a); + gotPayments.clear(); + } } else { if(payTheManaCost(nextCardToPlay->getManaCost(),nextCardToPlay->has(Constants::ANYTYPEOFMANA),nextCardToPlay,gotPayments)) { @@ -3839,13 +3862,20 @@ int AIPlayerBaka::computeActions() gotPayments.clear(); } } - } else if(payAlternative){ // Now AI can cast cards using alternative cost. + } else if(payAlternative == OTHER){ // Now AI can cast cards using other cost. if(payTheManaCost(nextCardToPlay->getManaCost()->getAlternative(),nextCardToPlay->has(Constants::ANYTYPEOFMANA),nextCardToPlay,gotPayments)) { AIAction * a = NEW AIAction(this, nextCardToPlay); clickstream.push(a); gotPayments.clear(); } + } else if(payAlternative == MORPH){ // Now AI can cast cards using morph cost. + if(payTheManaCost(nextCardToPlay->getManaCost()->getMorph(),nextCardToPlay->has(Constants::ANYTYPEOFMANA),nextCardToPlay,gotPayments)) + { + AIAction * a = NEW AIAction(this, nextCardToPlay); + clickstream.push(a); + gotPayments.clear(); + } } else { if(payTheManaCost(nextCardToPlay->getManaCost(),nextCardToPlay->has(Constants::ANYTYPEOFMANA),nextCardToPlay,gotPayments)) {