Return to Ravnica Spoiler Season
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Agetian, friarsol, Blacksmith, KrazyTheFox, CCGHQ Admins
Re: Return to Ravnica Spoiler Season
by Sloth » 30 Sep 2012, 20:43
I think i can come up with a version that is more user (and AI) friendly.ArsenalNut wrote:Here's the script I came up with for Jarad's Orders
- Jarad's Orders | Open
- Name:Jarad's Orders
ManaCost:2 B G
Types:Sorcery
Text:no text
A:SP$ ChangeZone | Cost$ 2 B G | Origin$ Library | Destination$ Library | ChangeType$ Creature | ChangeNum$ 2 | RememberChanged$ True | SubAbility$ DBChoice | SpellDescription$ Search your library for up to two creature cards and reveal them. Put one into your hand and the other into your graveyard. Then shuffle your library.
SVar:DBChoice:DB$ TwoPiles | Defined$ You | DefinedCards$ Remembered | Separator$ You | ChosenPile$ DBHand | UnchosenPile$ DBGrave
SVar:DBHand:DB$ ChangeZone | Defined$ Remembered | Origin$ Library | Destination$ Hand
SVar:DBGrave:DB$ ChangeZone | Defined$ Remembered | Origin$ Library | Destination$ Graveyard
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/jarads_orders.jpg
End
The script works but I want to see if there so unintended consequence I am missing. Also the actual play of the card is very menu intensive.
EDIT: Here is my version:
- Jarad's Orders | Open
- Code: Select all
Name:Jarad's Orders
ManaCost:2 B G
Types:Sorcery
Text:no text
A:SP$ ChangeZone | Cost$ 2 B G | Origin$ Library | Destination$ Library | ChangeType$ Creature | ChangeNum$ 2 | RememberChanged$ True | Reveal$ True | Shuffle$ False | StackDescription$ SpellDescription | SubAbility$ DBChangeZone1 | SpellDescription$ Search your library for up to two creature cards and reveal them. Put one into your hand and the other into your graveyard. Then shuffle your library.
SVar:DBChangeZone1:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Creature.IsRemembered | ChangeNum$ 1 | Mandatory$ True | NoLooking$ True | SelectPrompt$ Select a card for your hand | Shuffle$ False | SubAbility$ DBChangeZone2 | StackDescription$ None
SVar:DBChangeZone2:DB$ ChangeZone | Origin$ Library | Destination$ Graveyard | ChangeType$ Creature.IsRemembered | Mandatory$ True | NoLooking$ True | SelectPrompt$ Select a card for your graveyard | StackDescription$ None | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/jarads_orders.jpg
End
-

Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Return to Ravnica Spoiler Season
by friarsol » 30 Sep 2012, 21:08
If there's only one valid choice it goes into your hand. It's kinda like a dig, but with cards you choose from your library.Sloth wrote:My only concern is the case with only one creature in the library. Do you have to put it into your hand or can you put it into your graveyard? If i'm reading the card, i think the former is correct. What do you think?
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Return to Ravnica Spoiler Season
by moomarc » 01 Oct 2012, 03:51
Shouldn't there be Min/MaxTarget params in there seeing as you can search for up to two creatures?
-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: Return to Ravnica Spoiler Season
by ArsenalNut » 01 Oct 2012, 04:50
No because you can cancel out of the initial choices to only select one card or no cards. There is a bug that the reveal box freezes the game if you don't select any cards.moomarc wrote:Shouldn't there be Min/MaxTarget params in there seeing as you can search for up to two creatures?
Edit: I fixed the bug by adding a check on the list size
Last edited by ArsenalNut on 01 Oct 2012, 05:04, edited 1 time in total.
So many cards, so little time
-

ArsenalNut - Posts: 512
- Joined: 08 Jul 2011, 03:49
- Has thanked: 27 times
- Been thanked: 121 times
Re: Return to Ravnica Spoiler Season
by ArsenalNut » 01 Oct 2012, 04:57
I thought I had Grave Betrayal worked out.
The only part that doesn't work is
- Grave Betrayal | Open
- Name:Grave Betrayal
ManaCost:5 B B
Types:Enchantment
Text:no text
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.YouDontCtrl | TriggerZones$ Battlefield | Execute$ TrigEffect | TriggerDescription$ Whenever a creature you don't control dies, return it to the battlefield under your control with an additional +1/+1 counter on it at the beginning of the next end step. That creature is a black Zombie in addition to its other colors and types.
SVar:TrigEffect:AB$ Effect | Cost$ 0 | Name$ Grave Betrayal Effect | Triggers$ TrigEOT | SVars$ GBReturn,GBCounter,GBZombify | References$ GBReturn,GBCounter,GBZombify | RememberObjects$ TriggeredCard
SVar:TrigEOT:Mode$ Phase | Phase$ End of Turn | Execute$ GBReturn | TriggerDescription$ Return creature to the battlefield under your control with an additional +1/+1 counter on it at the beginning of the next end step. It is a black Zombie in addition to its other colors and types.
SVar:GBReturn:AB$ ChangeZone | Cost$ 0 | Defined$ Remembered | Origin$ Graveyard | Destination$ Battlefield | GainControl$ True | SubAbility$ GBCounter
SVar:GBCounter:DB$ PutCounter | Defined$ Remembered | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ GBZombify
SVar:GBZombify:DB$ Animate | Defined$ Remembered | Types$ Zombie | Colors$ Black | Permanent$ True
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/grave_betrayal.jpg
End
The only part that doesn't work is
This doesn't work because the effect goes away when the current end step stops instead of the next one. Is this a bug with effects?If a creature you don’t control dies during the end step, that creature won’t return to the battlefield until the beginning of the next end step.
So many cards, so little time
-

