It is currently 15 Aug 2025, 01:14
   
Text Size

Trigger discussion (was WheneverKeyword reference)

Post MTG Forge Related Programming Questions Here

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

Trigger discussion (was WheneverKeyword reference)

Postby Hellfish » 09 Jan 2011, 13:45

Do we have a reference for how to do things with the WheneverKeyword? I was looking at the Zendikar Quests and was trying to figure out for which ones I'd have to hardcode the circumstances in which you could put a counter on them. (I'm thinking Quest for Pure Flame and Quest for Ula's Temple hardcoded at the very least.)
Last edited by Hellfish on 10 Jan 2011, 11:51, edited 1 time in total.
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Re: WheneverKeyword reference

Postby Sloth » 09 Jan 2011, 15:15

I say the whenever keyword needs a complete rewrite (or at least a very big cleanup) more than a documentation, because the syntax is so random and the AI is flaky for some effects. BeachedAs wrote everything from scratch without using existing structures (and in a chaotic undocumented way).
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: WheneverKeyword reference

Postby Chris H. » 09 Jan 2011, 15:52

I examined the code on several occasions but I do not understand most of it. I like the way Sol designed the AFs. They have keys and values that are fairly easy to see and understand. The old style of keywords is OK but can be hard to interpret if there are many input parameters.
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: WheneverKeyword reference

Postby friarsol » 09 Jan 2011, 15:55

I think anything the Whenever keyword can do, we can do using the AbilityFactory triggering and SubAbilities. If someone wants to give it a shot, they can go for it. I'm currently swamped in overhauling Mana Abilities.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: WheneverKeyword reference

Postby Hellfish » 09 Jan 2011, 16:44

Yeah okay, working on triggers for AFs might be better right now then? And maybe ripping out the WheneverKeyword code afterwards.
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Re: WheneverKeyword reference

Postby friarsol » 09 Jan 2011, 18:04

Hellfish wrote:Yeah okay, working on triggers for AFs might be better right now then? And maybe ripping out the WheneverKeyword code afterwards.
My lofty idealism says yes.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: WheneverKeyword reference

Postby DennisBergkamp » 09 Jan 2011, 23:11

The scariest parts in the WheneverKeyword code:

1. It's really fricking long.
2. All of the objects start with capitals, which for whatever reason, confused me to no end.

Usually I'm pretty good at understanding code just by reading it, but in this case I really had to use a debugger to even see what the heck was going on :mrgreen:
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: WheneverKeyword reference

Postby friarsol » 09 Jan 2011, 23:56

The thing that bothers me the most is the spacing. If it was tabbed properly I think I could understand it a lot better.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: WheneverKeyword reference

Postby Hellfish » 10 Jan 2011, 11:44

