--[[ ############################################################################## _____/\\\\\\\\\\\____/\\\________/\\\__/\\\________/\\\__/\\\\\\\\\\\_ # ___/\\\/////////\\\_\/\\\_______\/\\\_\/\\\_______\/\\\_\/////\\\///__ # __\//\\\______\///__\//\\\______/\\\__\/\\\_______\/\\\_____\/\\\_____ # ___\////\\\__________\//\\\____/\\\___\/\\\_______\/\\\_____\/\\\_____ # ______\////\\\________\//\\\__/\\\____\/\\\_______\/\\\_____\/\\\_____ # _________\////\\\______\//\\\/\\\_____\/\\\_______\/\\\_____\/\\\_____ # __/\\\______\//\\\______\//\\\\\______\//\\\______/\\\______\/\\\_____ # _\///\\\\\\\\\\\/________\//\\\________\///\\\\\\\\\/____/\\\\\\\\\\\_# ___\///////////___________\///___________\/////////_____\///////////_# ############################################################################## S U P E R - V I L L A I N - U I By: Munglunch # ############################################################################## ########################################################## LOCALIZED LUA FUNCTIONS ########################################################## ]]-- --[[ GLOBALS ]]-- local _G = _G; local unpack = _G.unpack; local select = _G.select; local assert = _G.assert; local math = _G.math; local random = math.random; --[[ ########################################################## GET ADDON DATA ########################################################## ]]-- local SuperVillain, L = unpack(select(2, ...)); local MOD = SuperVillain.SVUnit if(not MOD) then return end; local _, ns = ... local oUF_SuperVillain = ns.oUF --[[ MUNGLUNCH's FASTER ASSERT FUNCTION ]]-- local assert = enforce; assert(oUF_SuperVillain, "SVUI was unable to locate oUF."); --[[ ########################################################## LOCALS ########################################################## ]]-- -- local MISSING_MODEL_FILE = [[Spells\Blackmagic_precast_base.m2]]; -- local MISSING_MODEL_FILE = [[Spells\Crow_baked.m2]]; -- local MISSING_MODEL_FILE = [[Spells\monsterlure01.m2]]; -- local MISSING_MODEL_FILE = [[interface\buttons\talktome_gears.m2]]; -- local MISSING_MODEL_FILE = [[creature\Ghostlyskullpet\ghostlyskullpet.m2]]; -- local MISSING_MODEL_FILE = [[creature\ghost\ghost.m2]]; local MISSING_MODEL_FILE = [[Spells\Monk_travelingmist_missile.m2]]; local HEALTH_ANIM_FILE = [[Interface\Addons\SVUI\assets\artwork\Unitframe\UNIT-HEALTH-ANIMATION]]; local ELITE_TOP = [[Interface\Addons\SVUI\assets\artwork\Unitframe\Border\ELITE-TOP]] local ELITE_BOTTOM = [[Interface\Addons\SVUI\assets\artwork\Unitframe\Border\ELITE-BOTTOM]] local ELITE_RIGHT = [[Interface\Addons\SVUI\assets\artwork\Unitframe\Border\ELITE-RIGHT]] local STUNNED_ANIM = [[Interface\Addons\SVUI\assets\artwork\Unitframe\UNIT-STUNNED]] local token = {[0] = "MANA", [1] = "RAGE", [2] = "FOCUS", [3] = "ENERGY", [6] = "RUNIC_POWER"} local Anim_OnUpdate = function(self) local parent = self.parent local coord = self._coords; parent:SetTexCoord(coord[1],coord[2],coord[3],coord[4]) end local Anim_OnPlay = function(self) local parent = self.parent parent:SetAlpha(1) if not parent:IsShown() then parent:Show() end end local Anim_OnStop = function(self) local parent = self.parent parent:SetAlpha(0) if parent:IsShown() then parent:Hide() end end local function SetNewAnimation(frame, animType, parent) local anim = frame:CreateAnimation(animType, subType) anim.parent = parent return anim end local function SetAnim(frame, parent) local speed = 0.08 frame.anim = frame:CreateAnimationGroup("Sprite") frame.anim.parent = parent; frame.anim:SetScript("OnPlay", Anim_OnPlay) frame.anim:SetScript("OnFinished", Anim_OnStop) frame.anim:SetScript("OnStop", Anim_OnStop) frame.anim[1] = SetNewAnimation(frame.anim, "Translation", frame) frame.anim[1]:SetOrder(1) frame.anim[1]:SetDuration(speed) frame.anim[1]._coords = {0,0.5,0,0.25} frame.anim[1]:SetScript("OnUpdate", Anim_OnUpdate) frame.anim[2] = SetNewAnimation(frame.anim, "Translation", frame) frame.anim[2]:SetOrder(2) frame.anim[2]:SetDuration(speed) frame.anim[2]._coords = {0.5,1,0,0.25} frame.anim[2]:SetScript("OnUpdate", Anim_OnUpdate) frame.anim[3] = SetNewAnimation(frame.anim, "Translation", frame) frame.anim[3]:SetOrder(3) frame.anim[3]:SetDuration(speed) frame.anim[3]._coords = {0,0.5,0.25,0.5} frame.anim[3]:SetScript("OnUpdate", Anim_OnUpdate) frame.anim[4] = SetNewAnimation(frame.anim, "Translation", frame) frame.anim[4]:SetOrder(4) frame.anim[4]:SetDuration(speed) frame.anim[4]._coords = {0.5,1,0.25,0.5} frame.anim[4]:SetScript("OnUpdate", Anim_OnUpdate) frame.anim[5] = SetNewAnimation(frame.anim, "Translation", frame) frame.anim[5]:SetOrder(5) frame.anim[5]:SetDuration(speed) frame.anim[5]._coords = {0,0.5,0.5,0.75} frame.anim[5]:SetScript("OnUpdate", Anim_OnUpdate) frame.anim[6] = SetNewAnimation(frame.anim, "Translation", frame) frame.anim[6]:SetOrder(6) frame.anim[6]:SetDuration(speed) frame.anim[6]._coords = {0.5,1,0.5,0.75} frame.anim[6]:SetScript("OnUpdate", Anim_OnUpdate) frame.anim[7] = SetNewAnimation(frame.anim, "Translation", frame) frame.anim[7]:SetOrder(7) frame.anim[7]:SetDuration(speed) frame.anim[7]._coords = {0,0.5,0.75,1} frame.anim[7]:SetScript("OnUpdate", Anim_OnUpdate) frame.anim[8] = SetNewAnimation(frame.anim, "Translation", frame) frame.anim[8]:SetOrder(8) frame.anim[8]:SetDuration(speed) frame.anim[8]._coords = {0.5,1,0.75,1} frame.anim[8]:SetScript("OnUpdate", Anim_OnUpdate) frame.anim:SetLooping("REPEAT") end --[[ ########################################################## ACTIONPANEL ########################################################## ]]-- local UpdateThreat = function(self, event, unit) if(unit ~= self.unit) or not unit or not IsLoggedIn() then return end local threat = self.Threat local status = UnitThreatSituation(unit) local r, g, b if(status and status > 0) then r, g, b = GetThreatStatusColor(status) threat:SetBackdropBorderColor(r, g, b) else threat:SetBackdropBorderColor(0, 0, 0, 0.5) end end local UpdatePlayerThreat = function(self, event, unit) if(unit ~= self.unit) or not unit or not IsLoggedIn() then return end local threat = self.Threat local status = UnitThreatSituation(unit) local r, g, b if(status and status > 0) then r, g, b = GetThreatStatusColor(status) threat:SetBackdropBorderColor(r, g, b) if(status > 1) then threat.OhShit:Show() end else threat:SetBackdropBorderColor(0, 0, 0, 0.5) threat.OhShit:Hide() end end local OhShit_OnShow = function(self) if not self.anim:IsPlaying() then self.anim:Play() end end local function CreateThreat(frame, unit) local threat = CreateFrame('Frame', nil, frame) threat:Point('TOPLEFT', frame, 'TOPLEFT', -3, 3) threat:Point('BOTTOMRIGHT', frame, 'BOTTOMRIGHT', 3, -3) threat:SetBackdrop({ edgeFile = [[Interface\AddOns\SVUI\assets\artwork\Template\GLOW]], edgeSize = 3, insets = { left = 2, right = 2, top = 2, bottom = 2 } }); threat:SetBackdropBorderColor(0,0,0,0.5) if(unit == "player") then local aggro = CreateFrame("Frame", nil, threat) aggro:SetFrameStrata("HIGH") aggro:SetFrameLevel(30) aggro:Size(52,52) aggro:Point("TOPRIGHT",frame,16,16) aggro.bg = aggro:CreateTexture(nil, "BORDER") aggro.bg:FillInner(aggro) aggro.bg:SetTexture("Interface\\AddOns\\SVUI\\assets\\artwork\\Unitframe\\UNIT-AGGRO") SuperVillain.Animate:Pulse(aggro) aggro:Hide() aggro:SetScript("OnShow", OhShit_OnShow) threat.OhShit = aggro threat.Override = UpdatePlayerThreat else threat.Override = UpdateThreat end return threat end local function CreateActionPanel(frame, offset) if(frame.ActionPanel) then return; end offset = offset or 2 local panel = CreateFrame('Frame', nil, frame) panel:Point('TOPLEFT', frame, 'TOPLEFT', -1, 1) panel:Point('BOTTOMRIGHT', frame, 'BOTTOMRIGHT', 1, -1) --[[ UNDERLAY BORDER ]]-- local borderLeft = panel:CreateTexture(nil, "BORDER") borderLeft:SetTexture(0, 0, 0) borderLeft:SetPoint("TOPLEFT") borderLeft:SetPoint("BOTTOMLEFT") borderLeft:SetWidth(offset) local borderRight = panel:CreateTexture(nil, "BORDER") borderRight:SetTexture(0, 0, 0) borderRight:SetPoint("TOPRIGHT") borderRight:SetPoint("BOTTOMRIGHT") borderRight:SetWidth(offset) local borderTop = panel:CreateTexture(nil, "BORDER") borderTop:SetTexture(0, 0, 0) borderTop:SetPoint("TOPLEFT") borderTop:SetPoint("TOPRIGHT") borderTop:SetHeight(offset) local borderBottom = panel:CreateTexture(nil, "BORDER") borderBottom:SetTexture(0, 0, 0) borderBottom:SetPoint("BOTTOMLEFT") borderBottom:SetPoint("BOTTOMRIGHT") borderBottom:SetHeight(offset) --[[ OVERLAY BORDER ]]-- panel.border = {} panel.border[1] = panel:CreateTexture(nil, "OVERLAY") panel.border[1]:SetTexture(0, 0, 0) panel.border[1]:SetPoint("TOPLEFT") panel.border[1]:SetPoint("TOPRIGHT") panel.border[1]:SetHeight(2) panel.border[2] = panel:CreateTexture(nil, "OVERLAY") panel.border[2]:SetTexture(0, 0, 0) panel.border[2]:SetPoint("BOTTOMLEFT") panel.border[2]:SetPoint("BOTTOMRIGHT") panel.border[2]:SetHeight(2) panel.border[3] = panel:CreateTexture(nil, "OVERLAY") panel.border[3]:SetTexture(0, 0, 0) panel.border[3]:SetPoint("TOPRIGHT") panel.border[3]:SetPoint("BOTTOMRIGHT") panel.border[3]:SetWidth(2) panel.border[4] = panel:CreateTexture(nil, "OVERLAY") panel.border[4]:SetTexture(0, 0, 0) panel.border[4]:SetPoint("TOPLEFT") panel.border[4]:SetPoint("BOTTOMLEFT") panel.border[4]:SetWidth(2) panel:SetBackdrop({ bgFile = [[Interface\BUTTONS\WHITE8X8]], edgeFile = [[Interface\BUTTONS\WHITE8X8]], tile = false, tileSize = 0, edgeSize = 1, insets = { left = 0, right = 0, top = 0, bottom = 0, }, }) panel:SetBackdropColor(0,0,0) panel:SetBackdropBorderColor(0,0,0) panel:SetFrameStrata("BACKGROUND") panel:SetFrameLevel(0) return panel end local function CreateNameText(frame, unitName) local db = MOD.db if(MOD.db[unitName] and MOD.db[unitName].name) then db = MOD.db[unitName].name end local name = frame:CreateFontString(nil, "OVERLAY") name:SetFont(SuperVillain.Shared:Fetch("font", db.font), db.fontSize, db.fontOutline) name:SetShadowOffset(2, -2) name:SetShadowColor(0, 0, 0, 1) if unitNmae == "target" then name:SetPoint("RIGHT", frame) else name:SetPoint("CENTER", frame) end return name; end function MOD:SetActionPanel(frame, unit, noHealthText, noPowerText, noMiscText) if(unit and (unit == "target" or unit == "player")) then frame.ActionPanel = CreateActionPanel(frame, 3) frame.Threat = CreateThreat(frame.ActionPanel, unit) local info = CreateFrame("Frame", nil, frame) info:SetFrameStrata("BACKGROUND") info:SetFrameLevel(0) info:Point("TOPLEFT", frame.ActionPanel, "BOTTOMLEFT", -1, 1) info:Point("TOPRIGHT", frame.ActionPanel, "BOTTOMRIGHT", 1, 1) info:SetHeight(30) local bg = info:CreateTexture(nil, "BACKGROUND") bg:FillInner(info) bg:SetTexture(1, 1, 1, 1) bg:SetGradientAlpha("VERTICAL", 0, 0, 0, 0, 0, 0, 0, 0.7) frame.InfoPanel = CreateFrame("Frame", nil, info) frame.InfoPanel:SetFrameStrata("MEDIUM") frame.InfoPanel:SetAllPoints(info) if(unit == "target") then frame.ActionPanel:SetFrameLevel(1) frame.ActionPanel.special = CreateFrame("Frame", nil, frame.ActionPanel) frame.ActionPanel.special:SetAllPoints(frame) frame.ActionPanel.special:SetFrameStrata("BACKGROUND") frame.ActionPanel.special:SetFrameLevel(0) frame.ActionPanel.special[1] = frame.ActionPanel.special:CreateTexture(nil, "OVERLAY", nil, 1) frame.ActionPanel.special[1]:SetPoint("BOTTOMLEFT", frame.ActionPanel.special, "TOPLEFT", 0, 0) frame.ActionPanel.special[1]:SetPoint("BOTTOMRIGHT", frame.ActionPanel.special, "TOPRIGHT", 0, 0) frame.ActionPanel.special[1]:SetHeight(frame.ActionPanel:GetWidth() * 0.15) frame.ActionPanel.special[1]:SetTexture(ELITE_TOP) frame.ActionPanel.special[1]:SetVertexColor(1, 0.75, 0) frame.ActionPanel.special[1]:SetBlendMode("BLEND") frame.ActionPanel.special[2] = frame.ActionPanel.special:CreateTexture(nil, "OVERLAY", nil, 1) frame.ActionPanel.special[2]:SetPoint("TOPLEFT", frame.ActionPanel.special, "BOTTOMLEFT", 0, 0) frame.ActionPanel.special[2]:SetPoint("TOPRIGHT", frame.ActionPanel.special, "BOTTOMRIGHT", 0, 0) frame.ActionPanel.special[2]:SetHeight(frame.ActionPanel:GetWidth() * 0.15) frame.ActionPanel.special[2]:SetTexture(ELITE_BOTTOM) frame.ActionPanel.special[2]:SetVertexColor(1, 0.75, 0) frame.ActionPanel.special[2]:SetBlendMode("BLEND") frame.ActionPanel.special[3] = frame.ActionPanel.special:CreateTexture(nil, "OVERLAY", nil, 1) frame.ActionPanel.special[3]:SetPoint("TOPLEFT", frame.ActionPanel.special, "TOPRIGHT", 0, 0) frame.ActionPanel.special[3]:SetPoint("BOTTOMLEFT", frame.ActionPanel.special, "BOTTOMRIGHT", 0, 0) frame.ActionPanel.special[3]:SetWidth(frame.ActionPanel:GetHeight() * 2.25) frame.ActionPanel.special[3]:SetTexture(ELITE_RIGHT) frame.ActionPanel.special[3]:SetVertexColor(1, 0.75, 0) frame.ActionPanel.special[3]:SetBlendMode("BLEND") frame.ActionPanel.special:SetAlpha(0.7) frame.ActionPanel.special:Hide() else frame.LossOfControl = CreateFrame("Frame", nil, frame.InfoPanel) frame.LossOfControl:SetAllPoints(frame) frame.LossOfControl:SetFrameStrata("DIALOG") frame.LossOfControl:SetFrameLevel(99) local stunned = frame.LossOfControl:CreateTexture(nil, "OVERLAY", nil, 1) stunned:SetPoint("CENTER", frame, "CENTER", 0, 0) stunned:SetSize(96, 96) stunned:SetTexture(STUNNED_ANIM) stunned:SetBlendMode("ADD") SuperVillain.Animate:Sprite(stunned, 0.12, false, true) stunned:Hide() frame.LossOfControl.stunned = stunned LossOfControlFrame:HookScript("OnShow", function() if(_G["SVUI_Player"] and _G["SVUI_Player"].LossOfControl) then _G["SVUI_Player"].LossOfControl:Show() end end) LossOfControlFrame:HookScript("OnHide", function() if(_G["SVUI_Player"] and _G["SVUI_Player"].LossOfControl) then _G["SVUI_Player"].LossOfControl:Hide() end end) end else frame.ActionPanel = CreateActionPanel(frame, 2) frame.InfoPanel = CreateFrame("Frame", nil, frame) frame.InfoPanel:SetFrameStrata("MEDIUM") frame.InfoPanel:Point("TOPLEFT", frame.ActionPanel, "TOPLEFT", 2, -2) frame.InfoPanel:Point("BOTTOMRIGHT", frame.ActionPanel, "BOTTOMRIGHT", -2, 2) frame.InfoPanel:SetFrameLevel(frame.InfoPanel:GetFrameLevel() + 30) end frame.InfoPanel.Name = CreateNameText(frame.InfoPanel, unit) local reverse = unit and (unit == "target" or unit == "focus" or unit == "boss" or unit == "arena") or false; local offset, direction if(not noHealthText) then frame.InfoPanel.Health = frame.InfoPanel:CreateFontString(nil, "OVERLAY") frame.InfoPanel.Health:SetFont(SuperVillain.Shared:Fetch("font", MOD.db.font), MOD.db.fontSize, MOD.db.fontOutline) offset = reverse and 2 or -2; direction = reverse and "LEFT" or "RIGHT"; frame.InfoPanel.Health:Point(direction, frame.InfoPanel, direction, offset, 0) end if(not noPowerText) then frame.InfoPanel.Power = frame.InfoPanel:CreateFontString(nil, "OVERLAY") frame.InfoPanel.Power:SetFont(SuperVillain.Shared:Fetch("font", MOD.db.font), MOD.db.fontSize, MOD.db.fontOutline) offset = reverse and -2 or 2; direction = reverse and "RIGHT" or "LEFT"; frame.InfoPanel.Power:Point(direction, frame.InfoPanel, direction, offset, 0) end if(not noMiscText) then frame.InfoPanel.Misc = frame.InfoPanel:CreateFontString(nil, "OVERLAY") frame.InfoPanel.Misc:SetFont(SuperVillain.Shared:Fetch("font", MOD.db.font), MOD.db.fontSize, MOD.db.fontOutline) frame.InfoPanel.Misc:Point("CENTER", frame, "CENTER", 0, 0) end frame.HealthPanel = CreateFrame("Frame", nil, frame) frame.HealthPanel:SetAllPoints(frame) frame.StatusPanel = CreateFrame("Frame", nil, frame.HealthPanel) frame.StatusPanel:EnableMouse(false) if(unit and (unit == "player" or unit == "pet" or unit == "target" or unit == "targettarget" or unit == "focus" or unit == "focustarget")) then frame.StatusPanel:SetAllPoints(frame.HealthPanel) frame.StatusPanel.media = { [[Interface\Addons\SVUI\assets\artwork\Unitframe\TARGET-DC]], [[Interface\Addons\SVUI\assets\artwork\Unitframe\TARGET-DEAD]], [[Interface\Addons\SVUI\assets\artwork\Unitframe\TARGET-TAPPED]] } else frame.StatusPanel:SetSize(50, 50) frame.StatusPanel:SetPoint("CENTER", frame.HealthPanel, "CENTER", 0, 0) frame.StatusPanel.media = { [[Interface\Addons\SVUI\assets\artwork\Unitframe\UNIT-DC]], [[Interface\Addons\SVUI\assets\artwork\Unitframe\UNIT-DEAD]], [[Interface\Addons\SVUI\assets\artwork\Unitframe\UNIT-TAPPED]] } end frame.StatusPanel.texture = frame.StatusPanel:CreateTexture(nil, "OVERLAY") frame.StatusPanel.texture:SetAllPoints() frame.StatusPanel.texture:SetTexture([[Interface\BUTTONS\WHITE8X8]]) frame.StatusPanel.texture:SetBlendMode("ADD") frame.StatusPanel.texture:SetGradient("VERTICAL",1,1,0,1,0,0) frame.StatusPanel.texture:SetAlpha(0) frame.StatusPanel:SetFrameStrata("LOW") frame.StatusPanel:SetFrameLevel(20) end --[[ ########################################################## HEALTH ########################################################## ]]-- local function updateFrequentUpdates(self) local health = self.Health if health.frequentUpdates and not self:IsEventRegistered("UNIT_HEALTH_FREQUENT") then if GetCVarBool("predictedHealth") ~= 1 then SetCVar("predictedHealth", 1) end self:RegisterEvent('UNIT_HEALTH_FREQUENT', Path) if self:IsEventRegistered("UNIT_HEALTH") then self:UnregisterEvent("UNIT_HEALTH", Path) end elseif not self:IsEventRegistered("UNIT_HEALTH") then self:RegisterEvent('UNIT_HEALTH', Path) if self:IsEventRegistered("UNIT_HEALTH_FREQUENT") then self:UnregisterEvent("UNIT_HEALTH_FREQUENT", Path) end end end local CustomUpdate = function(self, event, unit) if(self.unit ~= unit) or not unit then return end local health = self.Health local min, max = UnitHealth(unit), UnitHealthMax(unit) local disconnected = not UnitIsConnected(unit) local invisible = ((min == max) or UnitIsDeadOrGhost(unit) or disconnected); local tapped = (UnitIsTapped(unit) and (not UnitIsTappedByPlayer(unit))); if health.fillInverted then health:SetReverseFill(true) end health:SetMinMaxValues(-max, 0) health:SetValue(-min) health.disconnected = disconnected if health.frequentUpdates ~= health.__frequentUpdates then health.__frequentUpdates = health.frequentUpdates updateFrequentUpdates(self) end local bg = health.bg; local mu = (min / max); if(invisible or not health.overlayAnimation) then health.animation[1].anim:Stop() health.animation[1]:SetAlpha(0) end if(invisible) then health:SetStatusBarColor(0.6,0.4,1,0.5) health.animation[1]:SetVertexColor(0.8,0.3,1,0.4) elseif(health.colorOverlay) then local t = oUF_SuperVillain.colors.health health:SetStatusBarColor(t[1], t[2], t[3], 0.9) else health:SetStatusBarColor(1, 0.25 * mu, 0, 0.85) health.animation[1]:SetVertexColor(1, 0.1 * mu, 0, 0.5) end if(bg) then bg:SetVertexColor(0,0,0,0) end if(health.overlayAnimation and not invisible) then if(mu <= 0.25) then health.animation[1]:SetAlpha(1) health.animation[1].anim:Play() else health.animation[1].anim:Stop() health.animation[1]:SetAlpha(0) end end if self.ResurrectIcon then self.ResurrectIcon:SetAlpha(min == 0 and 1 or 0) end if self.isForced then local current = random(1,max) health:SetValue(-current) end end local Update = function(self, event, unit) if(self.unit ~= unit) or not unit then return end local health = self.Health local min, max = UnitHealth(unit), UnitHealthMax(unit) local disconnected = not UnitIsConnected(unit) if health.fillInverted then health:SetReverseFill(true) end health:SetMinMaxValues(0, max) if(disconnected) then health:SetValue(max) else health:SetValue(min) end health.disconnected = disconnected if health.frequentUpdates ~= health.__frequentUpdates then health.__frequentUpdates = health.frequentUpdates updateFrequentUpdates(self) end local bg = health.bg; local db = MOD.db or SuperVillain.db.SVUnit; local r, g, b, t, t2; if(health.colorTapping and not UnitPlayerControlled(unit) and UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit) and not UnitIsTappedByAllThreatList(unit)) then t = oUF_SuperVillain.colors.tapped elseif(health.colorDisconnected and not UnitIsConnected(unit)) then t = oUF_SuperVillain.colors.disconnected elseif(health.colorClass and UnitIsPlayer(unit)) or (health.colorClassNPC and not UnitIsPlayer(unit)) or (health.colorClassPet and UnitPlayerControlled(unit) and not UnitIsPlayer(unit)) then local _, class = UnitClass(unit) local tmp = oUF_SuperVillain.colors.class[class] or oUF_SuperVillain.colors.health t = {(tmp[1] * 0.75),(tmp[2] * 0.75),(tmp[3] * 0.75)} if(bg and db.classbackdrop and UnitIsPlayer(unit)) then t2 = t end elseif(health.colorReaction and UnitReaction(unit, 'player')) then t = oUF_SuperVillain.colors.reaction[UnitReaction(unit, "player")] if(bg and db.classbackdrop and not UnitIsPlayer(unit) and UnitReaction(unit, "player")) then t2 = t end elseif(health.colorSmooth) then r, g, b = oUF_SuperVillain.ColorGradient(min, max, unpack(health.smoothGradient or oUF_SuperVillain.colors.smooth)) elseif(health.colorHealth) then t = oUF_SuperVillain.colors.health end if(t) then r, g, b = t[1], t[2], t[3] end if(b) then if(db.healthclass == true and db.colorhealthbyvalue == true or db.colorhealthbyvalue and self.isForced and not(UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit))) then r, g, b = oUF_SuperVillain.ColorGradient(min,max,1,0,0,1,1,0,r,g,b) end health:SetStatusBarColor(r, g, b) if(bg) then local mu = bg.multiplier or 1 if(t2) then r, g, b = t2[1], t2[2], t2[3] end bg:SetVertexColor(r * mu, g * mu, b * mu) end end if self.ResurrectIcon then self.ResurrectIcon:SetAlpha(min == 0 and 1 or 0) end if self.isForced then min = random(1,max) health:SetValue(min) end if(db.gridMode) then health:SetOrientation("VERTICAL") end end function MOD:CreateHealthBar(frame, hasbg, reverse) local healthBar = CreateFrame("StatusBar", nil, frame) healthBar:SetFrameStrata("LOW") healthBar:SetFrameLevel(4) healthBar:SetStatusBarTexture(SuperVillain.Media.bar.default) if hasbg then healthBar.bg = healthBar:CreateTexture(nil, "BORDER") healthBar.bg:SetAllPoints() healthBar.bg:SetTexture(SuperVillain.Media.bar.gradient) healthBar.bg:SetVertexColor(0.4, 0.1, 0.1) healthBar.bg.multiplier = 0.25 end local flasher = CreateFrame("Frame", nil, frame) flasher:SetFrameLevel(3) flasher:SetAllPoints(healthBar) flasher[1] = flasher:CreateTexture(nil, "OVERLAY", nil, 1) flasher[1]:SetTexture(HEALTH_ANIM_FILE) flasher[1]:SetTexCoord(0, 0.5, 0, 0.25) flasher[1]:SetVertexColor(1, 0.3, 0.1, 0.5) flasher[1]:SetBlendMode("ADD") flasher[1]:SetAllPoints(flasher) SetAnim(flasher[1], flasher) flasher:Hide() healthBar.animation = flasher healthBar.noupdate = false; healthBar.fillInverted = reverse; healthBar.colorTapping = true; healthBar.colorDisconnected = true healthBar.Override = Update; return healthBar end function MOD:RefreshHealthBar(frame, overlay) if(overlay) then frame.Health.Override = CustomUpdate; else frame.Health.Override = Update; end end --[[ ########################################################## POWER ########################################################## ]]-- local PostUpdateAltPower = function(self, min, current, max) local remaining = floor(current / max * 100) local parent = self:GetParent() if remaining < 35 then self:SetStatusBarColor(0, 1, 0) elseif remaining < 70 then self:SetStatusBarColor(1, 1, 0) else self:SetStatusBarColor(1, 0, 0) end local unit = parent.unit; if(unit == "player" and self.text) then local apInfo = select(10, UnitAlternatePowerInfo(unit)) if remaining > 0 then self.text:SetText(apInfo..": "..format("%d%%", remaining)) else self.text:SetText(apInfo..": 0%") end elseif(unit and unit:find("boss%d") and self.text) then self.text:SetTextColor(self:GetStatusBarColor()) if not parent.InfoPanel.Power:GetText() or parent.InfoPanel.Power:GetText() == "" then self.text:Point("BOTTOMRIGHT", parent.Health, "BOTTOMRIGHT") else self.text:Point("RIGHT", parent.InfoPanel.Power, "LEFT", 2, 0) end if remaining > 0 then self.text:SetText("|cffD7BEA5[|r"..format("%d%%", remaining).."|cffD7BEA5]|r") else self.text:SetText(nil) end end end function MOD:CreatePowerBar(frame, bg) local power = CreateFrame("StatusBar", nil, frame) power:SetStatusBarTexture([[Interface\AddOns\SVUI\assets\artwork\Bars\DEFAULT]]) power:SetPanelTemplate("Bar") if bg then power.bg = power:CreateTexture(nil, "BORDER") power.bg:SetAllPoints() power.bg:SetTexture([[Interface\AddOns\SVUI\assets\artwork\Template\DEFAULT]]) power.bg.multiplier = 0.2 end power.colorDisconnected = false; power.colorTapping = false; power.PostUpdate = MOD.PostUpdatePower; return power end function MOD:CreateAltPowerBar(frame) local altPower = CreateFrame("StatusBar", nil, frame) altPower:SetStatusBarTexture([[Interface\AddOns\SVUI\assets\artwork\Bars\DEFAULT]]) altPower:SetPanelTemplate("Bar") altPower:GetStatusBarTexture():SetHorizTile(false) altPower:SetFrameStrata("MEDIUM") altPower.text = altPower:CreateFontString(nil, "OVERLAY") altPower.text:SetPoint("CENTER") altPower.text:SetJustifyH("CENTER") altPower.text:SetFont(SuperVillain.Shared:Fetch("font", MOD.db.font), MOD.db.fontSize, MOD.db.fontOutline) altPower.PostUpdate = PostUpdateAltPower; return altPower end local function PowerUpdateNamePosition(frame, unit) local panel = frame.InfoPanel if(not panel.Power or (panel.Power and not panel.Power:IsShown()) or not panel.Name) then return end local db = MOD.db[unit] local parent = panel.Name:GetParent() if UnitIsPlayer(unit)then local point = db.name.position; panel.Power:SetAlpha(1) panel.Name:ClearAllPoints() SuperVillain:ReversePoint(panel.Name, point, parent, db.name.xOffset, db.name.yOffset) else panel.Power:SetAlpha(db.power.hideonnpc and 0 or 1) panel.Name:ClearAllPoints() panel.Name:SetPoint(panel.Power:GetPoint()) end end function MOD:PostUpdatePower(unit, value, max) local db = MOD.db[unit] local powerType, _, _, _, _ = UnitPowerType(unit) local parent = self:GetParent() if parent.isForced then value = random(1, max) powerType = random(0, 4) self:SetValue(value) end local colors = oUF_SuperVillain.colors.power[token[powerType]] local mult = self.bg.multiplier or 1; local isPlayer = UnitPlayerControlled(unit) if isPlayer and self.colorClass then local _, class = UnitClassBase(unit); colors = oUF_SuperVillain["colors"].class[class] elseif not isPlayer then local react = UnitReaction("player", unit) colors = oUF_SuperVillain["colors"].reaction[react] end if not colors then return end self:SetStatusBarColor(colors[1], colors[2], colors[3]) self.bg:SetVertexColor(colors[1] * mult, colors[2] * mult, colors[3] * mult) if db and db.power and db.power.hideonnpc then PowerUpdateNamePosition(parent, unit) end end --[[ ########################################################## PORTRAIT ########################################################## ]]-- local Update2DPortrait = function(self, event, unit) if(not unit or not UnitIsUnit(self.unit, unit)) then return end local portrait = self.Portrait SetPortraitTexture(portrait, unit) end local Update3DPortrait = function(self, event, unit) if(not unit or not UnitIsUnit(self.unit, unit)) then return end local portrait = self.Portrait if(not portrait:IsObjectType'Model') then return; end local guid = UnitGUID(unit) local camera = portrait.UserCamDistance or 1 local rotate = portrait.UserRotation if(not UnitExists(unit) or not UnitIsConnected(unit) or not UnitIsVisible(unit)) then portrait:SetCamDistanceScale(1) portrait:SetPortraitZoom(0) portrait:SetPosition(4,-1,1) portrait:ClearModel() portrait:SetModel(MISSING_MODEL_FILE) portrait.guid = nil portrait:SetBackdropColor(0.25,0.25,0.25) if portrait.UpdateColor then portrait:UpdateColor(0.25,0.25,0.25) end elseif(portrait.guid ~= guid or event == 'UNIT_MODEL_CHANGED') then portrait:SetCamDistanceScale(camera) portrait:SetPortraitZoom(1) portrait:SetPosition(0,0,0) portrait:ClearModel() portrait:SetUnit(unit) portrait.guid = guid if(rotate and portrait:GetFacing() ~= rotate / 60) then portrait:SetFacing(rotate / 60) end local r, g, b, color = 0.25, 0.25, 0.25 if not UnitIsPlayer(unit)then color = oUF_SuperVillain.colors.reaction[UnitReaction(unit,"player")] if(color ~= nil) then r,g,b = color[1], color[2], color[3] end; else local _,unitClass = UnitClass(unit) if unitClass then color = oUF_SuperVillain.colors.class[unitClass] r,g,b = color[1], color[2], color[3] end end portrait:SetBackdropColor(r,g,b) if portrait.UpdateColor then portrait:UpdateColor(r,g,b) end end end function MOD:CreatePortrait(frame,smallUnit,isPlayer) -- 3D Portrait local portrait3D = CreateFrame("PlayerModel",nil,frame) portrait3D:SetFrameStrata("LOW") portrait3D:SetFrameLevel(2) if smallUnit then portrait3D:SetPanelTemplate("UnitSmall") else portrait3D:SetPanelTemplate("UnitLarge") end; local overlay = CreateFrame("Frame",nil,portrait3D) overlay:SetAllPoints(portrait3D.Panel) overlay:SetFrameLevel(3) portrait3D.overlay = overlay; portrait3D.UserRotation = 0; portrait3D.UserCamDistance = 1.3; -- 2D Portrait local portrait2Danchor = CreateFrame('Frame',nil,frame) portrait2Danchor:SetFrameStrata("LOW") portrait2Danchor:SetFrameLevel(2) local portrait2D = portrait2Danchor:CreateTexture(nil,'OVERLAY') portrait2D:SetTexCoord(0.15,0.85,0.15,0.85) portrait2D:SetAllPoints(portrait2Danchor) portrait2D.anchor = portrait2Danchor; if smallUnit then portrait2Danchor:SetFixedPanelTemplate("UnitSmall") else portrait2Danchor:SetFixedPanelTemplate("UnitLarge") end; portrait2D.Panel = portrait2Danchor.Panel; local overlay = CreateFrame("Frame",nil,portrait2Danchor) overlay:SetAllPoints(portrait2D.Panel) overlay:SetFrameLevel(3) portrait2D.overlay = overlay; -- Set Updates portrait2D.Override = Update2DPortrait portrait3D.Override = Update3DPortrait -- Assign To Frame frame.PortraitModel = portrait3D; frame.PortraitTexture = portrait2D; end