local Srendarr = _G['Srendarr'] local LMP = LibStub('LibMediaProvider-1.0') local L = Srendarr:GetLocale() local Aura = {} -- CONSTANTS -- local ICON_SIZE = Srendarr.ICON_SIZE local BAR_HEIGHT = Srendarr.BAR_HEIGHT local AURA_FADE_TIME = Srendarr.AURA_FADE_TIME -- UPVALUES -- local WM = WINDOW_MANAGER local GetGameTimeMilliseconds = GetGameTimeMilliseconds local strformat = string.format local math_floor = math.floor local tremove = table.remove local tinsert = table.insert local zo_strformat = zo_strformat local tSec = L.Time_Seconds local tMin = L.Time_Minutes local tHour = L.Time_Hours local tToggle = L.Time_Toggle local tPassive = L.Time_Passive local tCast = L.Time_Cast local currentTime, colours, remFrame, remName local function AddControl(parent, cType, level) local c = WM:CreateControl(nil, parent, cType) c:SetDrawLayer(DL_CONTROLS) c:SetDrawLevel(level) return c, c end local function BuildAura(frame) local aura, ctrl aura, ctrl = AddControl(frame, CT_TEXTURE, 2) ctrl:SetDimensions(ICON_SIZE, ICON_SIZE) ctrl:SetTexture([[/esoui/art/actionbar/abilityframe64_up.dds]]) -- ICON aura.icon, ctrl = AddControl(aura, CT_TEXTURE, 1) ctrl:SetDimensions(ICON_SIZE, ICON_SIZE) ctrl:SetAnchor(CENTER) -- LABELS aura.name, ctrl = AddControl(aura, CT_LABEL, 3) ctrl:SetVerticalAlignment(1) aura.timer, ctrl = AddControl(aura, CT_LABEL, 3) ctrl:SetVerticalAlignment(1) ctrl:SetHorizontalAlignment(1) -- BAR aura.bar, ctrl = AddControl(aura, CT_STATUSBAR, 2) ctrl:SetHeight(BAR_HEIGHT) ctrl:SetTexture([[/esoui/art/miscellaneous/progressbar_genericfill.dds]]) ctrl:SetTextureCoords(0, 1, 0, 0.625) ctrl:SetLeadingEdge([[/esoui/art/miscellaneous/progressbar_genericfill_leadingedge.dds]], 8, 32) ctrl:SetLeadingEdgeTextureCoords(0, 1, 0, 0.625) ctrl:EnableLeadingEdge(true) ctrl:SetMinMax(0, 1) ctrl:SetHandler('OnValueChanged', function(bar, value) bar.gloss:SetValue(value) end) -- change gloss value as main bar changes -- BAR GLOSS aura.bar.gloss, ctrl = AddControl(aura.bar, CT_STATUSBAR, 3) ctrl:SetHeight(BAR_HEIGHT) ctrl:SetAnchor(TOPLEFT) ctrl:SetTexture([[/esoui/art/miscellaneous/progressbar_genericfill_gloss.dds]]) ctrl:SetTextureCoords(0, 1, 0, 0.625) ctrl:SetLeadingEdge([[/esoui/art/miscellaneous/progressbar_genericfill_leadingedge_gloss.dds]], 8, 32) ctrl:SetLeadingEdgeTextureCoords(0, 1, 0, 0.625) ctrl:EnableLeadingEdge(true) ctrl:SetMinMax(0, 1) -- BAR FRAME aura.barBorderL, ctrl = AddControl(aura.bar, CT_TEXTURE, 4) ctrl:SetDimensions(10, BAR_HEIGHT) ctrl:SetAnchor(TOPLEFT) ctrl:SetTexture([[/esoui/art/miscellaneous/progressbar_frame.dds]]) aura.barBorderR, ctrl = AddControl(aura.bar, CT_TEXTURE, 4) ctrl:SetDimensions(10, BAR_HEIGHT) ctrl:SetAnchor(TOPRIGHT) ctrl:SetTexture([[/esoui/art/miscellaneous/progressbar_frame.dds]]) aura.barBorderM, ctrl = AddControl(aura.bar, CT_TEXTURE, 4) ctrl:SetHeight(BAR_HEIGHT) ctrl:SetAnchor(TOPLEFT, aura.bar, TOPLEFT, 10, 0) ctrl:SetTexture([[/esoui/art/miscellaneous/progressbar_frame.dds]]) ctrl:SetTextureCoords(0.019500000402331, 0.58980000019073, 0, 0.625) -- BAR BACKDROP aura.barBackdropEnd, ctrl = AddControl(aura.bar, CT_TEXTURE, 1) ctrl:SetDimensions(10, BAR_HEIGHT) ctrl:SetTexture([[/esoui/art/miscellaneous/progressbar_genericfill_leadingedge.dds]]) ctrl:SetColor(0,0,0,0.4) aura.barBackdrop, ctrl = AddControl(aura.bar, CT_TEXTURE, 1) ctrl:SetHeight(BAR_HEIGHT) ctrl:SetTexture('') ctrl:SetColor(0,0,0,0.4) aura.k_frame = frame aura['Configure'] = Aura.Configure aura['Ghost'] = Aura.Ghost aura['Release'] = Aura.Release aura:Configure() return aura end local function FormatTime(remaining) if (remaining < 60) then -- seconds return strformat(tSec, remaining) elseif (remaining < 3600) then -- minutes return strformat(tMin, math_floor(remaining / 60)) else -- hours return strformat(tHour, math_floor(remaining / 3600)) end end local function OnMouseEnter(control) local abilityIndex if control.abilityId then local abilityId = control.abilityId for index = 1, GetNumAbilities() do if GetAbilityIdByIndex(index) == abilityId then abilityIndex = index break end end if abilityIndex then InitializeTooltip(InformationTooltip, control, BOTTOMLEFT, 0, -2, TOPLEFT) InformationTooltip:SetAbility(abilityIndex) end end if not abilityIndex then if control.buffId then local unitTag = control:GetParent().k_id == 4 and 'reticleover' or 'player' InitializeTooltip(InformationTooltip, control, BOTTOMLEFT, 0, -2, TOPLEFT) InformationTooltip:SetBuff(control.buffId, unitTag) elseif control.tooltipText then InitializeTooltip(InformationTooltip, control, BOTTOMLEFT, 0, -2, TOPLEFT) SetTooltipText(InformationTooltip, control.tooltipText) end end end local function OnMouseExit(control) ClearTooltip(InformationTooltip) end function Aura:New(frame, aType, tType, name, icon, start, finish, isShield, abilityType, buffId, abilityId) local aura = tremove(frame.k_auraPool, 1) -- grab from inactive pool if (not aura) then -- no inactive Aura, create one aura = BuildAura(frame) end -- initialize for display aura.k_name = name aura.k_type = aType aura.k_timerType = tType aura.k_isGhost = false aura.k_start = start aura.k_finish = finish aura.k_isShield = isShield aura.k_abilityType = abilityType -- tooltip text if showing aura.tooltipText = zo_strformat(SI_ABILITY_TOOLTIP_NAME, name) aura.buffId = buffId aura.abilityId = abilityId aura.name:SetText(aura.tooltipText) aura.icon:SetTexture(icon) if (aType < 3) then -- timed (short) or timed (long) currentTime = GetGameTimeMilliseconds() / 1000 if (start >= finish) then return end -- abort if 0 (or less) duration if (start > currentTime) then -- casting (starts later) aura.timer:SetText(tCast) aura.bar:SetValue(0.99) else aura.timer:SetText(FormatTime(finish - currentTime)) aura.bar:SetValue(1 - ((currentTime - start) / (finish - start))) end colours = frame.k_db.barColours.timed elseif (aType == 3) then -- toggle aura.timer:SetText((frame.k_db.timerShowTP) and tToggle or '') aura.bar:SetValue(0.99) colours = frame.k_db.barColours.toggle else -- passive aura.timer:SetText((frame.k_db.timerShowTP) and tPassive or '') aura.bar:SetValue(0.99) colours = frame.k_db.barColours.passive end aura.bar:SetGradientColors(colours.r1, colours.g1, colours.b1, 1, colours.r2, colours.g2, colours.b2, 1) aura:SetHidden(false) frame.k_auraActive[name] = aura return aura end function Aura:Ghost() if (self.k_isGhost) then return end -- already ghosting self.k_isGhost = true self.k_finish = (GetGameTimeMilliseconds() / 1000) self.icon:SetDesaturation(1) end function Aura:Release() self:SetHidden(true) -- return to default appearance self:SetAlpha(1) self.icon:SetDesaturation(0) self.k_isGhost = false -- remove from auralists and add to inactive pool remFrame, remName = self.k_frame, self.k_name remFrame.k_auraActive[remName] = nil tinsert(remFrame.k_auraPool, self) end function Aura:Configure() local db = self.k_frame.k_db self.name:SetFont(strformat('%s|%d|%s', LMP:Fetch('font', db.nameFont), db.nameSize, db.nameOutline)) self.name:SetHeight(db.nameSize) self.name:SetColor(db.nameColour.r, db.nameColour.g, db.nameColour.b) self.timer:SetFont(strformat('%s|%d|%s', LMP:Fetch('font', db.timerFont), db.timerSize, db.timerOutline)) self.timer:SetHeight(db.timerSize) self.timer:SetColor(db.timerColour.r, db.timerColour.g, db.timerColour.b) -- tooltip control if (db.tooltips) then self:SetMouseEnabled(true) if (not self:GetHandler('OnMouseEnter')) then -- no mouse watchers, add self:SetHandler('OnMouseEnter', OnMouseEnter) self:SetHandler('OnMouseExit', OnMouseExit) end else self:SetMouseEnabled(false) if (self:GetHandler('OnMouseEnter')) then -- mouse watchers, remove self:SetHandler('OnMouseEnter', nil) self:SetHandler('OnMouseExit', nil) end end if (db.auraGrowth == 'LEFT' or db.auraGrowth == 'RIGHT' or db.auraGrowth == 'LEFTCENTER' or db.auraGrowth == 'RIGHTCENTER') then -- horizontal aura growth if (db.timerShowHorz == 'HIDE') then self.timer:SetHidden(true) else self.timer:ClearAnchors() if (db.timerShowHorz == 'ABOVE') then self.timer:SetAnchor(BOTTOM, self, TOP, 0, -5) elseif (db.timerShowHorz == 'BELOW') then self.timer:SetAnchor(TOP, self, BOTTOM, 0, 1) elseif (db.timerShowHorz == 'OVER') then self.timer:SetAnchor(BOTTOM, self, BOTTOM, 0, -4) end self.timer:SetHidden(false) end self.name:SetHidden(true) self.bar:SetHidden(true) else -- vertical aura growth local point = (db.auraIconOnRight) and RIGHT or LEFT local pointInv = (db.auraIconOnRight) and LEFT or RIGHT local align = (db.auraIconOnRight) and 2 or 0 local xMulti = (db.auraIconOnRight) and -1 or 1 if (db.timerShowVert == 'HIDE') then self.timer:SetHidden(true) else self.timer:ClearAnchors() self.timer:SetAnchor(BOTTOM, self, BOTTOM, 0, -4) self.timer:SetHidden(false) end -- configure bar display self.bar:SetWidth(db.barWidth) self.bar.gloss:SetWidth(db.barWidth) self.bar.gloss:SetHidden(not db.barGloss) self.barBorderM:SetWidth(db.barWidth - 20) self.barBackdrop:ClearAnchors() self.barBackdrop:SetAnchor(point + TOP, self.bar, point + TOP, 0, 0) self.barBackdrop:SetWidth(db.barWidth - 10) self.barBackdropEnd:ClearAnchors() self.barBackdropEnd:SetAnchor(pointInv + TOP, self.bar, pointInv + TOP, 0, 0) if (db.auraIconOnRight) then self.bar:SetBarAlignment(BAR_ALIGNMENT_REVERSE) self.bar.gloss:SetBarAlignment(BAR_ALIGNMENT_REVERSE) self.barBorderL:SetTextureCoords(0.6133000254631, 0.59380000829697, 0, 0.625) self.barBorderR:SetTextureCoords(0.019500000402331, 0, 0, 0.625) self.barBackdropEnd:SetTextureCoords(1, 0, 0, 0.625) else self.bar:SetBarAlignment(BAR_ALIGNMENT_NORMAL) self.bar.gloss:SetBarAlignment(BAR_ALIGNMENT_NORMAL) self.barBorderL:SetTextureCoords(0, 0.019500000402331, 0, 0.625) self.barBorderR:SetTextureCoords(0.59380000829697, 0.6133000254631, 0, 0.625) self.barBackdropEnd:SetTextureCoords(0, 1, 0, 0.625) end -- anchor (or hide) 'side' elements if (db.showNameBar) then self.name:ClearAnchors() self.name:SetAnchor(point + TOP, self, pointInv + TOP, xMulti * 4, 0) self.name:SetHidden(false) self.bar:ClearAnchors() self.bar:SetAnchor(point + BOTTOM, self, pointInv + BOTTOM, xMulti * 3, 0) self.bar:SetHidden(false) else self.name:SetHidden(true) self.bar:SetHidden(true) end end end Srendarr.Aura = Aura