It is currently 12 Sep 2025, 14:36
   
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 Triadasoul » 03 Dec 2009, 22:48

The last card before i start to figure out how SVN works.

Lurking Informant
Code: Select all
cardfactory_creature:
//*************** START *********** START **************************
       else if(cardName.equals("Lurking Informant"))
       {
         final SpellAbility a1 = new Ability_Tap(card, "2")
         {
            private static final long serialVersionUID = 1446529067071763245L;
             public void resolve()
           {
                    String player = getTargetPlayer();
                    
                    PlayerZone lib = AllZone.getZone(Constant.Zone.Library, player);
                    PlayerZone grave = AllZone.getZone(Constant.Zone.Graveyard, player);
                    CardList libList = new CardList(lib.getCards());
                    Card c = libList.get(0);
                    String[] choices = {"Yes", "No"};
                    if(card.getController().equals(Constant.Player.Human))
                    {
                         Object o = AllZone.Display.getChoice("Mill " + c.getName() + " ?" , choices);
                         if(o.equals("Yes"))
                           {lib.remove(c);
                            grave.add(c);
                           }
                    }
                    else {
                    CardList landlist = new CardList();
                   landlist.addAll(AllZone.Human_Play.getCards());
                   // i have no better idea how AI could use it then letting draw unneeded lands
                   // this part will be good place to use card values lists or card values deck info
                   if (countLands(card) > 5 && !c.getType().contains("Land"))
                                  {
                                      lib.remove(c);
                                         grave.add(c);
                                  }
                  if (countLands(card) <= 5)
                                      {
                                   lib.remove(c);
                                   grave.add(c);
                                      }
                    }
                  
            
           }
             private int countLands(Card c)
           {
              PlayerZone play = AllZone.getZone(Constant.Zone.Play, c
                    .getController());
              CardList lands = new CardList(play.getCards());
              lands = lands.getType("Land");
              return lands.size();
           }
          
           public boolean canPlayAI()
           {
               String player = getTargetPlayer();
                PlayerZone lib = AllZone.getZone(Constant.Zone.Library, player);
                CardList libList = new CardList(lib.getCards());
                return libList.size() > 0;
           }
         };//SpellAbility
         card.addSpellAbility(a1);
         a1.setDescription("2, tap: Look at the top card of target player's library. You may put that card into that player's graveyard.");
         a1.setStackDescription("Lurking Informant ability");
         a1.setBeforePayMana(new Input_PayManaCost(a1));
         a1.setBeforePayMana(CardFactoryUtil.input_targetPlayer(a1));
       }//*************** END ************ END **************************
===================================================================================
Lurking Informant
1 UB
Creature Human Rogue
no text
1/2
===================================================================================
lurking_informant.jpg     http://www.wizards.com/global/images/magic/general/lurking_informant.jpg
Triadasoul
 
Posts: 223
Joined: 21 Jun 2008, 20:17
Has thanked: 0 time
Been thanked: 4 times

Re: Programming a card

Postby DennisBergkamp » 04 Dec 2009, 00:23

Triadasoul wrote:Also Gaddock Teeg =).
This could be implemented with casting cost altering (free spells/cheaper spells) to kill two birds with one stone. So we could set banned cards casting cost to 999999.

PS: I've pm'ed you the gmail account.
Well, I don't think setting banned cards casting cost to 99999 would be a good idea (I think about half of Mr Chaos' decks will still be able to cast these cards with those Gaea's Cradle and Priest of Titania :lol: ).
I was thinking of just using a keyword, "This card cannot be cast" maybe? I started coding an attempt, I'll post it once I've finished it and if it actually works :)
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 » 04 Dec 2009, 00:50

I think about half of Mr Chaos' decks will still be able to cast these cards with those Gaea's Cradle and Priest of Titania
I think this will be too slow with PCs productivity :lol:

I was thinking of just using a keyword, "This card cannot be cast" maybe? I started coding an attempt, I'll post it once I've finished it and if it actually works
Great! thank you :D

Freaky Dovescape implementation of mine. But it seems to work with current counterspell implementation even if there are many copies of it in play.

Code: Select all
GameactionUtil
playCard_Dovescape(c);

