spPumpTgt - Targeted Pump Spells
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
20 posts
• Page 1 of 2 • 1, 2
spPumpTgt - Targeted Pump Spells
by Rob Cashwalker » 17 Jul 2009, 14:06
Spells which follow the syntax "Target creature [gets | gains] [+p/+t | keyword] [and gains keyword] until end of turn.
In other words, it supports p/t pumps:
Giant Growth
G
Instant
Target creature gets +3/+3 until end of turn.
spPumpTgt:+3/+3
Or p/t/k pumps:
Wildsize
2 G
Instant
Target creature gets +2/+2 and gains trample until end of turn.
spPumpTgt:+2/+2/Trample
or just keyword pumps:
Accelerate
1 R
Instant
Target creature gains haste until end of turn.#Draw a card.
spPumpTgt:Haste
Cantrip
I've tested it a little bit with Giant Growth and Wildsize both human and AI.
In other words, it supports p/t pumps:
Giant Growth
G
Instant
Target creature gets +3/+3 until end of turn.
spPumpTgt:+3/+3
Or p/t/k pumps:
Wildsize
2 G
Instant
Target creature gets +2/+2 and gains trample until end of turn.
spPumpTgt:+2/+2/Trample
or just keyword pumps:
Accelerate
1 R
Instant
Target creature gains haste until end of turn.#Draw a card.
spPumpTgt:Haste
Cantrip
- Code: Select all
private final int shouldSpPumpTgt(Card c){
ArrayList<String> a = c.getKeyword();
for (int i = 0; i < a.size(); i++)
if (a.get(i).toString().startsWith("spPumpTgt"))
return i;
return -1;
}
- Code: Select all
// Generic target creature pump
if (shouldSpPumpTgt(card) != -1)
{
int n = shouldSpPumpTgt(card);
String parse = card.getKeyword().get(n).toString();
card.removeIntrinsicKeyword(parse);
String k[] = parse.split(":");
String ptk[] = k[1].split("/");
final int attack[] = {0};
final int defense[] = {0};
final String keyword[] = {"none"};
if (ptk.length == 1)
keyword[0] = ptk[0];
if (ptk.length >= 2)
{
attack[0] = Integer.parseInt(ptk[0].replace("+", ""));
defense[0] = Integer.parseInt(ptk[1].replace("+", ""));
}
if (ptk.length == 3)
keyword[0] = ptk[2];
/* String Desc = new String();
Desc = "Target creature ";
if (attack[0] != 0 || defense[0] != 0)
{
Desc = Desc + "gets ";
if (attack[0] > 0)
Desc = Desc + "+" + attack[0];
else
Desc = Desc + attack[0];
Desc = Desc + "/";
if (defense[0] > 0)
Desc = Desc + "+" + defense[0];
else
Desc = Desc + defense[0];
if (! keyword[0].equals("none"))
Desc = Desc + " and ";
}
if (! keyword[0].equals("none"))
Desc = Desc + "gains " + keyword;
Desc = Desc + " until end of turn.";
*/
SpellAbility spPump = new Spell(card)
{
private static final long serialVersionUID = 42244224L;
public boolean canPlayAI()
{
Card c = getAttacker();
if (c != null)
{
setTargetCard(c);
return true;
}
else
return false;
}
public Card getAttacker()
{
Combat c = ComputerUtil.getAttackers();
CardList list = new CardList(c.getAttackers());
CardListUtil.sortFlying(list);
list = list.filter(new CardListFilter()
{
public boolean addCard(Card c)
{
return (CardFactoryUtil.canTarget(card, c)) &&
(! c.getKeyword().contains(keyword[0])) &&
(! c.hasSickness() && keyword[0].equals("Haste"));
}
});
if (list.size() > 0)
return list.get(0);
else
return null;
}
public void resolve()
{
final Card[] target = new Card[1];
final Command untilEOT = new Command()
{
private static final long serialVersionUID = -42244224L;
public void execute()
{
if (AllZone.GameAction.isCardInPlay(target[0]))
{
target[0].addTempAttackBoost(-attack[0]);
target[0].addTempDefenseBoost(-defense[0]);
if (!keyword[0].equals("none"))
target[0].removeExtrinsicKeyword(keyword[0]);
}
}
};
target[0] = getTargetCard();
if (AllZone.GameAction.isCardInPlay(target[0]) && CardFactoryUtil.canTarget(card, target[0]))
{
target[0].addTempAttackBoost(attack[0]);
target[0].addTempDefenseBoost(defense[0]);
if (!keyword[0].equals("none"))
target[0].addExtrinsicKeyword(keyword[0]);
AllZone.EndOfTurn.addUntil(untilEOT);
}
}
};
spPump.setBeforePayMana(CardFactoryUtil.input_targetCreature(spPump));
//spPump.setDescription(Desc);
card.clearSpellAbility();
card.addSpellAbility(spPump);
}
I've tested it a little bit with Giant Growth and Wildsize both human and AI.
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: spPumpTgt - Targeted Pump Spells
by Sloth » 18 Jul 2009, 14:59
Great! A lot new cards can be added!
I'm not finished checking but here are some instants I found, that can now be added to cards.txt:
I'm not finished checking but here are some instants I found, that can now be added to cards.txt:
- Code: Select all
Silk Net
G
Instant
Target creature gets +1/+1 and gains reach until end of turn.
spPumpTgt:+1/+1/Reach
Predator's Strike
1 G
Instant
Target creature gets +3/+3 and gains trample until end of turn.
spPumpTgt:+3/+3/Trample
Kindled Fury
R
Instant
Target creature gets +1/+0 and gains first strike until end of turn.
spPumpTgt:+1/+0/First Strike
Fists of the Anvil
1 R
Instant
Target creature gets +4/+0 until end of turn.
spPumpTgt:+4/+0
Fanatical Fever
2 G G
Instant
Target creature gets +3/+0 and gains trample until end of turn.
spPumpTgt:+3/+0/Trample
Colossal Might
R G
Instant
Target creature gets +4/+2 and gains trample until end of turn.
spPumpTgt:+4/+2/Trample
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: spPumpTgt - Targeted Pump Spells
by DennisBergkamp » 19 Jul 2009, 10:38
Nice one Rob, I'm adding this stuff in right now 
And thank you Sloth for those extra cards!

