New keyword: spDestroyAll
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
20 posts
• Page 1 of 2 • 1, 2
New keyword: spDestroyAll
by Sloth » 15 Aug 2010, 17:24
I've added a new keyword: spDestroyAll
spDestroyAll:<AffectedType>:<Options>
<AffectedType>: takes all the restrictions of spDestroyTgt.
<Options>: Only NoRegen is supported at the moment.
The AI will use these spells if at least 2 more human permanents will be destroyed. That means that some spells like Armageddon should not be converted, but most of the other spells have the same restrictions (Wrath of God) or none at all (Purify).
Here is the code:
spDestroyAll:<AffectedType>:<Options>
<AffectedType>: takes all the restrictions of spDestroyTgt.
<Options>: Only NoRegen is supported at the moment.
The AI will use these spells if at least 2 more human permanents will be destroyed. That means that some spells like Armageddon should not be converted, but most of the other spells have the same restrictions (Wrath of God) or none at all (Purify).
Here is the code:
- Code: Select all
// Generic destroy all card
if(hasKeyword(card, "spDestroyAll") != -1) {
int n = hasKeyword(card, "spDestroyAll");
String parse = card.getKeyword().get(n).toString();
card.removeIntrinsicKeyword(parse);
String k[] = parse.split(":");
String Targets = k[1]; // Artifact, Creature, Enchantment, Land, Permanent, White, Blue, Black, Red, Green, Colorless, MultiColor
// non-Artifact, non-Creature, non-Enchantment, non-Land, non-Permanent,
//non-White, non-Blue, non-Black, non-Red, non-Green, non-Colorless, non-MultiColor
final String Tgts[] = Targets.split(",");
final boolean NoRegen = (k.length == 3);
card.clearSpellAbility();
final SpellAbility spDstryAll = new Spell(card) {
private static final long serialVersionUID = 132554543614L;
@Override
public boolean canPlayAI() {
CardList human = new CardList(AllZone.Human_Play.getCards());
CardList computer = new CardList(AllZone.Computer_Play.getCards());
human = human.getValidCards(Tgts);
human = human.getNotKeyword("Indestructible");
computer = computer.getValidCards(Tgts);
computer = computer.getNotKeyword("Indestructible");
// the computer will at least destroy 2 more human permanents
return AllZone.Phase.getPhase().equals(Constant.Phase.Main2) &&
(computer.size() < human.size() - 1);
}
@Override
public void resolve() {
CardList all = new CardList();
all.addAll(AllZone.Human_Play.getCards());
all.addAll(AllZone.Computer_Play.getCards());
all = all.getValidCards(Tgts);
CardListUtil.sortByIndestructible(all);
CardListUtil.sortByDestroyEffect(all);
for(int i = 0; i < all.size(); i++) {
Card c = all.get(i);
if(NoRegen) AllZone.GameAction.destroyNoRegeneration(c); else AllZone.GameAction.destroy(c);
}
}// resolve()
}; //SpDstryAll
card.setSVar("PlayMain1", "TRUE");
card.addSpellAbility(spDstryAll);
}//spDestroyAll
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: New keyword: spDestroyAll
by Rob Cashwalker » 16 Aug 2010, 00:18
Nice work.
I would suggest changing
final boolean NoRegen = (k.length == 3);
to actually check for "NoRegen" so other options can be added without changing much code.
Edit - For example, add Drawback as an option.
I would suggest changing
final boolean NoRegen = (k.length == 3);
to actually check for "NoRegen" so other options can be added without changing much code.
Edit - For example, add Drawback as an option.
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: New keyword: spDestroyAll
by Chris H. » 17 Aug 2010, 20:14
`Sloth wrote:I've added a new keyword: spDestroyAll
spDestroyAll:<AffectedType>:<Options>
<AffectedType>: takes all the restrictions of spDestroyTgt.
<Options>: Only NoRegen is supported at the moment.
The AI will use these spells if at least 2 more human permanents will be destroyed. That means that some spells like Armageddon should not be converted, but most of the other spells have the same restrictions (Wrath of God) or none at all (Purify).
I converted 4 spells to the spDestroyAll keyword.
Acid Rain
Boil
Boiling Seas
Flashfires
These spells use a different AI test. It only checks to see if the human has > 3 of the affected land type in play. I thought about it and decided that we humans are likely to play multi-color decks more often than single color decks. And these four cards will not appear in a randomly generated deck.
So, the spDestroyAll AI test may be enough. What do other people think?
-
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: New keyword: spDestroyAll
by Chris H. » 17 Aug 2010, 23:39
We have a code block with a number of spells:
Akroma's Vengeance
Devastation
Jokulhaups
Purify
Shatterstorm
Obliterate
I commented out the code block and tried to convert Akroma's Vengeance. The card now looks like this:
It worked in a test game, except for one thing. When this spell is cast, it brings up a choose window where we get to select the spDestroyAll or the Cycling SpellAbility. Having the spell description on the fourth line, well, the spDestroyAll spell description will not appear in the choose window. In the original code block there is a test for this card and it sets the spell description via:
Akroma's Vengeance
Devastation
Jokulhaups
Purify
Shatterstorm
Obliterate
I commented out the code block and tried to convert Akroma's Vengeance. The card now looks like this:
`Akroma's Vengeance
4 W W
Sorcery
Destroy all artifacts, creatures, and enchantments.
spDestroyAll:Artifact,Creature,Enchantment
Cycling:3
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/akromas_vengeance.jpg
It worked in a test game, except for one thing. When this spell is cast, it brings up a choose window where we get to select the spDestroyAll or the Cycling SpellAbility. Having the spell description on the fourth line, well, the spDestroyAll spell description will not appear in the choose window. In the original code block there is a test for this card and it sets the spell description via:
- Code: Select all
spell.setDescription("Destroy all artifacts, creatures, and enchantments.");
-
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: New keyword: spDestroyAll
by Rob Cashwalker » 18 Aug 2010, 00:21
The original spDestroyTgt that Sloth has based these keywords on, assumed very simple spells using just the normal card text.
I am revising spDestroyTgt right now to support Drawback. I will also look into making sure these spells set their descriptions.
I am revising spDestroyTgt right now to support Drawback. I will also look into making sure these spells set their descriptions.
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: New keyword: spDestroyAll
by Sloth » 18 Aug 2010, 07:54
Thanks Rob!Rob Cashwalker wrote:I am revising spDestroyTgt right now to support Drawback. I will also look into making sure these spells set their descriptions.
I just converted Rebuild to keyword and the Cycling choice works fine.
I will now start to improve canPlayAI for spDestroyAll.
My first draft is:
X = number of permanents + total CMC + number of lands (human)
and if the computers life is below 7 add the total power of the human creatures (which should make a huge difference).
Y = number of permanents + total CMC + number of lands (computer)
canPlayAI returns true if Y < X - 3.
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: New keyword: spDestroyAll
by Chris H. » 18 Aug 2010, 13:11
`Rob Cashwalker wrote:The original spDestroyTgt that Sloth has based these keywords on, assumed very simple spells using just the normal card text.
I am revising spDestroyTgt right now to support Drawback. I will also look into making sure these spells set their descriptions.
I merged Rob's work into my local copy and was able to convert over a few more spells.
However, Obliterate does not display it's "CARDNAME can't be countered." keyword. We had in the past several other keywords that failed to show up in the text panel. I should be able to add this additional keyword to the proper section in card.getText(), or at least I think that I can fix it this way. We will see.

-
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: New keyword: spDestroyAll
by Rob Cashwalker » 18 Aug 2010, 13:32
I originally assigned card.getText to the spell description, then card.setText("").
Now, I noticed that there's card.getSpellText, which seems like it should return the "printed" text, as opposed to the parsed, generated text.
Now, I noticed that there's card.getSpellText, which seems like it should return the "printed" text, as opposed to the parsed, generated text.
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: New keyword: spDestroyAll
by Chris H. » 18 Aug 2010, 16:38
`Rob Cashwalker wrote:I originally assigned card.getText to the spell description, then card.setText("").
Now, I noticed that there's card.getSpellText, which seems like it should return the "printed" text, as opposed to the parsed, generated text.
That might solve the problem. We should check into this and see if it makes a difference at some point.
-
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: New keyword: spDestroyAll
by Rob Cashwalker » 18 Aug 2010, 17:28
The code I submitted last night uses it. So if it's not working now, then I don't know what it should do.
The DestroyTgt and BounceTgt code relies on the wording "Destroy/Return target ____" being at the beginning of the printed text. The "____" is inserted into the input prompt.
Without using the card text (relying on the description coming from the keyword line itself, then I would need another parameter of SVar to provide the "____".
After using the card.getSpellText for the spellDescription, it uses card.setText("") to clear it. (so it doesn't appear twice from card.getText() - once from the printed text and then from the SpellAbility)
The DestroyAll and BounceAll code just sucks up the card.getSpellText, and then clears it. It doesn't need the printed text for anything else.
The DestroyTgt and BounceTgt code relies on the wording "Destroy/Return target ____" being at the beginning of the printed text. The "____" is inserted into the input prompt.
Without using the card text (relying on the description coming from the keyword line itself, then I would need another parameter of SVar to provide the "____".
After using the card.getSpellText for the spellDescription, it uses card.setText("") to clear it. (so it doesn't appear twice from card.getText() - once from the printed text and then from the SpellAbility)
The DestroyAll and BounceAll code just sucks up the card.getSpellText, and then clears it. It doesn't need the printed text for anything else.
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: New keyword: spDestroyAll
by Chris H. » 19 Aug 2010, 00:46
I had problems converting Guan Yu's 1,000-Li March to keyword. It would not display the spell text. The card worked and would kill tapped creatures. I looked at your message and realized that I would have to change the cards.txt entry to this:
Guan Yu's 1,000-Li March
4 W W
Sorcery
Destroy all creatures that are tapped.
spDestroyAll:Creature.tapped
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/guan_yus_1000_li_march.jpg
Guan Yu's 1,000-Li March
4 W W
Sorcery
Destroy all creatures that are tapped.
spDestroyAll:Creature.tapped
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/guan_yus_1000_li_march.jpg
-
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: New keyword: spDestroyAll
by Rob Cashwalker » 21 Aug 2010, 03:31
I just added drawback handling to spDestroyAll.
This was my test card:
To actually count some other criteria, use "dX" and an SVar to define the Count$.
Doing this card also revealed some bugs in the doDrawback math handling code, so I had to debug those before proving the actual functionality.
This was my test card:
- Code: Select all
Hellfire
2 B B B
Sorcery
Destroy all nonblack creatures. Hellfire deals X plus 3 damage to you, where X is the number of creatures put into all graveyards this way.
spDestroyAll:Creature.nonBlack:Drawback$DamageYou/X.Plus.3
SVar:Rarity:Rare
To actually count some other criteria, use "dX" and an SVar to define the Count$.
Doing this card also revealed some bugs in the doDrawback math handling code, so I had to debug those before proving the actual functionality.
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: New keyword: spDestroyAll
by Chris H. » 07 Sep 2010, 19:20
`Rob Cashwalker wrote:I just added drawback handling to spDestroyAll.
This was my test card:There are a handful of cards with drawbacks we can handle. I think all or almost all of them involve the number of cards the spell actually destroyed, so that is the number being passed as "X".
- Code: Select all
Hellfire
2 B B B
Sorcery
Destroy all nonblack creatures. Hellfire deals X plus 3 damage to you, where X is the number of creatures put into all graveyards this way.
spDestroyAll:Creature.nonBlack:Drawback$DamageYou/X.Plus.3
SVar:Rarity:Rare
To actually count some other criteria, use "dX" and an SVar to define the Count$.
Doing this card also revealed some bugs in the doDrawback math handling code, so I had to debug those before proving the actual functionality.
I spent some time trying to figure out the SVar for Hellfire. I assume that this would do it:
SVar:X:Count$TypeOnBattlefield.Creature.nonBlack
-
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: New keyword: spDestroyAll
by Chris H. » 07 Sep 2010, 20:03
`friarisol wrote:That doesn't account for Indestructible creatures or creatures that regenerated from the Hellfire (and possibly others).
I had considered:
SVar:X:Count$TypeInAllYards.Creature.nonBlack
but this version also has problems determining the correct number of X. And I am not sure when X is calculated, although I assume that it is equal to the number of cards in the list of valid targets.
-
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
20 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 30 guests