hi and welcome,
first of all you should unregister the event_add_on_loaded again as your addon was found as it is run for each addon and library once and does not need to do your checks for each of the addons then anymore if yours was already found:
In your case this is no big problem but one should just understand that and unregister events again if not needed anymore -> could/may increase performance and loading screens in total above all addons.
Lua Code:
function HideCritterHealthbar.OnAddOnLoaded(event, addonName)
if addonName == HideCritterHealthbar.name then
EVENT_MANAGER:UnregisterForEvent(HideCritterHealthbar.name, EVENT_ADD_ON_LOADED)
HideCritterHealthbar:Initialize()
end
end
2nd:
Stick to 1 usage of the notation . or : !
function HideCritterHealthbar.OnAddOnLoaded(event, addonName)
function HideCritterHealthbar:Initialize()
You should not use the : if your addon is not using any kinf of object oriented approach using classes and objects.
As this is imply a function rename it to function HideCritterHealthbar.Initialize and also rename the call to it to use the . and do not use the : if not needed. Some example tutorials still use it and you can do like you want, but in the end it somehow disturbs the eye as one expects HideCritterHealthbar to be an object of ZO_Object or a subclass of something that way (which uses the variable "self" to point to it's own object).
You are using the 2self" pointer inside that line e.g. via self.main to point to the function HideCritterHealthbar.Main
EVENT_MANAGER:RegisterForEvent(self.name, EVENT_RETICLE_TARGET_CHANGED, self.Main)
-> Change that to EVENT_MANAGER:RegisterForEvent(self.name, EVENT_RETICLE_TARGET_CHANGED, HideCritterHealthbar.Main)
Else self could not work properly as you did not define HideCritterHealthbar as subcalss of ZO_Object.
Also change self.name to HideCritterHealthbar.name
In total you should think about the laod order of lua, it will compile from top to bottom so variables defined below a function that tries to use it will be out of scope/nil.
As your variable HideCritterHealthbar isd efined global (means no local up in front -> so it will be available via _G["HideCritterHealthbar"] or simply HideCritterHealthbar) the load order does not matter. But if they would be local you would need to put the event_add_on_loaded at the bottom, initialization above it, main above this and so on so that they would be found properly.
Do not use the hardcoded values here if there exist constants to use:
Code:
if (rReaction == 2 or rReaction == 3 or rReaction == 5) then
The API function GetUnitReaction returns a value of type UnitReactionType whichc an all be found in the API ESOUIDocumentation_Pxx.txt files linked at the Wiki -> API versions.
The UnitReactionTypes can be:
Code:
h5. UnitReactionType
* UNIT_REACTION_COMPANION
* UNIT_REACTION_DEFAULT
* UNIT_REACTION_FRIENDLY
* UNIT_REACTION_HOSTILE
* UNIT_REACTION_NEUTRAL
* UNIT_REACTION_NPC_ALLY
* UNIT_REACTION_PLAYER_ALLY
So better to use those instead of 2 3 and so on! You can inspect teh values of teh constants via an addon like MerTorchbug or Zgoo ingame via chat commands like /tb UNIT_REACTION_DEFAULT or /zgoo UNIT_REACTION_DEFAULT It will output the value into chat then.
Or you can use mer Torchbug's UI so simply type /tb and let it load. Then at the global inspector choose the appropriate tab e.g. constants or functions and use the search at the top.
Here is a list of the constant = value
Code:
UNIT_REACTION_DEFAULT = 0
UNIT_REACTION_FRIENDLY = 3
UNIT_REACTION_HOSTILE = 1
UNIT_REACTION_NEUTRAL = 2
UNIT_REACTION_NPC_ALLY = 5
UNIT_REACTION_PLAYER_ALLY = 4
Currently trying to find the reason for your problem.
Maybe the event is called multiple times if you move the reticle, like first as you leave the critter below the crosshair and then as you move it above the other user/npc etc.
You culd add debug messages via
d("My Text: " .. tostring(variableName))
to see what variable got what value and which event is called how often etc.
Anyway this here would be my improved code for you, hope it helps to learn a bit. Most ist the same you had written in the code, just a bit improved.
Lua Code:
HideCritterHealthbar = {}
HideCritterHealthbar.name = "HideCritterHealthbar"
local myAddonName = HideCritterHealthbar.name -- Speed up variable
local retOver = "reticleover" --Speed up variable
-- main function that runs every time target changes
function HideCritterHealthbar.Main(event)
local rName = GetUnitName(retOver)
local rReaction = GetUnitReaction(retOver)
local rIsCritter = false --preset the variable wth false to prevent several if ...else...down below
local reactionsToCheck = {
[UNIT_REACTION_NEUTRAL] = true,
[UNIT_REACTION_FRIENDLY] = true,
[UNIT_REACTION_NPC_ALLY] = true,
}
local namesToCheck = {
["Beetle"] = true,
["Butterfly"] = true,
Rat = true, --only a different notation possible for Strings. Either ["stringName"] or stringName directly
}
--Easier / more performant way to check multiple values. Check if it is inside a table namesToCheck
--if tableName[variableName] will check if the variableName in tableName is ~= nil and if it is a boolean value if is == true
--If the variable is not of type boolean it will just check if it's inside the table via ~= nil
if reactionsToCheck[rReaction] and namesToCheck[rName] then
rIsCritter = true
end
--The 3 lines above can be written as 1 line as well:
--rIsCritter = (reactionsToCheck[rReaction] and namesToCheck[rName]) or false
UNIT_FRAMES:SetFrameHiddenForReason(retOver, "disabled", rIsCritter)
ZO_UnitFrames_UpdateWindow(retOver, true)
end
function HideCritterHealthbar.Initialize()
EVENT_MANAGER:RegisterForEvent(myAddonName, EVENT_RETICLE_TARGET_CHANGED, HideCritterHealthbar.Main)
EVENT_MANAGER:UnregisterForEvent(myAddonName, EVENT_ADD_ON_LOADED)
end
function HideCritterHealthbar.OnAddOnLoaded(event, addonName)
if addonName == myAddonName then
EVENT_MANAGER:UnregisterForEvent(myAddonName, EVENT_ADD_ON_LOADED)
HideCritterHealthbar.Initialize()
end
end
EVENT_MANAGER:RegisterForEvent(myAddonName, EVENT_ADD_ON_LOADED, HideCritterHealthbar.OnAddOnLoaded)