And thank you Sloth for those extra cards!
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: spPumpTgt - Targeted Pump Spells
by Rob Cashwalker » 20 Jul 2009, 04:54
Cool. Like I said I only did some limited testing, and the AI might not fully appreciate all the possibilities. It certainly (as with all "pumps") doesn't do negative-only pumps. In fact, now that I think about it, (and look down at the post) I forgot to put in the usual check to see with the defense would be reduced below zero.
Dennis - do you know what the abTgtPump bug is that Sloth mentioned?
Dennis - do you know what the abTgtPump bug is that Sloth mentioned?
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: spPumpTgt - Targeted Pump Spells
by Sloth » 20 Jul 2009, 12:42
Here are a few more for cards.txt:
- Code: Select all
Wielding the Green Dragon
1 G
Sorcery
Target creature gets +4/+4 until end of turn.
spPumpTgt:+4/+4
Screaming Fury
2 R
Sorcery
Target creature gets +5/+0 and gains haste until end of turn.
spPumpTgt:+5/+0/Haste
Sangrite Surge
4 R G
Sorcery
Target creature gets +3/+3 and gains double strike until end of turn.
spPumpTgt:+3/+3/Double Strike
Monstrous Growth
1 G
Sorcery
Target creature gets +4/+4 until end of turn.
spPumpTgt:+4/+4
Howling Fury
2 B
Sorcery
Target creature gets +4/+0 until end of turn.
spPumpTgt:+4/+0
Fit of Rage
1 R
Sorcery
Target creature gets +3/+3 and gains first strike until end of turn.
spPumpTgt:+3/+3/First Strike
Sudden Strength
3 G
Instant
Target creature gets +3/+3 until end of turn.#Draw a card.
spPumpTgt:+3/+3
Cantrip
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: spPumpTgt - Targeted Pump Spells
by Sloth » 20 Jul 2009, 12:58
I found even more:
- Code: Select all
Cloak of Feathers
U
Sorcery
Target creature gains flying until end of turn.#Draw a card.
spPumpTgt:Flying
Cantrip
Unnatural Speed
R
Instant
Target creature gains haste until end of turn.
spPumpTgt:Haste
Shriek of Dread
1 B
Instant
Target creature gains fear until end of turn.
spPumpTgt:Fear
Shadow Rift
U
Instant
Target creature gains shadow until end of turn.#Draw a card.
spPumpTgt:Shadow
Cantrip
Leap
U
Instant
Target creature gains flying until end of turn.#Draw a card.
spPumpTgt:Flying
Cantrip
Lace with Moonglove
2 G
Instant
Target creature gains deathtouch until end of turn.#Draw a card.
spPumpTgt:Deathtouch
Cantrip
Jump
U
Instant
Target creature gains flying until end of turn.
spPumpTgt:Flying
Double Cleave
1 RW
Instant
Target creature gains double strike until end of turn.
spPumpTgt:Double Strike
Breach
2 B
Instant
Target creature gets +2/+0 and gains fear until end of turn.
spPumpTgt:+2/+0/Fear
Accelerate
R
Instant
Target creature gains haste until end of turn.#Draw a card.
spPumpTgt:Haste
Cantrip
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: spPumpTgt - Targeted Pump Spells
by Rob Cashwalker » 20 Jul 2009, 15:57
The trick with multiple keywords, like spPumpTgt and Cycling is that the order of processing in CardFactory.java needs to be changed. The permanent ability keywords need to be first. Then the spell keywords need to be second. Then the "tack-on" keywords need to be processed last, possibly at the very end of CardFactory, allowing for "tack-ons" to be used for explicitly coded cards.
Cantrip isn't implemented like the others. It's checked upon resolution of any spell - if the card contains the keyword, then it just draws a card. Quite separately from any other card code.
The tricky part I've been trying to think about lately, is the Charms or Commands. Each individual ability of Chaos Charm for example, is something that we have keywords for. But we can't just do it like this:
Chaos Charm
R
Instant
Choose one - Destroy target Wall; or Chaos Charm deals 1 damage to target creature; or target creature gains haste until end of turn.
spDestroyTgt:Creature.Wall
spDamageC:1 (OK, we don't have creature-only damage yet, but it's easy enough)
spPumpTgt:Haste
Because each of the sp___ code blocks clears out the spell abilities of the card. (because all cards are assumed to be permanents, and given a default spell ability to be put into play).
So it would process spDestroyTgt (never mind the fact that the code needs the text formatted a certain way in order to extract the input dialog text) removing the default ability.
Then it would process the spDamageC ability, removing the spDestroyTgt abilty.
Then it would process the spPumpTgt ability, removing the spDamageC ability.
And that's just a rough example, because that's not the order of code blocks... spDamageC would be first, up by the spDamageCP and spDamageP blocks; then spDestroyTgt, and spPumpTgt would probably be inserted last when Dennis merges it.
I think the best way to handle this may be something like the following:
When you go to play the spell, the game will now present each spell option. This won't work for the Commands, which want two choices... but that's OK... for now.
Cantrip isn't implemented like the others. It's checked upon resolution of any spell - if the card contains the keyword, then it just draws a card. Quite separately from any other card code.
The tricky part I've been trying to think about lately, is the Charms or Commands. Each individual ability of Chaos Charm for example, is something that we have keywords for. But we can't just do it like this:
Chaos Charm
R
Instant
Choose one - Destroy target Wall; or Chaos Charm deals 1 damage to target creature; or target creature gains haste until end of turn.
spDestroyTgt:Creature.Wall
spDamageC:1 (OK, we don't have creature-only damage yet, but it's easy enough)
spPumpTgt:Haste
Because each of the sp___ code blocks clears out the spell abilities of the card. (because all cards are assumed to be permanents, and given a default spell ability to be put into play).
So it would process spDestroyTgt (never mind the fact that the code needs the text formatted a certain way in order to extract the input dialog text) removing the default ability.
Then it would process the spDamageC ability, removing the spDestroyTgt abilty.
Then it would process the spPumpTgt ability, removing the spDamageC ability.
And that's just a rough example, because that's not the order of code blocks... spDamageC would be first, up by the spDamageCP and spDamageP blocks; then spDestroyTgt, and spPumpTgt would probably be inserted last when Dennis merges it.
I think the best way to handle this may be something like the following:
- Code: Select all
public boolean hasSpKeyword()
{
ArrayList k = card.getKeywords();
for (i = 0; i < k.length; i++)
if (k(i).startsWith("sp")
return true;
return false;
}
- Code: Select all
if (hasSpKeyword)
{
card.clearSpellAbility();
if (shouldSpDamageCP)
{
...
}
if (shouldSpDamageP)
{
...
}
if (shouldSpDestroyTgt)
{
...
}
if (shouldSpPumpTgt)
{
...
}
...
etc
...
}
When you go to play the spell, the game will now present each spell option. This won't work for the Commands, which want two choices... but that's OK... for now.
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: spPumpTgt - Targeted Pump Spells
by MageKing17 » 20 Jul 2009, 17:44
That's really not the way you want to do choice spells. What if you had a spell that said "Destroy target wall. CARDNAME deals 1 damage to target creature. Target creature gains haste"? You couldn't make it do all those things just by using spDestroyTgt, spDamageC, and spPumpTgt. In Incantus, modal spells are handled a bit oddly... since all abilities are declared with the help of decorators, we just add another decorator to the effects block that defines it as modal and lists all the various modes (with each mode's doc text determining what text it displays, and the decorator having a "choose" argument to determine how many modes can be selected). The annoying thing is that "choose one or both" can't be done... instead, we have to add a third mode saying "both", and make sure to put a timestep inbetween each action (because if you choose two modes, each one happens one after the other, not simultaneously).
-
MageKing17 - Programmer
- Posts: 473
- Joined: 12 Jun 2008, 20:40
- Has thanked: 5 times
- Been thanked: 9 times
Re: spPumpTgt - Targeted Pump Spells
by DennisBergkamp » 20 Jul 2009, 21:52
I have no idea, I was hoping you wouldDennis - do you know what the abTgtPump bug is that Sloth mentioned?

-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: spPumpTgt - Targeted Pump Spells
by Rob Cashwalker » 21 Jul 2009, 05:00
I know, I know. But here's the thing - the way MTGForge is right now, simple choice spells are super easy. The hard ones are where a sequence of simple actions are done... if only there was a way to take an existing object's resolve method and "add to it"....MageKing17 wrote:That's really not the way you want to do choice spells. What if you had a spell that said "Destroy target wall. CARDNAME deals 1 damage to target creature. Target creature gains haste"? You couldn't make it do all those things just by using spDestroyTgt, spDamageC, and spPumpTgt. In Incantus, modal spells are handled a bit oddly... since all abilities are declared with the help of decorators, we just add another decorator to the effects block that defines it as modal and lists all the various modes (with each mode's doc text determining what text it displays, and the decorator having a "choose" argument to determine how many modes can be selected). The annoying thing is that "choose one or both" can't be done... instead, we have to add a third mode saying "both", and make sure to put a timestep inbetween each action (because if you choose two modes, each one happens one after the other, not simultaneously).
Frankly, there's probably a way to do this, if the actual code weren't tied directly into the object definitions... so there's one spell object definition, but it could dynamically include code from other methods....
Most mechanics will have some basic implementation and then variants with additional actions. Some mechanics have more variations than others.
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: spPumpTgt - Targeted Pump Spells
by zerker2000 » 26 Jul 2009, 12:35
I think I experimented with something like
- Code: Select all
ArrayList<Command> onResolveCommands
O forest, hold thy wand'ring son
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
- zerker2000
- Programmer
- Posts: 569
- Joined: 09 May 2009, 21:40
- Location: South Pasadena, CA
- Has thanked: 0 time
- Been thanked: 0 time
Re: spPumpTgt - Targeted Pump Spells
by Chris H. » 06 Aug 2009, 12:36
`
spPumpTgt and negative buffs
As a test, I added the following card to cards.txt:
Last Gasp
1 B
Instant
Target creature gets -3/-3 until end of turn.
spPumpTgt:-3/-3
I created a test deck with Last Gasp, Moor Fiend and Mox Jet. I assigned this deck to both the computer and to myself.
I can cast the Last Gasp and kill the computer's Moor Fiend. The spPumpTgt keyword code can handle negative buffs.
The computer will not cast the Last Gasp on it's own Moor Fiend or on my Moor Fiend. The card just sits unused in the computer's hand as a dead card. I originally suspected that the computer might target it's own creature.
While I have spent a lot of time looking at the source code, most of it is beyond my comprehension. I have seen the messages stating that the code base does not have the framework/hooks that would allow the computer to use these types of spells/abilities to the best effect.
We could add the following cards via keywords:
Afflict
Bewilder
Disorient
Flowstone Strike
Last Gasp
Pull Under
Shrink
and include the names of these cards in the listing of cards that will not be included in randomly constructed decks for the computer. This is the best compromise that I can come up with at this time.
spPumpTgt and negative buffs
As a test, I added the following card to cards.txt:
Last Gasp
1 B
Instant
Target creature gets -3/-3 until end of turn.
spPumpTgt:-3/-3
I created a test deck with Last Gasp, Moor Fiend and Mox Jet. I assigned this deck to both the computer and to myself.
I can cast the Last Gasp and kill the computer's Moor Fiend. The spPumpTgt keyword code can handle negative buffs.
The computer will not cast the Last Gasp on it's own Moor Fiend or on my Moor Fiend. The card just sits unused in the computer's hand as a dead card. I originally suspected that the computer might target it's own creature.
While I have spent a lot of time looking at the source code, most of it is beyond my comprehension. I have seen the messages stating that the code base does not have the framework/hooks that would allow the computer to use these types of spells/abilities to the best effect.
We could add the following cards via keywords:
Afflict
Bewilder
Disorient
Flowstone Strike
Last Gasp
Pull Under
Shrink
and include the names of these cards in the listing of cards that will not be included in randomly constructed decks for the computer. This is the best compromise that I can come up with at this time.
-
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: spPumpTgt - Targeted Pump Spells
by Rob Cashwalker » 06 Aug 2009, 16:53
The basic pump code works fine for negative values for the human. But the AI doesn't know what to do with it.
The AI could be tweaked to just take a look at the numbers and choose a human creature accordingly. However, I see one reason not to do this: there is almost no point to applying a negative attack value, since the computer can't do it on the human's turn. Only if it's a negative defense value would it be useful right now. Because of this, I'd rather give the ability a new name, not "pump". Maybe take a page from M10 - Degrade.
The AI could be tweaked to just take a look at the numbers and choose a human creature accordingly. However, I see one reason not to do this: there is almost no point to applying a negative attack value, since the computer can't do it on the human's turn. Only if it's a negative defense value would it be useful right now. Because of this, I'd rather give the ability a new name, not "pump". Maybe take a page from M10 - Degrade.
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: spPumpTgt - Targeted Pump Spells
by Chris H. » 07 Aug 2009, 00:11
Thank you Rob for the explanation. We can hold off of adding the negative value power pumps for this moment.
On a related note, I tested a deck with Giant Growth and the computer will not cast it on it's own Kird Ape.
It appears that the spPumpTgt keyword creates a dead card that the computer can not play, whether or not the Power buff/boost is negative or positive.

On a related note, I tested a deck with Giant Growth and the computer will not cast it on it's own Kird Ape.
It appears that the spPumpTgt keyword creates a dead card that the computer can not play, whether or not the Power buff/boost is negative or positive.

-
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: spPumpTgt - Targeted Pump Spells
by mtgrares » 07 Aug 2009, 17:29
I don't know about the spPumpTgt directly but the computer plays cards if SpellAbility.canPlay() returns true and if SpellAbility.canPlayAI() returns true. More than likely your problem is somewhere in there.It appears that the spPumpTgt keyword creates a dead card that the computer can not play, whether or not the Power buff/boost is negative or positive
- mtgrares
- DEVELOPER
- Posts: 1352
- Joined: 08 Sep 2008, 22:10
- Has thanked: 3 times
- Been thanked: 12 times
20 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: Edwardfab and 36 guests