It is currently 13 Sep 2025, 13:50
   
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 » 30 Sep 2009, 15:11

Thank you for your help and comments.
Now, i'm wondering if the enchant "undying rage" could be code like this:
//*************** START *********** START **************************
if(cardName.equals("Undying Rage"))
{
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);

setTargetCard(list.get(0));
return true;
}//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);

}//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(+2);
crd.addSemiPermanentDefenseBoost(+2);
crd.addExtrinsicKeyword("This creature cannot block");
}
}//execute()
};//Command


Command onUnEnchant = new Command()
{


public void execute()
{
if (card.isEnchanting())
{
Card crd = card.getEnchanting().get(0);
crd.removeExtrinsicKeyword("This creature cannot block");
crd.addSemiPermanentAttackBoost(-1);
crd.addSemiPermanentDefenseBoost(-2);
}

}//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 **************************

I don't think the code takes care about "when this card is put in a graveyard from play, return it in its owner's hand"
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby DennisBergkamp » 30 Sep 2009, 15:31

Yes, this should definitely work. Except:

Code: Select all
...
public void execute()
{
if (card.isEnchanting())
{
Card crd = card.getEnchanting().get(0);
crd.removeExtrinsicKeyword("This creature cannot block");
crd.addSemiPermanentAttackBoost(-1);
crd.addSemiPermanentDefenseBoost(-2);
}
...
You have a -1 instead of a -2 (just a typo I assume).
The "when this card is put in a graveyard from play, return it in its owner's hand" part is easy to add. In GameAction.destroy():

Code: Select all
if (c.getName().equals("Rancor") || c.getName().equals("Brilliant Halo") )
    {
       PlayerZone hand = AllZone.getZone(Constant.Zone.Hand,c.getOwner());
       moveTo(hand, c);
    }
Adding a '|| c.getName().equals("Undying Rage") ' into that if statement would take care of that.
Thanks, I'll add this card also :)
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 Marek14 » 30 Sep 2009, 16:26

DennisBergkamp wrote:Yes, this should definitely work. Except:

Code: Select all
...
public void execute()
{
if (card.isEnchanting())
{
Card crd = card.getEnchanting().get(0);
crd.removeExtrinsicKeyword("This creature cannot block");
crd.addSemiPermanentAttackBoost(-1);
crd.addSemiPermanentDefenseBoost(-2);
}
...
You have a -1 instead of a -2 (just a typo I assume).
The "when this card is put in a graveyard from play, return it in its owner's hand" part is easy to add. In GameAction.destroy():

Code: Select all
if (c.getName().equals("Rancor") || c.getName().equals("Brilliant Halo") )
    {
       PlayerZone hand = AllZone.getZone(Constant.Zone.Hand,c.getOwner());
       moveTo(hand, c);
    }
Adding a '|| c.getName().equals("Undying Rage") ' into that if statement would take care of that.
Thanks, I'll add this card also :)
BTW, I think I had a creature with Brilliant Halo die, and the Halo wound up in my hand without ever going through triggered ability... it is not implemented as one?

Anyways, here's a complete list of things with the same ability. Most of them seems that they could be added right away:

Aspect of Mongoose
Brilliant Halo
Cessation
Despondency
Endless Cockroaches
Fallen Ideal
Fiery Mantle
Fool's Demise
Fortitude
Launch
Rancor
Shivan Phoenix
Sleeper's Guile
Slow Motion
Sluggishness
Spirit Loop
Spreading Algae
Undying Rage
Weatherseed Treefolk
Marek14
Tester
 
Posts: 2773
Joined: 07 Jun 2008, 07:54
Has thanked: 0 time
Been thanked: 303 times

Re: Programming a card

Postby cyclope » 30 Sep 2009, 16:32

Thanks for your help Dennis...
So if my code is correct , this will also be correct:
Code: Select all
//*************** START *********** START **************************
if(cardName.equals("Aspect of Mongouse"))
{
  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);

      setTargetCard(list.get(0));
      return true;
    }//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("Shroud");
                     } 
      }//execute()
  };//Command
 

  Command onUnEnchant = new Command()
  {   
   

      public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
            crd.removeExtrinsicKeyword("Shroud");

         }
      
      }//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 **************************
