Page 7 of 15

Re: Programming a card

PostPosted: 26 Oct 2009, 13:56
by cyclope
If Dennis could explain me how he will fix the bug with the Lieges card , i'm found of explainations...

I've tried to code two other cards:
Grixis Battlemage:
Code: Select all
Grixis Battlemage

//*************** START *********** START **************************
if (cardName.equals("Grixis Battlemage")
    {
   
   final SpellAbility ability = new Ability_Tap(card, "U")
        {

         private static final long serialVersionUID = ;
         public boolean canPlayAI() {return false;}
        public void resolve()
        {
          AllZone.GameAction.drawCard(card.getController());
          AllZone.InputControl.setInput(CardFactoryUtil.input_discard());
        }
      };//SpellAbility
      card.addSpellAbility(ability);
      ability.setDescription("U ,tap: Draw a card, then discard a card.");
      ability.setStackDescription("Grixis Battlemage - draw a card, then discard a card.");
     
    }//*************** END ************ END **************************

and in cards.txt
Grixis Battlemage
2 B
Creature Human Wizard
U, tap : draw a card then discard a card. R, tap: target creature can't block this turn.
2/2
TgtKpump R T: This creature cannot block
but i'm not sure the AI can target a creature with TgtKpump keyword...

Jund Battlemage:
Code: Select all
//*************** START *********** START **************************
if (cardName.equals("Jund Battlemage")
    {
       final SpellAbility ability = new Ability_Tap(card, "G")
        {

         private static final long serialVersionUID = ;
        public void resolve()
          {
            Card c = new Card();
            c.setName("Saproling");
            c.setImageName("G 1 1 Saproling");

            c.setOwner(card.getController());
            c.setController(card.getController());

            c.setManaCost("G");
            c.setToken(true);

            c.addType("Creature");
            c.addType("Saproling");

            c.setBaseAttack(1);
            c.setBaseDefense(1);

            PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController());
            play.add(c);
          }//resolve()
        };


   final SpellAbility ability2 = new Ability_Tap(card, "B")
        {

         private static final long serialVersionUID = ;
         public void resolve()
         {
          String opponent = AllZone.GameAction.getOpponent(card.getController());
          AllZone.GameAction.getPlayerLife(opponent).subtractLife(1);
        }
        public boolean canPlayAI()
        {
          //computer should play ability if this creature doesn't attack
          Combat c = ComputerUtil.getAttackers();
          CardList list = new CardList(c.getAttackers());

          //could this creature attack?, if attacks, do not use ability
          return (! list.contains(card));
        }
        };//SpellAbility


        card.addSpellAbility(ability);
        ability.setDescription("G , tap: put a 1/1 green Saproling creature token onto battlefield);
   ability.setStackDescription(card.getName() +  " - Put a 1/1 green Saproling token onto the battlefield.");
        ability.setBeforePayMana(CardFactoryUtil.input_targetCreature(ability));
   card.addSpellAbility(ability2);
      ability2.setDescription("B, tap: Target player loses 1 life.");
      ability2.setStackDescription(card.getName() + " - Opponent loses 1 life.");

     }//*************** END ************ END **************************

in cards.txt:
Jund Battlemage
2 R
Creature Human Shaman
B, tap : target player loses 1 life. G, tap: put a 1/1 green Saproling creature token onto battlefield.
2/2
Rep me if i've made some errors...I've made some headways but i don't understand the whole code...

Re: Programming a card

PostPosted: 26 Oct 2009, 15:34
by Chris H.
cyclope wrote:Rep me if i've made some errors... I've made some headways but i don't understand the whole code...
`
I think that you are doing a good job. :) I am also learning Java and Eclipse. I know you have a Macbook. Have you tried Eclipse?

I sometimes have problems creating the

private static final long serialVersionUID =

and I have learned that Eclipse will at times fail to create them properly and I now repeat the process until it works.

Re: Programming a card

PostPosted: 26 Oct 2009, 16:55
by cyclope
Hi Chris , i've only used eclipse to re-compile the source to make an gui that works with my mac for some version of MTG Forge...
I'll try to add longserialversion UID with new cards soon and i'll rep you as soon as i've done it...

Re: Programming a card

PostPosted: 26 Oct 2009, 17:56
by cyclope
Some more cards:
Lightning Talons:
Code: Select all
//*************** START *********** START **************************
if(cardName.equals("Lightning Talons"))
{
  final SpellAbility spell = new Spell(card)
  {

   public boolean canPlayAI()
    {
      CardList list = new CardList(AllZone.Computer_Play.getCards());
      list = list.getType("Creature");

      if(list.isEmpty())
       return false;

      //else
      CardListUtil.sortAttack(list);
      CardListUtil.sortFlying(list);

      for (int i=0;i<list.size();i++) {
         if (CardFactoryUtil.canTarget(card, list.get(i)))
         {
            setTargetCard(list.get(i));
            return true;
         }
      }
      return false;
    }//canPlayAI()
    public void resolve()
    {
      PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController());
      play.add(card);
     
      Card c = getTargetCard();
     
      if(AllZone.GameAction.isCardInPlay(c)  && CardFactoryUtil.canTarget(card, c) )
      {
         card.enchantCard(c);
         System.out.println("Enchanted: " +getTargetCard());
      }
    }//resolve()
  };//SpellAbility
  card.clearSpellAbility();
  card.addSpellAbility(spell);

  Command onEnchant = new Command()
  {   

   public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
      crd.addSemiPermanentAttackBoost(3);
      crd.addExtrinsicKeyword("First Strike");
           
         }
      }//execute()
  };//Command


  Command onUnEnchant = new Command()
  {   

   public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
        crd.addSemiPermanentAttackBoost(-3);
      crd.removeExtrinsicKeyword("First Strike");          

         }
     
      }//execute()
   };//Command
   
   Command onLeavesPlay = new Command()
   {


   public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
            card.unEnchantCard(crd);
         }
      }
   };

  card.setEnchant(onEnchant);
  card.setUnEnchant(onUnEnchant);
  card.setLeavesPlay(onLeavesPlay);

  spell.setBeforePayMana(CardFactoryUtil.input_targetCreature(spell));
}//*************** END ************ END **************************

in card.txt:
Lightning Talons
2 R
Enchantment Aura
Enchanted creature gets +3/+0 and has first strike.
Enchant creature
Despondency:
Code: Select all
//*************** START *********** START **************************
if(cardName.equals("Despondency"))
{
  final SpellAbility spell = new Spell(card)
  {

   private static final long serialVersionUID = ;
   public boolean canPlayAI()
    {
      CardList list = new CardList(AllZone.Human_Play.getCards());
      list = list.getType("Creature");

      if(list.isEmpty())
       return false;

      //else
      CardListUtil.sortAttack(list);
      CardListUtil.sortFlying(list);

      for (int i=0;i<list.size();i++) {
         if (CardFactoryUtil.canTarget(card, list.get(i)))
         {
            setTargetCard(list.get(i));
            return true;
         }
      }
      return false;
    }//canPlayAI()
    public void resolve()
    {
      PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController());
      play.add(card);
     
      Card c = getTargetCard();
     
      if(AllZone.GameAction.isCardInPlay(c)  && CardFactoryUtil.canTarget(card, c) )
      {
         card.enchantCard(c);
         //System.out.println("Enchanted: " +getTargetCard());
      }
    }//resolve()
  };//SpellAbility
  card.clearSpellAbility();
  card.addSpellAbility(spell);
 
  Command onEnchant = new Command()
  {   

   private static final long serialVersionUID = ;

   public void execute()
    {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
            crd.addSemiPermanentAttackBoost(-2);
            
         } 
    }//execute()
  };//Command
 

  Command onUnEnchant = new Command()
  {   

        private static final long serialVersionUID = ;

      public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
            crd.addSemiPermanentAttackBoost(2);               
            
         }
      
      }//execute()
   };//Command
   
   Command onLeavesPlay = new Command()
   {

      private static final long serialVersionUID = ;

      public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
            card.unEnchantCard(crd);
         }
      }
   };
 
  card.addEnchantCommand(onEnchant);
  card.addUnEnchantCommand(onUnEnchant);
  card.addLeavesPlayCommand(onLeavesPlay);
 
  spell.setBeforePayMana(CardFactoryUtil.input_targetCreature(spell));
}//*************** END ************ END **************************

in card.txt:
Despondency
1 B
Enchantment Aura
Enchanted creature gets -2/+0.
When this card is put into a graveyard from the battlefield, return this card to its owner's hand
Enchant creature
Onyx Goblet:
Code: Select all
//*************** START *********** START **************************
    if(cardName.equals("Onyx Goblet"))
    {
      final Ability_Tap ability = new Ability_Tap(card)
      {
      private static final long serialVersionUID =

      public boolean canPlayAI() {return AllZone.Phase.getPhase().equals(Constant.Phase.Main2);}

      public void resolve()
        {
          String opponent = AllZone.GameAction.getOpponent(card.getController());
          AllZone.GameAction.getPlayerLife(opponent).subtractLife(1);
        }
               }
      };//SpellAbility
      card.addSpellAbility(ability);
      ability.setDescription("tap: Target player loses 1 life.");
      ability.setStackDescription(card.getName() + " - Opponent loses 1 life.");
      ability.setBeforePayMana(new Input_NoCost_TapAbility(ability));
    }//*************** END ************ END **************************
Braidwood Cup
Code: Select all
//*************** START *********** START **************************
    if(cardName.equals("Braidwood Cup"))
    {
      final Ability_Tap ability = new Ability_Tap(card)
      {
      private static final long serialVersionUID =

      public boolean canPlayAI() {return AllZone.Phase.getPhase().equals(Constant.Phase.Main2);}

      public void resolve()
        {
          AllZone.GameAction.getPlayerLife(card.getController()).addLife(1);        }
               }
      };//SpellAbility
      card.addSpellAbility(ability);
      ability.setDescription("tap: You gain 1 life.");
      ability.setStackDescription("Braidwood Cup -"+card.getController() + " gains 1 life.");
      ability.setBeforePayMana(new Input_NoCost_TapAbility(ability));
    }//*************** END ************ END **************************

Absolute Grace:
Code: Select all
In GameActionUtil.java:

- in public static void executeCardStateEffects() add : Absolute_Grace.execute();

- after }// executeCardStateEffects() add:

public static Command Absolute_Grace = new Command()
   {
      private static final long serialVersionUID = ;
      
      CardList gloriousAnthemList = new CardList();

      public void execute()
      {
         String keyword = "Protection from black";

         CardList list = gloriousAnthemList;
         Card c;
         // reset all cards in list - aka "old" cards
         for (int i = 0; i < list.size(); i++)
         {
            c = list.get(i);
            c.removeExtrinsicKeyword(keyword);
         }

         list.clear();
         PlayerZone[] zone = getZone("Absolute Grace");

         for (int outer = 0; outer < zone.length; outer++)
         {
            CardList creature = new CardList();
            creature.addAll(AllZone.Human_Play.getCards());
            creature.addAll(AllZone.Computer_Play.getCards());
            creature = creature.getType("Creature");

            for (int i = 0; i < creature.size(); i++)
            {
               c = creature.get(i);
               if (!c.getKeyword().contains(keyword))
               {
                  c.addExtrinsicKeyword(keyword);
                  gloriousAnthemList.add(c);
               }
            }// for inner
         }// for outer
      }// execute()
   };

and in" public static HashMap<String, Command> commands = new HashMap<String, Command>();
   static {" add: commands.put("Absolute_Grace", Absolute_Grace);

and finally in StateBasedEffects.java, after "public void initStateBasedEffectsList()":

cardToEffectsList.put("Absolute Grace", new String[] {"Absolute Grace"});

and in cards.txt:
Absolute Grace
1 W
Enchantment
All creatures gain protection from black.
Absolute Law:
Code: Select all
In GameActionUtil.java:

- in public static void executeCardStateEffects() add : Absolute_Law.execute();

- after }// executeCardStateEffects() add:

public static Command Absolute_Law = new Command()
   {
      private static final long serialVersionUID = ;
      
      CardList gloriousAnthemList = new CardList();

      public void execute()
      {
         String keyword = "Protection from red";

         CardList list = gloriousAnthemList;
         Card c;
         // reset all cards in list - aka "old" cards
         for (int i = 0; i < list.size(); i++)
         {
            c = list.get(i);
            c.removeExtrinsicKeyword(keyword);
         }

         list.clear();
         PlayerZone[] zone = getZone("Absolute Law");

         for (int outer = 0; outer < zone.length; outer++)
         {
            CardList creature = new CardList();
            creature.addAll(AllZone.Human_Play.getCards());
            creature.addAll(AllZone.Computer_Play.getCards());
            creature = creature.getType("Creature");

            for (int i = 0; i < creature.size(); i++)
            {
               c = creature.get(i);
               if (!c.getKeyword().contains(keyword))
               {
                  c.addExtrinsicKeyword(keyword);
                  gloriousAnthemList.add(c);
               }
            }// for inner
         }// for outer
      }// execute()
   };

and in" public static HashMap<String, Command> commands = new HashMap<String, Command>();
   static {" add: commands.put("Absolute_Law", Absolute_Law);

and finally in StateBasedEffects.java, after "public void initStateBasedEffectsList()":

cardToEffectsList.put("Absolute Law", new String[] {"Absolute Law"});

and in cards.txt:
Absolute Law
1 W
Enchantment
All creatures gain protection from red.
Rejuvenate:
Code: Select all
//*************** START *********** START **************************
    if(cardName.equals("Rejuvenate")
    {
      SpellAbility spell = new Spell(card)
      {
      

      public boolean canPlay()
        {
          setStackDescription(card.getName() +" - " +card.getController() +" gains 6 life.");
          return super.canPlay();
        }

        public void resolve()
        {
          PlayerLife life = AllZone.GameAction.getPlayerLife(card.getController());
          life.addLife(6);
        }
      };
      spell.setDescription("You gain 6 life.");

      card.clearSpellAbility();
      card.addSpellAbility(spell);
     
    }//*************** END ************ END **************************

in cards.txt:
Rejuvenate
3 G
Sorcery
You gain 6 life.
Cycling:2
I hope all these codes are correct ....

Re: Programming a card

PostPosted: 26 Oct 2009, 19:25
by DennisBergkamp
Nice Cyclope, I'll add these, thanks :)
As for the Lieges, I'm not 100% sure how to make them work without bugs yet. I'll play around with the code though...

When generating one of those serialIDs in Eclipse, be sure that there's no compile errors on the file you're working on, also be sure to save first, then generate it.

Re: Programming a card

PostPosted: 26 Oct 2009, 20:46
by Chris H.
DennisBergkamp wrote:When generating one of those serialIDs in Eclipse, be sure that there's no compile errors on the file you're working on, also be sure to save first, then generate it.
`
There are times on my Mac when a serialID is generated yet I still get the warning stating that I need a serialID. So, I generate the serialID a second time and get the same exact serialID string.

And I now get a warning/error since I have two of them in place. So I delete one of the two serialIDs and everything works at that point. Do you see something similar in Windows or is this a Mac Eclipse specific problem.

Re: Programming a card

PostPosted: 26 Oct 2009, 21:19
by silly freak
i think this is more a timing thing. eclipse needs its time to recompile after changing card factory, so it may just not yet have realized that there is an id.

Re: Programming a card

PostPosted: 26 Oct 2009, 21:25
by DennisBergkamp
Hmm, it might be a performance kind of thing (in CardFactory). Save right after generating the serialID and wait a second or two, the warning should disappear.
In the next version performance will be way better, so that shouldn't be much of a problem anymore.

Or maybe it is something funky going on with Mac/Eclipse.

Re: Programming a card

PostPosted: 27 Oct 2009, 05:14
by zerker2000
I hope everyone agrees with the following:
"Oh friendly forum administrators, would you be so kind as to move this post to Developer's Corner!"

Re: Programming a card

PostPosted: 27 Oct 2009, 16:48
by cyclope
two other cards:
Shrieking Drake:
Code: Select all
Shrieking Drake
 //*************** START *********** START **************************
    if(cardName.equals("Shrieking Drake"))
    {
      final SpellAbility ability = new Ability(card, "0")
      {
        public void resolve()
        {
         
          Card c = getTargetCard();
          PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, c.getOwner());

          if(AllZone.GameAction.isCardInPlay(c))
          {
            AllZone.getZone(c).remove(c);

            if(! c.isToken())
            {
              Card newCard = AllZone.CardFactory.getCard(c.getName(), c.getOwner());
              hand.add(newCard);
            }
          }
        }
      };
      Command intoPlay = new Command()
      {
        private static final long serialVersionUID = ;

      public void execute()
        {
                      
           PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController());
           
           CardList creatures = new CardList(play.getCards());
           creatures = creatures.getType("Creature");
           
           //Object o = AllZone.Display.getChoiceOptional("Select a creature card to bounce", blackBlue.toArray());
           
           
           AllZone.InputControl.setInput(CardFactoryUtil.input_targetSpecific(ability, creatures, "Select a creature you control.", false));
            ButtonUtil.disableAll();
         
        }//execute()
      };//Command
      card.addComesIntoPlayCommand(intoPlay);

      card.clearSpellAbility();

      card.addSpellAbility(new Spell_Permanent(card)
      {
        private static final long serialVersionUID = ;

      public boolean canPlayAI()
        {
          return false;
        }
      });
    }//*************** END ************ END **************************

