Scripting a multi-variable trigger

Posted by Faedara on Wed 14 Jul 2010 04:52 AM — 11 posts, 36,531 views.

#0
I'm making anti-theft triggers, and looking at Lua I thought, why make ten or twenty triggers, one for each piece of clothing, when I can make a single trigger for all my clothing.

However, I'm stuck on how to do this, and I feel I'm not even close to a solution.

So far I have:

^You remove (list of clothing each separated by a | )/.$

Which for obvious reasons I don't think will work. But what I need is for the script to identify which object in the list was removed and replace the wildcard in the following response with a variable appropriate to the clothing removed because the clothing descriptions and keywords are different.

wear *

I'm not entirely new to this, but I only recently opened an XML, took a good look, and realized this is simple if I can just understand things like this.
Amended on Wed 14 Jul 2010 04:54 AM by Faedara
USA #1
You can insert a MUSHclient variable into a pattern field using the syntax @!variable. The ! is a special flag on the normal @variable that tells it to preserve the |'s in the variable instead of escaping them, which lets you do:

^You remove (@!protected_clothes)\.$


(You used /. above instead, which probably isn't what you want. Make sure to use the right kind of slash!)

Then you just have to manage the MUSHclient variable "protected clothes". I think the easiest way to use this is to use a MUSHclient array (ArrayCreate() and similar functions) with the clothes as the key (not the value). Then you can use ArrayExportKeys() to get a | delimited string you can use in the variable in the regexp.

If any of that didn't make sense, I'd be glad to give examples. Just a little bit too harried at this particular moment.
#2
I'd love an example please. My "simple" just flew right out the window. And since you seem to be busy I'll research what you just said while you're away.
Australia Forum Administrator #3
What he means is, that if the variable "protected_clothes" contains something like:


hat|pants|shirt|tie|cape


Then the code he gave will get MUSHclient to substitute that into a regular expression, effectively testing for hat OR pants etc.

However another approach is to simply match on:


You remove *.


(This is NOT a regular expression).

Now in the script wildcard 1 is whatever got removed, and you can do a table lookup on it.

eg.


clothing = {
  hat = "You put the hat back on",
  tie = "You wear your tie again",
  shoes = "You put your shoes on",
  ["your cane"] = "You wield your cane",
-- more here
  }  -- end of table

action = clothing ["%1"]

if action then
  Send (action)
end -- if


So we lookup in the clothing table for a match on wildcard 1, and if found (ie. action is not nil) then we get back some value which we do something with.
Amended on Wed 14 Jul 2010 06:28 AM by Nick Gammon
#4
You don't sleep much, do you Nick?

And the problem with that is, as I mentioned earlier, the description when taking it off is *not* the same as the item identifier.

So if I take off "a canvas backpack" the only word I need and can use to put it back on is either pack or backpack, "wear a canvas backpack" would have no effect.
USA #5
Faedara said:

I'd love an example please. My "simple" just flew right out the window. And since you seem to be busy I'll research what you just said while you're away.


I might draft a simple reusable function to keep the complexity hidden, but here's the basic idea. (Nick's got a good one, too, and if it fits your situation, use it! Sometimes you just need to match only on specific things though, and this makes it a little easier.)

Put this somewhere outside your trigger, ideally your script file, so it's run immediately when the world is loaded.
local function keys_to_list(tbl)
  local tmp = {}
  for k,_ in pairs(tbl) do
    table.insert(string.gsub(k, "|", "\\|")
  end
  return table.concat(tmp, "|")
end

protected_clothes = {}

function add_clothes(name, keyword)
  protected_clothes[name] = keyword
  SetVariable("protected_clothes", keys_to_list(protected_clothes))
end

function remove_clothes(name)
  protected_clothes[name] = nil
  SetVariable("protected_clothes", keys_to_list(protected_clothes))
end


Then you can call add_clothes and remove_clothes, which automatically update the protected_clothes variable for you. I used a Lua table simply because I'm in that sort of mindset right now, but a MUSHclient Array would provide ArrayExportKeys(), which does the job of my keys_to_list() function itself.

It also adds the keyword as the value, so you can do something like Send("wear " .. protected_clothes["%1"]) to get at it.
Amended on Wed 14 Jul 2010 06:43 AM by Twisol
Australia Forum Administrator #6
Faedara said:

You don't sleep much, do you Nick?


It's only 5 pm here. :)

Faedara said:

And the problem with that is, as I mentioned earlier, the description when taking it off is *not* the same as the item identifier.


Well my example was trying to show you might match on "hat" but send "put on my cap" - the match word, and what you do with it, are only linked in the sense that they are together in the table.
#7
I see... it'll take me some time then, but I should be able to use that to figure out what I'm doing.

And I'm glad I'm a night person then, it's 3:18am here.
#8
New piece to this question, I'm using that variable table you gave me Nick, but I don't know how to change where it sends the command. Sending the command directly to the client skips command stacking, so I want to send it to the command line instead. ((No longer for clothing, this is now for a combo type alias))
USA #9
Try using Execute() instead of Send().
#10
That's exactly what I needed, thanks