It is currently 09 Sep 2025, 17:51
   
Text Size

Cascade and Kicker

Post MTG Forge Related Programming Questions Here

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

Cascade and Kicker

Postby jim » 08 May 2010, 21:04

Last night I was playing Forge and used Bloodbraid Elf to Cascade into a Burst Lightning. I chose to play the Kicker ability and was pleasantly surprised when I didn't have to pay the additional mana cost. As far as I understand the rules, I should have had to pay the Kicker cost of 4.

I prototyped a fix for this in my local copy. Basically I added a 'setKickerAbility/isKickerAbility' pair of accessors. In the code for BurstLightning, I do the following to the kicker ability:
Code: Select all
            kicker.setManaCost("R 4");
            kicker.setAdditionalManaCost("4");
            kicker.setKickerAbility(true);
            kicker.setBeforePayMana(CardFactoryUtil.input_targetCreaturePlayer(kicker, true, false));
            kicker.setDescription("Kicker: 4");
 
I also changed GameAction.playSpellAbilityForFree to check for the Kicker and ask for the additional mana. The code is below. It's only been tested for the Bloodbraid Elf/Burst Lightning case, but appears to work as expected in that case. If this solution works I'd also change the other cards that have Kicker slightly (I think there are only two).

I am not terribly familiar with Forge's code for either Kicker or Input, and so I am asking for comments on this solution. If someone knows of or planned a better way to fix this I'm happy to defer to them.
Code: Select all
    public void playSpellAbilityForFree(final SpellAbility sa) {
       
       
       if(sa.getBeforePayMana() == null) {
          boolean x = false;
           if (sa.getSourceCard().getManaCost().contains("X"))
              x = true;
          
           if (sa.isKickerAbility()) {
                Command paid1 = new Command() {
                   
                private static final long serialVersionUID = 1L;

                public void execute() {
                        AllZone.Stack.add(sa);
                    }
                };
               AllZone.InputControl.setInput(new Input_PayManaCost_Ability(sa.getAdditionalManaCost(),paid1));              
           }
          AllZone.Stack.add(sa, x);
           
        } else {
           if (sa.isKickerAbility()) {
              sa.getBeforePayMana().setFree(false);
              sa.setManaCost(sa.getAdditionalManaCost());
           } else {
                sa.getBeforePayMana().setFree(true);              
           }
            AllZone.InputControl.setInput(sa.getBeforePayMana());
        }
jim
 
Posts: 46
Joined: 19 Feb 2010, 01:46
Location: Sunny New England
Has thanked: 0 time
Been thanked: 0 time

Re: Cascade and Kicker

Postby DennisBergkamp » 08 May 2010, 23:27

No, I think this is the best way to fix this.
However, you should probably also take into account buyback, I think kicker and buyback are currently the cases for Cascade not working correctly.
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: Cascade and Kicker

Postby jim » 09 May 2010, 00:57

Dennis,

Thanks for pointing out that Buyback is also a problem -- I hadn't noticed that, but it makes sense. I also think that a similar technique will probably handle it. I should be able to get to fixing this during the week. Thanks!
jim
 
Posts: 46
Joined: 19 Feb 2010, 01:46
Location: Sunny New England
Has thanked: 0 time
Been thanked: 0 time

Re: Cascade and Kicker

Postby DennisBergkamp » 09 May 2010, 03:11

No probs, thanks for taking care of this!
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: Cascade and Kicker

Postby jim » 16 May 2010, 00:35

A quick update. I have to admit I've not done much more than look at the Buyback cards at this point -- my real life has not allowed me much time for Forge programming recently. I still intend to go after this, but wanted to admit that it'll take me longer than I thought.
jim
 
Posts: 46
Joined: 19 Feb 2010, 01:46
Location: Sunny New England
Has thanked: 0 time
Been thanked: 0 time

Re: Cascade and Kicker

Postby jim » 16 May 2010, 13:41

The other two Kicker spells we have (Conquerer's Pledge and Gatekeeper of Malakir) should now work with Cascade too. I tested Conquerer's Pledge but not Gatekeeper of Malakir.

Next I need to fix the AI for Cascade-Kicker and then fix both the Human and the AI for Cascade-Buyback.

I spent some time looking at the Cascade-Regrowth bug (Regrowth asks for its input twice when Cascaded) but have nothing useful to suggest yet.
jim
 
Posts: 46
Joined: 19 Feb 2010, 01:46
Location: Sunny New England
Has thanked: 0 time
Been thanked: 0 time

Re: Cascade and Kicker

Postby Chris H. » 16 May 2010, 13:53

Thank you Jim.

It is not always easy to find the time or to figure out how to handle a given situation ... I too at times find myself doing the easy and simple work and I will put off the more difficult problems and bugs. :wink:
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: Cascade and Kicker

Postby DennisBergkamp » 16 May 2010, 17:19

Nice job Jim, thanks =D>
It's good to see Cascade is almost working correctly. I'm not sure about the Regrowth bug either, but it's not the first time I've seen weird stuff happening when inputs are involved.
Things just get reset in a funky way, and parts of code get re-executed when not expected... I think basically the same thing was happening with Zur the Enchanter and Oblivion Ring.
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: Cascade and Kicker

Postby jim » 16 May 2010, 19:54

In the code for Regrowth I reversed the two lines stop() and AllZone.Stack.add(spell); below (stop() used to be second: now it is first). After this change, I no longer see the input dialog twice when Regrowth is played with Cascade.
Code: Select all
if(this.isFree()) {
    this.setFree(false);
    stop();
    AllZone.Stack.add(spell);
}
I admit I don't understand this and so am reluctant to check it in :? However, it's only in Regrowth's code and so really can only affect Regrowth's interaction with Cascade. Does anybody see a reason not to do this?
jim
 
Posts: 46
Joined: 19 Feb 2010, 01:46
Location: Sunny New England
Has thanked: 0 time
Been thanked: 0 time

Re: Cascade and Kicker

Postby DennisBergkamp » 16 May 2010, 20:06

Hmm, interesting. Well if this does work (and the original Regrowth spell also still works), I don't see a reason why not?
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: Cascade and Kicker

Postby jim » 22 May 2010, 10:56

Okay, I believe the Regrowth bug is fixed now in the SVN. (Yes, I've been very slow again this week.)

We have the 'this.isFree()' code all over CardFactory. However, Regrowth appears to be the only place where we use it inside showMessage() -- everywhere else we use it inside selectCard(). My guess is that this is why the problem occurred.
jim
 
Posts: 46
Joined: 19 Feb 2010, 01:46
Location: Sunny New England
Has thanked: 0 time
Been thanked: 0 time

Re: Cascade and Kicker

Postby DennisBergkamp » 22 May 2010, 21:24

Thanks Jim. Yes, this is most likely the reason...
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time


Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 51 guests

Main Menu

User Menu

Our Partners


Who is online

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

Login Form