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

Gammon Software Solutions 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?
(New message)
Subject: Simple kill alias
Name:
Your forum user name.
Register forum user name
Password:
Your forum password.
Forgotten password?
Message:
Message to be posted (in English, please).
Forum codes:
Check this if your message uses 'forum codes' or templates (auto-detected for new posts).
Forum codes Templates

Save this message ...


Subject review (reverse sequence)

Pages: 1  2  3 4  

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Sat 24 Sep 2011 06:34 AM (UTC)  quote  ]
Message
Blixel said:
But I am to understand you can't use wait in a function, so it had to be replaced.

Certainly it can. He's not saying that it can't be used in a function. This is the critical line that is being disagreed with:

Blixel said:
But I don't need the alias in order to test if this function is working (fundamentally). If it doesn't work by calling it directly, then it's not going to work by having an alias "on top" of it.

You need to understand that this function isn't as self-contained as it might appear. To use this function, it must be called from within a wait.make() block, because it assumes that it can use wait.match(). So it's valid to call from your alias because your alias uses the wait module. However, you can't do a naive call of the function. If you want to call it standalone, you'd need to call it like this:
wait.make(function()
  mobkillengine("dark link")
end)

If you called it straight (i.e. directly from the main line of execution instead of from a wait coroutine), it wouldn't work, because there is no active coroutine to pause and resume.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Blixel   (39 posts)  [Biography] bio
Date Sat 24 Sep 2011 05:12 AM (UTC)  quote  ]

Amended on Sat 24 Sep 2011 05:13 AM (UTC) by Blixel

Message
Nick Gammon said:

What is this intended to do?


 x = ("^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\.?$)|(^The dead have no need to fight\.$)")




The original code for that was this:

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)


But I am to understand you can't use wait in a function, so it had to be replaced. I tried replacing it with this:

x = match.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\.?$)")


I thought I had seen match.regexp used somewhere before, but apparently there's no such function.

So, I am still trying to figure out how to replace x = wait.regexp (....) with some similar code that will work in a function.
[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Sat 24 Sep 2011 04:03 AM (UTC)  quote  ]
Message
What is this intended to do?


 x = ("^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\.?$)|(^The dead have no need to fight\.$)")


- Nick Gammon

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

Posted by Blixel   (39 posts)  [Biography] bio
Date Sat 24 Sep 2011 01:19 AM (UTC)  quote  ]

Amended on Sat 24 Sep 2011 01:20 AM (UTC) by Blixel

Message
Nick Gammon said:

Quote:

But I don't need the alias in order to test if this function is working (fundamentally).


But you do if you are relying on the stuff inherited from using the wait module.

For example:



require "wait"

-- a function here to modularize things

function mobkillengine (mob)

 -- kill one mob here

end -- function mobkillengine

wait.make (function ()  --- coroutine below here

   for k, v in ipairs (utils.split ("%1", ",")) do
     mobkillengine (Trim (v))
   end -- for

end)  -- end of coroutine


If your function is using the "wait" stuff (that is, it expects to be inside a coroutine) then you can't test it stand-alone.


I'm getting really confused here.

But first let me remind us what the point of splitting this up into two separate parts was in the first place. The point was to make mobkillengine capable of killing 1 mob - as supplied by the user. Going back to a previous message, I said:

blixel said:
I have another question about this kill routine. Sometimes a monster will enter the room after you've cleared the room. When the monster comes in, the game gives the name of the monster. The text is always in this format:

>A wererat appears suddenly and attacks!

Or, in terms of a regular expression, it's always in this format:

^\>?A (.*?) appears suddenly and attacks\!$

Since we know the name of the monster, there is no reason to Send ("look") in order to get the "M - *" line.

My thinking was to split the kill routine into two pieces.


So the first piece would be responsible for "evaluating" the room ... that is, it would look for that "M - *" line, break the monster line down into a list, and then pass the list to mobkillengine, 1 mob at a time.

And the Whole Point of doing that is so that I can Also call mobkillengine by itself ... so that - in the case when ">A wererat appears suddenly and attacks!", I can simply have a trigger that will "Execute ("mobkillengine %1")

If I can't do that, then it does absolutely no good to split this up into two separate pieces.

Hopefully that makes sense. The reason I wanted to break that up into two pieces was so that mobkillengine could be used for two different purposes. 1.) So that it could kill a single mob - when supplied with the mob name by the user via a trigger. 2.) So that it could be fed a list of mobs, 1 mob at a time, by some other function/alias in a loop.

