gaz
New Member
Posts: 27
|
Post by gaz on Feb 20, 2006 6:43:09 GMT -5
Hiya,
The drop item function will occasionally crash, critical exception error. Line 655 i believe, which is just as the function starts.
Does windower have problems if im alt-tabed out when send key functions are used?
Also, Is there anyway to add an auto re-bait function incase the line breaks, or an alarm to say that the line has broke? (Well I know there is, just... how, hehe)
|
|
|
Post by X-Drop on Feb 20, 2006 8:33:45 GMT -5
Hiya, The drop item function will occasionally crash, critical exception error. Line 655 i believe, which is the just the function start. Does windower have problems if im alt-tabed out when send key functions are used? Also, Is there anyway to add an auto re-bait function incase the line breaks, or an alarm to say that the line has broke? (Well I know there is, just... how, hehe) Lemme guess... line 655 crashed because of attempt to index fish (a nil value). Do me a favor, next time this happens post the name of the fish. Re-bait the line? Um.. no, not touching that. There is a ton of things Lunar could do for you, but I didn't include. You should do like any good fisherman in FFXI and create a macro.
|
|
gaz
New Member
Posts: 27
|
Post by gaz on Feb 20, 2006 8:48:48 GMT -5
Thanks, It was either:
A Ripped Cap or Pamtam Kelp (this does stack by the way - Levi says it dosn't)
Perhaps it has problems throwing multiple Kelps away becase it thinks they dont stack?
I've only just started fishing to kill time in those long spells waiting for a party. So, now a newb question, how do I rebait in a macro... /equip ammo "little worm" ?
Cheers,
|
|
|
Post by X-Drop on Feb 20, 2006 9:07:53 GMT -5
Here's the rewritten path function. function define_path() -------------------------------------------------------------------------------------------------------- local i,j -- temperary placeholder varibles (not used, just shifts the important varible over)
i,j,script_path = string.find(debug.getinfo(1).source,"(.+[\\/]Lunar[\\/]Scripts[\\/].+[\\/])") i,j,dir_name = string.find( Windower.script_GetArg(1),"(.+[\\/])") i,j,lunar_path = string.find(debug.getinfo(1).source,"(.+[\\/]Lunar[\\/]Scripts[\\/])") i,j,windower_path = string.find(debug.getinfo(1).source,"^(.+[\\/])plugins[\\/]Lunar[\\/]Scripts[\\/]") -------------------------------------------------------------------------------------------------------- end
|
2 of the varibles can easily be derrived from the others. function define_path() -------------------------------------------------------------------------------------------------------- local i,j -- temperary placeholder varibles (not used, just shifts the important varible over)
i,j,windower_path = string.find(debug.getinfo(1).source,"^(.+[\\/])plugins[\\/]Lunar[\\/]Scripts[\\/]") i,j,dir_name = string.find( Windower.script_GetArg(1),"(.+[\\/])")
lunar_path = windower_path.."plugins\\Lunar\\Scripts\\" script_path = lunar_path..dir_name -------------------------------------------------------------------------------------------------------- end
|
Excellent job. These paths are much more refined than the previous ones. Curious though, you get the '@' symbol in debug.getinfo(1).source too though, huh?
function runCmd(cmd) -------------------------------------------------------------------------------------------------------- local _,_,windowerPath=string.find(debug.getinfo(1).source,"^(.+[\\/])plugins[\\/]Lunar[\\/]Scripts[\\/]") local scriptFile=string.gsub(os.tmpname(),"[\\/%.]","")..".tws" local fopt=io.open(windowerPath.."scripts/"..scriptFile,"wt")
if fopt then fopt:write(cmd) fopt:close() Windower.console_Exec(scriptFile,true) os.remove(windowerPath.."scripts/"..scriptFile)
return true else Windower.console_Write("Unable to open command script.") return false end -------------------------------------------------------------------------------------------------------- end
|
Wow, I totally missed that fact that "w" will create a new file if it does not exist. Damn that helps alot. I like the '.tws' too!^^
I've held my comment until after I fixed some things. Check out how pressing a hotkey in one thread simulates an instant change in another thread without actually having to stop and check for new commands. Actually, the script is stopping and checking commands at some point. Until we can get event callbacks, nobody can really say this truthfully. What I see that's eliminated is the check for what command is being executed. Instead, it's taking in the command as a function name. I see the script is made more to interface with it's GUI rather than CLI, but the script can crash if a user decides to send a command manually to the script. The idea of using something global like IsKeyBound() was actually Tiny Terrors idea to allow multiple threads to communicate. Before I was using some crazy reading/writing technique to produce a communication hub. But it was terribly slow because I had to create a semaphore to lock the comm file when it was being written to. It works, but this is another example of dirty code. It's capable of causing interference with other scripts running. Slim chance given the number of keys that can be bound and the different shift states, but still possible enough to happen by accident. Other than using the command function I posted to send commands to other scripts (better idea), we'll pretty much need that IPC lib that Tiny has in one of the upcoming versions. Again, I'm not a programmer so my explanation of things is always a bit off. It is dirty code that I'm using, true. The point I was trying to make is this, Leviathan can run it's coarse and never have to stop what it's doing to check for user input. That is cool stuff. Leviathan checks for a bound key in the same manner that it would check the value of a variable. The end result is nearly instant processing of user input. The alternative of using Windower.console_Exec("blah.txt") was considered, but pass on because in that scenario Leviathan would have to stop what it is doing to check on user input. That is not too cool... Nevertheless, the event callback that you mentioned earlier is what I would like to see eventually added to Lunar. What I do in Leviathan is some off-the-wall shit, but it does the job nicely in Lunar's current state.
|
|
|
Post by X-Drop on Feb 20, 2006 9:16:24 GMT -5
Thanks, It was either: A Ripped Cap or Pamtam Kelp (this does stack by the way - Levi says it dosn't) Perhaps it has problems throwing multiple Kelps away becase it thinks they dont stack? I've only just started fishing to kill time in those long spells waiting for a party. So, now a newb question, how do I rebait in a macro... /equip ammo "little worm" ? Cheers, I'm gonna look into those two catches. Might be the phrasing used.
Your macro looks good, just remember to capitalize the string as seen in game, /equip ammo "Little Worm"
Check out this these links since you are just starting out. Updated FishingClanwind
|
|
gaz
New Member
Posts: 27
|
Post by gaz on Feb 20, 2006 9:30:15 GMT -5
Cool thanks,
If its not too much bother, when your done fixing this and implemnting any other improvements can you release Leviathan 1.52 or 1.51 (fix).
Leviathan makes fishing so much fun ;D
|
|
sdphantom
Full Member
Savior and Destroyer
Posts: 230
|
Post by sdphantom on Feb 20, 2006 10:03:55 GMT -5
Here's the rewritten path function. function define_path() -------------------------------------------------------------------------------------------------------- local i,j -- temperary placeholder varibles (not used, just shifts the important varible over)
i,j,script_path = string.find(debug.getinfo(1).source,"(.+[\\/]Lunar[\\/]Scripts[\\/].+[\\/])") i,j,dir_name = string.find( Windower.script_GetArg(1),"(.+[\\/])") i,j,lunar_path = string.find(debug.getinfo(1).source,"(.+[\\/]Lunar[\\/]Scripts[\\/])") i,j,windower_path = string.find(debug.getinfo(1).source,"^(.+[\\/])plugins[\\/]Lunar[\\/]Scripts[\\/]") -------------------------------------------------------------------------------------------------------- end
|
2 of the varibles can easily be derrived from the others. function define_path() -------------------------------------------------------------------------------------------------------- local i,j -- temperary placeholder varibles (not used, just shifts the important varible over)
i,j,windower_path = string.find(debug.getinfo(1).source,"^(.+[\\/])plugins[\\/]Lunar[\\/]Scripts[\\/]") i,j,dir_name = string.find( Windower.script_GetArg(1),"(.+[\\/])")
lunar_path = windower_path.."plugins\\Lunar\\Scripts\\" script_path = lunar_path..dir_name -------------------------------------------------------------------------------------------------------- end
|
Excellent job. These paths are much more refined than the previous ones. Curious though, you get the '@' symbol in debug.getinfo(1).source too though, huh? I believe so, using a number instead of a function name points to the coresponding function in the call stack. Other than that, there shouldn't be any difference. I always overlook the '@' symbol existing there and think it's only the script path. The patterns only go up to the last '\' of the path, so it shouldn't even go near the '@' symbol. I've held my comment until after I fixed some things. Actually, the script is stopping and checking commands at some point. Until we can get event callbacks, nobody can really say this truthfully. What I see that's eliminated is the check for what command is being executed. Instead, it's taking in the command as a function name. I see the script is made more to interface with it's GUI rather than CLI, but the script can crash if a user decides to send a command manually to the script. It works, but this is another example of dirty code. It's capable of causing interference with other scripts running. Slim chance given the number of keys that can be bound and the different shift states, but still possible enough to happen by accident. Other than using the command function I posted to send commands to other scripts (better idea), we'll pretty much need that IPC lib that Tiny has in one of the upcoming versions. Again, I'm not a programmer so my explanation of things is always a bit off. It is dirty code that I'm using, true. The point I was trying to make is this, Leviathan can run it's coarse and never have to stop what it's doing to check for user input. That is cool stuff. Leviathan checks for a bound key in the same manner that it would check the value of a variable. The end result is nearly instant processing of user input. The alternative of using Windower.console_Exec("blah.txt") was considered, but pass on because in that scenario Leviathan would have to stop what it is doing to check on user input. That is not too cool... I think we're talking about different things. I think you're talking about using the key bindings so the user doesn't need to type commands in all the time, making the script seem to run smoother. In reality, the keybindings are piled on top of the command code. The keybinds send commands to the script's command stack. The script checks on the command stack every so often and runs whatever command exists. The code speaks volumes of what it's really doing, even though it may be different than what it seems.
|
|
|
Post by X-Drop on Feb 20, 2006 10:51:53 GMT -5
I think you're talking about using the key bindings so the user doesn't need to type commands in all the time, making the script seem to run smoother. Nope... I do not use the key binding to send any command string whatsoever. Actually I just use an empty string. What I'm doing in Leviathan has nothing to do with commands typed into the console nor commands passed in a key binding. Rather I have one script handle user input by simply binding a certain key. Leviathan never stop to check for any commands on the stack, because there are never any commands sent there. All Leviathan does is look to see if a certain key is bound, much like if a certain global variable is true/false. And in this sense, the user input is nearly instant by having multiple threads communicate(albeit in a very limited manner). Much like a callback event, no?
|
|
Sufo
New Member
Extreme Web Designer and Scripter
Posts: 48
|
Post by Sufo on Feb 20, 2006 14:07:25 GMT -5
Hiya, The drop item function will occasionally crash, critical exception error. Line 655 i believe, which is the just the function start. Does windower have problems if im alt-tabed out when send key functions are used? Also, Is there anyway to add an auto re-bait function incase the line breaks, or an alarm to say that the line has broke? (Well I know there is, just... how, hehe) Lemme guess... line 655 crashed because of attempt to index fish (a nil value). Do me a favor, next time this happens post the name of the fish. Re-bait the line? Um.. no, not touching that. There is a ton of things Lunar could do for you, but I didn't include. You should do like any good fisherman in FFXI and create a macro. Hey X-Drop, This happened to me last night as well. The fish it crashed on was Bastore Sardines. I only caught one of them as well. Not sure if that would make the difference but I thought I'd add that too.
|
|
|
Post by X-Drop on Feb 20, 2006 14:25:31 GMT -5
Hey X-Drop, This happened to me last night as well. The fish it crashed on was Bastore Sardines. I only caught one of them as well. Not sure if that would make the difference but I thought I'd add that too. Hmm... do Bastore Sardines normally display fine for you? And if so then your saying this was just a rare instance that it didn't display Bastore Sardines properly? That's wierd because they display just fine for me.
|
|
Sufo
New Member
Extreme Web Designer and Scripter
Posts: 48
|
Post by Sufo on Feb 20, 2006 15:31:04 GMT -5
Hey X-Drop, This happened to me last night as well. The fish it crashed on was Bastore Sardines. I only caught one of them as well. Not sure if that would make the difference but I thought I'd add that too. Hmm... do Bastore Sardines normally display fine for you? And if so then your saying this was just a rare instance that it didn't display Bastore Sardines properly? That's wierd because they display just fine for me. Yeah they usually work perfectly. I used the scipt with a new character though. Do I absoluteley need to change the name? Or is it just for thewelcome?
|
|
|
Post by X-Drop on Feb 20, 2006 16:08:33 GMT -5
Yeah they usually work perfectly. I used the scipt with a new character though. Do I absoluteley need to change the name? Or is it just for thewelcome? Ah, there's the problem. Did you notice at startup on your mule Leviathan said "Welcome, Jareph!"? I wish I coulda just used FFXI.player_GetPlayerName() to grab the name without the hassle, but you need the correct character name if you want Leviathan to run.
|
|
Sufo
New Member
Extreme Web Designer and Scripter
Posts: 48
|
Post by Sufo on Feb 20, 2006 16:17:24 GMT -5
Yeah they usually work perfectly. I used the scipt with a new character though. Do I absoluteley need to change the name? Or is it just for thewelcome? Ah, there's the problem. Did you notice at startup on your mule Leviathan said "Welcome, Jareph!"? I wish I coulda just used FFXI.player_GetPlayerName() to grab the name without the hassle, but you need the correct character name if you want Leviathan to run. Ok Ill change that once the server maintenance is done..... (ends at 5PM where I'm at! @_@ )
|
|
|
Post by X-Drop on Feb 20, 2006 17:06:45 GMT -5
Ok then.... there went that fun! The FFXI update has rendered some of the Lunar functions useless. Not a surprise I guess, but a little bit of a bummer. Gonna go see what other function are broke.
|
|
sdphantom
Full Member
Savior and Destroyer
Posts: 230
|
Post by sdphantom on Feb 20, 2006 20:51:52 GMT -5
I think you're talking about using the key bindings so the user doesn't need to type commands in all the time, making the script seem to run smoother. Nope... I do not use the key binding to send any command string whatsoever. Actually I just use an empty string. What I'm doing in Leviathan has nothing to do with commands typed into the console nor commands passed in a key binding. Rather I have one script handle user input by simply binding a certain key. Leviathan never stop to check for any commands on the stack, because there are never any commands sent there. All Leviathan does is look to see if a certain key is bound, much like if a certain global variable is true/false. And in this sense, the user input is nearly instant by having multiple threads communicate(albeit in a very limited manner). Much like a callback event, no? Ya, I see this is a pseudo callback. In a normal event callback, you have your hooks that hardly anyone sees that call functions in the main program. All of these example functions are found in your "hook" script, Input.lua. I see it as still part of Leviathan from the fact of that it's one of the 4 scripts in the project. That's where our thoughts differ. Without the IPC lib, we do what we can. We can't directly call functions of another script, so we improvise by using superglobal flags, dynamic commands, etc.
Source: Input.lua function bind_keys() -------------------------------------------------------------------------------------------------------- --Control.control_BindKey("INSERT", true, false, false, "") if catch_filter == 1 then Control.control_BindKey( "INSERT", true, true, false, "" ) end if catch_filter == 2 then Control.control_BindKey( "INSERT", true, false, true, "" ) end if assistance then Control.control_BindKey( "INSERT", true, true, true, "" ) end if sound_fx then Control.control_BindKey( "DELETE", true, false, false, "" ) end if auto_toss then Control.control_BindKey( "DELETE", true, true, false, "" ) end if auto_sort then Control.control_BindKey( "DELETE", true, false, true, "" ) end
Control.control_BindKey( assistance_key[1], true, assistance_key[3], assistance_key[2], ".Lunar command " .. dir_name .. "Input.lua f_assistance" ) Control.control_BindKey( catch_filter_key[1], true, catch_filter_key[3], catch_filter_key[2], ".Lunar command " .. dir_name .. "Input.lua f_catch_filter" ) Control.control_BindKey( auto_toss_key[1], true, auto_toss_key[3], auto_toss_key[2], ".Lunar command " .. dir_name .. "Input.lua f_auto_toss" ) Control.control_BindKey( auto_sort_key[1], true, auto_sort_key[3], auto_sort_key[2], ".Lunar command " .. dir_name .. "Input.lua f_auto_sort" ) Control.control_BindKey( sound_fx_key[1], true, sound_fx_key[3], sound_fx_key[2], ".Lunar command " .. dir_name .. "Input.lua f_sound_fx" ) Control.control_BindKey( quit_key[1], true, quit_key[3], quit_key[2], ".Lunar command " .. dir_name .. "Input.lua f_quit" ) local hotkeys = { assistance_key, catch_filter_key, auto_toss_key, auto_sort_key, sound_fx_key, quit_key, } local output = "" for index, value in ipairs(hotkeys) do local hotkey = "" if value[3] then hotkey = "ctrl+" end if value[2] then hotkey = hotkey .. "alt+" end hotkey = hotkey .. value[1] output = string.format( "%s[%s]%s ", output, hotkey, value[4] ) end Graphics.text_SetText( output, Display ) -------------------------------------------------------------------------------------------------------- end
|
This is where your key bindings for user input is, right? In the long run, these bindings, when triggered, send commands to itself. EX: Control.control_BindKey(quit_key[1],true,quit_key[3],quit_key[2], ".Lunar command "..dir_name.."Input.lua f_quit")
Source: Input.lua function get_command() -------------------------------------------------------------------------------------------------------- local command = {} for i = 1, Windower.script_GetCommandCount(), 1 do command = Windower.script_GetCommand() end local dynamic_function = _G[command[1]] dynamic_function() -------------------------------------------------------------------------------------------------------- end
|
The commands are picked up by this function and run. The commands sent by the key bindings above trigger functions like the one below.
Source: Input.lua function f_auto_sort() -------------------------------------------------------------------------------------------------------- if auto_sort then auto_sort = false Control.control_UnbindKey( "DELETE", true, false, true ) Graphics.primitive_SetVisibility(0, Auto_Sort_Icon) else auto_sort = true Control.control_BindKey( "DELETE", true, false, true, "" ) Graphics.primitive_SetVisibility(1, Auto_Sort_Icon) end -------------------------------------------------------------------------------------------------------- end
|
This is an example of one of the functions that is called by the key bindings. It sets a superglobal flag using another set of key bindings that are set to run nothing. Just a simple "is bound or not" will suffice. The main script runs checks on these flags when needed as if they were normal variables.
|
|