It is currently 09 Sep 2025, 04:43
   
Text Size

Two cards with {cost}, Sacrifice CARDNAME: Add {mana} to yo

Post MTG Forge Related Programming Questions Here

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

Two cards with {cost}, Sacrifice CARDNAME: Add {mana} to yo

Postby Sloth » 02 Jun 2010, 12:15

I found 2 cards that can be added to cards.txt:

Code: Select all
Implements of Sacrifice
2
Artifact
no text
1, tap, Sacrifice CARDNAME: Add W W to your mana pool.
1, tap, Sacrifice CARDNAME: Add U U to your mana pool.
1, tap, Sacrifice CARDNAME: Add B B to your mana pool.
1, tap, Sacrifice CARDNAME: Add R R to your mana pool.
1, tap, Sacrifice CARDNAME: Add G G to your mana pool.

Kaleidostone
2
Artifact
no text
When CARDNAME enters the battlefield, draw a card.
5, tap, Sacrifice CARDNAME: Add W U B R G to your mana pool.
in card-pictures.txt:
Code: Select all
implements_of_sacrifice.jpg      http://www.wizards.com/global/images/magic/general/implements_of_sacrifice.jpg
kaleidostone.jpg      http://www.wizards.com/global/images/magic/general/kaleidostone.jpg
Thanks for adding Grave-Shell Scarab Chris!

PS: Little Fix: Fire-Field Ogre has an Unearth cost of U B R not 1 U B R
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: Two cards with {cost}, Sacrifice CARDNAME: Add {mana} t

Postby Chris H. » 02 Jun 2010, 19:11

Thank you for your submissions Sloth. Unfortunately, the Implements of Sacrifice card displays the same cosmetic problem as the Wild Cantor card.

Cards that have more than one copy of this keyword bring up a Choose dialog where we choose one of these spell abilities from a list. "CARDNAME" is displayed in the listing and is not being replaced automatically with the card's name.

I found several lines of code in the Ability_Mana.java class and I discovered that I could add several lines of code which would give us several versions of this keyword. We could use this version where there is only one spell ability:

Code: Select all
{cost}, Sacrifice CARDNAME: Add {mana} to your mana pool.
`
and then use one of the two versions below for cards that have more than one spell ability:

Code: Select all
{cost}, Sacrifice this card: Add {mana} to your mana pool.
{cost}, Sacrifice this creature: Add {mana} to your mana pool.
`
This would prevent the term "CARDNAME" from appearing in the list of choices. "this card" and "this creature" might be less unsightly for our user-base.
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: Two cards with {cost}, Sacrifice CARDNAME: Add {mana} t

Postby Rob Cashwalker » 03 Jun 2010, 02:37

Just guessing, but try modifying SpellAbility.getSpellDescription() to replace CARDNAME, just like Card.getText().
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: Two cards with {cost}, Sacrifice CARDNAME: Add {mana} t

Postby Chris H. » 03 Jun 2010, 10:21

Rob Cashwalker wrote:Just guessing, but try modifying SpellAbility.getSpellDescription() to replace CARDNAME, just like Card.getText().
`
Thank you, Rob. :)

I will take a look at this section of code and will see if I can figure this out.
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: Two cards with {cost}, Sacrifice CARDNAME: Add {mana} t

Postby Chris H. » 03 Jun 2010, 18:50

I examined the code for Card.getText() and the code for SpellAbility.setDescription() and discovered that they both include a line which replaces "CARDNAME" with .getName().

I think that the option panel that asks us to "Choose" from a list of spell abilities is displaying these from a list of keywords. The code which replaces "CARDNAME" with .getName() does not change the actual keyword but the spell description text?
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: Two cards with {cost}, Sacrifice CARDNAME: Add {mana} t

Postby Rob Cashwalker » 04 Jun 2010, 19:36

That's odd.

The idea is that the "keyword" representation of an ability should stay the same, while the outward appearance is that CARDNAME is replaced on the fly.

The GUI for the list may be called in different ways, so the ManaAbility may populate the list differently, I guess.
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: Two cards with {cost}, Sacrifice CARDNAME: Add {mana} t

Postby DennisBergkamp » 04 Jun 2010, 21:44

Yeah, exactly... I've played around with this a bit and couldn't really find a way to do a string replace.
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: Two cards with {cost}, Sacrifice CARDNAME: Add {mana} t

Postby Chris H. » 07 Jun 2010, 15:10

This gets even odder. I replaced all of the CARDNAME with the actual card's name for these cards in cards.txt. I then found and modified two sections of code in Abiility_Mana.isSacrifice()

Code: Select all
    public boolean isSacrifice()
    {
       return orig.contains("Sacrifice CARDNAME: Add ") ||
             orig.contains("Sacrifice " + sourceCard.getName() + " : Add ");
    }
`
and in Ability_Mana.mana()

