local Srendarr = _G['Srendarr'] local ICON_SIZE = Srendarr.ICON_SIZE local UPDATE_THRESHOLD = Srendarr.UPDATE_THRESHOLD local round = zo_round local strfind = zo_plainstrfind local tsort = table.sort local tremove = table.remove local tinsert = table.insert local Aura = Srendarr.Aura local AuraFrame = {} local function SortByTime(a, b) if (a.k_type < 3 and b.k_type < 3) then -- timed, sort by time return a.k_finish > b.k_finish elseif (a.k_type == b.k_type) then -- non-timed, same type, sort by name return a.k_name > b.k_name else -- non-timed, different types, sort by type return a.k_type > b.k_type end end local function SortByName(a, b) return a.k_name > b.k_name end local function UpdateDisplayCentered(self) tsort(self.k_auraSorted, self.k_sortFunc) self.k_offsetI = self.k_offsetX * ((#self.k_auraSorted - 1) / 2) for i, aura in pairs(self.k_auraSorted) do aura:ClearAnchors() aura:SetAnchor(CENTER, self, CENTER, self.k_offsetI, 0) self.k_offsetI = self.k_offsetI - self.k_offsetX end end local function UpdateDisplayDirection(self) tsort(self.k_auraSorted, self.k_sortFunc) for i, aura in ipairs(self.k_auraSorted) do aura:ClearAnchors() aura:SetAnchor(self.k_point, self, self.k_point, self.k_offsetX * (i - 1), self.k_offsetY * (i - 1)) end end local function ConfigureUpdateDisplay(self) local db = self.k_db if (db.auraSort == 'NAME') then self.k_sortFunc = SortByName else self.k_sortFunc = SortByTime end if (db.auraGrowth == 'LEFTCENTER' or db.auraGrowth == 'RIGHTCENTER') then self.k_offsetX = round((db.auraPadding + ICON_SIZE) * db.scale * ((db.auraGrowth == 'LEFTCENTER') and 1 or -1)) self['UpdateDisplay'] = UpdateDisplayCentered else if (db.auraGrowth == 'UP') then self.k_point, self.k_offsetX, self.k_offsetY = BOTTOM, 0, round(-1 * (db.auraPadding + ICON_SIZE) * db.scale) elseif (db.auraGrowth == 'DOWN') then self.k_point, self.k_offsetX, self.k_offsetY = TOP, 0, round((db.auraPadding + ICON_SIZE) * db.scale) elseif (db.auraGrowth == 'LEFT') then self.k_point, self.k_offsetX, self.k_offsetY = RIGHT, round(-1 * (db.auraPadding + ICON_SIZE) * db.scale), 0 else -- RIGHT self.k_point, self.k_offsetX, self.k_offsetY = LEFT, round((db.auraPadding + ICON_SIZE) * db.scale), 0 end self['UpdateDisplay'] = UpdateDisplayDirection end end local function AddAura(self, aType, tType, name, icon, start, finish, isShield, abilityType, buff, abilityId, effectType) local existingAura = self.k_auraActive[name] or nil --vampirism stage check, should be working for all 3 language versions if strfind(name, 'Vampirism') then if strfind(name, '1') then icon = 'Srendarr/Icons/Stage1.dds' elseif strfind(name, '2') then icon = 'Srendarr/Icons/Stage2.dds' elseif strfind(name, '3') then icon = 'Srendarr/Icons/Stage3.dds' elseif strfind(name, '4') then icon = 'Srendarr/Icons/Stage4.dds' end end -- Skip Minor Buffs if (Srendarr.db.hideMinorBuffs and Srendarr.MinorBuffs[abilityId] ~= nil) then return end -- Skip Major Buffs if (Srendarr.db.hideMajorBuffs and Srendarr.MajorBuffs[abilityId] ~= nil) then return end if (aType < 3) then -- timed if (existingAura) then -- existingAura, update it if (finish > (existingAura.k_finish + UPDATE_THRESHOLD)) then -- finish time changed enough to potentially need to alter display list existingAura.k_start, existingAura.k_finish = start, finish self:UpdateDisplay() else -- minor change in timing (probably from hook), update data but don't alter display list existingAura.k_start, existingAura.k_finish = start, finish end if (existingAura.k_isGhost) then -- was ghosting, set to full visibility existingAura.icon:SetDesaturation(0) existingAura:SetAlpha(1) existingAura.k_isGhost = false end else local newAura = Aura:New(self, aType, tType, name, icon, start, finish, isShield, abilityType, buff, abilityId) Srendarr:AddTimer(tType, name, newAura) tinsert(self.k_auraSorted, newAura) self:UpdateDisplay() end else -- toggle or passive if (existingAura) then return end -- existing aura, nothing to do, abort local newAura = Aura:New(self, aType, tType, name, icon, start, finish, isShield, abilityType, buff, abilityId) tinsert(self.k_auraSorted, newAura) self:UpdateDisplay() end end local function RemoveAura(self, name) local remAura = self.k_auraActive[name] or nil if (remAura) then -- aura exists, remove Srendarr:RemoveTimer(remAura.k_timerType, name) remAura:Release() for i, aura in pairs(self.k_auraSorted) do if (aura.k_name == name) then tremove(self.k_auraSorted, i) break end end self:UpdateDisplay() end end local function RemoveAllAuras(self) for _, aura in pairs(self.k_auraActive) do aura:Release() end while (#self.k_auraSorted > 0) do tremove(self.k_auraSorted, 1) end end local function ConfigureAllAuras(self) for _, aura in pairs(self.k_auraActive) do aura:Configure() end for _, aura in pairs(self.k_auraPool) do aura:Configure() end end local function SetAurasNonInteractive(self) for _, aura in pairs(self.k_auraActive) do aura:SetMouseEnabled(false) end for _, aura in pairs(self.k_auraPool) do aura:SetMouseEnabled(false) end end function AuraFrame:New(id, alpha) local frame = WINDOW_MANAGER:CreateControl(nil, Srendarr.auraAnchors[id], CT_CONTROL) frame:SetKeyboardEnabled(false) frame:SetMouseEnabled(false) frame:SetMovable(false) frame:SetDimensions(ICON_SIZE, ICON_SIZE) frame:SetAnchor(CENTER) frame:SetAlpha(alpha) frame.k_auraPool = {} frame.k_auraActive = {} frame.k_auraSorted = {} frame.k_db = Srendarr.db.frames[id] frame.k_id = id frame['ConfigureUpdateDisplay'] = ConfigureUpdateDisplay frame['AddAura'] = AddAura frame['RemoveAura'] = RemoveAura frame['RemoveAllAuras'] = RemoveAllAuras frame['ConfigureAllAuras'] = ConfigureAllAuras frame['SetAurasNonInteractive'] = SetAurasNonInteractive frame:ConfigureUpdateDisplay() return frame end Srendarr.AuraFrame = AuraFrame