and in GameActtion.destroy():
Code: Select all
if (c.getName().equals("Rancor") || c.getName().equals("Brilliant Halo") || c.getName().equals("Aspect of Mongoose"))
    {
       PlayerZone hand = AllZone.getZone(Constant.Zone.Hand,c.getOwner());
       moveTo(hand, c);
    }

But i can't find in which file the "GameAction.destroy()" is...
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby DennisBergkamp » 30 Sep 2009, 16:34

BTW, I think I had a creature with Brilliant Halo die, and the Halo wound up in my hand without ever going through triggered ability... it is not implemented as one?

Anyways, here's a complete list of things with the same ability. Most of them seems that they could be added right away:

Aspect of Mongoose
Brilliant Halo
Cessation
Despondency
Endless Cockroaches
Fallen Ideal
Fiery Mantle
Fool's Demise
Fortitude
Launch
Rancor
Shivan Phoenix
Sleeper's Guile
Slow Motion
Sluggishness
Spirit Loop
Spreading Algae
Undying Rage
Weatherseed Treefolk
Wow, didn't know there were that many. Maybe I'll just add it as a keyword:

"When this card is put into a graveyard from the battlefield, return this card to its owner's hand" ?

I'm not sure if it's possible to turn this into a triggered ability in MTGForge though, I'll give it a shot.
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 DennisBergkamp » 30 Sep 2009, 16:39

cyclope wrote:Thanks for your help Dennis...
So if my code is correct , this will also be correct:
Code: Select all
//*************** START *********** START **************************
if(cardName.equals("Aspect of Mongouse"))
{
  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);

      setTargetCard(list.get(0));
      return true;
    }//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("Shroud");
                     } 
      }//execute()
  };//Command
 

  Command onUnEnchant = new Command()
  {   
   

      public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
            crd.removeExtrinsicKeyword("Shroud");

         }
      
      }//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 **************************
and in GameActtion.destroy():
Code: Select all
if (c.getName().equals("Rancor") || c.getName().equals("Brilliant Halo") || c.getName().equals("Aspect of Mongoose"))
    {
       PlayerZone hand = AllZone.getZone(Constant.Zone.Hand,c.getOwner());
       moveTo(hand, c);
    }

But i can't find in which file the "GameAction.destroy()" is...
Exactly, that should work too (Aspect of Mongoose though instead of Mongouse :) ).
I was wrong about GameAction.destroy() (plus I misspelled it GameActtion), in fact it's in GameAction.sacrificeDestroy(Card c). Which is in the file GameAction.java, and starts on line 466 (the actual if statement is on line 516).
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 cyclope » 30 Sep 2009, 16:47

Thanks to Dennis...
Thanks too , to Marek, i'll try to write the code for most of the cards that he requests...
And of course, i'll try to avoid typing errors...
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby DennisBergkamp » 30 Sep 2009, 17:03

No problems, glad you're having fun Cyclope!
Probably the way to do this would be to change if statement in GameAction.java

Code: Select all
if (c.getName().equals("Rancor") || c.getName().equals("Brilliant Halo") || c.getName().equals("Aspect of Mongoose"))
    {
       PlayerZone hand = AllZone.getZone(Constant.Zone.Hand,c.getOwner());
       moveTo(hand, c);
    }
into:

Code: Select all
if (c.getKeyword().contains("When this card is put into a graveyard from the battlefield, return this card to its owner's hand"))
{
     PlayerZone hand = AllZone.getZone(Constant.Zone.Hand,c.getOwner());
     moveTo(hand, c);
}
And then define cards in cards.txt like this:

Code: Select all
Weatherseed Treefolk
2 G G G
Creature Treefolk
no text
5/3
Trample
When this card is put into a graveyard from the battlefield, return this card to its owner's hand
Same with Rancor, Brilliant Halo, Undying Rage, etc.
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 cyclope » 30 Sep 2009, 17:10

