It is currently 09 Sep 2025, 12:27
   
Text Size

spGainLife[Tgt] keyword

Post MTG Forge Related Programming Questions Here

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

spGainLife[Tgt] keyword

Postby Rob Cashwalker » 23 Mar 2010, 03:19

Hot on the heels of spLoseLife, it's closest cousin makes its debut performance!

spGainLife for you, spGainLifeTgt for a friend!

spGainLife:1 gets you one, spGainLife:2 gets you twice as much.

Most of the usual permutations apply.
New for this update, a math operation for Count$ - "Times.#" - While "Twice" is nice, "Times.2" is effectively the same, but "Times.3" is better, and who knows, "Times.4" might show up. (just don't try "Times.1.5")

Cards.txt to be added or modified (don't forget to comment them from CardFactory)
Code: Select all
An-Havva Inn
1 G G
Sorcery
no text
spGainLife:X:You gain X plus 1 life, where X is the number of green creatures on the battlefield.:An-Havva Inn - player gains X life
SVar:X:Count$GreenTypeOnBattlefield.Creature/Plus.1

Ancestral Tribute
5 W W
Sorcery
no text
spGainLife:X:You gain 2 life for each card in your graveyard.:Ancestral Tribute - player gains X life
SVar:X:Count$CardsInYourYard/Times.2
Flashback:9 W W W

Angel's Mercy
2 W W
Instant
no text
spGainLife:7

Bargain
2 W
Sorcery
no text
spGainLife:7:Drawback$OppDrawCard/1:Target opponent draws a card. You gain 7 life.:Bargain - opponent draws a card and you gain 7 life

Blossoming Wreath
G
Instant
no text
spGainLife:X:You gain life equal to the number of creature cards in your graveyard.:Blossoming Wreath - player gains X life
SVar:X:Count$TypeInYourYard.Creature

Bountiful Harvest
4 G
Sorcery
no text
spGainLife:X:You gain 1 life for each land you control.:Bountiful Harvest - player gains X life
SVar:X:Count$TypeYouControl.Land

Congregate
3 W
Instant
no text
spGainLifeTgt:X:Target player gains 2 life for each creature on the battlefield.:Congregate - target player gains X life
SVar:X:Count$TypeOnBattlefield.Creature/Times.2

Dosan's Oldest Chant
4 G
Sorcery
no text
spGainLife:6
Draw a card.

Festival of Trokin
W
Sorcery
no text
spGainLife:X:You gain 2 life for each creature you control.:Festival of Trokin - player gains X life
SVar:X:Count$TypeYouCtrl.Creature/Times.2

Folk Medicine
2 G
Instant
no text
spGainLife:X:You gain 1 life for each creature you control.:Folk Medicine - player gains X life
SVar:X:Count$TypeYouCtrl.Creature
Flashback:1 W

Fruition
G
Sorcery
no text
spGainLife:X:You gain 1 life for each Forest on the battlefield.:Fruition - player gains X life
SVar:X:Count$TypeOnBattlefield.Forest

Gerrard's Wisdom
2 W W
Sorcery
no text
spGainLife:X:You gain 2 life for each card in your hand.:Gerrard's Wisdom - player gains X life
SVar:X:Count$CardsInYourHand/Times.2

Heroe's Reunion
W G
Instant
no text
spGainLifeTgt:7

Invigorating Falls
2 G G
Sorcery
no text
spGainLife:X:You gain life equal to the number of creature cards in all graveyards.:Invigorating Falls - player gains X life
SVar:X:Count$TypeInAllYards.Creature

Joyous Respite
3 G
Sorcery Arcane
no text
spGainLife:X:You gain 1 life for each land you control.:Joyous Respite - player gains X life
SVar:X:Count$TypeYouCtrl.Land

Kiss of the Amesha
4 W U
Sorcery
no text
spGainLifeTgt:7:Drawback$TgtDrawCards/2:Target player gains 7 life and draws two cards.:Kiss of the Amesha - target player gains 7 life and draws 2 cards

Landbind Ritual
3 W W
Sorcery
no text
spGainLife:X:You gain 2 life for each Plains you control.:Landbind Ritual - player gains X life
SVar:X:Count$TypeYouCtrl.Plains

Natural Spring
3 G G
Sorcery
no text
spGainLifeTgt:8

Nourish
G G
Instant
no text
spGainLife:6

Peach Garden Oath
W
Sorcery
no text
spGainLife:X:You gain 2 life for each creature you control.:Peach Garden Oath - player gains X life
SVar:X:Count$TypeYouCtrl.Creature/Times.2

Presence of the Wise
2 W W
Sorcery
no text
spGainLife:X:You gain 2 life for each card in your hand.:Presence of the Wise - player gains X life
SVar:X:Count$CardsInYourHand/Times.2

Rejuvinate
3 G
Sorcery
no text
spGainLife:6
Cycling:2

Renewing Dawn
1 W
Sorcery
no text
spGainLife:X:You gain 2 life for each Mountain target opponent controls.:Renewing Dawn - player gains X life
SVar:X:Count$TypeOppCtrl.Mountain/Times.2

Reviving Dose
2 W
Instant
no text
spGainLife:3
Draw a card.

Sacred Nectar
1 W
Sorcery
no text
spGainLife:4

Soothing Balm
1 W
Instant
no text
spGainLifeTgt:5

Spring of Eternal Peace
3 G G
Sorcery
no text
spGainLife:8

Starlight
1 W
Sorcery
no text
spGainLife:X:You gain life for each black creature target opponent controls.:Starlight - player gains X life
SVar:X:Count$BlackTypeOppCtrl.Creature/Times.3

Sylvan Bounty
5 G
Instant
no text
spGainLifeTgt:8
TypeCycling:Basic:1 G

Vital Surge
1 G
Instant Arcane
no text
spGainLife:3

Wandering Stream
2 G
Sorcery
no text
spGainLife:X:Domain - You gain 2 life for each basic land type among lands you control.:Wandering Stream - player gains X life
SVar:X:Count$Domain/Times.2
CardFactory:
Code: Select all
        if (hasKeyword(card, "spGainLife") != -1)
        {
           int n = hasKeyword(card, "spGainLife");
           if (n != -1)
           {
                String parse = card.getKeyword().get(n).toString();
                card.removeIntrinsicKeyword(parse);
               
                String k[] = parse.split(":");
               
                  final boolean Tgt[] = {false};
                  Tgt[0] = k[0].contains("Tgt");

                final int NumLife[] = {-1};
                final String NumLifeX[] = {"none"};
               
                  if (k[1].matches("X"))
                  {
                     String x = card.getSVar(k[1]);
                     if (x.startsWith("Count$"))
                     {
                        String kk[] = x.split("\\$");
                        NumLifeX[0] = kk[1];
                     }
                  }
                  else if (k[1].matches("[0-9][0-9]?"))
                     NumLife[0] = Integer.parseInt(k[1]);
                 
                  // drawbacks and descriptions
                  final String DrawBack[] = {"none"};
                  final String spDesc[] = {"none"};
                  final String stDesc[] = {"none"};
                  if (k.length > 2)
                  {
                     if (k[2].contains("Drawback$"))
                     {
                        String kk[] = k[2].split("\\$");
                        DrawBack[0] = kk[1];
                        if (k.length > 3)
                           spDesc[0] = k[3];
                        if (k.length > 4)
                           stDesc[0] = k[4];
                     }
                     else
                     {
                        if (k.length > 2)
                           spDesc[0] = k[2];
                        if (k.length > 3)
                           stDesc[0] = k[3];
                     }
                  }
                  else
                  {
                     if (Tgt[0] == true)
                     {
                        spDesc[0] = "Target player gains " + NumLife[0] + " life.";
                        stDesc[0] =  cardName + " - target player gains life";
                     }
                     else
                     {
                        spDesc[0] = "You gain " + NumLife[0] + " life.";
                        stDesc[0] = cardName + " - you gain life";
                     }
                  }

                  final SpellAbility spGainLife = new Spell(card)
                  {
                  private static final long serialVersionUID = -8361697584661592092L;

                   public int getNumLife()
                   {
                      if (NumLife[0] != -1)
                         return NumLife[0];

                      if (! NumLifeX[0].equals("none"))
                         return CardFactoryUtil.xCount(card, NumLifeX[0]);
                     
                      return 0;
                   }
                   
                   public boolean canPlayAI()
                   {
                      if (Tgt[0] == true)
                         setTargetPlayer(Constant.Player.Computer);
                     
                      if (AllZone.Computer_Life.getLife() < 10)
                         return true;
                      else
                      {
                         Random r = new Random();
                         return (r.nextFloat() < .6667);
                      }
                   }

                  public void resolve()
                     {
                        int nlife = getNumLife();
                        String TgtPlayer;

                        if (Tgt[0] == true)
                           TgtPlayer = getTargetPlayer();
                        else
                           TgtPlayer = card.getController();
                       
                        AllZone.GameAction.addLife(TgtPlayer, nlife);
                       
                        if (!DrawBack[0].equals("none"))
                           CardFactoryUtil.doDrawBack(DrawBack[0], nlife, card.getController(), AllZone.GameAction.getOpponent(card.getController()), TgtPlayer, card, null);
                     }//resolve()
                  };//SpellAbility
                 
                  if (Tgt[0] == true)
                     spGainLife.setBeforePayMana(CardFactoryUtil.input_targetPlayer(spGainLife));
                 
                  spGainLife.setDescription(spDesc[0]);
                  spGainLife.setStackDescription(stDesc[0]);
                 
                  card.clearSpellAbility();
                  card.addSpellAbility(spGainLife);
                 
                  String bbCost = card.getSVar("Buyback");
                  if (!bbCost.equals(""))
                  {
                     SpellAbility bbGainLife = spGainLife.copy();
                     bbGainLife.setManaCost(CardUtil.addManaCosts(card.getManaCost(), bbCost));
                     bbGainLife.setDescription("Buyback " + bbCost + "(You may pay an additional " + bbCost + " as you cast this spell. If you do, put this card into your hand as it resolves.)");
                     bbGainLife.setIsBuyBackAbility(true);
                     
                     if (Tgt[0] == true)
                         bbGainLife.setBeforePayMana(CardFactoryUtil.input_targetPlayer(bbGainLife));
                     
                     card.addSpellAbility(bbGainLife);
                  }
           }
        }//spGainLife
CardFactoryUtil.doXMath():
Code: Select all
        else if(s[0].contains("Negative")) return num * -1;
        else if(s[0].contains("Times")) return num * Integer.parseInt(s[1]); // added with spGainLife
        else return num;
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: spGainLife[Tgt] keyword

Postby Chris H. » 23 Mar 2010, 10:57

Thank you. :D

I see that there is a few cards to be converted over. The new cards look interesting.
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: spGainLife[Tgt] keyword

Postby Chris H. » 23 Mar 2010, 15:41

A couple of the new spGainLife spells use Flashback as a keyword. My memory has gotten foggy (old age) and I seem to think that there was something about using Flashback as a keyword. :-k

I put together a test deck with Ancestral Tribute and Folk Medicine and when they were cast they did not appear in the Flashback window and I could not cast them a second time.

I tried another test deck with older Flashback spells and they worked correctly but the other Flashback spells are all hard coded. I think we should hold off on adding Ancestral Tribute and Folk Medicine at this time.

There are still a lot of new cards to add and there are 7 cards to convert over … should keep me busy for a while. :)
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: spGainLife[Tgt] keyword

Postby Chris H. » 25 Mar 2010, 02:02

Chris H. wrote:There are still a lot of new cards to add and there are 7 cards to convert over … should keep me busy for a while. :)
`
I am in the process of converting and merging these cards:


These 3 cards are part of a 4 card method and the fourth card, Renewed Faith can not yet be converted to keyword. I cleaned up the card object and we have a canPlay() section that appears to do very little if anything. What does the super.canPlay() do? Is it safe to remove this small section before I merge this material into our SVN?

Code: Select all
        //*************** START *********** START **************************
        else if(cardName.equals("Renewed Faith")) {
            SpellAbility spell = new Spell(card) {
                private static final long serialVersionUID = -1133816506198725425L;
               
                @Override
                public boolean canPlay() {
                    return super.canPlay();
                }
               
                @Override
                public void resolve() {
                    PlayerLife life = AllZone.GameAction.getPlayerLife(card.getController());
                    life.addLife(6);
                }
            };
           
            StringBuilder spDesc = new StringBuilder();
            spDesc.append("You gain 6 life.");
            spDesc.append("\r\n");
            spDesc.append("When you cycle Renewed Faith, you may gain 2 life.");
            spell.setDescription(spDesc.toString());
           
            StringBuilder stDesc = new StringBuilder();
            stDesc.append("Renewed Faith - ");
            stDesc.append(card.getController());
            stDesc.append(" gains life.");
            spell.setStackDescription(stDesc.toString());
           
            card.clearSpellAbility();
            card.addSpellAbility(spell);
           
            if (cardName.equals("Renewed Faith")) {
                card.addCycleCommand(new Command() {
                    private static final long serialVersionUID = 7699412574052780825L;
                   
                    public void execute() {
                        PlayerLife life = AllZone.GameAction.getPlayerLife(card.getController());
                        life.addLife(2);
                    }
                });
            }
        }//*************** END ************ END **************************
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: spGainLife[Tgt] keyword

Postby Rob Cashwalker » 25 Mar 2010, 02:44

Renewed Faith could be done by keyword for the life gain ability, and then the CardFactory code only needs to add the special cycling command near then end of the block.
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: spGainLife[Tgt] keyword

Postby DennisBergkamp » 25 Mar 2010, 04:11

These 3 cards are part of a 4 card method and the fourth card, Renewed Faith can not yet be converted to keyword. I cleaned up the card object and we have a canPlay() section that appears to do very little if anything. What does the super.canPlay() do? Is it safe to remove this small section before I merge this material into our SVN?
Yeah you can remove the whole canPlay() block (super.canPlay() is just the default).
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: spGainLife[Tgt] keyword

Postby Chris H. » 25 Mar 2010, 13:12

Thank you guys. Turns out that all we really need here is:

Code: Select all
//*************** START *********** START **************************
else if (cardName.equals("Renewed Faith")) {

    card.addCycleCommand(new Command() {
        private static final long serialVersionUID = 7699412574052780825L;
                   
        public void execute() {
            PlayerLife life = AllZone.GameAction.getPlayerLife(card.getController());
            life.addLife(2);
        }
    });
}//*************** END ************ END **************************
`
:)
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: spGainLife[Tgt] keyword

Postby DennisBergkamp » 25 Mar 2010, 19:04

Nice stuff!! I see we have 2880 cards now :)
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: spGainLife[Tgt] keyword

Postby susan123 » 23 Apr 2010, 07:15

very nice ans informative discussion takes place in this post,..........
i really appreciate it,..




thomas sabo on sale
thomas sabo
thomas sabo
thomas sabo
susan
susan123
 
Posts: 1
Joined: 23 Apr 2010, 07:11
Has thanked: 0 time
Been thanked: 0 time


Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 36 guests

Main Menu

User Menu

Our Partners


Who is online

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

Users browsing this forum: No registered users and 36 guests

Login Form