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:
local addonName, addon = ...
local Backdrop = {
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
}
local frame_x = 100
local frame_y = -250
local f = CreateFrame("Button", "ZAMTimer777", UIParent, "BackdropTemplate")
f:SetWidth(185)
f:SetHeight(30)
f:SetBackdrop(Backdrop)
f.text = f:CreateFontString(nil,"OVERLAY","GameTooltipText")
f.text:SetPoint("CENTER")
f:SetClampedToScreen(true)
f:SetPoint("CENTER",UIParent,"CENTER",frame_x,frame_y)
f:EnableMouse(true)
f:SetMovable(true)
f:RegisterForDrag("LeftButton")
f:RegisterForClicks("AnyUp")
f:Show()
f:RegisterEvent("PLAYER_ENTERING_WORLD")
f:SetScript("OnDragStart",function(self)
self:StartMoving()
end)
f:SetScript("OnDragStop",function(self)
self:StopMovingOrSizing()
end)
-- first %s is replaced by the color. The second is replaced by the time. |r resets the color back to default
local Localizations = {
enUS = {
Waiting = {
"|c1C7BCEFFFroststone A:\nbefore the start: %s%s|r",
"|c1C7BCEFFFroststone B:\nbefore the start: %s%s|r",
"|c1C7BCEFFFroststone C:\nbefore the start: %s%s|r",
"|c1C7BCEFFFroststone D:\nbefore the start: %s%s|r",
},
Running = {
"|cFF35BE21Froststone A:\n%s%s until completion|r",
"|cFF35BE21Froststone B:\n%s%s until completion|r",
"|cFF35BE21Froststone C:\n%s%s until completion|r",
"|cFF35BE21Froststone D:\n%s%s until completion|r",
},
},
}
local locale = GetLocale()
local L = Localizations[locale] or Localizations.enUS -- Default to enUS if locale doesn't exist in the table
------------------------------------------------------------------------------------------------------
-- These might be converted to Saved Variables so each character can determine
-- wether or not to play a sound, the alert times and colors and sound to play.
-- If so then most of the code below will have to move into an event handler for
-- the PLAYER_LOGIN or PLAYER_ENTERING_WORLD event.
local useColor = true
local useSound = true
local alert1 = 600 -- Alarm 1 set to 10 minutes before event
local alert1Color = "|cffffff00" -- Yellow
local alert2 = 300 -- Alarm 2 set to 5 minutes before event
local alert2Color = "|cffff0000" -- Red
local soundKit = 32585 -- Alarm sound
------------------------------------------------------------------------------------------------------
local function printTime(timetotrun, inevent)
local hideSeconds = timetotrun >= 120
local msg = L.Waiting
local msgColor = "|cffffffff"
if inevent then
msg = L.Running
else
if useColor and timetotrun <= alert2 then
msgColor = alert2Color
elseif timetotrun <= alert1 then
if useSound and not ZAMTimer777.Alerted then
ZAMTimer777.Alerted = true
PlaySound(soundKit, "Master")
end
if useColor then
msgColor = alert1Color
end
end
end
f.text:SetText(format(msg, msgColor, SecondsToTime(timetotrun, hideSeconds)))
end
regionEventStartTime = {
[1] = { -- eu
starttime = 1679572800,
eventDuration = 300,
eventIntervalInSeconds = 3600,
enable = true,
datablock = {}
},
}
local inEvent, timeToRun
local eventTime = regionEventStartTime[1].eventDuration -- Time the event runs in seconds(15 mins)
local waitTime = regionEventStartTime[1].eventIntervalInSeconds -- Time between events in seconds (90 mins)
local startTime = regionEventStartTime[1].starttime -- Start time from the table
local serverTime = GetServerTime()
local timeToEvent = (startTime - serverTime) % waitTime -- Remaining time before next event starts
if timeToEvent > (waitTime - eventTime) then -- Is there between 1:15 and 1:30 to go? If so, we're in the event
inEvent = true
timeToRun = eventTime - (waitTime - timeToEvent)
else -- Otherwise, set the ticker timer to time to next event
inEvent = false
timeToRun = timeToEvent
end
local ticker = C_Timer.NewTicker(1, function()
if timeToRun > 0 then
timeToRun = timeToRun - 1
printTime(timeToRun, inEvent)
return
end
ZAMTimer777.Alerted = false
if inEvent then -- The event just finished
inEvent = false
timeToRun = waitTime - eventTime -- Reset ticker timer to 90 minutes wait time minus 15 mins event time
else -- Waiting for the next event just expired
inEvent = true
timeToRun = eventTime -- And the event is running
end
printTime(timeToRun, inEvent)
end)
printTime(timeToRun, inEvent)
I tried to do it myself based on the given code and WA
Lua Code:
function(states, event, ...)
if event ~= "VOZ_TREASURE_GOBLIN_EVENT" and event ~= "STATUS" and event ~= "OPTIONS" then
return false
end
local zone_rotation = {
[0] = 84, -- Stormwind
[1] = 2023, -- Ohn'ahran Plains
[2] = 85, -- Orgrimmar
[3] = 2024, -- The Azure Span
[4] = 84, -- Stormwind
[5] = 2025, -- Thaldraszus
[6] = 85, -- Orgrimmar
[7] = 2112, -- Valdrakken
[8] = 84, -- Stormwind
[9] = 2022, -- The Waking Shores
[10] = 85, -- Orgrimmar
[11] = 2023, -- Ohn'ahran Plains
[12] = 84, -- Stormwind
[13] = 2024, -- The Azure Span
[14] = 85, -- Orgrimmar
[15] = 2025, -- Thaldraszus
[16] = 84, -- Stormwind
[17] = 2112, -- Valdrakken
[18] = 85, -- Orgrimmar
[19] = 2022, -- The Waking Shores
}
local region_timers = {
[1] = 1685041200, -- NA
[2] = 1684962000, -- KR
[3] = 1685001666, -- EU
[4] = nil, -- TW
[5] = nil -- CN
}
local region_start_timestamp = region_timers[GetCurrentRegion()]
if region_start_timestamp then
local duration = 300
local interval = 1800
local start_timestamp = GetServerTime() - region_start_timestamp
local next_event = interval - start_timestamp % interval
local spawning = interval - next_event < duration
local remaining = duration - (interval - next_event)
local offset = not spawning and interval or 0
local rotation_index = math.floor((start_timestamp + offset) / interval % 20)
local zone = C_Map.GetMapInfo(zone_rotation[rotation_index]).name
states[""] = {
changed = true,
show = true,
progressType = "timed",
autoHide = true,
duration = spawning and duration or interval - duration,
expirationTime = GetTime() + (spawning and remaining or next_event),
spawning = spawning,
name = zone
}
end
return true
end
Here's what I got. But this option works with an error (For testing I used an interval of 1 minute).
Lua Code:
local addonName, addon = ...
local Backdrop = {
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
}
local frame_x = 100
local frame_y = -250
local f = CreateFrame("Button", "ZAMTimer777", UIParent, "BackdropTemplate")
f:SetWidth(185)
f:SetHeight(30)
f:SetBackdrop(Backdrop)
f.text = f:CreateFontString(nil,"OVERLAY","GameTooltipText")
f.text:SetPoint("CENTER")
f:SetClampedToScreen(true)
f:SetPoint("CENTER",UIParent,"CENTER",frame_x,frame_y)
f:EnableMouse(true)
f:SetMovable(true)
f:RegisterForDrag("LeftButton")
f:RegisterForClicks("AnyUp")
f:Show()
f:RegisterEvent("PLAYER_ENTERING_WORLD")
f:SetScript("OnDragStart",function(self)
self:StartMoving()
end)
f:SetScript("OnDragStop",function(self)
self:StopMovingOrSizing()
end)
-- first %s is replaced by the color. The second is replaced by the time. |r resets the color back to default
local Localizations = {
enUS = {
Waiting = {
"|c1C7BCEFFFroststone A:\nbefore the start: %s%s|r",
"|c1C7BCEFFFroststone B:\nbefore the start: %s%s|r",
"|c1C7BCEFFFroststone C:\nbefore the start: %s%s|r",
"|c1C7BCEFFFroststone D:\nbefore the start: %s%s|r",
},
Running = {
"|cFF35BE21Froststone A:\n%s%s until completion|r",
"|cFF35BE21Froststone B:\n%s%s until completion|r",
"|cFF35BE21Froststone C:\n%s%s until completion|r",
"|cFF35BE21Froststone D:\n%s%s until completion|r",
},
},
}
local locale = GetLocale()
local L = Localizations[locale] or Localizations.enUS -- Default to enUS if locale doesn't exist in the table
------------------------------------------------------------------------------------------------------
-- These might be converted to Saved Variables so each character can determine
-- wether or not to play a sound, the alert times and colors and sound to play.
-- If so then most of the code below will have to move into an event handler for
-- the PLAYER_LOGIN or PLAYER_ENTERING_WORLD event.
local useColor = true
local useSound = true
local alert1 = 600 -- Alarm 1 set to 10 minutes before event
local alert1Color = "|cffffff00" -- Yellow
local alert2 = 300 -- Alarm 2 set to 5 minutes before event
local alert2Color = "|cffff0000" -- Red
local soundKit = 32585 -- Alarm sound
------------------------------------------------------------------------------------------------------
regionEventStartTime = {
[1] = { -- eu
starttime = 1679572800,
eventDuration = 7,
eventIntervalInSeconds = 20,
enable = true,
},
}
local timeToRun
local inEvent = true
local eventTime = regionEventStartTime[1].eventDuration -- Time the event runs in seconds(15 mins)
local waitTime = regionEventStartTime[1].eventIntervalInSeconds -- Time between events in seconds (90 mins)
local startTime = regionEventStartTime[1].starttime -- Start time from the table
local serverTime = 1710590400 --GetServerTime()
local timeToEvent = (startTime - serverTime) % waitTime -- Remaining time before next event starts
local currentEvent = math.floor((serverTime - startTime) / waitTime + 1) % 4
local function printTime(timetotrun, inevent, eventnumber)
local hideSeconds = timetotrun >= 120
local msg = L.Waiting[eventnumber]
local msgColor = "|cffffffff"
if inevent then
msg = L.Running[eventnumber-1]
else
if useColor and timetotrun <= alert2 then
msgColor = alert2Color
elseif timetotrun <= alert1 then
if useSound and not ZAMTimer777.Alerted then
ZAMTimer777.Alerted = true
PlaySound(soundKit, "Master")
end
if useColor then
msgColor = alert1Color
end
end
end
f.text:SetText(format(msg, msgColor, SecondsToTime(timetotrun, hideSeconds)))
end
if timeToEvent > (waitTime - eventTime) then -- Is there between 1:15 and 1:30 to go? If so, we're in the event
inEvent = true
timeToRun = eventTime - (waitTime - timeToEvent)
else -- Otherwise, set the ticker timer to time to next event
inEvent = false
timeToRun = timeToEvent
end
local ticker = C_Timer.NewTicker(1, function()
if timeToRun > 0 then
timeToRun = timeToRun - 1
printTime(timeToRun, inEvent, currentEvent+1)
return
end
ZAMTimer777.Alerted = false
if inEvent then -- The event just finished
inEvent = false
timeToRun = waitTime - eventTime -- Reset ticker timer to 90 minutes wait time minus 15 mins event time
else -- Waiting for the next event just expired
currentEvent = (currentEvent + 1) % 4
inEvent = true
timeToRun = eventTime -- And the event is running
end
printTime(timeToRun, inEvent)
end)
printTime(timeToRun, inEvent, currentEvent+1)
Second question
how can I make a button to hide the timer on command?
Lua Code:
SLASH_HUBB1 = "/hubb"
SlashCmdList["HUBB"] = function(msg)
if strupper(strtrim(msg)) == "BTN" then -- toggle the shown state of the button if the type /hubb btn
btn:SetShown(not btn:IsShown()) -- show the button
return
end
updateData()
updateList()
f:Show()
end