Here are some more codes for:
- Spirit Loop
- Sluggishness
- Sleeper's Guile
and Launch.

Code: Select all
add in card fatory:

//*************** START *********** START **************************
if(cardName.equals("Spirit Loop"))
{
  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);

      setTargetCard(list.get(0));
      return true;
    }//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 **************************

//*************** START *********** START **************************
if(cardName.equals("Launch"))
{
  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);

      setTargetCard(list.get(0));
      return true;
    }//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");
                     } 
      }//execute()
  };//Command
 

  Command onUnEnchant = new Command()
  {   
   

      public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
            crd.removeExtrinsicKeyword("Flying");

         }
      
      }//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 **************************

//*************** START *********** START **************************
if(cardName.equals("Sleeper's Guile"))
{
  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);

      setTargetCard(list.get(0));
      return true;
    }//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("Fear");
                     } 
      }//execute()
  };//Command
 

  Command onUnEnchant = new Command()
  {   
   

      public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
            crd.removeExtrinsicKeyword("Fear");

         }
      
      }//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 **************************

//*************** START *********** START **************************
if(cardName.equals("Sluggishness"))
{
  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);

      setTargetCard(list.get(0));
      return true;
    }//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("This creature can't block");
                     } 
      }//execute()
  };//Command
 

  Command onUnEnchant = new Command()
  {   
   

      public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
            crd.removeExtrinsicKeyword("This creature can't block");

         }
      
      }//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 **************************

 add in GameAction.destroy(): where there is :

if (c.getName().equals("Rancor") || c.getName().equals("Brilliant Halo") || c.getName().equals("Aspect of Mongoose"))
    {
       PlayerZone hand = AllZone.getZone(Constant.Zone.Hand,c.getOwner());
       moveTo(hand, c);
    }

|| c.getName().equals("Spirit Loop")|| c.getName().equals("Sluggishness")|| c.getName().equals("Sleeper's Guile")|| c.getName().equals("Launch")
For modifying the "if" code :
- i say again that i don't know java programming and that i'm just trying to understand how to code magic cards for forge by copying some codes in CardFactoty.java
- so i don't know if the code you give will work fine , Dennis.
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby Marek14 » 30 Sep 2009, 17:17

cyclope wrote:Thanks to Dennis...
Thanks too , to Marek, i'll try to write the code for most of the cards that he requests...
And of course, i'll try to avoid typing errors...
Well, it's not exactly a request. Let's just say that I'm a completist. :) I want Magic programs to support every card they can possible to support.

I am pure Melvin, mind you. I don't play that much, I simply love the cards and their rules structure.

For the record, a card that works similarly to the current wording (without triggering), is Firestorm Phoenix. But that one has a complex condition later, so that's harder.

Similar to these cards is Enduring Renewal (which returns every creature that goes to your graveyard), but its first ability might prove to be problematic. Depends on if you wish to dive into a wondrous and complex world of draw replacement.

BTW, I noticed that AEtherflame Wall doesn't have the "blocks shadow creatures" ability implemented. I thought that perhaps a flag would work here (or even an ability), with the rules for shadow changed so creature with shadow can be blocked with creature with shadow or with "can block shadow" flag (but NOT both at once). This would be useful, apart from AEtherflame Wall, for AEther Web, Heartwood Dryad, and Wall of Diffusion.

Similarly, a flag could allow a creature to block landwalkers normally, enabling Guildpact card Street Savvy.

A group of six flags checked by landwalkers could allow to "switch off" landwalk abilities (five basic types plus one for all landwalk). This would allow Crevasse, Deadfall, Gosta Dirk, Great Wall, Lord Magnus, Quagmire, Staff of the Ages, Undertow and Ur-Drago.

A flag for "shroud exceptions" could allow Autumn Willow.

Flag "can't accept counters": Tatterkite.

Plus, some possible flags for players:

"Can block with tapped creatures": Masako the Humorless. Instead of having "untapped" as a condition for blockers, it's "untapped or controller has this flag"
"Can't gain life": Everlasting Torment (would also need a global "pseudo-wither" flag), Forsaken Wastes, Stigma Lasher.
Checked in lifegain routine, and stopping the gain if true.
"Doesn't lose at 0 life": Lich, Lich's Tomb, Soul Echo, Transcendence
Checked by the state-based effects.
"Doesn't lose, period": Angel's Grace, Platinum Angel (also needs corresponding "can't win" flag)
Checked by the state-based effects, as well as direct "you lose" and "you win" effects.
"Damage doesn't lower under 1": Ali from Cairo, Angel's Grace, Fortune Thief, Sustaining Spirit, Worship
This would be checked as a part of damage resolution. The trick here is that the full damage is dealt (for purpose of lifelink, etc.), it just doesn't reduce the life as it should. After computing the new life total, if this flag is present and the original life total was 1 or more, the life is actually set to maximum (computed value, 1), otherwise to computed value.
Marek14
Tester
 
Posts: 2773
Joined: 07 Jun 2008, 07:54
Has thanked: 0 time
Been thanked: 303 times

Re: Programming a card

Postby cyclope » 30 Sep 2009, 18:35

Here is , i think , the code for Fiery Mantle:

Code: Select all
add in cardfactory.java:
//*************** START *********** START **************************
if(cardName.equals("Fiery Mantle"))
{
  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);

      setTargetCard(list.get(0));
      return true;
    }//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("PTPump R:+1/+0");
                     } 
      }//execute()
  };//Command
 

  Command onUnEnchant = new Command()
  {   
   

      public void execute()
      {
         if (card.isEnchanting())
         {
            Card crd = card.getEnchanting().get(0);
            crd.removeExtrinsicKeyword("PTPump R:+1/+0");

         }
      
      }//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 **************************


add in GameAction.sacrificeDestroy(card c): where there is :
if (c.getName().equals("Rancor") || c.getName().equals("Brilliant Halo") || c.getName().equals("Aspect of Mongoose"))
    {
       PlayerZone hand = AllZone.getZone(Constant.Zone.Hand,c.getOwner());
       moveTo(hand, c);
    }

|| c.getName().equals("Fiery Mantle")
Could anybody rep me if my codes are wrong , please ?
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby cyclope » 30 Sep 2009, 18:58

I think a card like Dosan's Oldest Chant should be easy to code ? What do you think of that :

Code: Select all
add in cardfactory.java :
//*************** START *********** START **************************
    if(cardName.equals("Dosan's Oldest Chant"))
    {
      final SpellAbility ability = new Spell(card)
      {
        public void resolve()
        {
          Card c = card;
          PlayerLife life = AllZone.GameAction.getPlayerLife(c.getController());
          life.addLife(6);
        }
      };
      Command intoPlay = new Command()
      {

      public void execute()
        {
          ability.setStackDescription(card.getName() + " - " +card.getController() +" gains 6 life");
          AllZone.Stack.add(ability);
        }
      };
      card.clearSpellAbility();
      card.addSpellAbility(spell);
    }//*************** END ************ END **************************

add in cards.tx:
Dosan's Oldest Chant
4 G
Sorcery
You gain 6 life
Cantrip
cyclope
 
Posts: 69
Joined: 28 Sep 2009, 18:08
Has thanked: 0 time
Been thanked: 0 time

Re: Programming a card

Postby DennisBergkamp » 30 Sep 2009, 20:32

Cool, these all look good. I'll add them in :)
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 Rob Cashwalker » 01 Oct 2009, 02:56

Fiery Mantle doesn't work. Adding a scripting keyword (as PTPump is) doesn't grant the ability once the game is running. The script keywords only work when a card is created through CardFactory.

Adding an explicitly coded SpellAbility is simple enough, but I'm not sure how to go about simply removing it if the enchantment becomes detached/destroyed or the creature is bounced from/into play.
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 cyclope » 01 Oct 2009, 16:21

Ok , Fiery Mantle code doesn't work...
Can anybody said me if the others are OK ?
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 53 guests

Main Menu

User Menu

Our Partners


Who is online

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

Login Form