View Single Post
03-16-24, 11:05 PM   #1
Hubb777
A Flamescale Wyrmkin
 
Hubb777's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2024
Posts: 113
2 questions on the timer

Hi all. Thanks again to Fizzlemizz, without him I couldn't do anything.

Data:
There are 4 events (A, B, C and D) and they go cyclically and endlessly (example: A, B, C, D, A, B, C, D, A, B, C and D)
The interval between all events is 1 hour (example Between event A and event B is 1 hour, between event B and event C is one hour, between event C and event D is 1 hour).
Events always last 5 minutes.
What is needed: For the event to be displayed correctly (where starttime = 1679572800, this is the start of event A).
For example, if I enter the game 3 hours 30 minutes after the start of event A, it will show me that event D will begin soon.

Source
Lua Code:
  1. local addonName, addon = ...
  2. local Backdrop = {
  3.     bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
  4. }
  5.  
  6. local frame_x = 100    
  7. local frame_y = -250    
  8. local f = CreateFrame("Button", "ZAMTimer777", UIParent, "BackdropTemplate")
  9. f:SetWidth(185)                                          
  10. f:SetHeight(30)
  11. f:SetBackdrop(Backdrop)
  12. f.text = f:CreateFontString(nil,"OVERLAY","GameTooltipText")
  13. f.text:SetPoint("CENTER")
  14. f:SetClampedToScreen(true)
  15. f:SetPoint("CENTER",UIParent,"CENTER",frame_x,frame_y)
  16. f:EnableMouse(true)
  17. f:SetMovable(true)
  18. f:RegisterForDrag("LeftButton")
  19. f:RegisterForClicks("AnyUp")
  20. f:Show()
  21. f:RegisterEvent("PLAYER_ENTERING_WORLD")
  22. f:SetScript("OnDragStart",function(self)
  23.     self:StartMoving()
  24. end)
  25. f:SetScript("OnDragStop",function(self)  
  26.     self:StopMovingOrSizing()
  27. end)
  28. -- first %s is replaced by the color. The second is replaced by the time. |r resets the color back to default
  29. local Localizations = {
  30.     enUS = {
  31.         Waiting = {
  32.             "|c1C7BCEFFFroststone A:\nbefore the start: %s%s|r",
  33.             "|c1C7BCEFFFroststone B:\nbefore the start: %s%s|r",
  34.             "|c1C7BCEFFFroststone C:\nbefore the start: %s%s|r",
  35.             "|c1C7BCEFFFroststone D:\nbefore the start: %s%s|r",
  36.         },     
  37.         Running = {
  38.             "|cFF35BE21Froststone A:\n%s%s until completion|r",
  39.             "|cFF35BE21Froststone B:\n%s%s until completion|r",
  40.             "|cFF35BE21Froststone C:\n%s%s until completion|r",
  41.             "|cFF35BE21Froststone D:\n%s%s until completion|r",
  42.         },
  43.     },
  44. }
  45.  
  46. local locale = GetLocale()
  47. local L = Localizations[locale] or Localizations.enUS -- Default to enUS if locale doesn't exist in the table
  48.  
  49. ------------------------------------------------------------------------------------------------------
  50. -- These might be converted to Saved Variables so each character can determine
  51. -- wether or not to play a sound, the alert times and colors and sound to play.
  52. -- If so then most of the code below will have to move into an event handler for
  53. -- the PLAYER_LOGIN or PLAYER_ENTERING_WORLD event.
  54. local useColor = true
  55. local useSound = true
  56. local alert1 = 600 -- Alarm 1 set to 10 minutes before event
  57. local alert1Color = "|cffffff00" -- Yellow
  58. local alert2 = 300 -- Alarm 2 set to 5 minutes before event
  59. local alert2Color = "|cffff0000" -- Red
  60. local soundKit = 32585 -- Alarm sound
  61. ------------------------------------------------------------------------------------------------------
  62.  
  63. local function printTime(timetotrun, inevent)
  64.     local hideSeconds = timetotrun >= 120
  65.     local msg = L.Waiting
  66.     local msgColor = "|cffffffff"
  67.     if inevent then
  68.         msg = L.Running
  69.     else
  70.         if useColor and timetotrun <= alert2 then
  71.             msgColor = alert2Color
  72.         elseif timetotrun <= alert1 then
  73.             if useSound and not ZAMTimer777.Alerted then
  74.                 ZAMTimer777.Alerted = true
  75.                 PlaySound(soundKit, "Master")
  76.             end
  77.             if useColor then
  78.                 msgColor = alert1Color
  79.             end
  80.         end
  81.     end
  82.     f.text:SetText(format(msg, msgColor, SecondsToTime(timetotrun, hideSeconds)))
  83. end
  84.  
  85. regionEventStartTime = {
  86.     [1] = { -- eu
  87.         starttime = 1679572800,
  88.         eventDuration = 300,
  89.         eventIntervalInSeconds = 3600,
  90.         enable = true,
  91.         datablock = {}
  92.     },
  93. }
  94.  
  95. local inEvent, timeToRun
  96. local eventTime = regionEventStartTime[1].eventDuration -- Time the event runs in seconds(15 mins)
  97. local waitTime = regionEventStartTime[1].eventIntervalInSeconds -- Time between events in seconds (90 mins)
  98. local startTime = regionEventStartTime[1].starttime -- Start time from the table
  99. local serverTime = GetServerTime()
  100. local timeToEvent = (startTime - serverTime) % waitTime -- Remaining time before next event starts
  101.  
  102. if timeToEvent > (waitTime - eventTime) then -- Is there between 1:15 and 1:30 to go? If so, we're in the event
  103.     inEvent = true
  104.     timeToRun = eventTime - (waitTime - timeToEvent)
  105. else                    -- Otherwise, set the ticker timer to time to next event
  106.     inEvent = false
  107.     timeToRun = timeToEvent
  108. end
  109. local ticker = C_Timer.NewTicker(1, function()
  110.     if timeToRun > 0 then
  111.         timeToRun = timeToRun - 1
  112.         printTime(timeToRun, inEvent)
  113.         return
  114.     end
  115.     ZAMTimer777.Alerted = false
  116.     if inEvent then -- The event just finished
  117.         inEvent = false
  118.         timeToRun = waitTime - eventTime -- Reset ticker timer to 90 minutes wait time minus 15 mins event time
  119.     else  -- Waiting for the next event just expired
  120.         inEvent = true
  121.         timeToRun = eventTime -- And the event is running
  122.     end
  123.     printTime(timeToRun, inEvent)
  124. end)
  125. printTime(timeToRun, inEvent)

