Improved Kicker cards, now it's possible to target a specific card with kicker cost and handle any event connected to a kicker casting cost.

This commit is contained in:
valfieri
2020-10-03 16:54:17 +02:00
parent 1b320d5325
commit bf6439db00
9 changed files with 109 additions and 19 deletions

View File

@@ -29482,9 +29482,9 @@ type=Instant
[/card]
[card]
name=Prohibit
other={3}{U} name(Kicker)
auto=ifnot paid(alternative) then target(*[manacost<=2]|stack) fizzle
auto=if paid(alternative) then target(*[manacost<=4]|stack) fizzle
kicker={2}
auto=ifnot paid(kicker) then target(*[manacost<=2]|stack) fizzle
auto=if paid(kicker) then target(*[manacost<=4]|stack) fizzle
text=Kicker {2} (You may pay an additional {2} as you cast this spell.) -- Counter target spell if its converted mana cost is 2 or less. If Prohibit was kicked, counter that spell if its converted mana cost is 4 or less instead.
mana={1}{U}
type=Instant

View File

@@ -5446,6 +5446,7 @@ toughness=1
[/card]
[card]
name=Arctic Merfolk
abilities=hasotherkicker
auto=alternative counter(1/1,1) all(this)
text=Kicker - Return a creature you control to its owner's hand. (You may return a creature you control to its owner's hand in addition to any other costs as you cast this spell.) -- If Arctic Merfolk was kicked, it enters the battlefield with a +1/+1 counter on it.
mana={1}{U}
@@ -12189,6 +12190,7 @@ type=Sorcery
[/card]
[card]
name=Blood Tribute
abilities=hasotherkicker
target=opponent
auto=lifeleech:-halfdownopponentlifetotal targetedplayer
text=Kicker - Tap an untapped Vampire you control. (You may tap a Vampire you control in addition to any other costs as you cast this spell.) -- Target opponent loses half his or her life, rounded up. If Blood Tribute was kicked, you gain life equal to the life lost this way.
@@ -12974,6 +12976,7 @@ toughness=2
[/card]
[card]
name=Bog Down
abilities=hasotherkicker
target=player
auto=ability$!name(discard 2 cards) target(<2>*|myhand) reject!$ targetedplayer
auto=alternative ability$!target(*|myhand) reject!$ targetedplayer
@@ -31432,6 +31435,7 @@ type=Enchantment
[/card]
[card]
name=Dralnu's Pet
abilities=hasotherkicker
other={3}{B}{U}{U}{D(other creature|myhand)} name(Kicker)
auto=if paid(alternative) then counter(1/1,storedmanacost) && transforms((,flying)) forever
text=Kicker - {2}{B}, Discard a creature card. (You may pay {2}{B} and discard a creature card in addition to any other costs as you cast this spell.) -- If Dralnu's Pet was kicked, it enters the battlefield with flying and with X +1/+1 counters on it, where X is the discarded card's converted mana cost.
@@ -33188,6 +33192,7 @@ type=Land
[/card]
[card]
name=Dwarven Landslide
abilities=hasotherkicker
target=land
auto=destroy
other={4}{R}{R}{S(land|myBattlefield)} name(Pay Kicker)
@@ -34385,8 +34390,8 @@ toughness=4
[/card]
[card]
name=Elemental Appeal
other={5}{R}{R}{R}{R} name(Pay Kicker)
auto=token(Elemental,Creature Elemental,7/1,red,trample,haste,unearth) and!( if paid(alternative) then 7/0 ueot )!
kicker={5}
auto=token(Elemental,Creature Elemental,7/1,red,trample,haste,unearth) and!( if paid(kicker) then 7/0 ueot )!
text=Kicker {5} (You may pay an additional {5} as you cast this spell.) -- Put a 7/1 red Elemental creature token with trample and haste onto the battlefield. Exile it at the beginning of the next end step. If Elemental Appeal was kicked, that creature gets +7/+0 until end of turn.
mana={R}{R}{R}{R}
type=Sorcery
@@ -61396,7 +61401,7 @@ toughness=2
[/card]
[card]
name=Kangee, Aerie Keeper
abilities=flying
abilities=flying,hasotherkicker
other={X}{4}{W}{U} name(Kicker)
auto=if paid(alternative) then counter(0/0,X,Feather)
auto=thisforeach(counter{0/0.1.Feather}) lord(other creature[bird]) 1/1
@@ -69432,6 +69437,7 @@ type=Enchantment
[/card]
[card]
name=Magma Burst
abilities=hasotherkicker
target=creature,player
auto=damage:3
auto=alternative damage:3 target(other creature,player)
@@ -86179,6 +86185,7 @@ type=Enchantment
[/card]
[card]
name=Phyrexian Scuta
abilities=hasotherkicker
text=Kicker - Pay 3 life. (You may pay 3 life in addition to any other costs as you cast this spell.) -- If Phyrexian Scuta was kicked, it enters the battlefield with two +1/+1 counters on it.
auto=alternative counter(1/1,2) all(this)
other={3}{B}{L:3} name(Pay Kicker)
@@ -88280,6 +88287,7 @@ subtype=Aura
[/card]
[card]
name=Primal Growth
abilities=hasotherkicker
aicode=activate transforms((,newability[ifnot paid(alternative) then target(land[basic]|mylibrary) moveto(mybattlefield)],newability[if paid(alternative) then target(<2>land[basic]|mylibrary) moveto(mybattlefield)])) ueot
auto=ifnot paid(alternative) then name(search card) reveal:plibrarycount optionone name(choose card) target(land[basic]|reveal) moveto(ownerlibrary) and!( becomes(tobecast) ueot )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerlibrary) and!( all(*|reveal) moveto(ownerlibrary) and!(shuffle)! )! optiontwoend afterrevealed all(tobecast|mylibrary) moveto(ownerlibrary) and!(moveTo(myBattlefield) and!(tap(noevent))!)! afterrevealedend revealend
auto=if paid(alternative) then name(search card) reveal:plibrarycount optionone name(choose card) target(<upto:2>land[basic]|reveal) moveto(ownerlibrary) and!( becomes(tobecast) ueot )! optiononeend optiontwo name(put back) target(<1>*|reveal) moveto(ownerlibrary) and!( all(*|reveal) moveto(ownerlibrary) and!(shuffle)! )! optiontwoend afterrevealed all(tobecast|mylibrary) moveto(ownerlibrary) and!(moveTo(myBattlefield) and!(tap(noevent))!)! afterrevealedend revealend
@@ -97363,6 +97371,7 @@ type=Instant
[/card]
[card]
name=Rushing River
abilities=hasotherkicker
target=*[-land]|battlefield
auto=moveto(ownerhand)
auto=alternative target(*[-land]|battlefield) moveto(ownerhand)
@@ -97836,9 +97845,9 @@ toughness=2
name=Sadistic Sacrament
target=player
aicode=activate transforms((,newability[if paid(alternative) then moveto(exile) target(<upto:15>*|targetedpersonslibrary)],newability[ifnot paid(alternative) then moveto(exile) target(<upto:3>*|targetedpersonslibrary)])) ueot
auto=if paid(alternative) then name(search card) Reveal:type:*:targetedpersonslibrary revealzone(targetedpersonslibrary) optionone name(choose card) target(<upto:15>*|reveal) transforms((,newability[all(other *|reveal) moveto(ownerlibrary) and!(shuffle)!],newability[moveto(exile)])) optiononeend optiontwo name(shuffle) bottomoflibrary target(<1>*|reveal) and!( all(*|reveal) bottomoflibrary and!(shuffle)! )! optiontwoend revealend
auto=ifnot paid(alternative) then name(search card) Reveal:type:*:targetedpersonslibrary revealzone(targetedpersonslibrary) optionone name(choose card) target(<upto:3>*|reveal) transforms((,newability[all(other *|reveal) moveto(ownerlibrary) and!(shuffle)!],newability[moveto(exile)])) optiononeend optiontwo name(shuffle) bottomoflibrary target(<1>*|reveal) and!( all(*|reveal) bottomoflibrary and!(shuffle)! )! optiontwoend revealend
other={7}{B}{B}{B} name(Kicker)
auto=if paid(kicker) then name(search card) Reveal:type:*:targetedpersonslibrary revealzone(targetedpersonslibrary) optionone name(choose card) target(<upto:15>*|reveal) transforms((,newability[all(other *|reveal) moveto(ownerlibrary) and!(shuffle)!],newability[moveto(exile)])) optiononeend optiontwo name(shuffle) bottomoflibrary target(<1>*|reveal) and!( all(*|reveal) bottomoflibrary and!(shuffle)! )! optiontwoend revealend
auto=ifnot paid(kicker) then name(search card) Reveal:type:*:targetedpersonslibrary revealzone(targetedpersonslibrary) optionone name(choose card) target(<upto:3>*|reveal) transforms((,newability[all(other *|reveal) moveto(ownerlibrary) and!(shuffle)!],newability[moveto(exile)])) optiononeend optiontwo name(shuffle) bottomoflibrary target(<1>*|reveal) and!( all(*|reveal) bottomoflibrary and!(shuffle)! )! optiontwoend revealend
kicker={7}
text=Kicker {7} (You may pay an additional {7} as you cast this spell.) -- Search target player's library for up to three cards, exile them, then that player shuffles his or her library. If Sadistic Sacrament was kicked, instead search that player's library for up to fifteen cards, exile them, then that player shuffles his or her library.
mana={B}{B}{B}
type=Sorcery
@@ -110469,9 +110478,9 @@ toughness=5
[card]
name=Sphinx of Lost Truths
abilities=flying
other={4}{U}{U}{U} name(pay kicker)
kicker={1}{U}
auto=draw:3
auto=ifnot paid(alternative) then reject notatarget(<3>*|myhand)
auto=ifnot paid(kicker) then reject notatarget(<3>*|myhand)
text=Kicker {1}{U} (You may pay an additional {1}{U} as you cast this spell.) -- Flying -- When Sphinx of Lost Truths enters the battlefield, draw three cards. Then if it wasn't kicked, discard three cards.
mana={3}{U}{U}
type=Creature