ArsenalNut - Posts: 512
- Joined: 08 Jul 2011, 03:49
- Has thanked: 27 times
- Been thanked: 121 times
Re: Return to Ravnica Spoiler Season
by moomarc » 01 Oct 2012, 05:20
Effects use ExecuteUntil which gets cleared at the cleanup step, so make the effect duration permanent and add an extra subability that exiles the effect to the end of your EOT trigger.ArsenalNut wrote:This doesn't work because the effect goes away when the current end step stops instead of the next one. Is this a bug with effects?
-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: Return to Ravnica Spoiler Season
by ArsenalNut » 01 Oct 2012, 05:32
That did the trick. That's the first card I've scripted that used the Effect AF. Pretty cool stuff.moomarc wrote:Effects use ExecuteUntil which gets cleared at the cleanup step, so make the effect duration permanent and add an extra subability that exiles the effect to the end of your EOT trigger.ArsenalNut wrote:This doesn't work because the effect goes away when the current end step stops instead of the next one. Is this a bug with effects?
So many cards, so little time
-

ArsenalNut - Posts: 512
- Joined: 08 Jul 2011, 03:49
- Has thanked: 27 times
- Been thanked: 121 times
Re: Return to Ravnica Spoiler Season
by ArsenalNut » 01 Oct 2012, 05:35
The RTR event decks just announced are completely supported with the new cards 
So many cards, so little time
-

ArsenalNut - Posts: 512
- Joined: 08 Jul 2011, 03:49
- Has thanked: 27 times
- Been thanked: 121 times
Re: Return to Ravnica Spoiler Season
by moomarc » 01 Oct 2012, 05:37
I know. Pretty powerful with all the params it has now. I did quite a few of them at one stage and got to the point where I now have a tendency to start a script with Effects before realising that it can be done more easily with Animate.ArsenalNut wrote:That did the trick. That's the first card I've scripted that used the Effect AF. Pretty cool stuff.moomarc wrote:Effects use ExecuteUntil which gets cleared at the cleanup step, so make the effect duration permanent and add an extra subability that exiles the effect to the end of your EOT trigger.ArsenalNut wrote:This doesn't work because the effect goes away when the current end step stops instead of the next one. Is this a bug with effects?
SWEET!ArsenalNut wrote:The RTR event decks just announced are completely supported with the new cards![]()

