Card Development Questions
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
Re: Card Development Questions
by jeffwadsworth » 29 Oct 2011, 23:11
Looking at Power Conduit in light of Sol's Wandering Mage. Would something like SubCounter<1/Any/Permanent.YouCtrl/a permanent you control> be doable?
Also testing Ghave, Guru of Spores. Its SubCounter<1/P1P1/Creature.YouCtrl/a creature you control> does not let you choose a creature. I take it that AddCounter was the only cost type coded for this?
Also testing Ghave, Guru of Spores. Its SubCounter<1/P1P1/Creature.YouCtrl/a creature you control> does not let you choose a creature. I take it that AddCounter was the only cost type coded for this?
- 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
by slowe » 29 Oct 2011, 23:56
I just worked through all of these Tezzeret scripting issues myself ... wish I'd checked here in the middle. Anyway, I used Hellfish's ValidCard-counters solution to fix the cmc/p/t comparison:friarsol wrote:Ah. Well ChosenX is right for the Variable. CMC (as well as power and toughness) just don't use variables in the right manner.
- Code: Select all
if (property.substring(z).equals("X")) {
x = CardFactoryUtil.xCount(source, source.getSVar("X"));
} else if (property.substring(z).equals("Y")) {
x = CardFactoryUtil.xCount(source, source.getSVar("Y"));
} else {
x = Integer.parseInt(property.substring(z));
}
- Code: Select all
else if (property.startsWith("power") ||
property.startsWith("toughness") || property.startsWith("cmc")) {
int x = 0;
int y = 0;
String rhs = "";
if (property.startsWith("power")) {
rhs = property.substring(7);
y = getNetAttack();
} else if (property.startsWith("toughness")) {
rhs = property.substring(11);
y = getNetDefense();
} else if (property.startsWith("cmc")) {
rhs = property.substring(5);
y = getCMC();
}
try {
x = Integer.parseInt(rhs);
} catch (NumberFormatException e) {
x = CardFactoryUtil.xCount(source, source.getSVar(rhs));
}
if (!AllZoneUtil.compare(y, property, x)) {
return false;
}
- script | Open
- Name:Tezzeret the Seeker
ManaCost:3 U U
Types:Planeswalker Tezzeret
Text:no text
Loyalty:4
A:AB$ Untap | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | TargetMin$ 0 | TargetMax$ 2 | SpellDescription$ Untap up to two target artifacts.
A:AB$ ChangeZone | Cost$ SubCounter<X/LOYALTY> | Origin$ Library | Destination$ Battlefield | ChangeType$ Artifact.cmcLEChosenX | ChangeNum$ 1 | Shuffle$ True | Planeswalker$ True | SpellDescription$ Search your library for an artifact with converted mana cost X or less and put it onto the battlefield.
A:AB$ AnimateAll | Cost$ SubCounter<5/LOYALTY> | ValidCards$ Artifact.YouCtrl | Types$ Artifact,Creature | Power$ 5 | Toughness$ 5 | Planeswalker$ True | Ultimate$ True | SpellDescription$ Artifacts you control become 5/5 artifact creatures until end of turn.
#ChosenX SVar created by Cost payment
SVar:X:XChoice
SVar:Rarity:Mythic
SVar:Picture:http://www.wizards.com/global/images/magic/general/tezzeret_the_seeker.jpg
SetInfo:ALA|Mythic|http://magiccards.info/scans/en/ala/60.jpg
Oracle:[+1] Untap up to two target artifacts.\n-X: Search your library for an artifact card with converted mana cost X or less and put it onto the battlefield. Then shuffle your library.\n[-5] Artifacts you control become 5/5 artifact creatures until end of turn.
End
- 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
by friarsol » 30 Oct 2011, 03:24
Jeff,friarsol wrote:I see what the problem is. The same "CheckSVar" parameter is listed in both Conditionals and Restrictions. We'll need to rename the Conditional one to ConditionCheckSVar so it's only checked on resolution, and not checked in both slots. I wonder if there's a bug with cards that use this that you can Activate them when the CheckSVar passes, but don't resolve if the CheckSVar fails during Resolution.jeffwadsworth wrote:I do not believe that is the correct conditional.
Thus, I think we need your Condition script code here...otherwise the spell does not fire.
Try out ConditionCheckSVar and ConditionSVarCompare now.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Card Development Questions
by friarsol » 30 Oct 2011, 03:26
Yea SubCounter doesn't quite have that capability yet. I even noted which cards would benefit from adding it:jeffwadsworth wrote:Looking at Power Conduit in light of Sol's Wandering Mage. Would something like SubCounter<1/Any/Permanent.YouCtrl/a permanent you control> be doable?
Also testing Ghave, Guru of Spores. Its SubCounter<1/P1P1/Creature.YouCtrl/a creature you control> does not let you choose a creature. I take it that AddCounter was the only cost type coded for this?
// Here are the cards that have RemoveCounter<Type>
// Ion Storm, Noviken Sages, Ghave, Guru of Spores, Power Conduit (any
// Counter is tough),
// Quillspike, Rift Elemental, Sage of Fables, Spike Rogue
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Card Development Questions
by Iran » 30 Oct 2011, 05:49
Others cards that I remember are Fate Transfer, Clockspinning, Jhoira's TimeBug, Dust of Momentsfriarsol wrote:Yea SubCounter doesn't quite have that capability yet. I even noted which cards would benefit from adding it:jeffwadsworth wrote:Looking at Power Conduit in light of Sol's Wandering Mage. Would something like SubCounter<1/Any/Permanent.YouCtrl/a permanent you control> be doable?
Also testing Ghave, Guru of Spores. Its SubCounter<1/P1P1/Creature.YouCtrl/a creature you control> does not let you choose a creature. I take it that AddCounter was the only cost type coded for this?
// Here are the cards that have RemoveCounter<Type>
// Ion Storm, Noviken Sages, Ghave, Guru of Spores, Power Conduit (any
// Counter is tough),
// Quillspike, Rift Elemental, Sage of Fables, Spike Rogue
Are the cards Curse of the Cabal, Martyr's Bond and Charmed Pendant scriptable?
thanks
Re: Card Development Questions
by friarsol » 30 Oct 2011, 14:06
These aren't the same as they don't remove counters as a cost.Iran wrote:Others cards that I remember are Fate Transfer, Clockspinning, Jhoira's TimeBug, Dust of Moments
Are the cards Curse of the Cabal, Martyr's Bond and Charmed Pendant scriptable?
thanks
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Card Development Questions
by jeffwadsworth » 30 Oct 2011, 23:49
Testing Essence Leak. First the script:
I get this error during the upkeep of the enchanted permanent's controller...in this case it is a Deep-Slumber Titan, but it happens on any permanent.
- | Open
- Name:Essence Leak
ManaCost:U
Types:Enchantment Aura
Text:no text
K:Enchant permanent
A:SP$ Attach | Cost$ U | ValidTgts$ Permanent | AILogic$ Curse
S:Mode$ Continuous | Affected$ Permanent.EnchantedBy+Red,Permanent.EnchantedBy+Green | AddTrigger$ TrigPhase | AddSVar$ TrigSac,X | Description$ As long as enchanted permanent is red or green, it has "At the beginning of your upkeep, sacrifice this permanent unless you pay its mana cost."
SVar:TrigPhase:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigSac | TriggerDescription$ At the beginning of your upkeep, sacrifice this permanent unless you pay its mana cost.
SVar:TrigSac:AB$ Sacrifice | Cost$ 0 | Defined$ Self | UnlessCost$ X | UnlessPayer$ You
SVar:X:Count$CardManaCost
SVar:Picture:http://www.wizards.com/global/images/magic/general/essence_leak.jpg
End
I get this error during the upkeep of the enchanted permanent's controller...in this case it is a Deep-Slumber Titan, but it happens on any permanent.
- | Open
- java.lang.RuntimeException: AbilityFactory : getAbility -- abString too short in Deep-Slumber Titan: []
at forge.card.abilityFactory.AbilityFactory.getMapParams(AbilityFactory.java:217)
at forge.card.abilityFactory.AbilityFactory.getAbility(AbilityFactory.java:268)
at forge.card.trigger.TriggerHandler.runSingleTrigger(TriggerHandler.java:430)
at forge.card.trigger.TriggerHandler.runTrigger(TriggerHandler.java:292)
at forge.Phase.handleBeginPhase(Phase.java:405)
at forge.gui.input.InputControl.updateInput(InputControl.java:184)
at forge.GuiInput.update(GuiInput.java:34)
at java.util.Observable.notifyObservers(Unknown Source)
at java.util.Observable.notifyObservers(Unknown Source)
at forge.MyObservable.updateObservers(MyObservable.java:21)
at forge.Phase.nextPhase(Phase.java:508)
at forge.Phase.nextPhase(Phase.java:511)
at forge.Phase.nextPhase(Phase.java:511)
at forge.GuiDisplay4$33.actionPerformed(GuiDisplay4.java:1141)
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.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(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
by slapshot5 » 31 Oct 2011, 00:12
I don't think Essence Leak can be done right now unless you've got some special code coming with it. You need to pay its mana cost (3 G G for example), not its converted mana cost (5).jeffwadsworth wrote:Testing Essence Leak. First the script:
-slapshot5
- slapshot5
- Programmer
- Posts: 1391
- Joined: 03 Jan 2010, 17:47
- Location: Mac OS X
- Has thanked: 25 times
- Been thanked: 68 times
- 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
by moomarc » 31 Oct 2011, 12:05
I'm trying to code Varchild's War-Riders in my quest to include all types of tokens in Forge. So far I have the following:
If I get that working, is there any rules issues that anyone can see? If not there are quite a few cards that could use this template.
- Code: Select all
Name:Varchild's War-Riders
ManaCost:1 R
Types:Creature Human Warrior
Text:no text
PT:3/4
K:Trample
K:Rampage 1
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Put an age counter on CARDNAME.
SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ AGE | CounterNum$ 1
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigCharm | TriggerDescription$ Cumulative upkeep - Put a 1/1 red Survivor creature token onto the battlefield under an opponent's control; or sacrifice CARDNAME unless you pay its upkeep cost for each age counter on it.
SVar:TrigCharm:AB$ Charm | Cost$ 0 | Choices$ TrigToken,DBSacrifice | SpellDescription$ Cumulative upkeep-Pay upkeep cost for each age counter on CARDNAME or sacrifice it.
SVar:TrigToken:DB$Token | Cost$ 0 | TokenAmount$ X | TokenName$ Survivor | TokenTypes$ Creature,Survivor | TokenOwner$ Opponent | TokenColors$ Red | TokenPower$ 1 | TokenToughness$ 1 | SpellDescription$ Put a 1/1 red Survivor creature token onto the battlefield under an opponent's control.
SVar:X:Count$CardCounters.AGE
SVar:DBSacrifice:DB$ Sacrifice | Cost$ 0 | Defined$ Self | SpellDescription$ Sacrifice CARDNAME.
SVar:RemAIDeck:True
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/varchilds_war_riders.jpg
SetInfo:ALL|Rare|http://magiccards.info/scans/en/ai/122.jpg
End
If I get that working, is there any rules issues that anyone can see? If not there are quite a few cards that could use this template.
Last edited by moomarc on 31 Oct 2011, 12:18, edited 1 time in total.
-Marc
-
moomarc - Pixel Commander
- Posts: 2091
- Joined: 04 Jun 2010, 15:22
- Location: Johannesburg, South Africa
- Has thanked: 371 times
- Been thanked: 372 times
Re: Card Development Questions
by slapshot5 » 31 Oct 2011, 12:18
Cumulative upkeep only supports mana costs because it's hard to multiply generic Costs. (At least that's the roadblock I hit when I looked at converting this ages ago). With the new CostParts and all, it may work to just string costs together.
Is something like "2 R Sac<1/Goblin> 2 R Sac<1/Goblin>" prompted and paid for correctly? If so, it should be pretty easy to convert cumulative upkeep to a Cost object. That would be a huge step towards getting Varchild's War-Riders scriptable.
Edit: And maybe it's even simpler than that. Just loop over adding CostParts to a new Cost? Maybe possible? Maybe Sol can chime in on the feasibility. If it's currently feasible, converting cumulative upkeep to Cost object would be a project I'd look into.
-slapshot5
Is something like "2 R Sac<1/Goblin> 2 R Sac<1/Goblin>" prompted and paid for correctly? If so, it should be pretty easy to convert cumulative upkeep to a Cost object. That would be a huge step towards getting Varchild's War-Riders scriptable.
Edit: And maybe it's even simpler than that. Just loop over adding CostParts to a new Cost? Maybe possible? Maybe Sol can chime in on the feasibility. If it's currently feasible, converting cumulative upkeep to Cost object would be a project I'd look into.
-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
by friarsol » 31 Oct 2011, 12:31
You could put the Charm first and just repeat the PutCounter each with a different SubAbility. I'm sure this feels clunky, I don't know what support Charm has for being a SubAbility itself.
- Code: Select all
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigCumUpkeep | TriggerDescription$ Cumulative Upkeep - Put a 1/1 red Survivor creature token onto the battlefield under an opponent's control.
SVar:TrigCumUpkeep:AB$ Charm | Cost$ 0 | Choices$ TrigAgeSurvivor,TrigAgeSacrifice | CharmNum$ 1
SVar:TrigAgeSurvivor:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ AGE | CounterNum$ 1 | SubAbility$ Survivor
SVar:Survivor:DB$Token | Cost$ 0 | TokenAmount$ X | TokenName$ Survivor | TokenTypes$ Creature,Survivor | TokenOwner$ Opponent | TokenColors$ Red | TokenPower$ 1 | TokenToughness$ 1 | SpellDescription$ Put a 1/1 red Survivor creature token onto the battlefield under an opponent's control.
SVar:X:Count$CardCounters.AGE
SVar:TrigAgeSacrifice:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ AGE | CounterNum$ 1 | SubAbility$ Sacrifice
SVar:Sacrifice:DB$ Sacrifice | Cost$ 0 | Defined$ Self | SpellDescription$ Sacrifice CARDNAME.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Card Development Questions
by friarsol » 31 Oct 2011, 12:45
The new cost part would handle that, but it might feel weird to pay a Cost separately for each Age Counter. Especially for your example with a mana payment and a Sacrifice, which would then require you to make 2X payments and could easily lead to sacrificing a Llanowar Elf instead of tapping for Green mana.slapshot5 wrote:Cumulative upkeep only supports mana costs because it's hard to multiply generic Costs. (At least that's the roadblock I hit when I looked at converting this ages ago). With the new CostParts and all, it may work to just string costs together.
Is something like "2 R Sac<1/Goblin> 2 R Sac<1/Goblin>" prompted and paid for correctly? If so, it should be pretty easy to convert cumulative upkeep to a Cost object. That would be a huge step towards getting Varchild's War-Riders scriptable.
Edit: And maybe it's even simpler than that. Just loop over adding CostParts to a new Cost? Maybe possible? Maybe Sol can chime in on the feasibility. If it's currently feasible, converting cumulative upkeep to Cost object would be a project I'd look into.
-slapshot5
Probably the best way to handle it would be to add a multiply function that takes a Cost and an integer.
However, this might not really be feasible until a Cost Object can be used in similar places (such as Unless). The Resolution of the Ability basically needs to stop while this payment is going on, but the structure for that isn't really in place yet.
http://cardforge.org/bugz/view.php?id=167
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Card Development Questions
by moomarc » 31 Oct 2011, 13:31
- Code: Select all
java.lang.ClassCastException: forge.card.abilityFactory.AbilityFactory_Counters$1 cannot be cast to forge.card.spellability.Ability_Sub
at forge.card.abilityFactory.AbilityFactory_Charm.setupCharmSAs(AbilityFactory_Charm.java:154)
at forge.card.trigger.TriggerHandler.runSingleTrigger(TriggerHandler.java:444)
at forge.card.trigger.TriggerHandler.runTrigger(TriggerHandler.java:292)
at forge.Phase.handleBeginPhase(Phase.java:405)

In the meanwhile I was working on Jotun Owl Keeper. The script should be
- Code: Select all
Name:Jotun Owl Keeper
ManaCost:2 W
Types:Creature Giant
Text:no text
PT:3/3
K:Cumulative upkeep:WU
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME dies, put a 1/1 white Bird creature token with flying onto the battlefield for each age counter on it.
SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ X | TokenName$ W 1 1 Bird Flying | TokenTypes$ Creature,Bird | TokenOwner$ You | TokenColors$ White | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying
SVar:X:Count$CardCounters.AGE
SVar:Rarity:Uncommon
SVar:Picture:http://www.wizards.com/global/images/magic/general/jotun_owl_keeper.jpg
SetInfo:CSP|Uncommon|http://magiccards.info/scans/en/cs/9.jpg
End
-Marc
-
moomarc - Pixel Commander
- Posts: 2091
- Joined: 04 Jun 2010, 15:22
- Location: Johannesburg, South Africa
- Has thanked: 371 times
- Been thanked: 372 times
Who is online
Users browsing this forum: No registered users and 26 guests