Code: Select all
       else if ((orig.contains("Sacrifice this creature: Add ") ||
             orig.contains("Sacrifice CARDNAME: Add ") ||
             orig.contains("Sacrifice " + sourceCard.getName() + ": Add "))
             
             && orig.contains(" to your mana pool."))
       {
          String m = orig.split(": Add ")[1].split(" to ")[0];
          return m;
       }
`
and ran a test deck. The cards in question still display CARDNAME in the choose window. I may have made a simple mistake. I will take a second look at this later. But I am starting to feel that it is time to move on.
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: Two cards with {cost}, Sacrifice CARDNAME: Add {mana} t

Postby Rob Cashwalker » 08 Jun 2010, 14:41

It starts in GameAction.playCard:
Code: Select all
} else {
            SpellAbility[] choices = canPlaySpellAbility(c.getSpellAbility());
            SpellAbility sa;
            /*
             System.out.println(choices.length);
             for(int i = 0; i < choices.length; i++)
                 System.out.println(choices[i]);
            */
            if(choices.length == 0) return;
            else if(choices.length == 1) sa = choices[0];
            else {
               sa = AllZone.Display.getChoiceOptional("Choose", choices);
Display.getChoiceOptional:
Code: Select all
public <T> T getChoiceOptional(String message, T... choices);
Wow... um... huh?

Searching for "getChoiceOptional" I find the real meat of it in GuiDisplay2 and GuiDisplay3:
Code: Select all
    public <T> T getChoiceOptional(String message, T... choices) {
        if(choices == null || choices.length == 0) return null;
        List<T> choice = getChoices(message, 0, 1, choices);

...
    public <T> List<T> getChoices(String message, int min, int max, T... choices) {
        ListChooser<T> c = new ListChooser<T>(message, min, max, choices);
        final JList list = c.getJList();
        list.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent ev) {
                if(list.getSelectedValue() instanceof Card) {
                    setCard((Card) list.getSelectedValue());
                }
            }
        });
        c.show();
        return c.getSelectedValues();
ListChooser:
Code: Select all
   public ListChooser(String title, String message, int minChoices, int maxChoices, List<T> list) {
        this.title = title;
        this.minChoices = minChoices;
        this.maxChoices = maxChoices;
        this.list = unmodifiableList(list);
        jList = new JList(new ChooserListModel());
        ok = new CloseAction(OK_OPTION, "OK");
        ok.setEnabled(minChoices == 0);
        cancel = new CloseAction(CANCEL_OPTION, "Cancel");
       
        Object[] options;
        if(minChoices == 0) options = new Object[] {new JButton(ok), new JButton(cancel)};
        else options = new Object[] {new JButton(ok)};
       
        p = new JOptionPane(new Object[] {message, new JScrollPane(jList)}, QUESTION_MESSAGE, DEFAULT_OPTION,
                null, options, options[0]);
Notice, nowhere along the way here, did any of this code attempt to extract the spell description. So internally, the list chooser must try to use ".toString()".
SpellAbilityList has a toString method, as does SpellAbility itself. But since Ability_Mana extends SpellAbility, the Ability_Mana.toString overrides it:
Code: Select all
    public String toString() {
        return orig;
orig is used throughout Ability_Mana looking for "CARDNAME" to key off the different effects. So it hasn't received any replacement.

BTW, SpellAbility.toString is bad as well:
Code: Select all
    public String toString() {
       if (description.contains("CARDNAME"))
          description = description.replace("CARDNAME", this.getSourceCard().getName());
        return description;
It modifies the underlying description. So if some effect wants to examine the actual description for CARDNAME later, it can't. "getDescription" should be separate from "toString", though in "getDescription" sometimes you might want to see "CARDNAME" and sometimes you don't....
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: Two cards with {cost}, Sacrifice CARDNAME: Add {mana} t

Postby Chris H. » 08 Jun 2010, 17:06

Thank you for looking into this situation.

Wow... um... huh?
`

Most of the code that you point out is over my level of knowledge and comprehension. I guess with a worst case scenario I could convert that one keyword to use "this creature" or "this card". :)
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: Two cards with {cost}, Sacrifice CARDNAME: Add {mana} t

Postby silly freak » 10 Jun 2010, 20:48

Code: Select all
public <T> T getChoiceOptional(String message, T... choices);
Wow... um... huh?
the "<T>" is a generic declaration. essentially, it means that the compiler replaces the type when calling. "T..." is a "vararg" array. for example, you could call it like

Code: Select all
String choice = getChoiceOptional("Title", "a", "b");
The compiler translates this into

Code: Select all
String choice = getChoiceOptional("Title", new String[] {"a", "b"});
and also knows that <T> is, for this single call, <String>

that's the magic ;)
___

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

Re: Two cards with {cost}, Sacrifice CARDNAME: Add {mana} t

Postby Rob Cashwalker » 11 Jun 2010, 04:09

So I'm correct in guessing that the chooser is using toString (a semi-standard method most objects should implement) to generate the list? Therefore changing the Ability_Mana.toString to include the replacement should do the trick?
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


Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 39 guests

Main Menu

User Menu

Our Partners


Who is online

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

Login Form