Thread Tools Display Modes
Prev Previous Post   Next Post Next
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
 

WoWInterface » AddOns, Compilations, Macros » AddOn Help/Support » 2 questions on the timer


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