health.lua 7.64 KB
Newer Older
Blazeflack's avatar
Blazeflack committed
1 2
--[[
# Element: Health Bar
Elv's avatar
Elv committed
3

Blazeflack's avatar
Blazeflack committed
4
Handles the updating of a status bar that displays the unit's health.
Elv's avatar
Elv committed
5

Blazeflack's avatar
Blazeflack committed
6
## Widget
Elv's avatar
Elv committed
7

Blazeflack's avatar
Blazeflack committed
8
Health - A `StatusBar` used to represent the unit's health.
Elv's avatar
Elv committed
9

Blazeflack's avatar
Blazeflack committed
10
## Sub-Widgets
Elv's avatar
Elv committed
11

Blazeflack's avatar
Blazeflack committed
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
.bg - A `Texture` used as a background. It will inherit the color of the main StatusBar.

## Notes

A default texture will be applied if the widget is a StatusBar and doesn't have a texture set.

## Options

.frequentUpdates   - Indicates whether to use UNIT_HEALTH_FREQUENT instead of UNIT_HEALTH to update the bar (boolean)
.smoothGradient    - 9 color values to be used with the .colorSmooth option (table)

The following options are listed by priority. The first check that returns true decides the color of the bar.

.colorTapping      - Use `self.colors.tapping` to color the bar if the unit isn't tapped by the player (boolean)
.colorDisconnected - Use `self.colors.disconnected` to color the bar if the unit is offline (boolean)
.colorClass        - Use `self.colors.class[class]` to color the bar based on unit class. `class` is defined by the
28
                     second return of [UnitClass](http://wowprogramming.com/docs/api/UnitClass.html) (boolean)
Blazeflack's avatar
Blazeflack committed
29 30 31 32 33
.colorClassNPC     - Use `self.colors.class[class]` to color the bar if the unit is a NPC (boolean)
.colorClassPet     - Use `self.colors.class[class]` to color the bar if the unit is player controlled, but not a player
                     (boolean)
.colorReaction     - Use `self.colors.reaction[reaction]` to color the bar based on the player's reaction towards the
                     unit. `reaction` is defined by the return value of
34
                     [UnitReaction](http://wowprogramming.com/docs/api/UnitReaction.html) (boolean)
Blazeflack's avatar
Blazeflack committed
35 36 37 38
.colorSmooth       - Use `smoothGradient` if present or `self.colors.smooth` to color the bar with a smooth gradient
                     based on the player's current health percentage (boolean)
.colorHealth       - Use `self.colors.health` to color the bar. This flag is used to reset the bar color back to default
                     if none of the above conditions are met (boolean)
Elv's avatar
Elv committed
39

Blazeflack's avatar
Blazeflack committed
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
## Sub-Widgets Options

.multiplier - Used to tint the background based on the main widgets R, G and B values. Defaults to 1 (number)[0-1]

## Attributes

.disconnected - Indicates whether the unit is disconnected (boolean)

## Examples

    -- Position and size
    local Health = CreateFrame('StatusBar', nil, self)
    Health:SetHeight(20)
    Health:SetPoint('TOP')
    Health:SetPoint('LEFT')
    Health:SetPoint('RIGHT')

    -- Add a background
    local Background = Health:CreateTexture(nil, 'BACKGROUND')
    Background:SetAllPoints(Health)
    Background:SetTexture(1, 1, 1, .5)

    -- Options
    Health.frequentUpdates = true
    Health.colorTapping = true
    Health.colorDisconnected = true
    Health.colorClass = true
    Health.colorReaction = true
    Health.colorHealth = true

    -- Make the background darker.
    Background.multiplier = .5

    -- Register it with oUF
	Health.bg = Background
    self.Health = Health
--]]

local _, ns = ...
local oUF = ns.oUF

local function UpdateColor(element, unit, cur, max)
	local parent = element.__owner
Elv's avatar
Elv committed
83 84

	local r, g, b, t
Blazeflack's avatar
Blazeflack committed
85 86 87 88 89 90 91
	if(element.colorTapping and not UnitPlayerControlled(unit) and UnitIsTapDenied(unit)) then
		t = parent.colors.tapped
	elseif(element.colorDisconnected and element.disconnected) then
		t = parent.colors.disconnected
	elseif(element.colorClass and UnitIsPlayer(unit)) or
		(element.colorClassNPC and not UnitIsPlayer(unit)) or
		(element.colorClassPet and UnitPlayerControlled(unit) and not UnitIsPlayer(unit)) then
Elv's avatar
Elv committed
92
		local _, class = UnitClass(unit)
Blazeflack's avatar
Blazeflack committed
93 94 95 96
		t = parent.colors.class[class]
	elseif(element.colorReaction and UnitReaction(unit, 'player')) then
		t = parent.colors.reaction[UnitReaction(unit, 'player')]
	elseif(element.colorSmooth) then
Simpy's avatar
Simpy committed
97
		r, g, b = parent:ColorGradient(cur, max, unpack(element.smoothGradient or parent.colors.smooth))
Blazeflack's avatar
Blazeflack committed
98 99
	elseif(element.colorHealth) then
		t = parent.colors.health
Elv's avatar
Elv committed
100 101 102 103 104 105
	end

	if(t) then
		r, g, b = t[1], t[2], t[3]
	end

Blazeflack's avatar
Blazeflack committed
106 107
	if(r or g or b) then
		element:SetStatusBarColor(r, g, b)
108

Blazeflack's avatar
Blazeflack committed
109 110 111
		local bg = element.bg
		if(bg) then
			local mu = bg.multiplier or 1
Elv's avatar
Elv committed
112 113 114
			bg:SetVertexColor(r * mu, g * mu, b * mu)
		end
	end
Blazeflack's avatar
Blazeflack committed
115
end
Elv's avatar
Elv committed
116

117
local function Update(self, event, unit)
Blazeflack's avatar
Blazeflack committed
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
	if(not unit or self.unit ~= unit) then return end
	local element = self.Health

	--[[ Callback: Health:PreUpdate(unit)
	Called before the element has been updated.

	* self - the Health element
	* unit - the unit for which the update has been triggered (string)
	--]]
	if(element.PreUpdate) then
		element:PreUpdate(unit)
	end

	local cur, max = UnitHealth(unit), UnitHealthMax(unit)
	local disconnected = not UnitIsConnected(unit)
	element:SetMinMaxValues(0, max)

	if(disconnected) then
		element:SetValue(max)
	else
		element:SetValue(cur)
	end

	element.disconnected = disconnected

	--[[ Override: Health:UpdateColor(unit, cur, max)
	Used to completely override the internal function for updating the widgets' colors.

	* self - the Health element
	* unit - the unit for which the update has been triggered (string)
	* cur  - the unit's current health value (number)
	* max  - the unit's maximum possible health value (number)
	--]]
	element:UpdateColor(unit, cur, max)

	--[[ Callback: Health:PostUpdate(unit, cur, max)
	Called after the element has been updated.

	* self - the Health element
	* unit - the unit for which the update has been triggered (string)
	* cur  - the unit's current health value (number)
	* max  - the unit's maximum possible health value (number)
	--]]
	if(element.PostUpdate) then
		return element:PostUpdate(unit, cur, max)
Elv's avatar
Elv committed
163 164 165
	end
end

Blazeflack's avatar
Blazeflack committed
166 167 168 169 170 171 172 173
local function Path(self, ...)
	--[[ Override: Health.Override(self, event, unit)
	Used to completely override the internal update function.

	* self  - the parent object
	* event - the event triggering the update (string)
	* unit  - the unit accompanying the event (string)
	--]]
Elv's avatar
Elv committed
174 175 176
	return (self.Health.Override or Update) (self, ...)
end

Blazeflack's avatar
Blazeflack committed
177
local function ForceUpdate(element)
Elv's avatar
Elv committed
178 179 180
	return Path(element.__owner, 'ForceUpdate', element.__owner.unit)
end

Merathilis's avatar
Merathilis committed
181 182
--[[ Health:SetFrequentUpdates(state)
Used to toggle frequent updates.
Simpy's avatar
Simpy committed
183

Merathilis's avatar
Merathilis committed
184 185 186 187
* self  - the Health element
* state - the desired state of frequent updates (boolean)
--]]
local function SetFrequentUpdates(element, state)
Azilroka's avatar
Azilroka committed
188 189 190
	if(element.frequentUpdates ~= state) then
		element.frequentUpdates = state
		if(element.frequentUpdates) then
Azilroka's avatar
Azilroka committed
191
			element.__owner:UnregisterEvent('UNIT_HEALTH', Path)
Azilroka's avatar
Azilroka committed
192 193 194
			element.__owner:RegisterEvent('UNIT_HEALTH_FREQUENT', Path)
		else
			element.__owner:UnregisterEvent('UNIT_HEALTH_FREQUENT', Path)
Azilroka's avatar
Azilroka committed
195
			element.__owner:RegisterEvent('UNIT_HEALTH', Path)
Azilroka's avatar
Azilroka committed
196 197
		end
	end
Merathilis's avatar
Merathilis committed
198 199
end

Blazeflack's avatar
Blazeflack committed
200 201 202 203 204
local function Enable(self, unit)
	local element = self.Health
	if(element) then
		element.__owner = self
		element.ForceUpdate = ForceUpdate
Merathilis's avatar
Merathilis committed
205
		element.SetFrequentUpdates = SetFrequentUpdates
Elv's avatar
Elv committed
206

Azilroka's avatar
Azilroka committed
207
		if(element.frequentUpdates) then
Blazeflack's avatar
Blazeflack committed
208
			self:RegisterEvent('UNIT_HEALTH_FREQUENT', Path)
Azilroka's avatar
Azilroka committed
209 210
		else
			self:RegisterEvent('UNIT_HEALTH', Path)
Azilroka's avatar
Azilroka committed
211
		end
Blazeflack's avatar
Blazeflack committed
212 213

		self:RegisterEvent('UNIT_MAXHEALTH', Path)
Elv's avatar
Elv committed
214
		self:RegisterEvent('UNIT_CONNECTION', Path)
Blazeflack's avatar
Blazeflack committed
215
		self:RegisterEvent('UNIT_FACTION', Path) -- For tapping
Elv's avatar
Elv committed
216

Blazeflack's avatar
Blazeflack committed
217 218 219
		if(element:IsObjectType('StatusBar') and not element:GetStatusBarTexture()) then
			element:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]])
		end
Elv's avatar
Elv committed
220

Blazeflack's avatar
Blazeflack committed
221 222
		if(not element.UpdateColor) then
			element.UpdateColor = UpdateColor
Elv's avatar
Elv committed
223 224
		end

Blazeflack's avatar
Blazeflack committed
225 226
		element:Show()

Elv's avatar
Elv committed
227 228 229 230
		return true
	end
end

Blazeflack's avatar
Blazeflack committed
231 232 233 234 235
local function Disable(self)
	local element = self.Health
	if(element) then
		element:Hide()

Elv's avatar
Elv committed
236 237 238 239 240 241 242 243 244
		self:UnregisterEvent('UNIT_HEALTH_FREQUENT', Path)
		self:UnregisterEvent('UNIT_HEALTH', Path)
		self:UnregisterEvent('UNIT_MAXHEALTH', Path)
		self:UnregisterEvent('UNIT_CONNECTION', Path)
		self:UnregisterEvent('UNIT_FACTION', Path)
	end
end

oUF:AddElement('Health', Path, Enable, Disable)