Ability_Cost Usage
So I've done a bunch of work on Ability_Cost in the last two weeks, so I figure I should post about it so people can start adding it in cards, and use it with new keywords.
Ability_Cost has some sweeping changes that override the old setBeforePayMana and setAfterPayMana system. The old system limited how much we could do before an ability was put onto the stack. This limitation led to a lot of cards having costs get paid during resolution and some of them would peak at the stack to prevent you from using an ability if you had already used it.
One of the first cards that irritated me about this was Tradewind Rider. The Rider would tap and go on the stack. But you'd have to wait to resolution to tap your other two creatures. If you didn't have two creatures available to tap on resolution, well your game would be in a dead state that you'd have to concede to get out of. Rider has recently been moved to the abCost system yet. And he's a big reason why it exists right now.
This system is centralized so hopefully we can get a ton of our abilities to run through the same gateway. Not only will it make finding bugs easier, it should make how the player pays for things more consistent.
To my knowledge the following keywords support using abCost instead of just ManaCost:
No Parameters:
T
Untap
Mana
Parameters:
tapXType<NumTap/ValidCard>
SubCounter<NumCounters/CounterType>
Sac<NumSacrifices/ValidCard>
PayLife<NumLife>
Discard<NumDiscards/{Hand,Random,Any,ValidCard}
I'll give a sample of just the keyword line for each cost:
For those who want to try to make some of the other costs here's a few things to keep in mind. Actions that are easily undoable (tapping cards, paying mana) should happen before things that aren't really undoable (sacrificing lands, discarding cards). Also, we should try to keep payments in the same order as they appear on actual cards. Sometimes it's tough to hunt down what goes where. Paying Mana comes first. Sacrifice always seems to come last, which makes whatever cost you are doing somewhere in the middle.
The cost is also built by the class, so don't forgot about adding some code into the toString() section to display the cost to the player.
/EndEdit
Now if you plan on making a new keyword, or updating an old one with abCost just make sure you also use the new Target class if the ability is targeted. Since setBeforePayMana isn't used anymore, we need to make sure Targeting is taken care of. Otherwise, your abilities probably won't do anything at all.
Your best bet is to check out how it works in abDamageTgt or abDestroyTgt. It's actually not that hard, and a large portion of Targets from here on out should be using the Valid Target portion of the class.
Quick brief on using the Target class.
Either use the set Tgt Paramters {C}{P} like abDamage does. These you don't need to set any extra parameters. The code will handle asking for the target at the appropriate time.
In abDestroy, that looks like this:
I'm going to take a break from doing any major abCost updates to work on some other things on the project. So lemme know if you have any questions when trying the new Classes out.
Ability_Cost has some sweeping changes that override the old setBeforePayMana and setAfterPayMana system. The old system limited how much we could do before an ability was put onto the stack. This limitation led to a lot of cards having costs get paid during resolution and some of them would peak at the stack to prevent you from using an ability if you had already used it.
One of the first cards that irritated me about this was Tradewind Rider. The Rider would tap and go on the stack. But you'd have to wait to resolution to tap your other two creatures. If you didn't have two creatures available to tap on resolution, well your game would be in a dead state that you'd have to concede to get out of. Rider has recently been moved to the abCost system yet. And he's a big reason why it exists right now.
This system is centralized so hopefully we can get a ton of our abilities to run through the same gateway. Not only will it make finding bugs easier, it should make how the player pays for things more consistent.
To my knowledge the following keywords support using abCost instead of just ManaCost:
- Code: Select all
abAllPump
abDamageTgt
abDestroyTgt
abPump[Tgt]
No Parameters:
T
Untap
Mana
Parameters:
tapXType<NumTap/ValidCard>
SubCounter<NumCounters/CounterType>
Sac<NumSacrifices/ValidCard>
PayLife<NumLife>
Discard<NumDiscards/{Hand,Random,Any,ValidCard}
I'll give a sample of just the keyword line for each cost:
- Code: Select all
Tap (Prodigal Sorcerer)
K:abDamageTgtCP T:1
Mana + Untap (Merrow Grimeblotter)
K:abPumpTgtC 1 UB Untap:-2/-0
SubtractCounter (Triskelion)
K:abDamageTgtCP SubCounter<1/P1P1>:1
SacrificeType (Atog)
K:abPump Sac<1/Artifact>:+2/+2
SacrificeThis (Fires of Yavimaya)
K:abPumpTgtC Sac<1/CARDNAME>:+2/+2
PayLife (Reckless Assault)
K:abDamageTgtCP 1 PayLife<2>:1
Discard Any (Kris Mage)
K:abDamageTgtCP R T Discard<1/Any>:1
Discard Random (Stormbind)
K:abDamageTgtCP 2 Discard<1/Random>:2
Discard Type (Seismic Assault)
K:abDamageTgtCP 2 Discard<1/Land>:2
Discard Hand (Null Brooch)
K:abCounterTgt 2 Discard<0/Hand>:nonCreature
(Note: abCounterTgt is not a keyword. The number given with Hand is ignored.)
Tap X Untapped (Hand of Justice)
K:abDestroyTgtV T tapXType<3/Creature.White>:Creature:Destroy target creature.
- Code: Select all
Exile Self/<Type>
AddCounter
Mill X
Exile from grave/library
For those who want to try to make some of the other costs here's a few things to keep in mind. Actions that are easily undoable (tapping cards, paying mana) should happen before things that aren't really undoable (sacrificing lands, discarding cards). Also, we should try to keep payments in the same order as they appear on actual cards. Sometimes it's tough to hunt down what goes where. Paying Mana comes first. Sacrifice always seems to come last, which makes whatever cost you are doing somewhere in the middle.
The cost is also built by the class, so don't forgot about adding some code into the toString() section to display the cost to the player.
/EndEdit
Now if you plan on making a new keyword, or updating an old one with abCost just make sure you also use the new Target class if the ability is targeted. Since setBeforePayMana isn't used anymore, we need to make sure Targeting is taken care of. Otherwise, your abilities probably won't do anything at all.
Your best bet is to check out how it works in abDamageTgt or abDestroyTgt. It's actually not that hard, and a large portion of Targets from here on out should be using the Valid Target portion of the class.
Quick brief on using the Target class.
Either use the set Tgt Paramters {C}{P} like abDamage does. These you don't need to set any extra parameters. The code will handle asking for the target at the appropriate time.
- Code: Select all
final Target tgt = new Target("TgtCP");
final Target tgt = new Target("TgtC");
final Target tgt = new Target("TgtP");
- Code: Select all
K:abDestroyTgtV Sac<1/CARDNAME>:Artifact,Enchantment
- Code: Select all
final String Tgts[] = k[1].split(",");
final Target tgtDstryTgt = new Target("TgtV");
tgtDstryTgt.setValidTgts(Tgts);
In abDestroy, that looks like this:
- Code: Select all
AbDstryTgt.setPayCosts(abCost);
AbDstryTgt.setTarget(tgtDstryTgt);
I'm going to take a break from doing any major abCost updates to work on some other things on the project. So lemme know if you have any questions when trying the new Classes out.