Thread Tools Display Modes
06-02-24, 09:29 AM   #1
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 134
Timer problems

Hi all. Need help with code.

What is needed: During "local duration = 10" there should be an inscription "Time left: Expired" indicating the remaining time (in this example, 10 seconds). For example "Time left: Expired 10 seconds"

What now: During "local duration = 10" the message ""Time left: 10 seconds" appears.


Lua Code:
  1. local addonName, addonTable = ...
  2.  
  3. local function UpdateTimer()
  4.     if addonTable.timerEndTime then
  5.         local timeLeft = addonTable.timerEndTime - GetTime()
  6.         if timeLeft > 0 then
  7.             local minutesLeft = math.floor(timeLeft / 60)
  8.             local secondsLeft = math.floor(timeLeft % 60)
  9.             if not addonTable.timerFrame then
  10.                 addonTable.timerFrame = CreateFrame("Frame", addonName.."TimerFrame", UIParent, "DialogBoxFrame")
  11.                 addonTable.timerFrame:SetSize(300, 300) -- Adjusted size
  12.                 addonTable.timerFrame:SetPoint("CENTER")
  13.                 addonTable.timerFrame:SetMovable(true)
  14.                 addonTable.timerFrame:EnableMouse(true)
  15.                 addonTable.timerFrame:RegisterForDrag("LeftButton")
  16.                 addonTable.timerFrame:SetScript("OnDragStart", addonTable.timerFrame.StartMoving)
  17.                 addonTable.timerFrame:SetScript("OnDragStop", addonTable.timerFrame.StopMovingOrSizing)
  18.                 addonTable.timerFrame:SetBackdrop({
  19.                     bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
  20.                     edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
  21.                     edgeSize = 16,
  22.                     insets = { left = 8, right = 6, top = 8, bottom = 8 },
  23.                 })
  24.                 addonTable.timerFrame:SetBackdropBorderColor(1, 1, 1)
  25.                
  26.                 addonTable.timerFrame.textZone = addonTable.timerFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
  27.                 addonTable.timerFrame.textZone:SetPoint("TOP", addonTable.timerFrame, "TOP", 0, -20)
  28.                
  29.                 addonTable.timerFrame.textTimer = addonTable.timerFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
  30.                 addonTable.timerFrame.textTimer:SetPoint("CENTER", addonTable.timerFrame, "CENTER", 0, 0)
  31.             end
  32.            
  33.             addonTable.timerFrame.textZone:SetText(addonTable.currentZone)
  34.             addonTable.timerFrame.textTimer:SetText(string.format("Time left: %02d:%02d", minutesLeft, secondsLeft))
  35.             addonTable.timerFrame:Show()
  36.         else
  37.             if addonTable.timerFrame then
  38.                 addonTable.timerFrame.textTimer:SetText("Time left: Expired")
  39.                 addonTable.timerFrame:Show()
  40.             end
  41.         end
  42.     end
  43. end
  44.  
  45. local function UpdateLocation()
  46.     local zone_rotation = {
  47.         [0] = 84, -- Stormwind
  48.         [1] = 2023, -- Ohn'ahran Plains
  49.         [2] = 85, -- Orgrimmar
  50.         [3] = 2024, -- The Azure Span
  51.         [4] = 84, -- Stormwind
  52.         [5] = 2025, -- Thaldraszus
  53.         [6] = 85, -- Orgrimmar
  54.         [7] = 2112, -- Valdrakken
  55.         [8] = 84, -- Stormwind
  56.         [9] = 2022, -- The Waking Shores
  57.         [10] = 85, -- Orgrimmar
  58.         [11] = 2023, -- Ohn'ahran Plains
  59.         [12] = 84, -- Stormwind
  60.         [13] = 2024, -- The Azure Span
  61.         [14] = 85, -- Orgrimmar
  62.         [15] = 2025, -- Thaldraszus
  63.         [16] = 84, -- Stormwind
  64.         [17] = 2112, -- Valdrakken
  65.         [18] = 85, -- Orgrimmar
  66.         [19] = 2022, -- The Waking Shores
  67.     }
  68.    
  69.     local region_timers = {
  70.         NA = 1685041200, -- NA
  71.         KR = 1684962000, -- KR
  72.         EU = 1685001600, -- EU
  73.         TW = nil, -- TW (Add TW timestamp if available)
  74.     }
  75.    
  76.     local region_start_timestamp = region_timers[GetCVar("portal"):upper()]
  77.     if region_start_timestamp then
  78.         local duration = 10 -- Adjusted duration
  79.         local interval = 60 -- Adjusted interval
  80.         local start_timestamp = GetServerTime() - region_start_timestamp
  81.         local next_event = interval - start_timestamp % interval
  82.         local spawning = interval - next_event < duration
  83.         local remaining = duration - (interval - next_event)
  84.        
  85.         local offset = not spawning and interval or 0
  86.         local rotation_index = math.floor((start_timestamp + offset) / interval % 20)
  87.         local currentLocationID = zone_rotation[rotation_index]
  88.         addonTable.currentZone = C_Map.GetMapInfo(currentLocationID).name
  89.        
  90.         if spawning then
  91.             addonTable.timerEndTime = GetTime() + remaining
  92.         else
  93.             addonTable.timerEndTime = GetTime() + next_event
  94.         end
  95.     end
  96. end
  97.  
  98. local function InitializeAddon()
  99.     addonTable.states = {}
  100.     addonTable.currentZone = ""
  101.     addonTable.timerEndTime = nil
  102.    
  103.     local frame = CreateFrame("Frame")
  104.     frame:RegisterEvent("PLAYER_ENTERING_WORLD")
  105.     frame:SetScript("OnEvent", function(_, event, ...)
  106.         if event == "PLAYER_ENTERING_WORLD" then
  107.             UpdateLocation() -- Update location on entering world
  108.         end
  109.     end)
  110.    
  111.     frame:SetScript("OnUpdate", function()
  112.         UpdateTimer() -- Update timer continuously
  113.         UpdateLocation() -- Update location continuously
  114.     end)
  115. end
  116.  
  117. InitializeAddon()
  Reply With Quote