in cards.txt:
Shrieking Drake
U
Creature Drake
When Shrieking Drake comes into play, return target creature you control in its owner's hand.
1/1
Flying
and Telim'Tor's Darts:
Code: Select all
//*************** START *********** START **************************
    if(cardName.equals("Telim'tor's Darts"))
    {
     final SpellAbility ability = new Ability_Tap(card, "2")
      {
      private static final long serialVersionUID =

      public boolean canPlayAI() {return AllZone.Phase.getPhase().equals(Constant.Phase.Main2);}

      public void resolve()
        {
          String opponent = AllZone.GameAction.getOpponent(card.getController());
          AllZone.GameAction.getPlayerLife(opponent).subtractLife(1);
        }
               }
      };//SpellAbility
      card.addSpellAbility(ability);
      ability.setDescription("2, tap: Target player loses 1 life.");
      ability.setStackDescription(card.getName() + " - Opponent loses 1 life.");
      ability.setBeforePayMana(new Input_NoCost_TapAbility(ability));
    }//*************** END ************ END **************************

in cards.txt:
Telim'Tor's Darts
2
Artifact
2,Tap: target players loses 1 life.
But i've got a question : does MTG Forge make the difference between "deal damage to target player" and "target player loses one life" ? If it does , i think my code for Telim isn't correct...

