It is currently 13 Sep 2025, 21:54
   
Text Size

Programming a card

Post MTG Forge Related Programming Questions Here

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

Re: Programming a card

Postby cyclope » 26 Oct 2009, 13:56

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...
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby Chris H. » 26 Oct 2009, 15:34

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.
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: Programming a card

Postby cyclope » 26 Oct 2009, 16:55

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...
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby cyclope » 26 Oct 2009, 17:56

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 ....
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby DennisBergkamp » 26 Oct 2009, 19:25

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

Re: Programming a card

Postby Chris H. » 26 Oct 2009, 20:46

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.
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: Programming a card

Postby silly freak » 26 Oct 2009, 21:19

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.
___

where's the "trust me, that will work!" switch for the compiler?
Laterna Magica - blog, forum, project, 2010/09/06 release!
silly freak
DEVELOPER
 
Posts: 598
Joined: 26 Mar 2009, 07:18
Location: Vienna, Austria
Has thanked: 93 times
Been thanked: 25 times

Re: Programming a card

Postby DennisBergkamp » 26 Oct 2009, 21:25

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

Re: Programming a card

Postby zerker2000 » 27 Oct 2009, 05:14

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!"
O forest, hold thy wand'ring son
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.


--Eladamri, the Seed of Freyalise
zerker2000
Programmer
 
Posts: 569
Joined: 09 May 2009, 21:40
Location: South Pasadena, CA
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby cyclope » 27 Oct 2009, 16:48

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...
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby Rob Cashwalker » 27 Oct 2009, 17:35

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.
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: Programming a card

Postby Chris H. » 27 Oct 2009, 17:51

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.
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: Programming a card

Postby cyclope » 29 Oct 2009, 09:53

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...
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby cyclope » 30 Oct 2009, 13:16

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
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby cyclope » 30 Oct 2009, 15:41

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
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

PreviousNext

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 28 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 28 users online :: 0 registered, 0 hidden and 28 guests (based on users active over the past 10 minutes)
Most users ever online was 7967 on 09 Sep 2025, 23:08

Users browsing this forum: No registered users and 28 guests

Login Form