Okay, stayed up all night coding and put together something experimental and a bit more easy to read:
Code: Select all
Name:Abyssal Horror
ManaCost:4 B B
Types:Creature Horror
Text:When Abyssal Horror enters the battlefield, target player discards two cards.
PT:2/2
K:Flying
T:Mode$ ChangesZone | From$ Any | To$ Battlefield | ValidCard$ Self | Execute$ ETBDiscard | StackDescription$ Target player discards 2 cards.
SVar:ETBDiscard:AB$Discard | Cost$ 0 | ValidTgts$ Player | TgtPrompt$ Select target player. | NumCards$ 2 | Mode$ TgtChoose
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/abyssal_horror.jpg
SetInfo:USG|Rare|http://magiccards.info/scans/en/us/115.jpg
SetInfo:S99|Rare|http://magiccards.info/scans/en/st/63.jpg
SetInfo:7ED|Rare|http://magiccards.info/scans/en/7e/115.jpg
End
T: lines define a trigger, i.e. "The When".
Then, in an SVar, a regular ability is written and referenced by the trigger, i.e. "The What". (Cost$ should usually be 0, unless it's a "Whenever X, you may pay Y to..."-type deal. Triggers have 3 universal parameters currently: Mode,Execute and Optional.Mode specifies what kind of trigger it is, Execute specifies which SVar contains the ability to trigger and Optional is kind of self-explanatory ;) . All other parameters depend on which Mode is used.

When adding a new trigger-mode, you'd have to do these 3 steps:
  • Add a new private boolean XTest(Trigger trigger,HashMap<String,Object> runParams) method to the new TriggerHandler class, where X is the name of the mode.
  • Add a call to that method from TriggerHandler.runTrigger.
  • Add calls to TriggerHandler.runTrigger from where the trigger should be uh triggered, where you must also fill out the runParams map with all objects that will be needed for the test to work.

Things I'm still working on:
  • SpellDescriptions: At this time, a description of the triggered ability is not added to the card's text box.
  • Parse triggers only once: Right now, they're parsed again and again whenever they are registered with the handler, which is when their host card comes into play. Speaking of which...
  • Parse and register certain triggers before they come into play: There are probably cards with triggered abilities that function outside the battlefield that I just can't recall right now.
  • More modes: DamageDone is in it's infant stages. CastSpell is a possibility. Suggestions welcome!

Of course, this is just an experimental draft, please do point out flaws or suggest alterations.
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Re: Trigger discussion (was WheneverKeyword reference)

Postby Sloth » 10 Jan 2011, 14:19

That looks pretty well thought out to me. Well done Hellfish.

I would like to have additional Conditions (like Threshold, isPresent) as a universal parameter (but maybe this can be handled in the SVar by the conditions of the Abilityfactory).

A few other random thoughts:
1. Does the Optional parameter handle opponents choice (for example Sibilant Spirit)?
2. Does the AI always choose to use the ability (when given the option)?
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: Trigger discussion (was WheneverKeyword reference)

Postby friarsol » 10 Jan 2011, 14:32

Could I request that ChangesZone use Origin and Destination instead of From/To to replicate AF$ChangeZone?
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Trigger discussion (was WheneverKeyword reference)

Postby Hellfish » 10 Jan 2011, 14:54

Sloth wrote:That looks pretty well thought out to me. Well done Hellfish.

I would like to have additional Conditions (like Threshold, isPresent) as a universal parameter (but maybe this can be handled in the SVar by the conditions of the Abilityfactory).

A few other random thoughts:
1. Does the Optional parameter handle opponents choice (for example Sibilant Spirit)?
2. Does the AI always choose to use the ability (when given the option)?
1.Currently the Optional parameter causes the TriggerHandler to ask the hostCards controller wether to trigger the ability at all. I will look deeper into this.
2.Currently AI always accepts if the canPlayAI of the resulting spellability returns true. Something could probably be arranged here.

(Currently is the word of the day :P )
friarsol wrote:Could I request that ChangesZone use Origin and Destination instead of From/To to replicate AF$ChangeZone?
Very yes. :)
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Re: Trigger discussion (was WheneverKeyword reference)

Postby friarsol » 10 Jan 2011, 15:08

So far it's looking good. I would look into the SpellAbility_Restriction class to get some ideas of what might restrict when things could activate (or be triggered). I definitely think "TriggerZone" would be an important one. For cards like: Auntie's Snitch or Bridge from Below
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Trigger discussion (was WheneverKeyword reference)

Postby Hellfish » 10 Jan 2011, 17:27

I think I've almost got it licked, at least as far as the ChangesZone mode is concerned.Now, triggers are only parsed once and registered upon starting a new game (GameAction.newGame()), then restricted with the optional TriggerZone parameter suggested by Sol. Now I just gotta figure out what's bugging the card text :?

The (apparently faulty) code I've used so far is just to loop through the triggers a card has in it's getAbilityText() method and extract the (now obligatory) TriggerDescription parameter, which works exactly like a SpellDescription. I'm not sure what's so wrong with that.
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Re: Trigger discussion (was WheneverKeyword reference)

Postby friarsol » 10 Jan 2011, 17:36

If you use something that can make Patches, you can Patch up your changes and post it to the boards. Then you can get a few more eyes on it. Without seeing anything else, what you are trying to do sounds right, so it must be a "mundane detail" as the boys from Office Space would say.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Next

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 13 guests

Main Menu

User Menu

Our Partners


Who is online

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

Login Form