View File

@@ -41,9 +41,12 @@ class CardDescriptor: public MTGCardInstance
int convertedManacost; // might fit better into MTGCardInstance?
int zposComparisonMode;
int zposition;
int hasKickerCost;
int anyCounter;
int init();
CardDescriptor();
void unsecureSetKicked(int i);
void unsecureSetHasKickerCost(int i);
void unsecureSetTapped(int i);
void unsecuresetfresh(int k);
void unsecuresetrecent(int j);

View File

@@ -286,7 +286,8 @@ class Constants
MENTOR = 160,
PROWESS = 161,
NOFIZZLEALTERNATIVE = 162,
NB_BASIC_ABILITIES = 163,
HASOTHERKICKER = 163,
NB_BASIC_ABILITIES = 164,
RARITY_S = 'S', //Special Rarity
RARITY_M = 'M', //Mythics

View File

@@ -20,6 +20,7 @@ CardDescriptor::CardDescriptor()
convertedManacost = -1;
zposComparisonMode = COMPARISON_NONE;
zposition = -1;
hasKickerCost = 0;
compareName ="";
nameComparisonMode = COMPARISON_NONE;
colorComparisonMode = COMPARISON_NONE;
@@ -50,6 +51,16 @@ int CardDescriptor::init()
return result;
}
void CardDescriptor::unsecureSetKicked(int k)
{
kicked = k;
}
void CardDescriptor::unsecureSetHasKickerCost(int k)
{
hasKickerCost = k;
}
void CardDescriptor::unsecureSetTapped(int i)
{
tapped = i;
@@ -220,6 +231,15 @@ MTGCardInstance * CardDescriptor::match(MTGCardInstance * card)
if (excludedSet.any())
return NULL;
if ((kicked == -1 && card->kicked) || (kicked == 1 && !card->kicked))
{
match = NULL;
}
if ((hasKickerCost == -1 && card->getManaCost()->getKicker()) || (hasKickerCost == 1 && !card->getManaCost()->getKicker()))
{
match = NULL;
}
if ((tapped == -1 && card->isTapped()) || (tapped == 1 && !card->isTapped()))
{

View File

@@ -1484,8 +1484,32 @@ bool CardGui::FilterCard(MTGCard * _card,string filter)
{
cd.unsecureSetTapped(1);
}
//Token
}
//Has been kicked
else if (attribute.find("kicked") != string::npos)
{
if (minus)
{
cd.unsecureSetKicked(-1);
}
else
{
cd.unsecureSetKicked(1);
}
}
//Has kicker cost
else if (attribute.find("haskicker") != string::npos)
{
if (minus)
{
cd.unsecureSetHasKickerCost(-1);
}
else
{
cd.unsecureSetHasKickerCost(1);
}
}
//Token
else if (attribute.find("token") != string::npos)
{
if (minus)
@@ -1496,8 +1520,8 @@ bool CardGui::FilterCard(MTGCard * _card,string filter)
{
cd.isToken = 1;
}
//put in its zone this turn
}
//put in its zone this turn
else if (attribute.find("fresh") != string::npos)
{
if (minus)

View File

@@ -193,7 +193,8 @@ const char* Constants::MTGBasicAbilities[] = {
"adventure", //it can be adventure
"mentor",
"prowess",
"nofizzle alternative" // No fizzle if paid with alternative cost (es. Zendikar Rising Modal Double Faced cards).
"nofizzle alternative", //No fizzle if paid with alternative cost (es. Zendikar Rising Modal Double Faced cards).
"hasotherkicker" //Kicker cost is expressed with "other" keyword (es. not mana kicker such as life and/or tap a creature)
};
map<string,int> Constants::MTGBasicAbilitiesMap;

View File

@@ -483,10 +483,11 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card)
ManaCost * previousManaPool = NEW ManaCost(player->getManaPool());
int payResult = player->getManaPool()->pay(card->getManaCost());
if (card->getManaCost()->getKicker() && (OptionKicker::KICKER_ALWAYS == options[Options::KICKERPAYMENT].number || card->controller()->isAI()))
if (card->getManaCost()->getKicker() && (card->kicked || OptionKicker::KICKER_ALWAYS == options[Options::KICKERPAYMENT].number || card->controller()->isAI()))
{
ManaCost * withKickerCost= NEW ManaCost(card->getManaCost());
withKickerCost->add(withKickerCost->getKicker());
card->kicked = 0;
if (card->getManaCost()->getKicker()->isMulti)
{
while(previousManaPool->canAfford(withKickerCost))
@@ -497,11 +498,14 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card)
for(int i = 0;i < card->kicked;i++)
player->getManaPool()->pay(card->getManaCost()->getKicker());
payResult = ManaCost::MANA_PAID_WITH_KICKER;
card->alternateCostPaid[ManaCost::MANA_PAID_WITH_KICKER] = 1;
}
else if (previousManaPool->canAfford(withKickerCost))
{
player->getManaPool()->pay(card->getManaCost()->getKicker());
payResult = ManaCost::MANA_PAID_WITH_KICKER;
card->kicked = 1;
card->alternateCostPaid[ManaCost::MANA_PAID_WITH_KICKER] = 1;
}
delete withKickerCost;
}
@@ -633,6 +637,7 @@ int MTGKickerRule::reactToClick(MTGCardInstance * card)
{
if (!game->targetListIsSet(card))
{
card->kicked = 1;
return 0;
}
}
@@ -649,6 +654,7 @@ int MTGKickerRule::reactToClick(MTGCardInstance * card)
{
ManaCost * withKickerCost= NEW ManaCost(card->getManaCost());
withKickerCost->add(withKickerCost->getKicker());
card->kicked = 0;
if (card->getManaCost()->getKicker()->isMulti)
{
while(previousManaPool->canAfford(withKickerCost))
@@ -659,11 +665,14 @@ int MTGKickerRule::reactToClick(MTGCardInstance * card)
for(int i = 0;i < card->kicked;i++)
player->getManaPool()->pay(card->getManaCost()->getKicker());
payResult = ManaCost::MANA_PAID_WITH_KICKER;
card->alternateCostPaid[ManaCost::MANA_PAID_WITH_KICKER] = 1;
}
else if (previousManaPool->canAfford(withKickerCost))
{
player->getManaPool()->pay(card->getManaCost()->getKicker());
payResult = ManaCost::MANA_PAID_WITH_KICKER;
card->kicked = 1;
card->alternateCostPaid[ManaCost::MANA_PAID_WITH_KICKER] = 1;
}
delete withKickerCost;
}
@@ -722,7 +731,6 @@ int MTGKickerRule::reactToClick(MTGCardInstance * card)
copy->castX = copy->X;
}
}
return 1;
}

View File

@@ -481,8 +481,32 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
{
cd->unsecureSetTapped(1);
}
//Token
}
//Has been kicked
else if (attribute.find("kicked") != string::npos)
{
if (minus)
{
cd->unsecureSetKicked(-1);
}
else
{
cd->unsecureSetKicked(1);
}
}
//Has kicker cost
else if (attribute.find("haskicker") != string::npos)
{
if (minus)
{
cd->unsecureSetHasKickerCost(-1);
}
else
{
cd->unsecureSetHasKickerCost(1);
}
}
//Token
else if (attribute.find("token") != string::npos)
{
if (minus)
@@ -493,8 +517,8 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
{
cd->isToken = 1;
}
//put in its zone this turn
}
//put in its zone this turn
else if (attribute.find("fresh") != string::npos)
{
if (minus)