Thread Tools Display Modes
08-01-24, 03:51 AM   #1
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 140
Timer Help

Hello everyone, here is the code.
Lua Code:
  1. -- Addon Initialization
  2. local addonName, addonTable = ...
  3.  
  4. -- Configuration
  5. addonTable.config = {
  6.     QUEST = true,  -- Enable quest tracking
  7.     LANGUAGE = "AUTO",  -- Default to AUTO
  8.     SHOW_CURRENCY = true,
  9.     ALARM_ENABLE = true,
  10.     WEEK_INTERVAL = 1,  -- Auto detect interval
  11.     OFFSET = 0,  -- Default offset
  12. }
  13.  
  14. addonTable.currencies = {
  15.     [0] = {
  16.         id = 3089,
  17.         name = "Residual Memories",
  18.     }
  19. }
  20.  
  21. -- Function to get the localized map names
  22. local function getLocalizedMapNames(language)
  23.     local map_id_list = { [0] = 70, [1] = 115, [2] = 32 }
  24.     local names = {}
  25.  
  26.     if language == "AUTO" then
  27.         for i, mapID in pairs(map_id_list) do
  28.             names[i] = C_Map.GetMapInfo(mapID).name
  29.         end
  30.     elseif language == "English" then
  31.         names = { [0] = "Dustwallow Marsh", [1] = "Dragonblight", [2] = "Searing Gorge" }
  32.     elseif language == "Korean" then
  33.         names = { [0] = "먼지진흙 습지대", [1] = "용의 안식처", [2] = "이글거리는 협곡" }
  34.     elseif language == "French" then
  35.         names = { [0] = "Marécage d'Âprefange", [1] = "Désolation des dragons", [2] = "Gorge des vents brûlants" }
  36.     elseif language == "German" then
  37.         names = { [0] = "Düstermarschen", [1] = "Drachenöde", [2] = "Sengende Schlucht" }
  38.     elseif language == "Spanish" then
  39.         names = { [0] = "Marjal Revolcafango", [1] = "Cementerio de dragones", [2] = "La Gargante de Fuego" }
  40.     elseif language == "Chinese" then
  41.         names = { [0] = "尘泥沼泽", [1] = "龙骨荒野", [2] = "灼热峡谷" }
  42.     else
  43.         names = { [0] = "Dustwallow Marsh", [1] = "Dragonblight", [2] = "Searing Gorge" }
  44.     end
  45.  
  46.     return names
  47. end
  48.  
  49. -- Function to get the next word in different languages
  50. local function getNextWord(language)
  51.     if language == "Korean" then return "다음"
  52.     elseif language == "German" then return "Nächste"
  53.     elseif language == "Spanish" then return "Siguiente"
  54.     elseif language == "Chinese" then return "下一张地图"
  55.     else return "Next" end
  56. end
  57.  
  58. -- Main Event Handler
  59. local function eventHandler(self, event, ...)
  60.     if event ~= "EVENT_TWW_RADIANT_ECHOES" and event ~= "STATUS" and event ~= "OPTIONS" then
  61.         return false
  62.     end
  63.  
  64.     local config = addonTable.config
  65.     local region_index = GetCurrentRegion()
  66.     local region_timers = { [1] = 1722281440, [2] = 1722472240, [3] = 1722290440, [4] = 1722488400, [5] = 1722488400 }
  67.     local region_start_timestamp = region_timers[region_index]
  68.     local region_start_delay = config.OFFSET
  69.     local language = config.LANGUAGE
  70.     local interval = (config.WEEK_INTERVAL == 2 and 5400) or (config.WEEK_INTERVAL == 3 and 3600) or (config.WEEK_INTERVAL == 4 and 1800) or 5400
  71.     local localizedMapNames = getLocalizedMapNames(language)
  72.     local wordNext = getNextWord(language)
  73.  
  74.     if region_start_timestamp then
  75.         local start_timestamp = GetServerTime() - region_start_timestamp + region_start_delay
  76.         local interval_delay_ingame = 0
  77.         interval = interval + interval_delay_ingame
  78.         local duration = 0
  79.         local next_event = interval - (start_timestamp % interval)
  80.         local spawning = (interval - next_event) < duration
  81.         local remaining = duration - (interval - next_event)
  82.         local offset = not spawning and interval or 0
  83.         local rotation_index = math.floor((start_timestamp + offset) / interval) % 3
  84.         local zone = localizedMapNames[rotation_index]
  85.         local questID = {82676, 82689, 78938}[rotation_index + 1]
  86.  
  87.         local state = {
  88.             changed = true,
  89.             show = true,
  90.             progressType = "timed",
  91.             autoHide = true,
  92.             duration = spawning and duration or interval - duration,
  93.             expirationTime = GetTime() + (spawning and remaining or next_event),
  94.             spawning = spawning,
  95.             name = wordNext .. ": " .. zone,
  96.             isQuestDone = C_QuestLog.IsQuestFlaggedCompleted(questID),
  97.             soundAlarm = config.ALARM_ENABLE
  98.         }
  99.  
  100.         -- Custom logic to handle the event
  101.         -- (You can replace this with your own event handling logic)
  102.         print(state.name, state.isQuestDone and "Quest Done" or "Quest Not Done")
  103.         if state.soundAlarm then
  104.             PlaySoundFile("Interface\\AddOns\\" .. addonName .. "\\sound\\alarm.mp3")
  105.         end
  106.     end
  107.  
  108.     return true
  109. end
  110.  
  111. -- Currency Display Event Handler
  112. local function currencyEventHandler(self, event, ...)
  113.     local config = addonTable.config
  114.     local IS_ENABLE = config.SHOW_CURRENCY
  115.     local residual_memories = addonTable.currencies[0]
  116.     local currency_info = C_CurrencyInfo.GetCurrencyInfo(residual_memories.id)
  117.    
  118.     if IS_ENABLE and currency_info and (currency_info.quantity >= 0) then
  119.         local state = {
  120.             changed = true,
  121.             show = true,
  122.             autoHide = false,
  123.             quantity = currency_info.quantity,
  124.             name = currency_info.name
  125.         }
  126.         -- Custom logic to handle the currency display update
  127.         -- (You can replace this with your own event handling logic)
  128.         print("Currency: " .. state.name .. ", Quantity: " .. state.quantity)
  129.         return true
  130.     else
  131.         local state = {
  132.             changed = true,
  133.             show = false,
  134.             autoHide = false,
  135.             quantity = currency_info and currency_info.quantity or 0,
  136.             name = currency_info and currency_info.name or residual_memories.name
  137.         }
  138.         -- Custom logic to handle the currency display update
  139.         -- (You can replace this with your own event handling logic)
  140.         print("Currency: " .. state.name .. ", Quantity: " .. state.quantity)
  141.         return false
  142.     end
  143. end
  144.  
  145. -- Initialize frame and register events
  146. local frame = CreateFrame("Frame")
  147. frame:RegisterEvent("EVENT_TWW_RADIANT_ECHOES")
  148. frame:RegisterEvent("STATUS")
  149. frame:RegisterEvent("OPTIONS")
  150. frame:SetScript("OnEvent", eventHandler)
  151.  
  152. -- Currency tracking frame
  153. local currencyFrame = CreateFrame("Frame")
  154. currencyFrame:RegisterEvent("CURRENCY_DISPLAY_UPDATE")
  155. currencyFrame:SetScript("OnEvent", currencyEventHandler)
  156.  
  157. -- Trigger initial event scan
  158. C_Timer.After(0, function() eventHandler(frame, "EVENT_TWW_RADIANT_ECHOES") end)


