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, 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.
 Entire forum ➜ MUSHclient ➜ General ➜ How do I make an Autocleric?

How do I make an Autocleric?

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


Pages: 1 2  3  

Posted by Trigger   (5 posts)  Bio
Date Tue 27 Feb 2007 10:00 PM (UTC)

Amended on Tue 27 Feb 2007 10:24 PM (UTC) by Trigger

Message
Ive been trying various ways to make this trigger but I really cant quiete understand your trigger system. I love your Mushclient and am enjoying it almost every day but I cant make this autocleric trigger.

If the mud sends this string:

Destroy says, 'heal'.

I want it to automatically

cast heal Destroy

For some reason this trigger

(.*) says, '(.*)'.
cast %2 %1

sends
cast heal'. You say, 'Pallando


I was hoping you guys would help me with this subject cause Im not to good at reading the helps files on the matter.
Trigger
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #1 on Wed 28 Feb 2007 12:40 AM (UTC)
Message
I don't see why it would do that. Can you copy and paste the actual trigger, see this post for how to do that:

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

- Nick Gammon

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

Posted by Shaun Biggs   USA  (644 posts)  Bio
Date Reply #2 on Wed 28 Feb 2007 01:37 AM (UTC)

Amended on Wed 28 Feb 2007 01:50 AM (UTC) by Shaun Biggs

Message
Just a quick question to Trigger. Are you testing this out by sending "say Pallando says 'heal'." to the mud? If so, the trigger would capture "You say, 'Pallando" as the first wildcard, and "heal'." as the second wildcard.

If this is the case, try testing it out with "emote says 'heal'." or open up the simulated output window with ctl-shift-F12, and put in "Pallando says, 'heal'" in the text area.

Also, keep in mind that what you wrote is an easily exploitable bot, and if botting is illegal in whatever mud you're playing on, you will get caught easily with that trigger. might be better to match on something like this:
^(/w+) says, '(heal|cure blindness|etc.)'.$
Still a bit exploitable, and still botting, but much more controlled. Otherwise, you might have people like me following you around going "say ventriloquate <yourname> I'm botting, and it has been proven by"

It is much easier to fight for one's ideals than to live up to them.
Top

Posted by Trigger   (5 posts)  Bio
Date Reply #3 on Wed 28 Feb 2007 03:45 AM (UTC)

Amended on Wed 28 Feb 2007 03:54 AM (UTC) by Trigger

Message
<triggers>
<trigger
enabled="y"
match="* says, '*'."
sequence="100"
>
<send>cast %2 %1</send>
</trigger>
</triggers>


Is the trigger copied
and when I use this one

<triggers>
<trigger
enabled="y"
match="(.*) says, '(.*)'"
regexp="y"
sequence="100"
>
<send>cast %2 %1</send>
</trigger>
</triggers>


The same thing happens
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #4 on Wed 28 Feb 2007 04:09 AM (UTC)
Message
I'd investigate what Shaun suggested. How are you testing the trigger?

Also I'd suggest you make sure that botting is allowed wherever you're playing. Some places consider it to be ok. On my MUD it is considered a very bad form of cheating.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #5 on Wed 28 Feb 2007 05:37 AM (UTC)
Message
I agree with the previous posters. You said that the triggers sends " You say," but those words appear nowhere in the trigger, so they must be in the MUD output.

In fact, the whole idea needs to be rethought a bit. The way you have written your trigger it will match on all says. So, for example, if you get this line from the MUD:


Nick says, 'Hi there, let's go meet at the inn'.


Then your trigger will match, and you will send:


cast Hi there, let's go meet at the inn Nick


You probably need to do what Shaun said, and restrict it to certain words like "heal" and so on.

- Nick Gammon

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

Posted by Trigger   (5 posts)  Bio
Date Reply #6 on Wed 28 Feb 2007 03:28 PM (UTC)

Amended on Wed 28 Feb 2007 04:47 PM (UTC) by Trigger

Message
It works great but Im still having trouble.
I want to cast

Remove poison

When someone says

Rem
or even
Remov
removepo


are anything after
rem
what should I do
what did I do wrong

<triggers>
<trigger
enabled="y"
match="(.*) tells you, '(Rem+ovePoison|Rem+ovepoison|rem+ovePoison|rem+ovepoison)'."
regexp="y"
sequence="100"
>
<send>cast %2 %1</send>
</trigger>
</triggers>


Also while I have your attention
Is there a way to
ignore the fact that it is capital
so that if they type
RemovePoison
or
Removepoison
it casts without having to make the trigger
(RemovePoison|Removepoison|removePoison|removepoison)
?

You Guys are great
Top

Posted by Shaun Biggs   USA  (644 posts)  Bio
Date Reply #7 on Wed 28 Feb 2007 05:19 PM (UTC)

