304 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			304 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| local _, ns = ...
 | |
| local oUF = _G.oUF or ns.oUF
 | |
| assert(oUF, "oUF_Cutaway was unable to locate oUF install.")
 | |
| 
 | |
| --[[
 | |
| 	Configuration values for both health and power:
 | |
| 		.enabled: enable cutaway for this element, defaults to disabled
 | |
| 		.fadeOutTime: How long it takes the cutaway health to fade, defaults to 0.6 seconds
 | |
| 		.lengthBeforeFade: How long it takes before the cutaway begins to fade, defaults to 0.3 seconds
 | |
| ]]
 | |
| -- GLOBALS: ElvUI
 | |
| 
 | |
| local max = math.max
 | |
| local assert = assert
 | |
| local hooksecurefunc = hooksecurefunc
 | |
| local UnitHealthMax = UnitHealthMax
 | |
| local UnitPowerMax = UnitPowerMax
 | |
| local UnitIsTapDenied = UnitIsTapDenied
 | |
| local UnitGUID = UnitGUID
 | |
| 
 | |
| local E -- placeholder
 | |
| local function checkElvUI()
 | |
| 	if not E then
 | |
| 		E = ElvUI and ElvUI[1]
 | |
| 
 | |
| 		assert(E, "oUF_Cutaway was not able to locate ElvUI and it is required.")
 | |
| 	end
 | |
| end
 | |
| 
 | |
| local function closureFunc(self)
 | |
| 	self.ready = nil
 | |
| 	self.playing = nil
 | |
| 	self.cur = nil
 | |
| end
 | |
| 
 | |
| local function fadeClosure(element)
 | |
| 	if not element.FadeObject then
 | |
| 		element.FadeObject = {
 | |
| 			finishedFuncKeep = true,
 | |
| 			finishedArg1 = element,
 | |
| 			finishedFunc = closureFunc
 | |
| 		}
 | |
| 	end
 | |
| 
 | |
| 	E:UIFrameFadeOut(element, element.fadeOutTime, element.__parentElement:GetAlpha(), 0)
 | |
| end
 | |
| 
 | |
| local function Shared_PreUpdate(self, element, unit)
 | |
| 	element.unit = unit
 | |
| 
 | |
| 	local oldGUID, newGUID = element.guid, UnitGUID(unit)
 | |
| 	element.guid = newGUID
 | |
| 
 | |
| 	if not oldGUID or oldGUID ~= newGUID then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	element.cur = self.cur
 | |
| 	element.ready = true
 | |
| end
 | |
| 
 | |
| local function UpdateSize(self, element, curV, maxV)
 | |
| 	local isVertical = self:GetOrientation() == 'VERTICAL'
 | |
| 	local pm = (isVertical and self:GetHeight()) or self:GetWidth()
 | |
| 	local oum = (1 / maxV) * pm
 | |
| 	local c = max(element.cur - curV, 0)
 | |
| 	local mm = c * oum
 | |
| 
 | |
| 	if isVertical then
 | |
| 		element:Height(mm)
 | |
| 	else
 | |
| 		element:Width(mm)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| local PRE, POST = 0, 1
 | |
| local function Shared_UpdateCheckReturn(self, element, updateType, ...)
 | |
| 	if not element:IsVisible() then
 | |
| 		return true
 | |
| 	end
 | |
| 
 | |
| 	if updateType == PRE then
 | |
| 		local maxV = ...
 | |
| 		return (not element.enabled or not self.cur) or element.ready or not maxV or maxV == 0
 | |
| 	elseif updateType == POST then
 | |
| 		local curV, maxV, unit = ...
 | |
| 		return (not element.enabled or not element.cur) or (not element.ready or not curV or not maxV or maxV == 0) or element.unit ~= unit
 | |
| 	end
 | |
| end
 | |
| 
 | |
| local function Health_PreUpdate(self, unit)
 | |
| 	local element = self.__owner.Cutaway.Health
 | |
| 	local maxV = (element.GetHealthMax or UnitHealthMax)(unit)
 | |
