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
➜ Lua
➜ Simple kill alias
It is now over 60 days since the last post. This thread is closed.
Refresh page
Pages: 1 2
3
4
Posted by
| Blixel
(80 posts) Bio
|
Date
| Mon 12 Sep 2011 05:41 AM (UTC) |
Message
| I'm playing an old MUD. It's fun, but it requires a lot of repetitive typing for combat. To kill a zombie, you type "hit z" [enter], "hit z", [enter], "hit z" [enter] ... until it's dead.
I'm trying to set up an alias for this. "att *" which then does:
hit %1
hit %1
hit %1
hit %1
This works, but the game doesn't allow commands to be entered too fast. So the first hit lands, but the other 3 are ignored because the game says I'm inputting too fast.
How can I make the alias wait a moment between hits? Something like:
hit %1
wait
hit %1
wait
hit %1
wait
hit %1
Of course that wouldn't work because it would send the word wait to the game, and that would be an invalid command.
Ideally, the command would do some checking ... such as hit until zombie is dead and then stop hitting. But for now, I'd be content to just have my attack command hit 4 times with a small pause in between each hit. | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #1 on Mon 12 Sep 2011 06:52 AM (UTC) |
Message
| Doing delays is described here:
http://www.gammon.com.au/forum/?id=4956
<aliases>
<alias
match="att *"
enabled="y"
send_to="12"
sequence="100"
>
<send>
require "wait"
wait.make (function ()
for i = 1, 4 do
Send ("hit %1")
wait.time (1)
end -- for
end)
</send>
</alias>
</aliases>
 |
