It is currently 08 Jun 2025, 21:59
   
Text Size

Card Development Questions

Post MTG Forge Related Programming Questions Here

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

Re: Card Development Questions

Postby friarsol » 11 Jun 2011, 02:58

jeffwadsworth wrote:Now this works fine, but to be 100%, the chosen dragon permanent must be exiled from anywhere, not just the battlefield. If Any is used, it just fizzles. Perhaps there is another way that doesn't require silly hacky SubAbilities that check every zone?
Are you sure about that? It doesn't have the same wording as Unearth does.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Card Development Questions

Postby jeffwadsworth » 11 Jun 2011, 04:00

friarsol wrote:
jeffwadsworth wrote:Now this works fine, but to be 100%, the chosen dragon permanent must be exiled from anywhere, not just the battlefield. If Any is used, it just fizzles. Perhaps there is another way that doesn't require silly hacky SubAbilities that check every zone?
Are you sure about that? It doesn't have the same wording as Unearth does.
well, i will add and see what happens.
jeffwadsworth
Super Tester Elite
 
Posts: 1172
Joined: 20 Oct 2010, 04:47
Location: USA
Has thanked: 287 times
Been thanked: 70 times

Re: Card Development Questions

Postby Sloth » 11 Jun 2011, 07:58

jeffwadsworth wrote:
friarsol wrote:
jeffwadsworth wrote:Now this works fine, but to be 100%, the chosen dragon permanent must be exiled from anywhere, not just the battlefield. If Any is used, it just fizzles. Perhaps there is another way that doesn't require silly hacky SubAbilities that check every zone?
Are you sure about that? It doesn't have the same wording as Unearth does.
well, i will add and see what happens.
I think what sol meant is that it is correct ruleswise that the dragon permanent doesn't get exiled from anywhere but the battlefield. And I agree.
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: Card Development Questions

Postby friarsol » 11 Jun 2011, 13:03

Sloth wrote:I think what sol meant is that it is correct ruleswise that the dragon permanent doesn't get exiled from anywhere but the battlefield. And I agree.
Good thing Sloth is here to translate for me :wink:
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Card Development Questions

Postby Starcrash » 15 Jun 2011, 03:00

I'm having a hard time getting Forge to recognize the various "pulse" conditions for the various pulse spells from Darksteel. For instance, I tried this with Pulse of the Fields (the white life-gaining spell)

A:SP$ GainLife | Cost$ 1 W W | Defined$ You | LifeAmount$ 4 | SubAbility$ SVar=TrigReturn | SpellDescription$ You gain 4 life. Then if an opponent has more life than you, return CARDNAME to its owner's hand.
SVar:TrigReturn:DB$ ChangeZone | ConditionPresent$ X | ConditionCompare$ LTY | Defined$ Self | Origin$ Stack | Destination$ Hand | ConditionDescription$ If an opponent has more life than you,
SVar:X:Count$YourLifeTotal
SVar:Y:Count$OppLifeTotal

The program completely ignores the condition and instead gives back Pulse of the Fields every time. I tried IsPresent$ instead (and even LifeAmount$, though I'm pretty certain that's trigger-only), and got the same outcome - no matter what I set as the conditions, they just get ignored. Is this why Pulse of the Tangle doesn't have code in the card itself? Are these cards - seemingly easy to code - still uncodeable?
Starcrash
 
Posts: 96
Joined: 30 May 2011, 18:39
Has thanked: 2 times
Been thanked: 1 time

Re: Card Development Questions

Postby jeffwadsworth » 15 Jun 2011, 03:49

Catacomb Dragon script:

| Open
Name:Catacomb Dragon
ManaCost:4 B B
Types:Creature Dragon
Text:no text
PT:4/4
K:Flying
T:Mode$ AttackerBlocked | ValidCard$ Card.Self | ValidBlocker$ Creature.nonArtifact+nonDragon | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever CARDNAME becomes blocked by a nonartifact, non-Dragon creature, that creature gets -X/-0 until end of turn, where X is half the creature's power, rounded down.
SVar:TrigPump:AB$Pump | Cost$ 0 | Defined$ TriggeredBlocker | NumAtt$ -X
SVar:X:TriggeredBlocker$CardPower/HalfDown
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/catacomb_dragon.jpg
End


During the declare blockers step it produces a NPE.

| Open
An error has occurred. You can copy/paste this message or save it to a file.
Please report this, plus what you tried to do, to:
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: 2011-01-06 10:34:48 -0600 (Thu, 06 Jan 2011) $, SVN revision: $Revision: 4891 $