| 	if Shared_UpdateCheckReturn(self, element, PRE, maxV) or UnitIsTapDenied(unit) then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	Shared_PreUpdate(self, element, unit)
 | |
| end
 | |
| 
 | |
| local function Health_PostUpdate(self, unit, curHealth, maxHealth)
 | |
| 	local element = self.__owner.Cutaway.Health
 | |
| 	if Shared_UpdateCheckReturn(self, element, POST, curHealth, maxHealth, unit) then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	UpdateSize(self, element, curHealth, maxHealth)
 | |
| 
 | |
| 	if element.playing then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	if (element.cur - curHealth) > (maxHealth * 0.01) then
 | |
| 		element:SetAlpha(self:GetAlpha())
 | |
| 
 | |
| 		E:Delay(element.lengthBeforeFade, fadeClosure, element)
 | |
| 
 | |
| 		element.playing = true
 | |
| 	else
 | |
| 		element:SetAlpha(0)
 | |
| 		closureFunc(element)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| local function Health_PostUpdateColor(self, r, g, b)
 | |
| 	self.__owner.Cutaway.Health:SetVertexColor(r * 1.5, g * 1.5, b * 1.5)
 | |
| end
 | |
| 
 | |
| local function Power_PreUpdate(self, unit)
 | |
| 	local element = self.__owner.Cutaway.Power
 | |
| 	local maxV = (element.GetPowerMax or UnitPowerMax)(unit)
 | |
| 	if Shared_UpdateCheckReturn(self, element, PRE, maxV) then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	Shared_PreUpdate(self, element, unit)
 | |
| end
 | |
| 
 | |
| local function Power_PostUpdate(self, unit, curPower, _, maxPower)
 | |
| 	local element = self.__owner.Cutaway.Power
 | |
| 	if Shared_UpdateCheckReturn(self, element, POST, curPower, maxPower, unit) then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	UpdateSize(self, element, curPower, maxPower)
 | |
| 
 | |
| 	if element.playing then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	if (element.cur - curPower) > (maxPower * 0.01) then
 | |
| 		element:SetAlpha(self:GetAlpha())
 | |
| 
 | |
| 		E:Delay(element.lengthBeforeFade, fadeClosure, element)
 | |
| 
 | |
| 		element.playing = true
 | |
| 	else
 | |
| 		element:SetAlpha(0)
 | |
| 		closureFunc(element)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| local function Power_PostUpdateColor(self, r, g, b)
 | |
| 	self.__owner.Cutaway.Power:SetVertexColor(r * 1.5, g * 1.5, b * 1.5)
 | |
| end
 | |
| 
 | |
| local defaults = {
 | |
| 	health = {
 | |
| 		enabled = false,
 | |
| 		lengthBeforeFade = 0.3,
 | |
| 		fadeOutTime = 0.6
 | |
| 	},
 | |
| 	power = {
 | |
| 		enabled = false,
 | |
| 		lengthBeforeFade = 0.3,
 | |
| 		fadeOutTime = 0.6
 | |
| 	}
 | |
| }
 | |
| 
 | |
| local function UpdateConfigurationValues(self, db)
 | |
| 	local hs, ps = false, false
 | |
| 	if self.Health then
 | |
| 		local health = self.Health
 | |
| 		local hdb = db.health
 | |
| 		hs = hdb.enabled
 | |
| 		health.enabled = hs
 | |
| 
 | |
| 		if hs then
 | |
| 			health.lengthBeforeFade = hdb.lengthBeforeFade
 | |
| 			health.fadeOutTime = hdb.fadeOutTime
 | |
| 			health:Show()
 | |
| 		else
 | |
| 			health:Hide()
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	if self.Power then
 | |
| 		local power = self.Power
 | |
| 		local pdb = db.power
 | |
| 		ps = pdb.enabled
 | |
| 		power.enabled = ps
 | |
| 
 | |
| 		if ps then
 | |
| 			power.lengthBeforeFade = pdb.lengthBeforeFade
 | |
| 			power.fadeOutTime = pdb.fadeOutTime
 | |
