It is currently 30 Oct 2025, 16:40
   
Text Size

Converting cards from Keyword to AbilityFactory

Post MTG Forge Related Programming Questions Here

Moderators: timmermac, Agetian, friarsol, Blacksmith, KrazyTheFox, CCGHQ Admins

Re: Converting cards from Keyword to AbilityFactory

Postby Chris H. » 21 Nov 2010, 11:05

friarsol wrote:The right info wasn't being sent in to the old drawback code. I just submitted a fix that will send in the Targeted player to Drawback and tested with Sign in Blood. I'm guessing that'd do the trick for the rest.

My long term solution is converting Drawback to new SubAbility stuff (once they are ready)

Hooray! Doesn't everyone love converting things?
`
Thank you for finding and fixing the problem. Yeah, the card conversions are coming along. There are still hundreds of cards that need to be changed over and tested. We have to expect a few bugs in the process. :wink:

It looks like the AF_Draw code still needs some additions to be able to handle X costs. That and the fix for the targeting issue will allow most if not all of the old draw cards to be converted.
User avatar
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: Converting cards from Keyword to AbilityFactory

Postby RedSypher » 21 Nov 2010, 15:38

I'm having an issue with enlightened tutor. when i tutor for something, it doesn't go to the top of my deck, it just vanishes entirely. It never gets to any zone.
RedSypher
 
Posts: 25
Joined: 31 Oct 2010, 06:48
Has thanked: 0 time
Been thanked: 0 time

Re: Converting cards from Keyword to AbilityFactory

Postby Sloth » 21 Nov 2010, 16:13

RedSypher wrote:I'm having an issue with enlightened tutor. when i tutor for something, it doesn't go to the top of my deck, it just vanishes entirely. It never gets to any zone.
Please post which version you are using. The newest SVN version doesn't have this problem.
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: Converting cards from Keyword to AbilityFactory

Postby Chris H. » 23 Nov 2010, 00:02

I spent some time today looking at the code while Rob was updating the SVN. I think that I figured out how to add X costs to the AF_Draw. It looks like the biggest challenge will be in getting the AI to use X casts properly and in an intelligent fashion.

It looks like Sol beat me to it with rev3776. :D
User avatar
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: Converting cards from Keyword to AbilityFactory

Postby friarsol » 23 Nov 2010, 00:31

Hehe. Sorry, I had it done the other day and forgot to submit it. AI choosing what X should be is definitely a challenge for all of the AbilityFactories.

We should probably brainstorm what needs to be considered/decided and how to use the decided information in ComputerUtil.payCosts()
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Converting cards from Keyword to AbilityFactory

Postby Chris H. » 23 Nov 2010, 17:33

I converted Minions' Murmurs to AF_Draw. The resolve is drawing the correct number of cards per the X value. The SubAbility$ (Drawback) is not causing the caster to lose any life.

Code: Select all
Name:Minions' Murmurs
ManaCost:2 B B
Types:Sorcery
Text:no text
A:SP$Draw | Cost$ 2 B B | NumCards$ X | SpellDescription$ You draw X cards and you lose X life, where X is the number of creatures you control. | SubAbility$ YouLoseLife/X
SVar:X:Count$TypeYouCtrl.Creature
SVar:RemAIDeck:True
SVar:Rarity:Uncommon
SVar:Picture:http://resources.wizards.com/magic/cards/fut/en-us/card130316.jpg
SetInfo:FUT|Uncommon|http://magiccards.info/scans/en/fut/71.jpg
End
User avatar
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: Converting cards from Keyword to AbilityFactory

Postby friarsol » 23 Nov 2010, 18:47

Hmmm.. not sure why old Drawback isn't working.

I got the new Drawback to work. Try this:
Code: Select all
Name:Minions' Murmurs
ManaCost:2 B B
Types:Sorcery
Text:no text
A:SP$Draw | Cost$ 2 B B | NumCards$ X | SpellDescription$ You draw X cards and you lose X life, where X is the number of creatures you control. | SubAbility$ SVar=DB1
SVar:DB1:DB$LoseLife | LifeAmount$ X
SVar:X:Count$TypeYouCtrl.Creature
SVar:RemAIDeck:True
SVar:Rarity:Uncommon
SVar:Picture:http://resources.wizards.com/magic/cards/fut/en-us/card130316.jpg
SetInfo:FUT|Uncommon|http://magiccards.info/scans/en/fut/71.jpg
End
The StackDescription of LoseLife is slightly wrong, could you change the Player player = line to:
Code: Select all
   static String loseLifeStackDescription(AbilityFactory af, SpellAbility sa){
       StringBuilder sb = new StringBuilder();
       int amount = AbilityFactory.calculateAmount(af.getHostCard(), af.getMapParams().get("LifeAmount"), sa);
   
       Player player = sa.getActivatingPlayer();
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Converting cards from Keyword to AbilityFactory

Postby Chris H. » 23 Nov 2010, 19:05

I converted Ancestral Vision to AF_Draw and this is one buggy card.


Code: Select all
Name:Ancestral Vision
ManaCost:no cost
Types:Sorcery
Text:no text
K:CARDNAME is blue.
K:Suspend:4:U
A:SP$Draw | Cost$ no cost | NumCards$ 3 | ValidTgts$ Player | TgtPrompt$ Choose a player to draw three cards | SpellDescription$ Target player draws three cards.
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/ancestral_vision.jpg
SetInfo:TSP|Rare|http://magiccards.info/scans/en/ts/48.jpg
End
`

