-- Indicators.lua local pairs, ipairs = pairs, ipairs; local floor = math.floor; local GetTime = GetTime; local UnitAura = UnitAura; local UnitIsDeadOrGhost, UnitIsConnected = UnitIsDeadOrGhost, UnitIsConnected; local CTimerAfter = C_Timer.After; local Settings = OmaRFSettings; local majorAuras = Settings.MajorAuras; local positions = {}; local watchedAuras = {}; local updaters = {}; local updating = {}; local auraFilters = {"HELPFUL", "HARMFUL"}; local M = {}; OmaRFIndicators = M; local function remaining(text, expires, current) if expires == 0 then text:SetText(""); return false; end local remain = expires - current; if remain > 8 then text:SetText(""); else text:SetText(floor(remain+0.5)); end return true; end local function updateIndicators(frame, unit) if not frame:IsShown() or not UnitIsConnected(unit) or UnitIsDeadOrGhost(unit) then updating[frame] = nil; return; end local needUpdate = false; local current = GetTime(); for _, pos in pairs(positions) do local ind = frame.inds[pos]; if ind.expires ~= nil then needUpdate = remaining(ind.text, ind.expires, current) or needUpdate; end end for i = 1,3 do local ind = frame.major[i]; if ind.expires ~= nil then needUpdate = remaining(ind.text, ind.expires, current) or needUpdate; end end if needUpdate then CTimerAfter(0.16, updaters[frame]); else updating[frame] = nil; end end function M.CheckIndicators(frame, unit) for _, pos in pairs(positions) do frame.inds[pos].expires = nil; frame.inds[pos]:Hide(); frame.inds[pos].text:Hide(); end for i = 1,3 do frame.major[i].expires = nil; frame.major[i]:Hide(); frame.major[i].text:Hide(); frame.major[i].stack:Hide(); end local name, icon, count, expires, caster, id; local showInds, showMajors, needUpdate = false, false, false; local majorPos = 1; local current = GetTime(); for _, filter in ipairs(auraFilters) do local i = 1; while true do name, _, icon, count, _, _, expires, caster, _, _, id = UnitAura(unit, i, filter); if not id then break end local pos = watchedAuras[id] or watchedAuras[name]; if pos and caster == "player" then needUpdate = remaining(frame.inds[pos].text, expires, current); frame.inds[pos].expires = expires; frame.inds[pos]:Show(); frame.inds[pos].text:Show(); showInds = true; end if (majorAuras[id] or majorAuras[name]) and majorPos <= 3 then needUpdate = remaining(frame.major[majorPos].text, expires, current); frame.major[majorPos].expires = expires; frame.major[majorPos]:SetTexture(icon); frame.major[majorPos]:Show(); frame.major[majorPos].text:Show(); if count > 1 then frame.major[majorPos].stack:SetText(count); frame.major[majorPos].stack:Show(); end showMajors = true; majorPos = majorPos + 1; end i = i + 1; end end if showInds or showMajors then frame.inds:Show(); frame.major:Show(); if needUpdate and not updating[frame] then updating[frame] = true; -- race? -- create a function for updating the indicator local func = updaters[frame]; if not func then func = function() updateIndicators(frame, unit) end; updaters[frame] = func; end CTimerAfter(0.16, func); end else frame.inds:Hide(); frame.major:Hide(); end end function M.LoadChar() watchedAuras = Settings.Character["WatchedAuras"]; positions = Settings.Character.Positions; end