Page 1 of 1

Cascade and Kicker

PostPosted: 08 May 2010, 21:04
by jim
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());
        }

Re: Cascade and Kicker

PostPosted: 08 May 2010, 23:27
by DennisBergkamp
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.

Re: Cascade and Kicker

PostPosted: 09 May 2010, 00:57
by jim
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!

Re: Cascade and Kicker

PostPosted: 09 May 2010, 03:11
by DennisBergkamp
No probs, thanks for taking care of this!

Re: Cascade and Kicker

PostPosted: 16 May 2010, 00:35
by jim
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.

Re: Cascade and Kicker

PostPosted: 16 May 2010, 13:41
by jim
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.

Re: Cascade and Kicker

PostPosted: 16 May 2010, 13:53
by Chris H.
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:

Re: Cascade and Kicker

PostPosted: 16 May 2010, 17:19
by DennisBergkamp
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.

Re: Cascade and Kicker

PostPosted: 16 May 2010, 19:54
by jim
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?

Re: Cascade and Kicker

PostPosted: 16 May 2010, 20:06
by DennisBergkamp
Hmm, interesting. Well if this does work (and the original Regrowth spell also still works), I don't see a reason why not?

Re: Cascade and Kicker

PostPosted: 22 May 2010, 10:56
by jim
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.

Re: Cascade and Kicker

PostPosted: 22 May 2010, 21:24
by DennisBergkamp
Thanks Jim. Yes, this is most likely the reason...