The first error exception appears when the computer attempts to cast the spell.


Code: Select all
An error has occured. You can copy/paste this message or save it to a file.
Please report this, plus what you tried to do, to:
   http://www.slightlymagic.net/forum/viewforum.php?f=26
If you don't want to register an account, you can mail it directly to
   mtgerror@yahoo.com


There is an error in the card code for Ancestral Vision:



Version:
Forge -- official beta: $Date: 2010-09-14 08:34:27 -0400 (Tue, 14 Sep 2010) $, SVN revision: $Revision: 2039 $

OS: Mac OS X Version: 10.6.4 Architecture: x86_64

Java Version: 1.6.0_22 Vendor: Apple Inc.

Detailed error trace:
java.lang.RuntimeException: Mana_Part : checkMana() error, argument mana is invalid mana, mana - n
   at forge.Mana_Part.checkSingleMana(Mana_Part.java:32)
   at forge.Mana_PartColor.<init>(Mana_PartColor.java:15)
   at forge.ManaCost.getManaPart(ManaCost.java:198)
   at forge.ManaCost.split(ManaCost.java:168)
   at forge.ManaCost.<init>(ManaCost.java:27)
   at forge.ComputerUtil.canPayCost(ComputerUtil.java:198)
   at forge.ComputerAI_General.getPlayable(ComputerAI_General.java:151)
   at forge.ComputerAI_General.getMain2(ComputerAI_General.java:138)
   at forge.ComputerAI_General.playCards(ComputerAI_General.java:28)
   at forge.ComputerAI_General.main2(ComputerAI_General.java:24)
   at forge.ComputerAI_Input.think(ComputerAI_Input.java:65)
   at forge.ComputerAI_Input.showMessage(ComputerAI_Input.java:31)
   at forge.GuiInput.setInput(GuiInput.java:27)
   at forge.GuiInput.update(GuiInput.java:21)
   at java.util.Observable.notifyObservers(Observable.java:142)
   at java.util.Observable.notifyObservers(Observable.java:98)
   at forge.MyObservable.updateObservers(MyObservable.java:9)
   at forge.Phase.nextPhase(Phase.java:436)
   at forge.Phase.nextPhase(Phase.java:439)
   at forge.Phase.nextPhase(Phase.java:439)
   at forge.Phase.nextPhase(Phase.java:439)
   at forge.Phase.nextPhase(Phase.java:439)
   at forge.Phase.nextPhase(Phase.java:439)
   at forge.Phase.nextPhase(Phase.java:439)
   at forge.Phase.nextPhase(Phase.java:439)
   at forge.Phase.nextPhase(Phase.java:439)
   at forge.MyObservable.updateObservers(MyObservable.java:15)
   at forge.GuiDisplayUtil.updateGUI(GuiDisplayUtil.java:892)
   at forge.Input_PassPriority.selectButtonOK(Input_PassPriority.java:36)
   at forge.GuiInput.selectButtonOK(GuiInput.java:35)
   at forge.GuiDisplay3.okButtonActionPerformed(GuiDisplay3.java:1001)
   at forge.GuiDisplay3.access$3(GuiDisplay3.java:1000)
   at forge.GuiDisplay3$26.actionPerformed(GuiDisplay3.java:795)
   at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
   at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
   at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
   at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
   at javax.swing.plaf.basic.BasicButtonListener$Actions.actionPerformed(BasicButtonListener.java:287)
   at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1639)
   at javax.swing.JComponent.processKeyBinding(JComponent.java:2851)
   at javax.swing.JComponent.processKeyBindings(JComponent.java:2886)
   at javax.swing.JComponent.processKeyEvent(JComponent.java:2814)
   at java.awt.Component.processEvent(Component.java:6129)
   at java.awt.Container.processEvent(Container.java:2085)
   at java.awt.Component.dispatchEventImpl(Component.java:4714)
   at java.awt.Container.dispatchEventImpl(Container.java:2143)
   at java.awt.Component.dispatchEvent(Component.java:4544)
   at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1850)
   at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:712)
   at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:990)
   at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:855)
   at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:676)
   at java.awt.Component.dispatchEventImpl(Component.java:4586)
   at java.awt.Container.dispatchEventImpl(Container.java:2143)
   at java.awt.Window.dispatchEventImpl(Window.java:2478)
   at java.awt.Component.dispatchEvent(Component.java:4544)
   at java.awt.EventQueue.dispatchEvent(EventQueue.java:635)
   at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
   at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
   at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
   at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
   at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
   at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