I tried to do it myself based on the given code and WA
Lua Code:
  1. function(states, event, ...)
  2.     if event ~= "VOZ_TREASURE_GOBLIN_EVENT" and event ~= "STATUS" and event ~= "OPTIONS" then
  3.         return false
  4.     end
  5.    
  6.     local zone_rotation = {
  7.         [0] = 84, -- Stormwind
  8.         [1] = 2023, -- Ohn'ahran Plains
  9.         [2] = 85, -- Orgrimmar
  10.         [3] = 2024, -- The Azure Span
  11.         [4] = 84, -- Stormwind
  12.         [5] = 2025, -- Thaldraszus
  13.         [6] = 85, -- Orgrimmar
  14.         [7] = 2112, -- Valdrakken
  15.         [8] = 84, -- Stormwind
  16.         [9] = 2022, -- The Waking Shores
  17.         [10] = 85, -- Orgrimmar
  18.         [11] = 2023, -- Ohn'ahran Plains
  19.         [12] = 84, -- Stormwind
  20.         [13] = 2024, -- The Azure Span
  21.         [14] = 85, -- Orgrimmar
  22.         [15] = 2025, -- Thaldraszus
  23.         [16] = 84, -- Stormwind
  24.         [17] = 2112, -- Valdrakken
  25.         [18] = 85, -- Orgrimmar
  26.         [19] = 2022, -- The Waking Shores
  27.     }
  28.    
  29.     local region_timers = {
  30.         [1] = 1685041200, -- NA
  31.         [2] = 1684962000, -- KR
  32.         [3] = 1685001666, -- EU
  33.         [4] = nil, -- TW
  34.         [5] = nil  -- CN
  35.     }
  36.    
  37.     local region_start_timestamp = region_timers[GetCurrentRegion()]
  38.     if region_start_timestamp then
  39.         local duration = 300
  40.         local interval = 1800
  41.         local start_timestamp = GetServerTime() - region_start_timestamp
  42.         local next_event = interval - start_timestamp % interval
  43.         local spawning = interval - next_event < duration
  44.         local remaining = duration - (interval - next_event)
  45.        
  46.         local offset = not spawning and interval or 0
  47.         local rotation_index = math.floor((start_timestamp + offset) / interval % 20)
  48.         local zone = C_Map.GetMapInfo(zone_rotation[rotation_index]).name
  49.        
  50.         states[""] = {
  51.             changed = true,
  52.             show = true,
  53.             progressType = "timed",
  54.             autoHide = true,
  55.             duration = spawning and duration or interval - duration,
  56.             expirationTime = GetTime() + (spawning and remaining or next_event),
  57.             spawning = spawning,
  58.             name = zone
  59.         }
  60.     end
  61.    
  62.     return true
  63. end

