From 0b5f375df67a4359a496bd73448da556630acac7 Mon Sep 17 00:00:00 2001 From: Vittorio Alfieri Date: Wed, 20 Jan 2021 18:11:56 +0100 Subject: [PATCH] Fixed primitives, fixed multiple snow mana cost payments, added keywords to count snow mana pool (total and single colors). --- .../bin/Res/sets/primitives/borderline.txt | 102 +----------------- projects/mtg/src/MTGAbility.cpp | 42 +++++++- projects/mtg/src/WParsedInt.cpp | 32 +++++- 3 files changed, 72 insertions(+), 104 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/borderline.txt b/projects/mtg/bin/Res/sets/primitives/borderline.txt index 28041c21c..3bdd8bbae 100644 --- a/projects/mtg/bin/Res/sets/primitives/borderline.txt +++ b/projects/mtg/bin/Res/sets/primitives/borderline.txt @@ -457,14 +457,8 @@ type=Artifact name=Aether Storm auto=maxCast(creature)0 opponent auto=maxCast(creature)0 controller -auto={L:4}:bury all(this) -auto=@each opponent upkeep:ability$!name(Pay 4 life) pay[[{L:4}]] name(Pay 4 life) bury notatarget(Aether Storm|opponentBattlefield)?donothing!$ opponent -auto=@each opponent untap:ability$!name(Pay 4 life) pay[[{L:4}]] name(Pay 4 life) bury notatarget(Aether Storm|opponentBattlefield)?donothing!$ opponent -auto=@each opponent draw:ability$!name(Pay 4 life) pay[[{L:4}]] name(Pay 4 life) bury notatarget(Aether Storm|opponentBattlefield)?donothing!$ opponent -auto=@each opponent combatbegins:ability$!name(Pay 4 life) pay[[{L:4}]] name(Pay 4 life) bury notatarget(Aether Storm|opponentBattlefield)?donothing!$ opponent -auto=@each opponent blockers:ability$!name(Pay 4 life) pay[[{L:4}]] name(Pay 4 life) bury notatarget(Aether Storm|opponentBattlefield)?donothing!$ opponent -auto=@each opponent firstmain:ability$!name(Pay 4 life) pay[[{L:4}]] name(Pay 4 life) bury notatarget(Aether Storm|opponentBattlefield)?donothing!$ opponent -auto=@each opponent endofturn:ability$!name(Pay 4 life) pay[[{L:4}]] name(Pay 4 life) bury notatarget(Aether Storm|opponentBattlefield)?donothing!$ opponent +auto={L:4}:bury(this) opponent +auto={L:4}:bury(this) controller text=Creature spells can’t be cast. -- Pay 4 life: Destroy Aether Storm. It can’t be regenerated. Any player may activate this ability. mana={3}{U} type=Enchantment @@ -1046,21 +1040,6 @@ power=2 toughness=2 [/card] [card] -name=Alrund, God of the Cosmos -other={1}{U} name(Hakka, Whispering Raven) -otherrestriction=can play creature -autostack=if paid(alternative) then name(Hakka, Whispering Raven) name(Hakka, Whispering Raven) flip(Hakka, Whispering Raven) forcetype(Legendary Creature) -auto=this(variable{isflipped}<1) foreach(*[foretold]|myexile) 1/1 -auto=@each my endofturn restriction{compare(isflipped)~equalto~0}:transforms((,newability[choice name(Creature) reveal:2 optionone name(Get Creature) target(<2>Creature|reveal) moveto(myhand) optiononeend optiontwo name(Bottom of library) target(<2>*|reveal) bottomoflibrary optiontwoend revealend],newability[choice name(Artifact) reveal:2 optionone name(Get Artifact) target(<2>artifact|reveal) moveto(myhand) optiononeend optiontwo name(Bottom of library) target(<2>*|reveal) bottomoflibrary optiontwoend revealend],newability[choice name(Enchantment) reveal:2 optionone name(Get Enchantment) target(<2>enchantment|reveal) moveto(myhand) optiononeend optiontwo name(Bottom of library) target(<2>*|reveal) bottomoflibrary optiontwoend revealend],newability[choice name(Instant) reveal:2 optionone name(Get Instant) target(<2>instant|reveal) moveto(myhand) optiononeend optiontwo name(put in grave) name(Bottom of library) bottomoflibrary optiontwoend revealend],newability[choice name(Land) reveal:2 optionone name(Get Land) target(<2>land|reveal) moveto(myhand) optiononeend optiontwo name(Bottom of library) target(<2>*|reveal) bottomoflibrary optiontwoend revealend],newability[choice name(Planeswalker) reveal:2 optionone name(Get Planeswalker) target(<2>planeswalker|reveal) moveto(myhand) optiononeend optiontwo name(Bottom of library) target(<2>*|reveal) bottomoflibrary optiontwoend revealend],newability[choice name(Sorcery) reveal:2 optionone name(Get Sorcery) target(<2>sorcery|reveal) moveto(myhand) optiononeend optiontwo name(Bottom of library) target(<2>*|reveal) bottomoflibrary optiontwoend revealend],newability[choice name(Tribal) reveal:2 optionone name(Get Tribal) target(<2>tribal|reveal) moveto(myhand) optiononeend optiontwo name(Bottom of library) target(<2>*|reveal) bottomoflibrary optiontwoend revealend])) oneshot -aicode=@each my endofturn restriction{compare(isflipped)~equalto~0}:ability$!name(Choose one) choice name(Creature) all(*[creature;zpos<=2]|mylibrary) moveto(myhand) && all(*[-creature;zpos<=2]|mylibrary) bottomoflibrary _ choice name(Artifact) all(*[artifact;zpos<=2]|mylibrary) moveto(myhand) && all(*[-artifact;zpos<=2]|mylibrary) bottomoflibrary _ choice name(Enchantment) all(*[enchantment;zpos<=2]|mylibrary) moveto(myhand) && all(*[-enchantment;zpos<=2]|mylibrary) bottomoflibrary _ choice name(Instant) all(*[instant;zpos<=2]|mylibrary) moveto(myhand) && all(*[-instant;zpos<=2]|mylibrary) bottomoflibrary _ choice name(Land) all(*[land;zpos<=2]|mylibrary) moveto(myhand) && all(*[-land;zpos<=2]|mylibrary) bottomoflibrary _ choice name(Planeswalker) all(*[planeswalker;zpos<=2]|mylibrary) moveto(myhand) && all(*[-planeswalker;zpos<=2]|mylibrary) bottomoflibrary _ choice name(Sorcery) all(*[sorcery;zpos<=2]|mylibrary) moveto(myhand) && all(*[-sorcery;zpos<=2]|mylibrary) bottomoflibrary _ choice name(Tribal) all(*[tribal;zpos<=2]|mylibrary) moveto(myhand) && all(*[-tribal;zpos<=2]|mylibrary) bottomoflibrary!$ controller -text=Alrund gets +1/+1 for each card in your hand and each foretold card you own in exile. -- At the beginning of your end step, choose a card type, then reveal the top two cards of your library. Put all cards of the chosen type into your hand and the rest on the bottom of your library in any order. -mana={3}{U}{U} -type=Legendary Creature -subtype=God -power=1 -toughness=1 -[/card] -[card] name=Alseid of Life's Bounty abilities=lifelink auto={1}{S}:name(Protection from white) protection from white target(creature,enchantment|myBattlefield) @@ -21095,18 +21074,6 @@ mana={X}{W} type=Instant [/card] [card] -name=Hakka, Whispering Raven -abilities=flying -auto=@combatdamagefoeof(player) from(this):name(Return to hand and scry 2) name(Return to hand and scry 2) moveTo(ownerhand) and!( scry:2 scrycore delayed dontshow donothing scrycoreend scryend )! -auto=@combatdamageof(player) from(this):name(Return to hand and scry 2) name(Return to hand and scry 2) moveTo(ownerhand) and!( scry:2 scrycore delayed dontshow donothing scrycoreend scryend )! -text=Flying -- Whenever Hakka, Whispering Raven deals combat damage to a player, return it to its owner’s hand, then scry 2. -mana={1}{U} -type=Legendary Creature -subtype=Bird -power=2 -toughness=3 -[/card] -[card] name=Halana, Kessig Ranger abilities=reach,partner auto=@movedTo(other creature|mybattlefield):may pay({2}) name(Pay 2) all(trigger[to]) transforms((,newability[name(Damage creature) dynamicability target(creature)])) oneshot @@ -21185,22 +21152,6 @@ text=Cumulative upkeep {1} (At the beginning of your upkeep, put an age counter type=Land [/card] [card] -name=Halvar, God of Battle -other={1}{W} name(Sword of the Realms) -otherrestriction=can play equipment -autostack=if paid(alternative) then flip(Sword of the Realms) forcetype(Legendary Artifact) -auto=this(variable{isflipped}<1) lord(creature[geared;enchanted]|myBattlefield) double strike -auto=@each combatbegins restriction{compare(isflipped)~equalto~0,type(creature|mybattlefield)~morethan~1,type(creature[equipped]|mybattlefield)~morethan~0,type(creature[enchanted]|mybattlefield)~equalto~0}:may name(Re-attach target equipment) target(*[equipment]|mybattlefield) transforms((,newability[name(Attach to creature) name(Attach to creature) rehook target(creature|mybattlefield)])) oneshot -auto=@each combatbegins restriction{compare(isflipped)~equalto~0,type(creature|mybattlefield)~morethan~1,type(creature[equipped]|mybattlefield)~equalto~0,type(creature[enchanted]|mybattlefield)~morethan~0}:may name(Re-attach target aura) target(*[aura]|mybattlefield) transforms((,newability[name(Attach to creature) name(Attach to creature) rehook target(creature|mybattlefield)])) oneshot -auto=@each combatbegins restriction{compare(isflipped)~equalto~0,type(creature|mybattlefield)~morethan~1,type(creature[equipped]|mybattlefield)~morethan~0,type(creature[enchanted]|mybattlefield)~morethan~0}:may name(Re-attach target equipment or aura) target(*[aura;equipment]|mybattlefield) transforms((,newability[name(Attach to creature) name(Attach to creature) rehook target(creature|mybattlefield)])) oneshot -text=Creatures you control that are enchanted or equipped have double strike. -- At the beginning of each combat, you may attach target Aura or Equipment attached to a creature you control to target creature you control. -mana={2}{W}{W} -type=Legendary Creature -subtype=God -power=4 -toughness=4 -[/card] -[card] name=Hammer Dropper abilities=mentor auto=@combat(attacking) source(this) restriction{compare(p)~lessthan~1}:counter(1/1,1) target(other creature[attacking;power<=-1]|myBattlefield) @@ -24717,7 +24668,7 @@ type=Instant name=Invoke the Divine target=artifact,enchantment auto=destroy -auto=life:4 +auto=life:4 controller text=Destroy target artifact or enchantment. You gain 4 life. mana={2}{W} type=Instant @@ -25410,19 +25361,6 @@ power=3 toughness=2 [/card] [card] -name=Jorn, God of Winter -other={1}{U}{B} name(Kaldring, the Rimestaff) -otherrestriction=can play artifact -autostack=if paid(alternative) then flip(Kaldring, the Rimestaff) forcetype(Legendary Snow Artifact) -auto=@combat(attacking) source(this) restriction{compare(isflipped)~equalto~0}:all(*[snow]|mybattlefield) untap -text=Whenever Jorn attacks, untap each snow permanent you control. -mana={2}{G} -type=Legendary Snow Creature -subtype=God -power=4 -toughness=4 -[/card] -[card] name=Josu Vess, Lich Knight abilities=menace kicker={5}{B} @@ -25755,18 +25693,6 @@ power=3 toughness=3 [/card] [card] -name=Kaldring, the Rimestaff -auto={T}:name(Choose snow permanent) name(Choose snow permanent) target(*[snow]|mygraveyard) transforms((,newability[canplayfromgraveyard])) ueot && counter(0/0,1,KaldEffect) all(this) -auto=@movedto(*[snow]|mybattlefield) from(mygraveyard):this(counter{0/0.1.KaldEffect}>0) all(trigger[to]) tap(noevent) && ability$!counter(0/0,-1,KaldEffect) all(mysource)!$ controller -auto=@movedto(*[snow]|mystack) from(mygraveyard):this(counter{0/0.1.KaldEffect}>0) counter(0/0,1,KaldEffect2) && ability$!counter(0/0,-1,KaldEffect) all(mysource)!$ controller -auto=@movedto(*[snow]|mybattlefield):this(counter{0/0.1.KaldEffect2}>0) all(trigger[to]) tap(noevent) && ability$!counter(0/0,-1,KaldEffect2) all(mysource)!$ controller -auto=@each endofturn:this(counter{0/0.1.KaldEffect}>0) counter(0/0,-1,KaldEffect) -auto=@each endofturn:this(counter{0/0.1.KaldEffect2}>0) counter(0/0,-1,KaldEffect2) -text={T}: You may play target snow permanent card from your graveyard this turn. If you do, it enters the battlefield tapped. -mana={1}{U}{B} -type=Legendary Snow Artifact -[/card] -[card] name=Kalitas, Traitor of Ghet abilities=lifelink auto=@movedto(creature[token]|opponentbattlefield):all(trigger[to]) moveTo(exile) && token(Zombie,Creature Zombie,2/2,black) @@ -41572,17 +41498,6 @@ power=3 toughness=3 [/card] [card] -name=Saw It Coming -abilities=foretell -target=*|stack -auto=fizzle -autohand={2}:name(Pay 2 and exile face-down) name(Pay 2 and exile face-down) foretell myturnonly -autoexile={1}{U} restriction{compare(canforetellcast)~morethan~0,type(*|stack)~morethan~0}:name(Cast with foretell) name(Cast with foretell) activate castcard(alternative) -text=Counter target spell. -- Foretell {1}{U} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.) -mana={1}{U}{U} -type=Instant -[/card] -[card] name=Sawtusk Demolisher abilities=trample,mutate otherrestriction=type(creature[-human]|mybattlefield)~morethan~0 @@ -48604,17 +48519,6 @@ type=Artifact subtype=Equipment [/card] [card] -name=Sword of the Realms -auto={1}{W}:equip -auto=teach(creature) 2/0 -auto=teach(creature) vigilance -auto=teach(creature) handdeath -text=Equipped creature gets +2/+0 and has vigilance. -- Whenever equipped creature dies, return it to its owner’s hand. -- Equip {1}{W} -mana={1}{W} -type=Legendary Artifact -subttype=Equipment -[/card] -[card] name=Sword of Truth and Justice auto={2}:equip auto=teach(creature) protection from white diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index c7ccac504..2259cea99 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -6240,9 +6240,21 @@ int ActivatedAbility::reactToClick(MTGCardInstance * card) game->mExtraPayment = cost->extraCosts; return 0; } + if(cost->extraCosts){ // Added to check if the snow mana amount is enough to pay all the snow cost. + int countSnow = 0; + for(unsigned int i = 0; i < cost->extraCosts->costs.size(); i++){ + if(dynamic_cast (cost->extraCosts->costs[i])) + countSnow++; + } + if((source->controller()->snowManaG + source->controller()->snowManaU + source->controller()->snowManaR + + source->controller()->snowManaB + source->controller()->snowManaW + source->controller()->snowManaC) < countSnow){ + game->mExtraPayment = cost->extraCosts; + return 0; + } + } ManaCost * previousManaPool = NEW ManaCost(player->getManaPool()); + cost->doPayExtra(); // Bring here brefore the normal payment to solve Snow Mana payment bug. game->currentlyActing()->getManaPool()->pay(cost); - cost->doPayExtra(); SAFE_DELETE(abilityCost); abilityCost = previousManaPool->Diff(player->getManaPool()); delete previousManaPool; @@ -6265,9 +6277,21 @@ int ActivatedAbility::reactToTargetClick(Targetable * object) game->mExtraPayment = cost->extraCosts; return 0; } + if(cost->extraCosts){ // Added to check if the snow mana amount is enough to pay all the snow cost. + int countSnow = 0; + for(unsigned int i = 0; i < cost->extraCosts->costs.size(); i++){ + if(dynamic_cast (cost->extraCosts->costs[i])) + countSnow++; + } + if((source->controller()->snowManaG + source->controller()->snowManaU + source->controller()->snowManaR + + source->controller()->snowManaB + source->controller()->snowManaW + source->controller()->snowManaC) < countSnow){ + game->mExtraPayment = cost->extraCosts; + return 0; + } + } ManaCost * previousManaPool = NEW ManaCost(player->getManaPool()); + cost->doPayExtra(); // Bring here brefore the normal payment to solve Snow Mana payment bug. game->currentlyActing()->getManaPool()->pay(cost); - cost->doPayExtra(); SAFE_DELETE(abilityCost); abilityCost = previousManaPool->Diff(player->getManaPool()); delete previousManaPool; @@ -7182,8 +7206,20 @@ int AManaProducer::reactToClick(MTGCardInstance * _card) game->mExtraPayment = cost->extraCosts; return 0; } + if(cost->extraCosts){ // Added to check if the snow mana amount is enough to pay all the snow cost. + int countSnow = 0; + for(unsigned int i = 0; i < cost->extraCosts->costs.size(); i++){ + if(dynamic_cast (cost->extraCosts->costs[i])) + countSnow++; + } + if((source->controller()->snowManaG + source->controller()->snowManaU + source->controller()->snowManaR + + source->controller()->snowManaB + source->controller()->snowManaW + source->controller()->snowManaC) < countSnow){ + game->mExtraPayment = cost->extraCosts; + return 0; + } + } + cost->doPayExtra(); // Bring here brefore the normal payment to solve Snow Mana payment bug. game->currentlyActing()->getManaPool()->pay(cost); - cost->doPayExtra(); } if (options[Options::SFXVOLUME].number > 0) diff --git a/projects/mtg/src/WParsedInt.cpp b/projects/mtg/src/WParsedInt.cpp index 07bad02da..e074cfd6d 100644 --- a/projects/mtg/src/WParsedInt.cpp +++ b/projects/mtg/src/WParsedInt.cpp @@ -567,9 +567,37 @@ void WParsedInt::init(string s, Spell * spell, MTGCardInstance * card) { intValue = (target->foretellTurn < 0)?0:(target->getObserver()->turn-target->foretellTurn); // Check if you can use the foretell cost from exile (CurrentTurn > ForetellTurn). } - else if (s == "isflipped" || s == "snowcount") // Return 1 if card has been flipped -- // Snowcount is just to count the number of snow mana produced ... just for debugging purposes... + else if (s == "isflipped") // Return 1 if card has been flipped { - intValue = (s == "isflipped")?card->isFlipped:target->controller()->snowManaG + target->controller()->snowManaU +target->controller()->snowManaR + target->controller()->snowManaB + target->controller()->snowManaW + target->controller()->snowManaC; + intValue = card->isFlipped; + } + else if (s == "mysnowpoolcount" || s == "opponentsnowpoolcount") // snowpoolcount is just to count the number of snow mana produced ... + { + intValue = (s == "mysnowpoolcount")?(target->controller()->snowManaG + target->controller()->snowManaU + target->controller()->snowManaR + target->controller()->snowManaB + target->controller()->snowManaW + target->controller()->snowManaC):(target->controller()->opponent()->snowManaG + target->controller()->opponent()->snowManaU + target->controller()->opponent()->snowManaR + target->controller()->opponent()->snowManaB + target->controller()->opponent()->snowManaW + target->controller()->opponent()->snowManaC); + } + else if (s == "mysnowgreenpoolcount" || s == "opponentsnowgreenpoolcount") + { + intValue = (s == "mysnowgreenpoolcount")?target->controller()->snowManaG:target->controller()->opponent()->snowManaG; + } + else if (s == "mysnowredpoolcount" || s == "opponentsnowredpoolcount") + { + intValue = (s == "mysnowredpoolcount")?target->controller()->snowManaR:target->controller()->opponent()->snowManaR; + } + else if (s == "mysnowbluepoolcount" || s == "opponentsnowbluepoolcount") + { + intValue = (s == "mysnowbluepoolcount")?target->controller()->snowManaU:target->controller()->opponent()->snowManaU; + } + else if (s == "mysnowwhitepoolcount" || s == "opponentsnowwhitepoolcount") + { + intValue = (s == "mysnowwhitepoolcount")?target->controller()->snowManaW:target->controller()->opponent()->snowManaW; + } + else if (s == "mysnowblackpoolcount" || s == "opponentsnowblackpoolcount") + { + intValue = (s == "mysnowblackpoolcount")?target->controller()->snowManaB:target->controller()->opponent()->snowManaB; + } + else if (s == "mysnowcolorlesspoolcount" || s == "opponentsnowcolorlesspoolcount") + { + intValue = (s == "mysnowcolorlesspoolcount")?target->controller()->snowManaC:target->controller()->opponent()->snowManaC; } else if (s == "mypoolcount" || s == "opponentpoolcount") // total manapool {