spAllPump keyword
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
spAllPump keyword
by Rob Cashwalker » 05 Jun 2010, 01:33
My first code submission was a 420 line block that handled a couple dozen multi-creature pump spells. (I wanted to use Overrun and at the time, the closest Forge had was Tromp the Domains) It was a huge assortment of "if's", that provided for all the various spells.
I have now built a keyword handler to perform the same function, plus enables additional spells. (even Titanic Ultimatum can be converted to this keyword)
Basic Syntax:
CardFactory:
CardFactoryUtil.doDrawback:
I have now built a keyword handler to perform the same function, plus enables additional spells. (even Titanic Ultimatum can be converted to this keyword)
Basic Syntax:
- Code: Select all
spAllPump:{All | YouCtrl [/Restrictions]}:p/t/kw's:[Drawback]:spDesc:stDesc
CardFactory:
- Code: Select all
if (hasKeyword(card, "spAllPump") != -1)
{
int n = hasKeyword(card, "spAllPump");
String parse = card.getKeyword().get(n).toString();
card.removeIntrinsicKeyword(parse);
String k[] = parse.split(":");
final String Scope[] = k[1].split("/");
final int NumAttack[] = {-1138};
final String AttackX[] = {"none"};
final int NumDefense[] = {-1138};
final String DefenseX[] = {"none"};
final String Keyword[] = {"none"};
String ptk[] = k[2].split("/");
if (ptk.length == 1)
Keyword[0] = ptk[0];
if (ptk.length >= 2)
{
if (ptk[0].matches("[\\+\\-][XY]"))
{
String xy = card.getSVar(ptk[0].replaceAll("[\\+\\-]", ""));
if (xy.startsWith("Count$"))
{
String kk[] = xy.split("\\$");
AttackX[0] = kk[1];
if (ptk[0].contains("-"))
{
if (AttackX[0].contains("/"))
AttackX[0] = AttackX[0].replace("/", "/Negative");
else
AttackX[0] += "/Negative";
}
}
}
else if (ptk[0].matches("[\\+\\-][0-9]"))
NumAttack[0] = Integer.parseInt(ptk[0].replace("+", ""));
if (ptk[1].matches("[\\+\\-][XY]"))
{
String xy = card.getSVar(ptk[1].replaceAll("[\\+\\-]", ""));
if (xy.startsWith("Count$"))
{
String kk[] = xy.split("\\$");
DefenseX[0] = kk[1];
if (ptk[0].contains("-"))
{
if (DefenseX[0].contains("/"))
DefenseX[0] = DefenseX[0].replace("/", "/Negative");
else
DefenseX[0] += "/Negative";
}
}
}
else if (ptk[1].matches("[\\+\\-][0-9]"))
NumDefense[0] = Integer.parseInt(ptk[1].replace("+", ""));
}
if (ptk.length == 3)
Keyword[0] = ptk[2];
final String DrawBack[] = {"none"};
final String spDesc[] = {"none"};
final String stDesc[] = {"none"};
if (k.length > 3)
{
if (k[3].contains("Drawback$"))
{
String kk[] = k[3].split("\\$");
DrawBack[0] = kk[1];
if (k.length > 4) spDesc[0] = k[4];
if (k.length > 5) stDesc[0] = k[5];
}
else
{
if (k.length > 3) spDesc[0] = k[3];
if (k.length > 4) stDesc[0] = k[4];
}
}
SpellAbility spAllPump = new Spell(card)
{
private static final long serialVersionUID = 837472987492L;
private int getNumAttack() {
if(NumAttack[0] != -1138) return NumAttack[0];
if(!AttackX[0].equals("none")) return CardFactoryUtil.xCount(card, AttackX[0]);
return 0;
}
private int getNumDefense() {
if(NumDefense[0] != -1138) return NumDefense[0];
if(!DefenseX[0].equals("none")) return CardFactoryUtil.xCount(card, DefenseX[0]);
return 0;
}
private int getNumKeyword()
{
if (!Keyword[0].equals("none"))
return Keyword[0].split(" & ").length;
else return 0;
}
private CardList getScopeList()
{
CardList l = new CardList();
if (Scope[0].contains("YouCtrl"))
l.addAll(AllZone.getZone(Constant.Zone.Play, card.getController()).getCards());
if (Scope[0].contains("All")) {
l.addAll(AllZone.getZone(Constant.Zone.Play, Constant.Player.Human).getCards());
l.addAll(AllZone.getZone(Constant.Zone.Play, Constant.Player.Computer).getCards());
}
String fc[] = {"Creature"};
l = l.getValidCards(fc);
if (Scope.length > 1)
{
String v = Scope[1];
if (v.length() > 0)
l = l.getValidCards(v.split(","));
}
return l;
}
public boolean canPlayAI()
{
System.out.println("Phase - " + AllZone.Phase.getPhase());
String curPhase = AllZone.Phase.getPhase();
if (curPhase.equals(Constant.Phase.Main2))
return false;
CardList sl = getScopeList();
int NumScope = sl.size();
int defense = getNumDefense();
int attack = getNumAttack();
int key = getNumKeyword();
int th = (attack + defense + key) / 2; // Benefit Threshold
if (NumScope > th) // have enough creatures in play
{
Combat c = ComputerUtil.getAttackers();
if (c.getAttackers().length >= th) // have enough creatures that will attack
{
int ndead = 0;
for (int i=0; i<sl.size(); i++) // check to see if this will kill any creatures
if ((sl.get(i).getNetDefense() + defense) < 1)
ndead++;
if (!(ndead > (sl.size() / 2))) // don't kill more than half of the creatures
return true;
}
}
return false;
}
public void resolve()
{
final int attack = getNumAttack();
final int defense = getNumDefense();
final CardList sl = getScopeList();
System.out.println("Phase - " + AllZone.Phase.getPhase());
final Command untilEOT = new Command()
{
private static final long serialVersionUID = 92848209484928L;
public void execute()
{
for (int i=0; i<sl.size(); i++)
{
Card c = sl.get(i);
if (AllZone.GameAction.isCardInPlay(c))
{
c.addTempAttackBoost(-attack);
c.addTempDefenseBoost(-defense);
if (!Keyword[0].equals("none"))
{
String kws[] = Keyword[0].split(" & ");
for (int j=0; j<kws.length; j++)
c.removeExtrinsicKeyword(kws[j]);
}
}
}
}
}; // untilEOT command
for (int i=0; i<sl.size(); i++)
{
Card c = sl.get(i);
if (AllZone.GameAction.isCardInPlay(c))
{
c.addTempAttackBoost(attack);
c.addTempDefenseBoost(defense);
if (!Keyword[0].equals("none"))
{
String kws[] = Keyword[0].split(" & ");
for (int j=0; j<kws.length; j++)
c.addExtrinsicKeyword(kws[j]);
}
}
}
AllZone.EndOfTurn.addUntil(untilEOT);
if (!DrawBack[0].equals("none"))
CardFactoryUtil.doDrawBack(DrawBack[0], 0, card.getController(), AllZone.GameAction.getOpponent(card.getController()), card.getController(), card, card);
} // resolve
}; // spAllPump
spAllPump.setDescription(spDesc[0]);
spAllPump.setStackDescription(stDesc[0]);
card.clearSpellAbility();
card.addSpellAbility(spAllPump);
card.setSVar("PlayMain1", "TRUE");
String bbCost = card.getSVar("Buyback");
if (!bbCost.equals(""))
{
SpellAbility bbAllPump = spAllPump.copy();
bbAllPump.setManaCost(CardUtil.addManaCosts(card.getManaCost(), bbCost));
bbAllPump.setDescription("Buyback " + bbCost + "(You may pay an additional " + bbCost + " as you cast this spell. If you do, put this card into your hand as it resolves.)");
bbAllPump.setIsBuyBackAbility(true);
card.addSpellAbility(bbAllPump);
}
}
CardFactoryUtil.doDrawback:
- Code: Select all
if(d[0].contains("UntapAll")) // 6/10
{
CardList ut = new CardList();
if (d[0].contains("YouCtrl"))
ut.addAll(AllZone.getZone(Constant.Zone.Play, dbPlayer).getCards());
else if (d[0].contains("OppCtrl"))
ut.addAll(AllZone.getZone(Constant.Zone.Play, Opp).getCards());
else
{
ut.addAll(AllZone.getZone(Constant.Zone.Play, dbPlayer).getCards());
ut.addAll(AllZone.getZone(Constant.Zone.Play, Opp).getCards());
}
if (d[0].contains("Type"))
{
String dd[] = d[0].split("\\.");
ut = ut.getValidCards(dd);
}
for (int i=0; i<ut.size(); i++)
ut.get(i).untap();
}
- Code: Select all
Call to Glory
1 W
Instant
no text
spAllPump:YouCtrl/Samurai:+1/+1:Drawback$UntapAllTypeYouCtrl.Creature:Untap all creatures you control. Samurai creatures get +1/+1 until end of turn.:Call to Glory - Untap all creatures you control; Samurai get +1/+1 until EOT
Chorus of Woe
B
Sorcery
no text
spAllPump:YouCtrl:+1/+0:Creatures you control get +1/+0 until end of turn.:Chorus of Woe - Creatures get +1/+0 until EOT
Dance of Shadows
3 B B
Sorcery Arcane
no text
spAllPump:YouCtrl:+1/+0/Fear:Creatures you control get +1/+0 and gain fear until end of turn.:Dance of Shadows - Creatures get +1/+0 and gain fear until EOT
Desperate Charge
2 B
Sorcery
no text
spAllPump:YouCtrl:+2/+0:Creatures you control get +2/+0 until end of turn.:Desperate Charge - Creatures get +2/+0 until EOT
Flowstone Slide
X 2 R R
Sorcery
no text
spAllPump:All:+X/-X:All Creatures get +X/-X until end of turn.:Flowstone Slide - All creatures get +X/-X until EOT
SVar:X:Count$xPaid
Gleam of Resistance
4 W
Instant
no text
spAllPump:YouCtrl:+1/+2:Drawback$UntapAllTypeYouCtrl.Creature:Creatures you control get +1/+2 until end of turn. Untap those creatures.:Gleam of Resistance - Creatures get +1/+2 until EOT; untap those creatures
TypeCycling:Basic:1 W
Glorious Charge
1 W
Instant
no text
spAllPump:YouCtrl:+1/+1:Creatures you control get +1/+1 unti end of turn.:Glorious Charge - Creatures get +1/+1 until EOT
Haze of Rage
1 R
Sorcery
no text
spAllPump:YouCtrl:+1/+0:Creatures you control get +1/+0 until end of turn.:Haze of Rage - Creatures get +1/+0 until EOT
SVar:Buyback:2
Storm
Kjeldoran War Cry
1 W
Instant
no text
spAllPump:YouCtrl:+X/+X:Creatures you control get +X/+X until end of turn, where X is 1 plus the number of cards named Kjeldoran War Cry in all graveyards.:Kjeldoran War Cry - Creatures get +X/+X until EOT
SVar:X:Count$NamedInAllYards.Kjeldoran War Cry/Plus.1
Magnify
G
Instant
no text
spAllPump:All:+1/+1:All creatures get +1/+1 until end of turn.:Magnify - Creatures get +1/+1 until EOT
Nocturnal Raid
2 B B
Instant
no text
spAllPump:All/Black:+2/+0:Black creatures get +2/+0 until end of turn.:Nocturnal Raid - Black creatures get +2/+0 until EOT
Overrun
2 G G G
Sorcery
no text
spAllPump:YouCtrl:+3/+3/Trample:Creatures you control get +3/+3 and gain trample until end of turn.:Overrun - Creatures you control get +3/+3 and gain trample until EOT
Path of Anger's Flame
2 R
Instant - Arcane
no text
spAllPump:YouCtrl:+2/+0:Creatures you control get +2/+0 until end of turn.:Path of Anger's Flame - Creatures get +2/+0 until EOT
Righteous Charge
1 W W
Sorcery
no text
spAllPump:YouCtrl:+2/+2:Creatures you control get +2/+2 until end of turn.:Righteous Charge - Creatures get +2/+2 until EOT
Scare Tactics
B
Instant
no text
spAllPump:YouCtrl:+1/+0:Creatures you control get +1/+0 until end of turn.:Scare Tactics - Creatures get +1/+0 until EOT
Shield Wall
1 W
Instant
no text
spAllPump:YouCtrl:+0/+2:Creatures you control get +0/+2 until end of turn.:Shield Wall - Creatures get +0/+2 until EOT
Solidarity
3 W
Instant
no text
spAllPump:YouCtrl:+0/+5:Creatures you control get +0/+5 until end of turn.:Solidarity - Creatures get +0/+5 until EOT
Steadfastness
1 W
Sorcery
no text
spAllPump:YouCtrl:+0/+3:Creatures you control get +0/+3 until end of turn.:Steadfastness - Creatures get +0/+3 until EOT
Titanic Ultimatum
R R G G G W W
Sorcery
no text
spAllPump:YouCtrl:+5/+5/First Strike & Lifelink & Trample:Until end of turn, creatures you control get +5/+5 and gain first strike, lifelink and trample.:Titanic Ultimatum - Creatures get +5/+5 and gain first strike, lifelink and trample until EOT
Tromp the Domains
5 G
Sorcery
no text
spAllPump:YouCtrl:+X/+X/Trample:Domain - Until end of turn, creatures you control gain trample and get +1/+1 for each basic land type among lands you control.:Tromp the Domains - Creatures get +X/+X and gain trample until EOT
SVar:X:Count$Domain
Valorus Charge
1 W W
Sorcery
no text
spAllPump:All/White:+2/+0:White creatures get +1/+0 until end of turn.:Valorus Charge - Creatures get +1/+0 until EOT
Violent Outburst
1 R G
Instant
no text
spAllPump:YouCtrl:+1/+0:Creatures you control get +1/+0 until end of turn.:Violent Outburst - Creatures get +1/+0 until EOT
Cascade
Virtuous Charge
2 W
Sorcery
no text
spAllPump:YouCtrl:+1/+1:Creatures you control get +1/+1 until end of turn.:Virtuous Charge - Creatures get +1/+1 until EOT
Vitalizing Wind
8 G
Instant
no text
spAllPump:YouCtrl:+7/+7:Creatures you control get +7/+7 until end of turn.:Vitalizing Wind - Creatures get +7/+7 until EOT
Warrior's Charge
2 W
Sorcery
no text
spAllPump:YouCtrl:+1/+1:Creatures you control get +1/+1 until end of turn.:Warrior's Charge - Creatures get +1/+1 until EOT
Warrior's Honor
2 W
Instant
no text
spAllPump:YouCtrl:+1/+1:Creatures you control get +1/+1 until end of turn.:Warrior's Honor - Creatures get +1/+1 until EOT
Burst of Speed
R
Sorcery
no text
spAllPump:YouCtrl:Haste:Creatures you control gain haste until end of turn.:Burst of Speed - Creatures gain haste until EOT
Crossbow Ambush
G
Instant
no text
spAllPump:YouCtrl:Reach:Creatures you control gain reach until end of turn.:Crossbow Ambush - Creatures gain reach until EOT
Magnetic Flux
2 U
Instant
no text
spAllPump:YouCtrl/Artifact:Flying:Artifact creatures you control gain flying until end of turn.:Magnetic Flux - Creatures gain flying until EOT
Nature's Cloak
2 G
Sorcery
no text
spAllPump:YouCtrl/Green:Forestwalk:Green creatures you control gain forestwalk until end of turn.:Nature's Cloak - Creatures gain forestwalk until EOT
Tortoise Formation
3 U
Instant
no text
spAllPump:YouCtrl:Shroud:Creatures you control gain shroud until end of turn.:Tortoise Formation - Creatures gain shroud until EOT
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: spAllPump keyword
by Chris H. » 05 Jun 2010, 15:53
Thank you Rob.
In a quick test I thought that I saw Flowstone Slide giving my creatures +X/+X rather than +X/-X until end of turn. I cast it with several small and cheap creatures in play and I expected this spell to kill my creatures.
In a quick test I thought that I saw Flowstone Slide giving my creatures +X/+X rather than +X/-X until end of turn. I cast it with several small and cheap creatures in play and I expected this spell to kill my creatures.
-
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: spAllPump keyword
by Chris H. » 05 Jun 2010, 17:54
OK, four of these cards are new and do not require commenting out a block of code. Haze of Rage and Titanic Ultimatum are individual code blocks and these can be easily commented out.
The rest of your list come from a large code block of spells which appear right below the links to different CardFactories. This code block is fairly long and complicated.
There are five spells included in this code block which are not in your list. Four of these cards are keyword buffs with no P/T buff. Can your keyword handle these four spells?:
Brave the Elements
Burst of Speed
Nature's Cloak
Tortoise Formation
There is one last spell in this block that could be un-keywordable and I guess that the small amount of code for this one card would have to be placed in it's own separate code block. This card is:
Resuscitate
Hmmm, just ran a test with this card and the current code and the regenerateMe is displayed but you can not activate the ability. After looking at the code I expected that this ability would not be active.
Well, if the four cards above can be handled by your keyword, then we can convert these to keyword and I can give Resuscitate a note stating that this card does not work. The large code block can then be commented out and we will not need to edit this code section.
The rest of your list come from a large code block of spells which appear right below the links to different CardFactories. This code block is fairly long and complicated.
There are five spells included in this code block which are not in your list. Four of these cards are keyword buffs with no P/T buff. Can your keyword handle these four spells?:
Brave the Elements
Burst of Speed
Nature's Cloak
Tortoise Formation
There is one last spell in this block that could be un-keywordable and I guess that the small amount of code for this one card would have to be placed in it's own separate code block. This card is:
Resuscitate
Hmmm, just ran a test with this card and the current code and the regenerateMe is displayed but you can not activate the ability. After looking at the code I expected that this ability would not be active.
Well, if the four cards above can be handled by your keyword, then we can convert these to keyword and I can give Resuscitate a note stating that this card does not work. The large code block can then be commented out and we will not need to edit this code section.
-
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: spAllPump keyword
by Rob Cashwalker » 05 Jun 2010, 22:44
If Flowstone Slide isn't working, it might just be a typo.
Brave the Elements is not one of my original cards for that section it would need to become its own code. Burst of Speed, Nature's Cloak and Tortoise Formation are on the list I put up.
Resuscitate would need to be its own code, there's no easy way to just dynamically add regenerate by keyword. At least not yet, it's one of those things that we keep dreaming about - a keyword factory....
Brave the Elements is not one of my original cards for that section it would need to become its own code. Burst of Speed, Nature's Cloak and Tortoise Formation are on the list I put up.
Resuscitate would need to be its own code, there's no easy way to just dynamically add regenerate by keyword. At least not yet, it's one of those things that we keep dreaming about - a keyword factory....
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: spAllPump keyword
by Rob Cashwalker » 07 Jun 2010, 04:16
Yep, it was a typo in the code:
I fixed and committed the change.
- Code: Select all
DefenseX[0] = kk[1];
if (ptk[0].contains("-"))
{
if (DefenseX[0].contains("/"))
I fixed and committed the change.
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: spAllPump keyword
by Chris H. » 07 Jun 2010, 10:22
Thank you Rob. I noticed something strange about Path of Anger's Flame and Kjeldoran War Cry. These card's spell description is not being displayed in the card detail panel. The cards.txt entries look OK and these spells will give a boost when cast.
-
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: spAllPump keyword
by Rob Cashwalker » 07 Jun 2010, 13:44
Maybe they have some original code hidden somewhere?
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: spAllPump keyword
by Chris H. » 07 Jun 2010, 15:02
`Rob Cashwalker wrote:Maybe they have some original code hidden somewhere?
Yep, that explains it ... both of these cards also have a separate card object farther down in CardFactory. Time to pull out the mop and bucket from the broom closet again.
-
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: spAllPump keyword
by slapshot5 » 12 Oct 2010, 04:02
In trying to add Holy Light, I used the following keyword:
-slapshot5
- Code: Select all
K:spAllPump:All/nonWhite:-1/-1:Nonwhite creatures get -1/-1 until end of turn.:Holy Light - nonwhite creatures get -1/-1 until EOT.
- Code: Select all
K:spAllPump:All.nonWhite:-1/-1:Nonwhite creatures get -1/-1 until end of turn.:Holy Light - nonwhite creatures get -1/-1 until EOT.
-slapshot5
- slapshot5
- Programmer
- Posts: 1391
- Joined: 03 Jan 2010, 17:47
- Location: Mac OS X
- Has thanked: 25 times
- Been thanked: 68 times
Re: spAllPump keyword
by Sloth » 12 Oct 2010, 05:34
If I'm reading the parser correctly Nocturnal Raid is also wrong and it should be:slapshot5 wrote:In trying to add Holy Light, I used the following keyword:This was based upon Nocturnal Raid, given above. However, I had to change All/nonWhite to All.nonWhite for it to work as expected.
- Code: Select all
K:spAllPump:All/nonWhite:-1/-1:Nonwhite creatures get -1/-1 until end of turn.:Holy Light - nonwhite creatures get -1/-1 until EOT.
Is this expected, or is the parsing wrong?
- Code: Select all
K:spAllPump:All.nonWhite:-1/-1:Nonwhite creatures get -1/-1 until end of turn.:Holy Light - nonwhite creatures get -1/-1 until EOT.
-slapshot5
- Code: Select all
K:spAllPump:All/Creature.nonWhite:-1/-1:Nonwhite creatures get -1/-1 until end of turn.:Holy Light - nonwhite creatures get -1/-1 until EOT.
Remember though, that the AI can't handle negative spAllPump spells at the moment. Maybe a Curse option can be written?
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
10 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 47 guests