Is there a method to send messages can be triggered?

Posted by Zhenzh on Mon 19 Aug 2019 07:39 AM — 2 posts, 11,779 views.

China #0
What I want is a command similar to Note(), sending specified text to output window.
The key function is that the messages sent should be able to be triggered which is different from Note().
Australia Forum Administrator #1
There are two major ways of doing this.




The simplest is to use Simulate to "pretend" that the thing you want to send came from the MUD.

Template:function=Simulate
Simulate

The documentation for the Simulate script function is available online. It is also in the MUSHclient help file.



For example:


Simulate ("A kobold jumps out from behind the tree!\n")


Note the use of the newline character (\n) to indicate the end of the line, so that trigger processing takes place.

I don't particularly like this method because you can get into weird situations where the output that you simulate happens to be inserted into the incoming MUD data in a way that will screw things up.




Another approach is to make your own Note function that not only prints the thing you are noting, but also does trigger matching. Here is some example code:


function CheckTrigger (name, line)
  local regexp = GetTriggerInfo (name, 1)
  
  -- make sure trigger enabled
  if not GetTriggerInfo (name, 8) then
    return
  end -- if not enabled
  
  -- if not a regular expression,make it one
  if not GetTriggerInfo (name, 9) then
    regexp = MakeRegularExpression (regexp)
  end -- if not a regular expression yet
  
  local s, e = rex.new (regexp):match (line)
  if not s then
    return
  end -- if no match
 
  -- where the trigger sends its stuff
  local send_to = GetTriggerInfo (name, 15)
  local what_to_send = GetTriggerInfo (name, 2)
  
  -- implement SOME of the sendto possibilities  
  if send_to == sendto.world then
    Send (what_to_send)
  elseif send_to == sendto.output then
    print (what_to_send)
  elseif send_to == sendto.execute then
    Execute (what_to_send)
  elseif send_to == sendto.script then
    assert (loadstring (what_to_send)) ()
  end -- if
  
end -- CheckTrigger

function TriggerSortCompare (a, b)
  a_seq = GetTriggerInfo (a, 16) -- sequence
  b_seq = GetTriggerInfo (a, 16) -- sequence
  return a_seq < b_seq
end -- TriggerSortCompare

function MyNote (...)

  -- concatenate all arguments into one string  
  local combined = table.concat ({...}, '')
  
  print (combined) -- echo the note
  
  -- get the triggers
  local triggers = GetTriggerList()
  
  if not triggers then
    return  -- no triggers, all done!
  end -- if
  
  -- sort into sequence order
  table.sort (triggers, TriggerSortCompare)
  
  -- check each trigger
  for k, v in ipairs (triggers) do 
    CheckTrigger (v, combined) 
  end  -- for

end -- MyNote


In this example you call MyNote which prints the stuff you send to it, and then tries to match it against all of your triggers (in the world file). You would need to add more code if you wanted to match all plugins as well.

It gets your triggers with GetTriggerList, then sorts them into sequence order (as the client does) and then tries to match each one. If it matches it does some of the things a real trigger would, like sending stuff to output, back to the MUD, or call a script.

There are some limitations compared to real triggers, for example, wildcards are not dealt with. You could make it more complex if you need to.

Example of use:


MyNote ("A kobold jumps out from behind the tree!")