So ive had my addon Skull Me out for a while and was looking for someone to give me some actually feedback other than "It works"...I really would like to see someone go into the source code and tell me if im doing something horribly wrong but anything helps.
Im also open to any suggestions as im running out of ideas of what to do with it. If anyone wants to help me set up localization with it you can talk to me about it as Im not sure how to start it.
You have two folders in the main AddOn folder: gamer1224-stable, which is empty, and libs, which contains a bunch of Ace3 libraries that you aren't even using in your AddOn.
You're also defining global functions such as SkullMe_OnUpdate(), which should be file-local unless there is a pressing need to have other AddOns use them. You are also throwing variables into the global namespace, such as SkullMe_InstanceOnly - once again, if you don't need other AddOns to use these, make them file-local.
The logic could also be tightened up a bit. For example, this:
function SkullMe_OnUpdate()
if (SkullMe_MarkingSet == 0) then
if (time()-SkullMe_TimeTarget+1 > SkullMe_ChangeTime) then
if UnitExists("target") then
if not(UnitIsFriend("target", "player")) then
if not(GetRaidTargetIndex("target") == nil) then
if (SkullMe_MarkingOrder(GetRaidTargetIndex("target"))>SkullMe_MarkingOrder(SkullMe_Marking)) then
SetRaidTarget("target", SkullMe_Marking)
SkullMe_MarkingSet = 1
end
else
SetRaidTarget("target", SkullMe_Marking)
SkullMe_MarkingSet = 1
end
end
end
end
end
end
contains about six levels of nesting, which makes it hard to follow, and could be condensed into this:
function SkullMe_OnUpdate()
if SkullMe_MarkingSet ~= 0 then
return
end
if (time() - SkullMe_TimeTarget + 1 > SkullMe_ChangeTime) then
if UnitExists("target") and not UnitIsFriend("target", "player") then
if not GetRaidTargetIndex("target") then
if (SkullMe_MarkingOrder(GetRaidTargetIndex("target")) > SkullMe_MarkingOrder(SkullMe_Marking)) then
SetRaidTarget("target", SkullMe_Marking)
SkullMe_MarkingSet = 1
end
else
SetRaidTarget("target", SkullMe_Marking)
SkullMe_MarkingSet = 1
end
end
end
end
The OnUpdate itself could be better-throttled, using the elapsed parameter.
Also, notice that I changed
if not(GetRaidTargetIndex("target") == nil) then
to
if not GetRaidTargetIndex("target") then
because they are roughly equivalent except that the latter version only performs one check: that the return value of GetRaidTargetIndex() is nil or false. The former performs two checks: That the return value is equal to nil, then that the section in parentheses (return value == nil) is not true.
Yeah until last night I was just working on a version that did the job, I decided to start cleaning up alot of it last night. Thanks for everything you said, and the gamer1224-stable folder did once have something in it, I didn't notice it was still there.
Thanks, Im not a pro at lua. Ill get to work on all this now.
I did some major code rewrites and I can't find the issue. It occurs when I change targets so I think the problem is either the way I defined the function or how I used it in the event block.
Heres the code.
SkullMe = CreateFrame("Frame","SkullMe")
SkullMe:Show()
--PerLoad Variables
SkullMe.MarkingSet=0 --Interal Description: Have we set a pending mark yet?
SkullMe.TimeTarget=0 --Internal time till we set mark.
SkullMe.InInstance=true --Internal for if we are in a instance
SkullMe.FPS = 0.5 --Move to options later
SkullMe.elapsed = 0 --Internal for OnUpdate
SkullMe.Icons = {
Skull = "Interface\\TARGETINGFRAME\\UI-RaidTargetingIcon_8.blp",
Cross = "Interface\\TARGETINGFRAME\\UI-RaidTargetingIcon_7.blp",
Square = "Interface\\TARGETINGFRAME\\UI-RaidTargetingIcon_6.blp",
Moon = "Interface\\TARGETINGFRAME\\UI-RaidTargetingIcon_5.blp",
Triangle = "Interface\\TARGETINGFRAME\\UI-RaidTargetingIcon_4.blp",
Diamond = "Interface\\TARGETINGFRAME\\UI-RAIDTARGETINGICON_3.BLP",
Circle = "Interface\\TARGETINGFRAME\\UI-RaidTargetingIcon_2.blp",
Star = "Interface\\TARGETINGFRAME\\UI-RaidTargetingIcon_1.blp"
}
function SkullMe:Startup()
DEFAULT_CHAT_FRAME:AddMessage("Skull Me Loaded")
SkullMe:RegisterEvent("PLAYER_TARGET_CHANGED")
SkullMe:RegisterEvent("ADDON_LOADED")
SkullMe:SetScript("OnEvent",SkullMe.OnEvent)
SkullMe:SetScript("OnUpdate",SkullMe.OnUpdate)
SkullMe:DBMTimer()
end
function SkullMe:OnUpdate(elap)
--Control FPS
SkullMe.elapsed = SkullMe.elapsed + elap
if SkullMe.elapsed < SkullMe.FPS then return end
SkullMe.elapsed = 0
--Should we mark?
if (SkullMe.MarkingSet == 0) then
if (time()-SkullMe.TimeTarget+1 > SkullMe.ChangeTime) then
if UnitExists("target") then
if not GetRaidTargetIndex("target") then
if (SkullMe:MarkingOrder(GetRaidTargetIndex("target"))>SkullMe:MarkingOrder(SkullMe.Marking)) then
SetRaidTarget("target", SkullMe.Marking)
SkullM.MarkingSet = 1
end
else
SetRaidTarget("target", SkullMe.Marking)
SkullMe.MarkingSet = 1
end
end
end
end
end
function SkullMe:OnEvent(event, ...)
--Set args to the global style, I like it even tho I probably shouldn't altho names shouldnt really matter
local arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 = ...
--Determine if we are in a raid
--TODO: Move to a zone change event for speed
local _,_Instance = IsInInstance()
if ((SkullMe.InstanceOnly == true) and (_Instance == "party" or _Instance == "raid")) then
SkullMe.InInstance=true
elseif (SkullMe.InstanceOnly == true) then
SkullMe.InInstance=false
else
SkullMe.InInstance=true
end
if (SkullMe.Enabled == true and SkullMe.InInstance == true) then
if (event == "PLAYER_TARGET_CHANGED") then
if UnitExists("target") and not UnitIsFriend("target", "player") then
if not GetRaidTargetIndex("target") then --Is it currently marked? Check kill order if it is marked
if (SkullMe:MarkingOrder(GetRaidTargetIndex("target"))>SkullMe:MarkingOrder(SkullMe.Marking)) then
SkullMe.MarkingSet = 0 --TODO:Update above code when those change to tables
else
SkullMe.MarkingSet = 0
SkullMe:DBMTimer(SkullMe_ChangeTime, "AutoMark", SkullMe.Icons[SkullMe:NumberToText(SkullMe.Marking)], true)
end
end
else
SkullMe.MarkingSet = 1
end
SkullMe.TimeTarget = time()
end
end
if (event == "ADDON_LOADED") then --Set Defaults and Slash Handler
if (SkullMe.DBMBar == nil) then --TODO: Only do this when SkullMe is loaded, If its even needed to be
SkullMe.SetDefaults() --TODO: a event. Try executing on startup function later
end
SLASH_SKULLME1 = "/"..SkullMe.Slash1;
SLASH_SKULLME2 = "/"..SkullMe.Slash2;
SlashCmdList["SKULLME"] = function(msg)
SkullMe:SlashCommandHandler(msg);
end
end
end
function SkullMe:DBMTimer(timer, id, icon, huge)
if not(DBT and timer) then
SkullMe.DBTId = DBT:New() return end
if SkullMe.DBMBar then SkullMe.DBTId:CreateBar(timer, id, icon, huge) end
end
function SkullMe:SetDefaults()
SkullMe.Slash1 = "sm";
SkullMe.Slash2 = "skullme";
SkullMe.InstanceOnly = false
SkullMe.RMarkAllowed = true
SkullMe.Enabled = true
SkullMe.Marking = 8
SkullMe.ChangeTime = 5
SkullMe.DBMBar=true
DEFAULT_CHAT_FRAME:AddMessage("If this is your first time running please type /sm or /skullme. This addon was made by Healingdoom of Nazgrel.")
end
function SkullMe:MarkingOrder(arg1)
if arg1 == 8 then return 1
elseif arg1 == 7 then return 2
elseif arg1 == 2 then return 3
elseif arg1 == 4 then return 4
elseif arg1 == 1 then return 5
elseif arg1 == 5 then return 6
elseif arg1 == 6 then return 7
elseif arg1 == 3 then return 8
end
end
function SkullMe:MarkingOrderReverse(arg1)
if arg1 == 1 then return 8
elseif arg1 == 2 then return 7
elseif arg1 == 3 then return 2
elseif arg1 == 4 then return 4
elseif arg1 == 5 then return 1
elseif arg1 == 6 then return 5
elseif arg1 == 7 then return 6
elseif arg1 == 8 then return 3
end
end
function SkullMe:NumberToText(arg1)
if arg1 == 1 then return "Star"
elseif arg1 == 2 then return "Circle"
elseif arg1 == 3 then return "Diamond"
elseif arg1 == 4 then return "Triangle"
elseif arg1 == 5 then return "Moon"
elseif arg1 == 6 then return "Square"
elseif arg1 == 7 then return "Cross"
elseif arg1 == 8 then return "Skull"
end
end
function SkullMe:SendAddonMessage( prefix, message, sendtype, target)
_,_Instance = IsInInstance()
if not(_Instance == "pvp") then
SendAddonMessage( prefix, message, sendtype, target)
end
end
function SkullMe:SlashCommandHandler(msg)
if (msg == "options") then
InterfaceOptionsFrame_OpenToCategory("SkullMe")
print("Opening options menu.")
return
end
if (msg == "changeallow") then
SkullMe.RMarkAllowed = true
return
end
if (msg == "changedontallow") then
SkullMe.RMarkAllowed = false
return
end
if (msg == "reset") then
SkullMe.SetDefaults()
return
end
if (msg == "enable") then
SkullMe.Enabled=true
SkullMe.InstanceOnly=false
SkullMe:SendAddonMessage( "SMENABLE", "On", "RAID");
return
end
if (msg == "enable instance") then
SkullMe.InstanceOnly=true
SkullMe:SendAddonMessage( "SMENABLE", "Instance Only", "RAID");
return
end
if (msg == "disable") then
SkullMe.Enabled=false
SkullMe.InstanceOnly=false
SkullMe:SendAddonMessage( "SMENABLE", "Off", "RAID");
return
end
local _identifier, _arg1, _arg2 = strsplit(" ",msg)
if (_identifier == "time") then
SkullMe.ChangeTime=tonumber(_arg1)
return
end
if (_identifier == "mark") then
if (_arg1 == nil) then
DEFAULT_CHAT_FRAME:AddMessage("Values go from 1-8. 1=Star. 2=Circle. 3=Diamond. 4=Triangle. 5=Moon. 6=Square. 7=Cross. 8=Skull.");
return
else
SkullMe.Marking = tonumber(_arg1)
SkullMe:SendAddonMessage( "SMMARKO", tonumber(_arg1), "RAID");
return
end
end
if (_identifier == "request") then
SkullMe:SendAddonMessage( "SMREQUEST", UnitName("player"), "RAID")
print("Requesting Raid Info")
return
end
if (_identifier == "sendmark") then
if (_arg1 == nil) then
print("This tells someone to use a mark. Use the function with /sm sendmark <markID> <player>. MarkID is the same as /sm mark.")
return
else
SkullMe:SendAddonMessage("SMSENDMARK", _arg1, "WHISPER", _arg2)
return
end
end
DEFAULT_CHAT_FRAME:AddMessage("The Current Functions Are /sm enable, /sm disable, /sm time <Time Value>, and /sm mark <Mark Value>.To get a list of mark values type /sm mark and time values go in seconds.")
end
SkullMe:Startup()
I'm intrigued. What does the addon do that say using a keybind doesn't do? As a tank, I can see some utility in this, but it does restrict me from switching targets without changing my mark.
(eg. on twins, if I switch to help dps the other shield then will my mark switch to that target?)
Well for some fights you may come across problems with some fights, thats why you can disable it. For other fights such as anub in ToC you could get use as a offtank. You can assign 1 tank to skull and the other to cross and forget all about it, dps will know were to go. Also If a dps uses it they can become the dps "leader" telling everyone what to dps without changing what they normally do. Its just ment to make things eaiser in situations. Great for add tanking and cordinating dps realtime
Im looking at ther error message and it looks like I defined the function correctly but its still reading nil?...Whats up with that
The SkullMe:MarkingOrder() function hasn't been created yet when your OnUpdate tries to use it.
that's what is seems like, but how is that possible?
aren't those functions parsed first before anything is called? the setup function is called after everything has been parsed, no? it's not like those functions are locals which, if i understand lua, would be an order issue.
the debug info also indicates that SkullMe.MarkingOrder is defined as a function (see the self table breakdown in the bug info).
it feels to me less like a bug with the logic and more of a bug with how it's interfacing with the wow client. since he's using SkullMe:MarkingOrder instead of self:MarkingOrder it's possible that there's a problem where SkullMe is being redefined by a duplicate process or something...?
it'd be interested to see if using "self" in place of the global SkullMe would change the issue... and certainly it would be an easy thing to move the definition of SkullMe:MarkingOrder to be before the functions that use it just to be sure.
I do not use XML, I find it messy and lua is dynamic. The only other file is a GUI file for the ace3 options menu.
local options = {
name = "SkullMe",
type = "group",
childGroups = "tab",
args = {
title = {
order = 10,
type = "description",
name = "SkullMe was designed for tanks or dps to automaticly mark mobs",
},
titledesc = {
order = 20,
type = "description",
name = "You can also option these options with /sm options",
},
defaults = {
order = 25,
type = "execute",
name = "Default Options",
desc = "Sets all options to the defaults.",
func = function()
SkullMe:SetDefaults() end,
},
request = {
order = 26,
type = "execute",
name = "Request Info",
desc = "Requests SkullMe data from the raid.",
func = function()
SkullMe:SendAddonMessage( "SMREQUEST", UnitName("player"), "RAID")
print("Requesting Raid Info") end,
},
coretab = {
order = 30,
name = "Core",
type = "group",
args = {
enable = {
order = 10,
name = "Enabled",
type = "select",
desc = "SkullMe is on when checked. If Instance Only is picked, it will only run while in a instance.",
values = {
[1] = "Enable",
[2] = "Instance Only",
[3] = "Disable",
},
get = function()
if (SkullMe.Enabled == true and SkullMe.InstanceOnly == true) then
return 2
end
if (SkullMe.Enabled == true and SkullMe.InstanceOnly == false) then
return 1
end
if (SkullMe.Enabled == false and SkullMe.InstanceOnly == false) then
return 3
end
end,
set = function(info, val)
if (val == 1) then
SkullMe.Enabled = true
SkullMe.InstanceOnly = false
SkullMe:SendAddonMessage( "SMENABLE", "On", "RAID")
end
if (val == 2) then
SkullMe.Enabled = true
SkullMe.InstanceOnly = true
SkullMe:SendAddonMessage( "SMENABLE", "Instance Only", "RAID")
end
if (val == 3) then
SkullMe.Enabled = false
SkullMe.InstanceOnly = false
SkullMe:SendAddonMessage( "SMENABLE", "Off", "RAID")
end
end,
},
timevalue = {
order = 30,
name = "Sensitivity",
type = "range",
desc = "Time in seconds till the target becomes marked, after changing marks",
min = 1,
max = 20,
step = 1,
get = function()
return SkullMe.ChangeTime end,
set = function(info, val)
SkullMe.ChangeTime = val end,
},
mark = {
order = 40,
name = "Mark",
desc = "The mark to automaticly mark with",
type = "select",
values = {
[8] = "Skull",
[7] = "Cross",
[6] = "Square",
[5] = "Moon",
[4] = "Triangle",
[3] = "Diamond",
[2] = "Circle",
[1] = "Star",
},
get = function()
return SkullMe.Marking end,
set = function(info, value)
SkullMe.Marking = value end,
},
dbmtimer = {
order = 50,
name = "Deadly Boss Mods Timer",
type = "toggle",
desc = "Shows time till change in target.",
get = function()
return SkullMe.DBMBar end,
set = function(info, value)
SkullMe.DBMBar = value end,
},
},
},
raidtab = {
order = 40,
name = "Raid",
type = "group",
args = {
raidchangemark = {
order = 10,
name = "Raid Mark Change",
type = "toggle",
desc = "Allows other raid members change your mark. Turn off if it is being abused.",
get = function()
return SkullMe.RMarkAllowed end,
set = function(info, value)
SkullMe.RMarkAllowed = value end,
},
},
},
advancedtab = {
order = 50,
name = "Advanced",
type = "group",
args = {
disclaimer = {
order = 10,
name = "WARNING: This section is for beta or advanced functions. Wrong inputs may result in unexpected results.",
type = "description",
},
cmdextra1 = {
order = 20,
name = "Extra Slash Handler",
desc = "This will change your slash command handlers to the desired handle. Usefull if another addon interfers, or if SkullMe interfers with another. Requires a reload of UI to take effect.",
type = "input",
get = function()
return SkullMe.Slash1 end,
set = function(info, value)
SkullMe.Slash1 = value end,
},
cmdextra2 = {
order = 20,
name = "Extra Slash Handler",
desc = "This will change your slash command handlers to the desired handle. Usefull if another addon interfers, or if SkullMe interfers with another. Requires a reload of UI to take effect.",
type = "input",
get = function()
return SkullMe.Slash2 end,
set = function(info, value)
SkullMe.Slash2 = value end,
},
},
},
},
}
local config = LibStub("AceConfig-3.0")
local dialog = LibStub("AceConfigDialog-3.0")
config:RegisterOptionsTable("SkullMe-Bliz", options)
dialog:AddToBlizOptions("SkullMe-Bliz", "SkullMe")
Also to things off, I can't even use the function as a /script. SkullMe as a frame can be accessed globally. I also tried to move it before the update is defined, didn't help. I also tried making self the first parameter and using "." instead of ":". I dont use self normally because im not quite sure how it acts, can I use it everywere other than function definitions and the creation of the frame?
Updates(BTW these are my time, EST)
9:02 - Tried moving SkullMe:MarkingOrder up to before OnEvent and OnUpdate.
9:06 - Changed SkullMe:MarkingOrder to a table that works the same way and it gave another error
Message: Interface\AddOns\Skull Me\Skull Me.lua:70: attempt to index field 'MarkingOrder' (a nil value)
Time: 11/29/09 09:09:52
Count: 1
Stack: [string "Interface\FrameXML\BasicControls.xml:<Scrip..."]:18: in function <[string "Interface\FrameXML\BasicControls.xml:<Scrip..."]:4>
(tail call): ?
(tail call): ?
[C]: ?
Interface\AddOns\Skull Me\Skull Me.lua:70: in function <Interface\AddOns\Skull Me\Skull Me.lua:53>
[C]: in function `CameraOrSelectOrMoveStop'
[string "CAMERAORSELECTORMOVE"]:4: in function <[string "CAMERAORSELECTORMOVE"]:1>
Locals: self = SkullMe {
0 = <userdata>
Startup = <function> defined @Interface\AddOns\Skull Me\Skull Me.lua:21
MarkingOrder = <table> {
}
elapsed = 0
MarkingSet = 0
DBMTimer = <function> defined @Interface\AddOns\Skull Me\Skull Me.lua:95
OnUpdate = <function> defined @Interface\AddOns\Skull Me\Skull Me.lua:30
NumberToText = <table> {
}
TimeTarget = 0
Icons = <table> {
}
OnEvent = <function> defined @Interface\AddOns\Skull Me\Skull Me.lua:53
InInstance = true
SetDefaults = <function> defined @Interface\AddOns\Skull Me\Skull Me.lua:101
MarkingOrderReverse = <table> {
}
DBTId = <table> {
}
SendAddonMessage = <function> defined @Interface\AddOns\Skull Me\Skull Me.lua:156
SlashCommandHandler = <function> defined @Interface\AddOns\Skull Me\Skull Me.lua:163
FPS = 0.5
}
event = "PLAYER_TARGET_CHANGED"
arg1 = nil
arg2 = nil
arg3 = nil
arg4 = nil
arg5 = nil
arg6 = nil
arg7 = nil
arg8 = nil
arg9 = nil
_ = nil
_Instance = "none"
(*temporary) = nil
(*temporary) = nil
(*temporary) = "target"
(*temporary) = nil
(*temporary) = nil
(*temporary) = nil
(*temporary) = nil
(*temporary) = nil
(*temporary) = "attempt to index field 'MarkingOrder' (a nil value)"
-9:19 Attempted to dump the value of the SkullMe.MarkingOrder (As table)
Dump: value=SkullMe.MarkingOrder
empty result
-9:24 Attempted to dump the value of SkullMe.MarkingOrder (As function)
Dump: value=SkullMe.MarkingOrder
empty result
-9:30 Tryed switching the references as a function to self, function is now being read
Okay I fixed it by switching to a self instead, but what is causing the problem?..WoWLua failing or what?
Also I noticed that this thread got merged with my other one, Ideally I dont want my announcement for my addon in Lua Code Discussion, If you want to unmerge the threads (They dont serve the same purpose really) or just move this one back to the other forum or something I would appreciate it greatly.
Thanks for suggesting I use self instead of SkullMe...Not sure why i didn't try that before I posted.
Okay I fixed it by switching to a self instead, but what is causing the problem?..WoWLua failing or what?
Also I noticed that this thread got merged with my other one, Ideally I dont want my announcement for my addon in Lua Code Discussion, If you want to unmerge the threads (They dont serve the same purpose really) or just move this one back to the other forum or something I would appreciate it greatly.
Thanks for suggesting I use self instead of SkullMe...Not sure why i didn't try that before I posted.
Probably WoWLua failing. Why are you testing your addon in that thing? I suspect WoWLua is making 2 separate tables for SkullMe, one for the frame, and one for the global.
You should always be testing your addon in the actual WoW environment. WoWLua can help in finding bugs, but it is not a substitute, and it itself has bugs.
Okay I fixed it by switching to a self instead, but what is causing the problem?..WoWLua failing or what?
you could debug things a bit by doing printing tostring(SkullMe) and tostring(self) right before the offending line and see if they're identical. it would appear they are not. then it's a question of figuring out why they're not.
the self reference makes sure to use the frame that called the OnUpdate function rather than the global SkullMe.
it seems like you've got another lua file somewhere that's redefining SkullMe. there's really no reason to have SkullMe be global (at least for now certainly) so try making it local and see if that re-aligns the two variables (self and SkullMe). if so, then it's clear something is changing SkullMe in another file.
I mean how do i seperate the code into 2 tables...1 for my frame and another for my options, but still able to use self to get options.
CreateFrame appears to clear the table its set to.. local SkullMe = CreateFrame(<options>) will clear the SkullMe table to a empty frame, and clear ALL my options thus setting defaults each load. SkullMe.Marking is a example option.
CreateFrame() returns a Lua table, and you are assigning the memory address of that table to SkullMe.
Whatever "SkullMe" was last pointing at is gone. If this was some other table object, it will get garbage collected if there is no other reference to it. A frame's table isn't any different from a standard Lua table yuo create with {}.
So does that mean I can create the frame once and saved var it with all the settings?
EDIT: I used a SkullMeG = SkullMeG or CreateFrame("Frame", "SkullMe") to get my desired results...Turns out since its just a table thats created you can save frames?...Wow thought it was more complex than that lol
Im also open to any suggestions as im running out of ideas of what to do with it. If anyone wants to help me set up localization with it you can talk to me about it as Im not sure how to start it.
Heres a link to it on curse http://wow.curse.com/downloads/wow-addons/details/skull-me.aspx
You're also defining global functions such as SkullMe_OnUpdate(), which should be file-local unless there is a pressing need to have other AddOns use them. You are also throwing variables into the global namespace, such as SkullMe_InstanceOnly - once again, if you don't need other AddOns to use these, make them file-local.
The logic could also be tightened up a bit. For example, this:
contains about six levels of nesting, which makes it hard to follow, and could be condensed into this:
The OnUpdate itself could be better-throttled, using the elapsed parameter.
Also, notice that I changed
to
because they are roughly equivalent except that the latter version only performs one check: that the return value of GetRaidTargetIndex() is nil or false. The former performs two checks: That the return value is equal to nil, then that the section in parentheses (return value == nil) is not true.
That's only what I saw from my brief look.
Thanks, Im not a pro at lua. Ill get to work on all this now.
Heres the code.
and heres the error
If someone could help I would be grateful, I have no idea what I did wrong and ive been hacking at it for about a hour now.
(eg. on twins, if I switch to help dps the other shield then will my mark switch to that target?)
Im looking at ther error message and it looks like I defined the function correctly but its still reading nil?...Whats up with that
that's what is seems like, but how is that possible?
aren't those functions parsed first before anything is called? the setup function is called after everything has been parsed, no? it's not like those functions are locals which, if i understand lua, would be an order issue.
the debug info also indicates that SkullMe.MarkingOrder is defined as a function (see the self table breakdown in the bug info).
it feels to me less like a bug with the logic and more of a bug with how it's interfacing with the wow client. since he's using SkullMe:MarkingOrder instead of self:MarkingOrder it's possible that there's a problem where SkullMe is being redefined by a duplicate process or something...?
it'd be interested to see if using "self" in place of the global SkullMe would change the issue... and certainly it would be an easy thing to move the definition of SkullMe:MarkingOrder to be before the functions that use it just to be sure.
Both will cause there to be 2 SkullMe frames, one is accessible by the global, the other not, and initializing the 2nd would point to the first.
Also to things off, I can't even use the function as a /script. SkullMe as a frame can be accessed globally. I also tried to move it before the update is defined, didn't help. I also tried making self the first parameter and using "." instead of ":". I dont use self normally because im not quite sure how it acts, can I use it everywere other than function definitions and the creation of the frame?
Updates(BTW these are my time, EST)
9:02 - Tried moving SkullMe:MarkingOrder up to before OnEvent and OnUpdate.
9:06 - Changed SkullMe:MarkingOrder to a table that works the same way and it gave another error
-9:19 Attempted to dump the value of the SkullMe.MarkingOrder (As table)
-9:24 Attempted to dump the value of SkullMe.MarkingOrder (As function)
-9:30 Tryed switching the references as a function to self, function is now being read
Also I noticed that this thread got merged with my other one, Ideally I dont want my announcement for my addon in Lua Code Discussion, If you want to unmerge the threads (They dont serve the same purpose really) or just move this one back to the other forum or something I would appreciate it greatly.
Thanks for suggesting I use self instead of SkullMe...Not sure why i didn't try that before I posted.
Probably WoWLua failing. Why are you testing your addon in that thing? I suspect WoWLua is making 2 separate tables for SkullMe, one for the frame, and one for the global.
You should always be testing your addon in the actual WoW environment. WoWLua can help in finding bugs, but it is not a substitute, and it itself has bugs.
Also read this for the usage of "self"
http://www.lua.org/pil/16.html
And I used self and it fixed my problems...
If i define "local skullme = {}" in SkullMe.lua can i access it in SkullMe GUI.lua?
you could debug things a bit by doing printing tostring(SkullMe) and tostring(self) right before the offending line and see if they're identical. it would appear they are not. then it's a question of figuring out why they're not.
the self reference makes sure to use the frame that called the OnUpdate function rather than the global SkullMe.
it seems like you've got another lua file somewhere that's redefining SkullMe. there's really no reason to have SkullMe be global (at least for now certainly) so try making it local and see if that re-aligns the two variables (self and SkullMe). if so, then it's clear something is changing SkullMe in another file.
For some reason I cant figure out a way around CreateFrame clearing a table and If someone has a solution, Ive been working at it for a while.
CreateFrame appears to clear the table its set to.. local SkullMe = CreateFrame(<options>) will clear the SkullMe table to a empty frame, and clear ALL my options thus setting defaults each load. SkullMe.Marking is a example option.
Whatever "SkullMe" was last pointing at is gone. If this was some other table object, it will get garbage collected if there is no other reference to it. A frame's table isn't any different from a standard Lua table yuo create with {}.
EDIT: I used a SkullMeG = SkullMeG or CreateFrame("Frame", "SkullMe") to get my desired results...Turns out since its just a table thats created you can save frames?...Wow thought it was more complex than that lol