OS: Windows 7 Version: 6.1 Architecture: amd64

Java Version: 1.6.0_22 Vendor: Sun Microsystems Inc.

Detailed error trace:
java.lang.NullPointerException
at forge.card.abilityFactory.AbilityFactory.getDefinedCards(AbilityFactory.java:1043)
at forge.CombatUtil.predictPowerBonusOfBlocker(CombatUtil.java:921)
at forge.CombatUtil.canDestroyBlocker(CombatUtil.java:1177)
at forge.ComputerUtil_Block2.getSafeBlockers(ComputerUtil_Block2.java:35)
at forge.ComputerUtil_Block2.makeGoodBlocks(ComputerUtil_Block2.java:106)
at forge.ComputerUtil_Block2.getBlockers(ComputerUtil_Block2.java:402)
at forge.ComputerAI_General.declare_blockers(ComputerAI_General.java:284)
at forge.gui.input.InputControl.updateInput(InputControl.java:116)
at forge.gui.input.InputControl.updateInput(InputControl.java:98)
at forge.GuiInput.update(GuiInput.java:21)
at java.util.Observable.notifyObservers(Unknown Source)
at java.util.Observable.notifyObservers(Unknown Source)
at forge.MyObservable.updateObservers(MyObservable.java:9)
at forge.Phase.nextPhase(Phase.java:374)
at forge.GuiDisplay3$27.actionPerformed(GuiDisplay3.java:781)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
jeffwadsworth
Super Tester Elite
 
Posts: 1172
Joined: 20 Oct 2010, 04:47
Location: USA
Has thanked: 287 times
Been thanked: 70 times

Re: Card Development Questions

Postby friarsol » 15 Jun 2011, 04:11

Ugh. Looks like getDefined is sending in null in CombatUtil.predictPowerBonusOfBlocker for the SpellAbility which is needed to get the Triggered card.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Card Development Questions

Postby slapshot5 » 15 Jun 2011, 05:07

jeffwadsworth wrote:Catacomb Dragon script:

| Open
Name:Catacomb Dragon
ManaCost:4 B B
Types:Creature Dragon
Text:no text
PT:4/4
K:Flying
T:Mode$ AttackerBlocked | ValidCard$ Card.Self | ValidBlocker$ Creature.nonArtifact+nonDragon | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever CARDNAME becomes blocked by a nonartifact, non-Dragon creature, that creature gets -X/-0 until end of turn, where X is half the creature's power, rounded down.
SVar:TrigPump:AB$Pump | Cost$ 0 | Defined$ TriggeredBlocker | NumAtt$ -X
SVar:X:TriggeredBlocker$CardPower/HalfDown
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/catacomb_dragon.jpg
End


During the declare blockers step it produces a NPE.

| Open
An error has occurred. You can copy/paste this message or save it to a file.
Please report this, plus what you tried to do, to:
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: 2011-01-06 10:34:48 -0600 (Thu, 06 Jan 2011) $, SVN revision: $Revision: 4891 $

OS: Windows 7 Version: 6.1 Architecture: amd64

Java Version: 1.6.0_22 Vendor: Sun Microsystems Inc.

Detailed error trace:
java.lang.NullPointerException
at forge.card.abilityFactory.AbilityFactory.getDefinedCards(AbilityFactory.java:1043)
at forge.CombatUtil.predictPowerBonusOfBlocker(CombatUtil.java:921)
at forge.CombatUtil.canDestroyBlocker(CombatUtil.java:1177)
at forge.ComputerUtil_Block2.getSafeBlockers(ComputerUtil_Block2.java:35)
at forge.ComputerUtil_Block2.makeGoodBlocks(ComputerUtil_Block2.java:106)
at forge.ComputerUtil_Block2.getBlockers(ComputerUtil_Block2.java:402)
at forge.ComputerAI_General.declare_blockers(ComputerAI_General.java:284)
at forge.gui.input.InputControl.updateInput(InputControl.java:116)
at forge.gui.input.InputControl.updateInput(InputControl.java:98)
at forge.GuiInput.update(GuiInput.java:21)
at java.util.Observable.notifyObservers(Unknown Source)
at java.util.Observable.notifyObservers(Unknown Source)
at forge.MyObservable.updateObservers(MyObservable.java:9)
at forge.Phase.nextPhase(Phase.java:374)
at forge.GuiDisplay3$27.actionPerformed(GuiDisplay3.java:781)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Investigation notes: predictPowerBonusOfBlocker passes in null for the sa. When getting Defined, it sees "Triggered" which calls sa.getTriggeringObject() and Bam! NPE.

