Thread Tools Display Modes
02-09-10, 09:22 PM   #1
Sythalin
Curse staff
 
Sythalin's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 680
Grr, I hate it when I miss stuff...

Getting an error that I don't know how to resolve:

lua Code:
  1. -- SET CITIES --
  2. function MageTaxi:SetFaction()
  3.     if UnitFactionGroup("player") == "Alliance" then
  4.         cityList = {
  5.             [1] = "Stormwind",
  6.             [2] = "Ironforge",
  7.             [3] = "Darnassus",
  8.             [4] = "Exodar",
  9.             [5] = "Theramore",
  10.             [6] = "Shattrath",
  11.             [7] = "Dalaran",
  12.         }
  13.     else
  14.         cityList = {
  15.             [1] = "Undercity",
  16.             [2] = "Orgrimmar",
  17.             [3] = "Thunder Bluff",
  18.             [4] = "Silvermoon",
  19.             [5] = "Stonard",
  20.             [6] = "Shattrath",
  21.             [7] = "Dalaran"
  22.         }
  23.     end;
  24.         dest = cityList[1]
  25. end
  26.  
  27. -- SET DESTINATION --
  28. local function setLoc(i)
  29.     for num= 1,#cityList do
  30.         _G["MageTaxi_City".. num]:SetChecked(false)  -- line 91
  31.     end
  32.     dest = cityList[i]
  33.     _G["MageTaxi_City".. i]:SetChecked(true)
  34. end
  35.  
  36. function MageTaxi_createGUI()
  37.     -- other code
  38.     for i = 1,#cityList do
  39.         cb = CreateFrame("CHECKBUTTON", "MageTaxi_City"..i, f, "UIRadioButtonTemplate")
  40.             if i == 1 then
  41.                 cb:SetPoint("TOPLEFT", f, "TOPLEFT", 40, -45)
  42.             else
  43.                 cb:SetPoint("TOP", "MageTaxi_City".. (i-1), "BOTTOM", 0, -10)
  44.             end
  45.             cb:SetScript("OnClick", setLoc(i)) -- line 149
  46.         end
  47. end

Code:
Message: Interface\AddOns\MageTaxi\magetaxi.lua:91: attempt to index field '?' (a nil value)
Time: 02/09/10 21:08:49
Count: 1
Stack: Interface\AddOns\MageTaxi\magetaxi.lua:91: in function <Interface\AddOns\MageTaxi\magetaxi.lua:89>
Interface\AddOns\MageTaxi\magetaxi.lua:149: in function `MageTaxi_createGUI'
[string "MageTaxi_createGUI()"]:1: in main chunk
[C]: in function `RunScript'

Locals: i = 1
(for index) = 2
(for limit) = 7
(for step) = 1
num = 2
(*temporary) = nil
(*temporary) = nil
(*temporary) = "2"
(*temporary) = "attempt to index field '?' (a nil value)"
As far as the checkbuttons, it's only creating one and stopping (leading to the error, figured that part out). I'm looking for WHY it's not building all the buttons.

Last edited by Sythalin : 02-09-10 at 09:24 PM.
  Reply With Quote
02-09-10, 09:38 PM   #2
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,937
If you haven't already I would convert the _G["MageTaxi_City".. num] part out to a variable and see what that says each time and if the object of that name exists both there and in CreateGUI.

Apart from that I cannot initially see anything wrong there. Especially with the error reporting values between 1 and 7 with it being stuck at 2. So the question is to find out why MageTax_City2 isn't being created, or thinks it hasn't been created.

Ah, I think I know the problem, at least based on the code there. I had the same problem in my own code recently. When you call a function at creation time that is also used later on after all items are created the chances are it is trying to access something that doesn't exist yet.

Try changing the setloc function to something like this. This way if _G["MageTaxi_City2"] doesn't exist when working on _G["MageTaxi_City1"] it won't kick up a fuss. Of course this assumes you haven't pre-created the objects themselves. But then again #citylist is already of size 7 but does that mean _G["MageTaxi_City2"] exists or that there are blank entries in citylist ?

Code:
local function setLoc(i)
  for num= 1,#cityList do
    if _G["MageTaxi_City".. num] then _G["MageTaxi_City".. num]:SetChecked(false) end
  end
  dest = cityList[i]
  _G["MageTaxi_City".. i]:SetChecked(true)
end
__________________


Characters:
Gwynedda - 70 - Demon Warlock
Galaviel - 65 - Resto Druid
Gamaliel - 61 - Disc Priest
Gwynytha - 60 - Survival Hunter
Lienae - 60 - Resto Shaman
Plus several others below level 60

Info Panel IDs : http://www.wowinterface.com/forums/s...818#post136818
  Reply With Quote
02-09-10, 09:58 PM   #3
Akryn
A Firelord
AddOn Author - Click to view addons
Join Date: Mar 2008
Posts: 479
Edit: Oh I should've noticed that too,

