|
ReedN Wizard
Joined: 04 Jan 2006 Posts: 1279 Location: Portland, Oregon
|
Posted: Wed Mar 19, 2008 4:54 am
Help needed on a multi-state trigger |
I need a little help on a multi-state trigger to capture the text when I do an 'i' for inventory.
The general format of the output is:
You are wielding <bla bla> (This is an optional line that might not be there if I'm not wielding anything)
You are holding:
<things I'm holding>
You are wearing:
<things I'm wearing>
You have \d+ types...
You have \d+ items...
So I've got it all setup for the case when I'm wielding something. Problem is that if I'm not wielding something it will be thrown off and not work because of the extra state in there trying to match on the wielding line when it isn't present. I originally tried to do this by matching on either the wielding or holding lines (1 and 2) and then using either #set or #state to set me back to the same state if it was the optional wielding line and not the holding line. Problem is that I'm horribly confused about #set and #state and so I couldn't figure out a method to make that work. When I set the state back it immediately matched again and advanced, negating the effect I was trying to create.
Can anyone else think of a good way to account for this extra line that may or may not be present?
Code: |
<trigger name="i_trigger" type="Command Input" priority="39670" case="true" regex="true" id="3967">
<pattern>^i</pattern>
<value>#T+ disable_i_trigger</value>
<trigger param="1" case="true" regex="true">
<pattern>^You are wielding</pattern>
<value>#if (%iskey( @flags, silent_herb)) {#gag}</value>
</trigger>
<trigger type="Within Lines" param="1" case="true" regex="true">
<pattern>^You are holding:</pattern>
<value>#if (%iskey( @flags, silent_herb)) {#gag}</value>
</trigger>
<trigger type="Within Lines" param="1" case="true" regex="true">
<pattern>^(.*)$</pattern>
<value>#if (%iskey( @flags, silent_herb)) {#gag}
i_herbs_process %1</value>
</trigger>
<trigger type="Within Lines" param="1" case="true" regex="true">
<pattern>^You are wearing:$</pattern>
<value>#if (%iskey( @flags, silent_herb)) {#gag}</value>
</trigger>
<trigger type="Within Lines" param="1" case="true" regex="true">
<pattern>^(.*)$</pattern>
<value>#if (%iskey( @flags, silent_herb)) {#gag}</value>
</trigger>
<trigger type="Within Lines" param="1" case="true" regex="true">
<pattern>^You have \d+ types of items in the Rift\.$</pattern>
<value>#if (%iskey( @flags, silent_herb)) {#gag}</value>
</trigger>
<trigger type="Within Lines" param="1" case="true" regex="true">
<pattern>^You have \d+ items and (?:no|\d+) gold(?: sovereigns)?\.$</pattern>
<value>#if (%iskey( @flags, silent_herb)) {#gag}
i_del flags silent_herb</value>
</trigger>
</trigger>
|
|
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Wed Mar 19, 2008 6:42 am |
The only way you can deal with optional lines like this, really, is with a separate trigger. You could use a two-part pattern that you then check yourself using %match or %regex, but why try to match something up to four times just for one line? If it were me, I'd have a multistate trigger that started with an oninput state for the i command, that enabled an optional "You're wielding:" trigger. The second state will be the holding like, which disables that trigger.
|
|
|
|
ReedN Wizard
Joined: 04 Jan 2006 Posts: 1279 Location: Portland, Oregon
|
Posted: Wed Mar 19, 2008 7:12 am |
I'm pleased to hear it wasn't something totally obvious that I didn't think of. However, I am very curious as to why my use of #set and #state failed so miserably. I couldn't seem to overcome the effect that when I set it back a state it would immediately evaluate as true and rerun the contents of the trigger state. Perhaps if I had a clearer understanding of these functions it might be obvious to me. I had a real hard time deciphering the sparse explanations for set and state, so perhaps I could solicit any with a deeper understanding to help fill in the blanks:
======================================
Syntax: #SET id state value
Sets or resets a particular trigger state. If "id" is omitted, the last trigger accessed is used. If "value" is omitted, the trigger state is set to true. Otherwise, if Value is zero, the state is set to false. Note states are numbered starting at zero.
SET Example
#SET 0
Sets the first trigger state of the last trigger to true.
STATE
Syntax: #STATE id state
Sets the current state of a trigger. Causes state value to be set to false so that the trigger waits for the state to be matched. If the state number is omitted, the trigger is reset and set to its initial state. Note states are numbered starting at zero.
STATE Example
#STATE 0
Resets the trigger by setting the state value to zero.
======================================
So from what I understand each trigger has however many states the user creates for the particular trigger. The starting state is 0 and all other states are number sequentially from 0.
Each trigger state has a value which can either be true or false meaning it has either been evaluated as true or not. If the value is true and it is on that state then it can proceed to the next state. Otherwise it waits for the value to become true by the fulfulling of the condition of the state.
If I got that correct then the #state command looks like a subset of the #set command which can not only set the state, but can also set the state value to true or false (#state always sets the value to false).
So it looks like these two commands would be the same
#set id state 0
#state id state
So it seems like what I should have wanted to do was to match on either of the two lines, then to test the lines to see if I had the first optionally extra line or the fixed line. If I had the optional line then I would do (#set id 1 0) to set it to the first state with a value of 0 to set the state value to false (not fulfilled). However, I believe I tried this and the problem was that it was immediately executing the content of the first state again when I did the set command. This would seem to indicate that even though I set the state value false it was executing it anyway. |
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Wed Mar 19, 2008 9:59 am |
First, let me start with a disclaimer: I've never used #set. I use #state to move around states; if I want to execute some code that another part of the trigger would run at the same time, I'd rather just run that code than using #set. My understanding is based on playing with it rather than actually using it. With that said:
#state is very much not a subset of #set. #set doesn't set the current state, it just changes the value of a state. I'm not sure when these values get reset to 0 - could be when any state fires, could be when every state has fired (that'd make sense). I see it actually as a subset of #state - you use it to manually fire a state you're already on, if you know the text it's waiting for isn't coming (but if you're going to do that, why not just use #state to move to the next state?). That's obviously not how it's meant to be used, but I've never found a situation where I've needed it. Perhaps Viji or someone knows.
So yeah, your commands at the end aren't the same because #set doesn't change the current state. You could set a non-current state to 1 and then (I guess) when the trigger gets to it, it'll run its code without waiting for a match. That might be why it looks like they're being skipped. |
|
|
|
Rahab Wizard
Joined: 22 Mar 2007 Posts: 2320
|
Posted: Wed Mar 19, 2008 1:41 pm |
There's an extra complication with what you are doing. What if you aren't holding anyting? or wearing anything? You may have to account for all three being optional. Is there some other message if you don't have anything in inventory at all?
|
|
|
|
ReedN Wizard
Joined: 04 Jan 2006 Posts: 1279 Location: Portland, Oregon
|
Posted: Thu Mar 20, 2008 12:12 am |
I'll pretty much always have something under holding and wearing, that's not an issue.
|
|
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|