Here's what I got. But this option works with an error (For testing I used an interval of 1 minute).
Lua Code:
  1. local addonName, addon = ...
  2. local Backdrop = {
  3.     bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
  4. }
  5.  
  6. local frame_x = 100    
  7. local frame_y = -250    
  8. local f = CreateFrame("Button", "ZAMTimer777", UIParent, "BackdropTemplate")
  9. f:SetWidth(185)                                        
  10. f:SetHeight(30)
  11. f:SetBackdrop(Backdrop)
  12. f.text = f:CreateFontString(nil,"OVERLAY","GameTooltipText")
  13. f.text:SetPoint("CENTER")
  14. f:SetClampedToScreen(true)
  15. f:SetPoint("CENTER",UIParent,"CENTER",frame_x,frame_y)
  16. f:EnableMouse(true)
  17. f:SetMovable(true)
  18. f:RegisterForDrag("LeftButton")
  19. f:RegisterForClicks("AnyUp")
  20. f:Show()
  21. f:RegisterEvent("PLAYER_ENTERING_WORLD")
  22. f:SetScript("OnDragStart",function(self)
  23.     self:StartMoving()
  24. end)
  25. f:SetScript("OnDragStop",function(self)  
  26.     self:StopMovingOrSizing()
  27. end)
  28. -- first %s is replaced by the color. The second is replaced by the time. |r resets the color back to default
  29.  
  30.  
  31. local Localizations = {
  32.     enUS = {
  33.         Waiting = {
  34.             "|c1C7BCEFFFroststone A:\nbefore the start: %s%s|r",
  35.             "|c1C7BCEFFFroststone B:\nbefore the start: %s%s|r",
  36.             "|c1C7BCEFFFroststone C:\nbefore the start: %s%s|r",
  37.             "|c1C7BCEFFFroststone D:\nbefore the start: %s%s|r",
  38.         },     
  39.         Running = {
  40.             "|cFF35BE21Froststone A:\n%s%s until completion|r",
  41.             "|cFF35BE21Froststone B:\n%s%s until completion|r",
  42.             "|cFF35BE21Froststone C:\n%s%s until completion|r",
  43.             "|cFF35BE21Froststone D:\n%s%s until completion|r",
  44.         },
  45.     },
  46. }
  47.            
  48.  
  49. local locale = GetLocale()
  50. local L = Localizations[locale] or Localizations.enUS -- Default to enUS if locale doesn't exist in the table
  51.  
  52. ------------------------------------------------------------------------------------------------------
  53. -- These might be converted to Saved Variables so each character can determine
  54. -- wether or not to play a sound, the alert times and colors and sound to play.
  55. -- If so then most of the code below will have to move into an event handler for
  56. -- the PLAYER_LOGIN or PLAYER_ENTERING_WORLD event.
  57. local useColor = true
  58. local useSound = true
  59. local alert1 = 600 -- Alarm 1 set to 10 minutes before event
  60. local alert1Color = "|cffffff00" -- Yellow
  61. local alert2 = 300 -- Alarm 2 set to 5 minutes before event
  62. local alert2Color = "|cffff0000" -- Red
  63. local soundKit = 32585 -- Alarm sound
  64. ------------------------------------------------------------------------------------------------------
  65.  
  66.  
  67. regionEventStartTime = {
  68.     [1] = { -- eu
  69.         starttime = 1679572800,
  70.         eventDuration = 7,
  71.         eventIntervalInSeconds = 20,
  72.         enable = true,
  73.     },
  74. }
  75.  
  76.  
  77. local timeToRun
  78. local inEvent = true
  79. local eventTime = regionEventStartTime[1].eventDuration -- Time the event runs in seconds(15 mins)
  80. local waitTime = regionEventStartTime[1].eventIntervalInSeconds -- Time between events in seconds (90 mins)
  81. local startTime = regionEventStartTime[1].starttime -- Start time from the table
  82. local serverTime = 1710590400  --GetServerTime()
  83. local timeToEvent = (startTime - serverTime) % waitTime -- Remaining time before next event starts
  84. local currentEvent = math.floor((serverTime - startTime) / waitTime + 1) % 4
  85.  
  86.  
  87. local function printTime(timetotrun, inevent, eventnumber)
  88.     local hideSeconds = timetotrun >= 120
  89.     local msg = L.Waiting[eventnumber]
  90.     local msgColor = "|cffffffff"
  91.     if inevent then
  92.         msg = L.Running[eventnumber-1]
  93.     else
  94.         if useColor and timetotrun <= alert2 then
  95.             msgColor = alert2Color
  96.         elseif timetotrun <= alert1 then
  97.             if useSound and not ZAMTimer777.Alerted then
  98.                 ZAMTimer777.Alerted = true
  99.                 PlaySound(soundKit, "Master")
  100.             end
  101.             if useColor then
  102.                 msgColor = alert1Color
  103.             end
  104.         end
  105.     end
  106.     f.text:SetText(format(msg, msgColor, SecondsToTime(timetotrun, hideSeconds)))
  107. end
  108.  
  109.  
  110. if timeToEvent > (waitTime - eventTime) then -- Is there between 1:15 and 1:30 to go? If so, we're in the event
  111.     inEvent = true
  112.     timeToRun = eventTime - (waitTime - timeToEvent)
  113. else                    -- Otherwise, set the ticker timer to time to next event
  114.     inEvent = false
  115.     timeToRun = timeToEvent
  116. end
  117.  
  118. local ticker = C_Timer.NewTicker(1, function()
  119.     if timeToRun > 0 then
  120.         timeToRun = timeToRun - 1
  121.         printTime(timeToRun, inEvent, currentEvent+1)
  122.         return
  123.     end
  124.  
  125.     ZAMTimer777.Alerted = false
  126.     if inEvent then -- The event just finished
  127.         inEvent = false
  128.         timeToRun = waitTime - eventTime -- Reset ticker timer to 90 minutes wait time minus 15 mins event time
  129.     else  -- Waiting for the next event just expired
  130.         currentEvent = (currentEvent + 1) % 4
  131.         inEvent = true
  132.         timeToRun = eventTime -- And the event is running
  133.     end
  134.     printTime(timeToRun, inEvent)
  135. end)
  136. printTime(timeToRun, inEvent, currentEvent+1)

Second question
how can I make a button to hide the timer on command?
Lua Code:
  1. SLASH_HUBB1 = "/hubb"
  2. SlashCmdList["HUBB"] = function(msg)
  3.     if strupper(strtrim(msg)) == "BTN" then -- toggle the shown state of the button if the type /hubb btn
  4.         btn:SetShown(not btn:IsShown()) -- show the button
  5.         return
  6.     end
  7.     updateData()
  8.     updateList()
  9.     f:Show()
  10. end
  Reply With Quote