06-02-24, 11:50 AM   #2
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,921
In updateLocation you:

Lua Code:
  1. if spawning then
  2.     addonTable.timerEndTime = GetTime() + remaining -- is remaining > 0
  3. else
  4.     addonTable.timerEndTime = GetTime() + next_event -- is next_event > 0
  5. end
so presumably in either case, the addition of remaining or next_event to GetTime() in addonTable.timerEndTime will be greater than zero when you get to:

Lua Code:
  1. local timeLeft = addonTable.timerEndTime - GetTime()
  2. if timeLeft > 0 then
  3.    --...
  4. else -- remaining/next_event must be smaller than the OnUpdate elapsed time for timeLeft to be <= 0
  5.    --...
  6.    addonTable.timerFrame.textTimer:SetText("Time left: Expired")
  7. end
You need to re-think how you are determining expired.

If it's the same a "spawning" then add:
Lua Code:
  1. addonTable.spawning = spawning
  2. if spawning then
  3.   --...
to updateLocation.

Then instead of:
Lua Code:
  1. if timeLeft > 0 then

test for:
Lua Code:
  1. if not addonTable.spawning then
  2.     --...
  3. else
  4.     --...
  5.    addonTable.timerFrame.textTimer:SetText("Time left: Expired")
  6. end

If it's something else, you'll have to figure that out.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 06-02-24 at 04:28 PM.
  Reply With Quote
06-02-24, 12:07 PM   #3
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,921
As an aside, you don't need to re-create the two tables every OnUpdate. It's a waste of time and resources.

Instead move them outside (somewhere above) the function where they're used:
Lua Code:
  1. local zone_rotation = { -- here the tables are only created once when the file is loaded...
  2.     [0] = 84, -- Stormwind
  3.     [1] = 2023, -- Ohn'ahran Plains
  4.     [2] = 85, -- Orgrimmar
  5.     [3] = 2024, -- The Azure Span
  6.     [4] = 84, -- Stormwind
  7.     [5] = 2025, -- Thaldraszus
  8.     [6] = 85, -- Orgrimmar
  9.     [7] = 2112, -- Valdrakken
  10.     [8] = 84, -- Stormwind
  11.     [9] = 2022, -- The Waking Shores
  12.     [10] = 85, -- Orgrimmar
  13.     [11] = 2023, -- Ohn'ahran Plains
  14.     [12] = 84, -- Stormwind
  15.     [13] = 2024, -- The Azure Span
  16.     [14] = 85, -- Orgrimmar
  17.     [15] = 2025, -- Thaldraszus
  18.     [16] = 84, -- Stormwind
  19.     [17] = 2112, -- Valdrakken
  20.     [18] = 85, -- Orgrimmar
  21.     [19] = 2022, -- The Waking Shores
  22. }
  23.  
  24. local region_timers = {
  25.     NA = 1685041200, -- NA
  26.     KR = 1684962000, -- KR
  27.     EU = 1685001600, -- EU
  28.     TW = nil, -- TW (Add TW timestamp if available)
  29. }
  30.  
  31. local function UpdateLocation()
  32.      -- here a new table would be created each time the function is run
  33.     local region_start_timestamp = region_timers[GetCVar("portal"):upper()]
  34.     -- ...
  35. end
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 06-02-24 at 12:11 PM.
  Reply With Quote
06-02-24, 09:23 PM   #4
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 134
Hello, I managed to do this. Thank you very much for the tips. But a new problem has appeared. The "OK" button stopped working (previously, when it was pressed, the window with the timer disappeared).

How to make it work (or how to remove it) - either option will work for me.

