ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   AddOn Help/Support (https://www.esoui.com/forums/forumdisplay.php?f=164)
-   -   Need help with an addon writting (https://www.esoui.com/forums/showthread.php?t=10874)

Saint-Ange 03/14/24 08:51 AM

Need help with an addon writting
 
Hi, sorry I know everyone is very busy atm but I'm getting crazy over here. Yesterday I finished testing an addon and all was fine and published it: ToggleGroupFrame. Today I log in and catastrophe I got this error:
Code:

:1: function expected instead of nil
stack traceback:
:1: in function '(main chunk)'
        <Locals> keybind = "TOGGLE_GROUP_FRAME" </Locals>

and I'm unable to solve the problem. I'm a beginner, I try to follow guides, I've spent alone more time on this than I'd like to admit, my energy is depleted and my capacities aren't what they were. I need help to sort this out, especially now that I've clearly made the mistake to upload too early.

Here's the lua:
Code:

local addon = { name = "ToggleGroupFrame" }
local em = GetEventManager()
local groupFrameHidden = true
local showInCombat = true

ZO_CreateStringId("SI_BINDING_NAME_TOGGLE_GROUP_FRAME", "Show/Hide group frame")
ZO_CreateStringId("SI_BINDING_NAME_TOGGLE_GROUP_FRAME_IN_COMBAT", "Show/Hide in combat")

local function OnAddOnLoaded(event, addonName)
  if addonName ~= addon.name then return end
  Initialize()
end

function Initialize()
  ZO_UnitFramesGroups:SetHidden(true)

  local savedVariables = ZO_SavedVars:New("ToggleGroupFrameSavedVariables", 1, nil, {}, GetWorldName())

  SLASH_COMMANDS['/togglegroupframe'] = function()
      groupFrameHidden = not groupFrameHidden
      ZO_UnitFramesGroups:SetHidden(groupFrameHidden)
      savedVariables.groupFrameHidden = groupFrameHidden
  end
  SLASH_COMMANDS['/tgf'] = SLASH_COMMANDS['/togglegroupframe']
 
  SLASH_COMMANDS['/togglegroupframeincombat'] = function()
      showInCombat = not showInCombat
      savedVariables.showInCombat = showInCombat
      UpdateGroupFrameVisibility()
  end
  SLASH_COMMANDS['/tgfc'] = SLASH_COMMANDS['/togglegroupframeincombat']
  SLASH_COMMANDS['/tgfic'] = SLASH_COMMANDS['/togglegroupframeincombat']

  em:RegisterForEvent(addon.name, EVENT_PLAYER_COMBAT_STATE, OnCombatStateChanged)
  em:UnregisterForEvent(addon.name, EVENT_ADD_ON_LOADED)
end

function UpdateGroupFrameVisibility()
  if IsUnitInCombat("player") then
      if showInCombat then
        ZO_UnitFramesGroups:SetHidden(false)
      else
        ZO_UnitFramesGroups:SetHidden(true)
      end
  else
      ZO_UnitFramesGroups:SetHidden(groupFrameHidden)
  end
end

function OnCombatStateChanged(event, inCombat)
  if not groupFrameHidden then
      return
  end

  UpdateGroupFrameVisibility()
end

em:RegisterForEvent(addon.name, EVENT_ADD_ON_LOADED, OnAddOnLoaded)

and the xml just to be sure:
Code:

<Bindings>
  <Layer name="SI_KEYBINDINGS_LAYER_GENERAL">
    <Category name="ToggleGroupFrame">
      <Action name="TOGGLE_GROUP_FRAME">
        <Down>SLASH_COMMANDS["/togglegroupframe"]()</Down>
      </Action>
      <Action name="TOGGLE_GROUP_FRAME_IN_COMBAT">
        <Down>SLASH_COMMANDS["/togglegroupframeincombat"]()</Down>
      </Action>
    </Category>
  </Layer>
</Bindings>

Any help would be much much much appreciated.

Dolgubon 03/14/24 09:24 AM

First, you'll want to look at the error. What line does it say, and what code is on that line? That's always critical information for figuring out errors. Second, what does function expected instead of nil mean? Well, it means that on that line of code, you have functionName(), but functionName is actually nil. So make sure the function is actually declared.


Finally, you need to either make your functions local, or pop them in your addon table. They are currently global, so if anyone addon declares a global Initialize function (pretty likely tbh) it'll overwrite yours

Baertram 03/14/24 11:31 AM

Not sure why but if I dowload your currently uploaded addon file Windows Defender pops in and says your file is a virus.
Maybe a false positive but are you sure you had uploaded the actual addon and nothing else? :p


And yes, please, as Dolgubon already said:
Always put a local in front of your function names! Or if you define a table local addon, add the functions to that table

function addon.OnCombatStateChanged(param)
function addon.Initialize(param)
function addon.UpdateGroupFrameVisibility(param)


and call them the same addon.OnCombatStateChanged(...) or addon.Initialize, or addon.UpdateGroupFrameVisibility
-> Keep in mind that local functions and code cannot be accessed from XML files of your addon, so see below how to fix this.

Else you might overwrite other addons/ZOs lua code, or some other addon might do that at your addon.

Everything not explicitly defined local is global and must use a very unique name, which in your case could be
function ToggleGroupFrame_OnCombatStateChanged e.g. but actually that's not needed. Keep it local.
Or create 1 global table ToggleGroupFrame = {} and add all functions and variables to that, so you can call it from XML code.
Else it may overwrite, or get overwritten!

Saint-Ange 03/14/24 02:09 PM

Quote:

Originally Posted by Dolgubon (Post 49509)
First, you'll want to look at the error. What line does it say, and what code is on that line? That's always critical information for figuring out errors. Second, what does function expected instead of nil mean? Well, it means that on that line of code, you have functionName(), but functionName is actually nil. So make sure the function is actually declared.


Finally, you need to either make your functions local, or pop them in your addon table. They are currently global, so if anyone addon declares a global Initialize function (pretty likely tbh) it'll overwrite yours

That's exactly what happened, my addon overwrote an other one wich lost its saved variable, glad I had a save. Thank you very much :p

Saint-Ange 03/14/24 02:15 PM

Quote:

Originally Posted by Baertram (Post 49514)
Not sure why but if I dowload your currently uploaded addon file Windows Defender pops in and says your file is a virus.
Maybe a false positive but are you sure you had uploaded the actual addon and nothing else? :p


And yes, please, as Dolgubon already said:
Always put a local in front of your function names! Or if you define a table local addon, add the functions to that table

function addon.OnCombatStateChanged(param)
function addon.Initialize(param)
function addon.UpdateGroupFrameVisibility(param)


and call them the same addon.OnCombatStateChanged(...) or addon.Initialize, or addon.UpdateGroupFrameVisibility
-> Keep in mind that local functions and code cannot be accessed from XML files of your addon, so see below how to fix this.

Else you might overwrite other addons/ZOs lua code, or some other addon might do that at your addon.

Everything not explicitly defined local is global and must use a very unique name, which in your case could be
function ToggleGroupFrame_OnCombatStateChanged e.g. but actually that's not needed. Keep it local.
Or create 1 global table ToggleGroupFrame = {} and add all functions and variables to that, so you can call it from XML code.
Else it may overwrite, or get overwritten!

Ok, for the virus I recon it was a bit too much but it's good to live on the edge :p
Now, I've followed your indications and came up with this, it works though my saved variables .. aren't saved anymore so more work needed.

Code:

ToggleGroupFrame = {}

local addon = { name = "ToggleGroupFrame" }
local em = GetEventManager()
local groupFrameHidden = true
local showInCombat = true

ZO_CreateStringId("SI_BINDING_NAME_TOGGLE_GROUP_FRAME", "Show/Hide group frame")
ZO_CreateStringId("SI_BINDING_NAME_TOGGLE_GROUP_FRAME_IN_COMBAT", "Show/Hide in combat")

function addon.OnAddOnLoaded(event, addonName)
  if addonName ~= addon.name then return end
  addon.Initialize()
end

function addon.Initialize()
  ZO_UnitFramesGroups:SetHidden(true)

  local savedVariables = ZO_SavedVars:New("ToggleGroupFrameSavedVariables", 1, nil, {}, GetWorldName())

  SLASH_COMMANDS['/togglegroupframe'] = function()
      groupFrameHidden = not groupFrameHidden
      ZO_UnitFramesGroups:SetHidden(groupFrameHidden)
      savedVariables.groupFrameHidden = groupFrameHidden
  end
  SLASH_COMMANDS['/tgf'] = SLASH_COMMANDS['/togglegroupframe']
 
  SLASH_COMMANDS['/togglegroupframeincombat'] = function()
      showInCombat = not showInCombat
      savedVariables.showInCombat = showInCombat
      addon.UpdateGroupFrameVisibility()
  end
  SLASH_COMMANDS['/tgfc'] = SLASH_COMMANDS['/togglegroupframeincombat']
  SLASH_COMMANDS['/tgfic'] = SLASH_COMMANDS['/togglegroupframeincombat']

  em:RegisterForEvent(addon.name, EVENT_PLAYER_COMBAT_STATE, addon.OnCombatStateChanged)
  em:UnregisterForEvent(addon.name, EVENT_ADD_ON_LOADED)
end

function addon.UpdateGroupFrameVisibility()
  if IsUnitInCombat("player") then
      if showInCombat then
        ZO_UnitFramesGroups:SetHidden(false)
      else
        ZO_UnitFramesGroups:SetHidden(true)
      end
  else
      ZO_UnitFramesGroups:SetHidden(groupFrameHidden)
  end
end

function addon.OnCombatStateChanged(event, inCombat)
  if not groupFrameHidden then
      return
  end

  addon.UpdateGroupFrameVisibility()
end

em:RegisterForEvent(addon.name, EVENT_ADD_ON_LOADED, addon.OnAddOnLoaded)

Thank you very much lads! You know how it is when you .. just can't anymore. It's a lot to learn.


All times are GMT -6. The time now is 06:17 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2014 - 2022 MMOUI