public static void playCard_Dovescape(Card c)
   {
      PlayerZone hplay = AllZone.getZone(Constant.Zone.Play,
            Constant.Player.Human);
      PlayerZone cplay = AllZone.getZone(Constant.Zone.Play,
            Constant.Player.Computer);

      CardList list = new CardList();
      list.addAll(hplay.getCards());
      list.addAll(cplay.getCards());
        int cmc = CardUtil.getConvertedManaCost(c.getManaCost());
      list = list.getName("Dovescape");
      if ( ! c.getType().contains("Creature") && list.size()>0 ) {
   
         
         final Card card = list.get(0);

         Ability ability2 = new Ability(card, "0")
         {
            public void resolve()
            {
               SpellAbility sa = AllZone.Stack.pop();
               
                   AllZone.GameAction.moveToGraveyard(sa.getSourceCard());
         
            }
         }; // ability2

         ability2.setStackDescription("Dovescape Ability");
         AllZone.Stack.add(ability2);
   
      for (int j = 0; j < list.size()*cmc; j++)
      {
         Card crd = new Card();
            String controller = c.getController();
         crd.setOwner(controller);
         crd.setController(controller);
         
         crd.setName("Bird");
         crd.setImageName("WU 1 1 Bird");
         crd.setManaCost("WU");
         crd.setToken(true);

         crd.addType("Creature");
         crd.addType("Bird");
         crd.addIntrinsicKeyword("Flying");

         crd.setBaseAttack(1);
         crd.setBaseDefense(1);

         PlayerZone play = AllZone.getZone(Constant.Zone.Play, controller);
         play.add(crd);
      }
      }
   }
=======================================================================================
cards.txt
Dovescape
3 WU WU WU
Enchantment
Whenever a player casts a noncreature spell, counter that spell. That player puts X 1/1 white and blue Bird creature tokens with flying onto the battlefield, where X is the spell’s converted mana cost.
=======================================================================================
card-pictures.txt
dovescape.jpg         http://www.wizards.com/global/images/magic/general/dovescape.jpg
Triadasoul
 
Posts: 223
Joined: 21 Jun 2008, 20:17
Has thanked: 0 time
Been thanked: 4 times

Re: Programming a card

Postby Marek14 » 04 Dec 2009, 08:01

Triadasoul wrote:Also Gaddock Teeg =).
This could be implemented with casting cost altering (free spells/cheaper spells) to kill two birds with one stone. So we could set banned cards casting cost to 999999.

PS: I've pm'ed you the gmail account.
Other cards that need mechanism for banning spellcasting:

Abeyance
AEther Storm
Arcane Laboratory
Brand of Ill Omen
Cease-Fire
Circu, Dimir Lobotomist (already mentioned)
Colfenor's Plans
Cornered Market
Ethersworn Canonist
Grid Monitor
Hand to Hand
Llawan, Cephalid Empress
Mana Maze
Orim's Chant
Oriss, Samite Guardian
Rule of Law
Sen Triplets
Silence
Steel Golem
Xantid Swarm
Yawgmoth's Agenda
Voidstone Gargoyle
(split second cards)
(epic cards)

And for activated abilities:
Arrest
Cursed Totem
Damping Matrix
Detainment Spell
Faith's Fetters
Gelid Shackles
Ice Cage
Interdict
Katabatic Winds
Lost in Thought
Null Rod
Pithing Needle
Prison Term
Serra Bestiary
Stasis Cocoon
Stupefying Touch
Trickbind
Volrath's Curse

As for cost changing, here are effects that increase costs of other spells or abilities:
Alabaster Leech
Andradite Leech
Aura of Silence
Brutal Suppression
Chill
Defense Grid
Derelor
Drought
Feroz's Ban
Gloom
Glowrider
Grand Arbiter Augustin IV
High Seas
Hum of the Radix
Irini Sengir
Jade Leech
Kaervek's Torch
Ruby Leech
Sapphire Leech
Sphere of Resistance
Squeeze
Suppression Field
Thorn of Amethyst

Effects that reduce costs of other spells or abilities:
Ballyrush Banneret
Blood Funnel
Bosk Banneret
Brighthearth Banneret
Centaur Omenreader
Cloud Key
Daru Warchief
Dragonspeaker Shaman
Dream Chisel
Edgewalker
Emerald Medallion
Etherium Ssculptor
Frogtosser Banneret
Goblin Warchief
Grand Arbiter Augustin IV
Helm of Awakening
Jet Medallion
Krosan Drover
Krosan Warchief
Locket of Yesterdays
Long-Forgotten Gohei
Mana Matrix
Mistform Warchief
Mycosynth Golem
Nightscape Familiar
Pearl Medallion
Planar Gate
Ruby Medallion
Sapphire Medallion
Spellwild Ouphe
Stinkdrinker Daredevil
Stone Calendar
Stonybrook Banneret
Stormscape Familiar
Sunscape Familiar
Thornscape Familiar
Thunderscape Familiar
Undead Warchief
Urza's Filter
Urza's Incubator

And, applied after all of these:
Trinisphere
Marek14
Tester
 
Posts: 2773
Joined: 07 Jun 2008, 07:54
Has thanked: 0 time
Been thanked: 303 times

Re: Programming a card

Postby Triadasoul » 04 Dec 2009, 12:03