Lua Code:
  1. local addonName, addonTable = ...
  2.  
  3. local function UpdateTimer()
  4.     if addonTable.timerEndTime then
  5.         local timeLeft = addonTable.timerEndTime - GetTime()
  6.         if timeLeft > 0 then
  7.             local minutesLeft = math.floor(timeLeft / 60)
  8.             local secondsLeft = math.floor(timeLeft % 60)
  9.             if not addonTable.timerFrame then
  10.                 addonTable.timerFrame = CreateFrame("Frame", addonName.."TimerFrame", UIParent, "DialogBoxFrame")
  11.                 addonTable.timerFrame:SetSize(300, 300) -- Adjusted size
  12.                 addonTable.timerFrame:SetPoint("CENTER")
  13.                 addonTable.timerFrame:SetMovable(true)
  14.                 addonTable.timerFrame:EnableMouse(true)
  15.                 addonTable.timerFrame:RegisterForDrag("LeftButton")
  16.                 addonTable.timerFrame:SetScript("OnDragStart", addonTable.timerFrame.StartMoving)
  17.                 addonTable.timerFrame:SetScript("OnDragStop", addonTable.timerFrame.StopMovingOrSizing)
  18.                 addonTable.timerFrame:SetBackdrop({
  19.                     bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
  20.                     edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
  21.                     edgeSize = 16,
  22.                     insets = { left = 8, right = 6, top = 8, bottom = 8 },
  23.                 })
  24.                 addonTable.timerFrame:SetBackdropBorderColor(1, 1, 1)
  25.                
  26.                 addonTable.timerFrame.textZone = addonTable.timerFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
  27.                 addonTable.timerFrame.textZone:SetPoint("TOP", addonTable.timerFrame, "TOP", 0, -20)
  28.                
  29.                 addonTable.timerFrame.textTimer = addonTable.timerFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
  30.                 addonTable.timerFrame.textTimer:SetPoint("CENTER", addonTable.timerFrame, "CENTER", 0, 0)
  31.                
  32.                 -- Create the delete button
  33.                 addonTable.timerFrame.deleteButton = CreateFrame("Button", nil, addonTable.timerFrame, "UIPanelCloseButton")
  34.                 addonTable.timerFrame.deleteButton:SetPoint("TOPRIGHT", addonTable.timerFrame, "TOPRIGHT")
  35.                 addonTable.timerFrame.deleteButton:SetScript("OnClick", function()
  36.                     addonTable.timerFrame:Hide()
  37.                 end)
  38.             end
  39.            
  40.             addonTable.timerFrame.textZone:SetText(addonTable.currentZone)
  41.             if addonTable.spawning then
  42.                 addonTable.timerFrame.textTimer:SetText(string.format("Time ruin: %02d:%02d", minutesLeft, secondsLeft))
  43.             else
  44.                 addonTable.timerFrame.textTimer:SetText(string.format("Time left: %02d:%02d", minutesLeft, secondsLeft))
  45.             end
  46.             addonTable.timerFrame:Show()
  47.         else
  48.             if addonTable.timerFrame then
  49.                 addonTable.timerFrame:Hide()
  50.             end
  51.         end
  52.     end
  53. end
  54.  
  55. local function UpdateLocation()
  56.     local zone_rotation = {
  57.         [0] = 84, -- Stormwind
  58.         [1] = 2023, -- Ohn'ahran Plains
  59.         [2] = 85, -- Orgrimmar
  60.         [3] = 2024, -- The Azure Span
  61.         [4] = 84, -- Stormwind
  62.         [5] = 2025, -- Thaldraszus
  63.         [6] = 85, -- Orgrimmar
  64.         [7] = 2112, -- Valdrakken
  65.         [8] = 84, -- Stormwind
  66.         [9] = 2022, -- The Waking Shores
  67.         [10] = 85, -- Orgrimmar
  68.         [11] = 2023, -- Ohn'ahran Plains
  69.         [12] = 84, -- Stormwind
  70.         [13] = 2024, -- The Azure Span
  71.         [14] = 85, -- Orgrimmar
  72.         [15] = 2025, -- Thaldraszus
  73.         [16] = 84, -- Stormwind
  74.         [17] = 2112, -- Valdrakken
  75.         [18] = 85, -- Orgrimmar
  76.         [19] = 2022, -- The Waking Shores
  77.     }
  78.  
  79.     local region_timers = {
  80.         NA = 1685041200, -- NA
  81.         KR = 1684962000, -- KR
  82.         EU = 1685001600, -- EU
  83.         TW = nil, -- TW (Add TW timestamp if available)
  84.     }
  85.  
  86.     local region_start_timestamp = region_timers[GetCVar("portal"):upper()]
  87.     if region_start_timestamp then
  88.         local duration = 10 -- Adjusted duration
  89.         local interval = 60 -- Adjusted interval
  90.         local start_timestamp = GetServerTime() - region_start_timestamp
  91.         local next_event = interval - start_timestamp % interval
  92.         local spawning = interval - next_event < duration
  93.         local remaining = duration - (interval - next_event)
  94.  
  95.         local offset = not spawning and interval or 0
  96.         local rotation_index = math.floor((start_timestamp + offset) / interval % 20)
  97.         local currentLocationID = zone_rotation[rotation_index]
  98.         addonTable.currentZone = C_Map.GetMapInfo(currentLocationID).name
  99.  
  100.         addonTable.spawning = spawning
  101.         if spawning then
  102.             addonTable.timerEndTime = GetTime() + remaining
  103.         else
  104.             addonTable.timerEndTime = GetTime() + next_event
  105.         end
  106.     end
  107. end
  108.  
  109. local function InitializeAddon()
  110.     addonTable.states = {}
  111.     addonTable.currentZone = ""
  112.     addonTable.timerEndTime = nil
  113.     addonTable.spawning = false
  114.  
  115.     local frame = CreateFrame("Frame")
  116.     frame:RegisterEvent("PLAYER_ENTERING_WORLD")
  117.     frame:SetScript("OnEvent", function(_, event, ...)
  118.         if event == "PLAYER_ENTERING_WORLD" then
  119.             UpdateLocation() -- Update location on entering world
  120.         end
  121.     end)
  122.  
  123.     frame:SetScript("OnUpdate", function()
  124.         UpdateTimer() -- Update timer continuously
  125.         UpdateLocation() -- Update location continuously
  126.     end)
  127. end
  128.  
  129. InitializeAddon()
  Reply With Quote