-slapshot5
slapshot5
Programmer
 
Posts: 1391
Joined: 03 Jan 2010, 17:47
Location: Mac OS X
Has thanked: 25 times
Been thanked: 68 times

Re: Card Development Questions

Postby Sloth » 15 Jun 2011, 08:03

Starcrash wrote:I'm having a hard time getting Forge to recognize the various "pulse" conditions for the various pulse spells from Darksteel. For instance, I tried this with Pulse of the Fields (the white life-gaining spell)

A:SP$ GainLife | Cost$ 1 W W | Defined$ You | LifeAmount$ 4 | SubAbility$ SVar=TrigReturn | SpellDescription$ You gain 4 life. Then if an opponent has more life than you, return CARDNAME to its owner's hand.
SVar:TrigReturn:DB$ ChangeZone | ConditionPresent$ X | ConditionCompare$ LTY | Defined$ Self | Origin$ Stack | Destination$ Hand | ConditionDescription$ If an opponent has more life than you,
SVar:X:Count$YourLifeTotal
SVar:Y:Count$OppLifeTotal

The program completely ignores the condition and instead gives back Pulse of the Fields every time. I tried IsPresent$ instead (and even LifeAmount$, though I'm pretty certain that's trigger-only), and got the same outcome - no matter what I set as the conditions, they just get ignored. Is this why Pulse of the Tangle doesn't have code in the card itself? Are these cards - seemingly easy to code - still uncodeable?
ConditionPresent counts the number of cards on the battlefield that match the given restrictions, nothing more. It would need some extra coding.
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: Card Development Questions

Postby slapshot5 » 15 Jun 2011, 13:15

Sloth wrote:
Starcrash wrote:I'm having a hard time getting Forge to recognize the various "pulse" conditions for the various pulse spells from Darksteel. For instance, I tried this with Pulse of the Fields (the white life-gaining spell)

A:SP$ GainLife | Cost$ 1 W W | Defined$ You | LifeAmount$ 4 | SubAbility$ SVar=TrigReturn | SpellDescription$ You gain 4 life. Then if an opponent has more life than you, return CARDNAME to its owner's hand.
SVar:TrigReturn:DB$ ChangeZone | ConditionPresent$ X | ConditionCompare$ LTY | Defined$ Self | Origin$ Stack | Destination$ Hand | ConditionDescription$ If an opponent has more life than you,
SVar:X:Count$YourLifeTotal
SVar:Y:Count$OppLifeTotal

The program completely ignores the condition and instead gives back Pulse of the Fields every time. I tried IsPresent$ instead (and even LifeAmount$, though I'm pretty certain that's trigger-only), and got the same outcome - no matter what I set as the conditions, they just get ignored. Is this why Pulse of the Tangle doesn't have code in the card itself? Are these cards - seemingly easy to code - still uncodeable?
ConditionPresent counts the number of cards on the battlefield that match the given restrictions, nothing more. It would need some extra coding.
Ok, I was just thinking about this very thing, then I read this post. I guess that means I should just get to it, huh? I'll take a look at making this doable.

-slapshot5
slapshot5
Programmer
 
Posts: 1391
Joined: 03 Jan 2010, 17:47
Location: Mac OS X
Has thanked: 25 times
Been thanked: 68 times

Re: Card Development Questions

Postby slapshot5 » 15 Jun 2011, 18:53

slapshot5 wrote:
Sloth wrote:
Starcrash wrote:I'm having a hard time getting Forge to recognize the various "pulse" conditions for the various pulse spells from Darksteel. For instance, I tried this with Pulse of the Fields (the white life-gaining spell)

A:SP$ GainLife | Cost$ 1 W W | Defined$ You | LifeAmount$ 4 | SubAbility$ SVar=TrigReturn | SpellDescription$ You gain 4 life. Then if an opponent has more life than you, return CARDNAME to its owner's hand.
SVar:TrigReturn:DB$ ChangeZone | ConditionPresent$ X | ConditionCompare$ LTY | Defined$ Self | Origin$ Stack | Destination$ Hand | ConditionDescription$ If an opponent has more life than you,
SVar:X:Count$YourLifeTotal
SVar:Y:Count$OppLifeTotal