[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Thu 22 Sep 2011 10:41 PM (UTC)  quote  ]
Message
Quote:

But I don't need the alias in order to test if this function is working (fundamentally).


But you do if you are relying on the stuff inherited from using the wait module.

For example:



require "wait"

-- a function here to modularize things

function mobkillengine (mob)

 -- kill one mob here

end -- function mobkillengine

wait.make (function ()  --- coroutine below here

   for k, v in ipairs (utils.split ("%1", ",")) do
     mobkillengine (Trim (v))
   end -- for

end)  -- end of coroutine


If your function is using the "wait" stuff (that is, it expects to be inside a coroutine) then you can't test it stand-alone.

- Nick Gammon

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

Posted by Blixel   (39 posts)  [Biography] bio
Date Thu 22 Sep 2011 09:17 AM (UTC)  quote  ]

Amended on Thu 22 Sep 2011 09:27 AM (UTC) by Blixel

Message
Nick Gammon said:

match.regexp? What's that?

Can you paste your code? You are just showing the tiny bits that fail. The reasons why they fail would be more related to seeing the whole.

For example, "mobillengine" - where is that defined?


I'm not using a plugin.

Sorry, I had already copy/pasted the whole mobkillengine function from my script file in a previous message, so I didn't think it was necessary to paste it again.

"mobillengine" was a typo. I'm sorry.

Right now, I believe this function can stand alone ... without any other aliases or triggers.

Per one of you previous messages...

Nick Gammon said:
I think you are making a mistake by creating an alias to do what a function really should.

If you make a script file, and put mobkillengine into it as a function (not an alias), then you just call that from the first alias. That way the pauses in mobkillengine will now be incorporated into the first alias, and it will feed the kill commands in slowly.


So my goal with this function is to be able to get the moblist from the alias, and feed it into this function, 1 mob at a time.

But I don't need the alias in order to test if this function is working (fundamentally). If it doesn't work by calling it directly, then it's not going to work by having an alias "on top" of it.

With the typo corrected, the function will now hit a mob 1 time and then return. It isn't looping how I want.

Sorry to be such a pest.


function mobkillengine (mob)

  -- If readytokill is disabled, then we skip the
  -- whole routine. 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

    -- The first thing we do is set readytokill
    -- to false so another instance can't overlap. 
    readytokill = false
 
    -- 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")
      -- Would this be this instead:
      Send ("kill " .. mob)

      -- So far we have 7 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.
      -- 7.) We died.
      x = ("^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\.?$)|(^The dead have no need to fight\.$)")

          
    end -- while
        
    -- 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 main if statement

end -- function

[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Thu 22 Sep 2011 08:33 AM (UTC)  quote  ]
Message
I need to see your structure here. Are you using a script file? What is in it? Are you using a plugin? Are you putting stuff in aliases? It can be made to work, certainly. But the devil is in the detail, as they say.

- Nick Gammon

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

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Thu 22 Sep 2011 08:32 AM (UTC)  quote  ]
Message
Quote:

if I type "/mobkillengine("baboon") into the command input box ...


or "mobillengine"? You have to get the spelling right.

- Nick Gammon

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

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Thu 22 Sep 2011 08:30 AM (UTC)  quote  ]
Message
match.regexp? What's that?

Can you paste your code? You are just showing the tiny bits that fail. The reasons why they fail would be more related to seeing the whole.

For example, "mobillengine" - where is that defined?

- Nick Gammon

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

Posted by Blixel   (39 posts)  [Biography] bio
Date Thu 22 Sep 2011 07:22 AM (UTC)  quote  ]
Message
Nick Gammon said:

In what way does it not work? Error message?

It's hard to tell from snippets, the way the whole thing is assembled together is relevant.


Sorry, I thought my code would be obviously wrong in and of itself.

Using the above function, if I type "/mobkillengine("baboon") into the command input box, I get this:

Run-time error
World: Cleric
Immediate execution
[string "Command line"]:1: attempt to call global 'mobillengine' (a nil value)
stack traceback:
        [string "Command line"]:1: in main chunk


And when I try to run the greatly simplified isroomclear() function, I get this:

Run-time error
World: Cleric
Immediate execution
[string "Script file"]:73: attempt to index global 'wait' (a nil value)
stack traceback:
        [string "Script file"]:73: in function 'isroomclear'
        [string "Command line"]:1: in main chunk
Error context in script:
  69 : end -- function
  70 : 
  71 : function isroomclear ()
  72 :   Send ("look")
  73*:   line, wildcards = wait.regexp ("^M - (.*?)$", 1)
  74 :   if (line) then
  75 :     return 0
  76 :   end
  77 :   return 1