06-02-24, 09:27 PM   #5
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,921
I don't see an OK button in the code, only the addonTable.timerFrame.deleteButton which is a default close (red X) button

If that's the one you mean then you are running

Code:
addonTable.timerFrame:Show()
Continuously every OnUpdate where timeLeft > 0. You need some way of identifying the user closed the window until it's needed again (or the user opts to display it or...)
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 06-02-24 at 09:35 PM.
  Reply With Quote
06-02-24, 09:55 PM   #6
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 134
Originally Posted by Fizzlemizz View Post
I don't see an OK button in the code, only the addonTable.timerFrame.deleteButton which is a default close (red X) button

If that's the one you mean then you are running

Code:
addonTable.timerFrame:Show()
Continuously every OnUpdate where timeLeft > 0. You need some way of identifying the user closed the window until it's needed again (or the user opts to display it or...)
  Reply With Quote
06-02-24, 10:08 PM   #7
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,921
I missed it, it's part of the template.

The problem is exactly the same. The user presses the OK (or red X) and if there is still time left on the next OnUpdate (timeLeft > 0) then the addonTable.timerFrame:Show() will re-display the frame.

You want to use addonTable.timerFrame:Show() only once (like when the process changes from waiting to the next event actually starting). Then if you do that you may need a way for the user to manually show the frame if they want to (like a slash command etc.).

Whatever you do, you need to make sure the code doesn't re-display the frame until it's wanted/needed.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
06-02-24, 10:19 PM   #8
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 134
I want to show/hide a timer using a slash command. Therefore, I don't need the "OK" button.
  Reply With Quote
06-02-24, 11:22 PM   #9
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 134
I tried removing "addonTable.timerFrame:Show()" but in the end the timer started blinking when the location was changing.
  Reply With Quote
06-03-24, 12:01 AM   #10
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,921
It really depends on how you want it to work. It Maybe something as simple as this (once shown click OK or red X hides the frame until you type /zz):
See the --Added/--Moved comments

