workaround for the lack of two-line triggers

Post Reply
Caled
Posts: 403
Joined: Thu Apr 09, 2009 4:45 am

workaround for the lack of two-line triggers

Post by Caled »

There are more instances of places in my curing system where I want to trigger on two lines than I can think of, and I have been delaying coding anything for them because I know that support for this is on the 'todo' list for Mudlet. I need to do -something- in the mean time though; I just can't be competitive in pvp without them.

Here is an example:

You take out a salve of mending and quickly rub it on your left leg.
You messily spread the salve over your body, to no effect.
H:4260|5191 B:100% Exp:37 [kcsdb eb] <s>

The "messily spread" line tells me that my salve application failed because there is no affliction present. There are other lines which may immediately follow the first, that indicate other things, such as failure because I do not have the necessary salve balance, failure because there is a higher level of limb break which must be cured first, and also, of course, a line indicating a successful cure.

My desired solution is

Code: Select all

Pattern:
^You take our a salve of mending and quickly rub it on your (\w+) (\w+)\.$ 
Script:
limbapp = matches[2]
Options: multiline or ...something indicating that there is another line to come. Whatever the option will be

Pattern 2, "exact match"
You messily spread the salve over your body, to no effect.
Script:
aff_off("broken " .. limbapp)
Options:
Within 1 line
Now, I know that isn't possible. And I know that eventually it will be, when a full state system is implemented. What I am asking, is how do I go about this script in the mean time? Should I put all the possible lines that might follow the first, into a disabled group, and enable that group on the first line, and disable it with a prompt trigger inside the group?

Should I be setting flags on the first line, and turning them off when the subsequent lines fire, while turning the flag off with my main prompt trig?

I don't really like either solution, because:

1. enabling and disabling objects is apparently quite inefficient, and occasionally buggy, for the time being (fixing that being something else on the todo list)
2. I mentioned that I need to do this quite a lot, which means a lot of different flags, and that means setting a lot of different variables to zero in every prompt. This may not be a problem, but it feels wrong (perhaps just because of my zmud/cmud days when changing too many variables in a prompt trigger can cause too much overhead when the prompts are coming quickly).

All I am after is advice on what the best work-around is until the state system is implemented.

Caled
Posts: 403
Joined: Thu Apr 09, 2009 4:45 am

Re: workaround for the lack of two-line triggers

Post by Caled »

Heh, I was being dense, I think.
flags={}

Trig for first line:
flags.mending = matches[2]

In the trig for the messily spread:
if flags.mending ~= nil then aff_off("broken " .. flags.mending)
flags.mending=nil


In my prompt trigger:
flags={}

^ I don't have to clear 20 separate variables, by using a table I can clear the whole lot at once.

User avatar
Heiko
Site Admin
Posts: 1548
Joined: Wed Mar 11, 2009 6:26 pm

Re: workaround for the lack of two-line triggers

Post by Heiko »

1. You are correct that enabling and disabling objects has not yet been optimized for speed. This will be implemented soon though as well as your two requests regarding the state machine namely:
a) I'll add a pattern type to describe line delta qualifiers within the pattern list e.g. regex "asdf", at least one more line, regex "bla"
b) I'll add a pattern type for color triggers as well as tempColorTrigger()

These additions will definitely be implemented before the feature freeze for 1.0 that will come soon.
If I have forgotten something important, remind me please.

2. Your problem will be solved nicely with the upcoming next git update where I've added a feature to chains that lets you define how long the trigger chain will be "open" after the chain head has matched. This update of the chain system will do away with the current limitations of the chains to content that is contained in the same line. The new feature will extend the usability of chains enormously.
In your above example you'll define a chain head with a pattern to match
"You take out a salve of mending and quickly rub it on your left leg."
and then set the option: keep chain open for 1 more line.
Then you'll add a bunch of triggers to the chain that handle the follow up line. This solution will be much faster and much more convenient than all other clients that either use multiline regex or handle the problem via enable/disable triggers. The chain will be open until the stay-open-line-delta has been reached or until you explicitely disable the chain with disableTrigger(). The new chain feature has no effect for filters, of course.
I'll update git tonight - hopefully.

As an explanation to other readers of this posting:

Chains and Filters
Chains
"Chains" and "filters" are different entities in Mudlet and serve completely different ends. A chain is defined in Mudlet by making a trigger group and adding a trigger pattern to the group. A group without a pattern is a simple trigger group that serves no other purposes than adding structure to your trigger system. Such a normal trigger group will always grant access to its children unless it has been explicitely disabled either manually or by a script. A trigger group with a defined trigger pattern, however, will behave like a normal trigger and match if the pattern matches. Such a trigger group is called "chain head". A chain head will only grant access to its children if the trigger pattern has matched and the chain has been enabled. Thus, chains can be looked at as a mechanism to automatically enable and disable triggers or groups of triggers when a certain condition has been met i. e. the trigger pattern of the chain head has been matched. (However, technically this is not correct as disabled child triggers will not be invoked if the chain head matches. In other words, in chains you can still enabled/disabled elements. The idea of a chain can better be described by necessary and sufficient condition - both of which need to be met before a child trigger is being run.)

