local addon, ns = ... local cfg = ns.cfg local cast = ns.cast local lib = CreateFrame("Frame") local _, playerClass = UnitClass("player") oUF.colors.power['MANA'] = {0.0, 0.56, 1.0} oUF.colors.power['RAGE'] = {1.0,0,0} oUF.colors.power['FOCUS'] = {1.0,0.75,0.25} oUF.colors.power['ENERGY'] = {1.0, 0.9, 0.35} oUF.colors.power['RUNIC_POWER'] = {0.44,0.44,0.44} local _, pType = UnitPowerType("player") local pcolor = oUF.colors.power[pType] or {.3,.45,.65} oUF.colors.runes = {{196/255, 30/255, 58/255};{173/255, 217/255, 25/255};{35/255, 127/255, 255/255};{178/255, 53/255, 240/255};} ns.colors = setmetatable({ power = setmetatable({ ['MANA'] = {0.0, 0.56, 1.0}, ['RAGE'] = {1.0,0,0}, ['FOCUS'] = {1.0,0.75,0.25}, ['ENERGY'] = {1.0, 0.9, 0.35}, ['RUNIC_POWER'] = {0.44,0.44,0.44}, }, {__index = oUF.colors.power}), }, {__index = oUF.colors}) -- FUNCTIONS local retVal = function(f, val1, val2, val3) if f.mystyle == "player" or f.mystyle == "target" then return val1 elseif f.mystyle == "raid" or f.mystyle == "party" then return val3 else return val2 end end --status bar filling fix (from oUF_Mono) local fixStatusbar = function(b) b:GetStatusBarTexture():SetHorizTile(false) b:GetStatusBarTexture():SetVertTile(false) end --backdrop table local backdrop_tab = { bgFile = cfg.backdrop_texture, edgeFile = cfg.backdrop_edge_texture, tile = false, tileSize = 0, edgeSize = 5, insets = { left = 3, right = 3, top = 3, bottom = 3, }, } -- backdrop func lib.gen_backdrop = function(f) f:SetBackdrop(backdrop_tab); f:SetBackdropColor(0,0,0,1) f:SetBackdropBorderColor(0,0,0,0.8) end lib.gen_castbackdrop = function(f) f:SetBackdrop(backdrop_tab); f:SetBackdropColor(0,0,0,0.6) f:SetBackdropBorderColor(0,0,0,1) end lib.gen_totemback = function(f) f:SetBackdrop(backdrop_tab); f:SetBackdropColor(0,0,0,0.6) f:SetBackdropBorderColor(0,0,0,0.8) end -- Right Click Menu lib.spawnMenu = function(self) local unit = self.unit:sub(1, -2) local cunit = self.unit:gsub("^%l", string.upper) if(cunit == "Vehicle") then cunit = "Pet" end if(unit == "party") then ToggleDropDownMenu(1, nil, _G["PartyMemberFrame"..self.id.."DropDown"], "cursor", 0, 0) elseif(_G[cunit.."FrameDropDown"]) then ToggleDropDownMenu(1, nil, _G[cunit.."FrameDropDown"], "cursor", 0, 0) elseif unit == "raid" then FriendsDropDown.unit = self.unit FriendsDropDown.id = self.id FriendsDropDown.initialize = RaidFrameDropDown_Initialize ToggleDropDownMenu(1,nil,FriendsDropDown,"cursor") end end --fontstring func lib.gen_fontstring = function(f, name, size, outline) local fs = f:CreateFontString(nil, "OVERLAY") fs:SetFont(name, size, outline) fs:SetShadowColor(0,0,0,0.8) fs:SetShadowOffset(1,-1) return fs end -- Power Bar Arrow function local arrow = {[[Interface\Addons\oUF_Fail\media\textureArrow]]} --set color -- Huge thanks to Zork and Rainrider for helping me figure this out. lib.setArrowColor = function(self) local _, pType = UnitPowerType("player") local pcolor = oUF.colors.power[pType] or {.3,.45,.65} self.Power.arrow:SetVertexColor(unpack(pcolor)) end local fixTex = function(tex) local ULx,ULy,LLx,LLy,URx,URy,LRx,LRy = tex:GetTexCoord() tex:SetTexCoord(ULy,ULx,LLy,LLx,URy,URx,LRy,LRx) end --gen healthbar func lib.gen_hpbar = function(f) --statusbar local s = CreateFrame("StatusBar", nil, f) s:SetStatusBarTexture(cfg.statusbar_texture) fixStatusbar(s) if f.mystyle == "focus" or f.mystyle =="focustarget" then s:SetHeight(30) elseif f.mystyle =="pet" then s:SetHeight(28) else s:SetHeight(retVal(f,28,24,20)) end s:SetWidth(f:GetWidth()) s:SetPoint("BOTTOM",0,0) s:SetFrameLevel(4) --helper local h = CreateFrame("Frame", nil, s) h:SetFrameLevel(3) h:SetPoint("TOPLEFT",-5,5) h:SetPoint("BOTTOMRIGHT", 5, -5) lib.gen_backdrop(h) --bg local b = s:CreateTexture(nil, "BACKGROUND") b:SetTexture(cfg.statusbar_texture) b:SetAllPoints(s) b:SetVertexColor(1, 0.1, 0.1,0.8) f.Health = s f.Health.bg2 = b end --gen hp strings func lib.gen_hpstrings = function(f, unit) --creating helper frame here so our font strings don't inherit healthbar parameters local h = CreateFrame("Frame", nil, f) h:SetAllPoints(f.Health) h:SetFrameLevel(15) local fontsize if f.mystyle == "player" then fontsize = 36 elseif f.mystyle == "target" then fontsize =14 elseif f.mystyle == "raid" or f.mystyle == "party" then fontsize = 15 else fontsize = 14 end local name = lib.gen_fontstring(f.Health, cfg.font, retVal(f,15,15,15), "THINOUTLINE") if f.mystyle == "player" then name:SetPoint("RIGHT", f.Health, "RIGHT", 0, 0) name:SetJustifyH("RIGHT") elseif f.mystyle == "raid" or f.mystyle == "party" then name:SetPoint("LEFT", f.Health, "LEFT", 0, 4) name:SetJustifyH("LEFT") elseif f.mystyle == "pet" then name:SetPoint("LEFT", f.Health, "TOPLEFT", 2, -4) name:SetJustifyH("LEFT") else name:SetPoint("LEFT", f.Health, "TOPLEFT", 6, 0) name:SetJustifyH("LEFT") end local hpval = lib.gen_fontstring(f.Health, cfg.font, fontsize, "THINOUTLINE") if f.mystyle == "player" then hpval:SetPoint("LEFT", f.Health, "LEFT", 2, -1) hpval:SetJustifyH("LEFT") elseif f.mystyle == "raid" or f.mystyle == "party" then hpval:SetPoint("RIGHT", f.Health, "RIGHT", 6, -8) hpval:SetJustifyH("LEFT") elseif f.mystyle == "focus" or f.mystyle == "focustarget" then hpval:SetPoint("RIGHT", f.Health, "RIGHT", 2, -6) hpval:SetJustifyH("LEFT") --elseif f.mystyle == "target" or f.mystyle == "pet" then --hpval:Hide() else hpval:SetPoint("RIGHT", f.Health, "TOPRIGHT", retVal(f,2,2,-3), retVal(f,-18,-14,-17)) end if f.mystyle == "player" then name:SetPoint("RIGHT", f, "RIGHT", 10, 6) --elseif f.mystyle == "raid" or f.mystyle == "party" then -- name:SetPoint("CENTER", f, "CENTER", 0, 6) elseif f.mystyle == "target" or f.mystyle == "pet" then name:SetPoint("RIGHT", f, "RIGHT", 0, -12) else name:SetPoint("RIGHT", f, "RIGHT", 0, 0) end if f.mystyle == "player" then f:Tag(name, "[fail:afkdnd]") elseif f.mystyle == "target" then f:Tag(name, "[fail:level] [fail:color][name][fail:afkdnd]") elseif f.mystyle == "raid" or f.mystyle == "party" then f:Tag(name, "[fail:color][name][fail:afkdnd]") else f:Tag(name, "[fail:color][name]") end if f.mystyle == "player" then f:Tag(hpval, "[fail:color][curhp]") else f:Tag(hpval, retVal(f,"[fail:color][fail:hp]","[fail:color][fail:hp]","[fail:color][fail:raidhp]")) end local level if f.mystyle == "player" then level = lib.gen_fontstring(f.Health, cfg.font, fontsize/2, "THINOUTLINE") elseif f.mystyle == "target" then level = lib.gen_fontstring(f.Health, cfg.font, 18, "THINOUTLINE") end if f.mystyle == "player" and cfg.ShowPlayerName then level:SetPoint("TOPRIGHT", f.Health, "TOPRIGHT", 0, 10) level:SetJustifyH("RIGHT") elseif f.mystyle =="target" then level:SetPoint("RIGHT", f, "RIGHT", 8, 16) level:SetJustifyH("RIGHT") end if f.mystyle == "player" and cfg.ShowPlayerName then f:Tag(level, "[fail:level] [fail:color][name]") elseif f.mystyle =="target" then f:Tag(level, "[fail:pp]") end end --gen powerbar func lib.gen_ppbar = function(f) --statusbar local s = CreateFrame("StatusBar", nil, f) s:SetStatusBarTexture(cfg.powerbar_texture) fixStatusbar(s) if f.mystyle == "player" or f.mystyle == "pet" then s:SetHeight(16) s:SetWidth(f:GetWidth()) s:SetPoint("TOP",f,"TOP",8,0) else s:SetHeight(retVal(f,16,14,10)) s:SetWidth(f:GetWidth()) s:SetPoint("TOP",f,"TOP",6,0) end s:SetFrameLevel(1) --helper local h = CreateFrame("Frame", nil, s) h:SetFrameLevel(0) h:SetPoint("TOPLEFT",-5,5) h:SetPoint("BOTTOMRIGHT",5,-5) lib.gen_backdrop(h) --bg local b = s:CreateTexture(nil, "BACKGROUND") b:SetTexture(cfg.powerbar_texture) b:SetAllPoints(s) --arrow if f.mystyle == "player" then s.arrow = s:CreateTexture(nil, "OVERLAY") s.arrow:SetTexture([[Interface\Addons\oUF_Fail\media\textureArrow]]) s.arrow:SetSize(16,16) s.arrow:SetPoint("BOTTOM", s:GetStatusBarTexture(), "RIGHT", 1, 8) fixTex(s.arrow) local powa = lib.gen_fontstring(f.Health, cfg.font, 16, "OUTLINE") powa:SetPoint("RIGHT", s.arrow, "LEFT", 6, -8) powa:SetJustifyH("RIGHT") f:Tag(powa, "[fail:pp]") end f.Power = s f.Power.bg = b end --gen combat and LFD icons lib.gen_InfoIcons = function(f) local h = CreateFrame("Frame",nil,f) h:SetAllPoints(f) h:SetFrameLevel(10) --combat icon if f.mystyle == 'player' then f.Combat = h:CreateTexture(nil, 'OVERLAY') f.Combat:SetSize(16,16) f.Combat:SetPoint('LEFT', -4, -16) f.Combat:SetTexture([[Interface\Addons\oUF_Fail\media\combat]]) end -- rest icon if f.mystyle == 'player' and UnitLevel("Player") < 85 then f.Resting = h:CreateTexture(nil, 'OVERLAY') f.Resting:SetSize(18,18) f.Resting:SetPoint('TOPLEFT', 0, -2) f.Resting:SetTexture([[Interface\Addons\oUF_Fail\media\resting]]) f.Resting:SetAlpha(0.75) end --Leader icon li = h:CreateTexture(nil, "OVERLAY") li:SetPoint("TOPLEFT", f, -4, 0) li:SetSize(16,16) f.Leader = li --Assist icon ai = h:CreateTexture(nil, "OVERLAY") ai:SetPoint("TOPLEFT", f, 0, 8) ai:SetSize(12,12) f.Assistant = ai --ML icon local ml = h:CreateTexture(nil, 'OVERLAY') ml:SetSize(16,16) ml:SetPoint('LEFT', f.Leader, 'RIGHT') f.MasterLooter = ml end -- LFG Role Indicator lib.gen_LFDRole = function(f) local lfdi = lib.gen_fontstring(f.Health, cfg.smallfont, 10, "THINOUTLINE") lfdi:SetPoint('BOTTOM', f.Health, 'TOP', 0, 4) f:Tag(lfdi, "[fail:lfdrole]") end -- phase icon lib.addPhaseIcon = function(self) local picon = self.Health:CreateTexture(nil, 'OVERLAY') picon:SetPoint('TOPRIGHT', self, 'TOPRIGHT', 40, 8) picon:SetSize(16, 16) self.PhaseIcon = picon end -- quest icon lib.addQuestIcon = function(self) local qicon = self.Health:CreateTexture(nil, 'OVERLAY') qicon:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 8) qicon:SetSize(16, 16) self.QuestIcon = qicon end --gen raid mark icons lib.gen_RaidMark = function(f) local h = CreateFrame("Frame", nil, f) h:SetAllPoints(f) h:SetFrameLevel(10) h:SetAlpha(0.8) local ri = h:CreateTexture(nil,'OVERLAY',h) ri:SetPoint("CENTER", f.Health, "BOTTOM", -135, 18) ri:SetTexture([[Interface\Addons\oUF_Fail\media\raidicons.blp]]) local size = retVal(f, 36, 24, 18) ri:SetSize(size, size) f.RaidIcon = ri end --gen hilight texture lib.gen_highlight = function(f) local OnEnter = function(f) UnitFrame_OnEnter(f) f.Highlight:Show() end local OnLeave = function(f) UnitFrame_OnLeave(f) f.Highlight:Hide() end f:SetScript("OnEnter", OnEnter) f:SetScript("OnLeave", OnLeave) local hl = f.Health:CreateTexture(nil, "OVERLAY") hl:SetAllPoints(f.Health) hl:SetTexture(cfg.statusbar_texture) hl:SetVertexColor(.5,.5,.5,.1) hl:SetBlendMode("ADD") hl:Hide() f.Highlight = hl end -- Create Target Border function lib.CreateTargetBorder(self) self.TargetBorder = self.Health:CreateTexture("BACKGROUND", nil, self) self.TargetBorder:SetPoint("TOPLEFT", self.Health, "TOPLEFT", -24, 24) self.TargetBorder:SetPoint("BOTTOMRIGHT", self.Health, "BOTTOMRIGHT", 24, -24) self.TargetBorder:SetTexture([[Interface\Addons\oUF_Fail\media\target]]) self.TargetBorder:SetVertexColor(1.0, 1.0, 0.1,0.6) self.TargetBorder:SetBlendMode("ADD") self.TargetBorder:Hide() end -- Raid Frames Target Highlight Border function lib.ChangedTarget(self, event, unit) if UnitIsUnit('target', self.unit) then self.TargetBorder:Show() else self.TargetBorder:Hide() end end -- Create Raid Threat Status Border function lib.CreateThreatBorder(self) local glowBorder = {edgeFile = cfg.backdrop_edge_texture, edgeSize = 5} self.Thtborder = CreateFrame("Frame", nil, self) self.Thtborder:SetPoint("TOPLEFT", self, "TOPLEFT", -8, 9) self.Thtborder:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 9, -8) self.Thtborder:SetBackdrop(glowBorder) self.Thtborder:SetFrameLevel(1) self.Thtborder:Hide() end -- Raid Frames Threat Highlight function lib.UpdateThreat(self, event, unit) if (self.unit ~= unit) then return end local status = UnitThreatSituation(unit) unit = unit or self.unit if status and status > 1 then local r, g, b = GetThreatStatusColor(status) self.Thtborder:Show() self.Thtborder:SetBackdropBorderColor(r, g, b, 1) else self.Thtborder:SetBackdropBorderColor(r, g, b, 0) self.Thtborder:Hide() end end --gen castbar local PostCastStart = function(castbar, unit) if unit ~= 'player' then if castbar.interrupt then castbar.Backdrop:SetBackdropBorderColor(1, .9, .4) castbar.Backdrop:SetBackdropColor(1, .9, .4) else castbar.Backdrop:SetBackdropBorderColor(0, 0, 0) castbar.Backdrop:SetBackdropColor(0, 0, 0) end end end local CustomTimeText = function(castbar, duration) if castbar.casting then castbar.Time:SetFormattedText("%.1f / %.1f", duration, castbar.max) elseif castbar.channeling then castbar.Time:SetFormattedText("%.1f / %.1f", castbar.max - duration, castbar.max) end end --gen castbar lib.gen_castbar = function(f) if not cfg.Castbars then return end local cbColor = {95/255, 182/255, 255/255} local s = CreateFrame("StatusBar", "oUF_failCastbar"..f.mystyle, f) s:SetHeight(16) if f.mystyle == "focus" then s:SetWidth(f:GetWidth()*2 - 30) elseif f.mystyle == "player" then s:SetWidth(f:GetWidth()-21) elseif f.mystyle == "pet" then s:SetWidth(f:GetWidth()-23) else s:SetWidth(f:GetWidth()+50) end if f.mystyle == "player" then s:SetPoint("BOTTOM", f, "TOP", 20, 13) elseif f.mystyle == "target" then s:SetPoint("CENTER",f,"TOP",0,180) elseif f.mystyle == "targettarget" then s:SetPoint("BOTTOM",f,"TOP",0,0) else s:SetPoint("TOPLEFT",f,"BOTTOMLEFT",30,-15) end s:SetStatusBarTexture(cfg.statusbar_texture) s:SetStatusBarColor(95/255, 182/255, 255/255,1) s:SetFrameLevel(9) --color s.CastingColor = cbColor s.CompleteColor = {20/255, 208/255, 0/255} s.FailColor = {255/255, 12/255, 0/255} s.ChannelingColor = cbColor --helper local h = CreateFrame("Frame", nil, s) h:SetFrameLevel(0) h:SetPoint("TOPLEFT",-5,5) h:SetPoint("BOTTOMRIGHT",5,-5) lib.gen_castbackdrop(h) --spark sp = s:CreateTexture(nil, "OVERLAY") sp:SetTexture(spark) sp:SetBlendMode("ADD") sp:SetVertexColor(1, 1, 1, 1) sp:SetHeight(s:GetHeight()*2.5) sp:SetWidth(s:GetWidth()/18) --spell text local txt = lib.gen_fontstring(s, cfg.font, 10, "THINOUTLINE") if f.mystyle == "pet" then txt:Hide() else txt:SetPoint("LEFT", 2, 10) txt:SetJustifyH("LEFT") end --time local t = lib.gen_fontstring(s, cfg.font, 10, 'THINOUTLINE') if f.mystyle == "pet" then t:Hide() txt:Hide() else t:SetPoint("RIGHT", -2, 0) txt:SetPoint("RIGHT", f, "RIGHT", 0, 0) end --icon local i = s:CreateTexture(nil, "ARTWORK") i:SetSize(24,24) i:SetPoint("BOTTOMRIGHT", s, "BOTTOMLEFT", -6, 0) i:SetTexCoord(0.1, 0.9, 0.1, 0.9) --helper2 for icon local h2 = CreateFrame("Frame", nil, s) h2:SetFrameLevel(0) h2:SetPoint("TOPLEFT",i,"TOPLEFT",-5,5) h2:SetPoint("BOTTOMRIGHT",i,"BOTTOMRIGHT",5,-5) lib.gen_backdrop(h2) --if f.mystyle == "player" then --latency (only for player unit) --local z = s:CreateTexture(nil,"OVERLAY") --z:SetTexture(cfg.statusbar_texture) --z:SetVertexColor(1,0.1,0,.6) --z:SetPoint("TOPRIGHT") --z:SetPoint("BOTTOMRIGHT") --s:SetFrameLevel(1) --s.SafeZone = z -- custom latency display --local l = lib.gen_fontstring(s, cfg.font, 10, "THINOUTLINE") --l:SetPoint("CENTER", -2, 17) --l:SetJustifyH("RIGHT") --l:Hide() --s.Lag = l --f:RegisterEvent("UNIT_SPELLCAST_SENT", cast.OnCastSent) --end s.OnUpdate = cast.OnCastbarUpdate s.PostCastStart = cast.PostCastStart s.PostChannelStart = cast.PostCastStart s.PostCastStop = cast.PostCastStop s.PostChannelStop = cast.PostChannelStop s.PostCastFailed = cast.PostCastFailed s.PostCastInterrupted = cast.PostCastFailed f.Castbar = s f.Castbar.Text = txt f.Castbar.Time = t f.Castbar.Icon = i f.Castbar.Spark = sp end -- mirror castbar! lib.gen_mirrorcb = function(f) for _, bar in pairs({'MirrorTimer1','MirrorTimer2','MirrorTimer3',}) do for i, region in pairs({_G[bar]:GetRegions()}) do if (region.GetTexture and region:GetTexture() == 'SolidTexture') then region:Hide() end end _G[bar..'Border']:Hide() _G[bar]:SetParent(UIParent) _G[bar]:SetScale(1) _G[bar]:SetHeight(16) _G[bar]:SetWidth(280) _G[bar]:SetBackdropColor(.1,.1,.1) _G[bar..'Background'] = _G[bar]:CreateTexture(bar..'Background', 'BACKGROUND', _G[bar]) _G[bar..'Background']:SetTexture(cfg.statusbar_texture) _G[bar..'Background']:SetAllPoints(bar) _G[bar..'Background']:SetVertexColor(.15,.15,.15,.75) _G[bar..'Text']:SetFont(cfg.font, 14, "THINOUTLINE") _G[bar..'Text']:ClearAllPoints() _G[bar..'Text']:SetPoint('CENTER', MirrorTimer1StatusBar, 0, 1) _G[bar..'StatusBar']:SetAllPoints(_G[bar]) --glowing borders local h = CreateFrame("Frame", nil, _G[bar]) h:SetFrameLevel(0) h:SetPoint("TOPLEFT",-5,5) h:SetPoint("BOTTOMRIGHT",5,-5) lib.gen_backdrop(h) end end -- Post Create Icon Function local myPostCreateIcon = function(self, button) self.showDebuffType = true self.disableCooldown = true button.cd.noOCC = true button.cd.noCooldownCount = true -- button.icon:SetTexCoord(0,1,0,1) button.icon:SetTexCoord(.07, .93, .07, .93) button.icon:SetPoint("TOPLEFT", button, "TOPLEFT", 0, 0) button.icon:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", 0, 0) button.overlay:SetTexture(cfg.debuffBorder) button.overlay:SetTexCoord(0,1,0,1) button.overlay.Hide = function(self) self:SetVertexColor(0.3, 0.3, 0.3) end button.time = lib.gen_fontstring(button, cfg.smallfont, 12, "OUTLINE") button.time:SetPoint("BOTTOM", button, 2, -6) button.time:SetJustifyH('CENTER') button.time:SetVertexColor(1,1,1) button.count = lib.gen_fontstring(button, cfg.smallfont, 15, "OUTLINE") button.count:ClearAllPoints() button.count:SetPoint("TOPRIGHT", button, 5, 3) button.count:SetJustifyH('RIGHT') button.count:SetVertexColor(1,1,1) -- helper local h = CreateFrame("Frame", nil, button) h:SetFrameLevel(0) h:SetPoint("TOPLEFT",-5,5) h:SetPoint("BOTTOMRIGHT",5,-5) lib.gen_backdrop(h) end -- Post Update Icon Function local myPostUpdateIcon = function(self, unit, icon, index, offset, filter, isDebuff) local _, _, _, _, _, duration, expirationTime, unitCaster, _ = UnitAura(unit, index, icon.filter) if duration and duration > 0 then icon.time:Show() icon.timeLeft = expirationTime icon:SetScript("OnUpdate", CreateBuffTimer) else icon.time:Hide() icon.timeLeft = math.huge icon:SetScript("OnUpdate", nil) end -- Desaturate non-Player Debuffs if(icon.debuff) then if(unit == "target") then if (unitCaster == 'player' or unitCaster == 'vehicle') then icon.icon:SetDesaturated(false) elseif(not UnitPlayerControlled(unit)) then -- If Unit is Player Controlled don't desaturate debuffs icon:SetBackdropColor(0, 0, 0) icon.overlay:SetVertexColor(0.3, 0.3, 0.3) icon.icon:SetDesaturated(true) end end end -- Right Click Cancel Buff/Debuff icon:SetScript('OnMouseUp', function(self, mouseButton) if mouseButton == 'RightButton' then CancelUnitBuff('player', index) end end) icon.first = true end local FormatTime = function(s) local day, hour, minute = 86400, 3600, 60 if s >= day then return format("%dd", floor(s/day + 0.5)), s % day elseif s >= hour then return format("%dh", floor(s/hour + 0.5)), s % hour elseif s >= minute then if s <= minute * 5 then return format("%d:%02d", floor(s/60), s % minute), s - floor(s) end return format("%dm", floor(s/minute + 0.5)), s % minute elseif s >= minute / 12 then return floor(s + 0.5), (s * 100 - floor(s * 100))/100 end return format("%.1f", s), (s * 100 - floor(s * 100))/100 end -- Create Buff/Debuff Timer Function function CreateBuffTimer(self, elapsed) self.elapsed = (self.elapsed or 0) + elapsed if self.elapsed >= 0.1 then if not self.first then self.timeLeft = self.timeLeft - self.elapsed else self.timeLeft = self.timeLeft - GetTime() self.first = false end if self.timeLeft > 0 and self.timeLeft <= 60*15 then -- Show time between 0 and 15 min local time = FormatTime(self.timeLeft) self.time:SetText(time) if self.timeLeft >= 6 and self.timeLeft <= 60*5 then -- if Between 5 min and 6sec self.time:SetTextColor(0.95,0.95,0.95) elseif self.timeLeft > 3 and self.timeLeft < 6 then -- if Between 6sec and 3sec self.time:SetTextColor(0.95,0.70,0) elseif self.timeLeft <= 3 then -- Below 3sec self.time:SetTextColor(0.9, 0.05, 0.05) else self.time:SetTextColor(0.95,0.95,0.95) -- Fallback Color end else self.time:Hide() end self.elapsed = 0 end end -- Generates the Buffs lib.createBuffs = function(f) b = CreateFrame("Frame", nil, f) b.onlyShowPlayer = cfg.buffsOnlyShowPlayer if f.mystyle == "target" then b:SetPoint("TOPLEFT", f, "TOPRIGHT", 12, 0) b.initialAnchor = "TOPLEFT" b["growth-x"] = "RIGHT" b["growth-y"] = "DOWN" b.size = 24 b.num = 3 b.spacing = 6 b:SetHeight((b.size+b.spacing)*4) --b:SetWidth(f:GetWidth()) Default Value b:SetWidth(((b.size+b.spacing)*4)-b.spacing) elseif f.mystyle == "player" then b:SetPoint("TOPRIGHT", UIParent, "TOPRIGHT", -5, -5) b.initialAnchor = "TOPRIGHT" b["growth-x"] = "LEFT" b["growth-y"] = "DOWN" b.size = 36 b.num = 40 b.spacing = 5 b:SetHeight((b.size+b.spacing)*4) b:SetWidth(f:GetWidth()*2) else b.num = 0 end b.PostCreateIcon = myPostCreateIcon b.PostUpdateIcon = myPostUpdateIcon f.Buffs = b end -- Generates the Debuffs lib.createDebuffs = function(f) b = CreateFrame("Frame", nil, f) b.size = 28 b.num = 20 b.onlyShowPlayer = cfg.debuffsOnlyShowPlayer b.spacing = 6 b:SetHeight((b.size+b.spacing)*5) b:SetWidth(f:GetWidth()) if(playerClass == "ROGUE" or playerClass == "DRUID") then b:SetPoint("BOTTOMLEFT", f, "TOPLEFT", 0, 17) else b:SetPoint("BOTTOMLEFT", f, "TOPLEFT", 0, 6) end b.initialAnchor = "BOTTOMLEFT" b["growth-x"] = "RIGHT" b["growth-y"] = "UP" b.PostCreateIcon = myPostCreateIcon b.PostUpdateIcon = myPostUpdateIcon f.Debuffs = b end -- raid post update lib.PostUpdateRaidFrame = function(Health, unit, min, max) local disconnnected = not UnitIsConnected(unit) local dead = UnitIsDead(unit) local ghost = UnitIsGhost(unit) if disconnnected or dead or ghost then Health:SetValue(max) if(disconnnected) then Health:SetStatusBarColor(0,0,0,0.6) elseif(ghost) then Health:SetStatusBarColor(1,1,1,0.6) elseif(dead) then Health:SetStatusBarColor(1,0,0,0.7) end else Health:SetValue(min) if(unit == 'vehicle') then Health:SetStatusBarColor(22/255, 106/255, 44/255) end end if not UnitInRange(unit) then Health.bg2:SetVertexColor(.6, 0.3, 0.3,1) else Health.bg2:SetVertexColor(1, 0.1, 0.1,1) end end -- Eclipse Bar function local eclipseBarBuff = function(self, unit) if self.hasSolarEclipse then self.eBarBG:SetBackdropBorderColor(1,1,.5,.7) elseif self.hasLunarEclipse then self.eBarBG:SetBackdropBorderColor(.2,.2,1,.7) else self.eBarBG:SetBackdropBorderColor(0,0,0,1) end end lib.addEclipseBar = function(self) if playerClass ~= "DRUID" then return end local eclipseBar = CreateFrame('Frame', nil, self) eclipseBar:SetPoint('TOPLEFT', self.Health, 'BOTTOMLEFT', 0, -6) eclipseBar:SetHeight(4) eclipseBar:SetWidth(self.Health:GetWidth()) eclipseBar:SetFrameLevel(4) local h = CreateFrame("Frame", nil, eclipseBar) h:SetPoint("TOPLEFT",-5,5) h:SetPoint("BOTTOMRIGHT",5,-5) lib.gen_backdrop(h) eclipseBar.eBarBG = h local lunarBar = CreateFrame('StatusBar', nil, eclipseBar) lunarBar:SetPoint('LEFT', eclipseBar, 'LEFT', 0, 0) lunarBar:SetSize(eclipseBar:GetWidth(), eclipseBar:GetHeight()) lunarBar:SetStatusBarTexture(cfg.statusbar_texture) lunarBar:SetStatusBarColor(0, .1, .7) lunarBar:SetFrameLevel(5) local solarBar = CreateFrame('StatusBar', nil, eclipseBar) solarBar:SetPoint('LEFT', lunarBar:GetStatusBarTexture(), 'RIGHT', 0, 0) solarBar:SetSize(eclipseBar:GetWidth(), eclipseBar:GetHeight()) solarBar:SetStatusBarTexture(cfg.statusbar_texture) solarBar:SetStatusBarColor(1,1,.13) solarBar:SetFrameLevel(5) local EBText = lib.gen_fontstring(solarBar, cfg.font, 10, "OUTLINE") EBText:SetPoint('CENTER', eclipseBar, 'CENTER', 0, 0) self:Tag(EBText, '[pereclipse]') eclipseBar.SolarBar = solarBar eclipseBar.LunarBar = lunarBar self.EclipseBar = eclipseBar self.EclipseBar.PostUnitAura = eclipseBarBuff end -- SoulShard bar lib.genShards = function(self) if playerClass ~= "WARLOCK" then return end local ssOverride = function(self, event, unit, powerType) if(self.unit ~= unit or (powerType and powerType ~= "SOUL_SHARDS")) then return end local ss = self.SoulShards local num = UnitPower(unit, SPELL_POWER_SOUL_SHARDS) for i = 1, SHARD_BAR_NUM_SHARDS do if(i <= num) then ss[i]:SetAlpha(1) else ss[i]:SetAlpha(0.2) end end end local barFrame = CreateFrame("Frame", nil, self) barFrame:SetPoint("TOPLEFT", self, "BOTTOMLEFT", 0, -5) barFrame:SetHeight(6) barFrame:SetWidth(self:GetWidth()) barFrame:SetFrameLevel(4) for i= 1, 3 do local shard = CreateFrame("StatusBar", nil, barFrame) shard:SetSize((self.Health:GetWidth() / 3)-4, 6) shard:SetStatusBarTexture(cfg.statusbar_texture) shard:SetStatusBarColor(.86,.44, 1) shard:SetFrameLevel(4) local h = CreateFrame("Frame", nil, shard) h:SetFrameLevel(1) h:SetPoint("TOPLEFT",-5,5) h:SetPoint("BOTTOMRIGHT",5,-5) lib.gen_totemback(h) if (i == 1) then shard:SetPoint("TOPLEFT", self.Health, "BOTTOMLEFT", 0, -5) else shard:SetPoint("TOPLEFT", barFrame[i-1], "TOPRIGHT", 6, 0) end barFrame[i] = shard end self.SoulShards = barFrame self.SoulShards.Override = ssOverride end -- HolyPowerbar lib.genHolyPower = function(self) if playerClass ~= "PALADIN" then return end local hpOverride = function(self, event, unit, powerType) if(self.unit ~= unit or (powerType and powerType ~= "HOLY_POWER")) then return end local hp = self.HolyPower if(hp.PreUpdate) then hp:PreUpdate(unit) end local num = UnitPower(unit, SPELL_POWER_HOLY_POWER) for i = 1, MAX_HOLY_POWER do if(i <= num) then hp[i]:SetAlpha(1) else hp[i]:SetAlpha(0.2) end end end local barFrame = CreateFrame("Frame", nil, self) barFrame:SetPoint("TOPLEFT", self, "BOTTOMLEFT", 0, -5) barFrame:SetHeight(6) barFrame:SetWidth(self:GetWidth()) barFrame:SetFrameLevel(4) for i = 1, 3 do local holyShard = CreateFrame("StatusBar", self:GetName().."_Holypower"..i, self) holyShard:SetHeight(6) holyShard:SetWidth((self.Health:GetWidth() / 3)-4, 6) holyShard:SetStatusBarTexture(cfg.statusbar_texture) holyShard:SetStatusBarColor(.9,.95,.33) holyShard:SetFrameLevel(4) local h = CreateFrame("Frame", nil, holyShard) h:SetFrameLevel(1) h:SetPoint("TOPLEFT",-5,5) h:SetPoint("BOTTOMRIGHT",5,-5) lib.gen_totemback(h) if (i == 1) then holyShard:SetPoint("TOPLEFT", self.Health, "BOTTOMLEFT", 0, -5) else holyShard:SetPoint("TOPLEFT", barFrame[i-1], "TOPRIGHT", 6, 0) end barFrame[i] = holyShard end self.HolyPower = barFrame self.HolyPower.Override = hpOverride end -- runebar lib.genRunes = function(self) if playerClass ~= "DEATHKNIGHT" then return end local runeFrame = CreateFrame("Frame", nil, self) runeFrame:SetPoint("TOPLEFT", self, "BOTTOMLEFT", 0, -5) runeFrame:SetHeight(4) runeFrame:SetWidth(self:GetWidth()) runeFrame:SetFrameLevel(4) for i= 1, 6 do local rune = CreateFrame("StatusBar", nil, runeFrame) rune:SetSize((self.Health:GetWidth() / 6)-5, 7) rune:SetStatusBarTexture(cfg.statusbar_texture) rune:SetFrameLevel(4) local h = CreateFrame("Frame", nil, rune) h:SetFrameLevel(1) h:SetPoint("TOPLEFT",-5,5) h:SetPoint("BOTTOMRIGHT",5,-5) lib.gen_totemback(h) if (i == 1) then rune:SetPoint("TOPLEFT", self.Health, "BOTTOMLEFT", 0, -6) else rune:SetPoint("TOPLEFT", runeFrame[i-1], "TOPRIGHT", 6, 0) end runeFrame[i] = rune end self.Runes = runeFrame end -- ReadyCheck lib.ReadyCheck = function(self) if cfg.RCheckIcon then rCheck = self.Health:CreateTexture(nil, "OVERLAY") rCheck:SetSize(14, 14) rCheck:SetPoint("BOTTOMLEFT", self.Health, "TOPRIGHT", -13, -12) self.ReadyCheck = rCheck end end -- raid debuffs lib.raidDebuffs = function(f) if cfg.showRaidDebuffs then local raid_debuffs = { debuffs = { -- Any Zone ["Viper Sting"] = 12, -- Viper Sting ["Wound Poison"] = 9, -- Wound Poison ["Mortal Strike"] = 8, -- Mortal Strike ["Furious Attacks"] = 8, -- Furious Attacks ["Aimed Shot"] = 8, -- Aimed Shot ["Counterspell"] = 10, -- Counterspell ["Blind"] = 10, -- Blind ["Cyclone"] = 10, -- Cyclone ["Hex"] = 7, -- Hex ["Polymorph"] = 7, -- Polymorph ["Entangling Roots"] = 7, -- Entangling Roots ["Frost Nova"] = 7, -- Frost Nova ["Freezing Trap"] = 7, -- Freezing Trap ["Crippling Poison"] = 6, -- Crippling Poison ["Bash"] = 5, -- Bash ["Cheap Shot"] = 5, -- Cheap Shot ["Kidney Shot"] = 5, -- Kidney Shot ["Throwdown"] = 5, -- Throwdown ["Sap"] = 5, -- Sap ["Hamstring"] = 5, -- Hamstring ["Wing Clip"] = 5, -- Wing Clip ["Fear"] = 3, -- Fear ["Psychic Scream"] = 3, -- Psychic Scream ["Howl of Terror"] = 3, -- Howl of Terror ["Intimidating Shout"] = 3, -- Intimidating Shout }, } local instDebuffs = {} local instances = raid_debuffs.instances local getzone = function() local zone = GetInstanceInfo() if instances[zone] then instDebuffs = instances[zone] else instDebuffs = {} end end local debuffs = raid_debuffs.debuffs local CustomFilter = function(icons, ...) local _, icon, name, _, _, _, dtype = ... if instDebuffs[name] then icon.priority = instDebuffs[name] return true elseif debuffs[name] then icon.priority = debuffs[name] return true else icon.priority = 0 end end local dbsize = 18 local debuffs = CreateFrame("Frame", nil, f) debuffs:SetWidth(dbsize) debuffs:SetHeight(dbsize) debuffs:SetPoint("TOPRIGHT", -10, 3) debuffs.size = dbsize debuffs.CustomFilter = CustomFilter f.raidDebuffs = debuffs end end -- oUF_HealPred lib.HealPred = function(self) if not cfg.ShowIncHeals then return end local mhpb = CreateFrame('StatusBar', nil, self.Health) mhpb:SetPoint('TOPLEFT', self.Health:GetStatusBarTexture(), 'TOPRIGHT', 0, 0) mhpb:SetPoint('BOTTOMLEFT', self.Health:GetStatusBarTexture(), 'BOTTOMRIGHT', 0, 0) mhpb:SetWidth(self:GetWidth()) mhpb:SetStatusBarTexture(cfg.statusbar_texture) mhpb:SetStatusBarColor(1, 1, 1, 0.4) mhpb:SetFrameLevel(1) local ohpb = CreateFrame('StatusBar', nil, self.Health) ohpb:SetPoint('TOPLEFT', mhpb:GetStatusBarTexture(), 'TOPRIGHT', 0, 0) ohpb:SetPoint('BOTTOMLEFT', mhpb:GetStatusBarTexture(), 'BOTTOMRIGHT', 0, 0) ohpb:SetWidth(self:GetWidth()) ohpb:SetStatusBarTexture(cfg.statusbar_texture) ohpb:SetStatusBarColor(1, 1, 1, 0.4) mhpb:SetFrameLevel(1) self.HealPrediction = { myBar = mhpb, otherBar = ohpb, maxOverflow = 1, } end -- Combo points lib.RogueComboPoints = function(self) if(playerClass == "ROGUE" or playerClass == "DRUID") then local barFrame = CreateFrame("Frame", nil, self) barFrame:SetPoint("TOPLEFT", self, "BOTTOMLEFT", 0, -5) barFrame:SetHeight(4) barFrame:SetWidth(self:GetWidth()) barFrame:SetFrameLevel(4) for i = 1, MAX_COMBO_POINTS do local point = CreateFrame("StatusBar", nil, barFrame) point:SetSize((self.Health:GetWidth() / 5)-5, 6) if i > 1 then point:SetPoint("LEFT", point[i - 1], "RIGHT") end point:SetStatusBarTexture(cfg.statusbar_texture) point:SetStatusBarColor(1.0, 0.9, 0) local h = CreateFrame("Frame", nil, point) h:SetFrameLevel(1) h:SetPoint("TOPLEFT",-5,5) h:SetPoint("BOTTOMRIGHT",5,-5) lib.gen_totemback(h) if (i == 1) then point:SetPoint('BOTTOMLEFT', self.Health, 'TOPLEFT', 0, 12) else point:SetPoint("TOPLEFT", barFrame[i-1], "TOPRIGHT", 6, 0) end barFrame[i] = point end self.CPoints = barFrame self.CPoints.unit = "player" end end -- Addons/Plugins ------------------------------------------- -- Totem timer support (requires oUF_boring_totembar) lib.gen_TotemBar = function(self) if ( playerClass == "SHAMAN" and IsAddOnLoaded("oUF_boring_totembar") ) then local TotemBar = CreateFrame("Frame", nil, self) TotemBar:SetPoint("TOP", self, "BOTTOM", 0, -4) TotemBar:SetWidth(self:GetWidth()) TotemBar:SetHeight(8) TotemBar.Destroy = true TotemBar.AbbreviateNames = true TotemBar.UpdateColors = true oUF.colors.totems = { { 233/255, 46/255, 16/255 }, -- fire { 173/255, 217/255, 25/255 }, -- earth { 35/255, 127/255, 255/255 }, -- water { 178/255, 53/255, 240/255 } -- air } for i = 1, 4 do local t = CreateFrame("Frame", nil, TotemBar) t:SetHeight(8) t:SetWidth(self.Health:GetWidth()/4 - 5) local bar = CreateFrame("StatusBar", nil, t) bar:SetAllPoints(t) bar:SetStatusBarTexture(cfg.statusbar_texture) t.StatusBar = bar local h = CreateFrame("Frame", nil, t) h:SetFrameLevel(1) h:SetPoint("TOPLEFT",-5,5) h:SetPoint("BOTTOMRIGHT",5,-5) lib.gen_totemback(h) if (i == 1) then t:SetPoint("TOPLEFT", self.Health, "BOTTOMLEFT", 0, -5) else t:SetPoint('TOPLEFT', TotemBar[i-1], "TOPRIGHT", 6, 0) end t.bg = t:CreateTexture(nil, "BORDER") t.bg:SetAllPoints(t) t.bg:SetTexture(cfg.backdrop_texture) t.bg.multiplier = 0.15 t.bg:SetAlpha(0.6) local text = lib.gen_fontstring(t, cfg.smallfont, 10, "THINOUTLINE") text:SetPoint("CENTER",t,"BOTTOM",0,-8) text:SetFontObject"GameFontNormal" t.Text = text TotemBar[i] = t end self.TotemBar = TotemBar end end -- oUF_DebuffHighlight lib.debuffHighlight = function(self) if cfg.enableDebuffHighlight then local dbh = self.Health:CreateTexture(nil, "OVERLAY") dbh:SetAllPoints(self.Health) dbh:SetTexture(cfg.debuffhighlight_texture) dbh:SetBlendMode("ADD") dbh:SetVertexColor(0,0,0,0) -- set alpha to 0 to hide the texture self.DebuffHighlight = dbh self.DebuffHighlightAlpha = 0.5 self.DebuffHighlightFilter = true end end -- AuraWatch local AWPostCreateIcon = function(AWatch, icon, spellID, name, self) icon.cd:SetReverse() local count = lib.gen_fontstring(icon, cfg.smallfont, 12, "OUTLINE") count:SetPoint("CENTER", icon, "BOTTOM", 3, 3) icon.count = count local h = CreateFrame("Frame", nil, icon) h:SetFrameLevel(4) h:SetPoint("TOPLEFT",-3,3) h:SetPoint("BOTTOMRIGHT",3,-3) lib.gen_backdrop(h) end lib.createAuraWatch = function(self, unit) if cfg.showAuraWatch then local auras = {} local spellIDs = { DEATHKNIGHT = { }, DRUID = { 33763, -- Lifebloom 8936, -- Regrowth 774, -- Rejuvenation 48438, -- Wild Growth }, HUNTER = { 34477, -- Misdirection }, MAGE = { 54646, -- Focus Magic }, PALADIN = { 53563, -- Beacon of Light 25771, -- Forbearance }, PRIEST = { 17, -- Power Word: Shield 139, -- Renew 33076, -- Prayer of Mending 6788, -- Weakened Soul }, ROGUE = { 57934, -- Tricks of the Trade }, SHAMAN = { 974, -- Earth Shield 61295, -- Riptide }, WARLOCK = { 20707, -- Soulstone Resurrection }, WARRIOR = { 50720, -- Vigilance }, } auras.onlyShowPresent = true auras.anyUnit = true auras.PostCreateIcon = AWPostCreateIcon -- Set any other AuraWatch settings auras.icons = {} for i, sid in pairs(spellIDs[playerClass]) do local icon = CreateFrame("Frame", nil, self) icon.spellID = sid -- set the dimensions and positions icon:SetWidth(14) icon:SetHeight(14) icon:SetFrameLevel(5) icon:SetPoint("BOTTOMRIGHT", self, "BOTTOMLEFT", 12 * i, 5) auras.icons[sid] = icon end self.AuraWatch = auras end end -- oUF_CombatFeedback lib.gen_combat_feedback = function(f) if IsAddOnLoaded("oUF_CombatFeedback") then local h = CreateFrame("Frame", nil, f.Health) h:SetAllPoints(f.Health) h:SetFrameLevel(30) local cfbt = lib.gen_fontstring(h, cfg.font, 18, "THINOUTLINE") cfbt:SetPoint("CENTER", f.Health, "BOTTOM", 0, -1) cfbt.maxAlpha = 0.75 cfbt.ignoreEnergize = true f.CombatFeedbackText = cfbt end end -- oUF_WeaponEnchant (temporary weapon enchant icon) lib.gen_WeaponEnchant = function(self) if IsAddOnLoaded("oUF_WeaponEnchant") then self.Enchant = CreateFrame("Frame", nil, self) self.Enchant:SetSize(24, 52) self.Enchant:SetPoint("TOPLEFT", oUF_failPlayer.Health, "TOPRIGHT", 10, 14) self.Enchant.size = 20 self.Enchant.spacing = 6 self.Enchant.initialAnchor = "LEFT" self.Enchant["growth-y"] = "DOWN" self.Enchant:SetFrameLevel(10) self.PostCreateEnchantIcon = myPostCreateIcon self.PostUpdateEnchantIcon = myPostUpdateIcon end end -- oUF_Vengeance Support lib.gen_Vengeance = function(self) if IsAddOnLoaded("oUF_Vengeance") then --statusbar local v = CreateFrame("StatusBar", nil, self) v:SetWidth(self.Health:GetWidth()+6) v:SetHeight(6) v:SetPoint("TOPLEFT", self.Health, "BOTTOMLEFT", 0, -6) v:SetStatusBarTexture(cfg.statusbar_texture) v:SetStatusBarColor(1, 0.1, 0.1,1) -- helper local h = CreateFrame("Frame", nil, v) h:SetFrameLevel(1) h:SetPoint("TOPLEFT",-5,5) h:SetPoint("BOTTOMRIGHT",5,-5) lib.gen_backdrop(h) --bg local b = v:CreateTexture(nil, "BACKGROUND") b:SetTexture(cfg.statusbar_texture) b:SetAllPoints(v) b:SetVertexColor(0.44,0.44,0.44,0.8) -- text label v.Text = lib.gen_fontstring(v, cfg.smallfont, 10, "THINOUTLINE") v.Text:SetPoint("CENTER",v,"CENTER",0,0) v.Text:SetJustifyH("LEFT") self.Vengeance = v self.Vengeance.bg = b end end --hand the lib to the namespace for further usage ns.lib = lib