Dennis could you add in Gameactionutil executeEndofTurnEffects support similar to executeUpkeepEffects(), for transforming and removing effects from Thistledown Duo or Shorecrasher Mimic?

And what's up with Carnophage i've posted earlier ?
Triadasoul
 
Posts: 223
Joined: 21 Jun 2008, 20:17
Has thanked: 0 time
Been thanked: 4 times

Re: Programming a card

Postby Rob Cashwalker » 04 Dec 2009, 15:56

End of Turn effects are handled already -

AllZone.EndOfTurn.addUntil(Command)
AllZone.EndOfTurn.addAt(Command)
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 Triadasoul » 04 Dec 2009, 16:48

Rob Cashwalker wrote:End of Turn effects are handled already -

AllZone.EndOfTurn.addUntil(Command)
AllZone.EndOfTurn.addAt(Command)
Thank you, i think i had an idea how to implement Mimic then :D
Triadasoul
 
Posts: 223
Joined: 21 Jun 2008, 20:17
Has thanked: 0 time
Been thanked: 4 times

Re: Programming a card

Postby DennisBergkamp » 04 Dec 2009, 20:03

I see you figured out how to use the SVN, very good :)

I haven't added Carnophage and Sangrophage yet because I'd like to figure out what's going on with the AI's upkeep first. I know the first few phases have always been kind of buggy (upkeep kind of flows over into the draw phase sometimes), but I did not know the AI's upkeep happened AFTER untap #-o

I've also figured out how to do "uncastable". Meddling Mage seems to work, when it leaves play, the named card can be cast again. I'll also add Iona, Shield of Emeria and Gaddock Teeg, + perhaps some more cards listed by Marek.
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 » 04 Dec 2009, 21:00

It's supposed to be Untap, Upkeep, Draw, Main1, Combat, Main2, End.
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 DennisBergkamp » 04 Dec 2009, 21:16

Argh, yes I meant to say "I didn't know the AI's upkeep is BEFORE his untap phase" :roll:
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 » 04 Dec 2009, 22:32

Great! When i figure out how to update my local version with it automatically, i'll try that lobotomist.

PS: Not only AI'a but a player's upkeep is also before an untap phase.
Triadasoul
 
Posts: 223
Joined: 21 Jun 2008, 20:17
Has thanked: 0 time
Been thanked: 4 times

Re: Programming a card

Postby DennisBergkamp » 04 Dec 2009, 22:58

Updating your local version should work through Team -> update. Sometimes there's some conflicts though, in the Team Synchronize Perspective, you can right click on the files with conflicts, then choose "Edit conflicts". A text compare should pop up between the local and remote versions of the file. When you're done with the changes, save it, and click "Mark as resolved". Then you can also commit the file.

Of course, you can always start a new project, and just import directly from SVN.


About the untap being before upkeep for the player, that seems to work correctly though in Forge, right ?

The Lobotomist might be trickier by the way, you'd have to somehow keep track of the cards he removed.
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 » 04 Dec 2009, 23:25

Thank you :D i've already figured out with synchronization. But i want to have some test copy for my experiments with it, cause not all of my cards work well and they shouldn't be synchronized of course.

Nope, those Carnophages (without keyword "this doesn't untap....") become untapped at player's main1 phase in case their upkeep cost wasn't payed.

Yes i've already encountered this complexity about the list )). Is it correct to build an array of cardnames ? And by the way should there be two entries of lobotomist ability one for spell tracking and one for spell banning purposes or could it be done all in one spell-tracking block ( like Fable of Wolf and Owl )?
Triadasoul
 
Posts: 223
Joined: 21 Jun 2008, 20:17
Has thanked: 0 time
Been thanked: 4 times

Re: Programming a card

Postby nantuko84 » 05 Dec 2009, 00:13

But i want to have some test copy for my experiments with it, cause not all of my cards work well and they shouldn't be synchronized of course.
Well, you can use SVN branches for any experiments. If you do, you do not need to create separate folder for your cards, all your code will be in the same folder and SVN will handle different versions by itself. All you need, is just to switch between branches. And later, when any branch is done, you can merge it back into trunk (that is main brunch). I often use branching for features that can break current version. Though need to say that GIT is more comfortable with branching than SVN.
nantuko84
DEVELOPER
 
Posts: 266
Joined: 08 Feb 2009, 21:14
Has thanked: 2 times
Been thanked: 9 times

Re: Programming a card

Postby Triadasoul » 05 Dec 2009, 00:48

Thank you i'll try it. =)

I have some problem with my Dovescape cause it's countering last ability in the stack instead of the first spell in the stack. How can i get the first spell from the stack full of abilities?
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 37 guests

Main Menu

User Menu

Our Partners


Who is online

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

Login Form