Multizone Origin for ChangeZone
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
10 posts
• Page 1 of 1
Multizone Origin for ChangeZone
by moomarc » 16 Jul 2012, 17:44
I've made some changes to ChangeZone in my local copy that allows multizone Origin .Eg: Venser's Diffusion now uses this clean script:
Otherwise here's a patch for ChangeZone.java if anyone wants to try it out:
Mostly it was just boxing the various blocks with
Otherwise, what are some of the scenarios I should test?
- Code: Select all
A:SP$ ChangeZone | Cost$ 2 U | ValidTgts$ Permanent.nonLand,Card.suspended | TgtPrompt$ Choose target nonland permanent or suspended card. | IsCurse$ True | Origin$ Exile,Battlefield | Destination$ Hand | SpellDescription$ Return target nonland permanent or suspended card to its owner's hand.
Otherwise here's a patch for ChangeZone.java if anyone wants to try it out:
MultiOriginPatch.txt
- (59.48 KiB) Downloaded 269 times
Mostly it was just boxing the various blocks with
- Code: Select all
for (ZoneType origin : originList) {
Otherwise, what are some of the scenarios I should test?
-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: Multizone Origin for ChangeZone
by moomarc » 16 Jul 2012, 21:31
Quick note that you need the change to Target selection I committed with Timebender for the multi origin to work for the human player. All it does is include valid targets from the battlefield in the list normally used for targeting in other zones if zones.size() >= 1.
-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: Multizone Origin for ChangeZone
by friarsol » 16 Jul 2012, 22:56
Is there any way to differentiate where the card is coming from? Like how can I quickly tell if that's my card on the battlefield, or if that's my suspended card.moomarc wrote:Quick note that you need the change to Target selection I committed with Timebender for the multi origin to work for the human player. All it does is include valid targets from the battlefield in the list normally used for targeting in other zones if zones.size() >= 1.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Multizone Origin for ChangeZone
by moomarc » 17 Jul 2012, 04:09
I'll have a look later but there should be a way to append the zone to each name in the choice list if there's more than one origin.friarsol wrote:Is there any way to differentiate where the card is coming from? Like how can I quickly tell if that's my card on the battlefield, or if that's my suspended card.moomarc wrote:Quick note that you need the change to Target selection I committed with Timebender for the multi origin to work for the human player. All it does is include valid targets from the battlefield in the list normally used for targeting in other zones if zones.size() >= 1.
-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: Multizone Origin for ChangeZone
by moomarc » 17 Jul 2012, 08:15
Haven't managed to append the card's zone yet, but I did realise that because of the way that Forge defines a Permanent, I had to add an extra restriction in IsValid for OnBattlefield (otherwise Venser's Diffusion, Timebender and the other cards from this block that I've been working on will allow you to target "Permanent cards" instead of Permanents). I'll apply the fix as soon as I've retested them all.
-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: Multizone Origin for ChangeZone
by friarsol » 17 Jul 2012, 12:13
I'm not sure if we need to append the Zone to the card name (that might be too long anyway) but I wonder if the select box can have a descripter choice that isn't selectable that can list the start of a Zone. I don't know how (or if) this works in Java but in HTML it looks like thismoomarc wrote:I'll have a look later but there should be a way to append the zone to each name in the choice list if there's more than one origin.
http://www.w3schools.com/tags/tryit.asp ... l_optgroup
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Multizone Origin for ChangeZone
by moomarc » 17 Jul 2012, 12:24
I've been looking at the chooseOneOrNone GUI code (the whole GuiUtils class actually) and I'm stuggling to see how to work get anything extra in there. I think I might be able to work something out thanks to your suggestion though. Basically I need to break the arraylist passed to GuiUtils into smaller arrays per zone, then insert a dummy card in position 0, and feed those back into getChoices. Might be a bit beyond my skills but I'll give it a bash...friarsol wrote:I'm not sure if we need to append the Zone to the card name (that might be too long anyway) but I wonder if the select box can have a descripter choice that isn't selectable that can list the start of a Zone. I don't know how (or if) this works in Java but in HTML it looks like thismoomarc wrote:I'll have a look later but there should be a way to append the zone to each name in the choice list if there's more than one origin.
http://www.w3schools.com/tags/tryit.asp ... l_optgroup
-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: Multizone Origin for ChangeZone
by moomarc » 17 Jul 2012, 16:53

- Code: Select all
java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.next(Unknown Source)
at forge.card.spellability.TargetSelection.chooseCardFromList(TargetSelection.java:444)
- Code: Select all
public final void chooseCardFromList(final CardList choices, final boolean targeted, final boolean mandatory) {
// Send in a list of valid cards, and popup a choice box to target
final Card dummy = new Card();
dummy.setName("[FINISH TARGETING]");
final SpellAbility sa = this.ability;
final String message = this.target.getVTSelection();
final Card divBattlefield = new Card();
divBattlefield.setName("--CARDS ON BATTLEFIELD:--");
final Card divExile = new Card();
divExile.setName("--CARDS IN EXILE:--");
final Card divGrave = new Card();
divGrave.setName("--CARDS IN GRAVEYARD:--");
final Card divLibrary = new Card();
divLibrary.setName("--CARDS IN LIBRARY:--");
final Card divStack = new Card();
divStack.setName("--CARDS IN LIBRARY:--");
CardList choicesZoneUnfiltered = choices;
final CardList crdsBattle = new CardList();
final CardList crdsExile = new CardList();
final CardList crdsGrave = new CardList();
final CardList crdsLibrary = new CardList();
final CardList crdsStack = new CardList();
//ln444 for (final Card inZone : choicesZoneUnfiltered) {
if (AllZoneUtil.getCardsIn(ZoneType.Battlefield).contains(inZone)) {
crdsBattle.add(inZone);
choicesZoneUnfiltered.remove(inZone);
} else if (AllZoneUtil.getCardsIn(ZoneType.Exile).contains(inZone)) {
crdsExile.add(inZone);
choicesZoneUnfiltered.remove(inZone);
} else if (AllZoneUtil.getCardsIn(ZoneType.Graveyard).contains(inZone)) {
crdsGrave.add(inZone);
choicesZoneUnfiltered.remove(inZone);
} else if (AllZoneUtil.getCardsIn(ZoneType.Library).contains(inZone)) {
crdsLibrary.add(inZone);
choicesZoneUnfiltered.remove(inZone);
} else if (AllZoneUtil.getCardsIn(ZoneType.Stack).contains(inZone)) {
crdsStack.add(inZone);
choicesZoneUnfiltered.remove(inZone);
}
}
CardList choicesFiltered = new CardList();
if (crdsBattle.size() >= 1) {
choicesFiltered.add(divBattlefield);
choicesFiltered.addAll(crdsBattle);
crdsBattle.clear();
}
if (crdsExile.size() >= 1) {
choicesFiltered.add(divExile);
choicesFiltered.addAll(crdsExile);
crdsExile.clear();
}
if (crdsGrave.size() >= 1) {
choicesFiltered.add(divGrave);
choicesFiltered.addAll(crdsGrave);
crdsGrave.clear();
}
if (crdsLibrary.size() >= 1) {
choicesFiltered.add(divLibrary);
choicesFiltered.addAll(crdsLibrary);
crdsLibrary.clear();
}
if (crdsStack.size() >= 1) {
choicesFiltered.add(divStack);
choicesFiltered.addAll(crdsStack);
crdsStack.clear();
}
final Target tgt = this.getTgt();
final CardList choicesWithDone = choicesFiltered;
if (tgt.isMinTargetsChosen(sa.getSourceCard(), sa)) {
// is there a more elegant way of doing this?
choicesWithDone.add(dummy);
}
final Object check = GuiUtils.chooseOneOrNone(message, choicesWithDone.toArray());
if (check != null) {
final Card c = (Card) check;
if (!c.equals(divBattlefield) && !c.equals(divExile) && !c.equals(divGrave)
&& !c.equals(divLibrary) && !c.equals(divStack)) {
if (c.equals(dummy)) {
this.setDoneTarget(true);
} else {
tgt.addTarget(c);
}
}
} else {
this.setCancel(true);
}
this.chooseTargets();
}
-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: Multizone Origin for ChangeZone
by Hellfish » 17 Jul 2012, 17:13
The ConcurrentModificationException is thrown when you try to add or remove elements from a list inside of a loop that loops through the same list. Do you really need to remove the inZone card after it's been added to it's correct CardList? Or will cards occur multiple times in choicesZoneUnfiltered? If not, you'll only loop "past" each card once anyway.
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
-
Hellfish - Programmer
- Posts: 1297
- Joined: 07 Jun 2009, 10:41
- Location: South of the Pumphouse
- Has thanked: 110 times
- Been thanked: 169 times
Re: Multizone Origin for ChangeZone
by moomarc » 17 Jul 2012, 17:35
I LOVE YOU! Thanks for that. Works like a dream! I'm going to commit this for now because it makes the Time Spiral cards I've added over the last day or so a bit easier to use. (Erm, apologies for the overreaction. I'm still just a designer with a newfound interest in hobby coding (thanks to Forge) so this was intense coding for me trying to track the right place to put it and work out the way to do it. So it was good to see it was just something small I missed).Hellfish wrote:The ConcurrentModificationException is thrown when you try to add or remove elements from a list inside of a loop that loops through the same list. Do you really need to remove the inZone card after it's been added to it's correct CardList? Or will cards occur multiple times in choicesZoneUnfiltered? If not, you'll only loop "past" each card once anyway.
Then, I'm starting another 3 week contract tomorrow so will probably have very little time for Forge. This means I won't be able to test whether the ChangeZone AI is broken anywhere because of the multi origin changes I made (the Time Spiral stuff is all just using the capabilities of TgtZone in AbilityFactory). So far I haven't come across anything strange, but I don't want to commit anything I won't be able to fix if anything comes up. Nothing has changed since I posted the ChangeZone patch in the first post, so if anyone feels it's worth adding use that patch. The only card I know of that actually uses a multizone origin is Venser's Diffusion, so here would be the updated script:
- Venser's Diffusion | Open
- Name:Venser's Diffusion
ManaCost:2 U
Types:Instant
Text:no text
A:SP$ ChangeZone | Cost$ 2 U | ValidTgts$ Permanent.nonLand+OnBattlefield,Card.suspended | TgtPrompt$ Choose target nonland permanent or suspended card. | IsCurse$ True | Origin$ Exile,Battlefield | Destination$ Hand | SpellDescription$ Return target nonland permanent or suspended card to its owner's hand.
SVar:Rarity:Common
SVar:Picture:http://www.wizards.com/global/images/magic/general/vensers_diffusion.jpg
SetInfo:FUT|Common|http://magiccards.info/scans/en/fut/47.jpg
Oracle:Return target nonland permanent or suspended card to its owner's hand.
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
10 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 50 guests