Improved "Affinity" ability to support variables, fixed several primitives with affinity ability.

This commit is contained in:
Vittorio Alfieri
2023-05-27 21:24:25 +02:00
parent 5785e413ec
commit 066b30b1b7
3 changed files with 77 additions and 75 deletions

View File

@@ -33620,10 +33620,8 @@ type=Artifact
[card]
name=Geistlight Snare
target=*|stack
restriction=type(*[enchantment]|mybattlefield)~equalto~0
otherrestriction=type(*[enchantment]|mybattlefield)~morethan~0
anyzone=this(variable{type:spirit:mybattlefield}>0) changecost(colorless:-1) forcedalive
other={1}{U} name(Cast for 1 less
anyzone=this(variable{type:spirit:mybattlefield}>0)while changecost(colorless:-1) forcedalive
anyzone=this(variable{type:enchantment:mybattlefield}>0)while changecost(colorless:-1) forcedalive
auto=transforms((,newability[pay[[{3}]] name(pay 3 mana) donothing?fizzle])) forever
text=This spell costs {1} less to cast if you control a Spirit. It also costs {1} less to cast if you control an enchantment. -- Counter target spell unless its controller pays {3}.
mana={2}{U}
@@ -33968,7 +33966,7 @@ toughness=12
[card]
name=Ghalta, Primal Hunger
abilities=trample
anyzone=thisforeach(variable{pwrtotalinplay}>0) changecost(colorless:-1) forcedalive
anyzone=affinity(variable{pwrtotalinplay}) reduce({1})
text=This spell costs {X} less to cast, where X is the total power of creatures you control. -- Trample
mana={10}{G}{G}
type=Legendary Creature
@@ -44430,7 +44428,9 @@ type=Sorcery
[/card]
[card]
name=Into the Story
auto=aslongas(*|opponentgraveyard) altercost(colorless,-3) >6
restriction=type(*|opponentgraveyard)~lessthan~7
otherrestriction=type(*|opponentgraveyard)~morethan~6
other={2}{U}{U} name(Cast 3 less)
auto=draw:4 controller
text=This spell costs {3} less to cast if an opponent has seven or more cards in their graveyard. -- Draw four cards.
mana={5}{U}{U}
@@ -50858,15 +50858,7 @@ type=Legendary Enchantment
[card]
name=Licia, Sanguine Tribune
abilities=first strike,lifelink
anyzone=this(variable{lifegain}>0) changecost(colorless:-1)
anyzone=this(variable{lifegain}>1) changecost(colorless:-1)
anyzone=this(variable{lifegain}>2) changecost(colorless:-1)
anyzone=this(variable{lifegain}>3) changecost(colorless:-1)
anyzone=this(variable{lifegain}>4) changecost(colorless:-1)
anyzone=this(variable{lifegain}>5) changecost(colorless:-1)
anyzone=this(variable{lifegain}>6) changecost(colorless:-1)
anyzone=this(variable{lifegain}>7) changecost(colorless:-1)
anyzone=this(variable{lifegain}>8) changecost(colorless:-1)
anyzone=affinity(variable{lifegain}) reduce({1})
auto={L:5}:counter(1/1,3) myTurnOnly limit:1
text=This spell costs {1} less to cast for each 1 life you gained this turn. -- First strike, lifelink -- Pay 5 life: Put three +1/+1 counters on Licia, Sanguine Tribune. Activate this ability only during your turn and only once each turn.
mana={5}{R}{W}{B}
@@ -52921,26 +52913,26 @@ toughness=7
[card]
name=Maelstrom Muse
abilities=flying
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~1}:name(Reduce cost of 1) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-1)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~2}:name(Reduce cost of 2) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-2)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~3}:name(Reduce cost of 3) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-3)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~4}:name(Reduce cost of 4) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-4)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~5}:name(Reduce cost of 5) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-5)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~6}:name(Reduce cost of 6) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-6)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~7}:name(Reduce cost of 7) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-7)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~8}:name(Reduce cost of 8) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-8)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~9}:name(Reduce cost of 9) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-9)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~10}:name(Reduce cost of 10) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-10)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~11}:name(Reduce cost of 11) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-11)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~12}:name(Reduce cost of 12) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-12)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~13}:name(Reduce cost of 13) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-13)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~14}:name(Reduce cost of 14) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-14)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~15}:name(Reduce cost of 15) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-15)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~16}:name(Reduce cost of 16) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-16)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~17}:name(Reduce cost of 17) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-17)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~18}:name(Reduce cost of 18) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-18)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~19}:name(Reduce cost of 19) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-19)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~morethan~19}:name(Reduce cost of 20) transforms((,newability[lord(*[instant;sorcery]|mycastingzone) changecost(colorless:-20)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~1}:name(Reduce cost of 1) name(Reduce cost of 1) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-1)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~2}:name(Reduce cost of 2) name(Reduce cost of 2) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-2)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~3}:name(Reduce cost of 3) name(Reduce cost of 3) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-3)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~4}:name(Reduce cost of 4) name(Reduce cost of 4) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-4)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~5}:name(Reduce cost of 5) name(Reduce cost of 5) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-5)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~6}:name(Reduce cost of 6) name(Reduce cost of 6) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-6)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~7}:name(Reduce cost of 7) name(Reduce cost of 7) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-7)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~8}:name(Reduce cost of 8) name(Reduce cost of 8) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-8)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~9}:name(Reduce cost of 9) name(Reduce cost of 9) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-9)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~10}:name(Reduce cost of 10) name(Reduce cost of 10) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-10)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~11}:name(Reduce cost of 11) name(Reduce cost of 11) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-11)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~12}:name(Reduce cost of 12) name(Reduce cost of 12) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-12)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~13}:name(Reduce cost of 13) name(Reduce cost of 13) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-13)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~14}:name(Reduce cost of 14) name(Reduce cost of 14) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-14)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~15}:name(Reduce cost of 15) name(Reduce cost of 15) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-15)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~16}:name(Reduce cost of 16) name(Reduce cost of 16) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-16)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~17}:name(Reduce cost of 17) name(Reduce cost of 17) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-17)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~18}:name(Reduce cost of 18) name(Reduce cost of 18) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-18)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~equalto~19}:name(Reduce cost of 19) name(Reduce cost of 19) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-19)])) ueot
auto=@combat(attacking) source(this) restriction{compare(power)~morethan~19}:name(Reduce cost of 20) name(Reduce cost of 20) target(*[instant;sorcery]|mycastingzone) transforms((,newability[changecost(colorless:-20)])) ueot
text=Flying -- Whenever Maelstrom Muse attacks, the next instant or sorcery spell you cast this turn costs {X} less to cast, where X is Maelstrom Muse's power as this ability resolves.
mana={1}{U}{UR}{R}
type=Creature
@@ -56500,9 +56492,7 @@ type=Instant
[card]
name=Molten Monstrosity
abilities=trample
autoexile=thisforeach(variable{pwr:highest:creature:mybattlefield}>0) changecost(colorless:-1) forcedalive
autograveyard=thisforeach(variable{pwr:highest:creature:mybattlefield}>0) changecost(colorless:-1) forcedalive
autohand=thisforeach(variable{pwr:highest:creature:mybattlefield}>0) changecost(colorless:-1) forcedalive
anyzone=affinity(variable{pwr:highest:creature:mybattlefield}) reduce({1})
text=This spell costs {X} less to cast, where X is the greatest power among creatures you control. -- Trample
mana={7}{R}
type=Creature
@@ -59006,7 +58996,7 @@ subtype=Aura
[card]
name=New Perspectives
auto=draw:3 controller
auto=aslongas(*|myHand) all(*[cycling]|mycastingzone) altercost(colorless,-99) >6
auto=this(variable{type:*:myhand}>6) lord(*[cycling]|myhand) transforms((,newability[{0}{cycle}:name(Cycling for 0) draw:1 controller]))
text=When New Perspectives enters the battlefield, draw three cards. -- As long as you have seven or more cards in hand, you may pay {0} rather than pay cycling costs.
mana={5}{U}
type=Enchantment
@@ -60202,8 +60192,10 @@ toughness=6
[card]
name=Oakhame Adversary
abilities=deathtouch
auto=aslongas(*[green]|opponentbattlefield) altercost(colorless,-2) >0
auto=@combatdamaged(player) from(this):draw:1
restriction=type(*[green]|opponentbattlefield)~equalto~0
otherrestriction=type(*[green]|opponentbattlefield)~morethan~0
other={1}{G} name(Cast 2 less)
auto=@combatdamaged(player) from(this):name(Draw a card) draw:1 controller
text=This spell costs {2} less to cast if an opponent controls a green permanent. -- Deathtouch -- Whenever Oakhame Adversary deals combat damage to a player, draw a card.
mana={3}{G}
type=Creature
@@ -60471,9 +60463,7 @@ toughness=3
[card]
name=Obsidian Charmaw
abilities=flying
autoexile=thisforeach(variable{olandc}>0) changecost(colorless:-1) forcedalive
autograveyard=thisforeach(variable{olandc}>0) changecost(colorless:-1) forcedalive
autohand=thisforeach(variable{olandc}>0) changecost(colorless:-1) forcedalive
anyzone=affinity(variable{olandc}) reduce({1})
auto=name(Destroy land) target(land[-basic]|opponentBattlefield) destroy
text=This spell costs {1} less to cast for each land your opponents control that could produce {C}. -- Flying -- When Obsidian Charmaw enters the battlefield, destroy target nonbasic land an opponent controls.
mana={3}{R}{R}
@@ -68244,7 +68234,7 @@ toughness=3
name=Rakdos, Lord of Riots
abilities=flying,trample
restriction=_SPECTACLE_
auto=lord(creature|myhand,myCommandzone,mygraveyard,myexile) transforms((,newability[thisforeach(variable{oplifelost}>0) changecost(colorless:-1)]))
auto=lord(creature|mycastingzone) transforms((,newability[affinity(variable{oplifelost}) reduce({1})]))
text=You can't cast Rakdos, Lord of Riots unless an opponent lost life this turn. -- Flying, trample -- Creature spells you cast cost {1} less to cast for each 1 life your opponents have lost this turn.
mana={B}{B}{R}{R}
type=Legendary Creature
@@ -73837,7 +73827,7 @@ toughness=4
[/card]
[card]
name=Sailors' Bane
anyzone=affinity(*[instant;sorcery;adventure]|mygraveyard) reduce({1})
anyzone=affinity(instant,sorcery,adventure|mygraveexile) reduce({1})
auto=_WARD_(4)
text=This spell costs {1} less to cast for each card you own in exile and in your graveyard that's an instant card, a sorcery card, or a card that has an Adventure. -- Ward {4} (Whenever this creature becomes the target of a spell or ability an opponent controls, counter it unless that player pays {4}.)
mana={7}{U}{U}
@@ -83367,9 +83357,7 @@ type=Instant
[card]
name=Sproutback Trudge
abilities=trample
autoexile=thisforeach(variable{lifegain}>0) changecost(colorless:-1) forcedalive
autograveyard=thisforeach(variable{lifegain}>0) changecost(colorless:-1) forcedalive
autohand=thisforeach(variable{lifegain}>0) changecost(colorless:-1) forcedalive
anyzone=affinity(variable{lifegain}) reduce({1})
autograveyard=@each my secondmain restriction{compare(lifegain)~morethan~0}:name(Can play from graveyard) transforms((,newability[canplayfromgraveyard])) ueot
text=This spell costs {X} less to cast, where X is the amount of life you gained this turn. -- Trample -- At the beginning of your end step, if you gained life this turn, you may cast Sproutback Trudge from your graveyard.
mana={7}{G}{G}
@@ -89047,9 +89035,7 @@ subtype=Saga
[/card]
[card]
name=The Great Henge
autoexile=thisforeach(variable{pwr:highest:creature:mybattlefield}>0) changecost(colorless:-1) forcedalive
autograveyard=thisforeach(variable{pwr:highest:creature:mybattlefield}>0) changecost(colorless:-1) forcedalive
autohand=thisforeach(variable{pwr:highest:creature:mybattlefield}>0) changecost(colorless:-1) forcedalive
anyzone=affinity(variable{pwr:highest:creature:mybattlefield}) reduce({1})
auto={T}:add{G}{G} && life:2 controller
auto=@movedto(creature[-token]|mybattlefield):all(trigger[to]) counter(1/1) && draw:1 controller
text=This spell costs {X} less to cast, where X is the greatest power among creatures you control. -- {T}: Add {G}{G}. You gain 2 life. -- Whenever a nontoken creature enters the battlefield under your control, put a +1/+1 counter on it and draw a card.
@@ -89904,9 +89890,7 @@ toughness=3
[card]
name=Thrasta, Tempest's Roar
abilities=trample,haste
autoexile=thisforeach(variable{pstormcount}>0) changecost(colorless:-3) forcedalive
autograveyard=thisforeach(variable{pstormcount}>0) changecost(colorless:-3) forcedalive
autohand=thisforeach(variable{pstormcount}>0) changecost(colorless:-3) forcedalive
anyzone=affinity(variable{pstormcount}) reduce({3})
auto=this(cantargetcard(*[fresh])) opponentshroud
text=This spell costs {3} less to cast for each other spell cast this turn. -- Trample, haste -- Trample over planeswalkers (This creature can deal excess combat damage to the controller of the planeswalker it's attacking.) -- Thrasta, Tempest's Roar has hexproof as long as it entered the battlefield this turn.
mana={10}{G}{G}
@@ -99303,8 +99287,10 @@ type=Legendary Land
[/card]
[card]
name=Winged Words
auto=draw:2
autohand=aslongas(creature[flying]|mybattlefield) altercost(colorless,-1)
restriction=type(creature[flying]|mybattlefield)~equalto~0
otherrestriction=type(creature[flying]|mybattlefield)~morethan~0
other={1}{U} name(Cast 1 less)
auto=draw:2 controller
text=This spell costs {1} less to cast if you control a creature with flying. -- Draw two cards.
mana={2}{U}
type=Sorcery

View File

@@ -113638,7 +113638,7 @@ toughness=5
name=Stoic Rebuttal
target=*|stack
auto=fizzle
auto=aslongas(artifact|mybattlefield) changecost(colorless:-1) >2
anyzone=this(variable{type:artifact:mybattlefield}>2)while changecost(colorless:-1) forcedalive
text=Metalcraft -- This spell cost {1} less to cast if you control three or more artifacts. -- Counter target spell.
mana={1}{U}{U}
type=Instant

View File

@@ -1252,23 +1252,39 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * Cos
}
}
}
TargetChooserFactory tf(getObserver());
TargetChooser * tcn = tf.createTargetChooser(newAff->tcString, card, NULL);
for (int w = 0; w < 2; ++w)
if(newAff->tcString.find("variable{") != string::npos)
{
Player *p = getObserver()->players[w];
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++)
vector<string> eval = parseBetween(newAff->tcString, "variable{", "}");
if(eval.size())
{
MTGGameZone * z = zones[k];
if (tcn->targetsZone(z))
WParsedInt* value = NEW WParsedInt(eval[1], NULL, card);
if(value)
{
reducem += z->countByCanTarget(tcn);
reducem += value->getValue();
SAFE_DELETE(value);
}
}
}
SAFE_DELETE(tcn);
else
{
TargetChooserFactory tf(getObserver());
TargetChooser * tcn = tf.createTargetChooser(newAff->tcString, card, NULL);
for (int w = 0; w < 2; ++w)
{
Player *p = getObserver()->players[w];
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 * z = zones[k];
if (tcn->targetsZone(z))
{
reducem += z->countByCanTarget(tcn);
}
}
}
SAFE_DELETE(tcn);
}
ManaCost * removingCost = ManaCost::parseManaCost(newAff->manaString);
for (int j = 0; j < reducem; j++)
Cost->remove(removingCost);
@@ -1391,42 +1407,42 @@ ManaCost * MTGCardInstance::computeNewCost(MTGCardInstance * card,ManaCost * Cos
}
else if (card->has(Constants::AFFINITYGRAVECREATURES))
{
WParsedInt* value = NEW WParsedInt("type:creature:mygraveyard",NULL, card);
WParsedInt* value = NEW WParsedInt("type:creature:mygraveyard", NULL, card);
if(value)
reduce = value->getValue();
SAFE_DELETE(value);
}
else if (card->has(Constants::AFFINITYALLDEADCREATURES))
{
WParsedInt* value = NEW WParsedInt("bothalldeadcreature",NULL, card);
WParsedInt* value = NEW WParsedInt("bothalldeadcreature", NULL, card);
if(value)
reduce = value->getValue();
SAFE_DELETE(value);
}
else if (card->has(Constants::AFFINITYPARTY))
{
WParsedInt* value = NEW WParsedInt("calculateparty",NULL, card);
WParsedInt* value = NEW WParsedInt("calculateparty", NULL, card);
if(value)
reduce = value->getValue();
SAFE_DELETE(value);
}
else if (card->has(Constants::AFFINITYBASICLANDTYPES))
{
WParsedInt* value = NEW WParsedInt("pbasiclandtypes",NULL, card);
WParsedInt* value = NEW WParsedInt("pbasiclandtypes", NULL, card);
if(value)
reduce = value->getValue();
SAFE_DELETE(value);
}
else if (card->has(Constants::AFFINITYTWOBASICLANDTYPES))
{
WParsedInt* value = NEW WParsedInt("pbasiclandtypes",NULL, card);
WParsedInt* value = NEW WParsedInt("pbasiclandtypes", NULL, card);
if(value)
reduce = value->getValue() * 2;
SAFE_DELETE(value);
}
else if (card->has(Constants::AFFINITYGRAVEINSTSORC))
{
WParsedInt* value = NEW WParsedInt("pginstantsorcery",NULL, card);
WParsedInt* value = NEW WParsedInt("pginstantsorcery", NULL, card);
if(value)
reduce = value->getValue();
SAFE_DELETE(value);