Thread Tools Display Modes
09-08-23, 10:29 PM   #1
Nyyght
A Defias Bandit
 
Nyyght's Avatar
Join Date: Sep 2023
Posts: 3
Making a Handynotes plugin - Cannot get function to return a value in one part.

Hello! I recently started learning to script LUA, so please forgive me if this is a simple fix/newb question. I have been searching all over the internet for almost a week and I am finally ready to admit defeat and request help from people who actually know what they're doing. Thank you in advance for your time!

My issue is that I've made several functions that all return a value which work in my other functions and even the tooltip function of my script. However, when I try to pull any functions into the the custom iterator function it keeps returning nil. Everything I try to plug in returns nil--even though it displays everywhere else fine. I'm not sure where I'm going wrong.

Here is the function I am trying to call my icon from. It works as intended when I pull it into the tooltip function. The "task_id" section decides if the achievement or quest is completed and if it is it returns "skipme", if not, it returns the criteria id or quest id.

local get_the_best_icon = function(uiMapId, coord, task_id)
local point = points[uiMapId] and points[uiMapId][coord]
if point then
local relevant_icon = point["icon_type"]
local completed_icon = "complete.tga"
local folder_dir = "Interface/AddOns/HandyNotes_EfficientSee/Icons/"

if task_id == "skipme" then
local show_icon = folder_dir..completed_icon
return show_icon
else
local show_icon = folder_dir..relevant_icon
return show_icon
end
return show_icon
end
end


Here is the part I cannot, for the life of me, get to work. This is the custom iterator and I am trying to get it to pull the icon from the get_the_best_icon function (for completed or not) to be shown for each node. All my attempts show nil here, even when working in other functions within the script.
do
local function iter(t, prestate)

if not t then return nil end
local state, value = next(t, prestate)
while state do

if value then

local icon = get_the_best_icon(value[1])
Debug("iter step", state, icon, db.icon_scale, db.icon_alpha)
return state, nil, icon, db.icon_scale, db.icon_alpha

end
state, value = next(t, state) -- Get next data
end
return nil, nil, nil, nil
end

function HLHandler:GetNodes2(uiMapId, minimap)
return iter, points[uiMapId], nil
end
end

Again, thank you so much for your time!
  Reply With Quote
09-08-23, 11:39 PM   #2
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,879
In the iterator you:
Lua Code:
  1. local icon = get_the_best_icon(value[1])

In the get_the_best_icon function you
Lua Code:
  1. local point = points[uiMapId] and points[uiMapId][coord]

