Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD General Discussion
Spirit
Newbie


Joined: 01 Mar 2014
Posts: 4

PostPosted: Fri Mar 13, 2015 6:22 pm   

Multiline pattern match/do not match differentiation problem
 
I am trying to set up some triggers on a pair of related multiline patterns. Each pattern indicates a similar effect upon the player, but because the source of that effect can differ, I want to handle them differently through seperate triggers/functions. The two possible patterns are as follows:

You perform an action.
Your body floats.

and

Any other random line of text.
Your body floats.


Pattern 1:

#TRIGGER {^You perform an action.$Your body floats.$} {}

This is intended to match the first pattern but not the second. It works as intended.

Pattern 2:

#TRIGGER {^{^You perform an action.}$Your body floats.$} {}

This is intended to match any variant of the second pattern excepting the first, and remains consistent with my self-imposed rule to start trigger patterns with a newline character whenever possible. It does not match either pattern.


#TRIGGER {{^You perform an action.}$Your body floats.$} {}

This is intended to match any variant of the second pattern excepting the first, and is inconsistent with my newline pattern rule. It matches both of the above patterns.


This issue seems to be an edge case in the way the {^Do not match this string} pattern is designed to work. The syntax I am using appears consistent with the CMUD documentation, and I can't see an obvious syntactic mistake in the trigger text. I don't have the alternative of providing every possible example for the second pattern either, because the first line of that pattern can be literally any other line delivered by the MUD in question. I'd also like to avoid storing the first line into a variable and then comparing it against a string, partly for performance reasons, and partly because this is one example of a set of similar problems that I need a common solution for.

Anyone have a solution for this issue, or able to point out whatever mistake I may be making with the syntax?
Reply with quote
shalimar
GURU


Joined: 04 Aug 2002
Posts: 4671
Location: Pensacola, FL, USA

PostPosted: Sat Mar 14, 2015 1:28 am   
 
#TRIGGER {^You perform an action.$} {ididit=1}
#COND {*} {ididit=0} {Within|Param=1}

and

#TRIGGER {^Your body floats.$} {#IF (@ididit) {me stuff} {not me stuff}} "" {Pri=1}

The first trigger sets a variable when you cause something to happen, but after one line it gets reset.
The second trigger is set with the fastest possible priority, so that it can fire before the condition of the first trigger.
_________________
Discord: Shalimarwildcat
Reply with quote
Daern
Sorcerer


Joined: 15 Apr 2011
Posts: 809

PostPosted: Sat Mar 14, 2015 7:29 am   
 
You could also use a single trigger on "^Your body floats.$" and use %line to check what the previous line was.
Reply with quote
Spirit
Newbie


Joined: 01 Mar 2014
Posts: 4

PostPosted: Sat Mar 14, 2015 2:44 pm   
 
shalimar wrote:
#TRIGGER {^You perform an action.$} {ididit=1}
#COND {*} {ididit=0} {Within|Param=1}

and

#TRIGGER {^Your body floats.$} {#IF (@ididit) {me stuff} {not me stuff}} "" {Pri=1}

The first trigger sets a variable when you cause something to happen, but after one line it gets reset.
The second trigger is set with the fastest possible priority, so that it can fire before the condition of the first trigger.

This method won't offer the efficiency I need. Given that I'm going to need at least 50 similar examples (that I can forsee, it'll probably end up being many more) active all the time, and they all use different patterns for the first line, this solution is going to result in several hundred match/variable access/variable store calls every few seconds.

Even if performance was not particularly important, this solution would be far from ideal.

Daern wrote:
You could also use a single trigger on "^Your body floats.$" and use %line to check what the previous line was.

I'm aware of this solution, which is a variant of the string compare method I mentioned that I want to avoid if possible. I'll go with it if there isn't a more efficient option though.

What I am hoping for is a solution that's consistent with the standard options in the pattern matching documentation, so that the only action the trigger has to perform is call a predefined standard function. It's starting to seem like the client itself isn't consistent with the documentation in this particular use case though.
Reply with quote
shalimar
GURU


Joined: 04 Aug 2002
Posts: 4671
Location: Pensacola, FL, USA

PostPosted: Sat Mar 14, 2015 9:44 pm   
 
so change the base trigger to..

#TR {^{@list_of_actions}$}
_________________
Discord: Shalimarwildcat
Reply with quote
Spirit
Newbie


Joined: 01 Mar 2014
Posts: 4

PostPosted: Sun Mar 15, 2015 1:19 am   
 
shalimar wrote:
so change the base trigger to..

#TR {^{@list_of_actions}$}

This is still quite slow, particularly when the action list starts getting large as CMUD will have to process the search for every line the MUD delivers. There are also instances where this solution will break because it involves two semi-coupled triggers which may act independently when they shouldn't. A multiline pattern will not catch all cases either, but at least it won't do things when it shouldn't, and workarounds can be implemented for those unusual cases where needed.

I've chosen for now to go with a variant of Daern's suggestion of using a local strcmp between %line() and a known string to determine what the client should do next:

  #TRIGGER {^Your body floats.$} {#call @funcActBasedOnCaster("lightfoot", %line(1) == "You perform an action.")}

  #FUNCTION funcActBasedOnCaster($Buff, $SelfCast) {#if ($SelfCast == true) {#call @funcBuffedMyself($Buff)} {#call @funcSomeoneBuffedMe($Buff)}}

I'm really not satisfied with the fact that these triggers now need to scan the output window and compare a string to determine which way to branch, particularly since some of those string comparisons can exceed 200 characters. That said, this is the most elegant and flexible solution I've encountered, and I suspect it's probably faster than my original attempt would have been, given that the first line of the multiline pattern was essentially a wildcard itself.

Other suggestions are welcome.
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD General Discussion All times are GMT
Page 1 of 1

 
Jump to:  
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

© 2009 Zugg Software. Hosted by Wolfpaw.net