| 			power:Show()
 | |
| 		else
 | |
| 			power:Hide()
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	return hs, ps
 | |
| end
 | |
| 
 | |
| local function Enable(self)
 | |
| 	local element = self and self.Cutaway
 | |
| 	if element then
 | |
| 		checkElvUI()
 | |
| 
 | |
| 		if element.Health and element.Health:IsObjectType("Texture") and not element.Health:GetTexture() then
 | |
| 			element.Health:SetTexture([[Interface\TargetingFrame\UI-StatusBar]])
 | |
| 		end
 | |
| 
 | |
| 		if element.Power and element.Power:IsObjectType("Texture") and not element.Power:GetTexture() then
 | |
| 			element.Power:SetTexture([[Interface\TargetingFrame\UI-StatusBar]])
 | |
| 		end
 | |
| 
 | |
| 		if not element.defaultsSet then
 | |
| 			UpdateConfigurationValues(element, defaults)
 | |
| 			element.defaultsSet = true
 | |
| 		end
 | |
| 
 | |
| 		if element.Health and self.Health then
 | |
| 			self.Health.__owner = self
 | |
| 			element.Health.__parentElement = self.Health
 | |
| 			element.Health:SetAlpha(0)
 | |
| 
 | |
| 			if not element.Health.hasCutawayHook then
 | |
| 				if self.Health.PreUpdate then
 | |
| 					hooksecurefunc(self.Health, "PreUpdate", Health_PreUpdate)
 | |
| 				else
 | |
| 					self.Health.PreUpdate = Health_PreUpdate
 | |
| 				end
 | |
| 
 | |
| 				if self.Health.PostUpdate then
 | |
| 					hooksecurefunc(self.Health, "PostUpdate", Health_PostUpdate)
 | |
| 				else
 | |
| 					self.Health.PostUpdate = Health_PostUpdate
 | |
| 				end
 | |
| 
 | |
| 				hooksecurefunc(self.Health, "SetStatusBarColor", Health_PostUpdateColor)
 | |
| 
 | |
| 				element.Health.hasCutawayHook = true
 | |
| 			end
 | |
| 		end
 | |
| 
 | |
| 		if element.Power and self.Power then
 | |
| 			self.Power.__owner = self
 | |
| 			element.Power.__parentElement = self.Power
 | |
| 			element.Power:SetAlpha(0)
 | |
| 
 | |
| 			if not element.Power.hasCutawayHook then
 | |
| 				if self.Power.PreUpdate then
 | |
| 					hooksecurefunc(self.Power, "PreUpdate", Power_PreUpdate)
 | |
| 				else
 | |
| 					self.Power.PreUpdate = Power_PreUpdate
 | |
| 				end
 | |
| 
 | |
| 				if self.Power.PostUpdate then
 | |
| 					hooksecurefunc(self.Power, "PostUpdate", Power_PostUpdate)
 | |
| 				else
 | |
| 					self.Power.PostUpdate = Power_PostUpdate
 | |
| 				end
 | |
| 
 | |
| 				hooksecurefunc(self.Power, "SetStatusBarColor", Power_PostUpdateColor)
 | |
| 
 | |
| 				element.Power.hasCutawayHook = true
 | |
| 			end
 | |
| 		end
 | |
| 
 | |
| 		if not element.UpdateConfigurationValues then
 | |
| 			element.UpdateConfigurationValues = UpdateConfigurationValues
 | |
| 		end
 | |
| 
 | |
| 		return true
 | |
| 	end
 | |
| end
 | |
| 
 | |
| local function disableElement(element)
 | |
| 	if element then
 | |
| 		element.enabled = false
 | |
| 		element:Hide()
 | |
| 	end
 | |
| end
 | |
| 
 | |
| local function Disable(self)
 | |
| 	if self and self.Cutaway then
 | |
| 		disableElement(self.Cutaway.Health)
 | |
| 		disableElement(self.Cutaway.Power)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| oUF:AddElement("Cutaway", nil, Enable, Disable)
 |