Nick Gammon said:
Hmm, yes. Can you paste the whole aliases so I can test them?
Sorry about all the comments. :) I'm paranoid about forgetting what stuff does.
Here is some input text:
M - wolf, adder, adder
M - werewolf, zombie
M - wolf, wolf, troglodyte
M - troll
This alias gets the monster list and sends the list of monsters (using a for loop) to the second alias.
group="Get Monster List"
wait.make (function ()
-- Initialize moblist to nil
moblist = nil
-- Have a look at the room to see if there is
-- a line that starts with "M - ".
-- If there is, that will become our list of
-- mobs to kill.
-- The line variable is returned by wait.regexp
-- and will have the entire line, including the
-- "M - " part. The wildcards variable will only
-- include the wildcard part of our line, which
-- in this case will be a comma separated string
-- of monster names. (e.g. owl, wolf, icetoad)
line, wildcards = wait.regexp ("^M\ -\ (.*)", 1)
-- If wait.regexp didn't return a line, then there
-- was no "M - " line in this room. Presumably,
-- this would mean the room is clear of mobs.
if (line) then
-- If wait.regexp does return a line, then we
-- set the moblist equal to the wildcards.
moblist = wildcards 
-- Initialize mob variable to nil. This is our
-- general purpose variable name that we'll use
-- as we step through the list of mob names.
mob = nil
-- Tells other triggers that may be
-- watching that the room is not
-- clear. There is killing to be done.
roomcleared = false
-- Split the monster list into a table
moblist = utils.split (moblist, ",")
-- Cycle through our monster table one
-- mob at a time.
-- The Trim function removes white space
-- around the monster name. So we will
-- "kill owl" as opposed to "kill owl "
for k, mob in ipairs (moblist) do
Execute ("mobkillengine " .. Trim (mob))
-- Room should be free of mobs by now.
roomcleared = true
end -- if (line)
end) -- wait</send>
It is the intention to have this next alias process the list from the first one. (Or, to allow this next alias to stand alone with user input or other trigger text [see bottom for example of other trigger text].)
<send>-- If autokill is disabled, then forget this
-- whole routine. Presumably, autokill was
-- disabled so we can walk around without the
-- constant interruption of killing.
-- Also, if readytokill is disabled, then we
-- forget the whole routine as well. The main
-- reason readytokill would be disabled would
-- be due to the fact that we are Already
-- killing some other mob. We don't want our
-- killing to overlap, so when we start this
-- routine, we set readytokill to off so that
-- if it gets called a second time, the second
-- instance will just ignore it until the first
-- instance is done killing.
if (readytokill) then
--if (autokill and readytokill) then
-- Autokill is on, and we are ready to kill.
-- The first thing we do is set readytokill
-- to false so another instance can't overlap.
readytokill = false
wait.make (function ()
-- This is our failsafe. With enough logic,
-- this should never be needed. But just in
-- case something goes sideways, we can type
-- giveup to force our kill loop to stop.
giveup = false
-- Initialize x variable to nil
local x = nil
-- Our main kill loop
while not (x or giveup) do
-- Keep hitting until the mob is
-- dead or until the mob runs away.
Send ("kill %1")
-- So far we have 6 known reasons to
-- quit hitting.
-- 1.) Mob is slain!
-- 2.) Mob has run away.
-- 3.) We have specified an invalid target.
-- 4.) We are trying to attack ourself!
-- 5.) We are trying to attack inside a town.
-- 6.) We did not specify a target.
x = wait.regexp ("^The .* (is slain!)|(flees in panic!)|(^There is no .* here\.$)|(^You can\'t attack yourself!$)|(^A being clothed in white appears before you\.$)|(^Do what\.?$)", 1.2)
end -- while
-- After a kill, we send a short wait to
-- prevent a "One moment please" message
-- from coming up.
-- One of our conditions has been met.
-- The mob was killed or it ran away.
-- In either case, we are ready to kill
-- again. So we set the readytokill
-- variable back to true so this routine
-- can be called again.
readytokill = true
end) -- end wait function
end -- end main if statement</send>
Here is other trigger text that makes splitting this routine into two pieces very useful. When a mob "appears suddenly", we don't need to look at the room. The game tells us the name of the mob. So if we look at the room again anyway, it just causes lots of extra screen scrolling.
group="Monster List for Auto-Killing"
match="^\>?A (.*?) appears suddenly and attacks!$"
<send>Execute ("mobkillengine %1")</send>