Page 6 of 8

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 26 Jan 2011, 14:13
by Hellfish
I've made a little progress, and unfortunately my hunch was wrong. There's something funky happening with the input state. Somewhere between GameAction.playSpellAbility and Input_PayManaCost_Ability.selectCard, the input state isn't set properly to "paying the triggered ability" and remains in "paying the activated ability", if that makes any sense.

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 26 Jan 2011, 14:39
by friarsol
Yea I really had to wrestle the Input controls into doing what I wanted since it's not very flexible. So what exactly is the situation and where is it falling apart? Spellbomb goes to the graveyard? You want to activate it, but you never get the opportunity? What activated ability are you still being forced to pay? Give me a sample and your steps and I'll try to debug it.

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 26 Jan 2011, 14:57
by Hellfish
My test case is Origin Spellbomb and one plains.
Play the Plains,
Generate Mana to pay for casting and activating the spellbomb,
Choose Yes when asked about using it's triggered ability,
Attempt to tap the plains for mana or take from the mana pool.

If you put a breakpoint on GuiControl.selectCard you can see that the InputControl is still in the activated abilities payment-input state when you try to tap the plains to pay for the triggered ability.

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 26 Jan 2011, 15:44
by friarsol
Hmm.. It looks like the problem is related to when payment is taking place. It should be taking place on resolution, but it's actually taking place before the trigger goes on the stack. The same is true for may triggers. They always go on the stack and then on resolution you choose whether or not to activate it.

So the Trigger interrupts the Cost_Payment of the Spellbomb's Activation. It gets put on the Input Queue. Then the original Ability finishes resolving, the state never gets reset to it's base state because there is something in the waiting queue. And then the input gets in a bad state.

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 26 Jan 2011, 20:50
by Hellfish
Ok, got it to work, but A) it's messy and B) I'm not sure it's 100% correct.

what I do is basically propagate a single boolean through the whole chain of functions that handle cost payment, which denotes that the associated SpellAbility should skip the stack. Then I created a counterpart to ComputerUtil.playNoStack() for the humanplayer (GameAction.playSpellAbility_NoStack()), which is used by the wrapperAbility.resolve() in Triggerhandler. The wrapper ability in itself is free and always put on the stack when the trigger goes off, in it's resolve it asks the player if they want to make use of it and has them play any costs (via the messy playSpellAbility_NoStack()). Otherwise the actual ability created by the trigger is put on the stack as an additional entry after the wrapper resolves.

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 26 Jan 2011, 21:10
by friarsol
Hellfish wrote:Ok, got it to work, but A) it's messy and B) I'm not sure it's 100% correct.

what I do is basically propagate a single boolean through the whole chain of functions that handle cost payment, which denotes that the associated SpellAbility should skip the stack. Then I created a counterpart to ComputerUtil.playNoStack() for the humanplayer (GameAction.playSpellAbility_NoStack()), which is used by the wrapperAbility.resolve() in Triggerhandler. The wrapper ability in itself is free and always put on the stack when the trigger goes off, in it's resolve it asks the player if they want to make use of it and has them play any costs (via the messy playSpellAbility_NoStack()). Otherwise the actual ability created by the trigger is put on the stack as an additional entry after the wrapper resolves.
Alright I'm not sure if what you said lines up or not (particularly the additional entry bit)
1) Trigger occurs. Any targets occur now.
2) Trigger starts resolving. If it's Optional the player says yes or no. If there is any Cost, this occurs now.
3) Trigger continues resolving.
a) If player chooses no or did not pay the cost properly, the ability ends, not resolving the inner ability.
b) Everything has been paid/chosen properly. Resolve the inner ability (don't place it on the stack).
4) Trigger finishes resolving.

This definitely sounds like a mess. We'll have to build some type of structure within the Trigger that handles this better.

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 26 Jan 2011, 21:20
by Hellfish
Almost, except targeting occurs after accepting (if it's optional) and payment. :/

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 26 Jan 2011, 21:33
by friarsol
Hellfish wrote:Almost, except targeting occurs after accepting (if it's optional) and payment. :/
Hmm.. the outer-most Ability doesn't target for the AF Ability?

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 26 Jan 2011, 21:43
by Hellfish
Oh yeah, you're right, I was just confused after only working with the non-targeting spellbombs in this matter.

What I meant with the additional entry bit was that if I didn't do all that messy extra code for having the actual spellability skip the stack, it would be put on the stack as an additional entry when the wrapper resolves.

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 26 Jan 2011, 22:07
by friarsol
Hellfish wrote:What I meant with the additional entry bit was that if I didn't do all that messy extra code for having the actual spellability skip the stack, it would be put on the stack as an additional entry when the wrapper resolves.
Oh good. I was worried the triggered abilities were doubling up on the stack. Unfortunately we might be stuck with this mess of extra code for this release. But we should have plenty of time to iron this out afterwards so we don't have to use dummy abilities just to get the timing to be proper.

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 26 Jan 2011, 22:11
by Hellfish
Alright, I'll commit it then and make a note to purge this monstrosity when I can. :P

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 26 Jan 2011, 22:35
by friarsol
Hellfish wrote:Alright, I'll commit it then and make a note to purge this monstrosity when I can. :P
So I just tested this (for targeting) and it didn't seem to work. I tested Bala Ged Scorpion, Memnite, Ornithopter. It never prompts me to target. It should prompt me before the original trigger hits the stack. And not prompt me when the inner ability actually resolves.

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 26 Jan 2011, 22:53
by Hellfish
I think I see what's happening. GameAction.playSpellAbility decides not to fill any requirements because the wrapper doesn't pass a Ability_Cost,possibly.
EDIT:Getting closer, now it targets on both triggering and resolving. #-o
EDIT2:Welp, fixed it with more messy code. :? I guess this release will be stage 1: get it to work. Next release will be stage 2: make it fit and look nice.

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 27 Jan 2011, 04:14
by friarsol
We may need to tweak how the AI handles triggers too. For Triggers that don't cost anything should be more lenient (I may gain 1 life? Of course I want to gain life) instead of considering it in the same light as an Ability. For mandatory triggers, if the Human doesn't have any of a cursed trigger the AI should have to target itself.

Eventually, we should have some logic to look for ETB effects and only cast them if the Human has a valid/worthy target.

Re: Trigger discussion (was WheneverKeyword reference)

PostPosted: 28 Jan 2011, 20:41
by Hellfish
Added another example to the wiki page as requested by Zirbert, what, four pages ago? :oops: