WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   [Classic] GetNumFactions() not getting past index 1 (https://www.wowinterface.com/forums/showthread.php?t=57602)

myrroddin 10-14-19 09:09 PM

[Classic] GetNumFactions() not getting past index 1
 
I have a function that sets the watched faction by factionID, seeing how Blizzard's SetWatchedFactionIndex() only works from 1 to GetNumFactions() I had to create a function.

However, my code isn't advancing properly past index 1, "Alliance" in my testbed. Oddly, the test prints are getting the correct factionID and name. I am missing something, and can't spot it.

I don't think it matters that this code is for Classic, by all accounts it should work for Retail as well, except my comparison tables that return the factionID are based on Classic's UIMapIDs, which are not the same for both versions.

The first print's output is "Stormwind" because that is where my toon is, while the second's output is "1", which is not correct. Based on my low level and lack of world exploration, the index should be "5" for Stormwind.

Further testing from other print outputs does indicate that the factionID 1453 is correct, and matching for Stormwind.
Lua Code:
  1. -- Blizzard sets watched faction by index, not by factionID so create our own API
  2. function RepByZone:SetWatchedFactionByFactionID(id)
  3.     if type(id) == "table" then id = tonumber(id) end
  4.     if type(id) ~= "number" then return end
  5.  
  6.     self:OpenAllFactionHeaders()
  7.     for i = 1, GetNumFactions() do
  8.         local name, _, standingID, _, _, _, _, _, isHeader, _, _, isWatched, _, factionID = GetFactionInfoByID(id)
  9.         if id == factionID then
  10.             self:Print("DEBUG: SetWatchedFactionByFactionID name:", name)
  11.             self:Print("DEBUG: SetWatchedFactionByFactionID index:", i)
  12.             if not isWatched then
  13.                 SetWatchedFactionIndex(i)
  14.             end
  15.             self:CloseAllFactionHeaders()
  16.             return name, id
  17.         else
  18.             break
  19.         end
  20.     end
  21.     self:CloseAllFactionHeaders()
  22. end

myrroddin 10-14-19 09:16 PM

It occurs to me to post more code, so this is my entire opening and closing of faction headers, plus setting of the faction by factionID. If anyone wants to see all of the code, I'll be happy to post that too.
Lua Code:
  1. local repsCollapsed = {} -- Obey user's settings about headers opened or closed
  2. -- Open all faction headers
  3. function RepByZone:OpenAllFactionHeaders()
  4.     local i = 1
  5.     while i <= GetNumFactions() do
  6.         local name, _, _, _, _, _, _, _, isHeader, isCollapsed = GetFactionInfo(i)
  7.         if isHeader then
  8.             repsCollapsed[name] = isCollapsed
  9.             if name == FACTION_INACTIVE then
  10.                 if not isCollapsed then
  11.                     CollapseFactionHeader(i)
  12.                 end
  13.                 break
  14.             elseif isCollapsed then
  15.                 ExpandFactionHeader(i)
  16.             end
  17.         end
  18.         i = i + 1
  19.     end
  20. end
  21.  
  22. -- Close all faction headers
  23. function RepByZone:CloseAllFactionHeaders()
  24.     local i = 1
  25.     while i <= GetNumFactions() do
  26.         local name, _, _, _, _, _, _, _, isHeader, isCollapsed = GetFactionInfo(i)
  27.         if isHeader then
  28.             if isCollapsed and not repsCollapsed[name] then
  29.                 ExpandFactionHeader(i)
  30.             elseif repsCollapsed[name] and not isCollapsed then
  31.                 CollapseFactionHeader(i)
  32.             end
  33.         end
  34.         i = i + 1
  35.     end
  36.     wipe(repsCollapsed)
  37. end
  38.  
  39. function RepByZone:GetAllFactions()
  40.     -- Will not return factions the user has marked as inactive
  41.     self:OpenAllFactionHeaders()
  42.     local factionList = {}
  43.  
  44.     for i = 1, GetNumFactions() do
  45.         local name, _, _, _, _, _, _, _, isHeader, _, _, _, _, factionID = GetFactionInfo(i)
  46.         if not isHeader then
  47.             factionList[factionID] = name
  48.         end
  49.     end
  50.  
  51.     self:CloseAllFactionHeaders()
  52.     return factionList
  53. end
  54.  
  55. -- Blizzard sets watched faction by index, not by factionID so create our own API
  56. function RepByZone:SetWatchedFactionByFactionID(id)
  57.     if type(id) == "table" then id = tonumber(id) end
  58.     if type(id) ~= "number" then return end
  59.  
  60.     self:OpenAllFactionHeaders()
  61.     for i = 1, GetNumFactions() do
  62.         local name, _, standingID, _, _, _, _, _, isHeader, _, _, isWatched, _, factionID = GetFactionInfoByID(id)
  63.         if id == factionID then
  64.             self:Print("DEBUG: SetWatchedFactionByFactionID name:", name)
  65.             self:Print("DEBUG: SetWatchedFactionByFactionID index:", i)
  66.             if not isWatched then
  67.                 SetWatchedFactionIndex(i)
  68.             end
  69.             self:CloseAllFactionHeaders()
  70.             return name, id
  71.         else
  72.             break
  73.         end
  74.     end
  75.     self:CloseAllFactionHeaders()
  76. end
  77.  
  78. -- Player switched zones, set watched faction
  79. function RepByZone:SwitchedZones()
  80.     local UImapID = IsInInstance() and select(8, GetInstanceInfo()) or C_Map.GetBestMapForUnit("player")
  81.     local locationsAndFactions = IsInInstance() and self:InstanceAndFactionList() or self:ZoneAndFactionList()
  82.     -- local mapID = C_Map.GetMapInfo(UImapID).mapID
  83.     self:Print("DEBUG: Current UImapID is", UImapID)
  84.     -- self:Print("DEBUG: Current mapID is", mapID)
  85.     self:SetWatchedFactionByFactionID(db.defaultRepID)
  86.     for zoneID, factionID in pairs(locationsAndFactions) do
  87.         if zoneID == UImapID then
  88.             self:Print("DEBUG: zoneID and UImapID match")
  89.             self:SetWatchedFactionByFactionID(factionID)
  90.             break
  91.         end
  92.     end
  93. end

Vrul 10-14-19 09:47 PM

It seems like the line:
Code:

local name, _, standingID, _, _, _, _, _, isHeader, _, _, isWatched, _, factionID = GetFactionInfoByID(id)
should be:
Code:

local name, _, standingID, _, _, _, _, _, isHeader, _, _, isWatched, _, factionID = GetFactionInfo(i)
otherwise you are iterating from 1 to GetNumFactions() but checking the same id over and over which doesn't change in the loop so you could just do it once.

myrroddin 10-14-19 10:04 PM

Vrul, yes, that's probably a bug, though upon testing walking from Stormwind City to Elwynn Forest, the UIMapIDs sync, but the watched rep is now printing nothing. Hm, progress?
Lua Code:
  1. function RepByZone:SetWatchedFactionByFactionID(id)
  2.     if type(id) == "table" then id = tonumber(id) end
  3.     if type(id) ~= "number" then return end
  4.  
  5.     self:OpenAllFactionHeaders()
  6.     for i = 1, GetNumFactions() do
  7.         local name, _, standingID, _, _, _, _, _, isHeader, _, _, isWatched, _, factionID = GetFactionInfo(i)
  8.         if id == factionID then
  9.             self:Print("DEBUG: SetWatchedFactionByFactionID name:", name) --doesn't print now
  10.             self:Print("DEBUG: SetWatchedFactionByFactionID index:", i) -- doesn't print now
  11.             if not isWatched then
  12.                 SetWatchedFactionIndex(i)
  13.             end
  14.             self:CloseAllFactionHeaders()
  15.             return name, id
  16.         else
  17.             break
  18.         end
  19.     end
  20.     self:CloseAllFactionHeaders()
  21. end

Fizzlemizz 10-14-19 10:18 PM

Code:

if type(id) == "table" then id = tonumber(id) end
Doesn't that just result in id being nil?

myrroddin 10-14-19 10:28 PM

I'll comment it out for now. Eventually that line is for when I pass subzone strings via a table for those smaller areas that have a different associated faction than the main zone.

I thought that if the type wasn't a table, the line would do nothing. Maybe it does, so I'll test by commenting it out.

myrroddin 10-14-19 10:32 PM

Commenting it out still doesn't fix the issue. The lines
Code:

self:Print("DEBUG: SetWatchedFactionByFactionID name:", name)
self:Print("DEBUG: SetWatchedFactionByFactionID index:", i)

Are not printing anything in the function SetWatchedFactionByFactionID()
That means the code isn't even looping, right?

Vrul 10-14-19 10:36 PM

Quote:

Originally Posted by myrroddin (Post 334265)
The lines
Code:

self:Print("DEBUG: SetWatchedFactionByFactionID name:", name)
self:Print("DEBUG: SetWatchedFactionByFactionID index:", i)

Are not printing anything in the function SetWatchedFactionByFactionID()
That means the code isn't even looping, right?

No, that just means the condition "id == factionID" is not being met.

Vrul 10-14-19 10:40 PM

See what you get with:
lua Code:
  1. function RepByZone:SetWatchedFactionByFactionID(id)
  2.     if type(id) == "table" then id = tonumber(id) end
  3.     if type(id) ~= "number" then return end
  4.  
  5.     self:OpenAllFactionHeaders()
  6.     for i = 1, GetNumFactions() do
  7.         local name, _, standingID, _, _, _, _, _, isHeader, _, _, isWatched, _, factionID = GetFactionInfo(i)
  8.         self:Print("DEBUG: SetWatchedFactionByFactionID name:", name)
  9.         self:Print("DEBUG: SetWatchedFactionByFactionID index:", i)
  10.         if id == factionID then
  11.             if not isWatched then
  12.                 SetWatchedFactionIndex(i)
  13.             end
  14.             self:CloseAllFactionHeaders()
  15.             return name, id
  16.         end
  17.     end
  18.     self:CloseAllFactionHeaders()
  19. end

myrroddin 10-14-19 11:17 PM

Quote:

Originally Posted by Vrul (Post 334267)
See what you get with:< snip >

That seems to be working, woot! I've tested between Stormwind and Elywnn Forest, as per usual. When I get a chance I will go to another zone.

Taking the else break part was the fix, huh?

Urtgard 10-16-19 03:49 AM

break stops the loop.

You stop the loop if id ~= factionID but you want to stop it when you found the correct id.
Lua Code:
  1. if id == factionID then
  2.     --do stuff with id
  3.     break
  4. end

myrroddin 10-16-19 11:14 AM

Quote:

Originally Posted by Urtgard (Post 334282)
break stops the loop.

You stop the loop if id ~= factionID but you want to stop it when you found the correct id.
Lua Code:
  1. if id == factionID then
  2.     --do stuff with id
  3.     break
  4. end

D'oh, of course. Thanks, Urtgard. Now I only need to get the Curseforge Packer to stop screwing up my code, and then RepByZone will be useful. If this continues into the afternoon, I'll manually input all fields and upload a manual zip file.


All times are GMT -6. The time now is 08:12 AM.

vBulletin © 2020, Jelsoft Enterprises Ltd
© 2004 - 2019 MMOUI