It should look something like the picture. Only with the addition of the event currency (id = 3089) and event tasks (questID = {82676, 82689, 78938}). But it always gives an error

Lua Code:
  1. 14x ZamestoTV_PrePathTimer/mmm.lua:1 ZamestoTV_PrePathTimer/mmm.lua:85: unexpected symbol near '['
I don't understand what's going on =(, thank you in advance for your answers.
  Reply With Quote
08-01-24, 03:57 AM   #2
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 140
Lua Code:
  1. -- Addon Initialization
  2. local addonName, addonTable = ...
  3.  
  4. -- Configuration
  5. addonTable.config = {
  6.     QUEST = true,  -- Enable quest tracking
  7.     LANGUAGE = "AUTO",  -- Default to AUTO
  8.     SHOW_CURRENCY = true,
  9.     ALARM_ENABLE = true,
  10.     WEEK_INTERVAL = 1,  -- Auto detect interval
  11.     OFFSET = 0,  -- Default offset
  12. }
  13.  
  14. addonTable.currencies = {
  15.     [0] = {
  16.         id = 3089,
  17.         name = "Residual Memories",
  18.     }
  19. }
  20.  
  21. -- Function to get the localized map names
  22. local function getLocalizedMapNames(language)
  23.     local map_id_list = { [0] = 70, [1] = 115, [2] = 32 }
  24.     local names = {}
  25.  
  26.     if language == "AUTO" then
  27.         for i, mapID in pairs(map_id_list) do
  28.             names[i] = C_Map.GetMapInfo(mapID).name
  29.         end
  30.     elseif language == "English" then
  31.         names = { [0] = "Dustwallow Marsh", [1] = "Dragonblight", [2] = "Searing Gorge" }
  32.     elseif language == "Korean" then
  33.         names = { [0] = "먼지진흙 습지대", [1] = "용의 안식처", [2] = "이글거리는 협곡" }
  34.     elseif language == "French" then
  35.         names = { [0] = "Marécage d'Âprefange", [1] = "Désolation des dragons", [2] = "Gorge des vents brûlants" }
  36.     elseif language == "German" then
  37.         names = { [0] = "Düstermarschen", [1] = "Drachenöde", [2] = "Sengende Schlucht" }
  38.     elseif language == "Spanish" then
  39.         names = { [0] = "Marjal Revolcafango", [1] = "Cementerio de dragones", [2] = "La Gargante de Fuego" }
  40.     elseif language == "Chinese" then
  41.         names = { [0] = "尘泥沼泽", [1] = "龙骨荒野", [2] = "灼热峡谷" }
  42.     else
  43.         names = { [0] = "Dustwallow Marsh", [1] = "Dragonblight", [2] = "Searing Gorge" }
  44.     end
  45.  
  46.     return names
  47. end
  48.  
  49. -- Function to get the next word in different languages
  50. local function getNextWord(language)
  51.     if language == "Korean" then return "다음"
  52.     elseif language == "German" then return "Nächste"
  53.     elseif language == "Spanish" then return "Siguiente"
  54.     elseif language == "Chinese" then return "下一张地图"
  55.     else return "Next" end
  56. end
  57.  
  58. -- Main Event Handler
  59. local function eventHandler(self, event, ...)
  60.     if event ~= "PLAYER_ENTERING_WORLD" and event ~= "ZONE_CHANGED_NEW_AREA" and event ~= "CURRENCY_DISPLAY_UPDATE" then
  61.         return false
  62.     end
  63.  
  64.     local config = addonTable.config
  65.     local region_index = GetCurrentRegion()
  66.     local region_timers = { [1] = 1722281440, [2] = 1722472240, [3] = 1722290440, [4] = 1722488400, [5] = 1722488400 }
  67.     local region_start_timestamp = region_timers[region_index]
  68.     local region_start_delay = config.OFFSET
  69.     local language = config.LANGUAGE
  70.     local interval = (config.WEEK_INTERVAL == 2 and 5400) or (config.WEEK_INTERVAL == 3 and 3600) or (config.WEEK_INTERVAL == 4 and 1800) or 5400
  71.     local localizedMapNames = getLocalizedMapNames(language)
  72.     local wordNext = getNextWord(language)
  73.  
  74.     if region_start_timestamp then
  75.         local start_timestamp = GetServerTime() - region_start_timestamp + region_start_delay
  76.         local interval_delay_ingame = 0
  77.         interval = interval + interval_delay_ingame
  78.         local duration = 0
  79.         local next_event = interval - (start_timestamp % interval)
  80.         local spawning = (interval - next_event) < duration
  81.         local remaining = duration - (interval - next_event)
  82.         local offset = not spawning and interval or 0
  83.         local rotation_index = math.floor((start_timestamp + offset) / interval) % 3
  84.         local zone = localizedMapNames[rotation_index]
  85.         local questID = ({82676, 82689, 78938})[rotation_index + 1]
  86.  
  87.         local state = {
  88.             changed = true,
  89.             show = true,
  90.             progressType = "timed",
  91.             autoHide = true,
  92.             duration = spawning and duration or interval - duration,
  93.             expirationTime = GetTime() + (spawning and remaining or next_event),
  94.             spawning = spawning,
  95.             name = wordNext .. ": " .. zone,
  96.             isQuestDone = C_QuestLog.IsQuestFlaggedCompleted(questID),
  97.             soundAlarm = config.ALARM_ENABLE
  98.         }
  99.  
  100.         -- Custom logic to handle the event
  101.         -- (You can replace this with your own event handling logic)
  102.         print(state.name, state.isQuestDone and "Quest Done" or "Quest Not Done")
  103.         if state.soundAlarm then
  104.             PlaySoundFile("Interface\\AddOns\\" .. addonName .. "\\sound\\alarm.mp3")
  105.         end
  106.     end
  107.  
  108.     return true
  109. end
  110.  
  111. -- Currency Display Event Handler
  112. local function currencyEventHandler(self, event, ...)
  113.     local config = addonTable.config
  114.     local IS_ENABLE = config.SHOW_CURRENCY
  115.     local residual_memories = addonTable.currencies[0]
  116.     local currency_info = C_CurrencyInfo.GetCurrencyInfo(residual_memories.id)
  117.    
  118.     if IS_ENABLE and currency_info and (currency_info.quantity >= 0) then
  119.         local state = {
  120.             changed = true,
  121.             show = true,
  122.             autoHide = false,
  123.             quantity = currency_info.quantity,
  124.             name = currency_info.name
  125.         }
  126.         -- Custom logic to handle the currency display update
  127.         -- (You can replace this with your own event handling logic)
  128.         print("Currency: " .. state.name .. ", Quantity: " .. state.quantity)
  129.         return true
  130.     else
  131.         local state = {
  132.             changed = true,
  133.             show = false,
  134.             autoHide = false,
  135.             quantity = currency_info and currency_info.quantity or 0,
  136.             name = currency_info and currency_info.name or residual_memories.name
  137.         }
  138.         -- Custom logic to handle the currency display update
  139.         -- (You can replace this with your own event handling logic)
  140.         print("Currency: " .. state.name .. ", Quantity: " .. state.quantity)
  141.         return false
  142.     end
  143. end
  144.  
  145. -- Initialize frame and register events
  146. local frame = CreateFrame("Frame")
  147. frame:RegisterEvent("PLAYER_ENTERING_WORLD")
  148. frame:RegisterEvent("ZONE_CHANGED_NEW_AREA")
  149. frame:SetScript("OnEvent", eventHandler)
  150.  
  151. -- Currency tracking frame
  152. local currencyFrame = CreateFrame("Frame")
  153. currencyFrame:RegisterEvent("CURRENCY_DISPLAY_UPDATE")
  154. currencyFrame:SetScript("OnEvent", currencyEventHandler)
  155.  
  156. -- Trigger initial event scan
  157. C_Timer.After(0, function() eventHandler(frame, "PLAYER_ENTERING_WORLD") end)

I managed to fix the errors, but the next question arose. How do I put all this in a frame? (currently it is printed in the chat when entering the game)
  Reply With Quote
08-01-24, 05:23 AM   #3
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 140
Lua Code:
  1. -- Addon Initialization
  2. local addonName, addonTable = ...
  3.  
  4. -- Configuration
  5. addonTable.config = {
  6.     QUEST = true,  -- Enable quest tracking
  7.     LANGUAGE = "AUTO",  -- Default to AUTO
  8.     SHOW_CURRENCY = true,
  9.     ALARM_ENABLE = true,
  10.     WEEK_INTERVAL = 1,  -- Auto detect interval
  11.     OFFSET = 0,  -- Default offset
  12. }
  13.  
  14. addonTable.currencies = {
  15.     [0] = {
  16.         id = 3089,
  17.         name = "Residual Memories",
  18.     }
  19. }
  20.  
  21. -- Function to get the localized map names
  22. local function getLocalizedMapNames(language)
  23.     local map_id_list = { [0] = 70, [1] = 115, [2] = 32 }
  24.     local names = {}
  25.  
  26.     if language == "AUTO" then
  27.         for i, mapID in pairs(map_id_list) do
  28.             names[i] = C_Map.GetMapInfo(mapID).name
  29.         end
  30.     elseif language == "English" then
  31.         names = { [0] = "Dustwallow Marsh", [1] = "Dragonblight", [2] = "Searing Gorge" }
  32.     elseif language == "Korean" then
  33.         names = { [0] = "먼지진흙 습지대", [1] = "용의 안식처", [2] = "이글거리는 협곡" }
  34.     elseif language == "French" then
  35.         names = { [0] = "Marécage d'Âprefange", [1] = "Désolation des dragons", [2] = "Gorge des vents brûlants" }
  36.     elseif language == "German" then
  37.         names = { [0] = "Düstermarschen", [1] = "Drachenöde", [2] = "Sengende Schlucht" }
  38.     elseif language == "Spanish" then
  39.         names = { [0] = "Marjal Revolcafango", [1] = "Cementerio de dragones", [2] = "La Gargante de Fuego" }
  40.     elseif language == "Chinese" then
  41.         names = { [0] = "尘泥沼泽", [1] = "龙骨荒野", [2] = "灼热峡谷" }
  42.     else
  43.         names = { [0] = "Dustwallow Marsh", [1] = "Dragonblight", [2] = "Searing Gorge" }
  44.     end
  45.  
  46.     return names
  47. end
  48.  
  49. -- Function to get the next word in different languages
  50. local function getNextWord(language)
  51.     if language == "Korean" then return "다음"
  52.     elseif language == "German" then return "Nächste"
  53.     elseif language == "Spanish" then return "Siguiente"
  54.     elseif language == "Chinese" then return "下一张地图"
  55.     else return "Next" end
  56. end
  57.  
  58. -- Function to create the display frame
  59. local function createDisplayFrame()
  60.     local frame = CreateFrame("Frame", "AddonDisplayFrame", UIParent, "BasicFrameTemplateWithInset")
  61.     frame:SetSize(300, 130)
  62.     frame:SetPoint("CENTER")
  63.     frame.title = frame:CreateFontString(nil, "OVERLAY")
  64.     frame.title:SetFontObject("GameFontHighlightLarge")
  65.     frame.title:SetPoint("CENTER", frame.TitleBg, "CENTER", 0, 0)
  66.     frame.title:SetText(addonName)
  67.  
  68.     frame.content = CreateFrame("Frame", nil, frame)
  69.     frame.content:SetSize(280, 160)
  70.     frame.content:SetPoint("TOP", frame, "TOP", 0, -40)
  71.  
  72.     frame.text = frame.content:CreateFontString(nil, "OVERLAY")
  73.     frame.text:SetFontObject("GameFontHighlight")
  74.     frame.text:SetPoint("TOPLEFT", frame.content, "TOPLEFT", 10, -10)
  75.     frame.text:SetWidth(260)
  76.     frame.text:SetJustifyH("LEFT")
  77.     frame.text:SetJustifyV("TOP")
  78.  
  79.     -- Add drag functionality
  80.     local isDragging = false
  81.     local dragStartX, dragStartY
  82.  
  83.     frame:SetMovable(true)
  84.     frame:EnableMouse(true)
  85.     frame:RegisterForDrag("LeftButton")
  86.     frame:SetScript("OnMouseDown", function(self, button)
  87.         if button == "LeftButton" then
  88.             isDragging = true
  89.             dragStartX, dragStartY = self:GetCenter()
  90.             self:StartMoving()
  91.         end
  92.     end)
  93.     frame:SetScript("OnMouseUp", function(self)
  94.         if isDragging then
  95.             isDragging = false
  96.             self:StopMovingOrSizing()
  97.         end
  98.     end)
  99.  
  100.     -- Initially hide the frame
  101.     frame:Hide()
  102.  
  103.     return frame
  104. end
  105.  
  106. local displayFrame = createDisplayFrame()
  107.  
  108. -- Function to update the display frame text
  109. local function updateDisplayFrame()
  110.     local config = addonTable.config
  111.     local region_index = GetCurrentRegion()
  112.     local region_timers = { [1] = 1722281440, [2] = 1722472240, [3] = 1722290440, [4] = 1722488400, [5] = 1722488400 }
  113.     local region_start_timestamp = region_timers[region_index]
  114.     local region_start_delay = config.OFFSET
  115.     local language = config.LANGUAGE
  116.     local interval = (config.WEEK_INTERVAL == 2 and 5400) or (config.WEEK_INTERVAL == 3 and 3600) or (config.WEEK_INTERVAL == 4 and 1800) or 5400
  117.     local localizedMapNames = getLocalizedMapNames(language)
  118.     local wordNext = getNextWord(language)
  119.  
  120.     local locationText = ""
  121.     local currencyText = ""
  122.  
  123.     if region_start_timestamp then
  124.         local start_timestamp = GetServerTime() - region_start_timestamp + region_start_delay
  125.         local interval_delay_ingame = 0
  126.         interval = interval + interval_delay_ingame
  127.         local duration = 0
  128.         local next_event = interval - (start_timestamp % interval)
  129.         local spawning = (interval - next_event) < duration
  130.         local remaining = duration - (interval - next_event)
  131.         local offset = not spawning and interval or 0
  132.         local rotation_index = math.floor((start_timestamp + offset) / interval) % 3
  133.         local zone = localizedMapNames[rotation_index]
  134.         local questID = ({82676, 82689, 78938})[rotation_index + 1]
  135.  
  136.         local state = {
  137.             changed = true,
  138.             show = true,
  139.             progressType = "timed",
  140.             autoHide = true,
  141.             duration = spawning and duration or interval - duration,
  142.             expirationTime = GetTime() + (spawning and remaining or next_event),
  143.             spawning = spawning,
  144.             name = wordNext .. ": " .. zone,
  145.             isQuestDone = C_QuestLog.IsQuestFlaggedCompleted(questID),
  146.             soundAlarm = config.ALARM_ENABLE
  147.         }
  148.  
  149.         locationText = state.name .. "\n" .. (state.isQuestDone and "Quest Done" or "Quest Not Done")
  150.     end
  151.  
  152.     -- Update currency information
  153.     local config = addonTable.config
  154.     local IS_ENABLE = config.SHOW_CURRENCY
  155.     local residual_memories = addonTable.currencies[0]
  156.     local currency_info = C_CurrencyInfo.GetCurrencyInfo(residual_memories.id)
  157.    
  158.     if IS_ENABLE and currency_info and (currency_info.quantity >= 0) then
  159.         currencyText = "Currency: " .. currency_info.name .. ", Quantity: " .. currency_info.quantity
  160.     else
  161.         currencyText = "Currency: " .. (currency_info and currency_info.name or residual_memories.name) .. ", Quantity: " .. (currency_info and currency_info.quantity or 0)
  162.     end
  163.  
  164.     -- Update the display frame with both location and currency information
  165.     displayFrame.text:SetText(locationText .. "\n" .. currencyText)
  166. end
  167.  
  168. -- Main Event Handler
  169. local function eventHandler(self, event, ...)
  170.     if event ~= "PLAYER_ENTERING_WORLD" and event ~= "ZONE_CHANGED_NEW_AREA" and event ~= "CURRENCY_DISPLAY_UPDATE" then
  171.         return false
  172.     end
  173.  
  174.     -- Update the display frame text
  175.     updateDisplayFrame()
  176.  
  177.     return true
  178. end
  179.  
  180. -- Currency Display Event Handler
  181. local function currencyEventHandler(self, event, ...)
  182.     -- Update the display frame text
  183.     updateDisplayFrame()
  184.     return true
  185. end
  186.  
  187. -- Slash Command Handler
  188. SLASH_ZD1 = "/zd"
  189. SlashCmdList["ZD"] = function(msg)
  190.     if displayFrame:IsShown() then
  191.         displayFrame:Hide()
  192.     else
  193.         displayFrame:Show()
  194.     end
  195. end
  196.  
  197. -- Initialize frame and register events
  198. local frame = CreateFrame("Frame")
  199. frame:RegisterEvent("PLAYER_ENTERING_WORLD")
  200. frame:RegisterEvent("ZONE_CHANGED_NEW_AREA")
  201. frame:SetScript("OnEvent", eventHandler)
  202.  
  203. -- Currency tracking frame
  204. local currencyFrame = CreateFrame("Frame")
  205. currencyFrame:RegisterEvent("CURRENCY_DISPLAY_UPDATE")
  206. currencyFrame:SetScript("OnEvent", currencyEventHandler)
  207.  
  208. -- Trigger initial event scan
  209. C_Timer.After(0, function() eventHandler(frame, "PLAYER_ENTERING_WORLD") end)

It seems to have worked
  Reply With Quote
08-01-24, 06:20 AM   #4
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 140
Lua Code:
  1. -- Addon Initialization
  2. local addonName, addonTable = ...
  3.  
  4. -- Configuration
  5. addonTable.config = {
  6.     QUEST = true,  -- Enable quest tracking
  7.     LANGUAGE = "AUTO",  -- Default to AUTO
  8.     SHOW_CURRENCY = true,
  9.     ALARM_ENABLE = true,
  10.     WEEK_INTERVAL = 1,  -- Auto detect interval
  11.     OFFSET = 0,  -- Default offset
  12. }
  13.  
  14. addonTable.currencies = {
  15.     [0] = {
  16.         id = 3089,
  17.         name = "Residual Memories",
  18.     }
  19. }
  20.  
  21. -- Function to get the localized map names
  22. local function getLocalizedMapNames(language)
  23.     local map_id_list = { [0] = 70, [1] = 115, [2] = 32 }
  24.     local names = {}
  25.  
  26.     if language == "AUTO" then
  27.         for i, mapID in pairs(map_id_list) do
  28.             names[i] = C_Map.GetMapInfo(mapID).name
  29.         end
  30.     elseif language == "English" then
  31.         names = { [0] = "Dustwallow Marsh", [1] = "Dragonblight", [2] = "Searing Gorge" }
  32.     elseif language == "Korean" then
  33.         names = { [0] = "먼지진흙 습지대", [1] = "용의 안식처", [2] = "이글거리는 협곡" }
  34.     elseif language == "French" then
  35.         names = { [0] = "Marécage d'Âprefange", [1] = "Désolation des dragons", [2] = "Gorge des vents brûlants" }
  36.     elseif language == "German" then
  37.         names = { [0] = "Düstermarschen", [1] = "Drachenöde", [2] = "Sengende Schlucht" }
  38.     elseif language == "Spanish" then
  39.         names = { [0] = "Marjal Revolcafango", [1] = "Cementerio de dragones", [2] = "La Gargante de Fuego" }
  40.     elseif language == "Chinese" then
  41.         names = { [0] = "尘泥沼泽", [1] = "龙骨荒野", [2] = "灼热峡谷" }
  42.     else
  43.         names = { [0] = "Dustwallow Marsh", [1] = "Dragonblight", [2] = "Searing Gorge" }
  44.     end
  45.  
  46.     return names
  47. end
  48.  
  49. -- Function to get the next word in different languages
  50. local function getNextWord(language)
  51.     if language == "Korean" then return "다음"
  52.     elseif language == "German" then return "Nächste"
  53.     elseif language == "Spanish" then return "Siguiente"
  54.     elseif language == "Chinese" then return "下一张地图"
  55.     else return "Next" end
  56. end
  57.  
  58. -- Function to create the display frame
  59. local function createDisplayFrame()
  60.     local frame = CreateFrame("Frame", "AddonDisplayFrame", UIParent, "BasicFrameTemplateWithInset")
  61.     frame:SetSize(300, 200)
  62.     frame:SetPoint("CENTER")
  63.     frame.title = frame:CreateFontString(nil, "OVERLAY")
  64.     frame.title:SetFontObject("GameFontHighlightLarge")
  65.     frame.title:SetPoint("CENTER", frame.TitleBg, "CENTER", 0, 0)
  66.     frame.title:SetText(addonName)
  67.  
  68.     frame.content = CreateFrame("Frame", nil, frame)
  69.     frame.content:SetSize(280, 160)
  70.     frame.content:SetPoint("TOP", frame, "TOP", 0, -40)
  71.  
  72.     frame.text = frame.content:CreateFontString(nil, "OVERLAY")
  73.     frame.text:SetFontObject("GameFontHighlight")
  74.     frame.text:SetPoint("TOPLEFT", frame.content, "TOPLEFT", 10, -10)
  75.     frame.text:SetWidth(260)
  76.     frame.text:SetJustifyH("LEFT")
  77.     frame.text:SetJustifyV("TOP")
  78.  
  79.     -- Add drag functionality
  80.     local isDragging = false
  81.     local dragStartX, dragStartY
  82.  
  83.     frame:SetMovable(true)
  84.     frame:EnableMouse(true)
  85.     frame:RegisterForDrag("LeftButton")
  86.     frame:SetScript("OnMouseDown", function(self, button)
  87.         if button == "LeftButton" then
  88.             isDragging = true
  89.             dragStartX, dragStartY = self:GetCenter()
  90.             self:StartMoving()
  91.         end
  92.     end)
  93.     frame:SetScript("OnMouseUp", function(self)
  94.         if isDragging then
  95.             isDragging = false
  96.             self:StopMovingOrSizing()
  97.         end
  98.     end)
  99.  
  100.     -- Initially hide the frame
  101.     frame:Hide()
  102.  
  103.     return frame
  104. end
  105.  
  106. local displayFrame = createDisplayFrame()
  107.  
  108. -- Function to update the display frame text
  109. local function updateDisplayFrame()
  110.     local config = addonTable.config
  111.     local region_index = GetCurrentRegion()
  112.     local region_timers = { [1] = 1722281440, [2] = 1722472240, [3] = 1722290440, [4] = 1722488400, [5] = 1722488400 }
  113.     local region_start_timestamp = region_timers[region_index]
  114.     local region_start_delay = config.OFFSET
  115.     local language = config.LANGUAGE
  116.     local interval = (config.WEEK_INTERVAL == 2 and 5400) or (config.WEEK_INTERVAL == 3 and 3600) or (config.WEEK_INTERVAL == 4 and 1800) or 5400
  117.     local localizedMapNames = getLocalizedMapNames(language)
  118.     local wordNext = getNextWord(language)
  119.  
  120.     local locationText = ""
  121.     local currencyText = ""
  122.  
  123.     if region_start_timestamp then
  124.         local start_timestamp = GetServerTime() - region_start_timestamp + region_start_delay
  125.         local interval_delay_ingame = 0
  126.         interval = interval + interval_delay_ingame
  127.         local duration = 0
  128.         local next_event = interval - (start_timestamp % interval)
  129.         local spawning = (interval - next_event) < duration
  130.         local remaining = duration - (interval - next_event)
  131.         local offset = not spawning and interval or 0
  132.         local rotation_index = math.floor((start_timestamp + offset) / interval) % 3
  133.         local zone = localizedMapNames[rotation_index]
  134.         local questID = ({82676, 82689, 78938})[rotation_index + 1]
  135.  
  136.         local state = {
  137.             changed = true,
  138.             show = true,
  139.             progressType = "timed",
  140.             autoHide = true,
  141.             duration = spawning and duration or interval - duration,
  142.             expirationTime = GetTime() + (spawning and remaining or next_event),
  143.             spawning = spawning,
  144.             name = wordNext .. ": " .. zone,
  145.             isQuestDone = C_QuestLog.IsQuestFlaggedCompleted(questID),
  146.             soundAlarm = config.ALARM_ENABLE
  147.         }
  148.  
  149.         locationText = state.name .. "\n" .. (state.isQuestDone and "Quest Done" or "Quest Not Done")
  150.     end
  151.  
  152.     -- Update currency information
  153.     local config = addonTable.config
  154.     local IS_ENABLE = config.SHOW_CURRENCY
  155.     local residual_memories = addonTable.currencies[0]
  156.     local currency_info = C_CurrencyInfo.GetCurrencyInfo(residual_memories.id)
  157.    
  158.     if IS_ENABLE and currency_info and (currency_info.quantity >= 0) then
  159.         currencyText = "Currency: " .. currency_info.name .. ", Quantity: " .. currency_info.quantity
  160.     else
  161.         currencyText = "Currency: " .. (currency_info and currency_info.name or residual_memories.name) .. ", Quantity: " .. (currency_info and currency_info.quantity or 0)
  162.     end
  163.  
  164.     -- Update the display frame with both location and currency information
  165.     displayFrame.text:SetText(locationText .. "\n" .. currencyText)
  166. end
  167.  
  168. -- Main Event Handler
  169. local function eventHandler(self, event, ...)
  170.     if event ~= "PLAYER_ENTERING_WORLD" and event ~= "ZONE_CHANGED_NEW_AREA" and event ~= "CURRENCY_DISPLAY_UPDATE" then
  171.         return false
  172.     end
  173.  
  174.     -- Update the display frame text
  175.     updateDisplayFrame()
  176.  
  177.     return true
  178. end
  179.  
  180. -- Currency Display Event Handler
  181. local function currencyEventHandler(self, event, ...)
  182.     -- Update the display frame text
  183.     updateDisplayFrame()
  184.     return true
  185. end
  186.  
  187. -- Slash Command Handler
  188. SLASH_ZD1 = "/zd"
  189. SlashCmdList["ZD"] = function(msg)
  190.     if displayFrame:IsShown() then
  191.         displayFrame:Hide()
  192.     else
  193.         displayFrame:Show()
  194.     end
  195. end
  196.  
  197. -- Initialize frame and register events
  198. local frame = CreateFrame("Frame")
  199. frame:RegisterEvent("PLAYER_ENTERING_WORLD")
  200. frame:RegisterEvent("ZONE_CHANGED_NEW_AREA")
  201. frame:SetScript("OnEvent", eventHandler)
  202.  
  203. -- Currency tracking frame
  204. local currencyFrame = CreateFrame("Frame")
  205. currencyFrame:RegisterEvent("CURRENCY_DISPLAY_UPDATE")
  206. currencyFrame:SetScript("OnEvent", currencyEventHandler)
  207.  
  208. -- Trigger initial event scan
  209. C_Timer.After(0, function() eventHandler(frame, "PLAYER_ENTERING_WORLD") end)

New problem, text "Next", "Quest Done", "Quest Not Done", "Currency: " and ", Quantity: " does not support other languages. Only English. What is the reason?
  Reply With Quote
08-01-24, 11:25 AM   #5
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,974
You created a function for localising map names getLocalizedMapNames, you need to do the same with other texts you want to localise. eg with "Quest Done" and "Quest not Done"
Lua Code:
  1. local questDone = "Quest Done" -- default to english
  2. local questNotDone = "Quest not Done" -- default to english
  3. -- etc.
  4. local function getLocalizedMapNames(language)
  5.     local map_id_list = { [0] = 70, [1] = 115, [2] = 32 }
  6.     local names = {}
  7.  
  8.     if language == "AUTO" then
  9.         for i, mapID in pairs(map_id_list) do
  10.             names[i] = C_Map.GetMapInfo(mapID).name
  11.         end
  12.     elseif language == "English" then
  13.         names = { [0] = "Dustwallow Marsh", [1] = "Dragonblight", [2] = "Searing Gorge" }
  14.     elseif language == "Korean" then
  15.         names = { [0] = "먼지진흙 습지대", [1] = "용의 안식처", [2] = "이글거리는 협곡" }
  16.         questDone = "Korean for Quest Done" -- use Korean
  17.         questNotDone = "Korean for Quest not Done" -- use Korean
  18.     elseif language == "French" then
  19.         names = { [0] = "Marécage d'Âprefange", [1] = "Désolation des dragons", [2] = "Gorge des vents brûlants" }
  20.         questDone = "French for Quest Done" -- use French
  21.         questNotDone = "French for Quest not Done" -- use French
  22.   -- etc.
  23. end

and use the localised text like:
Lua Code:
  1. locationText = state.name .. "\n" .. (state.isQuestDone and questDone or questNotDone)

Do the same with any other text you want to localise.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
08-01-24, 11:37 PM   #6
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 140
Hi, it didn't work, this text is still in English.
Lua Code:
  1. -- Addon Initialization
  2. local addonName, addonTable = ...
  3.  
  4. -- Configuration
  5. addonTable.config = {
  6.     QUEST = true,  -- Enable quest tracking
  7.     LANGUAGE = "AUTO",  -- Default to AUTO
  8.     SHOW_CURRENCY = true,
  9.     ALARM_ENABLE = true,
  10.     WEEK_INTERVAL = 1,  -- Auto detect interval
  11.     OFFSET = 0,  -- Default offset
  12. }
  13.  
  14. addonTable.currencies = {
  15.     [0] = {
  16.         id = 3089,
  17.         name = "Residual Memories",
  18.     }
  19. }
  20.  
  21. -- Localized strings for quest status
  22. local questDone = "Quest Done" -- default to English
  23. local questNotDone = "Quest Not Done" -- default to English
  24.  
  25. -- Function to get the localized map names and quest status messages
  26. local function getLocalizedMapNames(language)
  27.     local map_id_list = { [0] = 70, [1] = 115, [2] = 32 }
  28.     local names = {}
  29.  
  30.     if language == "AUTO" then
  31.         for i, mapID in pairs(map_id_list) do
  32.             names[i] = C_Map.GetMapInfo(mapID).name
  33.         end
  34.     elseif language == "English" then
  35.         names = { [0] = "Dustwallow Marsh", [1] = "Dragonblight", [2] = "Searing Gorge" }
  36.     elseif language == "Korean" then
  37.         names = { [0] = "먼지진흙 습지대", [1] = "용의 안식처", [2] = "이글거리는 협곡" }
  38.         questDone = "퀘스트 완료" -- Korean for Quest Done
  39.         questNotDone = "퀘스트 미완료" -- Korean for Quest Not Done
  40.     elseif language == "French" then
  41.         names = { [0] = "Marécage d'Âprefange", [1] = "Désolation des dragons", [2] = "Gorge des vents brûlants" }
  42.         questDone = "Quête Terminée" -- French for Quest Done
  43.         questNotDone = "Quête Non Terminée" -- French for Quest Not Done
  44.     elseif language == "German" then
  45.         names = { [0] = "Düstermarschen", [1] = "Drachenöde", [2] = "Sengende Schlucht" }
  46.         questDone = "Quest Abgeschlossen" -- German for Quest Done
  47.         questNotDone = "Quest Nicht Abgeschlossen" -- German for Quest Not Done
  48.     elseif language == "Spanish" then
  49.         names = { [0] = "Marjal Revolcafango", [1] = "Cementerio de dragones", [2] = "La Garganta de Fuego" }
  50.         questDone = "Misión Completa" -- Spanish for Quest Done
  51.         questNotDone = "Misión No Completa" -- Spanish for Quest Not Done
  52.     elseif language == "Chinese" then
  53.         names = { [0] = "尘泥沼泽", [1] = "龙骨荒野", [2] = "灼热峡谷" }
  54.         questDone = "任务完成" -- Chinese for Quest Done
  55.         questNotDone = "任务未完成" -- Chinese for Quest Not Done
  56.     else
  57.         names = { [0] = "Dustwallow Marsh", [1] = "Dragonblight", [2] = "Searing Gorge" }
  58.     end
  59.  
  60.     return names
  61. end
  62.  
  63. -- Function to get the next word in different languages
  64. local function getNextWord(language)
  65.     if language == "Korean" then return "다음"
  66.     elseif language == "German" then return "Nächste"
  67.     elseif language == "Spanish" then return "Siguiente"
  68.     elseif language == "Chinese" then return "下一张地图"
  69.     else return "Next" end
  70. end
  71.  
  72. -- Function to create the display frame
  73. local function createDisplayFrame()
  74.     local frame = CreateFrame("Frame", "AddonDisplayFrame", UIParent, "BasicFrameTemplateWithInset")
  75.     frame:SetSize(300, 130)
  76.     frame:SetPoint("CENTER")
  77.     frame.title = frame:CreateFontString(nil, "OVERLAY")
  78.     frame.title:SetFontObject("GameFontHighlightLarge")
  79.     frame.title:SetPoint("CENTER", frame.TitleBg, "CENTER", 0, 0)
  80.     frame.title:SetText(addonName)
  81.  
  82.     frame.content = CreateFrame("Frame", nil, frame)
  83.     frame.content:SetSize(280, 160)
  84.     frame.content:SetPoint("TOP", frame, "TOP", 0, -40)
  85.  
  86.     frame.text = frame.content:CreateFontString(nil, "OVERLAY")
  87.     frame.text:SetFontObject("GameFontHighlight")
  88.     frame.text:SetPoint("TOPLEFT", frame.content, "TOPLEFT", 10, -10)
  89.     frame.text:SetWidth(260)
  90.     frame.text:SetJustifyH("LEFT")
  91.     frame.text:SetJustifyV("TOP")
  92.  
  93.     -- Add drag functionality
  94.     local isDragging = false
  95.     local dragStartX, dragStartY
  96.  
  97.     frame:SetMovable(true)
  98.     frame:EnableMouse(true)
  99.     frame:RegisterForDrag("LeftButton")
  100.     frame:SetScript("OnMouseDown", function(self, button)
  101.         if button == "LeftButton" then
  102.             isDragging = true
  103.             dragStartX, dragStartY = self:GetCenter()
  104.             self:StartMoving()
  105.         end
  106.     end)
  107.     frame:SetScript("OnMouseUp", function(self)
  108.         if isDragging then
  109.             isDragging = false
  110.             self:StopMovingOrSizing()
  111.         end
  112.     end)
  113.  
  114.     -- Initially hide the frame
  115.     frame:Hide()
  116.  
  117.     return frame
  118. end
  119.  
  120. local displayFrame = createDisplayFrame()
  121.  
  122. -- Function to update the display frame text
  123. local function updateDisplayFrame()
  124.     local config = addonTable.config
  125.     local region_index = GetCurrentRegion()
  126.     local region_timers = { [1] = 1722281440, [2] = 1722472240, [3] = 1722574800, [4] = 1722488400, [5] = 1722488400 }
  127.     local region_start_timestamp = region_timers[region_index]
  128.     local region_start_delay = config.OFFSET
  129.     local language = config.LANGUAGE
  130.     local interval = (config.WEEK_INTERVAL == 2 and 3600) or (config.WEEK_INTERVAL == 3 and 3600) or (config.WEEK_INTERVAL == 4 and 1800) or 3600
  131.     local localizedMapNames = getLocalizedMapNames(language)
  132.     local wordNext = getNextWord(language)
  133.  
  134.     local locationText = ""
  135.     local currencyText = ""
  136.  
  137.     if region_start_timestamp then
  138.         local start_timestamp = GetServerTime() - region_start_timestamp + region_start_delay
  139.         local interval_delay_ingame = 0
  140.         interval = interval + interval_delay_ingame
  141.         local duration = 0
  142.         local next_event = interval - (start_timestamp % interval)
  143.         local spawning = (interval - next_event) < duration
  144.         local remaining = duration - (interval - next_event)
  145.         local offset = not spawning and interval or 0
  146.         local rotation_index = math.floor((start_timestamp + offset) / interval) % 3
  147.         local zone = localizedMapNames[rotation_index]
  148.         local questID = ({82676, 82689, 78938})[rotation_index + 1]
  149.  
  150.         local state = {
  151.             changed = true,
  152.             show = true,
  153.             progressType = "timed",
  154.             autoHide = true,
  155.             duration = spawning and duration or interval - duration,
  156.             expirationTime = GetTime() + (spawning and remaining or next_event),
  157.             spawning = spawning,
  158.             name = wordNext .. ": " .. zone,
  159.             isQuestDone = C_QuestLog.IsQuestFlaggedCompleted(questID),
  160.             soundAlarm = config.ALARM_ENABLE
  161.         }
  162.  
  163.         locationText = state.name .. "\n" .. (state.isQuestDone and questDone or questNotDone)
  164.     end
  165.  
  166.     -- Update currency information
  167.     local config = addonTable.config
  168.     local IS_ENABLE = config.SHOW_CURRENCY
  169.     local residual_memories = addonTable.currencies[0]
  170.     local currency_info = C_CurrencyInfo.GetCurrencyInfo(residual_memories.id)
  171.    
  172.     if IS_ENABLE and currency_info and (currency_info.quantity >= 0) then
  173.         currencyText = "Currency: " .. currency_info.name .. ", Quantity: " .. currency_info.quantity
  174.     else
  175.         currencyText = "Currency: " .. (currency_info and currency_info.name or residual_memories.name) .. ", Quantity: " .. (currency_info and currency_info.quantity or 0)
  176.     end
  177.  
  178.     -- Update the display frame with both location and currency information
  179.     displayFrame.text:SetText(locationText .. "\n" .. currencyText)
  180. end
  181.  
  182. -- Main Event Handler
  183. local function eventHandler(self, event, ...)
  184.     if event ~= "PLAYER_ENTERING_WORLD" and event ~= "ZONE_CHANGED_NEW_AREA" and event ~= "CURRENCY_DISPLAY_UPDATE" then
  185.         return false
  186.     end
  187.  
  188.     -- Update the display frame text
  189.     updateDisplayFrame()
  190.  
  191.     return true
  192. end
  193.  
  194. -- Currency Display Event Handler
  195. local function currencyEventHandler(self, event, ...)
  196.     -- Update the display frame text
  197.     updateDisplayFrame()
  198.     return true
  199. end
  200.  
  201. -- Slash Command Handler
  202. SLASH_ZD1 = "/zd"
  203. SlashCmdList["ZD"] = function(msg)
  204.     if displayFrame:IsShown() then
  205.         displayFrame:Hide()
  206.     else
  207.         displayFrame:Show()
  208.     end
  209. end
  210.  
  211. -- Initialize frame and register events
  212. local frame = CreateFrame("Frame")
  213. frame:RegisterEvent("PLAYER_ENTERING_WORLD")
  214. frame:RegisterEvent("ZONE_CHANGED_NEW_AREA")
  215. frame:SetScript("OnEvent", eventHandler)
  216.  
  217. -- Currency tracking frame
  218. local currencyFrame = CreateFrame("Frame")
  219. currencyFrame:RegisterEvent("CURRENCY_DISPLAY_UPDATE")
  220. currencyFrame:SetScript("OnEvent", currencyEventHandler)
  221.  
  222. -- Trigger initial event scan
  223. C_Timer.After(0, function() eventHandler(frame, "PLAYER_ENTERING_WORLD") end)
  Reply With Quote
08-02-24, 12:10 AM   #7
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,974
You default LANGUAGE to "AUTO" in addonTable.config

I presume that gets set to a localisation somewhere?

If the addonTable.config.LANGUAGE is not a localisation (or a different form of localisation to what you want) then you will have to create another for it.

Remove questDone and questNotDone entries from the getLocalizedMapNames function.

After:
Lua Code:
  1. -- Localized strings for quest status
  2. local questDone = "Quest Done" -- default to English
  3. local questNotDone = "Quest Not Done" -- default to English

Add:
Lua Code:
  1. local locale = GetLocale()
  2. -- locale = "frFR" -- uncomment and change the locale = text to test
  3. if locale == "frFR" then
  4.     questDone = "Quête Terminée" -- French for Quest Done
  5.     questNotDone = "Quête Non Terminée" -- French for Quest Not Done
  6. elseif locale == "koKR" then
  7.     questDone = "퀘스트 완료" -- Korean for Quest Done
  8.     questNotDone = "퀘스트 미완료" -- Korean for Quest Not Done
  9. elseif locale == "deDE" then
  10.         questDone = "Quest Abgeschlossen" -- German for Quest Done
  11.         questNotDone = "Quest Nicht Abgeschlossen" -- German for Quest Not Done
  12. elseif locale == "esES" or locale == "esMX" then
  13.         questDone = "Misión Completa" -- Spanish/Mexican (just a combo. example) for Quest Done
  14.         questNotDone = "Misión No Completa" -- Spanish for Quest Not Done
  15. elseif locale == "zhCN" then
  16.         questDone = "任务完成" -- Chinese for Quest Done
  17.         questNotDone = "任务未完成" -- Chinese for Quest Not Done
  18. end

See GetLocale in the wiki for all the localisations
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 08-02-24 at 12:13 AM.
  Reply With Quote
08-02-24, 04:09 AM   #8
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 140
It worked. You are the best. Thank you very much for your help.
  Reply With Quote

WoWInterface » AddOns, Compilations, Macros » AddOn Help/Support » Timer Help


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