Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ General ➜ Passing wildcards to script procedure as arguments

Passing wildcards to script procedure as arguments

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


Pages: 1  2 3  

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #15 on Thu 22 Jan 2009 03:44 AM (UTC)
Message
I'm sorry, I don't really understand your question. It would help if you showed the trigger(s) in question.

Quote:

Why would I want to have to create other variables when I am already using the LUA table?


What other variables? If you could show the entire thing you are attempting, along with sample output, it would become clearer.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Curious2   (47 posts)  Bio
Date Reply #16 on Thu 22 Jan 2009 04:27 AM (UTC)
Message
Well for example in the following trigger:

^Blah beats you over the head with a stick\.$

Let's say that gives stupidity.

Now how do I communicate that to the afflict function?

You stated, "You could put the affliction into the trigger name (label), and then the script could simply use that."

I tried putting stupidity in the label, but that doesn't work because you also have a trigger that cures it too and they both can't have the same id/label.

I need to send stupidity to the afflict and unafflict functions which set the state of afflicted.stupidity to true or false and substitute the triggers with Afflicted: stupidity or Cured: stupidity.

Another person mentioned putting 30 if statements, but that seems silly when I already know the argument I am sending and a giant waste of time.

As far as the variable part that is simply what you stated:

---------------------

Here is another way of achieving that. In the trigger use "send to variable", This lets you send a nice long string to a single variable, without the overhead of invoking the script engine parser. For example:


<triggers>
<trigger
custom_colour="2"
enabled="y"
match="You are going mad."
script="on_affliction"
send_to="9"
sequence="100"
variable="affliction"
>
<send>madness</send>
</trigger>
</triggers>



This puts the word "madness" into the MUSHclient variable "affliction" and then calls the script "on_affliction". That can then pull "madness" out of the variable and set the appropriate script language variables. This is what it might look like in Lua:


function on_affliction (name, line, wildcards)
afflictions [GetVariable ("affliction")] = true
end -- function

------------------

Is that really how you have to do it? Pass it to another variable first?
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #17 on Thu 22 Jan 2009 04:42 AM (UTC)
Message
Well no, you don't have to do it that way. That was a suggestion to minimize writing. Another approach which avoids the (single) intermediate variable, but means more typing, is this:


<triggers>
  <trigger
   enabled="y"
   match="You are going mad."
   send_to="12"
   sequence="100"
  >
  <send>
afflict ("madness")
</send>
  </trigger>
</triggers>


That simply calls the function you suggested (afflict) and passes the word "madness" to it, thus avoiding any intermediate variables. I suppose this is neater, but the trigger is very slightly more complicated.

Then your unafflict could be done like this:


<triggers>
  <trigger
   enabled="y"
   match="You are feeling sane."
   send_to="12"
   sequence="100"
  >
  <send>
unafflict ("madness")
</send>
  </trigger>
</triggers>


And then ditto for the other afflictions. I don't think you can make it much simpler than this, because somehow you need to translate the affliction messages into an affliction name, and the triggers seem the simplest way of doing it.

One possible alternative would be to simply have a trigger that matches everything (ie. "*") and then use a Lua table-lookup to map the line to the affliction, eg.


affliction_on_table = {
  ["You are going mad."] = "madness",
  ["You feel sleepy."] = "sleep",
  }

affliction_off_table = {
  ["You are feeling sane."] = "madness",
  ["You feel awake again."] = "sleep",
  }


If you go down that path make sure you give it a low sequence number (eg. 50) and mark the trigger "keep evaluating" because you will still want other triggers to match too.




- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Curious2   (47 posts)  Bio
Date Reply #18 on Thu 22 Jan 2009 05:23 AM (UTC)
Message
<triggers>
<trigger
enabled="y"
group="Venoms"
match="^The idea of eating or drinking is repulsive to you\.$"
omit_from_output="y"
regexp="y"
send_to="12"
sequence="100"
variable="affliction"
>
<send>afflict("anorexia")</send>
</trigger>
</triggers>

Okay now my afflict function won't work. It doesn't do the colournote. It does change afflicted.anorexia to true though. Why isn't ColourNote working when I test the trigger?

function afflict(name, line, wildcards)
afflicted[name] = true
ColourNote("red", "black", "Afflicted: ", "khaki", "black", name)
end

Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #19 on Thu 22 Jan 2009 05:33 AM (UTC)
Message
See http://mushclient.com/faq point 51.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Curious2   (47 posts)  Bio
Date Reply #20 on Thu 22 Jan 2009 05:38 AM (UTC)
Message
Ah ha! Script (after omit). No wonder.
Top