`

The second error exception appears as the spell is resolving when cast by the human. The human player is not asked to select a target player:


Code: Select all
An error has occured. You can copy/paste this message or save it to a file.
Please report this, plus what you tried to do, to:
   http://www.slightlymagic.net/forum/viewforum.php?f=26
If you don't want to register an account, you can mail it directly to
   mtgerror@yahoo.com


null


Version:
Forge -- official beta: $Date: 2010-09-14 08:34:27 -0400 (Tue, 14 Sep 2010) $, SVN revision: $Revision: 2039 $

OS: Mac OS X Version: 10.6.4 Architecture: x86_64

Java Version: 1.6.0_22 Vendor: Apple Inc.

Detailed error trace:
java.lang.NullPointerException
   at forge.Card.subtractCounter(Card.java:388)
   at forge.GameActionUtil.upkeep_Suspend(GameActionUtil.java:8684)
   at forge.GameActionUtil.executeUpkeepEffects(GameActionUtil.java:148)
   at forge.PhaseUtil.handleUpkeep(PhaseUtil.java:272)
   at forge.Phase.handleBeginPhase(Phase.java:162)
   at forge.InputControl.updateInput(InputControl.java:60)
   at forge.GuiInput.update(GuiInput.java:19)
   at java.util.Observable.notifyObservers(Observable.java:142)
   at java.util.Observable.notifyObservers(Observable.java:98)
   at forge.MyObservable.updateObservers(MyObservable.java:9)
   at forge.Phase.nextPhase(Phase.java:436)
   at forge.Phase.nextPhase(Phase.java:439)
   at forge.Phase.nextPhase(Phase.java:439)
   at forge.GuiDisplay3$26.actionPerformed(GuiDisplay3.java:800)
   at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
   at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
   at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
   at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
   at javax.swing.plaf.basic.BasicButtonListener$Actions.actionPerformed(BasicButtonListener.java:287)
   at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1639)
   at javax.swing.JComponent.processKeyBinding(JComponent.java:2851)
   at javax.swing.JComponent.processKeyBindings(JComponent.java:2886)
   at javax.swing.JComponent.processKeyEvent(JComponent.java:2814)
   at java.awt.Component.processEvent(Component.java:6129)
   at java.awt.Container.processEvent(Container.java:2085)
   at java.awt.Component.dispatchEventImpl(Component.java:4714)
   at java.awt.Container.dispatchEventImpl(Container.java:2143)
   at java.awt.Component.dispatchEvent(Component.java:4544)
   at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1850)
   at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:712)
   at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:990)
   at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:855)
   at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:676)
   at java.awt.Component.dispatchEventImpl(Component.java:4586)
   at java.awt.Container.dispatchEventImpl(Container.java:2143)
   at java.awt.Window.dispatchEventImpl(Window.java:2478)
   at java.awt.Component.dispatchEvent(Component.java:4544)
   at java.awt.EventQueue.dispatchEvent(EventQueue.java:635)
   at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
   at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
   at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
   at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
   at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
   at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
User avatar
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: Converting cards from Keyword to AbilityFactory

Postby Chris H. » 23 Nov 2010, 19:08

friarsol wrote:Hmmm.. not sure why old Drawback isn't working.

I got the new Drawback to work. Try this:
`
Thank you Sol, I will give your suggestions a try. :)
User avatar
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: Converting cards from Keyword to AbilityFactory

Postby friarsol » 23 Nov 2010, 19:45

I'll take care of Ancestral Vision. That card has been a pain in my ass ever since I wrote Suspend.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Converting cards from Keyword to AbilityFactory

Postby Chris H. » 23 Nov 2010, 19:52

Chris H. wrote:
friarsol wrote:Hmmm.. not sure why old Drawback isn't working.

I got the new Drawback to work. Try this:
`
Thank you Sol, I will give your suggestions a try. :)
`
OK, Minions' Murmurs is now working correctly. I think we have just that one last card to fix and convert. Afterwards, I will comment-out the ab&sp DrawCards keywords.
User avatar
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: Converting cards from Keyword to AbilityFactory

Postby friarsol » 23 Nov 2010, 20:27