For advice on how to copy the above, and paste it into MUSHclient, please see Pasting XML.
|
For checking if the mob is dead, try reading this:
http://www.gammon.com.au/forum/?id=4957
I'll let you have the fun of getting that right, but basically you want to do something like:
x = wait.match ("The * is dead!", 1)
The timeout of 1 means it will time-out after 1 second. If x is nil then it timed-out (ie. the mob isn't dead) and if x is not nil then you know you killed it.
So you might do something like this:
local x = nil
while not x do
Send ("hit %1")
x = wait.match ("The * is dead!", 1)
end -- while
Of course, you change the message "The * is dead!" to whatever you see when the thing you are fighting dies. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Blixel
(80 posts) Bio
|
Date
| Reply #2 on Mon 12 Sep 2011 07:15 AM (UTC) Amended on Mon 12 Sep 2011 08:00 AM (UTC) by Blixel
|
Message
| Cool, thanks. You helped me achieve my primary objective.
I have "k [letter]" doing this now:
require "wait"
wait.make (function ()
for i = 1, 4 do
Send ("hit %1")
wait.time (1)
end -- for
end)
And it works! That alone is so much nicer, but it's a "dumb" loop.
I worked with your other idea and got it working, but have questions.
require "wait"
wait.make (function ()
local x = nil
while not x do
Send ("hit %1")
x = wait.match ("The * is slain!", 1)
end -- while
end)
Problem 1. If the monster runs away, the condition is not met. How do I add an OR to the match? One other condition is "The * flees in panic!"
Problem 2. If the condition isn't met, the loop doesn't stop and I have to turn off scripting. What is the easiest way to kill the loop?
I'm not sure how many conditions I'll have to think of to get the loop to work flawlessly every time, so I need a quick way to kill it. | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #3 on Mon 12 Sep 2011 09:03 AM (UTC) |
Message
| This is truly the fun of scripting. You keep improving your stuff!
You can make your test check for multiple things by using a regular expression and using the "or" operator which is "|".
<aliases>
<alias
match="k *"
enabled="y"
send_to="12"
sequence="100"
>
<send>
require "wait"
wait.make (function ()
local x = nil
giveup = false
while not (x or giveup) do
Send ("hit %1")
x = wait.regexp ("^The .* (is slain!)|(flees in panic!)", 1)
end -- while
end)
</send>
</alias>
</aliases>
Note that wait.match has changed to wait.regexp.
 |
Regular expressions
- Regular expressions (as used in triggers and aliases) are documented on the Regular expression tips forum page.
- Also see how Lua string matching patterns work, as documented on the Lua string.find page.
|
Also to allow for manual cancelling we also test the "giveup" variable. Now we need an alias to set it:
<aliases>
<alias
match="giveup"
enabled="y"
send_to="12"
sequence="100"
>
<send>giveup = true</send>
</alias>
</aliases>
Now if you type "giveup" it sets the variable "giveup" to be true, which is tested in the attack alias. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Blixel
(80 posts) Bio
|
Date
| Reply #4 on Mon 12 Sep 2011 09:43 AM (UTC) |
Message
| A thousand thanks. With that additional OR, it seems to work every time now. (I haven't had to test the giveup condition yet.)
Wow, what a refreshing break. I've been having a ton of fun with this old MUD, but it was starting to get tedious having to type out that kill command constantly.
I'd like to explore a few more ideas with this scripting stuff ... if it isn't too insanely complicated.
A couple of ideas. How hard would it be to add a look alias that read in the monsters in the room, and then used this kill alias to eliminate them one at a time?
>look
You are standing at a bend in the path. A small pine tree has gained purchase in the wall here and grows up at a sharp angle.
[][][][][][]
M x []
-------- []
.......| []
.......|$ []
.......| []
M - frostbat, lynx
Send ("look")
wait for "M - "
if "M - " not there, do nothing -- no monsters in the room
otherwise, kill $1, then kill $2, etc...
And my other idea is for a sell alias. When standing at the shop, I have to type "sell [item]" repetitively.
inv
You are carrying some platemail, a brass-ring, a bottle, a key, a glass-ring, a flask, a flask, a mace, your spellbook and 100 gold pieces.
So my idea here would be to sell items that were in some kind of trinket list, but not sell my important magical items like my brass-ring.
trinkets = {pearl, shortsword, stone, whip,} etc...
| Top |
|
Posted by
| Blixel
(80 posts) Bio
|
Date
| Reply #5 on Tue 13 Sep 2011 04:50 PM (UTC) |
Message
| I'm making a lot of progress with my triggers and aliases.
This works great:
<trigger
enabled="y"
group="Were-creature"
match="^M\ -\ .*were*"
regexp="y"
send_to="12"
sequence="100"
>
<send>ColourNote ("white", "green", "--------------------------------------")
ColourNote ("white", "green", "Were-creature is detected in the room!")
ColourNote ("white", "green", "--------------------------------------")</send>
</trigger>
That message really pops out at me. A wererat, werewolf, or wearbear in the room with you is bad news. If you get bit, you suffer from Lycanthropy.
This also works really well:
<trigger
enabled="y"
group="Auto-Killing"
keep_evaluating="y"
match="^M\ -\ .*zombie*"
regexp="y"
send_to="12"
sequence="100"
>
<send>require "wait"
wait.make (function ()
local x = nil
giveup = false
while not (x or giveup) do
wait.time (0.2)
Send ("chant reeshseno")
wait.time (0.2)
Send ("cast light zombie")
x = wait.regexp ("^You killed the monster!",1)
end -- while
end)</send>
</trigger>
If I walk into a room and there's a zombie there, my Cleric automatically casts light until the zombie dies.
But what doesn't work is this:
<trigger
group="Tests"
keep_evaluating="y"
match="^M\ -\ (.*?)"
regexp="y"
send_to="12"
sequence="100"
>
<send>Note ("A %1 is here")</send>
</trigger>
That note always outputs as "A is here"
I'm trying to figure out how to get the list of mobs in the room so I can issue a general kill command.
I don't need special triggers for all the basic monsters. Do I need to build a table or something?
| Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #6 on Tue 13 Sep 2011 10:11 PM (UTC) |
Message
|
Quote:
That note always outputs as "A is here"
When matching what lines?
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Blixel
(80 posts) Bio
|
Date
| Reply #7 on Wed 14 Sep 2011 12:52 AM (UTC) |
Message
|
Nick Gammon said:
Quote:
That note always outputs as "A is here"
When matching what lines?
The mob line reads like this (4 examples):
M - wolf, adder, adder
M - werewolf, zombie
M - wolf, wolf, troglodyte
M - troll
| Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #8 on Wed 14 Sep 2011 09:19 PM (UTC) |
Message
| You need to add a trailing $ sign.
The sequence ".*?" matches on the minimal amount it can, which still matches. The minimal amount of "any character" is "no characters".
However the minimal amount of "any character followed by the end of the line" is the rest of the line.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Blixel
(80 posts) Bio
|
Date
| Reply #9 on Wed 14 Sep 2011 10:33 PM (UTC) |
Message
|
Nick Gammon said:
You need to add a trailing $ sign.
The sequence ".*?" matches on the minimal amount it can, which still matches. The minimal amount of "any character" is "no characters".
However the minimal amount of "any character followed by the end of the line" is the rest of the line.
Confusing. I suppose I'll understand it eventually.
But why doesn't this work?
Send ("look")
local x = nil
x = match="^M\ -\ (.*?)$"
Compile error
World: FL2
Immediate execution
[string "Alias: "]:3: unexpected symbol near '='
How is that any different than what we started with (which does work).
require "wait"
wait.make (function ()
local x = nil
giveup = false
while not (x or giveup) do
Send ("hit %1")
x = wait.regexp ("^The .* (is slain!)|(flees in panic!)|(^There is no .* here\.)|(^You can\'t attack yourself!)", 1)
end -- while
end)
| Top |
|
Posted by
| Twisol
USA (2,257 posts) Bio
|
Date
| Reply #10 on Thu 15 Sep 2011 02:32 AM (UTC) Amended on Thu 15 Sep 2011 02:33 AM (UTC) by Twisol
|
Message
|
Blixel said:Send ("look")
local x = nil
x = match="^M\ -\ (.*?)$"
You have "x = match = <stuff>". Lua's = operator doesn't have any value of its own, so you can't chain ='s like that. |
'Soludra' on Achaea
Blog: http://jonathan.com/
GitHub: http://github.com/Twisol | Top |
|
Posted by
| Blixel
(80 posts) Bio
|
Date
| Reply #11 on Thu 15 Sep 2011 01:45 PM (UTC) |
Message
| I'm trying to work this out on my own by asking indirect questions, but that isn't working. So let me try to ask the question this way.
I have a mob line that looks like this:
M - troglodyte, piercer, troll
What I want to do is cycle through that list, one mob a time, executing my kill script, until all the mobs are slain.
Currently, I am doing this by using a trigger like this:
^M\ -\ .*(adder|brigand|dervish|fox|frostbat|gnoll|highwayman|hobgoblin|icetoad|lemure|lynx|owl|piercer|robber|snowman|troglodyte|troll|weasel|wolf|wolverine).*$
roomcleared = false
ColourNote ("white", "blue", "Call autokill %1")
Execute ("autokill %1")
My autokill function will automatically look at the room when it's done killing ... which will make the above trigger activate again if there are more mobs to be killed.
However, all that extra "look" calling is unnecessary and just causes a bunch of extra screen scrolling.
It would be better to do a for or while loop, but I don't know how to turn the mob line into a list that I can cycle through. | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #12 on Thu 15 Sep 2011 09:26 PM (UTC) |
Message
| |
Posted by
| Blixel
(80 posts) Bio
|
Date
| Reply #13 on Fri 16 Sep 2011 05:05 AM (UTC) |
Message
|
Blixel said:
The mob line reads like this (4 examples):
M - wolf, adder, adder
M - werewolf, zombie
M - wolf, wolf, troglodyte
M - troll
Oh my God, this is so aggravating. Why don't any of these match?? I want to return a moblist that is = to "wolf, adder, adder" (as in example 1), or "werewolf, zombie" (as in example 2), or "wolf, wolf, troglodyte" (as in example 3), or just "troll" as in example 4.
^M\ -\ (.*?)$
^M\ -\ .*
^M\ -\ .*$
^M\ -\ *
^M\ -\ (.*)
^M\ -\ *.*
^M\ -\ *$
Nothing works. In every case:
monsterlist = %1
Note ("monsterlist is ", monsterlist)
says monsterlist is nil
| Top |
|
Posted by
| Twisol
USA (2,257 posts) Bio
|
Date
| Reply #14 on Fri 16 Sep 2011 05:26 AM (UTC) |
Message
| You need to put quotes around %1.
monsterlist = "%1"
Note ("monsterlist is ", monsterlist)
You'd normally get a syntax error if you forget the ""'s, but in this case Lua sees "monsterlist = wolf, adder, adder" which is valid script... it's just not what you want. Lua sees that as taking the values of variables named wolf and adder, and assigning the first of those to monsterlist. You want to assign the string value "wolf, adder, adder" to monsterlist, so you have to put quotes around %1. |
'Soludra' on Achaea
Blog: http://jonathan.com/
GitHub: http://github.com/Twisol | 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.
118,638 views.
This is page 1, subject is 4 pages long: 1 2
3
4
It is now over 60 days since the last post. This thread is closed.
Refresh page
top