Last edited by Akryn : 02-10-10 at 07:17 AM.
  Reply With Quote
02-10-10, 05:03 AM   #4
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Originally Posted by ChaosInc View Post
As far as the checkbuttons, it's only creating one and stopping (leading to the error, figured that part out). I'm looking for WHY it's not building all the buttons.
Code:
cb:SetScript("OnClick", setLoc(i))
Was that line meant to be:

Code:
cb:SetScript("OnClick", function() setLoc(i) end)
As it is now you are trying to set the "OnClick" script for each button to the return value of setLoc, but in calling setLoc you are attempting to reference frames that haven't been created yet.

Edit:

Instead of creating a separate function for each frame's "OnClick" handler why not just do:

Code:
local function setLoc(self)
	for i = 1, #cityList do
		_G["MageTaxi_City" .. i]:SetChecked(false)
	end
	dest = cityList[self.id]
	self:SetChecked(true)
end
 
function MageTaxi_createGUI()
	-- other code
	for i = 1, #cityList do
		cb = CreateFrame("CHECKBUTTON", "MageTaxi_City" .. i, f, "UIRadioButtonTemplate")
		if i == 1 then
			cb:SetPoint("TOPLEFT", f, "TOPLEFT", 40, -45)
		else
			cb:SetPoint("TOP", "MageTaxi_City" .. (i - 1), "BOTTOM", 0, -10)
		end
		cb.id = i
		cb:SetScript("OnClick", setLoc) -- line 149
	end
end

Last edited by Vrul : 02-10-10 at 05:13 AM.
  Reply With Quote
02-10-10, 05:46 AM   #5
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
The error is in the SetScript on line 149. SetScript accepts 2 parameters, the script and the function that should be called.

Code:
cb:SetScript("OnClick", setLoc(i))
This will generate an error This will happen if the onclick handler is called:

Code:
setLoc(i)(...)
Errors. This IS correct:

Code:
cb:SetScript("OnClick", function(i) setLoc(i) end)
Which will be called like this(function:2FJ39 is the link to the local function created by function(i) setLoc(i) end):

Code:
function:2FJ39(...)
And the most neat way is this:

Code:
cb:SetScript("OnClick", setLoc)
Which will get called like this:

Code:
setLoc(...)
Which is what we want.

Final thing, you are concatenating the i variable in your setLoc function, don't you mean this?

Code:
i = i:GetName()
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.

Last edited by nightcracker : 02-10-10 at 05:48 AM.
  Reply With Quote
02-10-10, 10:59 AM   #6
Sythalin
Curse staff
 
Sythalin's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 680
Originally Posted by Vrul View Post
[code]
Edit:

Instead of creating a separate function for each frame's "OnClick" handler why not just do:

Code:
local function setLoc(self)
	for i = 1, #cityList do
		_G["MageTaxi_City" .. i]:SetChecked(false)
	end
	dest = cityList[self.id]
	self:SetChecked(true)
end
 
function MageTaxi_createGUI()
	-- other code
	for i = 1, #cityList do
		cb = CreateFrame("CHECKBUTTON", "MageTaxi_City" .. i, f, "UIRadioButtonTemplate")
		if i == 1 then
			cb:SetPoint("TOPLEFT", f, "TOPLEFT", 40, -45)
		else
			cb:SetPoint("TOP", "MageTaxi_City" .. (i - 1), "BOTTOM", 0, -10)
		end
		cb.id = i
		cb:SetScript("OnClick", setLoc) -- line 149
	end
end
Isn't just passing i doing the same thing, or am I not following this logic correctly?

Final thing, you are concatenating the i variable in your setLoc function, don't you mean this?
Code:
i = i:GetName()
Why would I want the name of a number?

And the most neat way is this:

Code:
cb:SetScript("OnClick", setLoc)
Which will get called like this:

Code:
setLoc(...)
Which is what we want.
... is still somewhat confusing to me. I understand that it's all arguments that are passed, but cb:SetScript("OnClick", setLoc) isn't passing anything, so how would I get the i value?

Still learning as I go along.
  Reply With Quote
02-10-10, 11:36 AM   #7
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
Originally Posted by ChaosInc View Post
Isn't just passing i doing the same thing, or am I not following this logic correctly?


Why would I want the name of a number?



... is still somewhat confusing to me. I understand that it's all arguments that are passed, but cb:SetScript("OnClick", setLoc) isn't passing anything, so how would I get the i value?

Still learning as I go along.
NOW I see what you want to do.... Here it comes:

Code:
function MageTaxi:SetFaction()
    if UnitFactionGroup("player") == "Alliance" then
        cityList = {
            [1] = "Stormwind",
            [2] = "Ironforge",
            [3] = "Darnassus",
            [4] = "Exodar",
            [5] = "Theramore",
            [6] = "Shattrath",
            [7] = "Dalaran",
        }
    else
        cityList = {
            [1] = "Undercity",
            [2] = "Orgrimmar",
            [3] = "Thunder Bluff",
            [4] = "Silvermoon",
            [5] = "Stonard",
            [6] = "Shattrath",
            [7] = "Dalaran"
        }
    end;
        dest = cityList[1]