The program completely ignores the condition and instead gives back Pulse of the Fields every time. I tried IsPresent$ instead (and even LifeAmount$, though I'm pretty certain that's trigger-only), and got the same outcome - no matter what I set as the conditions, they just get ignored. Is this why Pulse of the Tangle doesn't have code in the card itself? Are these cards - seemingly easy to code - still uncodeable?
ConditionPresent counts the number of cards on the battlefield that match the given restrictions, nothing more. It would need some extra coding.
Ok, I was just thinking about this very thing, then I read this post. I guess that means I should just get to it, huh? I'll take a look at making this doable.

-slapshot5
Ok, after I check in my rework of the conditions stuff, you'll do it like this:

Code: Select all
A:SP$ GainLife | Cost$ 1 W W | Defined$ You | LifeAmount$ 4 | SubAbility$ SVar=TrigReturn | SpellDescription$ You gain 4 life. Then if an opponent has more life than you, return CARDNAME to its owner's hand.
SVar:TrigReturn:DB$ ChangeZone | ConditionLifeTotal$ You | ConditionLifeAmount$ LTX | Defined$ Self | Origin$ Stack | Destination$ Hand | ConditionDescription$ If an opponent has more life than you,
SVar:X:Count$OppLifeTotal
-slapshot5
slapshot5
Programmer
 
Posts: 1391
Joined: 03 Jan 2010, 17:47
Location: Mac OS X
Has thanked: 25 times
Been thanked: 68 times

Re: Card Development Questions

Postby slapshot5 » 16 Jun 2011, 14:08

jeffwadsworth wrote:CopyPermanent. Any plans to include an option to make multiple copies like tokenamount$?
Just saw this. Yes, this is now implemented.
slapshot5
Programmer
 
Posts: 1391
Joined: 03 Jan 2010, 17:47
Location: Mac OS X
Has thanked: 25 times
Been thanked: 68 times

Re: Card Development Questions

Postby jeffwadsworth » 16 Jun 2011, 16:53

slapshot5 wrote:
jeffwadsworth wrote:CopyPermanent. Any plans to include an option to make multiple copies like tokenamount$?
Just saw this. Yes, this is now implemented.
Fantastic...now if I could just remember what card required it. #-o
jeffwadsworth
Super Tester Elite
 
Posts: 1172
Joined: 20 Oct 2010, 04:47
Location: USA
Has thanked: 287 times
Been thanked: 70 times

Re: Card Development Questions

Postby friarsol » 16 Jun 2011, 17:15

jeffwadsworth wrote:
slapshot5 wrote:
jeffwadsworth wrote:CopyPermanent. Any plans to include an option to make multiple copies like tokenamount$?
Just saw this. Yes, this is now implemented.
Fantastic...now if I could just remember what card required it. #-o
Rite of Replication? Which was already converted.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Card Development Questions

Postby jeffwadsworth » 16 Jun 2011, 21:23

Clockwork Hydra script:

| Open
Name:Clockwork Hydra
ManaCost:5
Types:Artifact Creature Hydra
Text:no text
K:etbCounter:P1P1:4
A:AB$ PutCounter | Cost$ T | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on CARDNAME.
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigRemoveCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks or blocks, remove a +1/+1 counter from it. If you do, CARDNAME deals 1 damage to target creature or player.
T:Mode$ Blocks | ValidCard$ Card.Self | Execute$ TrigRemoveCounter | TriggerZones$ Battlefield | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks or blocks, remove a +1/+1 counter from it. If you do, CARDNAME deals 1 damage to target creature or player.
SVar:TrigRemoveCounter:AB$RemoveCounter | Cost$ 0 | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBDamage
SVar:DBDamage:DB$DealDamage | Tgt$ TgtCP | NumDmg$ 1
SVar:Rarity:Uncommon
SVar:Picture:http://www.wizards.com/global/images/magic/general/clockwork_hydra.jpg
End


The counter is not being removed even though the trigger fires.
jeffwadsworth
Super Tester Elite
 
Posts: 1172
Joined: 20 Oct 2010, 04:47
Location: USA
Has thanked: 287 times
Been thanked: 70 times

PreviousNext

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 36 guests

cron

Who is online

In total there are 36 users online :: 0 registered, 0 hidden and 36 guests (based on users active over the past 10 minutes)
Most users ever online was 4143 on 23 Jan 2024, 08:21

Users browsing this forum: No registered users and 36 guests

Login Form