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
| |
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:
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
It is now over 60 days since the last post. This thread is closed.
Refresh page
top