if QueueQueue then return end QueueQueue = { ["name"] = "QueueQueue", ["version"] = 1.0, ["defaults"] = { ["indicator"] = { ["x"] = 410, ["y"] = 30, }, ["sound"] = true, }, ["queues"] = {}, ["lastUpdate"] = 0, } local QueueQueue = QueueQueue function QueueQueue.OnCampaignQueueJoined(event, campaignId, isGroup) QueueQueue.SyncOneCampaignQueue(campaignId, isGroup) end function QueueQueue.OnCampaignQueueLeft(event, campaignId, isGroup) QueueQueue.queues[campaignId] = nil end function QueueQueue.OnCampaignQueuePositionChanged(event, campaignId, isGroup, position) QueueQueue.queues[campaignId].position = position end function QueueQueue.OnCampaignQueueStateChanged(event, campaignId, isGroup, state) QueueQueue.queues[campaignId].state = state -- If entry just became available, play a very noticeable sound. if state == CAMPAIGN_QUEUE_REQUEST_STATE_CONFIRMING and QueueQueue.savedVariables.sound then PlaySound(SOUNDS.LEVEL_UP) end end function QueueQueue.SyncCampaignQueues() local queueCount = GetNumCampaignQueueEntries() QueueQueue.queues = {} for i=1,queueCount do QueueQueue.SyncOneCampaignQueue(GetCampaignQueueEntry(i)) end end function QueueQueue.SyncOneCampaignQueue(campaignId, isGroup) QueueQueue.queues[campaignId] = { ["isGroup"] = isGroup, ["name"] = GetCampaignName(campaignId), ["position"] = GetCampaignQueuePosition(campaignId, isGroup), ["state"] = GetCampaignQueueState(campaignId, isGroup), } end function QueueQueue.FormatTime(seconds) local hours = math.floor(seconds / 3600) local minutes = math.floor((seconds % 3600) / 60) seconds = seconds % 60 if hours > 0 then return string.format("%d:%02d:%02d", hours, minutes, seconds) else return string.format("%d:%02d", minutes, seconds) end end function QueueQueue.UpdateIndicator() local campaignId, queue = next(QueueQueue.queues) if queue then -- Display the campaign title QueueQueueIndicatorTitle:SetText(queue.name .. (queue.isGroup and " [Group]" or " [Solo]")) -- Display color-coded position indicator if queue.state == CAMPAIGN_QUEUE_REQUEST_STATE_CONFIRMING then QueueQueueIndicatorPosition:SetText("|c00FF00Ready!") elseif queue.state == CAMPAIGN_QUEUE_REQUEST_STATE_PENDING_ACCEPT then QueueQueueIndicatorPosition:SetText("|c00FF00Entering") elseif queue.state == CAMPAIGN_QUEUE_REQUEST_STATE_PENDING_JOIN then QueueQueueIndicatorPosition:SetText("|cEEEEEEQueueing") elseif queue.state == CAMPAIGN_QUEUE_REQUEST_STATE_PENDING_LEAVE then QueueQueueIndicatorPosition:SetText("|cEEEEEELeaving") elseif queue.position > 25 then QueueQueueIndicatorPosition:SetText("|cEEEEEE" .. queue.position) elseif queue.position > 10 then QueueQueueIndicatorPosition:SetText("|cFFFF00" .. queue.position) elseif queue.position > 0 then QueueQueueIndicatorPosition:SetText("|cFF8800" .. queue.position) else QueueQueueIndicatorPosition:SetText("?") end -- Display time spent in queue, if waiting... if queue.state == CAMPAIGN_QUEUE_REQUEST_STATE_WAITING then local seconds = GetSecondsInCampaignQueue(campaignId, queue.isGroup) QueueQueueIndicatorTime:SetText("|cCCCCCCQueued - " .. QueueQueue.FormatTime(seconds)) -- ...or time left to join, if available. elseif queue.state == CAMPAIGN_QUEUE_REQUEST_STATE_CONFIRMING then local seconds = GetCampaignQueueRemainingConfirmationSeconds(campaignId, queue.isGroup) -- Play discrete sound each second for the last 10 seconds of acceptance period. if seconds <= 10 and seconds > 0 and QueueQueue.savedVariables.sound then PlaySound(SOUNDS.GENERAL_ALERT_ERROR) end QueueQueueIndicatorTime:SetText(QueueQueue.FormatTime(seconds)) else QueueQueueIndicatorTime:SetText("") end else QueueQueueIndicatorTitle:SetText("") QueueQueueIndicatorPosition:SetText("") QueueQueueIndicatorTime:SetText("") end end function QueueQueue.OnUpdate() local now = GetSecondsSinceMidnight() if now ~= QueueQueue.lastUpdate then QueueQueue.lastUpdate = now QueueQueue.UpdateIndicator() end end function QueueQueue.OnIndicatorMoveStart() QueueQueueIndicatorBackdrop:SetAlpha(0.3) end function QueueQueue.OnIndicatorMoveStop() QueueQueueIndicatorBackdrop:SetAlpha(0.0) QueueQueue.savedVariables.indicator.x = QueueQueueIndicator:GetLeft() QueueQueue.savedVariables.indicator.y = QueueQueueIndicator:GetTop() end function QueueQueue.RestoreIndicatorPosition() local indicator = QueueQueue.savedVariables.indicator QueueQueueIndicator:ClearAnchors() QueueQueueIndicator:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, indicator.x, indicator.y) end function QueueQueue.RegisterEvents() EVENT_MANAGER:RegisterForEvent(QueueQueue.name, EVENT_CAMPAIGN_QUEUE_JOINED, QueueQueue.OnCampaignQueueJoined) EVENT_MANAGER:RegisterForEvent(QueueQueue.name, EVENT_CAMPAIGN_QUEUE_LEFT, QueueQueue.OnCampaignQueueLeft) EVENT_MANAGER:RegisterForEvent(QueueQueue.name, EVENT_CAMPAIGN_QUEUE_POSITION_CHANGED, QueueQueue.OnCampaignQueuePositionChanged) EVENT_MANAGER:RegisterForEvent(QueueQueue.name, EVENT_CAMPAIGN_QUEUE_STATE_CHANGED, QueueQueue.OnCampaignQueueStateChanged) end function QueueQueue.Initialize() QueueQueue.savedVariables = ZO_SavedVars:NewAccountWide("QueueQueueSavedVariables", 1, nil, QueueQueue.defaults) QueueQueue.RestoreIndicatorPosition() QueueQueue.SyncCampaignQueues() QueueQueue.RegisterEvents() end function QueueQueue.OnAddOnLoaded(event, addonName) if addonName == QueueQueue.name then QueueQueue.Initialize() end end EVENT_MANAGER:RegisterForEvent(QueueQueue.name, EVENT_ADD_ON_LOADED, QueueQueue.OnAddOnLoaded)