If we ever do any of the other 5 spells that have no cost, Ability_Cost doesn't know what "no cost" means, so I set the abCost to 0 and included an ActivationLimit of 0. This ActivationLimit prevents it from being "activated" but doesn't prevent it from being cast by other means (like suspend or cascade)

Code: Select all
Name:Ancestral Vision
ManaCost:no cost
Types:Sorcery
A:SP$Draw | Cost$ 0 | NumCards$ 3 | ValidTgts$ Player | TgtPrompt$ Choose a player to draw three cards | SpellDescription$ Target player draws three cards. | ActivationLimit$ 0
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Converting cards from Keyword to AbilityFactory

Postby Chris H. » 24 Nov 2010, 02:04

friarsol wrote:If we ever do any of the other 5 spells that have no cost, Ability_Cost doesn't know what "no cost" means, so I set the abCost to 0 and included an ActivationLimit of 0. This ActivationLimit prevents it from being "activated" but doesn't prevent it from being cast by other means (like suspend or cascade)

Code: Select all
Name:Ancestral Vision
ManaCost:no cost
Types:Sorcery
A:SP$Draw | Cost$ 0 | NumCards$ 3 | ValidTgts$ Player | TgtPrompt$ Choose a player to draw three cards | SpellDescription$ Target player draws three cards. | ActivationLimit$ 0
`
I suspected that the

java.lang.RuntimeException: Mana_Part : checkMana() error, argument mana is invalid mana, mana - n
`
in the error exception was because of the no cost. But this was only half of the answer. So that Cost$ 0 combined with the ActivationLimit$ 0 fixes the card. Interesting.
User avatar
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: Converting cards from Keyword to AbilityFactory

Postby Chris H. » 02 Dec 2010, 16:56

We only have 1 card left out of the approximately 450+ ab/spPump cards to convert over to AbilityFactory. This last one is tricky and I am currently stuck.

I just merged this version of Umezawa's Jitte into the SVN. Is there a way to signify that the pump goes to the card equipped by the Umezawa's Jitte? Looking at the code it appears that some initial work was done but that it was commented out.

Code: Select all
Name:Umezawa's Jitte
ManaCost:2
Types:Legendary Artifact Equipment
Text:Whenever equipped creature deals combat damage, put two charge counters on Umezawa's Jitte.
K:abPumpEquipped SubCounter<1/CHARGE>:+2/+2
#A:AB$Pump | Cost$ SubCounter<1/CHARGE> | NumAtt$ +2 | NumDef$ +2 | SpellDescription$ Equipped creature gets +2/+2 until end of turn.
A:AB$Pump | Cost$ SubCounter<1/CHARGE> | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ -1 | NumDef$ -1 | IsCurse$ True | SpellDescription$ Target creature gets -1/-1 until end of turn.
A:AB$GainLife | Cost$ SubCounter<1/CHARGE> | LifeAmount$ 2 | SpellDescription$ You gain 2 life.
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/umezawas_jitte.jpg
SetInfo:BOK|Rare|http://magiccards.info/scans/en/bok/163.jpg
End
User avatar
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: Converting cards from Keyword to AbilityFactory

Postby friarsol » 02 Dec 2010, 17:29

This is the type of non-targeted effects I was referring to as "Defined" or "Affected" in some thread a week or so ago. Two cards use "Affected" currently, Orcish Cannonade and Psionic Entity, but when we agree on a terminology these should be updated accordingly.

I'll start a thread to determine what it should be called, in the meantime lets assume we choose "Defined" for the following examples

Jitte would like this:

Code: Select all
A:AB$Pump | Cost$ SubCounter<1/CHARGE> | Defined$ Equipped | NumAtt$ +2 | NumDef$ +2 | SpellDescription$ Equipped creature gets +2/+2 until end of turn.
Firebreathing would look like:
Code: Select all
A:AB$Pump | Cost$ R | Defined$ Enchanted | NumAtt$ +1 | SpellDescription$ Enchanted creature gets +1/+0 until end of turn.
Veteran's Reflexes would look like:
Code: Select all
A:SP$Pump | Cost$ W | Target$ C | NumAtt$ +1 | NumDef$ +1 | SpellDescription$ Target creature gets +1/+1 until end of turn. Untap that creature. | SubAbility$ SVar=DB
SVar:DB:DB$Untap | Defined$ Targeted
Targeted is an interesting definition, since it cares about the same target the Parent Ability is using. This will come up only in SubAbilities, and is not valid to use in the Base Ability.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

PreviousNext

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 24 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 24 users online :: 0 registered, 0 hidden and 24 guests (based on users active over the past 10 minutes)
Most users ever online was 9298 on 10 Oct 2025, 12:54

Users browsing this forum: No registered users and 24 guests

Login Form