[Home] [Downloads] [Search] [Help/forum]

Gammon Forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Lua
. . -> [Subject]  Simple kill alias
Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?

Simple kill alias

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


Pages: 1 2  3  4  

Posted by Blixel   (54 posts)  [Biography] 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.
[Go to top] top

Posted by Nick Gammon   Australia  (21,322 posts)  [Biography] 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>


Template:pasting 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
[Go to top] top

Posted by Blixel   (54 posts)  [Biography] 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.
[Go to top] top

Posted by Nick Gammon   Australia  (21,322 posts)  [Biography] 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.

Template: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
[Go to top] top

Posted by Blixel   (54 posts)  [Biography] 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...

[Go to top] top

Posted by Blixel   (54 posts)  [Biography] 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?




[Go to top] top

Posted by Nick Gammon   Australia  (21,322 posts)  [Biography] 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
[Go to top] top

Posted by Blixel   (54 posts)  [Biography] 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

[Go to top] top

Posted by Nick Gammon   Australia  (21,322 posts)  [Biography] 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.


match="^M\ -\ (.*?)$"


- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Blixel   (54 posts)  [Biography] 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.


match="^M\ -\ (.*?)$"




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)


[Go to top] top

Posted by Twisol   USA  (2,257 posts)  [Biography] 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
[Go to top] top

Posted by Blixel   (54 posts)  [Biography] 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.
[Go to top] top

Posted by Nick Gammon   Australia  (21,322 posts)  [Biography] bio   Forum Administrator
Date Reply #12 on Thu 15 Sep 2011 09:26 PM (UTC)
Message
Just match your list of mobs (like you did earlier up) and then use something like string.gmatch:

http://www.gammon.com.au/scripts/doc.php?lua=string.gmatch

Or, utils.split:

http://www.gammon.com.au/scripts/doc.php?lua=utils.split

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Blixel   (54 posts)  [Biography] 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



[Go to top] top

Posted by Twisol   USA  (2,257 posts)  [Biography] 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
[Go to top] 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.


18,976 views.

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

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

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

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

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at FutureQuest]