-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: Return to Ravnica Spoiler Season
by Sloth » 01 Oct 2012, 07:21
@ArsenalNut: Why did you change the script of Triangle of War? Your version is no longer AI friendly.
-

Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Return to Ravnica Spoiler Season
by moomarc » 01 Oct 2012, 12:36
I've almost got Nivmagus Elemental working. Only problems are with copied spells [Gatherer ruling (hilariously dated 2004
)]
The first mission was getting the copied spells to show up in the list of choices, but eventually got that right. Then had a problem where if you activated the Nivmagus using the original (in the case of the Hunting Pack) then you wouldn't be able to activate using any of the copies.
Now the only issue I have left is that the copied stack instances aren't exiled. Can I post a patch, or should I commit and someone can look at it then revert if there's no saving it?
With regards to the AI, it won't use the ability unless you cast something in response to a spell it has on the stack... then it will use it every time. It actually works out quite well because often it means you're countering the spell in which case it's a waste anyway. But added the RemAIDeck:True flag anyway.
Edit:
My test cases are Hunting Pack and a Firebolt imprinted on Isochron Scepter.You can exile a copy of an instant or sorcery spell to activate Nivmagus Elemental’s ability if you control the copy.
The first mission was getting the copied spells to show up in the list of choices, but eventually got that right. Then had a problem where if you activated the Nivmagus using the original (in the case of the Hunting Pack) then you wouldn't be able to activate using any of the copies.
Now the only issue I have left is that the copied stack instances aren't exiled. Can I post a patch, or should I commit and someone can look at it then revert if there's no saving it?
With regards to the AI, it won't use the ability unless you cast something in response to a spell it has on the stack... then it will use it every time. It actually works out quite well because often it means you're countering the spell in which case it's a waste anyway. But added the RemAIDeck:True flag anyway.
Edit:
- Nivmagus Elemental | Open
- Name:Nivmagus Elemental
ManaCost:UR
Types:Creature Elemental
Text:no text
PT:1/2
A:AB$ PutCounter | Cost$ ExileFromStack<1/Spell.Instant+YouCtrl;Spell.Sorcery+YouCtrl/instant or sorcery spell> | CostDesc$ Exile an instant or sorcery spell you control: | CounterType$ P1P1 | CounterNum$ 2 | SpellDescription$ Put two +1/+1 counters on CARDNAME. (That spell won't resolve.)
SVar:RemAIDeck:True
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/nivmagus_elemental.jpg
SetInfo:RTR|Rare|http://magiccards.info/scans/en/rtr/219.jpg
Oracle:Exile an instant or sorcery spell you control: Put two +1/+1 counters on Nivmagus Elemental. (That spell won't resolve.)
End
- Patch | Open
- Index: src/main/java/forge/card/cost/Cost.java
===================================================================
--- src/main/java/forge/card/cost/Cost.java (revision 17191)
+++ src/main/java/forge/card/cost/Cost.java (working copy)
@@ -161,6 +161,7 @@
private static final String EXILE_STR = "Exile<";
private static final String EXILE_FROM_HAND_STR = "ExileFromHand<";
private static final String EXILE_FROM_GRAVE_STR = "ExileFromGrave<";
+ private static final String EXILE_FROM_STACK_STR = "ExileFromStack<";
private static final String EXILE_FROM_TOP_STR = "ExileFromTop<";
private static final String RETURN_STR = "Return<";
private static final String REVEAL_STR = "Reveal<";
@@ -305,6 +306,14 @@
this.costParts.add(new CostExile(splitStr[0], splitStr[1], description, ZoneType.Graveyard));
}
+ while (parse.contains(Cost.EXILE_FROM_STACK_STR)) {
+ final String[] splitStr = this.abCostParse(parse, Cost.EXILE_FROM_STACK_STR, 3);
+ parse = this.abUpdateParse(parse, Cost.EXILE_FROM_STACK_STR);
+
+ final String description = splitStr.length > 2 ? splitStr[2] : null;
+ this.costParts.add(new CostExile(splitStr[0], splitStr[1], description, ZoneType.Stack));
+ }
+
while (parse.contains(Cost.EXILE_FROM_TOP_STR)) {
final String[] splitStr = this.abCostParse(parse, Cost.EXILE_FROM_TOP_STR, 3);
parse = this.abUpdateParse(parse, Cost.EXILE_FROM_TOP_STR);
Index: src/main/java/forge/card/cost/CostExile.java
===================================================================
--- src/main/java/forge/card/cost/CostExile.java (revision 17191)
+++ src/main/java/forge/card/cost/CostExile.java (working copy)
@@ -17,6 +17,7 @@
*/
package forge.card.cost;
+import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.JOptionPane;
@@ -28,6 +29,7 @@
import forge.Singletons;
import forge.card.abilityfactory.AbilityFactory;
import forge.card.spellability.SpellAbility;
+import forge.card.spellability.SpellAbilityStackInstance;
import forge.control.input.Input;
import forge.game.player.ComputerUtil;
import forge.game.player.Player;
@@ -142,7 +144,14 @@
*/
@Override
public final boolean canPay(final SpellAbility ability, final Card source, final Player activator, final Cost cost) {
- CardList typeList = activator.getCardsIn(this.getFrom());
+ CardList typeList = new CardList();
+ if (this.getFrom().equals(ZoneType.Stack)) {
+ for (int i = 0; i < AllZone.getStack().size(); i++) {
+ typeList.add(AllZone.getStack().peekAbility(i).getSourceCard());
+ }
+ } else {
+ typeList = activator.getCardsIn(this.getFrom());
+ }
if (!this.getThis()) {
typeList = typeList.getValidCards(this.getType().split(";"), activator, source);
@@ -167,6 +176,15 @@
public final void payAI(final SpellAbility ability, final Card source, final CostPayment payment) {
for (final Card c : this.getList()) {
Singletons.getModel().getGameAction().exile(c);
+ if (this.from.equals(ZoneType.Stack)) {
+ ArrayList<SpellAbility> spells = c.getSpellAbilities();
+ for (SpellAbility spell : spells) {
+ if (c.isInZone(ZoneType.Exile)) {
+ final SpellAbilityStackInstance si = AllZone.getStack().getInstanceFromSpellAbility(spell);
+ AllZone.getStack().remove(si);
+ }
+ }
+ }
}
}
@@ -316,9 +334,18 @@
this.done();
}
- this.typeList = sa.getActivatingPlayer().getCardsIn(part.getFrom());
- this.typeList = this.typeList.getValidCards(type.split(";"), sa.getActivatingPlayer(),
- sa.getSourceCard());
+ if (part.getFrom().equals(ZoneType.Stack)) {
+ this.typeList = new CardList();
+ for (int i = 0; i < AllZone.getStack().size(); i++) {
+ this.typeList.add(AllZone.getStack().peekAbility(i).getSourceCard());
+ this.typeList = this.typeList.getValidCards(type.split(";"), sa.getActivatingPlayer(),
+ sa.getSourceCard());
+ }
+ } else {
+ this.typeList = sa.getActivatingPlayer().getCardsIn(part.getFrom());
+ this.typeList = this.typeList.getValidCards(type.split(";"), sa.getActivatingPlayer(),
+ sa.getSourceCard());
+ }
for (int i = 0; i < nNeeded; i++) {
if (this.typeList.size() == 0) {
@@ -336,6 +363,15 @@
if (i == (nNeeded - 1)) {
this.done();
}
+ if (part.getFrom().equals(ZoneType.Stack)) {
+ ArrayList<SpellAbility> spells = c.getSpellAbilities();
+ if (c.isInZone(ZoneType.Exile)) {
+ for (SpellAbility spell : spells) {
+ final SpellAbilityStackInstance si = AllZone.getStack().getInstanceFromSpellAbility(spell);
+ AllZone.getStack().remove(si);
+ }
+ }
+ }
} else {
this.cancel();
break;
@@ -403,6 +439,8 @@
if (part.getFrom().equals(ZoneType.Hand)) {
msg.append(" from your Hand");
+ } else if (part.getFrom().equals(ZoneType.Stack)) {
+ msg.append(" from the Stack");
}
this.typeList = sa.getActivatingPlayer().getCardsIn(part.getFrom());
this.typeList = this.typeList.getValidCards(type.split(";"), sa.getActivatingPlayer(),
Index: src/main/java/forge/card/cost/CostUtil.java
===================================================================
--- src/main/java/forge/card/cost/CostUtil.java (revision 17191)
+++ src/main/java/forge/card/cost/CostUtil.java (working copy)
@@ -37,7 +37,7 @@
*/
public class CostUtil {
private static Random r = new Random();
-
+
/**
* Check sacrifice cost.
*
@@ -457,8 +457,7 @@
// Just a shortcut..
AllZone.getInputControl().setInput(in, true);
}
-
-
+
public static Cost combineCosts(Cost cost1, Cost cost2) {
if (cost1 == null) {
if (cost2 == null) {
@@ -467,11 +466,11 @@
return cost2;
}
}
-
+
if (cost2 == null) {
return cost1;
}
-
+
for (final CostPart part : cost1.getCostParts()) {
if (!(part instanceof CostMana)) {
cost2.getCostParts().add(part);
-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: Return to Ravnica Spoiler Season
by ArsenalNut » 01 Oct 2012, 12:56
I missed the "TargetsFromDifferentZone$" portion and thought you could target two creatures on the same side.Sloth wrote:@ArsenalNut: Why did you change the script of Triangle of War? Your version is no longer AI friendly.
So many cards, so little time
-

ArsenalNut - Posts: 512
- Joined: 08 Jul 2011, 03:49
- Has thanked: 27 times
- Been thanked: 121 times
Re: Return to Ravnica Spoiler Season
by Sloth » 01 Oct 2012, 16:24
I will take a look at this. As this is a general problem you can probably commit savely.moomarc wrote:EDIT2: I noticed in testing that Counterspell also can't counter storm copies. Is this meant to be the case?
-

Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Return to Ravnica Spoiler Season
by moomarc » 01 Oct 2012, 16:31
I've actually changed my code a bit now so that ExileFromStack uses a separate input based on SAs instead of cards. It's working perfectly for the human and was about to test for the AI.Sloth wrote:I will take a look at this. As this is a general problem you can probably commit savely.moomarc wrote:EDIT2: I noticed in testing that Counterspell also can't counter storm copies. Is this meant to be the case?
Should I carry on with my current method or revert to how it was before? (well for now I suppose I'll keep both versions locally and see what works best after your fix).
-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: Return to Ravnica Spoiler Season
by moomarc » 01 Oct 2012, 17:55
Nivmagus Elemental isworking perfectly now, but just want to check one last thing before committing. Am I correct in thinking that exiling a spell from the stack also exiles the card (unless it's a copied spell)? If so I can commit right now.
-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 14 guests