Amended on Wed 28 Feb 2007 05:29 PM (UTC) by Shaun Biggs

Message
First, the easy question to answer. There is an "Ignore case" checkbox in the trigger wizard. That will match "heal" "Heal" "HEAL" and "hEaL" the same.

And now we get into the wonderful world of scripting. I'm going to give the example in Lua, since it comes with MUSHclient, and I'm getting more familiar with that than the other languages.
^(/w) says, '(heal|rem/w+)'$ for the matching trigger.
Then in the scripting window, put this as send to script:
function autocleric( tname, tstr, wildcards )
  local spell = string.lower( wildcards[2] )
  if string.match( "removepoison", local ) == not nil then
    local = "remove poison"
  end -- find remove poison
  send( "cast '"..local.."' "..wildcards[1] )
end -- autocleric

I didn't test it out, as botting is illegal on my mud and I didn't want to accidentally get in trouble, but it should work.

Also, as a side note, please take a quick look at http://www.gammon.com.au/mushclient/funwithtriggers.htm for help with using regex wildcards.. The ones in your previous example "rem+ovepoison" would match on "remmmmmmmmmmovepoison" because the + matches one or more of the previous character. Regex is a little weird at first, but doesn't take long to get used to it.

It is much easier to fight for one's ideals than to live up to them.
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #8 on Wed 28 Feb 2007 08:57 PM (UTC)
Message
I agree, although that example is slightly wrong. For one thing, things like /w should be \w, and for the player's name you need one or more so it should be \w+.

This trigger which uses inline (Lua) scripting, does what you are trying to do:


<triggers>
  <trigger
   enabled="y"
   ignore_case="y"
   match="^(\w+) says, '(heal|rem\w*)'\.$"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
local spell = string.lower ("%2")  -- make spell lower case
if string.sub (spell, 1, 3) == "rem" then  -- rem something?
  local removepoison = string.sub ("removepoison", 1, string.len (spell))
  if spell ~= removepoison then
    return
  end -- they didn't say "removepoison"
  spell = "'remove poison'" -- change spell
end -- if

-- now cast it

Send ("cast " .. spell .. " %1")
</send>
  </trigger>
</triggers>



The trigger matches on "heal" or "rem<something>".

Then in the script I check that the <something> is the rest of the word "removepoison", truncated to the length of what they typed. It also has "ignore case" set to allow for the upper-case letter.

If they typed "removepoison" (or part of it), then it changes the spell to 'remove poison' (including the quotes), ready for casting.

- Nick Gammon

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

Posted by Shaun Biggs   USA  (644 posts)  Bio
Date Reply #9 on Wed 28 Feb 2007 10:19 PM (UTC)

Amended on Thu 01 Mar 2007 12:11 AM (UTC) by Shaun Biggs

Message
I always get / and \ confused... stupid lysdexia. And I think I found my mistakes on the other parts, but I fail to see how it differs from yours. Well, once mine is written without a stupid amount of errors. Here it is converted to be not a function.
Trigger:  ^(\w+) says, '(heal|rem\w+)'/.$

local spell = string.lower( "%2" )
if string.match( "removepoison", spell ) == not nil then
  spell = "'remove poison'"
end -- find remove poison
send( "cast "..spell.." %1".. )

This will set the spell to "remove poison" if the whole spell name matches within "removepoison" starting from the beginning, otherwise it doesn't change the spell string at all, allowing for a greater variety in the future, and does it without as much mucking about with creating new variables. The trigger itself takes care of the fact that it can potentially match on "rem" if it's for the poison. I also have a habit of encapsulating everything into functions.

As for the weird issues with variable names and confusing / and \... sorry about that. I should know better than to code while questing.

It is much easier to fight for one's ideals than to live up to them.
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #10 on Thu 01 Mar 2007 04:09 AM (UTC)
Message
Yes, your method looks a bit neater once you get rid of the syntax and logic problems. :)

This is better:


if string.match( "removepoison", "^" .. spell ) then
  spell = "'remove poison'"
end -- find remove poison
send( "cast " .. spell .. " %1")


This line doesn't work as intended:


if string.match( "removepoison", spell ) == not nil then


The expression "not nil" is like saying "not false" and thus is true. Thus you are saying:


if string.match( "removepoison", spell ) == true then


The function string.match returns a string or nil, thus it will never return true.

You could have written:


if string.match( "removepoison", spell ) ~= nil then


But I think that looks redundant. Any non-nil (or non-false) result is considered true, so my version is cleaner, IMHO.

Finally, you don't want the 2 trailing dots on the "send" line.

Quote:

... if the whole spell name matches within "removepoison" starting from the beginning ...


I made sure it matched from the beginning by adding the "^" to the start of the regular expression.