Re: Programming a card

PostPosted: 27 Oct 2009, 17:35
by Rob Cashwalker
But i've got a question : does MTG Forge make the difference between "deal damage to target player" and "target player loses one life" ? If it does, i think my code for Telim isn't correct...
Depends on when the code was written and who wrote it.Originally, most all instances of the actual dealing of damage to the player is handled by simply subtracting the number from the player's life object.
When I released the spDamageTgt keyword, I added methods to GameAction class (that mirror the damage to a creature) as placeholders for dealing with damage to the player. All the method currently does subtract the life as we do now, but it serves as a central location where code may be placed to deal with prevention/redirection/multiplication or other effects. Old damage code can gradually be transitioned to point to this damagePlayer method. Losing life would also need to be handled similarly.

Re: Programming a card

PostPosted: 27 Oct 2009, 17:51
by Chris H.
zerker2000 wrote:I hope everyone agrees with the following:
"Oh friendly forum administrators, would you be so kind as to move this post to Developer's Corner!"
`
I think we should make sure that cyclope will be able to find this message topic that he started.

@ cyclope

Have you visited the MTG Forge > Developer's Corner section? If the "Programming a card" topic is moved to the Developer's Corner forum will you be able to find it?

We have some nice topics covering various areas of Forge development. We would enjoy having you and this topic join the Developer's Corner forum.

Re: Programming a card

PostPosted: 29 Oct 2009, 09:53
by cyclope
Thanks for your answer Rob...

And for Chris , yes , if you want you can move my thread to the "developper's corner " if you want , i think i'll be able to find it...

Re: Programming a card

PostPosted: 30 Oct 2009, 13:16
by cyclope
Some more cards that i've tried to code:
Frontline Sage:
Code: Select all
 //*************** START *********** START **************************
    if(cardName.equals("Frontline Sage"))
    {
         final SpellAbility ability = new Ability_Tap(card, "U")
      {
      private static final long serialVersionUID = ;
      public boolean canPlayAI() {return false;}
        public void resolve()
        {
          AllZone.GameAction.drawCard(card.getController());
          AllZone.InputControl.setInput(CardFactoryUtil.input_discard());
        }
      };//SpellAbility
      card.addSpellAbility(ability);
      ability.setDescription("U, tap: Draw a card, then discard a card.");
      ability.setStackDescription("Frontline Sage - draw a card, then discard a card.");
    }//*************** END ************ END **************************

and in cards.txt
Frontline Sage
2 U
Creature Human Wizard
U, tap : draw a card then discard a card.
0/1
Exalted
Asha's Favor:
Code: Select all
//*************** START *********** START **************************
if(cardName.equals("Asha's Favor"))
{
  final SpellAbility spell = new Spell(card)
  {

   public boolean canPlayAI()
    {
      CardList list = new CardList(AllZone.Computer_Play.getCards());
      list = list.getType("Creature");

      if(list.isEmpty())
       return false;

      //else
      CardListUtil.sortAttack(list);
      CardListUtil.sortFlying(list);

      for (int i=0;i<list.size();i++) {
         if (CardFactoryUtil.canTarget(card, list.get(i)))
         {
            setTargetCard(list.get(i));
            return true;
         }
      }
      return false;
    }//canPlayAI()
    public void resolve()
    {
      PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController());
      play.add(card);
     
      Card c = getTargetCard();
     
      if(AllZone.GameAction.isCardInPlay(c)  && CardFactoryUtil.canTarget(card, c) )
      {
         card.enchantCard(c);
         System.out.println("Enchanted: " +getTargetCard());
      }
    }//resolve()
  };//SpellAbility
  card.clearSpellAbility();
  card.addSpellAbility(spell);

  Command onEnchant = new Command()
  {   

   public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
            crd.addExtrinsicKeyword("Flying");
      crd.addExtrinsicKeyword("First Strike");
      crd.addExtrinsicKeyword("Vigilance");
         }
      }//execute()
  };//Command


  Command onUnEnchant = new Command()
  {   

   public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
            crd.removeExtrinsicKeyword("Flying");
      crd.removeExtrinsicKeyword("First Strike");
      crd.removeExtrinsicKeyword("Vigilance");
         }
     
      }//execute()
   };//Command
   
   Command onLeavesPlay = new Command()
   {


   public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
            card.unEnchantCard(crd);
         }
      }
   };

  card.setEnchant(onEnchant);
  card.setUnEnchant(onUnEnchant);
  card.setLeavesPlay(onLeavesPlay);

  spell.setBeforePayMana(CardFactoryUtil.input_targetCreature(spell));
}//*************** END ************ END **************************

in cards.txt:
Asha's favor
2 W
Enchantment Aura
Enchanted creature gains flying, first strike and vigilance.
Enchant creature

Silver Drake:
Code: Select all
 //*************** START *********** START **************************
    if(cardName.equals("Silver Drake"))
    {
      final SpellAbility ability = new Ability(card, "0")
      {
        public void resolve()
        {
          Card c = getTargetCard();
          PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, c.getOwner());

          if(AllZone.GameAction.isCardInPlay(c))
          {
            AllZone.getZone(c).remove(c);

            if(! c.isToken())
            {
              Card newCard = AllZone.CardFactory.getCard(c.getName(), c.getOwner());
              hand.add(newCard);
            }
          }
        }
      };
      Command intoPlay = new Command()
      {
      private static final long serialVersionUID = ;

      public void execute()
        {
           PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController());
           
           CardList creatures = new CardList(play.getCards());
           creatures = creatures.getType("Creature");
           
           CardList whiteBlue = new CardList();
           
           
           for(int i=0;i <creatures.size(); i++)
           {
              //if(!CardUtil.getColors(nonBlackCards.get(i)).contains(Constant.Color.Black))
              if (CardUtil.getColors(creatures.get(i)).contains(Constant.Color.White))
              {
                 whiteBlue.add(creatures.get(i));
              }
              else if (CardUtil.getColors(creatures.get(i)).contains(Constant.Color.Blue))
              {
                 whiteBlue.add(creatures.get(i));
              }
           }
           
           //Object o = AllZone.Display.getChoiceOptional("Select a creature card to bounce", blackBlue.toArray());
           
           
           AllZone.InputControl.setInput(CardFactoryUtil.input_targetSpecific(ability, whiteBlue, "Select a white or blue creature you control.", false));
            ButtonUtil.disableAll();
         
        }//execute()
      };//Command
      card.addComesIntoPlayCommand(intoPlay);

      card.clearSpellAbility();

      card.addSpellAbility(new Spell_Permanent(card)
      {
        private static final long serialVersionUID = ;

      public boolean canPlayAI()
        {
          return false;
        }
      });
    }//*************** END ************ END **************************

in cards.txt
Silver Drake
1 W U
Creature Drake
When Silver Drake comes into play, return a white or blue creature you control to its owner's hand.
3/3
Flying
For Silver Drake , i've modified the code of Shivan Wurm but i 've not understood why there is the line code "if(!CardUtil.getColors(nonBlackCards.get(i)).contains(Constant.Color.Black))" and the code "blackBlue.toArray()". Can someone explains them to me ?

Scepter of Insight:
Code: Select all
//*************** START *********** START **************************
    if(cardName.equals("Scepter of Insight"))
    {
     final SpellAbility ability = new Ability_Tap(card, "3 U")
      {
      private static final long serialVersionUID =

      public boolean canPlayAI() {return AllZone.Phase.getPhase().equals(Constant.Phase.Main2);}

      public void resolve()
        {
          AllZone.GameAction.drawCard(card.getController());
        }
               }
      };//SpellAbility
      card.addSpellAbility(ability);
      ability.setDescription("3 U, tap: Draw a card.");
      ability.setStackDescription(card.getName() + " - draw a card.");
    }//*************** END ************ END **************************

in cards.txt:
Scepter of Insight
1 U U
Artifact
3 U,Tap: draw a card.
For Scepter of Insight , i think the AI code must be changed but I don't know how to ... Some help , please...

Sparkcaster:
Code: Select all
Sparkcaster
 //*************** START *********** START **************************
    if(cardName.equals("Sparkcaster"))
    {
      final SpellAbility ability = new Ability(card, "0")
      {
        public void resolve()
        {
         String opponent = AllZone.GameAction.getOpponent(card.getController());
          AllZone.GameAction.getPlayerLife(opponent).subtractLife(1);
 
          Card c = getTargetCard();
          PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, c.getOwner());

          if(AllZone.GameAction.isCardInPlay(c))
          {
            AllZone.getZone(c).remove(c);

            if(! c.isToken())
            {
              Card newCard = AllZone.CardFactory.getCard(c.getName(), c.getOwner());
              hand.add(newCard);
   
            }
          }
        }
      };
      Command intoPlay = new Command()
      {
      private static final long serialVersionUID = ;

      public void execute()
        {
           PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController());
           
           CardList creatures = new CardList(play.getCards());
           creatures = creatures.getType("Creature");
           
           CardList redGreen = new CardList();
           
           
           for(int i=0;i <creatures.size(); i++)
           {
              //if(!CardUtil.getColors(nonBlackCards.get(i)).contains(Constant.Color.Black))
              if (CardUtil.getColors(creatures.get(i)).contains(Constant.Color.Red))
              {
                 redGreen.add(creatures.get(i));
              }
              else if (CardUtil.getColors(creatures.get(i)).contains(Constant.Color.Green))
              {
                 redGreen.add(creatures.get(i));
              }
           }
           
           //Object o = AllZone.Display.getChoiceOptional("Select a creature card to bounce", blackBlue.toArray());
           
           
           AllZone.InputControl.setInput(CardFactoryUtil.input_targetSpecific(ability, redGreen, "Select a red or green creature you control.", false));
            ButtonUtil.disableAll();
          ability.setStackDescription("Sparkcaster - " +card.getController() +" opponent loses 1 life");
          AllZone.Stack.add(ability);
        }//execute()
      };//Command
      card.addComesIntoPlayCommand(intoPlay);

      card.clearSpellAbility();

      card.addSpellAbility(new Spell_Permanent(card)
      {
        private static final long serialVersionUID = ;

      public boolean canPlayAI()
        {
          return false;
        }
      });
    }//*************** END ************ END **************************

in cards.txt
Sparkcaster
2 R G
Creature Kavu
When Sparkcaster comes into play, return a red or green creature you control to its owner's hand, and target player loses 1 life.
5/3
For this last card Sparkcaster, i think I've not implemented correctly the ability "target player loses 1 life"... Some help , please...

Thornscape Apprentice:
Code: Select all
Thornscape Apprentice

//*************** START *********** START **************************
if (cardName.equals("Thornscape Apprentice")
    {
       final SpellAbility ability = new Ability_Tap(card, "W")
        {

         private static final long serialVersionUID = ;
         public void resolve()
           {
             Card c = getTargetCard();
             c.tap();
           }
           public boolean canPlayAI() {return false;}
        };//SpellAbility


        card.addSpellAbility(ability);
        ability.setDescription("W, tap: Tap target creature.");
        ability.setBeforePayMana(CardFactoryUtil.input_targetCreature(ability));

     }//*************** END ************ END **************************

in cards.txt
Thornscape Apprentice
G
Creature Human Wizard
W, tap: tap target creature. R, tap: target creature gains first strike until end of turn
1/1
TgtKpump R T: First strike

Re: Programming a card

PostPosted: 30 Oct 2009, 15:41
by cyclope
As I was reading GameActionUtil.java file, i found the code for Aven Brigadier. I saw that there was a code when there was more than one Aven brigradier in play...

Can we add this code for the Lieges that I've proposed ?

Like this, for example, for Boartusk Liege:
Code: Select all
public static Command Boartisk_Liege_Other = new Command()
   {
      private static final long serialVersionUID = ;
      
      int otherBoartusk = 0;
      
      private int countOtherBoartusk()
      {
         PlayerZone hPlay = AllZone.getZone(Constant.Zone.Play, Constant.Player.Human);
         PlayerZone cPlay = AllZone.getZone(Constant.Zone.Play, Constant.Player.Computer);
         CardList boartusklieges = new CardList();
         
         boartusklieges.addAll(hPlay.getCards());
         boartusklieges.addAll(cPlay.getCards());
         boartusklieges = boartusklieges.getName("Boartusk Liege");
         return boartusklieges.size()-1;

      }

      public void execute()
      {

         
         CardList creature = new CardList();
         creature.addAll(AllZone.Human_Play.getCards());
         creature.addAll(AllZone.Computer_Play.getCards());
         
         creature = creature.getName("Boartusk Liege");

         for (int i = 0; i < creature.size(); i++)
         {
            Card c = creature.get(i);
            otherBoartusk = countOtherBoartusk();
            c.setOtherAttackBoost(2*otherBoartusk);
            c.setOtherDefenseBoost(2*otherBoartusk);
         }// for inner
      }// execute()
      
   };//boartusk_liege other