Lua Code:
  1. local addonName, addonTable = ...
  2.  
  3. local function UpdateTimer()
  4.     if addonTable.timerEndTime then
  5.         local timeLeft = addonTable.timerEndTime - GetTime()
  6.         if timeLeft > 0 then
  7.             local minutesLeft = math.floor(timeLeft / 60)
  8.             local secondsLeft = math.floor(timeLeft % 60)
  9.             if not addonTable.timerFrame then
  10.                 addonTable.timerFrame = CreateFrame("Frame", addonName.."TimerFrame", UIParent, "DialogBoxFrame")
  11.                 addonTable.timerFrame:SetSize(300, 300) -- Adjusted size
  12.                 addonTable.timerFrame:SetPoint("CENTER")
  13.                 addonTable.timerFrame:SetMovable(true)
  14.                 addonTable.timerFrame:EnableMouse(true)
  15.                 addonTable.timerFrame:RegisterForDrag("LeftButton")
  16.                 addonTable.timerFrame:SetScript("OnDragStart", addonTable.timerFrame.StartMoving)
  17.                 addonTable.timerFrame:SetScript("OnDragStop", addonTable.timerFrame.StopMovingOrSizing)
  18.                 addonTable.timerFrame:SetScript("OnHide", function(self) -- Added
  19.                     self.UserHidden = true -- Added
  20.                 end) -- Added
  21.                 addonTable.timerFrame:SetBackdrop({
  22.                     bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
  23.                     edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
  24.                     edgeSize = 16,
  25.                     insets = { left = 8, right = 6, top = 8, bottom = 8 },
  26.                 })
  27.                 addonTable.timerFrame:SetBackdropBorderColor(1, 1, 1)
  28.                
  29.                 addonTable.timerFrame.textZone = addonTable.timerFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
  30.                 addonTable.timerFrame.textZone:SetPoint("TOP", addonTable.timerFrame, "TOP", 0, -20)
  31.                
  32.                 addonTable.timerFrame.textTimer = addonTable.timerFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
  33.                 addonTable.timerFrame.textTimer:SetPoint("CENTER", addonTable.timerFrame, "CENTER", 0, 0)
  34.                
  35.                 -- Create the delete button
  36.                 addonTable.timerFrame.deleteButton = CreateFrame("Button", nil, addonTable.timerFrame, "UIPanelCloseButton")
  37.                 addonTable.timerFrame.deleteButton:SetPoint("TOPRIGHT", addonTable.timerFrame, "TOPRIGHT")
  38.                 addonTable.timerFrame.deleteButton:SetScript("OnClick", function()
  39.                     addonTable.timerFrame:Hide()
  40.                 end)
  41.             end
  42.            
  43.             addonTable.timerFrame.textZone:SetText(addonTable.currentZone)
  44.             if addonTable.spawning then
  45.                 addonTable.timerFrame.textTimer:SetText(string.format("Time ruin: %02d:%02d", minutesLeft, secondsLeft))
  46.             else
  47.                 addonTable.timerFrame.textTimer:SetText(string.format("Time left: %02d:%02d", minutesLeft, secondsLeft))
  48.             end
  49.         else
  50.             if addonTable.timerFrame then
  51.                 addonTable.timerFrame:Hide()
  52.             end
  53.         end
  54.     end
  55. end
  56.  
  57. local function UpdateLocation()
  58.     local zone_rotation = {
  59.         [0] = 84, -- Stormwind
  60.         [1] = 2023, -- Ohn'ahran Plains
  61.         [2] = 85, -- Orgrimmar
  62.         [3] = 2024, -- The Azure Span
  63.         [4] = 84, -- Stormwind
  64.         [5] = 2025, -- Thaldraszus
  65.         [6] = 85, -- Orgrimmar
  66.         [7] = 2112, -- Valdrakken
  67.         [8] = 84, -- Stormwind
  68.         [9] = 2022, -- The Waking Shores
  69.         [10] = 85, -- Orgrimmar
  70.         [11] = 2023, -- Ohn'ahran Plains
  71.         [12] = 84, -- Stormwind
  72.         [13] = 2024, -- The Azure Span
  73.         [14] = 85, -- Orgrimmar
  74.         [15] = 2025, -- Thaldraszus
  75.         [16] = 84, -- Stormwind
  76.         [17] = 2112, -- Valdrakken
  77.         [18] = 85, -- Orgrimmar
  78.         [19] = 2022, -- The Waking Shores
  79.     }
  80.  
  81.     local region_timers = {
  82.         NA = 1685041200, -- NA
  83.         US = 1685041200, -- NA
  84.         KR = 1684962000, -- KR
  85.         EU = 1685001600, -- EU
  86.         TW = nil, -- TW (Add TW timestamp if available)
  87.     }
  88.  
  89.     local region_start_timestamp = region_timers[GetCVar("portal"):upper()]
  90.     if region_start_timestamp then
  91.         local duration = 10 -- Adjusted duration
  92.         local interval = 60 -- Adjusted interval
  93.         local start_timestamp = GetServerTime() - region_start_timestamp
  94.         local next_event = interval - start_timestamp % interval
  95.         local spawning = interval - next_event < duration
  96.         local remaining = duration - (interval - next_event)
  97.  
  98.         local offset = not spawning and interval or 0
  99.         local rotation_index = math.floor((start_timestamp + offset) / interval % 20)
  100.         local currentLocationID = zone_rotation[rotation_index]
  101.         addonTable.currentZone = C_Map.GetMapInfo(currentLocationID).name
  102.  
  103.         addonTable.spawning = spawning
  104.         if spawning then
  105.             if addonTable.timerFrame and not addonTable.timerFrame.UserHidden then -- Added
  106.                 addonTable.timerFrame:Show() -- Moved
  107.         end -- Added
  108.             addonTable.timerEndTime = GetTime() + remaining
  109.         else
  110.             addonTable.timerEndTime = GetTime() + next_event
  111.         end
  112.     end
  113. end
  114.  
  115. local function InitializeAddon()
  116.     addonTable.states = {}
  117.     addonTable.currentZone = ""
  118.     addonTable.timerEndTime = nil
  119.     addonTable.spawning = false
  120.  
  121.     local frame = CreateFrame("Frame")
  122.     frame:RegisterEvent("PLAYER_ENTERING_WORLD")
  123.     frame:SetScript("OnEvent", function(_, event, ...)
  124.         if event == "PLAYER_ENTERING_WORLD" then
  125.             UpdateLocation() -- Update location on entering world
  126.         end
  127.     end)
  128.  
  129.     frame:SetScript("OnUpdate", function()
  130.         UpdateTimer() -- Update timer continuously
  131.         UpdateLocation() -- Update location continuously
  132.     end)
  133. end
  134.  
  135. InitializeAddon()
  136.  
  137. SLASH_ZAM4TIMER1 = "/zz" -- Added from here down
  138. SlashCmdList.ZAM4TIMER = function(msg)
  139.     if addonTable.timerFrame then
  140.         addonTable.timerFrame.UserHidden = nil
  141.         addonTable.timerFrame:Show()
  142.     end
  143. end

Maybe you want something different. That's what you need to figure out.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 06-03-24 at 12:05 AM.
  Reply With Quote
06-03-24, 12:22 AM   #11
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 134
You have helped me a lot again. Thank you so much for this, this forum is the best.
  Reply With Quote