- Nick Gammon

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

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #11 on Thu 01 Mar 2007 04:23 AM (UTC)

Amended on Thu 01 Mar 2007 04:24 AM (UTC) by David Haley

Message
Quote:
if string.match( "removepoison", spell ) ~= nil then


But I think that looks redundant. Any non-nil (or non-false) result is considered true, so my version is cleaner, IMHO.
I think there's a big conceptual difference between testing for non-nil and testing for true. Nil means "no value", and that can be different from "false". You could imagine a ternary logic system of sorts where variables are true, false or unspecified.

Or, consider function variables. Imagine I have a function like so:

function f(flag)
  if flag then
    -- do something
  else
    -- do something else
  end
end


Let's say you want flag to default to true. So, if f is called with no arguments (like just f()) the parameter will be nil.

You could write:


function f(flag)
  flag = flag or true

  if flag then
    -- do something
  else
    -- do something else
  end
end


However, this will prevent the value of "flag" from being negative. So, you could do:


function f(flag)
  flag = (flag == nil and true) or flag
  if flag then
    -- do something
  else
    -- do something else
  end
end


This way, if flag is nil, then you take the value true; otherwise, if flag is non-nil (so flag==nil is false) you will take the value of flag.

This is, incidentally, why I also prefer to sometimes leave in the "true" in if statements:

if foo == true then ... end

It makes more sense, I think, when you are looking at negation:

if foo == false then ... end

Here, your test will fail when foo is nil. Perhaps this is not what you want, and arguably you should be testing for nil to make sure you have a value in the first place.

All this to say that I think there's quite a conceptual difference between nil (i.e. unspecified) and false (i.e., well, specified to be false).

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Shaun Biggs   USA  (644 posts)  Bio
Date Reply #12 on Thu 01 Mar 2007 05:07 AM (UTC)

Amended on Thu 01 Mar 2007 05:09 AM (UTC) by Shaun Biggs

Message
Quote:
The expression "not nil" is like saying "not false" and thus is true.

I thought so too, until I couldn't figure out why one script wasn't working. After pounding my head on my monitor a few times (not normally a good option), I decided to try running this:
/print( false == false )
/print( false == nil )

the output for the first one is true. The output for the second one is false. I'd repeat what I said then, but I assume you frown upon long strings of expletives on your board. Quite counterintuitive if you're used to C, but then again Lua doesn't start arrays with 0 either (much to my constant confusion) string.match will return a nil value if a pattern is not found within the supplied string.

Your way makes a LOT more sense to read, but mine still does work. Once again, minus the syntax and logic problems. And I keep forgetting about the ~= and trying != instead. Crazy Lua. I keep thinking ~= looks like "sort of equals"

It is much easier to fight for one's ideals than to live up to them.
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #13 on Thu 01 Mar 2007 05:19 AM (UTC)
Message
Quote:

This is, incidentally, why I also prefer to sometimes leave in the "true" in if statements:

if foo == true then ... end


I see your point, but I think such code ends up becoming a bit obscure.

The construct:


if x then
 --- some code
end 


... is going to execute "some code" if x is true.

My view is that saying:



if x == true then
 --- some code
end 


... is adding another level of "is true" tests when one is already implied. You may as well say (to take the idea to extremes):


if (x == true) == true then
 --- some code
end 


To give an example from natural language, I may ask "is it raining?". To say "is it true it is raining?" is a bit redundant (except for emphasis perhaps). And no-one says "is it true it is true that it is is raining?".

The Lua authors recommend the idiom:


a = b or c


... as a simple way of supplying a default. It falls down a little bit with booleans, because, as you say, it is hard to supply a negative.

In the Lua manual, they repeatedly recommend idioms like this:


if string.find(s, "^%d") then ...


... rather than:


if string.find(s, "^%d") ~= nil then ...


I think this is because string.find returns nil if there is no match, and they define an "if" as failing if it is passed nil as the condition.

- Nick Gammon

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

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #14 on Thu 01 Mar 2007 05:25 AM (UTC)
Message
Quote:

/print( false == nil )

...

Quite counterintuitive if you're used to C


Yes, in C, under Windows, false and nil are probably going to end up being defined as the number 0. Thus, under C, under Windows, the following 3 are probably all equivalent:


  • 0 (zero)
  • FALSE
  • NIL


I qualify that a bit by adding that it probably depends a bit on the defines you are using. Also, on some platforms, NIL is not in fact zero.

However in Lua those are 3 distinct values, and types as well. One is a number, one is a boolean, and one is the special "non-value" nil. None are equivalent to each other.

You also have to be careful in Lua, that 0 is considered true, as the manual warns. Try this, for example:


if 0 then
 print "hi there"
end


C programmers do not expect to see anything printed.

- 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.


88,508 views.

This is page 1, subject is 3 pages long: 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.