abPump[Tgt] Keyword
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
25 posts
• Page 1 of 2 • 1, 2
abPump[Tgt] Keyword
by Rob Cashwalker » 15 Dec 2009, 04:44
New keyword technology has now been applied to the pump ability keyword.
Primarily, there's no separation of Keyword, Power/Toughness or Power/Toughness/Keyword pumps. They're all "abPump", and "abPumpTgt" if it's targeted. The keyword will differentiate based on the parameters.
Power and Toughness may be calculated using Count$, but with one caveat: Count$ takes a math parameter, which uses a "/" delimiter. Which would obviously cause issue as the power/toughness is delimited by "/". Luckilly, based on my research, of all current cards, there are no cards with pump boosts that included math.
Just in case, I added a replace function such that "\" will be become "/" before being passed to Count$ (CardFactoryUtil.xCount).
I added "UntapTgt" as a drawback effect. This supports Seedcradle Witch.
There are a number of abilities that include discard and sacrifice as costs. I haven't given much thought to working on those, but it may become useful at some point. I'm guessing it should be done as a variant of the SpellAbility class.
There are a number of abilities that include sacrificing the host or target at the end of turn as a drawback, and I would like to add that at some point.
Syntax:
abPump[Tgt] {mana/tap cost}:[power]/[toughness]/[keyword]:[Drawback|spDescription]:[spDescription|stDescription]:[stDescription]
Power and Toughness are optional, and may be the result of Count$ (CardPower and CardToughness added).
Keyword is optional.
A pump may be just a keyword, a p/t or a p/t/k, the code is smart enough.
Drawback$ now includes "UntapTgt".
If the ability is complex - uses Count$ or has a Drawback$, the spell and stack descriptions need to be included.
In addition to testing a few of the existing pump ability cards, I added these and tested them:
For some reason, Whenever I had Stormcloud Djinn in my deck, Forge turned it into Mahamoti Djinn. Load it back into deck editor, and I couldn't add Stormcloud Djin,, it kept turning into Mahamoti's, and I can't imagine how. Maybe it doesn't want me to play crap rares?
Somewhere along the way, too much in CardFactory changed. So when I tried to update my local copy, it came up with hundreds of errors, probably a mis-matched {} somewhere. I'm not confidant that the SVN commit would work. So, this update will have to be done purely by the code I post here.
CardFactory
CardFactoryUtil.doDrawBack
CardFactoryUtil.xCount
Primarily, there's no separation of Keyword, Power/Toughness or Power/Toughness/Keyword pumps. They're all "abPump", and "abPumpTgt" if it's targeted. The keyword will differentiate based on the parameters.
Power and Toughness may be calculated using Count$, but with one caveat: Count$ takes a math parameter, which uses a "/" delimiter. Which would obviously cause issue as the power/toughness is delimited by "/". Luckilly, based on my research, of all current cards, there are no cards with pump boosts that included math.
Just in case, I added a replace function such that "\" will be become "/" before being passed to Count$ (CardFactoryUtil.xCount).
I added "UntapTgt" as a drawback effect. This supports Seedcradle Witch.
There are a number of abilities that include discard and sacrifice as costs. I haven't given much thought to working on those, but it may become useful at some point. I'm guessing it should be done as a variant of the SpellAbility class.
There are a number of abilities that include sacrificing the host or target at the end of turn as a drawback, and I would like to add that at some point.
Syntax:
abPump[Tgt] {mana/tap cost}:[power]/[toughness]/[keyword]:[Drawback|spDescription]:[spDescription|stDescription]:[stDescription]
Power and Toughness are optional, and may be the result of Count$ (CardPower and CardToughness added).
Keyword is optional.
A pump may be just a keyword, a p/t or a p/t/k, the code is smart enough.
Drawback$ now includes "UntapTgt".
If the ability is complex - uses Count$ or has a Drawback$, the spell and stack descriptions need to be included.
In addition to testing a few of the existing pump ability cards, I added these and tested them:
- Code: Select all
Auriok Bladewarden
1 W
Creature Human Soldier
no text
1/1
abPumpTgt T:Count$CardPower/Count$CardPower:Target creature get +X/+X until end of turn, where X is Auriok Bladewarden's power.
Boreal Centaur
1 G
Snow Creature Centaur Warrior
Play this ability only once each turn.
2/2
abPump S:+1/+1
- Code: Select all
Chameleon Colossus
2 G G
Creature Shapeshifter
no text
Changeling
Protextion from black
abPump 2 G G:Count$CardPower/Count$CardPower:Chameleon Colossus gets +X/+X until end of turn, where X is its power.
- Code: Select all
Feral Animist
1 R G
Creature Goblic Shaman
no text
2/1
abPump 3:Count$CardPower/+0:Feral Animist gets +X/+0 until end of turn, where X is its power.
Fire-Belly Changeling
1 R
Creature Shapeshifter
Play this ability no more than twice each turn.
1/1
abPump R:+1/+0
Kitsune Loreweaver
1 W
Creature Fox Cleric
no text
2/1
abPump 1 W:+0/Count$NumCardsInYourHand:Kitsune Loreweaver get +0/+X until end of turn, where X is the number of cards in your hand.
Knight of the Skyward Eye
1 W
Creature Human Knight
Play this ability only once each turn.
2/2
abPump 3 G:+3/+3
Power Armor
4
Artifact
Domain
abPumpTgt 3 T:Count$Domain/Count$Domain:Target creature gets +1/+1 until end of turn for each basic land type among lands you control.
Seedcradle Witch
GW
Creature Elf Shaman
no text
1/1
abPumpTgt 2 G W:+3/+3:Drawback$UntapTgt:Target creature gets +3/+3 until end of turn. Untap that creature.
Stormcloud Djinn
4 U
Creature Djinn
no text
3/3
Flying
This creature can block only creatures with flying.
abPump R R:+2/+0:Drawback$DamageYou/1:Stormcloud Djinn gets +2/+0 until end of turn and deals 1 damage to you.
Timberwatch Elf
2 G
Creature Elf
no text
1/2
abPumpTgt T:Count$TypeOnBattlefield.Elf/Count$TypeOnBattlefield.Elf:Target creature get +X/+X until end of turn, where X is the number of Elves on the battlefield.
Viridian Lorebearers
3 G
Creature Elf Shaman
no text
apPumpTgt 3 G T:Count$TypeOppCtrl.Artifact/Count$TypeOppCtrl.Artifact:Target creature gets +X/+X until end of turn, where X is the number of artifacts your opponents control.
Wandering Goblins
2 R
Creature Goblin Warrior
Domain
0/3
abPump 3:Count$Domain/+0:Wandering Goblins gets +1/+0 until end of turn for each basic land type among lands you control.
Rappelling Scouts
2 W W
Creature Human Rebel Scout
no text
1/4
Flying
abPumpTgt 2 W:Protection from white
abPumpTgt 2 W:Protection from blue
abPumpTgt 2 W:Protection from black
abPumpTgt 2 W:Protection from red
abPumpTgt 2 W:Protection from green
Jodah's Avenger
5 U
Creature Shapeshifter
no text
4/4
abPump 0:-1/-1/Double Strike
abPump 0:-1/-1/Protection from red
abPump 0:-1/-1/Vigilance
abPump 0:-1/-1/Shadow
Skarrg, the Rage Pits
no cost
Land
no text
tap: add 1
abPumpTgt R G T:+1/+1/Trample
Wormwood Dryad
2 G
Creature Dryad
no text
3/1
abPump G:Forestwalk:Drawback$DamageYou/1:Wormwood Dryad gains forestwalk until end of turn and deals 1 damage to you.
abPump B:Swampwalk:Drawback$DamageYou/1:Wormwood Dryad gains swampwalk until end of turn and deals 1 damage to you.
Wormwood Treefolk
3 G G
Creature Treefolk
no text
4/4
abPump G G:Forestwalk:Drawback$DamageYou/2:Wormwood Dryad gains forestwalk until end of turn and deals 2 damage to you.
abPump B B:Swampwalk:Drawback$DamageYou/2:Wormwood Dryad gains swampwalk until end of turn and deals 2 damage to you.
For some reason, Whenever I had Stormcloud Djinn in my deck, Forge turned it into Mahamoti Djinn. Load it back into deck editor, and I couldn't add Stormcloud Djin,, it kept turning into Mahamoti's, and I can't imagine how. Maybe it doesn't want me to play crap rares?
Somewhere along the way, too much in CardFactory changed. So when I tried to update my local copy, it came up with hundreds of errors, probably a mis-matched {} somewhere. I'm not confidant that the SVN commit would work. So, this update will have to be done purely by the code I post here.
CardFactory
- Code: Select all
while(hasKeyword(card, "abPump") != -1)
{
int n = hasKeyword(card, "abPump");
if(n != -1)
{
String parse = card.getKeyword().get(n).toString();
card.removeIntrinsicKeyword(parse);
String k[] = parse.split(":");
final boolean Tgt[] = {false};
Tgt[0] = k[0].contains("Tgt");
String tmpCost;
if (Tgt[0])
tmpCost = k[0].substring(9);
else
tmpCost = k[0].substring(6);
boolean tapCost = false;
boolean tapOnlyCost = false;
if (tmpCost.contains("T"))
{
tapCost = true;
tmpCost = tmpCost.replace("T", "");
tmpCost = tmpCost.trim();
if (tmpCost.length() == 0)
tapOnlyCost = true;
}
final String manaCost = tmpCost.trim();
final int NumAttack[] = {-1138};
final String AttackX[] = {"none"};
final int NumDefense[] = {-1138};
final String DefenseX[] = {"none"};
final String Keyword[] = {"none"};
String ptk[] = k[1].split("/");
if (ptk.length == 1)
Keyword[0] = ptk[0];
if (ptk.length >= 2)
{
if (ptk[0].length() <= 3)
NumAttack[0] = Integer.parseInt(ptk[0].replace("+", ""));
else
if (ptk[0].startsWith("Count$"))
{
String kk[] = ptk[0].split("\\$");
AttackX[0] = kk[1].replace("\\", "/");
}
if (ptk[1].length() <= 3)
NumDefense[0] = Integer.parseInt(ptk[1].replace("+", ""));
else
if (ptk[1].startsWith("Count$"))
{
String kk[] = ptk[1].split("\\$");
DefenseX[0] = kk[1].replace("\\", "/");
}
}
if (ptk.length == 3)
Keyword[0] = ptk[2];
final String DrawBack[] = {"none"};
final String spDesc[] = {"none"};
final String stDesc[] = {"none"};
String d = new String("none");
if ((AttackX[0].equals("none") && !(NumAttack[0] == -1138)) && (DefenseX[0].equals("none") && !(NumDefense[0] == -1138)) && Keyword[0].equals("none"))
{
// pt boost
if (Tgt[0] == true)
d = "Target creature gets ";
else
d = cardName + " gets ";
if (NumAttack[0] > 0 || (NumAttack[0] == 0 && NumDefense[0] > 0)) // +0/+1
d = d + "+";
else if (NumAttack[0] < 0 || (NumAttack[0] == 0 && NumDefense[0] < 0)) // -0/-1
d = d + "-";
d = d + Math.abs(NumAttack[0]) + "/";
if (NumDefense[0] > 0 || (NumDefense[0] == 0 && NumAttack[0] > 0)) // +1/+0
d = d + "+";
else if (NumDefense[0] < 0 || (NumDefense[0] == 0 && NumAttack[0] < 0)) // -1/-0
d = d + "-";
d = d + Math.abs(NumDefense[0]) + " until end of turn.";
}
if ((AttackX[0].equals("none") && NumAttack[0] == -1138) && (DefenseX[0].equals("none") && NumDefense[0] == -1138) && !Keyword[0].equals("none"))
{
// k boost
if (Tgt[0] == true)
d = "Target creature gains ";
else
d = cardName + " gains ";
d = d + Keyword[0] + " until end of turn.";
}
if ((AttackX[0].equals("none") && !(NumAttack[0] == -1138)) && (DefenseX[0].equals("none") && !(NumDefense[0] == -1138)) && !Keyword[0].equals("none"))
{
// ptk boost
if (Tgt[0] == true)
d = "Target creature gets ";
else
d = cardName + " gets ";
if (NumAttack[0] > 0 || (NumAttack[0] == 0 && NumDefense[0] > 0)) // +0/+1
d = d + "+";
else if (NumAttack[0] < 0 || (NumAttack[0] == 0 && NumDefense[0] < 0)) // -0/-1
d = d + "-";
d = d + Math.abs(NumAttack[0]) + "/";
if (NumDefense[0] > 0 || (NumDefense[0] == 0 && NumAttack[0] > 0)) // +1/+0
d = d + "+";
else if (NumDefense[0] < 0 || (NumDefense[0] == 0 && NumAttack[0] < 0)) // -1/-0
d = d + "-";
d = d + Math.abs(NumDefense[0]);
d = d + " and gains " + Keyword[0] + " until end of turn.";
}
if (k.length > 2)
{
if (k[2].contains("Drawback$"))
{
String kk[] = k[2].split("\\$");
DrawBack[0] = kk[1];
if (k.length > 3)
d = k[3];
}
else
if (k.length > 2)
d = k[2];
}
if (!d.equals("none"))
{
if (tapOnlyCost == true)
spDesc[0] = "Tap: " + d;
else if (tapCost == true)
spDesc[0] = manaCost + ", tap: " + d;
else
spDesc[0] = manaCost + ": " + d;
stDesc[0] = d;
}
if (! tapCost)
{
final SpellAbility ability = new Ability_Activated(card, manaCost)
{
private static final long serialVersionUID = -1118592153328758083L;
private int defense;
private String keyword;
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;
}
public boolean canPlayAI()
{
defense = getNumDefense();
keyword = Keyword[0];
if (AllZone.Phase.getPhase().equals(Constant.Phase.Main2))
return false;
if (Tgt[0] == false)
{
setTargetCard(card);
if ((card.getNetDefense() + defense > 0) &&
(! card.getKeyword().contains(keyword)))
if (card.hasSickness() && keyword.equals("Haste"))
return true;
else if ((card.hasSickness() && (! keyword.equals("Haste"))) ||
((! card.hasSickness()) && keyword.equals("Haste")))
return false;
else
{
Random r = new Random();
if (r.nextFloat() <= Math.pow(.6667, card.getAbilityUsed()))
return CardFactoryUtil.AI_doesCreatureAttack(card);
}
}
CardList list = getCreatures();
if (!list.isEmpty())
{
boolean goodt = false;
Card t = new Card();
while (goodt == false && !list.isEmpty()) // loop until we find a target that is best and won't die when targeted or until no more creatures
{
t = CardFactoryUtil.AI_getBestCreature(list);
if ((t.getNetDefense() + defense) > 0) // handle negative defense pumps
goodt = true;
else
list.remove(t);
}
if (goodt == true)
{
Random r = new Random();
if (r.nextFloat() <= Math.pow(.6667, card.getAbilityUsed()))
{
setTargetCard(t);
return true;
}
}
}
return false;
}
public boolean canPlay()
{
return (CardFactoryUtil.canUseAbility(card)) &&
(AllZone.GameAction.isCardInPlay(card)) &&
(! card.isFaceDown());
}
private CardList getCreatures()
{
CardList list = new CardList(AllZone.Computer_Play.getCards());
list = list.filter(new CardListFilter()
{
public boolean addCard(Card c)
{
if (c.isCreature())
{
if (c.hasSickness() && keyword.equals("Haste")) // AI_doesCreatureAttack would have prevented the effect from granting haste, because it assumes the creature would already have it
return CardFactoryUtil.canTarget(card, c);
return (CardFactoryUtil.AI_doesCreatureAttack(c)) &&
(CardFactoryUtil.canTarget(card, c)) &&
(!keyword.equals("none") && !c.getKeyword().contains(keyword)) &&
(! (! c.hasSickness()) && keyword.equals("Haste")); // if creature doesn't have sickness, the haste keyword won't help
}
return false;
}
});
// list.remove(card); // if mana-only cost, allow self-target
return list;
}//getCreatures()
public void resolve()
{
if(AllZone.GameAction.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card, getTargetCard()) )
{
final Card[] creature = new Card[1];
if (Tgt[0] == true)
creature[0] = getTargetCard();
else
creature[0] = card;
final int a = getNumAttack();
final int d = getNumDefense();
final Command EOT = new Command()
{
private static final long serialVersionUID = -8840812331316327448L;
public void execute()
{
if(AllZone.GameAction.isCardInPlay(creature[0]))
{
creature[0].addTempAttackBoost(-1 * a);
creature[0].addTempDefenseBoost(-1 * d);
if (! Keyword[0].equals("none"))
creature[0].removeExtrinsicKeyword(Keyword[0]);
}
}
};
creature[0].addTempAttackBoost(a);
creature[0].addTempDefenseBoost(d);
if (! Keyword[0].equals("none"))
creature[0].addExtrinsicKeyword(Keyword[0]);
card.setAbilityUsed(card.getAbilityUsed()+1);
AllZone.EndOfTurn.addUntil(EOT);
if (! DrawBack[0].equals("none"))
CardFactoryUtil.doDrawBack(DrawBack[0], 0, card.getController(), AllZone.GameAction.getOpponent(card.getController()), null, card, creature[0]);
}//if (card is in play)
}//resolve()
};//SpellAbility
ability.setDescription(spDesc[0]);
ability.setStackDescription(stDesc[0]);
if (Tgt[0] == true)
ability.setBeforePayMana(CardFactoryUtil.input_targetCreature(ability));
else
ability.setTargetCard(card);
card.addSpellAbility(ability);
}
if (tapOnlyCost)
{
final SpellAbility ability = new Ability_Tap(card)
{
private static final long serialVersionUID = 5252594757468128739L;
private int defense;
private String keyword;
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;
}
public boolean canPlayAI()
{
defense = getNumDefense();
keyword = Keyword[0];
if(CardFactoryUtil.AI_doesCreatureAttack(card))
return false;
if (AllZone.Phase.getPhase().equals(Constant.Phase.Main2))
return false;
CardList list = getCreatures();
if (!list.isEmpty())
{
boolean goodt = false;
Card t = new Card();
while (goodt == false && !list.isEmpty())
{
t = CardFactoryUtil.AI_getBestCreature(list);
if ((t.getNetDefense() + defense) > 0)
goodt = true;
else
list.remove(t);
}
if (goodt == true)
{
setTargetCard(t);
return true;
}
}
return false;
}
public boolean canPlay()
{
boolean sick = true;
if (!card.hasSickness() || !card.isCreature())
sick = false;
if (card.isUntapped() && AllZone.GameAction.isCardInPlay(card)
&& !sick && !card.isFaceDown())
return true;
else
return false;
}
CardList getCreatures()
{
CardList list = new CardList(AllZone.Computer_Play.getCards());
list = list.filter(new CardListFilter()
{
public boolean addCard(Card c)
{
if (c.isCreature())
{
if (c.hasSickness() && keyword.equals("Haste"))
return CardFactoryUtil.canTarget(card, c);
return (CardFactoryUtil.AI_doesCreatureAttack(c)) &&
(CardFactoryUtil.canTarget(card, c)) &&
(!keyword.equals("none") && !c.getKeyword().contains(keyword)) &&
(! (! c.hasSickness()) && keyword.equals("Haste"));
}
return false;
}
});
list.remove(card);
return list;
}//getCreature()
public void resolve()
{
if(AllZone.GameAction.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card, getTargetCard()))
{
final Card[] creature = new Card[1];
if (Tgt[0] == true)
creature[0] = getTargetCard();
else
creature[0] = card;
final int a = getNumAttack();
final int d = getNumDefense();
final Command EOT = new Command()
{
private static final long serialVersionUID = 2134353417588894452L;
public void execute()
{
if(AllZone.GameAction.isCardInPlay(creature[0]))
{
creature[0].addTempAttackBoost(-1 * a);
creature[0].addTempDefenseBoost(-1 * d);
if (! Keyword[0].equals("none"))
creature[0].removeExtrinsicKeyword(Keyword[0]);
}
}
};
creature[0].addTempAttackBoost(a);
creature[0].addTempDefenseBoost(d);
if (! Keyword[0].equals("none"))
creature[0].addExtrinsicKeyword(Keyword[0]);
AllZone.EndOfTurn.addUntil(EOT);
if (! DrawBack[0].equals("none"))
CardFactoryUtil.doDrawBack(DrawBack[0], 0, card.getController(), AllZone.GameAction.getOpponent(card.getController()), null, card, creature[0]);
}//if (card is in play)
}//resolve()
};//SpellAbility
ability.setDescription(spDesc[0]);
ability.setStackDescription(stDesc[0]);
if (Tgt[0] == true)
ability.setBeforePayMana(CardFactoryUtil.input_targetCreature(ability));
else
ability.setTargetCard(card);
card.addSpellAbility(ability);
}
if (! tapOnlyCost && tapCost)
{
final SpellAbility ability = new Ability_Tap(card, manaCost)
{
private static final long serialVersionUID = 7593387152288440603L;
private int defense;
private String keyword;
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;
}
public boolean canPlayAI()
{
defense = getNumDefense();
keyword = Keyword[0];
if(CardFactoryUtil.AI_doesCreatureAttack(card))
return false;
if (AllZone.Phase.getPhase().equals(Constant.Phase.Main2))
return false;
CardList list = getCreatures();
if (!list.isEmpty())
{
boolean goodt = false;
Card t = new Card();
while (goodt == false && !list.isEmpty())
{
t = CardFactoryUtil.AI_getBestCreature(list);
if ((t.getNetDefense() + defense) > 0)
goodt = true;
else
list.remove(t);
}
if (goodt == true)
{
setTargetCard(t);
return true;
}
}
return false;
}
public boolean canPlay()
{
boolean sick = true;
if (!card.hasSickness() || !card.isCreature())
sick = false;
if (card.isUntapped() && AllZone.GameAction.isCardInPlay(card) &&
!sick && !card.isFaceDown())
return true;
else
return false;
}
CardList getCreatures()
{
CardList list = new CardList(AllZone.Computer_Play.getCards());
list = list.filter(new CardListFilter()
{
public boolean addCard(Card c)
{
if (c.hasSickness() && keyword.equals("Hsste"))
return CardFactoryUtil.canTarget(card, c);
return (CardFactoryUtil.AI_doesCreatureAttack(c)) &&
(CardFactoryUtil.canTarget(card, c)) &&
(!keyword.equals("none") && !c.getKeyword().contains(keyword)) &&
(! (! c.hasSickness()) && keyword.equals("Haste"));
}
});
list.remove(card);
return list;
}//getCreature()
public void resolve()
{
if(AllZone.GameAction.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card ,getTargetCard()))
{
final Card[] creature = new Card[1];
if (Tgt[0] == true)
creature[0] = getTargetCard();
else
creature[0] = card;
final int a = getNumAttack();
final int d = getNumDefense();
final Command EOT = new Command()
{
private static final long serialVersionUID = 3532917180149273560L;
public void execute()
{
if(AllZone.GameAction.isCardInPlay(creature[0]))
{
creature[0].addTempAttackBoost(-1 * a);
creature[0].addTempDefenseBoost(-1 * d);
if (! Keyword[0].equals("none"))
creature[0].removeExtrinsicKeyword(Keyword[0]);
}
}
};
creature[0].addTempAttackBoost(a);
creature[0].addTempDefenseBoost(d);
if (! Keyword[0].equals("none"))
creature[0].addExtrinsicKeyword(Keyword[0]);
AllZone.EndOfTurn.addUntil(EOT);
if (! DrawBack[0].equals("none"))
CardFactoryUtil.doDrawBack(DrawBack[0], 0, card.getController(), AllZone.GameAction.getOpponent(card.getController()), null, card, creature[0]);
}//if (card is in play)
}//resolve()
};//SpellAbility
ability.setDescription(spDesc[0]);
ability.setStackDescription(stDesc[0]);
if (Tgt[0] == true)
ability.setBeforePayMana(CardFactoryUtil.input_targetCreature(ability));
else
ability.setTargetCard(card);
card.addSpellAbility(ability);
}
}
}//while
CardFactoryUtil.doDrawBack
- Code: Select all
if (d[0].contains("Draw"))
for (int i=0; i < X; i++)
AllZone.GameAction.drawCard(dbPlayer);
// 11/30/09
if (d[0].contains("UntapTgt"))
TgtC.untap();
if (d[0].contains("GenToken")) // placeholder for effect
X = X + 0;
CardFactoryUtil.xCount
- Code: Select all
// Count$Hellbent.<numHB>.<numNotHB>
if (sq[0].contains("Hellbent"))
if (myHand.size() <= 1)
return doXMath(Integer.parseInt(sq[1]), m); // Hellbent
else
return doXMath(Integer.parseInt(sq[2]), m); // not Hellbent
// 11/30/09
// Count$CardPower
if (sq[0].contains("CardPower"))
return doXMath(c.getNetAttack(), m);
// Count$CardToughness
if (sq[0].contains("CardToughness"))
return doXMath(c.getNetDefense(), m);
//Generic Zone-based counting
// Count$QualityAndZones.Subquality
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: abPump[Tgt] Keyword
by Chris H. » 16 Dec 2009, 19:43
`For some reason, Whenever I had Stormcloud Djinn in my deck, Forge turned it into Mahamoti Djinn. Load it back into deck editor, and I couldn't add Stormcloud Djin,, it kept turning into Mahamoti's, and I can't imagine how. Maybe it doesn't want me to play crap rares?
It looks like the "name-mutator.txt" file has struck again. Notice line 229:
`
I suggest that we delete the contents of this file. Forge looks for a file of this name and will be happy if the file is empty. At some point we may want to delete/comment out the code which performs the name changing in the various java files.
-
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: abPump[Tgt] Keyword
by Rob Cashwalker » 16 Dec 2009, 20:52
Good catch.
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: abPump[Tgt] Keyword
by DennisBergkamp » 16 Dec 2009, 20:58
Great stuff Rob, thanks
I'll merge this code manually.
Yeah, I think it should be safe to empty the contents of name-mutator.txt... I could also try deleting references to the file in the code.