end

local function setLoc(i)
    for num= 1,#cityList do
        _G["MageTaxi_City".. num]:SetChecked(false)  -- line 91
    end
    dest = cityList[i]
    _G["MageTaxi_City".. i]:SetChecked(true)
end
 
function MageTaxi_createGUI()
    for i = 1,#cityList do
        cb = CreateFrame("CHECKBUTTON", "MageTaxi_City"..i, f, "UIRadioButtonTemplate")
		if i == 1 then
			cb:SetPoint("TOPLEFT", f, "TOPLEFT", 40, -45)
		else
			cb:SetPoint("TOP", "MageTaxi_City".. (i-1), "BOTTOM", 0, -10)
		end
		cb:SetScript("OnClick", function() setLoc(i) end) -- line 149
    end
end
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.
  Reply With Quote
02-10-10, 12:11 PM   #8
Sythalin
Curse staff
 
Sythalin's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2006
Posts: 680
Thanks, I realized the fix last night already, but good to see it verified (and it works btw).

One thing though that I've run into that maybe someone can help me with. I have ZERO understanding of string manipulation and it has me painted into a corner atm.

Code:
cityList = {
	[3] = "ThunderBluff",
}

b = CreateFrame("BUTTON", "MageTaxi_Port"..i, f, "SecureActionButtonTemplate")
	b:SetPoint("RIGHT", "MageTaxi_City"..i, "LEFT", 0, 0)
	b:SetHeight(18)
	b:SetWidth(18)
	b.texture = b:CreateTexture("MageTaxi_Spell"..i)
	b.texture:SetAllPoints(b)
	b.texture:SetTexture("Interface\\Icons\\Spell_Arcane_Portal".. cityList[i])
	b:SetAttribute("type", "spell")
	b:SetAttribute("spell", "Portal: ".. cityList[i])
fs = b:CreateFontString("MageTaxi_Text"..i)
	fs:SetFontObject("GameFontGreenSmall")
	fs:SetJustifyH("LEFT")
	s:SetText(cityList[i])
	fs:SetPoint("LEFT", "MageTaxi_City"..i, "RIGHT", 0,0)
Only things that really matter are the orange spots. The issue is with Thunder Bluff. The icon name puts it as "ThunderBluff" (no space), but I still want it to appear as "Thunder Bluff" in the font string. Is there a way to do this without having to assign a temp var for difference?
  Reply With Quote
02-10-10, 12:19 PM   #9
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
Originally Posted by ChaosInc View Post
Thanks, I realized the fix last night already, but good to see it verified (and it works btw).

One thing though that I've run into that maybe someone can help me with. I have ZERO understanding of string manipulation and it has me painted into a corner atm.

Code:
cityList = {
	[3] = "ThunderBluff",
}

b = CreateFrame("BUTTON", "MageTaxi_Port"..i, f, "SecureActionButtonTemplate")
	b:SetPoint("RIGHT", "MageTaxi_City"..i, "LEFT", 0, 0)
	b:SetHeight(18)
	b:SetWidth(18)
	b.texture = b:CreateTexture("MageTaxi_Spell"..i)
	b.texture:SetAllPoints(b)
	b.texture:SetTexture("Interface\\Icons\\Spell_Arcane_Portal".. cityList[i])
	b:SetAttribute("type", "spell")
	b:SetAttribute("spell", "Portal: ".. cityList[i])
fs = b:CreateFontString("MageTaxi_Text"..i)
	fs:SetFontObject("GameFontGreenSmall")
	fs:SetJustifyH("LEFT")
	s:SetText(cityList[i])
	fs:SetPoint("LEFT", "MageTaxi_City"..i, "RIGHT", 0,0)
Only things that really matter are the orange spots. The issue is with Thunder Bluff. The icon name puts it as "ThunderBluff" (no space), but I still want it to appear as "Thunder Bluff" in the font string. Is there a way to do this without having to assign a temp var for difference?
lua Code:
  1. s:SetText(gsub(cityList[i], "([a-z]+)([A-Z][a-z]+)", "%1 %2"))

I really like that I've done my regex homework so I can solve problems like this
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.

Last edited by nightcracker : 02-10-10 at 12:22 PM.
  Reply With Quote
02-10-10, 09:56 PM   #10
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Originally Posted by ChaosInc View Post
Isn't just passing i doing the same thing, or am I not following this logic correctly?
Passing i requires the function setLoc and an additional separate function for each city button. Saving i into the frame allows you to just have the one function shared by all the buttons. It is just an efficiency thing, why create 8 functions to accomplish the same thing you can do with just 1.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Grr, I hate it when I miss stuff...


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