[Home] [Downloads] [Search] [Help/forum]


Register forum user name Search FAQ

Gammon Forum

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  General
. . -> [Subject]  Beginner: making a trigger that repeats loop until regexp match

Beginner: making a trigger that repeats loop until regexp match

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page


Posted by Tigers12   (10 posts)  [Biography] bio
Date Fri 28 Aug 2009 08:26 AM (UTC)

Amended on Fri 28 Aug 2009 05:50 PM (UTC) by Tigers12

Message
I am starting from scratch (other than reading FAQ and searching forum for keywords).

I regularly use basic triggers that match regular expressions and fire off a series of commands or change color of outputs or omit output/muffle, etc.

This is new to me. Right now I have a trigger that starts on a regular expression match. It consists of three commands, A,B,C whereupon I need to check MUD output for different match. If no match then command D, A, B, C and re-check. No match after C, same, D, A, B, C, recheck. I would like to do this loop until I get match after C (will never be more than 12-15 loops before match). If match, stop loop, and send single command E. I would like to keep trigger enabled so that it will start afresh with next regular expression match (original).

Unfortunately I do not know if I will need a waitforregexp pause after C, because I have yet to learn the basic way to send the trigger to Lua script.


<triggers>
  <trigger
   custom_colour="2"
   enabled="y"
   match="(whisp of smoke)+"
   regexp="y"
   sequence="100"
  >
  <send>drop manual 7
take manual
shape ghoul
=kill ghoul
</send>
  </trigger>
</triggers>



After 'shape ghoul' command is sent, I am looking to match on "death's door" regular expression. If no match, then on to '=kill ghoul' command, and back to start of loop ('drop manual 7'). If match, I would like to end loop and send 'kill ghoul'

I apologize for basic nature of my problem. Once I get a good working example on my machine, I feel I will be able to play around with it to figure out more (about possibilites of triggers calling scripts).
[Go to top] top

Posted by Blainer   (191 posts)  [Biography] bio
Date Reply #1 on Fri 28 Aug 2009 09:33 AM (UTC)
Message
Template:codetag To make your code more readable please use [code] tags as described here.

Will make your code easier to read.
[Go to top] top

Posted by Blainer   (191 posts)  [Biography] bio
Date Reply #2 on Fri 28 Aug 2009 09:57 AM (UTC)
Message
Just to clarify you want to send the MUD three commands after the MUD sends "whisp of smoke" and if the output from the third command matchs
"death's door" then send 'kill ghoul' if not send the fourth command and the three commands again?

Do you need to wait for something to return from the MUD for each command?

It maybe helpful to copy and paste your command window after doing this manualy, with Echo my Commands on from the Commands config dialog.
[Go to top] top

Posted by Tigers12   (10 posts)  [Biography] bio
Date Reply #3 on Fri 28 Aug 2009 03:07 PM (UTC)

Amended on Fri 28 Aug 2009 05:51 PM (UTC) by Tigers12

Message
I do not need to wait for reply after each command, only the 'shape ghoul' command. Though the MUD will be sending small replies to the other commands, I do not need to match or note them (can be disregarded).

Your explanation of my goal is correct. Everytime "whisp of smoke," is seen, start trigger with 'drop manual 7', then 'take manual', then 'shape ghoul', then test/match response from the shape ghoul command, if it does NOT contain phrase "death's door," then '=kill ghoul', then back to 'drop manual 7'....and so on. If response (after shape ghoul) does contain match of phrase "death's door," then simply send 'kill ghoul' command and stop the loop (until next time "whisp of smoke" is seen, where whole trigger starts over).

Once again, I apologize for being vague.
[Go to top] top

Posted by Nick Gammon   Australia  (22,973 posts)  [Biography] bio   Forum Administrator
Date Reply #4 on Fri 28 Aug 2009 09:22 PM (UTC)

Amended on Fri 28 Aug 2009 09:36 PM (UTC) by Nick Gammon

Message
Quote:

match="(whisp of smoke)+"


First, why match on that? That will match on:


whisp of smoke
whisp of smokewhisp of smoke
whisp of smokewhisp of smokewhisp of smoke
whisp of smokewhisp of smokewhisp of smokewhisp of smoke


Surely a single match is enough?

Your next problem is, you must need some sort of delay, right? Otherwise a loop would just mindlessly send thousands of:


drop manual 7
take manual
shape ghoul
=kill ghoul


... without giving the MUD time to respond. For, example shaping the ghoul must take time, right?

The trigger below should do it. I added a 1 second pause between commands (you can trim that down to 0.1 second, or eliminate some of them, but I would leave a couple there).

Then, after sending "shape ghoul" it waits to either get "death's door" as a match, or 5 seconds to elapse. If no match (and line will be nil then), it does "=kill ghoul" and loops. If a match, it sends "kill ghoul" and returns, thus breaking the loop.



<triggers>
  <trigger
   custom_colour="2"
   enabled="y"
   match="whisp of smoke"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>

require "wait"

wait.make (function ()  --- coroutine below here

  repeat
    Send "drop manual 7"
    wait.time (1)

    Send "take manual"
    wait.time (1)

    Send "shape ghoul"
    wait.time (1)

    local line = wait.regexp ("death's door", 5)

    if line then
      Send "kill ghoul"
      return
    end -- if

    Send "=kill ghoul"
    wait.time (1)

  until false

 
end)  -- end of coroutine

</send>
  </trigger>
</triggers>


Template:pasting For advice on how to copy the above, and paste it into MUSHclient, please see Pasting XML.



- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (22,973 posts)  [Biography] bio   Forum Administrator
Date Reply #5 on Fri 28 Aug 2009 09:25 PM (UTC)
Message
There is a small discussion about the wait module here:

http://www.gammon.com.au/modules

In that is a link to a longer post which discusses it in more detail.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (22,973 posts)  [Biography] bio   Forum Administrator
Date Reply #6 on Fri 28 Aug 2009 09:41 PM (UTC)

Amended on Fri 28 Aug 2009 09:42 PM (UTC) by Nick Gammon

Message
A potential problem with what I showed was, if you got "whisp of smoke" while the trigger is running, then you would have two of them going at once, which would probably cause problems (you would be taking the manual, dropping it, etc. all out of sequence).

Probably a good idea is to give the trigger a name, and have it disable itself while it is running. This will work, because the script is created at the trigger match time, and it can then disable itself without affecting the running script. Like this:


<triggers>
  <trigger
   custom_colour="2"
   enabled="y"
   match="whisp of smoke"
   name="ghoul_trigger"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>

require "wait"

wait.make (function ()  --- coroutine below here

  EnableTrigger ("ghoul_trigger", false)  -- disable ourself

  repeat
    Send "drop manual 7"
    wait.time (1)

    Send "take manual"
    wait.time (1)

    Send "shape ghoul"
    wait.time (1)

    line = wait.regexp ("death's door", 5)

    -- line will be nil on a timeout
    if line then
      Send "kill ghoul"
      EnableTrigger ("ghoul_trigger", true)  -- enable ourself again
      return
    end -- if

    Send "=kill ghoul"
    wait.time (1)

  until false

 
end)  -- end of coroutine

</send>
  </trigger>
</triggers>


- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (22,973 posts)  [Biography] bio   Forum Administrator
Date Reply #7 on Fri 28 Aug 2009 09:44 PM (UTC)
Message
If you need to terminate the loop prematurely (eg. the doorbell rings) you can just:


say death's door


That will cause the MUD to do something like this:


You say '"death's door"'


The script will notice that and stop looping.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Tigers12   (10 posts)  [Biography] bio
Date Reply #8 on Sat 29 Aug 2009 12:44 AM (UTC)

Amended on Sat 29 Aug 2009 01:11 AM (UTC) by Tigers12

Message
Thank you for responses. You are absolutely correct about the loop, in fact I have concluded it isn't necessary as the total number of runs/tests will only be 7 maximum/per trigger pull. (You are also right about the '+' in the whisp trigger, no clue why it is there other than I didn't notice it/remove it from copying a different trigger that did need it)

After further review:

<triggers>
  <trigger
   custom_colour="2"
   enabled="y"
   match="(whisp of smoke)"
   regexp="y"
   sequence="100"
  >
  <send>drop manual 7
take manual
shape ghoul
=kill ghoul
drop manual 7
take manual
shape ghoul
=kill ghoul
drop manual 7
take manual
shape ghoul
=kill ghoul
drop manual 7
take manual
shape ghoul
=kill ghoul
drop manual 7
take manual
shape ghoul
=kill ghoul
drop manual 7
take manual
shape ghoul
=kill ghoul
drop manual 7
take manual
shape ghoul
=kill ghoul
kill ghoul

</send>
  </trigger>
</triggers>


Now I need to insert a waitforregexp test after each 'shape command' looking to match on 'death's door', if anything else, then continue, if it matches then skip to very last command in trigger, which is 'kill ghoul', then trigger can end. If at the end of the 7 cycles no match was found then will 'kill ghoul' anyway and trigger will end (another 'whisp of smoke' match will start it anew).

I am trying to get a grasp of the waitforregexp function/test right now. Will update when I figure it out enough to insert an attempt.

Edit: I realize that typing out the 'loop' 7 times was unnecessarly long (and stupid) and it can be coded as a single loop to be repeated only 7 times (max). Working on it and the waitforregexp. To be continued...
[Go to top] top

Posted by Nick Gammon   Australia  (22,973 posts)  [Biography] bio   Forum Administrator
Date Reply #9 on Sat 29 Aug 2009 02:02 AM (UTC)

Amended on Sun 30 Aug 2009 03:40 AM (UTC) by Nick Gammon

Message
Well you see my trigger did "send to script" which is why I used "Send" to send things to the MUD. And you are right, if you want to do it 7 times max, then a simple change will do that.

Also, if any of the things you are doing are aliases (eg. "=kill ghoul") rather than MUD commands, you need to change the word "Send" to "Execute". That makes MUSHclient re-parse what you are sending for alias matches.

To loop 7 times:


<triggers>
  <trigger
   custom_colour="2"
   enabled="y"
   match="whisp of smoke"
   name="ghoul_trigger"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>

require "wait"

wait.make (function ()  --- coroutine below here

  EnableTrigger ("ghoul_trigger", false)  -- disable ourself

  for i = 1, 7 do

    Send "drop manual 7"
    wait.time (1)

    Send "take manual"
    wait.time (1)

    Send "shape ghoul"
    wait.time (1)

    line = wait.regexp ("death's door", 5)

    -- line will be nil on a timeout
    if line then
      Send "kill ghoul"
      EnableTrigger ("ghoul_trigger", true)  -- enable ourself again
      return
    end -- if

    Send "=kill ghoul"
    wait.time (1)

  end -- for 

  EnableTrigger ("ghoul_trigger", true)  -- enable ourself again
 
end)  -- end of coroutine

</send>
  </trigger>
</triggers>


- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


27,784 views.

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at HostDash]