Posted by Curious2   (47 posts)  Bio
Date Reply #21 on Thu 22 Jan 2009 07:18 AM (UTC)
Message
I hate to be a bother, but how do you refer to the line being received that the trigger is matching?

For example, when the trigger fires I want to check the length against what was received, then check it against another string for a match.

This is for a certain type of affliction you can get on IRE that will put in scattered * throughout the pattern.

Example:

A prick*y stingi*g ove**omes your bo*y, fading away into numbness.

The line must always be 66 but how do you refer to line?

Like in zmud/cmud you use %line.
Top

Posted by Curious2   (47 posts)  Bio
Date Reply #22 on Thu 22 Jan 2009 07:19 AM (UTC)
Message
Sorry to clarify I meant the string.len will always be 66.
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #23 on Thu 22 Jan 2009 07:30 PM (UTC)
Message
The problem with the prickly thing has been discussed before, see:

http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=3525

However to answer your direct question, you could feed the length to the function, like this:


afflict("anorexia", string.len ("%0"))


Wildcard %0 is the entire matching text. This is not necessarily the entire line if you are using regular expressions, but will be if not.

However that suggestion has a potential problem if there is a quote in the text, and it would be better like this:


afflict("anorexia", string.len ([[%0]]))


The [[ ... ]] construct is a Lua "long quoted string" and allows for imbedded quotes (but not however imbedded [[). To work around that you can use this form:


afflict("anorexia", string.len ([===[%0]===]))


And hope they don't put [===[ on any line.

To be really certain, when passing the matching line to a script, you should really use a script function in a script file rather than send-to-script. Then the matching line is supplied as an argument, and it doesn't matter how many quotes are in it.

I note your earlier comment:

Quote:

I tried putting stupidity in the label, but that doesn't work because you also have a trigger that cures it too and they both can't have the same id/label.


It isn't too hard to make different labels, eg. on_stupidity and off_stupidity, and then have the script omit the on_ or off_ parts before looking them up in the table.




- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Curious2   (47 posts)  Bio
Date Reply #24 on Thu 22 Jan 2009 09:51 PM (UTC)
Message
I apologize for referring to something that was discussed before, but that thread title isn't exactly discriptive and I did a search for paralysis.

However, I had figured it out later after I got an error which told me that %0 referred to the entire trigger text. :-)

Anyway, all I did was just put this script in that trigger..

local str = [===[%0]===]
if string.len(str) == 66 then
str = string.gsub(str, "*", ".")
if string.match("A prickly stinging overcomes your body, fading away into numbness.", str) then
afflict("paralysis")
else
ColourNote("yellow", "black", "Paralysis Illusion!!")
end
end

It works perfectly. I changed it to use your suggestion on the quoting though. See anything wrong with it? I admit I'm a novice yet with LUA.
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #25 on Fri 23 Jan 2009 03:36 AM (UTC)
Message
That seem a clever way of making the periods match on the underlying text. Technically the period won't quite match correctly, you should probably replace "." by "%." before doing the string.match. Also the test for length 66 now becomes redundant, except to save a bit of speed, however the Lua pattern matching is very fast.

Perhaps if you did this:


str = string.gsub (str, ".", "%.")  -- periods should match exactly
str = string.gsub (str, "*", ".")   -- convert wildcards
str = "^" .. str .. "$"    -- anchor it


Then you don't need the test for the length.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #26 on Fri 23 Jan 2009 03:40 AM (UTC)

Amended on Fri 23 Jan 2009 03:45 AM (UTC) by Nick Gammon

Message
Actually if you are turning untrusted input into a regexp, you should probably fix up all special characters, as documented under string.find, like this:


str = string.gsub (str, "[$().%%%[%]*+%-?\%^]", "%%%1")  -- fix up special characters


Otherwise, if the string you are testing for "A prickly stinging overcomes your body, fading away into numbness" is something like: "blah blah [ ... blah" (66 character long) then the regexp will fail with an unmatched opening bracket.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Curious2   (47 posts)  Bio
Date Reply #27 on Sun 01 Feb 2009 03:59 AM (UTC)
Message
Quote:
e That seem a clever way of making the periods match on the underlying text. Technically the period won't quite match correctly, you should probably replace "." by "%." before doing the string.match. Also the test for length 66 now becomes redundant, except to save a bit of speed, however the Lua pattern matching is very fast.

Perhaps if you did this:


str = string.gsub (str, ".", "%.") -- periods should match exactly
str = string.gsub (str, "*", ".") -- convert wildcards
str = "^" .. str .. "$" -- anchor it



Then you don't need the test for the length.


No that doesn't work because it doesn't catch things like misspelling a word.

If I do, as you posted and include:

Quote:
str = string.gsub (str, ".", "%.")


It then ends up matching on a string like the following:

Quote:
A prickly stinging ov*rcom*s your body, f*d*ng aw*y into nubbne*s.


"nubbness" is incorrect.

Just doing str = string.gsub(str, "*", ".") matches correctly and will flag nubbne*s as an illusion for misspell.

I'm just replacing the stars * with . which represents any single character so it matches with the regex pattern.

A prickly stinging ov*rcom*s your body, f*d*ng aw*y into nubbne*s.

turns into...

A prickly stinging ov.rcom.s your body, f.d.ng aw.y into nubbne.s.

and I am matching it against...

A prickly stinging overcomes your body, fading away into numbness.

which has a period at the end of it.
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #28 on Sun 01 Feb 2009 04:15 AM (UTC)

Amended on Sun 01 Feb 2009 04:16 AM (UTC) by Nick Gammon

Message
Oops.

I meant:


str = string.gsub (str, "%.", "%.")  -- periods should match exactly


My initial suggestion would have changed every character into a dot, which would have matched anything that length. The amended version changes dots in the original to %.



str = "A prickly stinging ov*rcom*s your body, f*d*ng aw*y into nubbne*s."

str = string.gsub (str, "%.", "%.")  -- periods should match exactly
str = string.gsub (str, "*", ".")   -- convert wildcards
str = "^" .. str .. "$"    -- anchor it
if string.match ("A prickly stinging overcomes your body, fading away into numbness.", str) then
  Note ("paralysis")
else
  Note("Paralysis Illusion!!")
end


That successfully returns "illusion" and for the bad string, and "paralysis" for the correct one.

However my other suggestion almost worked too. ;)