Twisol had said you can't use wait in a function. So I tried replacing wait.regexp with match.regexp and got this:

Run-time error
World: Cleric
Immediate execution
[string "Script file"]:73: attempt to index global 'match' (a nil value)
stack traceback:
        [string "Script file"]:73: in function 'isroomclear'
        [string "Command line"]:1: in main chunk
Error context in script:
  69 : end -- function
  70 : 
  71 : function isroomclear ()
  72 :   Send ("look")
  73*:   line, wildcards = match.regexp ("^M - (.*?)$")
  74 :   if (line) then
  75 :     return 0
  76 :   end
  77 :   return 1



[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Thu 22 Sep 2011 03:12 AM (UTC)  quote  ]
Message
In what way does it not work? Error message?

It's hard to tell from snippets, the way the whole thing is assembled together is relevant.

- Nick Gammon

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

Posted by Blixel   (39 posts)  [Biography] bio
Date Wed 21 Sep 2011 03:25 PM (UTC)  quote  ]
Message
How do you match text inside of a function?

This method doesn't work:

function isroomclear ()
  Send ("look")
  line, wildcards = wait.regexp ("^M - (.*?)$", 1)
  if (line) then
    return 0
  else
    return 1
  end
end


I tried replacing wait.regexp with match.regexp (since there is no "wait" inside of the function), but that doesn't work either.

I did a google search for "lua function match regular expression" ... but it's difficult to understand all the examples other people are using in such different context.
[Go to top] top

Posted by Blixel   (39 posts)  [Biography] bio
Date Tue 20 Sep 2011 06:52 AM (UTC)  quote  ]

Amended on Thu 22 Sep 2011 09:20 AM (UTC) by Blixel

Message
Ok, I'm working on turning mobkillengine into a function. I did a google search on LUA functions and what I read seemed pretty straightforward.

Here's what I've come up with so far. Could you steer me in the right direction?

function mobkillengine (mob)

  -- If readytokill is disabled, then we skip the
  -- whole routine. 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

    -- The first thing we do is set readytokill
    -- to false so another instance can't overlap. 
    readytokill = false
 
    -- 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")
      -- Would this be this instead:
      Send ("kill " .. mob)

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

      -- Would this be match.regexp instead of wait?

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

      x = match.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\.?$)")

          
    end -- while
        
    -- After a kill, we send a short wait to
    -- prevent a "One moment please" message
    -- from coming up.
    -- I can move this wait.time (1) outside of the function
    -- wait.time (1)

    -- 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 main if statement

end -- function
[Go to top] top

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Mon 19 Sep 2011 04:05 PM (UTC)  quote  ]

Amended on Mon 19 Sep 2011 04:06 PM (UTC) by Twisol

Message
Blixel said:
How does this compare with Twisol's idea of using coroutines?

His way is simpler, but you have to make sure that you remove the wait.make() around the mobkillengine code. That's because, as I mentioned, the wait module itself is built upon coroutines. You want to pause the whole line of execution when killing a mob, not just that specific part. Otherwise you'll be back where you started: control returned to getmoblist before mobkillengine is done.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Blixel   (39 posts)  [Biography] bio
Date Mon 19 Sep 2011 08:18 AM (UTC)  quote  ]
Message
Nick Gammon said:
I think you are making a mistake by creating an alias to do what a function really should.

If you make a script file, and put mobkillengine into it as a function (not an alias), then you just call that from the first alias. That way the pauses in mobkillengine will now be incorporated into the first alias, and it will feed the kill commands in slowly.


Hmm... this is all new to me, so I'm learning as I go here. (Look back at my very first message in this thread to see how far this idea has developed from its original inception.)

I'm familiar with functions from Pascal and C. I understand feeding a function an argument or a dataset, and having the function return a piece of data itself, or simply return 1 or 0 for successful execution or failure respectively.

But I certainly have not yet looked into setting up a function in MUSHclient. I believe I understand what you are saying though. If I have the mobkillengine as a function, then the timing issue won't be an issue. The alias will pass the mob into the mobkillengine function, and the alias won't continue until mobkillengine returns.

How does this compare with Twisol's idea of using coroutines?
[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.


4,481 views.

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

[Reply to this subject]  Reply to this subject   [New subject]  Start a new subject   [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

[Home]

Written by Nick Gammon - 5K

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

[Best viewed with any browser - 2K]    [Internet Contents Rating Association (ICRA) - 2K]    [Web site powered by FutureQuest.Net]