02/02/23, 05:02 PM | #1 |
|
Help with basic keybind saving a variable
Hey guys im looking to convert a section of code im currently using and having to manually edit into a press and hold for 1-2secs keybind to save a target or user @name variable for it. Any suggestions? heres what ive got right now:
<Bindings> <Layer name="SI_KEYBINDINGS_LAYER_GENERAL"> <Category name="|c9900FFRidinDirty|r"> <Action name="MOUNT_USER"> <Down>UseMountAsPassenger("@NAME")</Down> <!-- EDIT FOR DESIRED TARGET @NAME --> </Action> </Category> </Layer> </Bindings> Last edited by sinnereso : 02/02/23 at 05:21 PM. Reason: added post icon |
02/02/23, 06:05 PM | #2 |
Pressing a keybind 1-2 seconds to trigger it's action is not possible afaik, once you press it it will be firing it's code.
But you could try to use the <Up> action instead of <Down> if this is available. This would make your code at the action fire as you release the keybind (I think I remember there was somethign not working this way, so you'd have to try it). Your code actually is not saving anything but just tries to "mount as passenger". So you'd need to save the target you look at first. Targets below the reticle have a unitTag called "reticleover", which can be passed in to all kind of API functions that use unitTags. The one you look for would be: GetUnitDisplayName(unitTag) In your case you need to call GetUnitDisplayName("reticleover") In your addon's lua file create a global table with the name of your addon, here I'll just use MyAddon. Replace that with your addon's name, e.g. RidinDirty Lua Code:
--In your EVENT_ADD_ON_LOADED callback do: --Define SavedVariables and add them MyAddon.savedVariables = ZO_SavedVariables:NewAccountWide(MyAddon.svName, 1, GetWorldName(), { lastMountOwner = nil }, nil, nil) --Saved with GetWorldName() differently per server so NA and EU and PTS players can save different targets to mount In your Bindings.xml: Code:
<Bindings> <Layer name="SI_KEYBINDINGS_LAYER_GENERAL"> <Category name="|c9900FFRidinDirty|r"> <Action name="MOUNT_SAVE_OWNER"> <Up>MyAddon.SaveMountOwner()</Up> <!-- Try if this works, else use Down --> </Action> <Action name="MOUNT_USER"> <Down>MyAddon.MountWithSavedOwner()</Down> </Action> </Category> </Layer> |
|
02/02/23, 06:37 PM | #3 |
|
Wow thank you.. I might be able to make use of most of that, I had a feeling what I wanted wasnt possible. I was really hoping to be able to set a keybind to mount a user and use the same keybind but holding it for 1-2secs to save the user to mount so manual editing of the bindings wasnt needed.
I think i can use most of what you provided with 2 seperate key bindings which is better than nothing.. thank you. |
02/02/23, 06:47 PM | #4 |
You can try if using <Down> (get reticle displayname and save it) and <Up> (mount on the saved displayname) works -> But I doubt it.
Add some d("text here") messages in the functions to see if they are called properly. |
|
02/02/23, 07:21 PM | #5 |
|
I just finished trying to mod what you posted just to see if i can get a functional version.. i changed the saved vars file and corrected a naming in the bindings. The addon seems to be loading fine with no errors but i cant get it to register under the controls.
heres how its setup atm all 3 files. It looks like it should be working but isnt. MANIFEST: Code:
; This Add-on is not created by, affiliated with or sponsored by ZeniMax ; Media Inc. or its affiliates. The Elder Scrolls® and related logos are ; registered trademarks or trademarks of ZeniMax Media Inc. in the United ; States and/or other countries. All rights reserved. ; You can read the full terms at https://account.elderscrollsonline.com/add-on-terms ## Title: |c9900FFRidinDirty|r ## Description: Keybind to mount specific @NAME's multi-rider mount entered on line #5 of "bindings.xml" ## Author: Michael Cullen(@sinnereso) ## Version: 1.3 ## APIVersion: 100034 100036 ## SavedVariables: RidinDirtyVars RidinDirty.lua bindings.xml Code:
RidinDirty = {} RidinDirty.svName = "RidinDirtyVars" --name of the SV table. --Dont forget to add the ##SavedVariables: MyAddonSavedVariables tag to your manifest txt file! RidinDirty.savedVariables = {} --empty SV table of my addon --Define the function to save the target displayname below the retilce to the SavedVariables function RidinDirty.SaveMountOwner() local displayNameToTaxiWith = GetUnitDisplayName("reticleover") if displayNameToTaxiWith == nil or displayNameToTaxiWith == "" then return end RidinDirty.savedVariables.lastMountOwner = displayNameToTaxiWith end --Define the function to Mount with the last saved target function RidinDirty.MountWithSavedOwner() local lastMountOwner = RidinDirty.savedVariables.lastMountOwner if lastMountOwner == nil or lastMountOwner == "" then return end UseMountAsPassenger(lastMountOwner) end Code:
<Bindings> <Layer name="SI_KEYBINDINGS_LAYER_GENERAL"> <Category name="|c9900FFRidinDirty|r"> <Action name="SAVE_MOUNT_OWNER"> <Up>RidinDirty.SaveMountOwner()</Up> <!-- Try if this works, else use Down --> </Action> <Action name="MOUNT_USER"> <Down>RidinDirty.MountWithSavedOwner()</Down> </Action> </Category> </Layer> </Bindings> |
02/02/23, 07:57 PM | #6 |
|
ok I think im close.. its all in the LUA now.
LUA: Code:
RidinDirty = {} RidinDirty.svName = "RidinDirtyVars" --name of the SV table. --Dont forget to add the ##SavedVariables: MyAddonSavedVariables tag to your manifest txt file! --RidinDirty.savedVariables = {} --empty SV table of my addon function RidinDirty:Initialize() RidinDirty.savedVariables = ZO_SavedVariables:NewAccountWide(RidinDirty.svName, RidinDirty.variableVersion, GetWorldName(), { lastMountOwner = nil }, nil, nil) --Saved with GetWorldName() differently per server so NA and EU and PTS players can save different targets to mount end local function OnAddOnLoaded(eventCode, addOnName) if (addOnName ~= "RidinDirty") then return end EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED) ZO_CreateStringId("SI_BINDING_NAME_MOUNT_USER", "Mount User") ZO_CreateStringId("SI_BINDING_NAME_SAVE_MOUNT_OWNER", "Save Mount Owner") EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED) end --Define the function to save the target displayname below the retilce to the SavedVariables function RidinDirty.SaveMountOwner() local displayNameToTaxiWith = GetUnitDisplayName("reticleover") if displayNameToTaxiWith == nil or displayNameToTaxiWith == "" then return end RidinDirty.savedVariables.lastMountOwner = displayNameToTaxiWith end --Define the function to Mount with the last saved target function RidinDirty.MountWithSavedOwner() local lastMountOwner = RidinDirty.savedVariables.lastMountOwner if lastMountOwner == nil or lastMountOwner == "" then return end UseMountAsPassenger(lastMountOwner) end EVENT_MANAGER:RegisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED, OnAddOnLoaded) |
02/02/23, 08:33 PM | #7 |
|
Im close but getting errors i cant make sense of yet.
LUA: Code:
RidinDirty = {} RidinDirty.svName = "RidinDirtyVars" --name of the SV table. --Dont forget to add the ##SavedVariables: MyAddonSavedVariables tag to your manifest txt file! --RidinDirty.savedVariables = {} --empty SV table of my addon function RidinDirty:Initialize() RidinDirty.savedVariables = ZO_SavedVariables:NewAccountWide(RidinDirty.svName, RidinDirty.variableVersion, GetWorldName(), { lastMountOwner = nil }, nil, nil) end local function OnAddOnLoaded(eventCode, addOnName) if (addOnName ~= "RidinDirty") then return end EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED) ZO_CreateStringId("SI_BINDING_NAME_MOUNT_OWNER", "Mount Owner") ZO_CreateStringId("SI_BINDING_NAME_SAVE_MOUNT_OWNER", "Save Mount Owner") EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED) end --Define the function to save the target displayname below the retilce to the SavedVariables function RidinDirty.SaveMountOwner() local displayNameToTaxiWith = GetUnitDisplayName("reticleover") if displayNameToTaxiWith == nil or displayNameToTaxiWith == "" then return end RidinDirty.savedVariables.lastMountOwner = displayNameToTaxiWith end --Define the function to Mount with the last saved target function RidinDirty.MountWithSavedOwner() local lastMountOwner = RidinDirty.savedVariables.lastMountOwner if lastMountOwner == nil or lastMountOwner == "" then return end UseMountAsPassenger(lastMountOwner) end EVENT_MANAGER:RegisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED, OnAddOnLoaded) Code:
user:addons/ridindirty/ridindirty.lua:26: attempt to index a nil value stack traceback: user:addons/ridindirty/ridindirty.lua:26: in function 'RidinDirty.SaveMountOwner' <locals> displaynametotaxiwith = "@XXXXXX" </locals> :1: in function '(main chunk)' <locals> keybind = "SAVE_MOUNT_OWNER" </locals> |
02/02/23, 08:43 PM | #8 |
You are not calling your Initialize function so there are no savedvars etc.
And you should not use the : notation if not needed (you'll learn that later on perhaps if needed). If your addon was created as a simple table like RidinDirty = {} you should define and call the functions with . notation! So changed RidinDirty:Initialized to RidinDirty.Initialize and call it at event_add_on_loaded. Lua Code:
btw the error message told you: line 26 = RidinDirty.savedVariables.lastMountOwner = displayNameToTaxiWith Error "attempt to index a nil value" It tries to index a table (RidinDirty.savedVariables), which is nil (as your Initialize function was not called and thus the table was not created) |
|
02/02/23, 09:25 PM | #9 |
|
SWEET! its working now with this code but isnt saving to variables file so its resetting to nil on reload/relog:
Code:
RidinDirty = {} RidinDirty.svName = "RidinDirtyVars" --name of the SV table. --Dont forget to add the ##SavedVariables: MyAddonSavedVariables tag to your manifest txt file! RidinDirty.savedVariables = {} --empty SV table of my addon function RidinDirty.Initialize() RidinDirty.savedVariables = ZO_SavedVariables:NewAccountWide(RidinDirty.svName, RidinDirty.variableVersion, GetWorldName(), { lastMountOwner = nil }, nil, nil) end --EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED) local function OnAddOnLoaded(eventCode, addOnName) if (addOnName ~= "RidinDirty") then return end ZO_CreateStringId("SI_BINDING_NAME_MOUNT_OWNER", "Mount Owner") ZO_CreateStringId("SI_BINDING_NAME_SAVE_MOUNT_OWNER", "Save Mount Owner") RidinDirty.Initialize() end --Define the function to save the target displayname below the retilce to the SavedVariables function RidinDirty.SaveMountOwner() local displayNameToTaxiWith = GetUnitDisplayName("reticleover") if displayNameToTaxiWith == nil or displayNameToTaxiWith == "" then return end RidinDirty.savedVariables.lastMountOwner = displayNameToTaxiWith end --Define the function to Mount with the last saved target function RidinDirty.MountWithSavedOwner() local lastMountOwner = RidinDirty.savedVariables.lastMountOwner if lastMountOwner == nil or lastMountOwner == "" then return end UseMountAsPassenger(lastMountOwner ) end --EVENT_MANAGER:RegisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED, OnAddOnLoaded) |
02/02/23, 09:41 PM | #10 |
Yes the event manager lines are needed as the event_add_on_loaded is called for each addon once and your addon shoud not do anything BEFORE actually your addon was loaded -> indicated via the event by comparing the addon name to yours.
After that you unregister it so that no other addon loaded after your's is doing the name comparison again and again. Same for addons that use savedvariables! If you initi them before event_add_on_loaded of your addon hits they will be re initalized later on and are empty then! -> All explained at the esoui WIKI tutorials Addons should always use that even unless your addon's purpose is not needing it because of no SV and only a simple code injection that could be loaded whenever you want it to load. If you do not use the event the code is run as the files are read and that could be way too early, before other addons that you check with the txt manifest tag ## DependsOn or ## OptionallyDependsOn were loaded! If your savedvariables do not save you either got a type in your SV table name in the lua code or in the txt manifest file behind the tag ## SavedVariables: <yourSVTableNameHere>? Compare them if they match completely! Or you have stripped the event_Add_on_loaded and loaded your SV before and thus they are nil again as described above! |
|
02/02/23, 10:15 PM | #11 |
|
## SavedVariables: RidinDirtyVars
matches everywhere perfectly.. i been at this 14hrs now and my mind is blown i think i cant even think anymore and rdy to give up need 1 button to saver an @name to a variable file and another to load it.. apparently its equal to calculating the mass of the universe lol |
02/02/23, 11:03 PM | #12 |
|
Code:
RidinDirty = {} RidinDirty.svName = "RidinDirtyVars" --name of the SV table. --Dont forget to add the ##SavedVariables: MyAddonSavedVariables tag to your manifest txt file! RidinDirty.savedVariables = {} --empty SV table of my addon function RidinDirty.Initialize() RidinDirty.savedVariables = ZO_SavedVariables:NewAccountWide(RidinDirty.svName, RidinDirty.variableVersion, nil, { lastMountOwner = nil }, GetWorldName()) end local function OnAddOnLoaded(eventCode, addOnName) if (addOnName ~= "RidinDirty") then return end ZO_CreateStringId("SI_BINDING_NAME_MOUNT_OWNER", "Mount Owner") ZO_CreateStringId("SI_BINDING_NAME_SAVE_MOUNT_OWNER", "Save Mount Owner") --EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED) RidinDirty.Initialize() end --Define the function to save the target displayname below the retilce to the SavedVariables function RidinDirty.SaveMountOwner() local displayNameToTaxiWith = GetUnitDisplayName("reticleover") if displayNameToTaxiWith == nil or displayNameToTaxiWith == "" then return end RidinDirty.savedVariables.lastMountOwner = displayNameToTaxiWith end --Define the function to Mount with the last saved target function RidinDirty.MountWithSavedOwner() local lastMountOwner = RidinDirty.savedVariables.lastMountOwner if lastMountOwner == nil or lastMountOwner == "" then return end UseMountAsPassenger(lastMountOwner) end --EVENT_MANAGER:RegisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED, OnAddOnLoaded) |
02/03/23, 08:21 AM | #13 |
|
So everything working as it should once loaded for that session but
-error on line8 with the initialize function not saving nil value after reload/relog -and the fact it isnt saving and have to re-set user after reload/relog which is likly what the error is saying. heres where im at so far: Code:
RidinDirty = {} RidinDirty.svName = "RidinDirtyVars" --name of the SV table. RidinDirty.savedVariables = {} --empty SV table of my addon function RidinDirty.Initialize() RidinDirty.savedVariables = ZO_SavedVariables:NewAccountWide(RidinDirty.svName, RidinDirty.variableVersion, GetWorldName(), nil, nil) end --EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED) local function OnAddOnLoaded(eventCode, addOnName) if (addOnName ~= "RidinDirty") then return end EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED) ZO_CreateStringId("SI_BINDING_NAME_MOUNT_OWNER", "Mount Owner") ZO_CreateStringId("SI_BINDING_NAME_SAVE_MOUNT_OWNER", "Save Mount Owner") EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED) d("ON_LOADED") RidinDirty.Initialize() end --Define the function to save the target displayname below the retilce to the SavedVariables function RidinDirty.SaveMountOwner() local displayNameToTaxiWith = GetUnitDisplayName("reticleover") if displayNameToTaxiWith == nil or displayNameToTaxiWith == "" then return end RidinDirty.savedVariables.lastMountOwner = displayNameToTaxiWith d("Saving Owner") end --Define the function to Mount with the last saved target function RidinDirty.MountWithSavedOwner() local lastMountOwner = RidinDirty.savedVariables.lastMountOwner if lastMountOwner == nil or lastMountOwner == "" then return end UseMountAsPassenger(lastMountOwner ) d("Mounting Owner") end EVENT_MANAGER:RegisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED, OnAddOnLoaded) |
02/03/23, 09:32 AM | #14 |
|
ok this works flawlessly except no saved variables and resets upon relodui/relog. So what i need help with is where to put this stuff to save and retrieve the data and not try to save a nil value:
Code:
RidinDirty.savedVariables = ZO_SavedVariables:NewAccountWide( RidinDirty.svName, RidinDirty.variableVersion, GetWorldName(), { lastMountOwner = nil }, nil, nil) Code:
RidinDirty = {} RidinDirty.svName = "RidinDirtyVars" --name of the SV table. RidinDirty.savedVariables = {} --empty SV table of my addon --function RidinDirty.Initialize() --RidinDirty.savedVariables = ZO_SavedVariables:NewAccountWide( RidinDirty.svName, RidinDirty.variableVersion, GetWorldName(), { lastMountOwner = nil }, nil, nil) --end local function OnAddOnLoaded(eventCode, addOnName) if (addOnName ~= "RidinDirty") then return end EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED) ZO_CreateStringId("SI_BINDING_NAME_MOUNT_OWNER", "Mount Owner") ZO_CreateStringId("SI_BINDING_NAME_SAVE_MOUNT_OWNER", "Save Mount Owner") EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED) --RidinDirty.Initialize() end --Define the function to save the target displayname below the retilce to the SavedVariables function RidinDirty.SaveMountOwner() local displayNameToTaxiWith = GetUnitDisplayName("reticleover") if displayNameToTaxiWith == nil or displayNameToTaxiWith == "" then return end RidinDirty.savedVariables.lastMountOwner = displayNameToTaxiWith d("Saving Owner") end --Define the function to Mount with the last saved target function RidinDirty.MountWithSavedOwner() local lastMountOwner = RidinDirty.savedVariables.lastMountOwner if lastMountOwner == nil or lastMountOwner == "" then return end UseMountAsPassenger(lastMountOwner ) d("Mounting Owner") end EVENT_MANAGER:RegisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED, OnAddOnLoaded) |
02/03/23, 09:56 AM | #15 |
You should "read" the error messages, they tell you at which line something is tried to index which is nil (tried to index means there is a table which is nil and you do something like table.data) or a variable is nil etc.
Where is RidinDirty.variableVersion defined? If you do not define it it will be nil and thus your SV won't have a version and not save. You need to define variables and functions before you can use them! Btw changing the SV version number will reset your SV data too! So keep that unchanged once released, unless there is the need to reset them, or your users will get angry with you :-) And you do not need to call this twice: EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED) Once is enough. |
|
02/03/23, 09:58 AM | #16 |
|
the errors all line 8 which is the ZO saved variables line and like 20ish which is the call for the initilize with that saved variable in it. ill see what i can do about the version.
|
02/03/23, 10:09 AM | #17 |
|
ok so switched the ZO saved variables back to what you originally suggested with the 1 as version.. still getting same error on line 8 and 17.
line8 attempt to index a nil value line17 <locals>the error is : eventcode = 65536,addonname = "RidinDirty"</locals> code: Code:
RidinDirty = {} RidinDirty.svName = "RidinDirtyVars" --name of the SV table. RidinDirty.savedVariables = {} --empty SV table of my addon function RidinDirty.Initialize() RidinDirty.savedVariables = ZO_SavedVariables:NewAccountWide( RidinDirty.svName, 1, GetWorldName(), { lastMountOwner = nil }, nil, nil) end local function OnAddOnLoaded(eventCode, addOnName) if (addOnName ~= "RidinDirty") then return end EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED) ZO_CreateStringId("SI_BINDING_NAME_MOUNT_OWNER", "Mount Owner") ZO_CreateStringId("SI_BINDING_NAME_SAVE_MOUNT_OWNER", "Save Mount Owner") EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED) RidinDirty.Initialize() end --Define the function to save the target displayname below the retilce to the SavedVariables function RidinDirty.SaveMountOwner() local displayNameToTaxiWith = GetUnitDisplayName("reticleover") if displayNameToTaxiWith == nil or displayNameToTaxiWith == "" then return end RidinDirty.savedVariables.lastMountOwner = displayNameToTaxiWith d("Saving Owner") end --Define the function to Mount with the last saved target function RidinDirty.MountWithSavedOwner() local lastMountOwner = RidinDirty.savedVariables.lastMountOwner if lastMountOwner == nil or lastMountOwner == "" then return end UseMountAsPassenger(lastMountOwner ) d("Mounting Owner") end EVENT_MANAGER:RegisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED, OnAddOnLoaded) |
02/03/23, 10:25 AM | #18 | |
Here is an example: Lua Code:
Careful: When a user switches from desktop to the game while holding the key the up event might trigger without the down event setting the timer. That would mean pressTime = nil and releaseTime - nil = don't know, probably an error. Might also only happen with modifier keys like Ctrl, Shift, Alt. You could probably emulate holding a key as well.. but you would need some kind of global flag that is switched when receiving an up event. And more can go wrong. Edit: By the way, I totally forgot about the Up-Event until now. I have /reloadui bound to a key but I think I'll take the holding a key for longer idea to prevent accidental reloads. Thanks for the ideas Last edited by wookiefriseur : 02/03/23 at 01:48 PM. Reason: Changed some variable names |
||
02/03/23, 11:16 AM | #19 |
|
Thank you ill look into it once i get this variable saving figured out.. its the primary issue.
|
02/03/23, 11:43 AM | #20 |
ESOUI » Developer Discussions » Lua/XML Help » Help with basic keybind saving a variable |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Linear Mode |
Switch to Hybrid Mode |
Switch to Threaded Mode |
|
|