However I shouldn't have put the asterisk into it.

Thus this works:



--test
str = "A prickly stinging ov*rcom*s your body, f*d*ng aw*y into nubbne*s."


-- process it
str = string.gsub (str, "[$().%%%[%]+%-?\%^]", "%%%1")  -- fix up special characters EXCEPT *
str = string.gsub (str, "*", ".")   -- convert wildcards
str = "^" .. str .. "$"    -- anchor it

print ("str=", str)  -- debug

if string.match ("A prickly stinging overcomes your body, fading away into numbness.", str) then
  Note ("paralysis")
else
  Note("Paralysis Illusion!!")
end



- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #29 on Sun 01 Feb 2009 04:21 AM (UTC)

Amended on Sun 01 Feb 2009 04:22 AM (UTC) by Nick Gammon

Message
Just to demonstrate what I am talking about. If we use the simple version you had (just converting asterisks to dots), and we are getting illusions from other players, than can easily make it fail. For example (note the square bracket):


str = "A prickly stinging ov*rcom*s your body, [f*d*ng aw*y into nubbne*s."

str = string.gsub (str, "*", ".")   -- convert wildcards
if string.match ("A prickly stinging overcomes your body, fading away into numbness.", str) then
  Note ("paralysis")
else
  Note("Paralysis Illusion!!")
end


Try that and it gives:


Run-time error
World: smaug 2
Immediate execution
[string "Immediate"]:4: malformed pattern (missing ']')
stack traceback:
        [C]: in function 'match'
        [string "Immediate"]:4: in main chunk


See? The bracket which has made its way into the regexp causes your script to fail. It won't take players long to figure that one out.

Whereas my suggestion version is immune to that:


--test
str = "A prickly stinging ov*rcom*s your body, [f*d*ng aw*y into nubbne*s."


-- process it
str = string.gsub (str, "[$().%%%[%]+%-?\%^]", "%%%1")  -- fix up special characters EXCEPT *
str = string.gsub (str, "*", ".")   -- convert wildcards
str = "^" .. str .. "$"    -- anchor it

print ("str=", str)  -- debug

if string.match ("A prickly stinging overcomes your body, fading away into numbness.", str) then
  Note ("paralysis")
else
  Note("Paralysis Illusion!!")
end

Output

str= ^A prickly stinging ov.rcom.s your body, %[f.d.ng aw.y into nubbne.s%.$
Paralysis Illusion!!

- Nick Gammon

www.gammon.com.au, www.mushclient.com
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.


85,961 views.

This is page 2, subject is 3 pages long:  [Previous page]  1  2 3  [Next page]

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

Go to topic:           Search the forum


[Go to top] top

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