Thread Tools Display Modes
02/02/23, 05:02 PM   #1
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 245
Question 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
  Reply With Quote
02/02/23, 06:05 PM   #2
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,965
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:
  1. MyAddon = {}
  2.  
  3. MyAddon.svName = "MyAddonSavedVariables" --name of the SV table.
  4. --Dont forget to add the ##SavedVariables: MyAddonSavedVariables tag to your manifest txt file!
  5. MyAddon.savedVariables = {} --empty SV table of my addon
  6.  
  7.  
  8. --Define the function to save the target displayname below the retilce to the SavedVariables
  9. function MyAddon.SaveMountOwner()
  10.    local displayNameToTaxiWith = GetUnitDisplayName("reticleover")
  11.    if displayNameToTaxiWith == nil or displayNameToTaxiWith == "" then return end
  12.    MyAddon.savedVariables.lastMountOwner = displayNameToTaxiWith
  13. end
  14.  
  15. --Define the function to Mount with the last saved target
  16. function MyAddon.MountWithSavedOwner()
  17.    local lastMountOwner = MyAddon.savedVariables.lastMountOwner
  18.    if lastMountOwner  == nil or lastMountOwner  == "" then return end
  19.  
  20.    UseMountAsPassenger(lastMountOwner )
  21. end

--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>
  Reply With Quote
02/02/23, 06:37 PM   #3
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 245
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.
  Reply With Quote
02/02/23, 06:47 PM   #4
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,965
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.
  Reply With Quote
02/02/23, 07:21 PM   #5
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 245
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
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
 
 
--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
BINDINGS:
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>
  Reply With Quote
02/02/23, 07:57 PM   #6
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 245
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)
getting errors now tho executing the save or mount. at least on random people which might be normals as you can only mount someone in group but it should save anyone's @name for the save part I would think.
  Reply With Quote
02/02/23, 08:33 PM   #7
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 245
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)
and errors saving user. please ignore case I had to retyp from screenshot:
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>
  Reply With Quote
02/02/23, 08:43 PM   #8
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,965
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:
  1. RidinDirty = {}
  2.  
  3. RidinDirty.svName = "RidinDirtyVars" --name of the SV table.
  4. --Dont forget to add the ##SavedVariables: MyAddonSavedVariables tag to your manifest txt file!
  5. --RidinDirty.savedVariables = {} --empty SV table of my addon
  6. function RidinDirty.Initialize()
  7.     RidinDirty.savedVariables = ZO_SavedVariables:NewAccountWide(RidinDirty.svName, RidinDirty.variableVersion, GetWorldName(), { lastMountOwner = nil }, nil, nil)
  8. end
  9.  
  10. local function OnAddOnLoaded(eventCode, addOnName)
  11.     if (addOnName ~= "RidinDirty") then return end
  12.  
  13.     EVENT_MANAGER:UnregisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED)
  14.  
  15.     ZO_CreateStringId("SI_BINDING_NAME_MOUNT_OWNER", "Mount Owner")
  16.     ZO_CreateStringId("SI_BINDING_NAME_SAVE_MOUNT_OWNER", "Save Mount Owner")
  17.        
  18.     RidinDirty.Initialize()
  19. end
  20.  
  21. --Define the function to save the target displayname below the retilce to the SavedVariables
  22. function RidinDirty.SaveMountOwner()
  23.    local displayNameToTaxiWith = GetUnitDisplayName("reticleover")
  24.    if displayNameToTaxiWith == nil or displayNameToTaxiWith == "" then return end
  25.    
  26.    RidinDirty.savedVariables.lastMountOwner = displayNameToTaxiWith
  27. end
  28.  
  29. --Define the function to Mount with the last saved target
  30. function RidinDirty.MountWithSavedOwner()
  31.    local lastMountOwner = RidinDirty.savedVariables.lastMountOwner
  32.    if lastMountOwner  == nil or lastMountOwner  == "" then return end
  33.    
  34.    UseMountAsPassenger(lastMountOwner)
  35. end
  36.  
  37. EVENT_MANAGER:RegisterForEvent("RidinDirty", EVENT_ADD_ON_LOADED, OnAddOnLoaded)



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)
  Reply With Quote
02/02/23, 09:25 PM   #9
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 245
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)
I had one other question.. are the event manager lines needed? they migrated in from a previous version and i dont fully understand them. its working with them commented out but like i said isnt saving to file so it resets on reload/relog.
  Reply With Quote
02/02/23, 09:41 PM   #10
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,965
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!
  Reply With Quote
02/02/23, 10:15 PM   #11
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 245
## 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
  Reply With Quote
02/02/23, 11:03 PM   #12
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 245
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)
This works porfectly but isnt saving to variable file so its clearing after reload/relog. If i enable the event manager lines it gives me errors on the initilize line 8 saying it cant index a nil value.
  Reply With Quote
02/03/23, 08:21 AM   #13
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 245
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)
  Reply With Quote
02/03/23, 09:32 AM   #14
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 245
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)
current code working with saved variables/initilize commented out:
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)
someone please help i cant stare at this any longer!
  Reply With Quote
02/03/23, 09:56 AM   #15
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,965
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.
  Reply With Quote
02/03/23, 09:58 AM   #16
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 245
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.
  Reply With Quote
02/03/23, 10:09 AM   #17
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 245
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)
  Reply With Quote
02/03/23, 10:25 AM   #18
wookiefriseur
 
wookiefriseur's Avatar
Join Date: Mar 2014
Posts: 53
Originally Posted by Baertram View Post
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.
Seeing you mention using both up and down made me think that you could fake a long press event by using listeners on both down and up.


Here is an example:
Lua Code:
  1. RidinDirty = {} -- your addon table
  2. RidinDirty.keys = {} -- table to put multiple keys in here
  3.  
  4. function RidinDirty.mountActionDown()
  5.    local keypressTime = os.time() -- get current timestamp in seconds
  6.    RidinDirty.keys["mounting_action_key"] = keypressTime -- save the time for later
  7.    d("Down at " .. RidinDirty.keys["mounting_action_key"])
  8. end
  9.  
  10. function RidinDirty.mountActionUp()
  11.   local thresholdInSeconds = 2 -- <2s is short, >=2 is long
  12.   local pressTime = RidinDirty.keys["mounting_action_key"] -- retrieve the time
  13.   local releaseTime = os.time() -- get the time of key release
  14.   d("Up at " .. releaseTime)
  15.  
  16.   local pressDuration =  releaseTime - pressTime -- calculate difference
  17.   if pressDuration >= thresholdInSeconds then
  18.     d("Long Press (" .. pressDuration .. "s)") -- call some function here
  19.   else
  20.     d("Short Press (" .. pressDuration .. "s)") -- call some other function here
  21.   end
  22. end


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
  Reply With Quote
02/03/23, 11:16 AM   #19
sinnereso
AddOn Author - Click to view addons
Join Date: Oct 2022
Posts: 245
Thank you ill look into it once i get this variable saving figured out.. its the primary issue.
  Reply With Quote
02/03/23, 11:43 AM   #20
wookiefriseur
 
wookiefriseur's Avatar
Join Date: Mar 2014
Posts: 53
Originally Posted by sinnereso View Post
Thank you ill look into it once i get this variable saving figured out.. its the primary issue.



Try to use ZO_SavedVars. ZO_SavedVariables is not a thing, I think.
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » Help with basic keybind saving a variable


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off