It is currently 03 Sep 2025, 07:17
   
Text Size

abPump[Tgt] Keyword

Post MTG Forge Related Programming Questions Here

Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins

abPump[Tgt] Keyword

Postby 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:
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.
Note, the explicit card code for the colossus can be commented out.

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.
I changed all previous instances of old Pump keywords in cards.txt to match the new syntax. Jodah's Avenger, Fire-Belly Changeling, Knight of the Skyward Eye, Skarrg, the Rage Pits and Rappelling Scouts weren't already in, but nothing special requiring the new syntax.

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
I also commented out PTPump, KPump, PTKPump, abTgtPTPump and TgtKPump. I have NOT updated spPumpTgt yet.

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;
Obviously, the line commented 11/30/09, "UntapTgt" is the intended change, the other two items aren't changed.

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
Again, the intended change is the CardPower and CardToughness.
The Force will be with you, Always.
User avatar
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

Postby 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.
User avatar
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

Postby Rob Cashwalker » 16 Dec 2009, 20:52

Good catch.
The Force will be with you, Always.
User avatar
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

Postby 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.
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: abPump[Tgt] Keyword

Postby Chris H. » 16 Dec 2009, 22:49

DennisBergkamp wrote: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.
`
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.
User avatar
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

Postby 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").
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: abPump[Tgt] Keyword

Postby 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 Force will be with you, Always.
User avatar
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

Postby 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)
Anyway, I updated the SVN with the changes (without Viridian Lorebearers - also I didn't comment out PTPump, KPump, PTKPump, abTgtPTPump and TgtKPump yet).
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: abPump[Tgt] Keyword

Postby 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.
User avatar
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

Postby Rob Cashwalker » 22 Dec 2009, 03:29

Aha!

Viridian Lorebearers was missing its p/t line. It has nothing to do with abPumpTgt.
The Force will be with you, Always.
User avatar
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

Postby DennisBergkamp » 22 Dec 2009, 04:44

Ah, duh :)
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: abPump[Tgt] Keyword

Postby 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.
User avatar
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

Postby DennisBergkamp » 22 Dec 2009, 15:27

Wow, I'd say the latter one! I completely missed it too :(
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: abPump[Tgt] Keyword

Postby 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".

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()
User avatar
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

Postby Rob Cashwalker » 29 Dec 2009, 03:58

Another good catch by Chris!

Fixed in SVN.
The Force will be with you, Always.
User avatar
Rob Cashwalker
Programmer
 
Posts: 2167
Joined: 09 Sep 2008, 15:09
Location: New York
Has thanked: 5 times
Been thanked: 40 times

Next

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 20 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 20 users online :: 0 registered, 0 hidden and 20 guests (based on users active over the past 10 minutes)
Most users ever online was 7303 on 15 Jul 2025, 20:46

Users browsing this forum: No registered users and 20 guests

Login Form