Yeah, I think it should be safe to empty the contents of name-mutator.txt... I could also try deleting references to the file in the code.
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: abPump[Tgt] Keyword
by Chris H. » 16 Dec 2009, 22:49
`DennisBergkamp wrote:Great stuff Rob, thanksI'll merge this code manually.
Yeah, I think it should be safe to empty the contents of name-mutator.txt... I could also try deleting references to the file in the code.
There is a file named "NameChanger.java" which reads the name-mutator.txt file. A small change to the code in NameChanger.java could let us delete the name-mutator.txt file as it would no longer be read.
We may not need to delete the 45 different code sections which refer to this NameChanger code. It is probably beyond my current level of coding skills.
-
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: abPump[Tgt] Keyword
by DennisBergkamp » 21 Dec 2009, 05:05
I'm almost done merging this, having some trouble though with Viridian Lorebearers (even after fixing the apparent misspelled "apPumpTgt").
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: abPump[Tgt] Keyword
by Rob Cashwalker » 21 Dec 2009, 18:09
That's one I guess I let slip through testing.... What's the issue? Not counting correctly?
The only glaring problem I can see from the code is that it would incorrectly count Changelings.
The only glaring problem I can see from the code is that it would incorrectly count Changelings.
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: abPump[Tgt] Keyword
by DennisBergkamp » 21 Dec 2009, 18:28
Dunno, it gives me some number format exception:
- Code: Select all
java.lang.NumberFormatException: For input string: "abPumpTgt 3 G T:Count$TypeOppCtrl.Artifact"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at forge.ReadCard.run(ReadCard.java:92)
at forge.CardFactory.readCards(CardFactory.java:85)
at forge.CardFactory.<init>(CardFactory.java:60)
at forge.AllZone.<clinit>(AllZone.java:21)
at forge.CardFactoryUtil.getCanPlayNumberOfLands(CardFactoryUtil.java:2941)
at forge.ComputerAI_General.<init>(ComputerAI_General.java:12)
at forge.Gui_NewGame.main(Gui_NewGame.java:131)
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: abPump[Tgt] Keyword
by Chris H. » 21 Dec 2009, 18:59
`DennisBergkamp wrote:Anyway, I updated the SVN with the changes (without Viridian Lorebearers - also I didn't comment out PTPump, KPump, PTKPump, abTgtPTPump and TgtKPump yet).
I plan to get on later tonight and will comment out the code for Chameleon Colossus. I will also change Rappelling Scouts from abPumpTgt to abPump.
-
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
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: abPump[Tgt] Keyword
by Rob Cashwalker » 22 Dec 2009, 14:19
Which is more DUH, my missing the p/t in the first place, or my missing it when looking at the code in the morning, but not figuring it out until the night?
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: abPump[Tgt] Keyword
by DennisBergkamp » 22 Dec 2009, 15:27
Wow, I'd say the latter one! I completely missed it too 

-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: abPump[Tgt] Keyword
by Chris H. » 29 Dec 2009, 02:31
I think that I stumbled across a bug in CardFactory.java by accident. The code section in question is the CardList getCreatures() method that is part of the "while(hasKeyword(card, "abPump") != -1)" code.
The bug appears in line 1378 and refers to "Hsste" rather than "Haste".
The bug appears in line 1378 and refers to "Hsste" rather than "Haste".
- Code: Select all
if (c.hasSickness() && keyword.equals("Hsste"))
CardList getCreatures()
{
CardList list = new CardList(AllZone.Computer_Play.getCards());
list = list.filter(new CardListFilter()
{
public boolean addCard(Card c)
{
if (c.hasSickness() && keyword.equals("Hsste"))
return CardFactoryUtil.canTarget(card, c);
return (CardFactoryUtil.AI_doesCreatureAttack(c)) &&
(CardFactoryUtil.canTarget(card, c)) &&
(!keyword.equals("none") && !c.getKeyword().contains(keyword)) &&
(! (! c.hasSickness()) && keyword.equals("Haste"));
}
});
list.remove(card);
return list;
}//getCreature()
-
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: abPump[Tgt] Keyword
by Rob Cashwalker » 29 Dec 2009, 03:58
Another good catch by Chris!
Fixed in SVN.
Fixed in SVN.
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
25 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 20 guests