Forums » Community Projects
Lua n00b in need of help with VO script
Hello All,
I'm a Lua n00b but I have some programming experience.
I've been reading the various Lua guides and I'm not having much trouble with the lua language itself, pretty similar to other languages, in concept, if not in Syntax. What I am having trouble with is getting it to work with VO.
I have set myself a simple task to start with. It is simply a script that displays the current amount of cargo you have in your ship.
It is as follows...
------
cargo = {}
function cargo()
print(GetActiveShipCargoCount())
end
------
I am triggering the script in VO by typing the following in the VO console...
/lua cargo()
However, I get the error:
-----
[string "console"]:1: attempt to read from undeclared variable cargo
stack traceback:
vo/error.lua:55: in function <vo/error.lua:54>
[C]: in function 'error'
vo/vo.lua:317:in function <vo/vo.lua:312>
[string "console"]:1: in function 'func'
vo/vo_console.lua:90:in function <vo/vo_console.lua:61>
(tail call):?
-----
Anyone able to tell me why this doesn't work? Omega 0 has been heping me via chat in game and he says it works fine for him.
Any and all help gratefully appreciated.
Cheers,
KD
I'm a Lua n00b but I have some programming experience.
I've been reading the various Lua guides and I'm not having much trouble with the lua language itself, pretty similar to other languages, in concept, if not in Syntax. What I am having trouble with is getting it to work with VO.
I have set myself a simple task to start with. It is simply a script that displays the current amount of cargo you have in your ship.
It is as follows...
------
cargo = {}
function cargo()
print(GetActiveShipCargoCount())
end
------
I am triggering the script in VO by typing the following in the VO console...
/lua cargo()
However, I get the error:
-----
[string "console"]:1: attempt to read from undeclared variable cargo
stack traceback:
vo/error.lua:55: in function <vo/error.lua:54>
[C]: in function 'error'
vo/vo.lua:317:in function <vo/vo.lua:312>
[string "console"]:1: in function 'func'
vo/vo_console.lua:90:in function <vo/vo_console.lua:61>
(tail call):?
-----
Anyone able to tell me why this doesn't work? Omega 0 has been heping me via chat in game and he says it works fine for him.
Any and all help gratefully appreciated.
Cheers,
KD
ummmm. on the nifty lil screen that shows your ship stats you can see how many Cu of cargo you have.......
Well, yes, of course. This is simply an exercise to teach myself lua and to make a project simple enough to minimise the chance of errors in the code.
Once I perfect this simple script, I will then be able to move on to more complex ones with the knowledge that I know how to make them work.
The point is the journey, not the destination.
Once I perfect this simple script, I will then be able to move on to more complex ones with the knowledge that I know how to make them work.
The point is the journey, not the destination.
did you put it in the right place and named it correctly?
it should print "Loaded plugin 'nameofplugin'" to the console if the game picked it up.
why are you defining cargo first as a table and then as a function?
it should print "Loaded plugin 'nameofplugin'" to the console if the game picked it up.
why are you defining cargo first as a table and then as a function?
did you put it in the right place and named it correctly?
it should print "Loaded plugin 'nameofplugin'" to the console if the game picked it up.
I believe so but I am not seeing that message come up so it must not be picking it up. That would explain the problem. I will see if I can see where I have gone wrong..
Hmm, OK. I think I may have misread the Plugins page. I run a Mac and the instructions are slightly different for Macs. I had:
1) Created a folder inside the Vendetta Package called "plugins"
2) Placed my script (named "main.lua") in there
However, on reading it again, it would seem that I need to:
1) Create a folder named "plugins" inside the Vendetta package
2) Create a folder inside plugins named the same as my script (in this case "cargo")
3) Put the script file (named "main.lua") inside that folder
Unfortunately, VO has just gone offline so I cant test it just now. With any luck it will work now. Thanks.
why are you defining cargo first as a table and then as a function?
Originally i did not have the first declaration there. However, I looked at a whole heap of example scripts when I had trouble with this one and every single one had the functions declared as a table at the start so, although I had not read anything about it in the documentation, I thought I'd try it just in case it was needed for some reason. It was just a case of "everyone else is doing it so I guess I should too".
EDIT - I missed a step in the second folder hierarchy list
it should print "Loaded plugin 'nameofplugin'" to the console if the game picked it up.
I believe so but I am not seeing that message come up so it must not be picking it up. That would explain the problem. I will see if I can see where I have gone wrong..
Hmm, OK. I think I may have misread the Plugins page. I run a Mac and the instructions are slightly different for Macs. I had:
1) Created a folder inside the Vendetta Package called "plugins"
2) Placed my script (named "main.lua") in there
However, on reading it again, it would seem that I need to:
1) Create a folder named "plugins" inside the Vendetta package
2) Create a folder inside plugins named the same as my script (in this case "cargo")
3) Put the script file (named "main.lua") inside that folder
Unfortunately, VO has just gone offline so I cant test it just now. With any luck it will work now. Thanks.
why are you defining cargo first as a table and then as a function?
Originally i did not have the first declaration there. However, I looked at a whole heap of example scripts when I had trouble with this one and every single one had the functions declared as a table at the start so, although I had not read anything about it in the documentation, I thought I'd try it just in case it was needed for some reason. It was just a case of "everyone else is doing it so I guess I should too".
EDIT - I missed a step in the second folder hierarchy list
Yep, it works now. Thanks for putting me onto that. I was looking for an error in the code when it was my setup that was out.
It's amazing how misreading a single sentence can set you back for hours.
Thanks again,
KD
It's amazing how misreading a single sentence can set you back for hours.
Thanks again,
KD
Next question...
Say I have a script with a loop in it. For arguements sake, a while loop. Now, I know how to break out of it within the script itself but how can I trigger a breakout from within VO?
For example, say that I want to do some action over and over, every 2 seconds until I press a certain key. How can I do that?
I'm pretty sure that I know how to make it to break out when a certain condition is met, for example, Keep jettisioning cargo, 1 unit at a time, until the cargo hold is empty (not that you would need to do that since you can JettisonAll() but just for the sake of the example). However, looking for user interaction is slightly different.
I've checked the documentation but I haven't been able to find this specific issue discussed. I may have just missed it but I did look.
Say I have a script with a loop in it. For arguements sake, a while loop. Now, I know how to break out of it within the script itself but how can I trigger a breakout from within VO?
For example, say that I want to do some action over and over, every 2 seconds until I press a certain key. How can I do that?
I'm pretty sure that I know how to make it to break out when a certain condition is met, for example, Keep jettisioning cargo, 1 unit at a time, until the cargo hold is empty (not that you would need to do that since you can JettisonAll() but just for the sake of the example). However, looking for user interaction is slightly different.
I've checked the documentation but I haven't been able to find this specific issue discussed. I may have just missed it but I did look.
I'd do that with a timer. Cause ven doesn't expose a sleep function so doing anything in a certain interval would be tricky, Even if it did you'd have to mess with threads to not lock up the client. Timers take care of that pretty nicely.
Something like this would print crap every two seconds till you use the stopcrap command:
-- create new timer
craptimer = Timer()
-- SetTimeout takes the timeout in msecs and optionally a
-- function to call when it's over if you leave out the function
-- it will call the last one assigned it. By resetting the
-- timeout within that function the timer will loop endlessly
craptimer:SetTimeout(2000, function() print("crap") craptimer:SetTimeout(2000) end)
-- a function to kill the timer
function stopcrap() craptimer:Kill() end
-- assign a command to it
RegisterUserCommand("stopcrap", stopcrap)
Something like this would print crap every two seconds till you use the stopcrap command:
-- create new timer
craptimer = Timer()
-- SetTimeout takes the timeout in msecs and optionally a
-- function to call when it's over if you leave out the function
-- it will call the last one assigned it. By resetting the
-- timeout within that function the timer will loop endlessly
craptimer:SetTimeout(2000, function() print("crap") craptimer:SetTimeout(2000) end)
-- a function to kill the timer
function stopcrap() craptimer:Kill() end
-- assign a command to it
RegisterUserCommand("stopcrap", stopcrap)
I've spent the last 48 hours reading the lua documentation and experimenting with a few scripts but, although I've gotten a few very simple scripts to work as a proof of concept, I'm still having some issues with this one. I could really use some help with it
I've managed to come up with something that is close to doing what I want but, given my lack of familiarity with lua, it's likely full of syntax errors and there are a few places where I've inserted pseudocode because I don't know how to do what I need. Apart from that, I think it's getting close.
I'm hoping that if I post what I have below, someone will be willing to tell me where I have gone wrong (although it may be quicker to tell me where I have gone right). I've commented it extensively so it shouldn't hard to follow.
Here's what I am trying to do...
Basically it's an automatic jettison script. I'll use a bind or alias to bind a joystick button or keystroke to the activation/deactivation commands.
There are 3 functions. One that activates the script, one that deactivates it, and the main one that does most of the work.
Once activated, the main function will check to see if the cargo bay is nearly full, if it is, it will jettison everything using JettisonAll(). If the bay is not nearly full, it will delay for a couple of seconds and then call itself and start the process all over again. If the deactivate command is given, a flag variable is toggled and the next time the main function is called, it will break out and stop the script.
...and that's all it does. Sounds simple, and it is, but it's got me stumped.
Here's the script so far, it's not finished and I still need to make sure I pass all the right parameters but it'll give you the basic idea. I've inserted pseudocode in some places where I don't know how to do something...
---------
--Mixed pseudocode/real code example of Auto Jettison Script
bufferSpace = 5 -- the amount of empty cargo space before the cargo jettison
maxCargo = GetActiveShipMaxCargo -- returns the cargo capacity of the current ship
currentCargo = GetActiveShipCargoCount -- returns the amount of cargo currently in the ship
cargoSpace = maxCargo - currentCargo -- amount of empty space left in the ship's cargo bay
stopFlag = true -- when true, it will break out of the loop and end. When false, it will continue the loop.
function turnAutoJetON(stopFlag) -- activates the script. Do I need an event handler or something here instead?
stopFlag = false -- sets the flag so that checkEmpty will continue to call itself
checkEmpty() - calls the checkEmpty function
end
function turnAutoJetOFF(stopFlag) -- Deactivates the script. Again, do I need a handler instead?
stopFlag = true -- sets flag to true so that when it hits the loop it will break out
checkEmpty() - calls checkEmpty
end
function checkEmpty(cargoSpace)
if stopFlag ~= true then
if cargoSpace <= bufferSpace then
jettisonAll()
else
-- delay for a few seconds. Need help here.
checkEmpty() -- Calls itself
else
return() - Is this syntax right? It's how i'd do it in C but dunno about lua
end
------------
As I said, it's full of syntax errors and I still need help with the delay (i'm not sure that I need anything as fancy as the timer that Mr Spuck mentioned, just a simple delay if that is possible) but I think the logic behind it is sound. If anyone could take a look and give me your opinion and/or advice I'd really appreciate it.
Cheers,
KD
I've managed to come up with something that is close to doing what I want but, given my lack of familiarity with lua, it's likely full of syntax errors and there are a few places where I've inserted pseudocode because I don't know how to do what I need. Apart from that, I think it's getting close.
I'm hoping that if I post what I have below, someone will be willing to tell me where I have gone wrong (although it may be quicker to tell me where I have gone right). I've commented it extensively so it shouldn't hard to follow.
Here's what I am trying to do...
Basically it's an automatic jettison script. I'll use a bind or alias to bind a joystick button or keystroke to the activation/deactivation commands.
There are 3 functions. One that activates the script, one that deactivates it, and the main one that does most of the work.
Once activated, the main function will check to see if the cargo bay is nearly full, if it is, it will jettison everything using JettisonAll(). If the bay is not nearly full, it will delay for a couple of seconds and then call itself and start the process all over again. If the deactivate command is given, a flag variable is toggled and the next time the main function is called, it will break out and stop the script.
...and that's all it does. Sounds simple, and it is, but it's got me stumped.
Here's the script so far, it's not finished and I still need to make sure I pass all the right parameters but it'll give you the basic idea. I've inserted pseudocode in some places where I don't know how to do something...
---------
--Mixed pseudocode/real code example of Auto Jettison Script
bufferSpace = 5 -- the amount of empty cargo space before the cargo jettison
maxCargo = GetActiveShipMaxCargo -- returns the cargo capacity of the current ship
currentCargo = GetActiveShipCargoCount -- returns the amount of cargo currently in the ship
cargoSpace = maxCargo - currentCargo -- amount of empty space left in the ship's cargo bay
stopFlag = true -- when true, it will break out of the loop and end. When false, it will continue the loop.
function turnAutoJetON(stopFlag) -- activates the script. Do I need an event handler or something here instead?
stopFlag = false -- sets the flag so that checkEmpty will continue to call itself
checkEmpty() - calls the checkEmpty function
end
function turnAutoJetOFF(stopFlag) -- Deactivates the script. Again, do I need a handler instead?
stopFlag = true -- sets flag to true so that when it hits the loop it will break out
checkEmpty() - calls checkEmpty
end
function checkEmpty(cargoSpace)
if stopFlag ~= true then
if cargoSpace <= bufferSpace then
jettisonAll()
else
-- delay for a few seconds. Need help here.
checkEmpty() -- Calls itself
else
return() - Is this syntax right? It's how i'd do it in C but dunno about lua
end
------------
As I said, it's full of syntax errors and I still need help with the delay (i'm not sure that I need anything as fancy as the timer that Mr Spuck mentioned, just a simple delay if that is possible) but I think the logic behind it is sound. If anyone could take a look and give me your opinion and/or advice I'd really appreciate it.
Cheers,
KD
yes it is so much better to have it from an event. I wrote a script to do this.
Please do not use this for AFK mining.
http://www.vendetta-online.com/x/msgboard/9/17960#224827
Ed
Please do not use this for AFK mining.
http://www.vendetta-online.com/x/msgboard/9/17960#224827
Ed
Hi Blacknet.
Thanks heaps for putting me onto that, it's pretty much what I'm after and, for the few minor things that I'd like to change, I can always edit the existing code. I should be able to manage that at least.
Yeah, I won't be going AFK while using this script, it'll just stop me from having to hit the jettison key every 10 seconds. It means I can chat while I'm mining to relieve the boredom when those 'roids get really hot. Cheers mate, I appreciate it.
However, the main reason that I wanted to get help with, and to build, this script, was to further my knowledge of lua and hopefully get better at working with it (the auto-jettison ability is just an excuse for a project), so if anyone can still help me to edit my script, I'd really appreciate it.
I have read the section in the documentation on event handlers but I'm still not straight on them. I dunno if I'm just thick or if the documentation isn't clear. Either way, if anyone can explain to me how to define and call them, I'd appreciate it.
Cheers,
KD
Thanks heaps for putting me onto that, it's pretty much what I'm after and, for the few minor things that I'd like to change, I can always edit the existing code. I should be able to manage that at least.
Yeah, I won't be going AFK while using this script, it'll just stop me from having to hit the jettison key every 10 seconds. It means I can chat while I'm mining to relieve the boredom when those 'roids get really hot. Cheers mate, I appreciate it.
However, the main reason that I wanted to get help with, and to build, this script, was to further my knowledge of lua and hopefully get better at working with it (the auto-jettison ability is just an excuse for a project), so if anyone can still help me to edit my script, I'd really appreciate it.
I have read the section in the documentation on event handlers but I'm still not straight on them. I dunno if I'm just thick or if the documentation isn't clear. Either way, if anyone can explain to me how to define and call them, I'd appreciate it.
Cheers,
KD
that's perhaps the hardest part of all, figuring out what arguments are passed and what the callbacks, events and the like, when the events trigger and which event etc...
Hopefully you will look thru the code and get a good feel for how it's done. You had the core functions ok but not the event flow. It also seemed the way you were going was with timers which is an extremely bad idea.
Notice in the code how I use the myapp.myeventhandler:OnEvent(eventname, arg) Also note the register line at the bottom of the file which is nothing more than saying you have a function which processes stuff when the even triggers. (note the issues above, when does it trigger :)
if ever in doubt printtable(arg) and print(eventname) is your friends.
Ed
Hopefully you will look thru the code and get a good feel for how it's done. You had the core functions ok but not the event flow. It also seemed the way you were going was with timers which is an extremely bad idea.
Notice in the code how I use the myapp.myeventhandler:OnEvent(eventname, arg) Also note the register line at the bottom of the file which is nothing more than saying you have a function which processes stuff when the even triggers. (note the issues above, when does it trigger :)
if ever in doubt printtable(arg) and print(eventname) is your friends.
Ed
Feel free to ask me what the arguments are for different functions and events.
OnEvent should take a variable number of args:
function blah:OnEvent(eventname, ...)
local args = {...}
do stuff.
end
OnEvent should take a variable number of args:
function blah:OnEvent(eventname, ...)
local args = {...}
do stuff.
end