From this (unless there's something unknown not present in the code shown), it appears you're only ever passing the uiMapId arg to the function and never the coord (or task_id).

If you haven't installed them yet, I would recommend BugGrabber and Bugsack (they work together) to help with debugging.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 09-08-23 at 11:58 PM.
  Reply With Quote
09-09-23, 03:32 AM   #3
Nyyght
A Defias Bandit
 
Nyyght's Avatar
Join Date: Sep 2023
Posts: 3
Thank you for the assistance!

Originally Posted by Fizzlemizz View Post
In the iterator you:
Lua Code:
  1. local icon = get_the_best_icon(value[1])

In the get_the_best_icon function you
Lua Code:
  1. local point = points[uiMapId] and points[uiMapId][coord]

From this (unless there's something unknown not present in the code shown), it appears you're only ever passing the uiMapId arg to the function and never the coord (or task_id).

If you haven't installed them yet, I would recommend BugGrabber and Bugsack (they work together) to help with debugging.
Hello, thank you so much for taking the time to help me! I really appreciate it.

I've downloaded the two debuggers you recommended and they have caught a few errors that usually didn't show. Unfortunately, I am still facing issues getting my icon function to show inside that iter function. It's really strange because I'm able to call functions into other sections (like the tooltips). I've even called the icon into the tooltips.

The tooltips are only showing for uncompleted tasks (as intended) but the icons don't show unless I add a single static link/folder. Meaning the icons are all or nothing.

Sorry about my formatting the first time. This is my first post here. I'm including the rest of the LUA, minus the initializing code, with a few entries of the data to show how I've set things up. I know I'm doing something wrong, but it's driving me up a wall that things seem to work everywhere except the iter function--even if I try to call uiMapId, coord, and task_id with the t and prestate.

Lua Code:
  1. local next = next
  2. local GameTooltip = GameTooltip
  3. local HandyNotes = HandyNotes
  4. local GetAchievementInfo = GetAchievementInfo
  5. local GetAchievementCriteriaInfo = GetAchievementCriteriaInfo
  6. local GetAchievementCriteriaInfoByID = GetAchievementCriteriaInfoByID
  7.  
  8. local playerName = UnitName("player");
  9. local PlayerFaction, _ = UnitFactionGroup("player")
  10. local current_uiMapID = C_Map.GetBestMapForUnit("player")
  11.  
  12. ---------------------------------------------------------
  13. -- Constants
  14.  
  15.  
  16. local points = {
  17.     -- [mapfile] = { [coord] = { [achievement_id], [criteria_id], [icon_type], [point_type], [faction], [note] } }
  18.    
  19.     [23] = { -- Eastern Plaguelands
  20.         [27592144] = {achieve = 771, criteria = 1101, quest_id = 0, item_id = 0, icon_type = "explore.tga", point_type = "achievement", faction = "Neutral", note = "Explore Plaguewood"}, -- 21
  21.         -- Eastern Plaguelands Quests ( )
  22.         [15606640] = {achieve = 0, criteria = 0, quest_id = 27367, item_id = 0, icon_type = "explore.tga", point_type = "quest", faction = "Neutral", note = "Quest End - Gidwin Goldbraids [4.2, 36.0] \n Next in Chain: Just Encased"}, -- 1
  23.     },
  24.  
  25. }
  26.  
  27. -- Obtain the point type.
  28. local info_for_point_type = function(uiMapId, coord)
  29.     local point = points[uiMapId] and points[uiMapId][coord]
  30.     if point then
  31.         local point_type = point["point_type"] 
  32.         return point_type
  33.     end
  34. end
  35.  
  36. -- Obtain the faction.
  37. local info_for_faction = function(uiMapId, coord)
  38.     local point = points[uiMapId] and points[uiMapId][coord]
  39.     if point then
  40.         local faction = point["faction"]   
  41.         return faction
  42.     end
  43. end
  44.  
  45. -- Obtain the achievement IDnumber and whether the criteria is completed or not.
  46. local info_from_coord = function(uiMapId, coord)
  47.     local point = points[uiMapId] and points[uiMapId][coord]
  48.     local point_type = info_for_point_type(uiMapId, coord)
  49.     local faction = info_for_faction(uiMapId, coord)
  50.     if point then  
  51.        
  52.         if(PlayerFaction == faction or faction == "Neutral") then
  53.        
  54.             -- If ACHIEVEMENT then decide if completed or return ID.
  55.             if(point_type == "achievement") then
  56.                 -- Gather the achievement and criteria information.
  57.                 local _, _, get_criteria_completed, _, _, _, _, _, _, _, _ = GetAchievementCriteriaInfoByID(point["achieve"], point["criteria"])   
  58.                
  59.                     if(get_criteria_completed == false) then
  60.                         local task_id = GetAchievementInfo(point["achieve"])
  61.                         return task_id
  62.                     else
  63.                         local task_id = "skipme"
  64.                         return task_id 
  65.                     end
  66.                    
  67.             -- If QUEST then decide if completed or return ID.     
  68.             elseif(point_type == "quest") then
  69.                 local quest_completed = C_QuestLog.IsQuestFlaggedCompleted(point["quest_id"])
  70.                
  71.                 if(quest_completed == false) then
  72.                     local task_id = point["quest_id"]
  73.                     return task_id
  74.                 else
  75.                 -- quest is the wrong faction or compelted so do not show.
  76.                     local task_id = "skipme"
  77.                     return task_id
  78.                 end
  79.             end
  80.         return task_id
  81.     end
  82. end
  83.  
  84.  
  85. -- Obtain the achievement name.
  86. local info_for_achievement_name = function(uiMapId, coord)
  87.     local point = points[uiMapId] and points[uiMapId][coord]
  88.     local point_type = info_for_point_type(uiMapId, coord)
  89.     local task_id = info_from_coord(uiMapId, coord)
  90.     if point then
  91.         -- Get achievement name
  92.         if(point_type == "achievement" and task_id ~= "skipme") then
  93.             local _, achievement_name = GetAchievementInfo(point["achieve"])   
  94.             return achievement_name
  95.         -- Get quest name
  96.         elseif(point_type == "quest" and task_id ~= "skipme") then
  97.             local achievement_name, _, _, _ = C_QuestLog.GetTitleForQuestID(point["quest_id"])
  98.             return achievement_name
  99.         else
  100.             local achievement_name = "skipthis"
  101.             return achievement_name
  102.         end
  103.     return achievement_name
  104.     end
  105. end
  106.  
  107. -- Obtain the achievement criteria.
  108. local info_for_criteria = function(uiMapId, coord)
  109.     local point = points[uiMapId] and points[uiMapId][coord]
  110.     local achievement = point["achieve"]
  111.     local point_type = info_for_point_type(uiMapId, coord)
  112.     if point then
  113.         if(achievement ~= 0 ) then
  114.         local achievement_criteria = GetAchievementCriteriaInfoByID(point["achieve"], point["criteria"])   
  115.         return achievement_criteria
  116.     elseif(achievement == 0 and point_type == "quest") then
  117.         local achievement_criteria = "Quest"
  118.         return achievement_criteria
  119.     else
  120.         local achievement_criteria = "None"
  121.         return achievement_criteria
  122.     end
  123.     end
  124. end
  125.  
  126. -- Obtain the criteria ID.
  127. local info_for_criteria_id = function(uiMapId, coord)
  128.     local point = points[uiMapId] and points[uiMapId][coord]
  129.     if point then
  130.         local criteria_id = point["criteria"]  
  131.         return criteria_id
  132.     end
  133. end
  134.  
  135. -- Obtain the note.
  136. local info_for_note = function(uiMapId, coord)
  137.     local point = points[uiMapId] and points[uiMapId][coord]
  138.     if point then
  139.         local note = point["note"] 
  140.         return note
  141.     end
  142. end
  143.  
  144. -- Obtain the icon type.
  145. local info_for_icon_type = function(uiMapId, coord)
  146.     local point = points[uiMapId] and points[uiMapId][coord]
  147.     if point then
  148.         local icon_type = point["icon_type"]   
  149.         return icon_type
  150.     end
  151. end
  152.  
  153. local get_the_best_icon = function(uiMapId, coord, task_id)
  154. local point = points[uiMapId] and points[uiMapId][coord]
  155.     if point then
  156.     local relevant_icon = point["icon_type"]
  157.     local completed_icon = "complete.tga"
  158.     local folder_dir = "Interface/AddOns/HandyNotes_EfficientSee/Icons/"
  159.  
  160.         if task_id == "skipme" then
  161.             local show_icon = folder_dir..completed_icon
  162.             return show_icon
  163.         else
  164.             local show_icon = folder_dir..relevant_icon
  165.             return show_icon
  166.         end
  167.     return show_icon
  168.     end
  169. end
  170.  
  171. ---------------------------------------------------------
  172. -- Plugin Handlers to HandyNotes
  173. local HLHandler = {}
  174. local info = {}
  175.  
  176. function HLHandler:OnEnter(uiMapId, coord)
  177.     local tooltip = GameTooltip
  178.     if ( self:GetCenter() > UIParent:GetCenter() ) then -- compare X coordinate
  179.         tooltip:SetOwner(self, "ANCHOR_LEFT")
  180.     else
  181.         tooltip:SetOwner(self, "ANCHOR_RIGHT")
  182.     end
  183.    
  184.     local task_id = info_from_coord(uiMapId, coord)
  185.     local achievement_criteria = info_for_criteria(uiMapId, coord)
  186.     local note = info_for_note(uiMapId, coord)
  187.     local icon_type = info_for_icon_type(uiMapId, coord)
  188.     local faction = info_for_faction(uiMapId, coord)
  189.     local point_type = info_for_point_type(uiMapId, coord)
  190.     local achievement_name = info_for_achievement_name(uiMapId, coord)
  191.     local criteria_id = info_for_criteria_id(uiMapId, coord)
  192.     local show_icon = get_the_best_icon(uiMapId, coord, task_id)
  193.     -- show the achievement and criteria notes.
  194.     if task_id ~= "skipme" and achievement_name ~= "skipthis" then
  195.         tooltip:SetText(("%s"):format(achievement_name)) -- Achievement
  196.         tooltip:AddLine(("%s"):format(achievement_criteria)) -- Achievement Criteria
  197.         tooltip:AddLine(("AchievementID: " .. task_id .. " CriteriaID: " .. criteria_id)) -- Achievement Note
  198.         tooltip:AddLine(("Faction: " .. faction .. "Player Faction:" .. PlayerFaction)) -- Icon Type
  199.         tooltip:AddLine(("Note: " .. note)) -- Achievement Note
  200.         tooltip:AddLine(("Icon Type: " .. icon_type)) -- Icon Type
  201.         tooltip:AddLine(("Point Type: " .. point_type)) -- Icon Type
  202.         tooltip:AddLine(("Point Type: " .. show_icon)) -- Icon Type
  203.         tooltip:Show()
  204.     end
  205. end
  206.  
  207. local function createWaypoint(button, uiMapId, coord)
  208.     local x, y = HandyNotes:getXY(coord)
  209.     local task_id = info_from_coord(uiMapId, coord)
  210.     if TomTom then
  211.         local persistent, minimap, world
  212.         if temporary then
  213.             persistent = true
  214.             minimap = false
  215.             world = false
  216.         end
  217.         TomTom:AddWaypoint(uiMapId, x, y, {
  218.             title=achievement,
  219.             persistent=persistent,
  220.             minimap=minimap,
  221.             world=world
  222.         })
  223.     end
  224. end
  225.  
  226. do
  227.     local currentZone, currentCoord
  228.     local function generateMenu(button, level)
  229.         if (not level) then return end
  230.         for k in pairs(info) do info[k] = nil end
  231.         if (level == 1) then
  232.             -- Create the title of the menu
  233.             info.isTitle      = 1
  234.             info.text         = "HandyNotes - EfficientSee"
  235.             info.notCheckable = 1
  236.             UIDropDownMenu_AddButton(info, level)
  237.  
  238.             if TomTom then
  239.                 -- Waypoint menu item
  240.                 info.disabled     = nil
  241.                 info.isTitle      = nil
  242.                 info.notCheckable = nil
  243.                 info.text = "Create waypoint"
  244.                 info.icon = nil
  245.                 info.func = createWaypoint
  246.                 info.arg1 = currentZone
  247.                 info.arg2 = currentCoord
  248.                 UIDropDownMenu_AddButton(info, level);
  249.             end
  250.  
  251.             -- Close menu item
  252.             info.text         = "Close"
  253.             info.icon         = nil
  254.             info.func         = function() CloseDropDownMenus() end
  255.             info.arg1         = nil
  256.             info.notCheckable = 1
  257.             UIDropDownMenu_AddButton(info, level);
  258.         end
  259.     end
  260.     local HL_Dropdown = CreateFrame("Frame", "HandyNotes_EfficientSeeDropdownMenu")
  261.     HL_Dropdown.displayMode = "MENU"
  262.     HL_Dropdown.initialize = generateMenu
  263.  
  264.     function HLHandler:OnClick(button, down, uiMapId, coord)
  265.         if button == "RightButton" and not down then
  266.             currentZone = uiMapId
  267.             currentCoord = coord
  268.             ToggleDropDownMenu(1, nil, HL_Dropdown, self, 0, 0)
  269.         end
  270.     end
  271. end
  272.  
  273. function HLHandler:OnLeave(uiMapId, coord)
  274.     GameTooltip:Hide()
  275. end
  276.  
  277. -- This is a custom iterator we use to iterate over every node in a given zone
  278.  
  279. do
  280.  
  281. local function iter(t, prestate)
  282.    
  283.         if not t then return nil end
  284.         local state, value = next(t, prestate)
  285.             while state do
  286.                    
  287.                      if value then
  288.                                                
  289.                         local icon = get_the_best_icon(uiMapId, coord, task_id)
  290.                            
  291.                         Debug("iter step", state, icon, db.icon_scale, db.icon_alpha)
  292.                         return state, nil, icon, db.icon_scale, db.icon_alpha  
  293.                        
  294.                     end
  295.                     state, value = next(t, state) -- Get next data
  296.                 end
  297.             return nil, nil, nil, nil
  298.         end
  299.  
  300. function HLHandler:GetNodes2(uiMapId, minimap)
  301.     return iter, points[uiMapId], nil
  302. end
  303. end
  Reply With Quote
09-09-23, 12:22 PM   #4
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,879
I don't use HandyNotes so I don't know all the ins-n-outs.

The iterator is cycling through your points table for the current map id. (23 [EPL] in the table in your code).
for each successful
Code:
next(...)
state will be the coord id. (number eg. 27592144 or 15606640) and value will be the corresponding sub-table in points[uiMapId]

To work the function would look more like:

Lua Code:
  1. local get_the_best_icon = function(point) -- point is the coord sub-table
  2.     if not point then return end -- should never happen but...
  3.     local relevant_icon = point["icon_type"]
  4.     local completed_icon = "complete.tga"
  5.     local folder_dir = "Interface/AddOns/HandyNotes_EfficientSee/Icons/"
  6.     if task_id == "skipme" then -- task_id not really usable here as it stands so a re-think needed.
  7.             local show_icon = folder_dir..completed_icon
  8.             return show_icon
  9.     else
  10.             local show_icon = folder_dir..relevant_icon -- This will prolbably be the only icon returned
  11.             return show_icon
  12.     end
  13.     return show_icon -- will never get here because of the if/else nature of the stgatement above.
  14. end

If the function is being used elsewhere you would use something like
Lua Code:
  1. if points[whatevertheMapIdis] and points[whatevertheMapIdis][whatevertheCoordIdis] then
  2.     local icon = get_the_best_icon = get_the_best_icon(points[whatevertheMapIdis][whatevertheCoordIdis])
  3.     -- do whatever with the icon
  4. end
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 09-09-23 at 05:19 PM.
  Reply With Quote
09-09-23, 11:07 PM   #5
Nyyght
A Defias Bandit
 
Nyyght's Avatar
Join Date: Sep 2023
Posts: 3
Talking Thank you! It's finally working!

Originally Posted by Fizzlemizz View Post
I don't use HandyNotes so I don't know all the ins-n-outs.

The iterator is cycling through your points table for the current map id. (23 [EPL] in the table in your code).
for each successful
Code:
next(...)
state will be the coord id. (number eg. 27592144 or 15606640) and value will be the corresponding sub-table in points[uiMapId]

To work the function would look more like:

Lua Code:
  1. local get_the_best_icon = function(point) -- point is the coord sub-table
  2.     if not point then return end -- should never happen but...
  3.     local relevant_icon = point["icon_type"]
  4.     local completed_icon = "complete.tga"
  5.     local folder_dir = "Interface/AddOns/HandyNotes_EfficientSee/Icons/"
  6.     if task_id == "skipme" then -- task_id not really usable here as it stands so a re-think needed.
  7.             local show_icon = folder_dir..completed_icon
  8.             return show_icon
  9.     else
  10.             local show_icon = folder_dir..relevant_icon -- This will prolbably be the only icon returned
  11.             return show_icon
  12.     end
  13.     return show_icon -- will never get here because of the if/else nature of the stgatement above.
  14. end

If the function is being used elsewhere you would use something like
Lua Code:
  1. if points[whatevertheMapIdis] and points[whatevertheMapIdis][whatevertheCoordIdis] then
  2.     local icon = get_the_best_icon = get_the_best_icon(points[whatevertheMapIdis][whatevertheCoordIdis])
  3.     -- do whatever with the icon
  4. end
BLESS YOU AND YOUR GIANT SMART BRAIN!

It took me a little more tinkering around, but I finally got it to work thanks to your direction! I am more grateful for you taking the time to help me than I can properly express! You deserve the MOST luck ever!
  Reply With Quote

WoWInterface » AddOns, Compilations, Macros » AddOn Help/Support » Making a Handynotes plugin - Cannot get function to return a value in one part.


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