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.
Entire forum
➜ MUSHclient
➜ Lua
➜ creating an Auto-Walker (no pre-knowledge)
creating an Auto-Walker (no pre-knowledge)
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| Bjorn Ironfist
(5 posts) Bio
|
Date
| Mon 10 Dec 2018 12:57 PM (UTC) |
Message
| Hello everyone!
I've been playing MUDs since 2003 and always used MushClient to do so, quite a long time I think.
Nevertheless - and since I am not the best when it comes to programming - it wasn't until recent years that I found out (shame to myself) about the very nice implemented timers and triggers functions (I only used aliases so far).
Times change and so do MUDs. When it was uncomfortable to use scripts in the past, lots of players in my MUD nowaydays do so for leveling. This brought me up with the idea trying to figure it out myself - creating new characters and new classes without months/years of manually killing the same creatures over and over again.
I searched this forum for weeks now, read the introduction to Lua, but still I am not quite sure how to fix certain problems that I have to struggle with.
I found this entry very helpful:
http://www.mushclient.com/forum/?id=8613&reply=8
Based on that I tried to write a timer for myself (since the Lua-Add-Timer-function just caused errors for me).
Here is what I came up with:
I want to cast my protection spells(shields and so on), then run a certain path (that loops) in the wild (no exists visible - just a map) and stop when I meet the desired creature to kill. After doing so continuing on my pre-defined path. If my shield, armor or weapon fails to work, I want to go some steps back, search a secure spot in the wilderness (none or harmless creatures on the field) and then cast my shield, repair armor, eat something etc. After that continuing.
To do so I added some Variables(?) that make something true or false and wrote down the path. It looks like this:
route = {
"e", "e", "e", "e", "e", "e", "e", "e", "se", "w", "w", "w", "w", "w", "w", "w", "w", "w", --very long continuing of the path
}
forward = true
backwards = false
peaceful = false
if forward == true or backwards == false then
loc = (loc or 0) + 1 -- maybe put it somewhere else
return
elseif loc > #route then
loc = 1
elseif backward == true then
loc = (loc or 0) - 1 -- I guess this is not correct
elseif peaceful ~= false then -- this too
Send "heal"
Send "cast shield"
end
Send (route [loc])
The variables are:
forward = true
You killed *
Your shield is ready.
forward = false
Your shield collapses.
A horrible creature. -- also triggers attack
backward = true
Your shield collapses.
Your axe broke. -- your armor broke etc
backward = false
Your shield is ready.
peaceful = false
A horrible creature. -- and some other creatures
I tried several things, but all of them didn't work out.
I also have the feeling that the timer somehow misinterprets my desired path. Sometimes I run straight forward to the south or somewhere else (although I always reset the timers before I tried it out again). Even when I do not add any further code, just the path.
I guess these are just minor problems and I hope someone can help me understand what I did wrong. I appreciate that you read so far and have a nice day! :) | Top |
|
Posted by
| Nick Gammon
Australia (23,120 posts) Bio
Forum Administrator |
Date
| Reply #1 on Mon 10 Dec 2018 08:06 PM (UTC) Amended on Mon 10 Dec 2018 08:08 PM (UTC) by Nick Gammon
|
Message
| Check you are allowed to make bots first! :)
A few tips:
Put this at the start and then you can forget about loc not existing:
loc = loc or 0 -- initialize if first time
Booleans can be tested more simply. Rather than:
if forward == true or backwards == false then
You can write:
if forward or not backwards then
However surely forward and backwards are mutually exclusive? You can't move both directions at once, so just use "forward" and then "not forward" is obviously backwards (unless you want to have "not moving" as an option).
Similarly, here:
elseif backward then -- don't need to compare to true
Spelling! Make up your mind if it is "backward" or "backwards":
backwards = false
...
elseif backward == true then --> "backwards"!
You are adding one to loc here, but not sending it:
if forward == true or backwards == false then
loc = (loc or 0) + 1 -- maybe put it somewhere else
return
The "return" will leave that part of the code.
You haven't got a test for when you go off the end of the route table after adding 1 to loc. You have the test if you don't add one, which doesn't make sense.
I suggest adding some debugging prints to help you work out what it is doing. eg.
if forward then
loc = loc + 1
if loc > #route then
loc = 1
end -- if passed end
print ("Now going forward using ", route [loc])
Send (route [loc])
return
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Bjorn Ironfist
(5 posts) Bio
|
Date
| Reply #2 on Tue 11 Dec 2018 12:38 PM (UTC) |
Message
| Hey Nick,
Thanks for your fast answer!
I think I understood almost every proposal of yours, except the following:
Nick Gammon said:
You are adding one to loc here, but not sending it:
if forward == true or backwards == false then
loc = (loc or 0) + 1 -- maybe put it somewhere else
return
The "return" will leave that part of the code.
That means that "return" will start the code all over again right? So I should put it at the very end?
Nick Gammon said:
I suggest adding some debugging prints to help you work out what it is doing. eg.
if forward then
loc = loc + 1
if loc > #route then
loc = 1
end -- if passed end
print ("Now going forward using", route [loc])
Send (route [loc])
return
I put it into the code and it prints it correctly before moving but unfortunately I can't figure out my mistakes.
Nick Gammon said:
You haven't got a test for when you go off the end of the route table after adding 1 to loc. You have the test if you don't add one, which doesn't make sense.
I tried putting it into my new code - hope you meant that:
route = {
"e", "e", "e", "e", "e", "e", -- and so on
}
loc = loc or 0
forward = true
backward = false
peaceful = false
if forward then
loc = (loc or 0) + 1
print ("Now going forward using", route [loc])
Send (route [loc])
elseif loc > #route then
loc = 1
elseif backward then
loc = (loc or 0) - 1
elseif loc < #route then
loc = - 1
elseif peaceful ~= false then
Send "heal"
Send "cast shield"
end
return
I get no error messages so far, but still I am running into some unexpected direction - even after deleting the timer and readding it.
I am just copying this code and paste it into the opened timer-window, maybe thats wrong..? (I set interval to 1 and 'Send To "Script"' - where I put Lua as scripting language and enabled it)
Also I don't stop when I meet the desired creature I want to kill - a trigger goes off that attacks the creature (I have no "stand"-command in my Mud), so I put f.eks. "A horrible creature" as trigger for forward = false + attack, but I just keep moving (into some unexpected direction).
Thanks for your help so far and greets to Australia from the other side of the earth ;) | Top |
|
Posted by
| Nick Gammon
Australia (23,120 posts) Bio
Forum Administrator |
Date
| Reply #3 on Tue 11 Dec 2018 09:35 PM (UTC) |
Message
| You still seem to be adding 1 but testing for it to exceed the array in a different spot, ditto for subtracting. It makes much more sense to check for exceeding the array bounds immediately after adding or subtracting.
More like this:
route = {
"e", "e", "e", "e", "e", "e", -- and so on
}
loc = loc or 0 -- loc will be nil first time around
forward = true
backward = false
peaceful = false
if forward then
loc = loc + 1
-- overflow?
if loc > #route then
loc = 1
end -- of past end of array
Tell ("Now going forward using ")
else -- backward
loc = loc - 1
-- underflow?
if loc < 1 then -- arrays start at 1
loc = #route -- back to end
end -- if
Tell ("Now going backward using ")
end -- if forward or backward
Note (route [loc]) -- show direction
Send (route [loc]) -- send the direction
if not peaceful then
Send "heal"
Send "cast shield"
end -- if not peaceful
Quote:
That means that "return" will start the code all over again right? So I should put it at the very end?
The return means that the code exits. It doesn't start all over again, until it is called next time.
Quote:
Also I don't stop when I meet the desired creature I want to kill - a trigger goes off that attacks the creature (I have no "stand"-command in my Mud), so I put f.eks. "A horrible creature" as trigger for forward = false + attack, but I just keep moving (into some unexpected direction).
The timer will keep firing, so I would expect that. You might need to rework a bit.
Try reading this:
http://www.gammon.com.au/forum/?id=4957
You probably want to have a coroutine set up (as in the examples) where you do something like:
- Go a direction
- If a condition is met start fighting
- If not, wait a moment, and go back to the start
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Bjorn Ironfist
(5 posts) Bio
|
Date
| Reply #4 on Wed 12 Dec 2018 01:38 PM (UTC) |
Message
| Thanks again for answering so fast!
Nick Gammon said:
You still seem to be adding 1 but testing for it to exceed the array in a different spot, ditto for subtracting. It makes much more sense to check for exceeding the array bounds immediately after adding or subtracting.
I'm not sure if I understood everything correctly, I really tried keeping in mind everything what was written in the introduction to Lua, but it is still very confusing and difficult if you have no knowledge of programming I guess.
I tested your new code and it works correctly for walking the desired path (into one direction).
Nick Gammon said:
The timer will keep firing, so I would expect that. You might need to rework a bit.
Try reading this:
http://www.gammon.com.au/forum/?id=4957
You probably want to have a coroutine set up (as in the examples) where you do something like:
*Go a direction
*If a condition is met start fighting
*If not, wait a moment, and go back to the start
Yes you are right, I am walking nonstop forward. I found your linked post before, like so many others, but I just don't know what to fill in it or where to put it hence I have no understanding of what it is doing. I guess it is easier when someone explains or teaches you - this is my call of course and not yours. It is just very difficult for me to understand, maybe I have to visit some local programming class (it's very intresting I have to admit).
I found this simple code of yours in another post:
<timers>
<timer
enabled="y"
second="2.00"
offset_second="0.00"
send_to="12"
>
<send>
route = {
"s", "s", "e", "n", -- to butcher
"s", "w", "n", "n", -- back again
}
-- stay here if we are fighting or recovering
if fighting or resting then
return
end -- if
loc = (loc or 0) + 1 -- next way to walk
-- if past end, go back to start
if loc > #route then
loc = 1
end -- if
Send (route [loc])
</send>
</timer>
</timers>
I used it as example to build my timer - since your timer worked very nice. It stopped me when I wrote something I used as trigger for fighting = true or resting = true.
Thats also why I don't understand my mistakes since I just wanted to add a "backward"-function that makes you rest on a save spot (with no creatures) that is not all the way back along the way (since it is a very long path). | Top |
|
Posted by
| Nick Gammon
Australia (23,120 posts) Bio
Forum Administrator |
Date
| Reply #5 on Wed 12 Dec 2018 08:59 PM (UTC) |
Message
| Well, if you are using triggers to detect fighting then the other code is probably almost OK. I modified what I posted above a bit:
route = {
"e", "e", "e", "e", "e", "e", -- and so on
}
-- initialize variables first time we run this
if not loc then
forward = true
peaceful = true
resting = false
loc = 0
end -- if first time
-- stay here if we are fighting or recovering
if fighting or resting then
if not peaceful then
Send "heal"
Send "cast shield"
end -- if not peaceful
return -- don't move
end -- if
if forward then
loc = loc + 1
-- overflow?
if loc > #route then
loc = 1
end -- of past end of array
Tell ("Now going forward using ")
else -- backward
loc = loc - 1
-- underflow?
if loc < 1 then -- arrays start at 1
loc = #route -- back to end
end -- if
Tell ("Now going backward using ")
end -- if forward or backward
Note (route [loc]) -- show direction
Send (route [loc]) -- send the direction
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Bjorn Ironfist
(5 posts) Bio
|
Date
| Reply #6 on Fri 14 Dec 2018 02:52 AM (UTC) |
Message
| Thanks again for your input Nick!
I tried it and it worked at first (except the backward + casting shield on a save-spot idea). It only printed the forward using, so I guess it just didn't work.
These were my first adjustments:
route = {
"e", "e", "e", "e", "e", "e", -- and so on
}
-- initialize variables first time we run this
if not loc then
forward = true
peaceful = true
backward = false --replaced 'resting' with 'backward'
loc = 0
end -- if first time
--[[ stay here if we are fighting or recovering
-> I don't need it since I have no trigger for it
if fighting or resting then
if not peaceful then -- It has to be peaceful, meaning there are no creatures on the field, to cast my shield, otherwise I will die, so:
]]
if not forward then
if backward and peaceful ~= false then
--[[ since I have no trigger for peaceful = true (because there will simply be no creature on the field)
I put ~= false because peaceful = false is triggered if a creature is on the field
]]
Send "heal"
Send "cast shield"
end -- if not forward
return -- don't move
end -- if
-- no further changes by me from this point
if forward then
loc = loc + 1
-- overflow?
if loc > #route then
loc = 1
end -- of past end of array
Tell ("Now going forward using ")
else -- backward
loc = loc - 1
-- underflow?
if loc < 1 then -- arrays start at 1
loc = #route -- back to end
end -- if
Tell ("Now going backward using ")
end -- if forward or backward
Note (route [loc]) -- show direction
Send (route [loc]) -- send the direction
I tried to "activate" the backward-going and casting a shield on a savespot-idea by the following second adjustments to the code:
route = {
"e", "e", "e", "e", "e", "e", -- and so on
}
-- initialize variables first time we run this
if not loc then
forward = true
--true:creature dead,shield ready;false: creature on field
peaceful = true
--false: creature on field; no true available
backward = false
--true: shield/weapon/armor broke;false: shield ready
loc = 0
end -- if first time
if not forward then
if backward and peaceful ~= false then
Send "heal"
Send "cast shield"
end
return -- don't move
end
if forward then
loc = loc + 1
if loc > #route then
loc = 1
end
print ("Now going forward using ")
end
if not forward and backward then --might be wrong from here
loc = loc - 1
if backward and loc < 1 then
loc = #route
end
print ("Now going backward using ")
end
Note (route [loc]) -- show direction
Send (route [loc]) -- send the direction
It didn't work, but I'm not sure if I have yet another problem to solve than the code itself. Since the first adjustments worked for simply going forwards, stopping to kill a creature and continue (except the going backwards of course) - I retried the timer later on (after I reset it) and it didn't work as before! I just walked into some strange direction again (printing "Now going forward using"). So I think it has something to do with my client or settings or maybe that mush client is in my windows directory?
Kind regards,
Bjorn | Top |
|
Posted by
| Nick Gammon
Australia (23,120 posts) Bio
Forum Administrator |
Date
| Reply #7 on Fri 14 Dec 2018 06:43 AM (UTC) |
Message
| I'm not clear why you need both "backward" and "forward". What is the alternative? Surely if you are going forward you are not going backward, so you only need one variable. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Bjorn Ironfist
(5 posts) Bio
|
Date
| Reply #8 on Fri 14 Dec 2018 10:31 PM (UTC) |
Message
|
Nick Gammon said:
I'm not clear why you need both "backward" and "forward". What is the alternative? Surely if you are going forward you are not going backward, so you only need one variable.
Yes you are right again!
Made me think of another idea of simply not walking back to look for a savespot at all, but instead just going straight forward and let the possibly damaged creature be and then look for a savespot to cast my shield and heal up again.
The new code looks like this:
route = {
"e", "e", "e", "e", "e", "e", -- and so on
}
-- initialize variables first time we run this
if not loc then
forward = true
--[[true:creature dead,shield ready,shield collapses, armor breaks, low hp;false: creature on field ]]
peaceful = true
-- only false: creature on field; no true available
search = false
--true: shield/weapon/armor broke;false: shield ready
loc = 0
end -- if first time
if forward and search then
peaceful = true --needed to set it on true somehow
end
if not forward then
if search and peaceful ~= false then
Send "heal" --Possible to fire only once?
Send "cast shield"
end
return -- don't move
end
if forward or search then
loc = loc + 1
if loc > #route then
loc = 1
end
print ("Now going forward using ")
end
Note (route [loc]) -- show direction
Send (route [loc]) -- send the direction
Also this happened again:
Bjorn Ironfist said:
I retried the timer later on (after I reset it) and it didn't work as before! I just walked into some strange direction again.
It seems to work though if I restart MUSHclient, but doing it every time I'm trying something new is no solution I guess. | Top |
|
Posted by
| Nick Gammon
Australia (23,120 posts) Bio
Forum Administrator |
Date
| Reply #9 on Sat 15 Dec 2018 12:13 AM (UTC) |
Message
|
Quote:
Made me think of another idea of simply not walking back to look for a savespot at all ...
If you only ever go forward, why have a variable that tells you which direction you are going? |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Nick Gammon
Australia (23,120 posts) Bio
Forum Administrator |
Date
| Reply #10 on Sat 15 Dec 2018 05:55 AM (UTC) |
Message
|
Quote:
Send "heal" --Possible to fire only once?
Anything is possible. Think of what you would do as a human. You would think "I won't cast another heal if I did one a moment ago". So, you remember when you cast heal last, and check how much time has elapsed. There are ways of finding out the time. |
- 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.
24,261 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top