abPump[Tgt] Keyword
Post MTG Forge Related Programming Questions Here
	Moderators: timmermac, Agetian, friarsol, Blacksmith, KrazyTheFox, CCGHQ Admins
			25 posts
			 • Page 1 of 2 • 1, 2
		
	
abPump[Tgt] Keyword
 by Rob Cashwalker » 15 Dec 2009, 04:44
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
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:
- Code: Select all
- Mahamoti Djinn : Stormcloud Djinn
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
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
by DennisBergkamp » 16 Dec 2009, 20:58 
Great stuff Rob, thanks  I'll merge this code manually.
 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.
			
		 I'll merge this code manually.
 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.
- 
				 
 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
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
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
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
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
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
Re: abPump[Tgt] Keyword
 by Rob Cashwalker » 22 Dec 2009, 03:29
by Rob Cashwalker » 22 Dec 2009, 03:29 
Aha!
Viridian Lorebearers was missing its p/t line. It has nothing to do with abPumpTgt.
			Viridian Lorebearers was missing its p/t line. It has nothing to do with abPumpTgt.
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
- 
				 
 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
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
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
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
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 48 guests
