Ability_Cost Usage
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
10 posts
• Page 1 of 1
Ability_Cost Usage
by friarsol » 16 Sep 2010, 21:31
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.
Last edited by friarsol on 17 Sep 2010, 16:31, edited 3 times in total.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Ability_Cost Usage
by Sloth » 17 Sep 2010, 05:30
Thanks a lot for this code and primer friarsol!
I guess hundrets of cards can be added, using your Ability_Cost and Target class.
Chapeau!
I guess hundrets of cards can be added, using your Ability_Cost and Target class.

Chapeau!
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Ability_Cost Usage
by DennisBergkamp » 17 Sep 2010, 06:49
Cool stuff, I'll play around with it, and see if I can add some new functionality 

-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: Ability_Cost Usage
by DennisBergkamp » 17 Sep 2010, 08:44
Alright, I've played around with this for a bit and I think I have some beginnings for Tradewind Rider (it seems to work so far, anyway - but it still doesn't work exclusively through keywords).
Maybe you could look at some of the code I've added for this, friarsol, and make sure it's all correct.
Maybe you could look at some of the code I've added for this, friarsol, and make sure it's all correct.
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: Ability_Cost Usage
by Chris H. » 17 Sep 2010, 10:21
This is interesting. It may take me awhile to absorb all of this, but I like what I see so far. I have managed to add a few of Rob's new abDestroyTgt cards.
Oh, and a question. Will this new Ability_Cost system make the old setBeforePayMana and setAfterPayMana systems obsolete?
Oh, and a question. Will this new Ability_Cost system make the old setBeforePayMana and setAfterPayMana systems obsolete?
-
Chris H. - Forge Moderator
- Posts: 6320
- Joined: 04 Nov 2008, 12:11
- Location: Mac OS X Yosemite
- Has thanked: 644 times
- Been thanked: 643 times
Re: Ability_Cost Usage
by Rob Cashwalker » 17 Sep 2010, 11:25
This is not exactly a "one class fits all" solution. But it is mutually exclusive. Using Ability_Cost will require using the Target class. Likewise, I don't think the Target class can be used without the Ability_Cost... yet. Checkout GameAction.PlaySpellAbility to see how it works.
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: Ability_Cost Usage
by friarsol » 17 Sep 2010, 16:25
Looks solid. I moved the location of the keyword before SubCounter (in a few spots) because Coral Reef has the tapping cost before a remove counter cost. And I think it'd be best if we try to keep all of the costs consistent with how the costs appear in Oracle. I think I added one or two lines as precautionary measures. I also added in a section for building the cost for the string description.DennisBergkamp wrote:Alright, I've played around with this for a bit and I think I have some beginnings for Tradewind Rider (it seems to work so far, anyway - but it still doesn't work exclusively through keywords).
Maybe you could look at some of the code I've added for this, friarsol, and make sure it's all correct.
I hadn't really mentioned those before, so overall great job!
The only thing left for this Cost would be to fill out the CancelPayment for it. It's usable now without being able to undo it, but it's always handy to have a way to backtrack if you tap the wrong card.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Ability_Cost Usage
by DennisBergkamp » 17 Sep 2010, 16:44
Thanks, I didn't forget about the cancel payment, but didn't have time... I'll add it (shouldn't be too difficult).
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: Ability_Cost Usage
by DennisBergkamp » 18 Sep 2010, 20:42
Unless there's no target, of course, just using Ability_Cost seems to work fine with Voice of the Woods.Rob Cashwalker wrote:This is not exactly a "one class fits all" solution. But it is mutually exclusive. Using Ability_Cost will require using the Target class. Likewise, I don't think the Target class can be used without the Ability_Cost... yet. Checkout GameAction.PlaySpellAbility to see how it works.
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: Ability_Cost Usage
by friarsol » 18 Sep 2010, 20:57
Yea I think Rob was more implying that if there is a target and you want to use abCost you have to use the Target class with it. With abPump creatures that Pump themselves like Atog, there isn't a need to run through the Target Selection process.DennisBergkamp wrote:Unless there's no target, of course, just using Ability_Cost seems to work fine with Voice of the Woods.Rob Cashwalker wrote:This is not exactly a "one class fits all" solution. But it is mutually exclusive. Using Ability_Cost will require using the Target class. Likewise, I don't think the Target class can be used without the Ability_Cost... yet. Checkout GameAction.PlaySpellAbility to see how it works.
You and Chris have been like workhorses putting all these cards together. That's good motivation for adding in big projects like abCost were.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
10 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 43 guests