06-24-24, 12:55 AM   #12
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 134
Lua Code:
  1. local addonName, addonTable = ...
  2.  
  3. -- Localization table
  4. local L = {
  5.     enUS = {
  6.         TIME_RUIN = "Event in progress",
  7.         TIME_LEFT = "Before changing location",
  8.     },
  9.     deDE = {
  10.         TIME_RUIN = "Veranstaltung läuft",
  11.         TIME_LEFT = "Vor einem Standortwechsel",
  12.     }
  13. }
  14.  
  15. -- Function to get localized string
  16. local function GetLocalizedString(key)
  17.     local locale = GetLocale()
  18.     if L[locale] and L[locale][key] then
  19.         return L[locale][key]
  20.     else
  21.         return L["enUS"][key] -- Fallback to English
  22.     end
  23. end
  24.  
  25. local function UpdateTimer()
  26.     if addonTable.timerEndTime then
  27.         local timeLeft = addonTable.timerEndTime - GetTime()
  28.         if timeLeft > 0 then
  29.             local hoursLeft = math.floor(timeLeft / 3600)
  30.             local minutesLeft = math.floor((timeLeft % 3600) / 60)
  31.             local secondsLeft = math.floor(timeLeft % 60)
  32.             if not addonTable.timerFrame then
  33.                 addonTable.timerFrame = CreateFrame("Frame", addonName.."TimerFrame", UIParent, "DialogBoxFrame")
  34.                 addonTable.timerFrame:SetSize(225, 120) -- Adjusted size
  35.                 addonTable.timerFrame:SetPoint("CENTER")
  36.                 addonTable.timerFrame:SetMovable(true)
  37.                 addonTable.timerFrame:EnableMouse(true)
  38.                 addonTable.timerFrame:RegisterForDrag("LeftButton")
  39.                 addonTable.timerFrame:SetScript("OnDragStart", addonTable.timerFrame.StartMoving)
  40.                 addonTable.timerFrame:SetScript("OnDragStop", addonTable.timerFrame.StopMovingOrSizing)
  41.                 addonTable.timerFrame:SetScript("OnHide", function(self)
  42.                     self.UserHidden = true
  43.                 end)
  44.                 addonTable.timerFrame:SetBackdrop({
  45.                     bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
  46.                     edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
  47.                     edgeSize = 16,
  48.                     insets = { left = 8, right = 6, top = 8, bottom = 8 },
  49.                 })
  50.                 addonTable.timerFrame:SetBackdropBorderColor(1, 1, 1)
  51.                
  52.                 addonTable.timerFrame.textZone = addonTable.timerFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
  53.                 addonTable.timerFrame.textZone:SetPoint("TOP", addonTable.timerFrame, "TOP", 0, -20)
  54.                
  55.                 addonTable.timerFrame.textTimer = addonTable.timerFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
  56.                 addonTable.timerFrame.textTimer:SetPoint("CENTER", addonTable.timerFrame, "CENTER", 0, 0)
  57.                
  58.                 addonTable.timerFrame.deleteButton = CreateFrame("Button", nil, addonTable.timerFrame, "UIPanelCloseButton")
  59.                 addonTable.timerFrame.deleteButton:SetPoint("TOPRIGHT", addonTable.timerFrame, "TOPRIGHT")
  60.                 addonTable.timerFrame.deleteButton:SetScript("OnClick", function()
  61.                     addonTable.timerFrame:Hide()
  62.                 end)
  63.             end
  64.            
  65.             addonTable.timerFrame.textZone:SetText(addonTable.currentZone)
  66.             if addonTable.spawning then
  67.                 addonTable.timerFrame.textTimer:SetText(string.format("%s: %02d:%02d:%02d", GetLocalizedString("TIME_RUIN"), hoursLeft, minutesLeft, secondsLeft))
  68.             else
  69.                 addonTable.timerFrame.textTimer:SetText(string.format("%s: %02d:%02d:%02d", GetLocalizedString("TIME_LEFT"), hoursLeft, minutesLeft, secondsLeft))
  70.             end
  71.         else
  72.             if addonTable.timerFrame then
  73.                 addonTable.timerFrame:Hide()
  74.             end
  75.         end
  76.     end
  77. end
  78.  
  79.  
  80. local function UpdateLocation()
  81.     local zone_rotation = {
  82.         [0] = 115, -- Dragonblight
  83.         [1] = 1254, -- Searing Gorge
  84.         [2] = 1315, -- Dustwallow Marsh
  85.     }
  86.  
  87.     local region_timers = {
  88.         NA = 1719210600, -- NA
  89.         US = 1719210600, -- US
  90.         KR = 1719210600, -- KR
  91.         EU = 1719210600, -- EU
  92.         TW = nil, -- TW (Add TW timestamp if available)
  93.     }
  94.  
  95.     local region_start_timestamp = region_timers[GetCVar("portal"):upper()]
  96.     if region_start_timestamp then
  97.         local duration = 600 -- Adjusted duration
  98.         local interval = 5400 -- Adjusted interval
  99.         local start_timestamp = GetServerTime() - region_start_timestamp
  100.         local next_event = interval - start_timestamp % interval
  101.         local spawning = interval - next_event < duration
  102.         local remaining = duration - (interval - next_event)
  103.  
  104.         local offset = not spawning and interval or 0
  105.         local rotation_index = math.floor((start_timestamp + offset) / interval % #zone_rotation)
  106.         local currentLocationID = zone_rotation[rotation_index]
  107.         addonTable.currentZone = C_Map.GetMapInfo(currentLocationID).name
  108.  
  109.         addonTable.spawning = spawning
  110.         if spawning then
  111.             if addonTable.timerFrame and not addonTable.timerFrame.UserHidden then
  112.                 addonTable.timerFrame:Show()
  113.             end
  114.             addonTable.timerEndTime = GetTime() + remaining
  115.         else
  116.             addonTable.timerEndTime = GetTime() + next_event
  117.         end
  118.     end
  119. end
  120.  
  121. local function InitializeAddon()
  122.     addonTable.states = {}
  123.     addonTable.currentZone = ""
  124.     addonTable.timerEndTime = nil
  125.     addonTable.spawning = false
  126.  
  127.     local frame = CreateFrame("Frame")
  128.     frame:RegisterEvent("PLAYER_ENTERING_WORLD")
  129.     frame:SetScript("OnEvent", function(_, event, ...)
  130.         if event == "PLAYER_ENTERING_WORLD" then
  131.             UpdateLocation() -- Update location on entering world
  132.         end
  133.     end)
  134.  
  135.     frame:SetScript("OnUpdate", function()
  136.         UpdateTimer() -- Update timer continuously
  137.         UpdateLocation() -- Update location continuously
  138.     end)
  139. end
  140.  
  141. InitializeAddon()
  142.  
  143. SLASH_ZAM4TIMER1 = "/zz"
  144. SlashCmdList.ZAM4TIMER = function(msg)
  145.     if addonTable.timerFrame then
  146.         addonTable.timerFrame.UserHidden = nil
  147.         addonTable.timerFrame:Show()
  148.     end
  149. end

Hi all. There's one last detail left that I can't do.

Now: Event (location name is displayed) "Before changing location" (for example, this is Dragonblight) and everything is displayed correctly. But when the "Event in progress" condition occurs, the previous location is still displayed. Currently the event starts every 1.5 hours with a duration of 10 minutes.

You need: Event (the name of the location is displayed) “Before changing location” (for example, this is Dragonblight), as soon as the condition “Event in progress” occurs, you need to change the location to the next one in the list. It is necessary to change the location when an event occurs.

The timer cycle is as follows: 1 hour 20 minutes before the location change (location 1 is displayed), the start of the event (location 2 is displayed) time 10 minutes, before the location change 1 hour 20 minutes (location 2 is displayed).

The highlighted one is not working correctly.

As I understand it, this is in the line
Lua Code:
  1. local spawning = interval - next_event < duration
But how to remake it?
  Reply With Quote
06-24-24, 02:35 AM   #13
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 134
In other words. Now there is a change of location at the moment of “completion” of the event (function “local duration = 600”). And you need to change the location at the moment of the “start of the event” (function local interval = 5400). And at the moment of “completion”, leave the location unchanged.
  Reply With Quote
06-24-24, 12:31 PM   #14
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,921
If I'm understanding correctly, instead of:
Lua Code:
  1. local zone_rotation = {
  2.     [0] = 115, -- Dragonblight
  3.     [1] = 1254, -- Searing Gorge
  4.     [2] = 1315, -- Dustwallow Marsh
  5. }
you might use:
Lua Code:
  1. local zone_rotation = {
  2.     [0] = { start=115, end=123, }, -- start Dragonblight, end 123 (replace 123 with the end zone id.)
  3.     [1] = { start=1254, end=1254, }, -- starts and ends Searing Gorge
  4.     [2] = { start=1315, end=1315, } , -- starts and ends Dustwallow Marsh
  5. }

Then for the start location you could:
Lua Code:
  1. local currentLocationID = zone_rotation[rotation_index].start

and for the end location, something like:
Lua Code:
  1. local endLocationID = zone_rotation[rotation_index].end

If I'm understanding correctly.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 06-24-24 at 12:35 PM.
  Reply With Quote
06-24-24, 10:43 PM   #15
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 134
Lua Code:
  1. local addonName, addonTable = ...
  2.  
  3. -- Localization table
  4. local L = {
  5.     enUS = {
  6.         TIME_RUIN = "Event in progress",
  7.         TIME_LEFT = "Before changing location",
  8.     },
  9.      deDE = {
  10.         TIME_RUIN = "Veranstaltung läuft",
  11.         TIME_LEFT = "Vor einem Standortwechsel",
  12.     }
  13. }
  14.  
  15. -- Function to get localized string
  16. local function GetLocalizedString(key)
  17.     local locale = GetLocale()
  18.     if L[locale] and L[locale][key] then
  19.         return L[locale][key]
  20.     else
  21.         return L["enUS"][key] -- Fallback to English
  22.     end
  23. end
  24.  
  25. local function UpdateTimer()
  26.     if addonTable.timerEndTime then
  27.         local timeLeft = addonTable.timerEndTime - GetTime()
  28.         if timeLeft > 0 then
  29.             local hoursLeft = math.floor(timeLeft / 3600)
  30.             local minutesLeft = math.floor((timeLeft % 3600) / 60)
  31.             local secondsLeft = math.floor(timeLeft % 60)
  32.             if not addonTable.timerFrame then
  33.                 addonTable.timerFrame = CreateFrame("Frame", addonName.."TimerFrame", UIParent, "DialogBoxFrame")
  34.                 addonTable.timerFrame:SetSize(225, 120) -- Adjusted size
  35.                 addonTable.timerFrame:SetPoint("CENTER")
  36.                 addonTable.timerFrame:SetMovable(true)
  37.                 addonTable.timerFrame:EnableMouse(true)
  38.                 addonTable.timerFrame:RegisterForDrag("LeftButton")
  39.                 addonTable.timerFrame:SetScript("OnDragStart", addonTable.timerFrame.StartMoving)
  40.                 addonTable.timerFrame:SetScript("OnDragStop", addonTable.timerFrame.StopMovingOrSizing)
  41.                 addonTable.timerFrame:SetScript("OnHide", function(self)
  42.                     self.UserHidden = true
  43.                 end)
  44.                 addonTable.timerFrame:SetBackdrop({
  45.                     bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
  46.                     edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
  47.                     edgeSize = 16,
  48.                     insets = { left = 8, right = 6, top = 8, bottom = 8 },
  49.                 })
  50.                 addonTable.timerFrame:SetBackdropBorderColor(1, 1, 1)
  51.                
  52.                 addonTable.timerFrame.textZone = addonTable.timerFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
  53.                 addonTable.timerFrame.textZone:SetPoint("TOP", addonTable.timerFrame, "TOP", 0, -20)
  54.                
  55.                 addonTable.timerFrame.textTimer = addonTable.timerFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
  56.                 addonTable.timerFrame.textTimer:SetPoint("CENTER", addonTable.timerFrame, "CENTER", 0, 0)
  57.                
  58.                 addonTable.timerFrame.deleteButton = CreateFrame("Button", nil, addonTable.timerFrame, "UIPanelCloseButton")
  59.                 addonTable.timerFrame.deleteButton:SetPoint("TOPRIGHT", addonTable.timerFrame, "TOPRIGHT")
  60.                 addonTable.timerFrame.deleteButton:SetScript("OnClick", function()
  61.                     addonTable.timerFrame:Hide()
  62.                 end)
  63.             end
  64.            
  65.             addonTable.timerFrame.textZone:SetText(addonTable.currentZone)
  66.             if addonTable.spawning then
  67.                 addonTable.timerFrame.textTimer:SetText(string.format("%s: %02d:%02d:%02d", GetLocalizedString("TIME_RUIN"), hoursLeft, minutesLeft, secondsLeft))
  68.             else
  69.                 addonTable.timerFrame.textTimer:SetText(string.format("%s: %02d:%02d:%02d", GetLocalizedString("TIME_LEFT"), hoursLeft, minutesLeft, secondsLeft))
  70.             end
  71.         else
  72.             if addonTable.timerFrame then
  73.                 addonTable.timerFrame:Hide()
  74.             end
  75.         end
  76.     end
  77. end
  78.  
  79. local function UpdateLocation()
  80.     local zone_rotation = {
  81.         [0] = 115, -- Dragonblight
  82.         [1] = 1254, -- Searing Gorge
  83.         [2] = 1315, -- Dustwallow Marsh
  84.     }
  85.  
  86.     local region_timers = {
  87.         NA = 1719210600, -- NA
  88.         US = 1719210600, -- US
  89.         KR = 1719210600, -- KR
  90.         EU = 1719230400, -- EU
  91.         TW = nil, -- TW (Add TW timestamp if available)
  92.     }
  93.  
  94.     local region_start_timestamp = region_timers[GetCVar("portal"):upper()]
  95.     if region_start_timestamp then
  96.         local duration = 600 -- Adjusted duration
  97.         local interval = 5400 -- Adjusted interval
  98.         local start_timestamp = GetServerTime() - region_start_timestamp
  99.         local next_event = interval - start_timestamp % interval
  100.         local spawning = interval - next_event < duration
  101.         local remaining = duration - (interval - next_event)
  102.  
  103.         local offset = not spawning and interval or 0
  104.         local rotation_index = math.floor(start_timestamp / interval % #zone_rotation)
  105.         local currentLocationID = zone_rotation[rotation_index]
  106.         addonTable.currentZone = C_Map.GetMapInfo(currentLocationID).name
  107.  
  108.         addonTable.spawning = spawning
  109.         if spawning then
  110.             if addonTable.timerFrame and not addonTable.timerFrame.UserHidden then
  111.                 addonTable.timerFrame:Show()
  112.             end
  113.             addonTable.timerEndTime = GetTime() + remaining
  114.         else
  115.             addonTable.timerEndTime = GetTime() + next_event
  116.         end
  117.     end
  118. end
  119.  
  120. local function InitializeAddon()
  121.     addonTable.states = {}
  122.     addonTable.currentZone = ""
  123.     addonTable.timerEndTime = nil
  124.     addonTable.spawning = false
  125.  
  126.     local frame = CreateFrame("Frame")
  127.     frame:RegisterEvent("PLAYER_ENTERING_WORLD")
  128.     frame:SetScript("OnEvent", function(_, event, ...)
  129.         if event == "PLAYER_ENTERING_WORLD" then
  130.             UpdateLocation() -- Update location on entering world
  131.         end
  132.     end)
  133.  
  134.     frame:SetScript("OnUpdate", function()
  135.         UpdateTimer() -- Update timer continuously
  136.         UpdateLocation() -- Update location continuously
  137.     end)
  138. end
  139.  
  140. InitializeAddon()
  141.  
  142. SLASH_ZAM4TIMER1 = "/zz"
  143. SlashCmdList.ZAM4TIMER = function(msg)
  144.     if addonTable.timerFrame then
  145.         addonTable.timerFrame.UserHidden = nil
  146.         addonTable.timerFrame:Show()
  147.     end
  148. end


Many thanks for the help. I did it like this. But I like your version of the code more and it is better.
  Reply With Quote

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


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