It is currently 12 Sep 2025, 22:22
   
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 » 31 Oct 2009, 19:19

I see you have moved my thread to the developpers' corner...
I'm happy ...
Can anybody post answers to my previous questions, please?
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby Chris H. » 31 Oct 2009, 20:06

cyclope wrote:I see you have moved my thread to the developpers' corner...
I'm happy ...
Can anybody post answers to my previous questions, please?
`
I, too, noticed that this topic has been moved. :D

I have not had a chance to paste your code into my developmental version of Forge, I have been meaning to as the cards look interesting. I am currently working on "fixing" the code to a keyword that I created and I am having some success, but I have not been able to finish.

Sometimes the code can look good and I think that I know what I am doing. I then paste the code into Eclipse and will get warnings or errors and I have to try to figure out what went wrong.

The next version of Forge will have the CardFactory file divided up into smaller pieces. You should find that your older MacBook running the Tiger OS is more responsive. You may want to try Eclipse again once the next version is released.
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 » 01 Nov 2009, 10:22

I have tried to code three cards from 2010 edition:
Angel's Mercy:
Code: Select all
//*************** START *********** START **************************
    if(cardName.equals("Angel's Mercy")
    {
      SpellAbility spell = new Spell(card)
      {
      

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

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

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

in cards.txt:
Angel's Mercy
2 W W
Instant
You gain 7 life.
Blinding Mage:
Code: Select all
//*************** START *********** START **************************
if (cardName.equals("Blinding Mage")
    {
       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
Blinding mage
1 W
Creature Human Wizard
W, tap: tap target creature.
1/2

and Captain of the Watch:
Code: Select all
in GameActionUtil.java:

public static Command Captain_Watch_Pump = new Command()
   {

      private static final long serialVersionUID = ;
      CardList gloriousAnthemList = new CardList();

      public void execute()
      {

         CardList cList = gloriousAnthemList;
         Card c;

         for (int i = 0; i < cList.size(); i++)
         {
            c = cList.get(i);
            c.addSemiPermanentAttackBoost(-1);
            c.addSemiPermanentDefenseBoost(-1);
            c.removeExtrinsicKeyword("Vigilance");
         }
         cList.clear();
         PlayerZone[] zone = getZone("Captain of the Watch");

         // for each zone found add +1/+1 to each card
         for (int outer = 0; outer < zone.length; outer++)
         {
            CardList creature = new CardList(zone[outer].getCards());
            creature = creature.getType("Soldier");

            for (int i = 0; i < creature.size(); i++)
            {
               c = creature.get(i);
               if (c.isCreature()
                     && !c.getName().equals("Captain of the Watch"))
               {
                  c.addSemiPermanentAttackBoost(1);
                  c.addSemiPermanentDefenseBoost(1);
                  c.addExtrinsicKeyword("Vigilance");
                  gloriousAnthemList.add(c);
               }

            } // for
         } // for

      }// execute()

   };//Captain_Watch_Pump
   
   public static Command Captain_Watch_Other = new Command()
   {

      private static final long serialVersionUID = ;
      int otherCaptainsw=0;
      
      private int countOtherCaptainsW()
      {
         PlayerZone play = AllZone.getZone(Constant.Zone.Play, c
               .getController());
         CardList captainsw = new CardList(play.getCards());
         captainsw = captainsw.getName("Captain of the Watch");
         return captainsw.size()-1;

      }

      public void execute()
      {

         
         CardList creature = new CardList();
         creature.addAll(AllZone.Human_Play.getCards());
         creature.addAll(AllZone.Computer_Play.getCards());
         
         creature = creature.getName("Captain of the Watch");

         for (int i = 0; i < creature.size(); i++)
         {
            Card c = creature.get(i);
            otherCaptainsw = countOtherCaptainsW();
            c.setOtherAttackBoost(otherCaptainsw);
            c.setOtherDefenseBoost(otherCaptainsw);
               

         }// for inner
      }// execute()
      
   };//Captain_Watch_Other

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

commands.put("Captain_Watch_Pump", Captain_Watch_Pump);
 commands.put("Captain_Watch_Other", Captain_Watch_Other);

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

cardToEffectsList.put("Captain of the Watch", new String[] {"Captain_Watch_Pump","Captain_Watch_Other"});

in CardFactory.java:

//*************** START *********** START **************************
    if(cardName.equals("Captain of the Watch"))
    {
      final SpellAbility ability = new Ability(card, "0")
      {
        public void resolve()
        {
          for(int i = 0; i < 3; i++)
            makeToken();
        }

        void makeToken()
        {
          Card c = new Card();

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

          c.setName("Soldier");
          c.setImageName("W1 1 Soldier");
          c.setManaCost("W");
          c.setToken(true);

          c.addType("Creature");
          c.addType("Soldier");
          c.setBaseAttack(1);
          c.setBaseDefense(1);

          play.add(c);
        }//makeToken()
      };
      Command intoPlay = new Command()
      {
      private static final long serialVersionUID = ;

      public void execute()
        {
          ability.setStackDescription("Captain of the Watch - put three 1/1 white Soldier creature token into play.");
          AllZone.Stack.add(ability);
        }
      };
      card.addComesIntoPlayCommand(intoPlay);
    }//*************** END ************ END **************************

in cards.txt:
Captain of the watch
4 W W
Creature Human Soldier
When Captain of the watch comes into play, put three 1/1 white Soldier creature tokens into play.All others soldiers you control gains +1/+1 and vigilance.
3/3
Vigilance

I hope these codes will be usefull...and rep me if I've made some errors...
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby Sloth » 01 Nov 2009, 13:40

Concerning Blinding Mage:
Wouldn't it be more easier to just add Blinding Mage along with some others to the entry of Master Decoy and Goldmeadow Harrier:
Code: Select all
if (cardName.equals("Goldmeadow Harrier") || cardName.equals("Loxodon Mystic") || cardName.equals("Master Decoy") || cardName.equals("Benalish Trapper") || cardName.equals("Blinding Mage") || cardName.equals("Ostiary Thrull") || cardName.equals("Whipcorder"))
cards.txt:
Code: Select all
Benalish Trapper
1 W
Creature Human Soldier
W, tap: tap target creature.
1/2

Whipcorder
W W
Creature Human Soldier Rebel
W, tap: tap target creature.
2/2
Morph:W

Ostiary Thrull
3 B
Creature Thrull
W, tap: tap target creature.
2/2
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: Programming a card

Postby cyclope » 01 Nov 2009, 13:58

yes , sloth, you're right , Blinding Mage is a creature with the ability like Goldmeadow Harrier...
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby cyclope » 01 Nov 2009, 19:41

Some more cards :

Lifelink:
Code: Select all
//*************** START *********** START **************************
if(cardName.equals("Lifelink"))
{
  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("Lifelink");
         }
      }//execute()
  };//Command


  Command onUnEnchant = new Command()
  {   

   public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
            crd.removeExtrinsicKeyword("Lifelink");
         }
     
      }//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:
Lifelink
W
Enchantment Aura
Enchanted creature has lifelink.
Enchant creature
Rhox Pikemaster:
Code: Select all
in GameActionUtil.java:

public static Command Rhox_Pikemaster_Pump = new Command()
   {

      private static final long serialVersionUID = ;
      CardList gloriousAnthemList = new CardList();

      public void execute()
      {

         CardList cList = gloriousAnthemList;
         Card c;

         for (int i = 0; i < cList.size(); i++)
         {
            c = cList.get(i);
            c.removeExtrinsicKeyword("First Strike");
         }
         cList.clear();
         PlayerZone[] zone = getZone("Rhox Pikemaster");

         // for each zone found add +1/+1 to each card
         for (int outer = 0; outer < zone.length; outer++)
         {
            CardList creature = new CardList(zone[outer].getCards());
            creature = creature.getType("Soldier");

            for (int i = 0; i < creature.size(); i++)
            {
               c = creature.get(i);
               if (c.isCreature()
                     && !c.getName().equals("Rhox Pikemaster"))
               {
                  c.addExtrinsicKeyword("First Strike");
                  gloriousAnthemList.add(c);
               }

            } // for
         } // for

      }// execute()

   };//Rhox_Pikemaster_Pump
   
   
and in" public static HashMap<String, Command> commands = new HashMap<String, Command>();
   static {" add:

commands.put("Rhox_Pikemaster_Pump", Rhox_Pikemaster_Pump);

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

cardToEffectsList.put("Rhox Pikemaster", new String[] {"Rhox_Pikemaster_Pump"});


in cards.txt:
Rhox Pikemaster
2 W W
Creature Rhino Soldier
All others soldiers you control gains first strike.
3/3
First Strike
Veteran Armorsmith:
Code: Select all
in GameActionUtil.java:

public static Command Veteran_Armorsmith_Pump = new Command()
   {

      private static final long serialVersionUID = ;
      CardList gloriousAnthemList = new CardList();

      public void execute()
      {

         CardList cList = gloriousAnthemList;
         Card c;

         for (int i = 0; i < cList.size(); i++)
         {
            c = cList.get(i);
            c.addSemiPermanentDefenseBoost(-1);
                     }
         cList.clear();
         PlayerZone[] zone = getZone("Veteran Armorsmith");

         // for each zone found add +1/+1 to each card
         for (int outer = 0; outer < zone.length; outer++)
         {
            CardList creature = new CardList(zone[outer].getCards());
            creature = creature.getType("Soldier");

            for (int i = 0; i < creature.size(); i++)
            {
               c = creature.get(i);
               if (c.isCreature()
                     && !c.getName().equals("Veteran Armorsmith"))
               {
                  c.addSemiPermanentDefenseBoost(1);
                  gloriousAnthemList.add(c);
               }

            } // for
         } // for

      }// execute()

   };//Veteran_Armorsmith_Pump
   
   public static Command Veteran_Armorsmith_Other = new Command()
   {

      private static final long serialVersionUID = ;
      int otherVeteranAS=0;
      
      private int countOtherVeteranAS()
      {
         PlayerZone play = AllZone.getZone(Constant.Zone.Play, c
               .getController());
         CardList veteranas = new CardList(play.getCards());
         veteranas = veteranas.getName("Veteran Armorsmith");
         return veteranas.size()-1;

      }

      public void execute()
      {

         
         CardList creature = new CardList();
         creature.addAll(AllZone.Human_Play.getCards());
         creature.addAll(AllZone.Computer_Play.getCards());
         
         creature = creature.getName("Veteran Armorsmith");

         for (int i = 0; i < creature.size(); i++)
         {
            Card c = creature.get(i);
            otherVeteranAS = countOtherVeteranAS();
            c.setOtherDefenseBoost(otherVeteranAS);
            
               

         }// for inner
      }// execute()
      
   };//Veteran_Armorsmith_Other

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

commands.put("Veteran_Armorsmith_Pump", Veteran_Armorsmith_Pump);
 commands.put("Veteran_Armorsmith_Other", Veteran_Armorsmith_Other);

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

cardToEffectsList.put("Veteran Armorsmith", new String[] {"Veteran_Armorsmith_Pump","Veteran_Armorsmith_Other"});

in cards.txt:
Veteran Armorsmith
W W
Creature Human Soldier
All others soldiers you control gains +0/+1.
2/3
Veteran Swordsmith:
Code: Select all
in GameActionUtil.java:

public static Command Veteran_Swordsmith_Pump = new Command()
   {

      private static final long serialVersionUID = ;
      CardList gloriousAnthemList = new CardList();

      public void execute()
      {

         CardList cList = gloriousAnthemList;
         Card c;

         for (int i = 0; i < cList.size(); i++)
         {
            c = cList.get(i);
            c.addSemiPermanentAttackBoost(-1);
                     }
         cList.clear();
         PlayerZone[] zone = getZone("Veteran Swordsmith");

         // for each zone found add +1/+1 to each card
         for (int outer = 0; outer < zone.length; outer++)
         {
            CardList creature = new CardList(zone[outer].getCards());
            creature = creature.getType("Soldier");

            for (int i = 0; i < creature.size(); i++)
            {
               c = creature.get(i);
               if (c.isCreature()
                     && !c.getName().equals("Veteran Swordsmith"))
               {
                  c.addSemiPermanentAttackBoost(1);
                  gloriousAnthemList.add(c);
               }

            } // for
         } // for

      }// execute()

   };//Veteran_Swordsmith_Pump
   
   public static Command Veteran_Swordsmith_Other = new Command()
   {

      private static final long serialVersionUID = ;
      int otherVeteranSS=0;
      
      private int countOtherVeteranSS()
      {
         PlayerZone play = AllZone.getZone(Constant.Zone.Play, c
               .getController());
         CardList veteranss = new CardList(play.getCards());
         veteranss = veteranss.getName("Veteran Swordsmith");
         return veteranss.size()-1;

      }

      public void execute()
      {

         
         CardList creature = new CardList();
         creature.addAll(AllZone.Human_Play.getCards());
         creature.addAll(AllZone.Computer_Play.getCards());
         
         creature = creature.getName("Veteran Swordsmith");

         for (int i = 0; i < creature.size(); i++)
         {
            Card c = creature.get(i);
            otherVeteranSS = countOtherVeteranSS();
            c.setOtherAttackBoost(otherVeteranSS);
            
               

         }// for inner
      }// execute()
      
   };//Veteran_Swordsmith_Other

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

commands.put("Veteran_Swordsmith_Pump", Veteran_Swordsmith_Pump);
 commands.put("Veteran_Swordsmith_Other", Veteran_Swordsmith_Other);

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

cardToEffectsList.put("Veteran Swordsmith", new String[] {"Veteran_Swordsmith_Pump","Veteran_Swordsmith_Other"});

in cards.txt:
Veteran Swordsmith
2 W
Creature Human Soldier
All others soldiers you control gains +1/+0.
3/2
I also think we could add Merfolk Looter card as it 's similar to Bonded Fetch...

Don't hesitate telling me if i've made some errors...
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby Marek14 » 01 Nov 2009, 20:51

Marek14
Tester
 
Posts: 2773
Joined: 07 Jun 2008, 07:54
Has thanked: 0 time
Been thanked: 303 times

Re: Programming a card

Postby DennisBergkamp » 02 Nov 2009, 00:05

Cyclope,

Nice, I've added quite a few of the cards you posted here.... some of them have small errors in the text part (whenever an "ability.setDescription(description);" is done, this ability's text does not need to be added in cards.txt, it will cause this text to show up double).

So, for instance:

Code: Select all
Blinding mage
1 W
Creature Human Wizard
W, tap: tap target creature.
1/2
should be:

Code: Select all
Blinding mage
1 W
Creature Human Wizard
no text
1/2
And I will wait with adding cards like Boartusk Liege... currently cards like it are pretty buggy. I will try to add them into the version after the next.
All the other stuff looks great though, thanks a bunch :)
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 Triadasoul » 02 Nov 2009, 06:49

With Blinding Mage implemented is there a way to implement land tap such as Rishadan Port ?
Triadasoul
 
Posts: 223
Joined: 21 Jun 2008, 20:17
Has thanked: 0 time
Been thanked: 4 times

Re: Programming a card

Postby apthaven » 02 Nov 2009, 18:30

"I am a man and real men do not consume pink beverages. Get thee gone woman, and bring me something brown." - Jace Wayland
apthaven
Tester
 
Posts: 242
Joined: 20 Jun 2009, 12:34
Has thanked: 0 time
Been thanked: 1 time

Re: Programming a card

Postby DennisBergkamp » 02 Nov 2009, 20:05

With Blinding Mage implemented is there a way to implement land tap such as Rishadan Port ?
Yeah, this is easy.
However, we currently do not have a phase stop before upkeep... so it wouldn't make that much sense. This is something I can add as an option though, much like the "stop at computer's EOT" option in the menu.
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 Triadasoul » 02 Nov 2009, 20:33

It would be great :D I think it'll give possibilities for more complex gameplay (such as manalink).
Triadasoul
 
Posts: 223
Joined: 21 Jun 2008, 20:17
Has thanked: 0 time
Been thanked: 4 times

Re: Programming a card

Postby Marek14 » 02 Nov 2009, 21:38

DennisBergkamp wrote:
With Blinding Mage implemented is there a way to implement land tap such as Rishadan Port ?
Yeah, this is easy.
However, we currently do not have a phase stop before upkeep... so it wouldn't make that much sense. This is something I can add as an option though, much like the "stop at computer's EOT" option in the menu.
Um, before draw. Noone gets priority before upkeep...
Marek14
Tester
 
Posts: 2773
Joined: 07 Jun 2008, 07:54
Has thanked: 0 time
Been thanked: 303 times

Re: Programming a card

Postby cyclope » 03 Nov 2009, 12:03

Three more cards:

Acolyte of Xathrid:
Code: Select all
//*************** START *********** START **************************
if (cardName.equals("Acolyte of Xathrid"))
    {
   final SpellAbility ability = new Ability_Tap(card, "1 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("1 B, tap: Target player loses 1 life.");
      ability.setStackDescription(card.getName() + " - Opponent loses 1 life.");

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

in cards.txt
Acolyte of Xathrid
B
Creature Human Cleric
no text
0/1
Assassinate:
Code: Select all
 //*************** START *********** START **************************
       else if(cardName.equals("Assassinate"))
       {
         final SpellAbility spell = new Spell(card)
         {
          
         public boolean canPlayAI()
           {
             CardList human = CardFactoryUtil.AI_getHumanCreature(card, true);
             human = human.filter(new CardListFilter()
             {
               public boolean addCard(Card c) {return c.isTapped();}
             });

             CardListUtil.sortAttack(human);
             CardListUtil.sortFlying(human);

             if(0 < human.size())
               setTargetCard(human.get(0));

             return 0 < human.size();
           }
           public void resolve()
           {
             Card c = getTargetCard();

             if(AllZone.GameAction.isCardInPlay(c) && c.isTapped()  && CardFactoryUtil.canTarget(card, c) )
             {
               AllZone.GameAction.destroy(c);
             }
           }//resolve()
         };//SpellAbility

         Input target = new Input()
         {
          
         public void showMessage()
           {
             AllZone.Display.showMessage("Select target tapped creature to destroy");
             ButtonUtil.enableOnlyCancel();
           }
           public void selectButtonCancel() {stop();}
           public void selectCard(Card c, PlayerZone zone)
           {
             if(!CardFactoryUtil.canTarget(card, c)){
                  AllZone.Display.showMessage("Cannot target this card (Shroud? Protection?).");
             }
             else if(c.isCreature() && zone.is(Constant.Zone.Play) && c.isTapped())
             {
               spell.setTargetCard(c);
               stopSetNext(new Input_PayManaCost(spell));
        
             }
           }//selectCard()
         };//Input

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

and in cards.txt:
Assassinate
2 B
Sorcery
Desroy target tapped creature.
Dread Warlock:
in CombatUtil.java:

in public static boolean canBlock(Card attacker, Card blocker) after" if (attacker.getName().equals("Skirk Shaman"))
{
if (!blocker.getType().contains("Artifact") &&
!CardUtil.getColors(blocker).contains(Constant.Color.Red))
return false;
}" ; add this:


Code: Select all
if (attacker.getName().equals("Dread Warlock"))
    {
       if (!CardUtil.getColors(blocker).contains(Constant.Color.Black))
          return false;
    }
and after: "if(attacker.getName().equals("Skirk Shaman"))
return blocker.getType().contains("Artifact") ||
CardUtil.getColors(blocker).contains(Constant.Color.Red);"
add this:

Code: Select all
if(attacker.getName().equals("Dread Warlock"))
      return CardUtil.getColors(blocker).contains(Constant.Color.Red);
in cards.txt
Code: Select all
Dread Warlock
1 B B
Creature Human Wizard
Dread Warlock can't be blocked except by black creatures.
2/2
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby Triadasoul » 27 Nov 2009, 15:02

Hi, i wanted to contribute, but i am a complete beginner in java, so i took some parts of the code and try to edit-compile them to suit Captain of the Watch needs :). I have several noob questions about this process:

1. How can i give this code a try in game?
2. What does serialVersionUID variable mean ?
3. In witch else files should i add code except Gameactionutil, StateBasedeffects.java, Cardfactory_creatures.java, Cards.txt, card-picture.txt in this case?

Code: Select all

Gameactionutil.java:
//=====================
public static Command Captain_of_the_Watch_Pump = new Command()
   {
      private static final long serialVersionUID = 542524781150091105L;
      
      CardList gloriousAnthemList = new CardList();

      public void execute()
      {

         CardList cList = gloriousAnthemList;
         Card c;

         for (int i = 0; i < cList.size(); i++)
         {
            c = cList.get(i);
            c.addSemiPermanentAttackBoost(-1);
            c.addSemiPermanentDefenseBoost(-1);
         }
         cList.clear();
         PlayerZone[] zone = getZone("Captain of the Watch");

         // for each zone found add +1/+1 to each card
         for (int outer = 0; outer < zone.length; outer++)
         {
            CardList creature = new CardList(zone[outer].getCards());
            creature = creature.getType("Soldier");

            for (int i = 0; i < creature.size(); i++)
            {
               c = creature.get(i);
               if (c.isCreature()
                     && !c.getName().equals("Captain of the Watch"))
               {
                  c.addSemiPermanentAttackBoost(1);
                  c.addSemiPermanentDefenseBoost(1);
                  gloriousAnthemList.add(c);
               }

            } // for
         } // for

      }// execute()

   };//Captain_of_the_Watch_Pump
   
   public static Command Captain_of_the_Watch_Other = new Command()
   {
      private static final long serialVersionUID = -7242601069504800797L;
      
      int otherCenns=0;
      
      private int countOtherCenns(Card c)
      {
         PlayerZone play = AllZone.getZone(Constant.Zone.Play, c
               .getController());
         CardList cenns = new CardList(play.getCards());
         cenns = cenns.getName("Captain of the Watch");
         return cenns.size()-1;

      }

      public void execute()
      {

         
         CardList creature = new CardList();
         creature.addAll(AllZone.Human_Play.getCards());
         creature.addAll(AllZone.Computer_Play.getCards());
         
         creature = creature.getName("Captain of the Watch");

         for (int i = 0; i < creature.size(); i++)
         {
            Card c = creature.get(i);
            otherCenns = countOtherCenns(c);
            c.setOtherAttackBoost(otherCenns);
            c.setOtherDefenseBoost(otherCenns);

         }// for inner
      }// execute()
      
   };//Wizened Cenn Other

//====================================

StateBasedeffects.java
//====================================
cardToEffectsList.put("Captain of the Watch", new String[] {"Captain of the Watch"});
//====================================

Cardfactory_creatures.java
//====================================
     //*************** START *********** START **************************
       else if(cardName.equals("Captain of the Watch"))
       {
          
          final SpellAbility comesIntoPlayAbility = new Ability(card, "0")
           {
             public void resolve()
             {
               makeToken();
               makeToken();
               makeToken();
             }//resolve()
            
             public void makeToken()
            {
                Card c = new Card();

                c.setName("Soldier");
                  c.setImageName("W 1 1 Soldier");

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

                  c.setManaCost("W");
                  c.setToken(true);
                 
                  c.addType("Creature");
                  c.addType("Soldier");
                  c.setBaseAttack(1);
                  c.setBaseDefense(1);

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

           }; //comesIntoPlayAbility
          
           Command intoPlay = new Command()
           {
            private static final long serialVersionUID = 8778828278589063477L;

            public void execute()
                {
                  comesIntoPlayAbility.setStackDescription(card.getName() + " - put three 1/1 white Soldier creature tokens into play.");
                  AllZone.Stack.add(comesIntoPlayAbility);
                }
           };
          
           card.addComesIntoPlayCommand(intoPlay);
}//*************** END ************ END **************************
//===================

Cards.txt:
//==================
Captain of the Watch
4 W W
Creature Human Soldier
Other Soldier creatures you control get +1/+1 and have vigilance.
When Captain of the Watch enters the battlefield, put three 1/1 white Soldier creature tokens onto the battlefield.
3/3
Vigilance
//====================

card-picture.txt
captain_of_the_watch.jpg http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=191070

Triadasoul
 
Posts: 223
Joined: 21 Jun 2008, 20:17
Has thanked: 0 time
Been thanked: 4 times

PreviousNext

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 27 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 27 users online :: 0 registered, 0 hidden and 27 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 27 guests

Login Form