Adding child triggers to this group will add eleements to the trigger chain. These chain elements will only be activated if the chain head has matched before and thus opened the trigger chain. The chain stays open until the "keep chain open for x lines" value has been reached. The default is 0 which means that the chain only stays open for the current line. When access to the chain has been granted all child triggers will be tested against the content of the current line.. Consequently, trigger chains are a means to automatically enable/disable trigger groups without the hassle of enabling and disabling trigger groups manually. This has 2 important advantages: Chains are faster than conventional solutions and chains reduce the complexity of your scripts and greatly reduce the usual system bugs that inevitably go along with enable/disable trigger xy function calls as it's very difficult and error prone to enable and disable your triggers correctly in large complex trigger systems. This is one of the most powerful features in Mudlet and should be used whenever possible.

Filters
You can turn a trigger chain head into a filter by checking the "filter" option. This changes the content of what is forwarded as trigger text to the children triggers in the chain. Chains forward the content of the current line as trigger text whereas filters forward the matched pattern instead of the current line. In other words, the text of the current line is filtered according to the pattern of the filter. For example:
You want to know the exits in the current room. The simplest solution is a simple filter on "You see exits to: (.*)" Then you simply add triggers to the filter chain such as "north", "south", "west", "east" etc. The direction triggers will only be called if the filter head has matched.

Caled
Posts: 403
Joined: Thu Apr 09, 2009 4:45 am

Re: workaround for the lack of two-line triggers

Post by Caled »

Thank you so much for that explanation. I know there is stuff in the manual, and also that conversation we had on IRC once, but that explanation just there made it all clear for me - I think it should eventually go into the manual.

User avatar
Heiko
Site Admin
Posts: 1548
Joined: Wed Mar 11, 2009 6:26 pm

Re: workaround for the lack of two-line triggers

Post by Heiko »

I've updated git. The new keep chain open for n lines or keep trigger script firing for n lines is now included. The line_spacer patterns will be next.

Caled
Posts: 403
Joined: Thu Apr 09, 2009 4:45 am

Re: workaround for the lack of two-line triggers

Post by Caled »

I'm not sure how to make the new changes work. I installed the new git version and have played around with it, but it is not immediately clear what options to click etc.

I figure the best way is to provide a screenshot of the trigger. It is a contrived example, and the trigger named, 'No discernible effect' has the pattern "The salve has no discernible effect." Its script is
echo(" Salve did nothing")

I want it to echo "salve did nothing" only if that trigger immediately follows the first. I understand that I want to select "Keep trigger chain open for 1 line" but I don't know which option does this, and I don't know in which of the triggers to select that option, either.
Attachments
multilinetrig.png

User avatar
Heiko
Site Admin
Posts: 1548
Joined: Wed Mar 11, 2009 6:26 pm

Re: workaround for the lack of two-line triggers

Post by Heiko »

You should not use the multiline option as you only have one pattern. Set the "fire length" option to 1 in order to keep the pipe open for one more line. Then put your echo in the script of the "No discernable effect" trigger.
The trigger script of the chain head i. e. you "salve to skin" chain will only be run once and never again as long as the chain is kept open. When the next line arrives (or as many lines as you have chosen to keep the chain open) access to the chain triggers (= the children of the chain head) will be granted i. e. they will be turned on and their respective scripts will be run whenever those triggers match.
The way this new feature is implemented at the moment will prevent the chain head pattern from being matched while the pipe is kept open. Consequently, if the chain head pattern is being sent by the MUD while the pipe is still open the chain will not be reset and match as it is still marked as open and there is no need to match it against the current line as access will be granted either way. I'm thinking about changing this behaviour to matching the chain head even while the pipe is open and resetting the chain if the pattern matches again. This is open for discussion though.

Caled
Posts: 403
Joined: Thu Apr 09, 2009 4:45 am

Re: workaround for the lack of two-line triggers

Post by Caled »

I don't think it should stay active and reset. If I need that kind of behaviour I can do something like:


Chain_head - "patternA" - fire length 10

Chain trigger 1 - patternB - script doing whatever
Chain trigger 2 - patternC - script closing chain immediately
Chain trigger 3 - patternA - script resetting chain (would need a function that does this)

Post Reply