/tags
local addon, ns = ... |
local ok = {} |
local config = { |
----------------------------------------------------------- Cast bar settings -- |
-- TODO: allow player/target frames to be config'd independently |
CastBar = { |
-- show cast bars (at all)? |
enabled = true, |
-- width of the castbar |
-- set to nil to use the width of the parent frame |
width = 250, |
-- height of the castbar |
height = 23, |
-- Show spell icons? |
showSpellIcons = true, |
-- Reposition the castbar when pet/tot frames are shown? |
dynamicPositioning = true, |
-- Show latency area on the player's castbar? |
showSafeZone = true, |
}, |
----------------------------------------------------------------- Media files -- |
-- Fonts ----------------------------------------------------------------------- |
Fonts = { |
n = kui.m.f.yanone, |
o = 'OUTLINE', |
s = 14, |
ss = 10, |
}, |
-- Textures -------------------------------------------------------------------- |
Textures = { |
bar = kui.m.t.bar, |
sbar = kui.m.t.sbar, |
frame = kui.m.t.shadow, |
buff = 'Interface\\AddOns\\oUF_Kui\\media\\border', |
pshade = kui.m.t.innerShade, |
}, |
----------------------------------------------------------------- Frame sizes -- |
-- h = height, w = width, hb = health bar height, pb = power bar height -------- |
-- hb and pb should add up to h - 3 to display correctly in most cases --------- |
Sizes = { |
def = { |
-- Default sizes |
-- player, target, [any nil option below] |
h = 37, |
w = 180, |
hb = 30, |
pb = 4 |
}, |
small = { |
-- focus |
w = 90 |
}, |
thin = { |
-- targettarget |
h = 23, |
hb = 17, |
pb = 3 |
}, |
thinsmall = { |
-- pet, pettarget, party |
w = 89, |
h = 23, |
hb = 17, |
pb = 3 |
}, |
raid = { |
-- raid |
w = 69, -- 58 |
h = 23, |
hb = 17, |
pb = 3 |
}, |
mini = { |
-- focustarget |
w = 30, |
h = 10, |
hb = 8 |
}, |
} |
} |
-------------------------------------------------------------- Slash commands -- |
-- Do not edit below this line ------------------------------------------------- |
function ok:Slash(msg, msgs) |
self.kui:configSlash(msg, msgs) |
end |
function ok:ADDON_LOADED() |
self.kui:registerSaved('oufKuiSaved') |
self.kui:addSetting(nil, 'reset', |
'Reset configuration to defaults. This will reload the UI', nil, |
function() |
_G['oufKuiSaved'] = {} |
ReloadUI() |
end) |
self.kui:addSetting(nil, 'scale', 0, |
'The scale of all frames. Relative from -1 up. For example, a setting of -0.5 (negative) will approximately halve the size of the frames', |
nil, { numL = -1, i = 'Must be a number greater than or equal to minus 1.' }) |
---------------------------------------------------------------------------- |
self.kui:addSettingGroup('pos', 'Position') |
self.kui:addSetting('pos', 'ypos', -300, |
'The vertical position offset of all frames') |
self.kui:addSetting('pos', 'xdist', 260, |
'The distance between the parent frames, player and target') |
---------------------------------------------------------------------------- |
self.kui:addSettingGroup('bars', 'Individual frames') |
self.kui:addSetting('bars', 'invert', false, |
'Fill health bars with colour as they get lower') |
self.kui:addSetting('bars', 'vertical', false, |
'Vertical power bars') |
self.kui:addSetting('bars', 'reverse', true, |
'Reverse bars which are aligned to the right of the screen (target, tot, etc)') |
self.kui:addSetting('bars', 'npcclass', false, |
'Colour NPCs by their class') |
self.kui:addSetting('bars', 'newcolours', true, |
'Use altered reaction (or reputation) colours') |
self.kui:addSetting('bars', 'portraits', true, |
'Show portraits behind health bars') |
self.kui:addSetting('bars', 'transparent', true, |
'Show transparent health bars when portraits are enabled') |
self.kui:addSetting('bars', 'heal', true, |
'Show healing predictions') |
---------------------------------------------------------------------------- |
self.kui:addSettingGroup('self', 'Player & pet frame') |
self.kui:addSetting('self', 'showname', false, |
'Show the name and level of your character') |
self.kui:addSetting('self', 'fade', false, |
'Fade out frames when not in combat') |
self.kui:addSetting('self', 'class', true, |
'Show secondary power bars (holy power, runes, etc)') |
self.kui:addSetting('self', 'combo', true, |
'Show combo points and ability stacks (like maelstrom weapon)') |
---------------------------------------------------------------------------- |
self.kui:addSettingGroup('all', 'Global frame') |
self.kui:addSetting('all', 'threat', true, |
'Show threat highlights') |
self.kui:addSetting('all', 'debufficon', false, |
'Show curable debuff icons over units') |
self.kui:addSetting('all', 'debuffhighlight', true, |
'Show curable debuff highlights (and flash units when their health is taken below 20%)') |
self.kui:addSetting('all', 'sortauras', true, |
'Sort group and target auras by time remaining') |
--[[ TODO |
self.kui:addSetting('all', 'greyscale', true, |
'Greyscale other units\'s auras') |
]] |
---------------------------------------------------------------------------- |
self.kui:addSettingGroup('group', 'Group frames') |
self.kui:addSetting('group', 'healmode', true, |
'Heal mode group frames') |
self.kui:addSetting('group', 'vertical', true, |
'Vertical power bars') |
self.kui:addSetting('group', 'invert', true, |
'Fill health bars will colour as they get lower') |
self.kui:addSetting('group', 'portraits', true, |
'Show portraits behind health bars') |
self.kui:addSetting('group', 'heal', true, |
'Show healing predictions') |
self.kui:addSetting('group', 'fade', true, |
'Fade units which are out of range') |
self.kui:addSlash('OUF_KUI', {'oufkui', 'oufk'}) |
end |
ok.kui = kui:addPlugin(addon, ok) |
ok.kui:addEvent('ADDON_LOADED') |
ns.ok = ok |
ns.c = config |
local _, ns = ... |
c = ns.c |
--[[ |
Rename this file to customConfig.lua in order to use it. |
The file is named such that it won't be overwritten if you use an automatic |
updater or otherwise overwrite files when updating. |
Check config.lua for what settings exist and what they do. |
For example, to hide spell icons, use the following. |
c.CastBar.showSpellIcons = false |
To make player and target bars 20px wider, use the following. |
c.Sizes.def.w = 200 |
etc. |
Settings which are managed by slash commands (/oufk or /oufkui) cannot be |
changed by this file. Options must each be on their own line. |
]] |
-- Edit below this line -------------------------------------------------------- |
## Interface: 40200 |
## Author: Kesava |
## Title: oUF_|cff9900ffKui|r |
## OptionalDeps: oUF_Smooth, oUF_CombatFeedback |
## RequiredDeps: oUF, Kui |
## SavedVariables: oufKuiSaved |
elements\BarFader.lua |
elements\ClassBars.lua |
elements\ThreatHighlight.lua |
elements\DebuffFlash.lua |
config.lua |
customConfig.lua |
whitelist.lua |
global.lua |
layout.lua |
--[[ |
Class bars |
Totems, runes, shards, druid mana & holy power |
By Kesava for oUF Kui |
]] |
-------------------------------------------------------- Utility funtions -- |
-- Arranges bars into columns depending on which bars are visible |
local function ArrangeBars(cb) |
local bar = cb.bars[1] |
local pv, pc, shown |
shown = 0 |
-- pv = previous visible bar |
-- pc = previous visible bar which starts a column |
for i = 1, #cb.bars do |
local nbar = cb.bars[i] |
if nbar.bg:IsShown() then |
nbar.bg:ClearAllPoints() |
if not pv then |
-- anchor to the unit frame |
nbar.bg:SetPoint('BOTTOMRIGHT') |
pc = nbar |
else |
-- find the correct anchor point |
if shown % cb.container.rows == 0 then |
-- left of the previous column |
nbar.bg:SetPoint( |
'BOTTOMRIGHT', pc.bg, 'BOTTOMLEFT', |
-cb.container.space, 0) |
pc = nbar |
else |
-- above the previous frame |
nbar.bg:SetPoint('BOTTOM', pv.bg, 'TOP', 0, cb.container.space) |
end |
end |
shown = shown + 1 |
pv = nbar |
end |
end |
end |
-- Hides the given bar and calls ArrangeBars if needed |
local function HideBar(self, bar) |
local cb = self.ClassBars |
bar.bg:Hide() |
if cb.bars[bar.id+1] then |
ArrangeBars(cb) |
end |
end |
-- Shows the given bar and calls ArrangeBars |
local function ShowBar(self, bar) |
local cb = self.ClassBars |
bar.bg:Show() |
ArrangeBars(cb) |
end |
------------------------------------------------------- Update Totem Bars -- |
local function UpdateShamanBar(self, bar) |
local haveTotem, totemName, startTime, duration = GetTotemInfo(bar.id) |
if haveTotem then |
bar.name = totemName |
bar.tl = (startTime + duration - GetTime()) |
if bar.tl >= 0 then |
local total = 0 |
ShowBar(self, bar) |
bar:SetValue(1 - ((GetTime() - startTime) / duration)) |
bar:SetScript('OnUpdate', function(self, elapsed) |
total = total + elapsed |
if total > 0.1 then |
total = 0 |
local haveTotem, totemName, startTime, duration = GetTotemInfo(self.id) |
self:SetValue(1 - ((GetTime() - startTime) / duration)) |
self.tl = (startTime + duration - GetTime()) |
end |
end) |
else |
bar:SetScript('OnUpdate', nil) |
HideBar(self, bar) |
end |
else |
HideBar(self, bar) |
end |
end |
local function ShamanTooltip(bar) |
if bar.name then |
local tl, delim = bar.tl, 's' |
if tl > 60 then |
tl = tl / 60 |
delim = 'm' |
end |
tl = floor(tl) |
return { |
bar.name, |
{ |
t = tl .. delim, |
c = { r = .6, g = .6, b = .6 } |
} |
} |
end |
end |
------------------------------------------------------------ Update Runes -- |
local function UpdateDeathKnightBar(self, bar) |
local type, startTime, duration, charged = GetRuneType(bar.id), GetRuneCooldown(bar.id) |
if not type then return end |
bar:SetStatusBarColor(unpack(self.ClassBars.colours[type])) |
bar.tl = startTime + duration - GetTime() |
if not charged then |
bar:SetValue((GetTime() - startTime) / duration) |
if not bar:GetScript('OnUpdate') then |
bar.bg:SetAlpha(.3) |
bar:SetScript('OnUpdate', function(self, elapsed) |
self.elapsed = (self.elapsed or 0) + elapsed |
if self.elapsed > 0.1 then |
self.elapsed = 0 |
local startTime, duration = GetRuneCooldown(bar.id) |
bar:SetValue((GetTime() - startTime) / duration) |
end |
end) |
end |
else |
bar.bg:SetAlpha(1) |
bar:SetValue(1) |
bar:SetScript('OnUpdate', nil) |
end |
end |
------------------------------------------------------- Update druid bars -- |
local function UpdateDruid(self, event) |
local cb = self.ClassBars |
-- Eclipse ------------------------------------------------------------- |
if event == 'UPDATE_SHAPESHIFT_FORM' or |
event == 'PLAYER_ENTERING_WORLD' or |
not event |
then |
-- toggle bars depending on form |
if GetShapeshiftFormID() == MOONKIN_FORM then |
ShowBar(self, cb.bars[1]) |
else |
HideBar(self, cb.bars[1]) |
end |
end |
if cb.bars[1].bg:IsShown() then |
local curr = UnitPower('player', SPELL_POWER_ECLIPSE) |
cb.bars[1]:SetValue(curr < 0 and -curr or curr) |
if curr > 0 then |
-- solar |
cb.bars[1]:SetStatusBarColor(238/255, 200/255, 77/255) |
cb.bars[1].col:SetVertexColor(156/255, 99/255, 16/255) |
else |
-- lunar |
cb.bars[1]:SetStatusBarColor(60/255, 150/255, 220/255) |
cb.bars[1].col:SetVertexColor(32/255, 53/255, 120/255) |
end |
end |
-- Mana ---------------------------------------------------------------- |
local shown = false |
if UnitPowerType('player') ~= 0 then |
local curr, max = |
UnitPower('player', 0), UnitPowerMax('player', 0) |
if curr ~= max then |
local per = (curr / max) * 100 |
cb.bars[2]:SetValue(per) |
cb.bars[2].bg:Show() |
shown = true |
end |
end |
if not shown and cb.bars[2].bg:IsShown() then |
cb.bars[2].bg:Hide() |
end |
end |
------------------------------------------------ Update Shards/Holy Power -- |
local function UpdateWarlockPaladin(self, event, ...) |
local cb, visible, curr = self.ClassBars, 0 |
curr = UnitPower('player', cb.type) |
for i = 1, 3 do |
if curr >= i then |
visible = visible + 1 |
cb.bars[i].bg:SetAlpha(1) |
else |
cb.bars[i].bg:SetAlpha(.3) |
end |
end |
if cb.class == 'PALADIN' then |
-- hide bars if none are visible |
if visible > 0 then |
cb.container:Show() |
else |
cb.container:Hide() |
end |
else |
-- or if they are all visible |
if visible == 3 then |
cb.container:Hide() |
else |
cb.container:Show() |
end |
end |
end |
--[[----------------------------------------------------- Update function -- |
Calls cb.o.update.f(self) |
Calls cb.o.update.b(self, bar) for each bar created by Create() |
]] |
local function Update(self, event, ...) |
local cb = self.ClassBars |
if event == 'UNIT_POWER' or event == 'UNIT_AURA' then |
local unit = ... |
if unit ~= self.unit then return end |
end |
if cb.o.update.f then |
cb.o.update.f(self, event, ...) |
end |
if cb.o.update.b then |
for k, b in pairs(cb.bars) do |
cb.o.update.b(self, b) |
end |
end |
end |
--[[----------------------------------------------------- Create function -- |
Creates bars from cb.o object |
Calls cb.o.create(self) upon completion |
Also forces Update with nil event |
]] |
local function Create(self) |
local cb = self.ClassBars |
cb.bars = {} |
local space = 2 |
local rows = cb.o.bars.rows or 1 |
local columns = #cb.o.bars / rows |
local height = (cb.height / rows) - (space * (rows - 1)) / rows |
-- create container (always shown) |
cb.container = CreateFrame("Frame", nil, self) |
cb.container:SetWidth((cb.width * columns) + (space * (columns - 1))) |
cb.container:SetHeight(cb.height) |
cb.container:SetPoint('RIGHT', self, 'LEFT', 2, 0) |
cb.container.rows = rows |
cb.container.space = space |
-- create bars, default method |
-- anchor first to topleft of frame |
-- anchor subsequent bars to the previous |
for k, v in ipairs(cb.o.bars) do |
local bg = CreateFrame("Frame", nil, cb.container) |
local b = CreateFrame("StatusBar", nil, bg) |
bg:SetBackdrop({ bgFile = kui.m.t.sbar }) |
bg:SetBackdropColor(.05, .05, .05) |
bg:SetWidth(cb.width) |
bg:SetHeight(height) |
if (k-1) % rows == 0 then |
if k == 1 then |
bg:SetPoint('BOTTOMRIGHT') |
else |
bg:SetPoint('BOTTOMRIGHT', cb.bars[k - rows].bg, 'BOTTOMLEFT', -space, 0) |
end |
else |
bg:SetPoint('BOTTOM', cb.bars[k - 1].bg, 'TOP', 0, space) |
end |
b:SetOrientation('VERTICAL') |
b:SetPoint('TOPLEFT', bg, 'TOPLEFT', 1, -1) |
b:SetPoint('BOTTOMRIGHT', bg, 'BOTTOMRIGHT', -1, 1) |
b:SetStatusBarTexture(kui.m.t.sbar) |
b:SetStatusBarColor(unpack(v.colour or cb.o.bars.colour or {1,1,1})) |
b:SetMinMaxValues(unpack(v.minmax or cb.o.bars.minmax or {0,1})) |
b.bg = bg |
b.id = k |
if cb.o.tooltip then |
b:EnableMouse(true) |
b:SetScript('OnEnter', function(self) |
lines = cb.o.tooltip(self) |
if lines and #lines > 0 then |
GameTooltip:SetOwner(self.bg, 'ANCHOR_CURSOR') |
for _, line in pairs(lines) do |
if line.t and line.c then |
GameTooltip:AddLine(line.t, line.c.r, line.c.g, line.c.b) |
else |
GameTooltip:AddLine(line) |
end |
end |
GameTooltip:Show() |
end |
end) |
b:SetScript('OnLeave', function() |
GameTooltip:Hide() |
end) |
end |
cb.bars[k] = b |
end |
-- register events |
for k, e in pairs(cb.o.events) do |
self:RegisterEvent(e, Update) |
end |
self:RegisterEvent('PLAYER_ENTERING_WORLD', Update) |
-- call post create |
if cb.o.create then |
cb.o.create(self) |
end |
Update(self) |
end |
-------------------------------------------------------- Enable ClassBars -- |
local function Enable(self, unit) |
local cb = self.ClassBars or nil |
if not cb then return end |
if |
cb.class ~= "SHAMAN" and cb.class ~= "DEATHKNIGHT" and |
cb.class ~= "DRUID" and cb.class ~= "PALADIN" and |
cb.class ~= "WARLOCK" |
then |
cb = nil |
return |
end |
cb.HideBar = HideBar |
cb.o = { |
bars = {}, |
update = {}, |
events = {} |
} |
------------------------------------------------------- Create Totem Bars -- |
if cb.class == 'SHAMAN' then |
cb.o.bars = { |
[1] = { colour = {255/255, 109/255, 22/255} }, -- fire |
[2] = { colour = {120/255, 255/255, 60/255} }, -- earth |
[3] = { colour = {112/255, 65/255, 255/255} }, -- air |
[4] = { colour = {112/255, 255/255, 255/255} }, -- water |
rows = 2 |
} |
cb.o.events = { 'PLAYER_TOTEM_UPDATE' } |
cb.o.update.b = UpdateShamanBar |
cb.o.tooltip = ShamanTooltip |
------------------------------------------------------------ Create Runes -- |
elseif cb.class == 'DEATHKNIGHT' then |
cb.o.bars = { |
[1] = {}, [2] = {}, [3] = {}, [4] = {}, [5] = {}, [6] = {}, |
rows = 2 |
} |
cb.o.events = { 'RUNE_POWER_UPDATE', 'RUNE_TYPE_UPDATE' } |
cb.o.create = function(self) |
RuneFrame:Hide() |
self.ClassBars.colours = { |
[1] = { .7, 0, 0 }, -- blood |
[2] = { .3, .7, 0 }, -- unholy |
[3] = { .2, .2, .8 }, -- frost |
[4] = { 1, .5, 0 } -- death |
} |
end |
cb.o.update.b = UpdateDeathKnightBar |
---------------------------------------------------------- Create Eclipse -- |
elseif cb.class == 'DRUID' then |
cb.o.bars = { |
[1] = { colour = { 111/255, 186/255, 245/255 } }, -- lunar |
[2] = { colour = { 78/255, 95/255, 190/255 } }, -- mana |
minmax = { 0, 100 } |
} |
cb.o.events = { |
'UPDATE_SHAPESHIFT_FORM', |
'ECLIPSE_DIRECTION_CHANGE', |
'UNIT_POWER', 'UNIT_MAXPOWER' |
} |
cb.o.create = function(self) |
-- create bar background |
cb.bars[1].col = cb.bars[1]:CreateTexture(nil, 'BACKGROUND') |
cb.bars[1].col:SetTexture(kui.m.t.sbar) |
cb.bars[1].col:SetAllPoints(cb.bars[1]) |
cb.bars[1].col:SetVertexColor(32/255, 53/255, 120/255, .8) |
end |
cb.o.update.f = UpdateDruid |
------------------------------------------------ Create Shards/Holy Power -- |
elseif cb.class == 'PALADIN' or cb.class == 'WARLOCK' then |
local colour |
if cb.class == 'PALADIN' then |
cb.type = SPELL_POWER_HOLY_POWER |
colour = { 1, 1, 0 } |
else |
cb.type = SPELL_POWER_SOUL_SHARDS |
colour = { .5, 0, 1 } |
end |
cb.o.bars = { |
[1] = {}, [2] = {}, [3] = {}, |
colour = colour, |
rows = 3 |
} |
cb.o.events = { 'UNIT_POWER' } |
cb.o.update.f = UpdateWarlockPaladin |
end |
Create(self) |
end |
oUF:AddElement("ClassBars", nil, Enable, nil) |
--[[ |
Threat Highlighting |
Changes the colour of the backdrop border |
By Kesava for oUF_Kui |
--]] |
local function Update(self, event, unit) |
if unit ~= self.unit then return end |
local status = UnitThreatSituation(unit) |
if status and status > 0 then |
local r, g, b = GetThreatStatusColor(status) |
self:SetBackdropBorderColor(r, g, b, .5) |
else |
self:SetBackdropBorderColor(0, 0, 0, .3) |
end |
end |
local function Enable(self) |
if self.KuiThreat then |
self:RegisterEvent('UNIT_THREAT_SITUATION_UPDATE', Update) |
return true |
end |
end |
local function Disable(self) |
if self.KuiThreat then |
self:UnregisterEvent('UNIT_THREAT_SITUATION_UPDATE', Update) |
end |
end |
oUF:AddElement('KuiThreat', Update, Enable, Disable) |
--[[ |
Usage: |
BarFade = true |
BarFadeMinAlpha = .2 [default: 0] |
BarFadeMidAlpha = .7 [default: .5] |
BarFadeMaxAlpha = 1 [default: 1] |
Modified by Kesava for oUF_Kui |
--]] |
local function pending(self, unit) |
local num, str = UnitPowerType(unit) |
local ut = unit..'target' |
if (self:IsMouseOver()) or -- moused over |
(self.Castbar and self.BarFade.casting) or -- casting |
(UnitAffectingCombat(unit)) or -- in combat |
(UnitExists(ut) and ( -- target [which is |
not UnitIsDead(ut) and -- not dead and |
not UnitIsFriend(unit, ut)) -- hostile |
) -- ] |
then |
return 1 |
elseif |
((str ~= 'RAGE' and str ~= 'RUNIC_POWER') and |
((UnitPower(unit) / UnitPowerMax(unit)) * 100) < 90 |
) or |
((str == 'RAGE' or str == 'RUNIC_POWER') and |
UnitPower(unit) > 10 |
) or |
(((UnitHealth(unit) / UnitHealthMax(unit)) * 100) < 90) |
then |
return .5 |
else |
return 0 |
end |
end |
local function update(self, event, unit) |
if (unit and unit ~= self.unit) then return end |
if event == 'UNIT_SPELLCAST_START' or event == 'UNIT_SPELLCAST_CHANNEL_START' then |
self.BarFade.casting = true |
elseif |
event == 'UNIT_SPELLCAST_FAILED' or |
event == 'UNIT_SPELLCAST_STOP' or |
event == 'UNIT_SPELLCAST_INTERRUPTED' or |
event == 'UNIT_SPELLCAST_CHANNEL_INTERRUPTED' or |
event == 'UNIT_SPELLCAST_CHANNEL_STOP' |
then |
self.BarFade.casting = false |
end |
local fadeTo, fadeFrom, duration |
= pending(self, self.unit), self:GetAlpha() |
if fadeTo == 1 then |
fadeTo = self.BarFadeMaxAlpha or 1 |
elseif fadeTo == .5 then |
fadeTo = self.BarFadeMidAlpha or .5 |
else |
fadeTo = self.BarFadeMinAlpha or 0 |
end |
if fadeTo ~= fadeFrom and fadeTo ~= self.BarFade.to then |
local fadeChange = (fadeTo - fadeFrom) |
self.BarFade.to = fadeTo |
if fadeChange < 0 then |
-- fade out slowly |
duration = 5 * fadeChange |
else |
-- fade in quickly |
duration = .5 * fadeChange |
end |
self.BarFade.ag:Stop() |
self:SetAlpha(fadeFrom) |
self.BarFade.fade:SetDuration((duration < 0) and -duration or duration) |
self.BarFade.fade:SetChange(fadeChange) |
self.BarFade.ag:Play() |
end |
end |
local function enable(self, unit) |
if(unit and self.BarFade) then |
self.BarFade = {} |
self.BarFade.ag = self:CreateAnimationGroup() |
self.BarFade.fade = self.BarFade.ag:CreateAnimation('Alpha') |
self.BarFade.ag:SetScript('OnFinished', function() |
self:SetAlpha(self.BarFade.to) |
self.BarFade.to = nil |
end) |
self:HookScript('OnEnter', update) |
self:HookScript('OnLeave', update) |
self:RegisterEvent('PLAYER_LOGIN', update) |
self:RegisterEvent('PLAYER_TARGET_CHANGED', update) |
self:RegisterEvent('UNIT_TARGET', update) |
self:RegisterEvent('UNIT_COMBAT', update) |
self:RegisterEvent('UNIT_HAPPINESS', update) |
self:RegisterEvent('UNIT_FOCUS', update) |
self:RegisterEvent('UNIT_HEALTH', update) |
self:RegisterEvent('UNIT_POWER', update) |
self:RegisterEvent('UNIT_ENERGY', update) |
self:RegisterEvent('UNIT_RAGE', update) |
self:RegisterEvent('UNIT_MANA', update) |
self:RegisterEvent('UNIT_RUNIC_POWER', update) |
self:RegisterEvent('PLAYER_REGEN_ENABLED', update) |
self:RegisterEvent('PLAYER_REGEN_DISABLED', update) |
if(self.Castbar) then |
self:RegisterEvent('UNIT_SPELLCAST_START', update) |
self:RegisterEvent('UNIT_SPELLCAST_FAILED', update) |
self:RegisterEvent('UNIT_SPELLCAST_STOP', update) |
self:RegisterEvent('UNIT_SPELLCAST_INTERRUPTED', update) |
self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_START', update) |
self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_INTERRUPTED', update) |
self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_STOP', update) |
end |
return true |
end |
end |
local function disable(self) |
if(self.BarFade) then |
self:UnregisterEvent('PLAYER_LOGIN', update) |
self:UnregisterEvent('PLAYER_TARGET_CHANGED', update) |
self:UnregisterEvent('UNIT_TARGET', update) |
self:UnregisterEvent('UNIT_COMBAT', update) |
self:UnregisterEvent('UNIT_HAPPINESS', update) |
self:UnregisterEvent('UNIT_FOCUS', update) |
self:UnregisterEvent('UNIT_HEALTH', update) |
self:UnregisterEvent('UNIT_POWER', update) |
self:UnregisterEvent('UNIT_ENERGY', update) |
self:UnregisterEvent('UNIT_RAGE', update) |
self:UnregisterEvent('UNIT_MANA', update) |
self:UnregisterEvent('UNIT_RUNIC_POWER', update) |
self:UnregisterEvent('PLAYER_REGEN_ENABLED', update) |
self:UnregisterEvent('PLAYER_REGEN_DISABLED', update) |
if(self.Castbar) then |
self:UnregisterEvent('UNIT_SPELLCAST_START', update) |
self:UnregisterEvent('UNIT_SPELLCAST_FAILED', update) |
self:UnregisterEvent('UNIT_SPELLCAST_STOP', update) |
self:UnregisterEvent('UNIT_SPELLCAST_INTERRUPTED', update) |
self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_START', update) |
self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_INTERRUPTED', update) |
self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_STOP', update) |
end |
end |
end |
oUF:AddElement('BarFader', update, enable, disable) |
--[[ |
Debuff Flash |
Pulsates over the provided parent frame when a target has a curable |
debuff. Flashes red when a unit is taken below 20%. |
self.KuiDebuffPulse = { |
f = [frame to highlight], |
h = [true to display highlight], |
i = [true to display icon] |
} |
Credit to oUF_DebuffHighlight for parts of this |
By Kesava for oUF_Kui |
]] |
local class = select(2, UnitClass("player")) |
local dispelList = { |
PRIEST = { Magic = true, Disease = true, }, |
SHAMAN = { Magic = true, Curse = true, }, |
PALADIN = { Magic = true, Poison = true, Disease = true, }, |
MAGE = { Curse = true, }, |
DRUID = { Magic = true, Curse = true, Poison = true, } |
} |
local function CanDispel(type) |
if dispelList[class] then |
return dispelList[class][type] |
else |
return nil |
end |
end |
local function GetDebuff(unit) |
if not UnitCanAssist('player', unit) then return end |
local i, _, name, type = 0 |
while true do |
i = i + 1 |
name, _, icon, count, type = UnitAura(unit, i, 'HARMFUL') |
if not name then break end |
if type and CanDispel(type) then |
return type, icon, count |
end |
end |
end |
local function Update(self, event, unit) |
if unit and self.unit ~= unit then return end |
local dp = self.KuiDebuffPulse.DebuffPulse |
local f = dp.flash |
if f and |
(event == 'UNIT_HEALTH' or |
event == 'OnUpdate' or |
event == 'OnShow') |
then |
-- flash when a unit is taken below 20% health |
local hp, max, per = UnitHealth(unit), UnitHealthMax(unit) |
per = (hp / max) * 100 |
if f.prevHpGUID ~= UnitGUID(self.unit) then |
-- reset previous health when unit is changed |
f.prevHp = nil |
end |
if (not f.prevHp or f.prevHp > 20) and |
per <= 20 and |
not f.pulse:IsPlaying() |
then |
-- show health flash only if pulse is not already playing and if the |
-- unit just reached < 20% |
f:SetVertexColor(1, 0, 0) |
f.flash:Play() |
end |
f.prevHp = per |
f.prevHpGUID = UnitGUID(self.unit) |
end |
if (f or dp.icon) and |
(event == 'UNIT_AURA' or |
(event == 'PLAYER_TARGET_CHANGED' and unit == 'target') or |
(event == 'PLAYER_FOCUS_CHANGED' and unit == 'focus')) |
then |
-- show debuff highlight/icon when a unit has a curable debuff |
local type, icon, count = GetDebuff(unit) |
--local type, icon, count = 'Magic', 'INTERFACE\\ICONS\\spell_warlock_focusshadow', 2 |
local i = dp.icon |
local c = dp.count |
if type then |
if f then |
-- play highlight animation |
local col = DebuffTypeColor[type] |
f:SetVertexColor(col.r, col.g, col.b) |
f.pulse:Play() |
end |
if i then |
-- and/or show icon & stack count |
if icon then |
i:SetTexture(icon) |
i:Show() |
end |
if count > 1 then |
c:SetText(count) |
c:Show() |
end |
end |
else |
-- there is no debuff; |
-- clear highlight/icon |
if f then |
f.pulse:Stop() |
end |
if i then |
i:Hide() |
c:Hide() |
end |
end |
end |
end |
local function Enable(self) |
if self.KuiDebuffPulse then |
self.KuiDebuffPulse.DebuffPulse = { |
container = CreateFrame("Frame", nil, self.KuiDebuffPulse.f) |
} |
local dp = self.KuiDebuffPulse.DebuffPulse |
if self.KuiDebuffPulse.h then |
-- create highlight |
dp.flash = dp.container:CreateTexture(nil, 'OVERLAY') |
local f = dp.flash |
f:SetAllPoints(self.KuiDebuffPulse.f) |
f:SetTexture(kui.m.t.innerShade) |
f:SetVertexColor(1, 1, 1) |
f:Hide() |
-- Pulse animations ------------------------------------------------ |
f.pulse = f:CreateAnimationGroup() |
f.pulse.a = f.pulse:CreateAnimation('Alpha') |
f.pulse:SetLooping('BOUNCE') |
f.pulse.a:SetDuration(1) |
f.pulse.a:SetChange(-.3) |
f.pulse.a:SetSmoothing('IN_OUT') |
-- Flash animations ------------------------------------------------ |
f.flash = f:CreateAnimationGroup() |
f.flash.a = f.flash:CreateAnimation('Alpha') |
f.flash.a:SetDuration(.5) |
f.flash.a:SetChange(-1) |
f.flash.a:SetSmoothing('IN') |
-- Scripts --------------------------------------------------------- |
f.flash:SetScript('OnPlay', function(self) |
f:SetAlpha(1) |
f:Show() |
end) |
f.pulse:SetScript('OnPlay', function() |
f:SetAlpha(.5) |
f:Show() |
end) |
local Reset = function() |
f:Hide() |
f:SetVertexColor(1, 1, 1) |
end |
f.flash:SetScript('OnStop', Reset) |
f.flash:SetScript('OnFinished', Reset) |
f.pulse:SetScript('OnStop', Reset) |
end |
if self.KuiDebuffPulse.i then |
-- create icon |
dp.icon = dp.container:CreateTexture(nil, 'OVERLAY') |
dp.count = kui.CreateFontString(dp.container, { size = 11, outline = 'OUTLINE' }) |
local i, c = |
dp.icon, dp.count |
i:SetPoint('CENTER', self.Health) |
i:SetSize(self.Health:GetHeight() - 4, self.Health:GetHeight() - 4) |
i:SetVertexColor(1, 1, 1) |
i:Hide() |
c:SetPoint('BOTTOMRIGHT', i, 2, 0) |
c:Hide() |
end |
-- events for low health bar flashing |
self:RegisterEvent('UNIT_HEALTH', Update) |
self:RegisterEvent('PLAYER_TARGET_CHANGED', Update) |
self:RegisterEvent('PLAYER_FOCUS_CHANGED', Update) |
if dispelList[class] then |
-- events for curable debuff highlighting & icons |
self:RegisterEvent('UNIT_AURA', Update) |
self:RegisterEvent('PLAYER_TALENT_UPDATE', Update) |
self:RegisterEvent('CHARACTER_POINTS_CHANGED', Update) |
end |
return true |
end |
end |
local function Disable(self) |
if self.KuiDebuffPulse then |
self:UnregisterEvent('UNIT_HEALTH', Update) |
self:UnregisterEvent('PLAYER_TARGET_CHANGED', Update) |
self:UnregisterEvent('PLAYER_FOCUS_CHANGED', Update) |
self:UnregisterEvent('UNIT_AURA', Update) |
self:UnregisterEvent('PLAYER_TALENT_UPDATE', Update) |
self:UnregisterEvent('CHARACTER_POINTS_CHANGED', Update) |
self.KuiDebuffPulse.DebuffPulse = nil |
end |
end |
oUF:AddElement('KuiFlash', Update, Enable, Disable) |
local _, ns = ... |
local whitelist = { |
-------------------------------------------------------- Spell whitelists -- |
-- Spells to track in the combo points frame ------------------------------- |
-- Value is the maximum amount of stacks |
CountSpells = { |
WARRIOR = { |
[GetSpellInfo(84584)] = 1, -- Slaughter |
[GetSpellInfo(84585)] = 2, |
[GetSpellInfo(84586)] = 3, |
[GetSpellInfo(87095)] = 3, -- Thunderstruck |
[GetSpellInfo(87096)] = 3, |
[GetSpellInfo(85738)] = 3, -- Meat Cleaver |
[GetSpellInfo(85739)] = 3, |
}, |
SHAMAN = { |
[GetSpellInfo(53817)] = 5, -- Maelstrom Weapon |
[GetSpellInfo(51562)] = 2, -- Tidal Waves |
[GetSpellInfo(51563)] = 2, |
[GetSpellInfo(51564)] = 2, |
}, |
WARLOCK = { |
[GetSpellInfo(54277)] = 3, -- Backdraft |
[GetSpellInfo(54276)] = 3, |
[GetSpellInfo(54274)] = 3 |
}, |
PRIEST = { |
[GetSpellInfo(63731)] = 2, -- Serendipity |
[GetSpellInfo(63735)] = 2, |
}, |
HUNTER = { |
[GetSpellInfo(82925)] = 5, -- Ready, Set, Aim (Master Marksman) |
}, |
}, |
-- TODO: These cannot collide. Fix that. |
-- TODO: Lacerate & Arcane Blast would be good candidates for this |
-- Unfortunately they are effects on the target |
-- So make it support target effects |
-- Important spells -------------------------------------------------------- |
-- These appear larger and in seperate frames on the target, and are the |
-- only buffs/debuffs shown on party frames. They must also be your own. |
-- Only buffs with a colour setting will be shown on raid frames. |
DRUID = { -- 4.2 |
[GetSpellInfo(774)] = { colour = { .7, 0, 1 }}, -- Rejuvenation |
[GetSpellInfo(33763)] = { colour = { 0, 1, 0 }, maxc = 3 }, -- Lifebloom |
[GetSpellInfo(8936)] = { colour = { .1, .5, .1 }}, -- Regrowth |
[GetSpellInfo(48438)] = { colour = { .2, .2, 1 }}, -- Wild Growth |
[GetSpellInfo(467)] = true, -- Thorns |
[GetSpellInfo(1126)] = true, -- Mark of the Wild |
[GetSpellInfo(770)] = true, -- Faerie Fire |
[GetSpellInfo(339)] = true, -- Entangling Roots |
[GetSpellInfo(8921)] = true, -- Moonfire |
[GetSpellInfo(93402)] = true, -- Sunfire |
[GetSpellInfo(5570)] = true, -- Insect Swarm |
[GetSpellInfo(16857)] = true, -- Faerie Fire (Feral) |
[GetSpellInfo(1079)] = true, -- Rip |
[GetSpellInfo(1822)] = true, -- Rake |
[GetSpellInfo(22570)] = true, -- Maim |
[GetSpellInfo(33876)] = true, -- Mangle (Cat) |
[GetSpellInfo(33878)] = true, -- Mangle (Bear) |
[GetSpellInfo(33745)] = true, -- Lacerate |
[GetSpellInfo(77758)] = true, -- Thrash |
-- untriggered |
[GetSpellInfo(48496)] = true, -- Living Seed 1 |
[GetSpellInfo(48499)] = true, -- Living Seed 2 |
[GetSpellInfo(48500)] = true, -- Living Seed 3 |
[GetSpellInfo(58179)] = true, -- Infected Wounds 1 |
[GetSpellInfo(58180)] = true, -- Infected Wounds 2 |
}, |
HUNTER = { -- 4.0.3 |
[GetSpellInfo(136)] = true, -- Mend Pet |
[GetSpellInfo(1130)] = true, -- Hunter's Mark |
[GetSpellInfo(82654)] = true, -- Widow Venom |
[GetSpellInfo(3674)] = true, -- Black Arrow |
[GetSpellInfo(19386)] = true, -- Wyvern Sting |
[GetSpellInfo(1978)] = true, -- Serpent Sting |
[GetSpellInfo(5116)] = true, -- Concussive Shot |
[GetSpellInfo(19503)] = true, -- Scatter Shot |
[GetSpellInfo(34490)] = true, -- Silencing Shot |
[GetSpellInfo(2974)] = true, -- Wing Clip |
[GetSpellInfo(19185)] = true, -- Entrapment 1 |
[GetSpellInfo(64803)] = true, -- Entrapment 2 |
-- untriggered |
-- piercing shots, 63468 |
-- marked for death |
-- TODO: need to work out a way to include traps (global list) |
}, |
MAGE = { |
[GetSpellInfo(54646)] = { colour = { .2, .8, .2 }}, -- Focus Magic |
[GetSpellInfo(80353)] = true, -- Time Warp |
[GetSpellInfo(130)] = true, -- Slow Fall |
[GetSpellInfo(118)] = true, -- Polymorph sheep |
[GetSpellInfo(61305)] = true, -- Polymorph cat |
[GetSpellInfo(28272)] = true, -- Polymorph pig |
[GetSpellInfo(61721)] = true, -- Polymorph rabbit |
[GetSpellInfo(61780)] = true, -- Polymorph turkey |
[GetSpellInfo(28271)] = true, -- Polymorph turtle |
[GetSpellInfo(44457)] = true, -- Living Bomb |
[GetSpellInfo(31661)] = true, -- Dragon's Breath |
[GetSpellInfo(22959)] = true, -- Critical Mass |
[GetSpellInfo(31589)] = true, -- Slow |
[GetSpellInfo(44572)] = true, -- Deep Freeze |
[GetSpellInfo(120)] = true, -- Cone of Cold |
[GetSpellInfo(122)] = true, -- Frost Nova |
[GetSpellInfo(116)] = true, -- Frostbolt |
[GetSpellInfo(11366)] = true, -- Pryoblast |
[GetSpellInfo(36032)] = true, -- Arcane Blast |
-- TODO: ignite |
}, |
DEATHKNIGHT = { -- 4.0.6 |
[GetSpellInfo(3714)] = true, -- Path of Frost |
[GetSpellInfo(57330)] = { colour = { .8, .5, 0 }}, -- Horn of Winter |
[GetSpellInfo(49016)] = true, -- Unholy Frenzy |
[GetSpellInfo(59879)] = true, -- Blood Plague |
[GetSpellInfo(59921)] = true, -- Frost Fever |
[GetSpellInfo(47476)] = true, -- Strangulate |
[GetSpellInfo(45524)] = true, -- Chains of Ice |
[GetSpellInfo(49203)] = true, -- Hungering Cold |
-- untriggered |
[GetSpellInfo(65142)] = true, -- Ebon Plague (probably) |
[GetSpellInfo(49194)] = true, -- Unholy Blight |
[GetSpellInfo(43265)] = true, -- Death and Decay |
[GetSpellInfo(55741)] = true, -- Desecration 1 |
[GetSpellInfo(68766)] = true, -- Desecration 2 |
}, |
WARRIOR = { -- 4.0.3 |
[GetSpellInfo(6673)] = { colour = { .8, .5, 0 }}, -- Battle Shout |
[GetSpellInfo(469)] = { colour = { .8, .5, 0 }}, -- Commanding Shout |
[GetSpellInfo(50720)] = { colour = { .7, 0, 1 }}, -- Vigilance |
[GetSpellInfo(7386)] = true, -- Sunder Armor |
[GetSpellInfo(772)] = true, -- Rend |
[GetSpellInfo(6343)] = true, -- Thunder Clap |
[GetSpellInfo(46968)] = true, -- Shockwave |
[GetSpellInfo(12809)] = true, -- Concussion Blow |
[GetSpellInfo(86346)] = true, -- Colossus Smash |
[GetSpellInfo(1715)] = true, -- Hamstring |
[GetSpellInfo(676)] = true, -- Disarm |
[GetSpellInfo(12323)] = true, -- Piercing Howl |
[GetSpellInfo(5246)] = true, -- Intimidating Shout |
[GetSpellInfo(1160)] = true, -- Demoralizing Shout |
[GetSpellInfo(1161)] = true, -- Challenging Shout |
}, |
PALADIN = { -- 4.2 |
[GetSpellInfo(70940)] = true, -- Divine Guardian |
[GetSpellInfo(1022)] = true, -- Hand of Protection |
[GetSpellInfo(1044)] = true, -- Hand of Freedom |
[GetSpellInfo(1038)] = true, -- Hand of Salvation |
[GetSpellInfo(6940)] = true, -- Hand of Sacrifice |
[GetSpellInfo(19740)] = { colour = { .8, .5, 0 }}, -- Blessing of Might |
[GetSpellInfo(20217)] = { colour = { .7, 0, 1 }}, -- Blessing of Kings |
[GetSpellInfo(53563)] = { colour = { 1, .5, 0 }}, -- Beacon of Light |
[GetSpellInfo(76669)] = true, -- Illuminated Healing |
[GetSpellInfo(879)] = true, -- Exorcism |
[GetSpellInfo(26573)] = true, -- Consecration |
[GetSpellInfo(31803)] = true, -- Censure |
[GetSpellInfo(853)] = true, -- Hammer of Justice |
[GetSpellInfo(2812)] = true, -- Holy Wrath |
[GetSpellInfo(10326)] = true, -- Turn Evil |
[GetSpellInfo(20066)] = true, -- Repentance |
}, |
WARLOCK = { -- 4.2 |
-- ... so, everything? |
[GetSpellInfo(5697)] = true, -- unending breath |
[GetSpellInfo(85767)] = { colour = { .3, 0, 1 }}, -- dark intent |
[GetSpellInfo(1120)] = true, -- drain soul |
[GetSpellInfo(689)] = true, -- drain life |
[GetSpellInfo(89420)] = true, -- drain life (soulburn) |
[GetSpellInfo(980)] = true, -- bane of agony |
[GetSpellInfo(603)] = true, -- bane of doom |
[GetSpellInfo(80240)] = true, -- bane of havoc |
[GetSpellInfo(1490)] = true, -- curse of the elements |
[GetSpellInfo(1714)] = true, -- curse of tongues |
[GetSpellInfo(702)] = true, -- curse of weakness |
[GetSpellInfo(18223)] = true, -- curse of exhaustion |
[GetSpellInfo(27243)] = true, -- seed of corruption |
[GetSpellInfo(172)] = true, -- corruption |
[GetSpellInfo(348)] = true, -- immolate |
[GetSpellInfo(30108)] = true, -- unstable affliction |
[GetSpellInfo(48181)] = true, -- haunt |
[GetSpellInfo(32386)] = true, -- shadow embrace 1 |
[GetSpellInfo(32388)] = true, -- shadow embrace 2 |
[GetSpellInfo(32389)] = true, -- shadow embrace 3 |
[GetSpellInfo(85547)] = true, -- jinx 1 |
[GetSpellInfo(86105)] = true, -- jinx 2 |
[GetSpellInfo(30283)] = true, -- shadowfury |
[GetSpellInfo(6789)] = true, -- deathcoil |
[GetSpellInfo(5782)] = true, -- fear |
[GetSpellInfo(5484)] = true, -- howl of terror |
[GetSpellInfo(710)] = true, -- banish |
-- untriggered |
[GetSpellInfo(85421)] = true, -- burning embers |
[GetSpellInfo(60946)] = true, -- nightmare 1 |
[GetSpellInfo(60947)] = true, -- nightmare 2 |
}, |
SHAMAN = { -- 4.0.3 |
[GetSpellInfo(974)] = { colour = { .8, .5, 0 }, maxc = 9 }, -- earth shield |
[GetSpellInfo(61295)] = { colour = { .2, .2, 1 }}, -- riptide |
[GetSpellInfo(2825)] = true, -- bloodlust |
[GetSpellInfo(32182)] = true, -- heroism |
[GetSpellInfo(8050)] = true, -- flame shock |
[GetSpellInfo(8042)] = true, -- earth shock |
[GetSpellInfo(8056)] = true, -- frost shock |
[GetSpellInfo(17364)] = true, -- stormstrike |
[GetSpellInfo(131)] = true, -- water breathing |
[GetSpellInfo(546)] = true, -- water walking |
[GetSpellInfo(51514)] = true, -- hex |
[GetSpellInfo(76780)] = true, -- bind elemental |
-- untriggered |
[GetSpellInfo(51945)] = { colour = { 1, 0, .7 }}, -- earthliving |
[GetSpellInfo(85838)] = { colour = { .5, .5, 1 }}, -- ancestral fortitude |
}, |
PRIEST = { |
[GetSpellInfo(1706)] = true, -- Levitate |
[GetSpellInfo(139)] = { color = { 0, .7, 0 }}, -- Renew |
[GetSpellInfo(10060)] = true, -- Power Infusion |
[GetSpellInfo(33206)] = true, -- Pain Suppression |
[GetSpellInfo(27683)] = true, -- Shadow Protection |
[GetSpellInfo(33076)] = { color = { .7, .7, 0 }}, -- Prayer of Mending |
[GetSpellInfo(47930)] = true, -- Grace 1 |
[GetSpellInfo(77613)] = true, -- Grace 2 |
[GetSpellInfo(14893)] = true, -- Inspiration 1 |
[GetSpellInfo(15357)] = true, -- Inspiration 2 |
[GetSpellInfo(17)] = { color = { 1, 1, 1 }}, -- Power Word: Shield |
[GetSpellInfo(21562)] = { color = { .1, .1, .8 }}, -- Power Word: Fortitude |
[GetSpellInfo(47788)] = true, -- Guardian Spirit |
[GetSpellInfo(6346)] = true, -- Fear Ward |
[GetSpellInfo(47509)] = true, -- Divine Aegis 1 |
[GetSpellInfo(47511)] = true, -- Divine Aegis 2 |
[GetSpellInfo(47515)] = true, -- Divine Aegis 3 |
[GetSpellInfo(2944)] = true, -- Devouring Plague |
[GetSpellInfo(15307)] = true, -- Mind Flay |
[GetSpellInfo(589)] = true, -- Shadow Word: Pain |
[GetSpellInfo(32379)] = true, -- Shadow Word: Death |
[GetSpellInfo(34914)] = true, -- Vampiric Touch |
[GetSpellInfo(15487)] = true, -- Silence |
[GetSpellInfo(64044)] = true, -- Psychic Horror |
[GetSpellInfo(8122)] = true, -- Psychic Scream |
[GetSpellInfo(9484)] = true, -- Shackle Undead |
}, |
ROGUE = { -- 4.0.6 |
[GetSpellInfo(57934)] = { color = { 1, 0, 0 }}, -- Tricks of the Trade |
[GetSpellInfo(6770)] = true, -- Sap |
[GetSpellInfo(703)] = true, -- Garrote |
[GetSpellInfo(1833)] = true, -- Cheap Shot |
[GetSpellInfo(1776)] = true, -- Gouge |
[GetSpellInfo(2094)] = true, -- Blind |
[GetSpellInfo(31125)] = true, -- Blade Twisting 1 |
[GetSpellInfo(51585)] = true, -- Blade Twisting 2 |
[GetSpellInfo(1943)] = true, -- Rupture |
[GetSpellInfo(51693)] = true, -- Waylay |
[GetSpellInfo(16511)] = true, -- Hemorrhage |
[GetSpellInfo(26679)] = true, -- Deadly Throw |
[GetSpellInfo(8647)] = true, -- Expose Armor |
[GetSpellInfo(408)] = true, -- Kidney Shot |
[GetSpellInfo(2823)] = true, -- Deadly Poison |
[GetSpellInfo(3408)] = true, -- Crippling Poison |
[GetSpellInfo(13219)] = true, -- Wound Poison |
-- TODO: poisons |
}, |
-- TODO: Should store the priority (and other stuff) about spells |
-- Rather than just true |
-- TODO: should perhaps separate CC into a global list |
} |
--[[ |
local _, class = UnitClass('player') |
print(class .. " = {") |
for spell,_ in pairs(whitelist[class]) do |
local _, spellID = GetSpellBookItemInfo(spell) |
if spellID then |
print("[GetSpellInfo(" .. spellID .. ")] = true, -- " .. spell) |
else |
print("[GetSpellInfo(DUNNO)] = true, -- " .. spell) |
end |
end |
print("},") |
]] |
ns.w = whitelist |
--[[ |
oUF Kui |
Kesava-Auchindoun |
As part of Kui |
]] |
local addon, ns = ... |
local config, whitelist, ok, oUF = |
ns.c, ns.w, ns.ok, oUF |
-- Layout functions -------------------------------------------------------- |
-------------------------------------------------- Create combat feedback -- |
local function CreateCombatFeedbackText(self) |
if not IsAddOnLoaded("oUF_CombatFeedback") then return end |
local unit, cbft = self.unit |
if self.group or (self.thin and self.small) then |
-- group & pet |
cbft = ok:FontTemplate(self.Health, { temp = 'small' }) |
cbft:SetPoint('CENTER', self, 'CENTER', 0, 11) |
cbft.maxAlpha = 1 |
elseif self.small then |
-- focus |
cbft = ok:FontTemplate(self.Health, { temp = 'small' }) |
cbft:SetPoint('BOTTOMLEFT', self.Health, 4, 3) |
cbft.maxAlpha = 1 |
else |
cbft = ok:FontTemplate(self) |
if unit == 'player' then |
cbft:SetPoint('LEFT', self, 'RIGHT', 0, 0) |
elseif unit == 'target' then |
cbft:SetPoint('RIGHT', self, 'LEFT', 0, 0) |
end |
end |
self.CombatFeedbackText = cbft |
end |
------------------------------------------------ Create health prediction -- |
local function CreateHealPrediction(self) |
local unit, width, mhpb, ohpb = |
self.unit, |
(self.sizes.w - 2), |
ok:CreateStatusBar({ parent = self.Health, reverse = (self.Health.reverser ~= nil) }), |
ok:CreateStatusBar({ parent = self.Health, reverse = (self.Health.reverser ~= nil) }) |
-- points; |
local points |
if self.Health.reverser then |
points = {'TOPRIGHT', 'TOPLEFT', 'BOTTOMRIGHT', 'BOTTOMLEFT'} |
else |
points = {'TOPLEFT', 'TOPRIGHT', 'BOTTOMLEFT', 'BOTTOMRIGHT'} |
end |
for _, f in next, { mhpb, ohpb } do |
f:SetStatusBarTexture(config.Textures.bar) |
f:SetWidth(width) |
f:SetPoint(points[1], self.Health:GetStatusBarTexture(), points[2], 0, 0) |
f:SetPoint(points[3], self.Health:GetStatusBarTexture(), points[4], 0, 0) |
end |
mhpb:SetStatusBarColor(0, 1, .5, .5) |
ohpb:SetStatusBarColor(0, 1, 0, .5) |
self.HealPrediction = { |
myBar = mhpb, |
otherBar = ohpb, |
maxOverflow = 1 |
} |
end |
----------------------------------------------------- Create resting text -- |
local function CreateRestText(self, bar) |
bar.rest = ok:FontTemplate(bar, { alpha = .6, size = 12 }) |
bar.rest.frequentUpdates = 1 |
if bar.name then |
bar.rest:SetPoint('CENTER') |
else |
bar.rest:SetPoint('LEFT', 5, 0) |
end |
self:Tag(bar.rest, '[kes:rest]') |
end |
----------------------------------------------------- Create health texts -- |
local function CreateHealthTexts(self, bar) |
local unit = self.unit |
-- health text --------------------------------------------------------- |
bar.big = ok:FontTemplate(bar) |
bar.sml = ok:FontTemplate(bar, { temp = 'small' }) |
if self.group then |
bar.sml:SetPoint('LEFT', 2, 0) |
bar.role = ok:FontTemplate(bar, { alpha = .5, size = 12 }) |
bar.role:SetPoint('LEFT', 2, 0) |
bar.role:Hide() |
self:Tag(bar.role, '[kes:role]') |
bar.big:SetPoint('RIGHT', -2, 0) |
bar.big:SetJustifyH('RIGHT') |
bar.name = ok:FontTemplate(bar) |
bar.name:SetPoint('RIGHT', -2, 0) |
bar.name:Hide() |
self:Tag(bar.name, '[kes:shortname]') |
self.Health.PostUpdate = ok.PostUpdateHealth |
return |
end |
-- positioning health text --------------------------------------------- |
local anchor |
if unit == 'target' or unit == 'targettarget' or unit == 'pettarget' then |
anchor = 'LEFT' |
else |
anchor = 'RIGHT' |
end |
bar.big:SetPoint('TOP'..anchor, (anchor == 'RIGHT' and -1 or 2), (self.thin and 0 or -1)) |
bar.big:SetJustifyH(anchor) |
if self.thin then |
-- anchor to the left/right of .big |
bar.sml:SetPoint('BOTTOM'..anchor, bar.big, 'BOTTOM'..(anchor == 'RIGHT' and 'LEFT' or 'RIGHT'), 0, 0) |
else |
-- anchor below .big |
bar.sml:SetPoint('TOP'..anchor, (anchor == 'RIGHT' and -1 or 2), -17) |
end |
bar.sml:SetJustifyH(anchor) |
-- name/level text ----------------------------------------------------- |
if (ok.kui:getSaved('self', 'showame') and unit == 'player') or |
(unit ~= 'player' and unit ~= 'pet' and unit ~= 'focus') |
then |
if not self.small then |
-- name |
bar.name = ok:FontTemplate(bar) |
self:Tag(bar.name, '[kes:name]') |
end |
if not self.thin and not self.small then |
-- level |
bar.lvl = ok:FontTemplate(bar, { temp = 'small' }) |
self:Tag(bar.lvl, '[kes:level]') |
end |
-- positioning name/level ------------------------------------------ |
local anchor |
if bar.name or bar.lvl then |
if unit == 'target' or unit == 'targettarget' then |
anchor = 'RIGHT' |
else |
anchor = 'LEFT' |
end |
end |
if bar.name then |
bar.name:SetPoint('TOP'..anchor, (anchor == 'RIGHT' and -1 or 2), (self.thin and 0 or -1)) |
bar.name:SetJustifyH(anchor) |
end |
if bar.lvl then |
bar.lvl:SetPoint('TOP'..anchor, (anchor == 'RIGHT' and -1 or 2), -17) |
bar.lvl:SetJustifyH(anchor) |
end |
end |
self.Health.PostUpdate = ok.PostUpdateHealth |
end |
--------------------------------------------------------- Create portrait -- |
local function CreatePortrait(self, bar) |
local unit = self.unit |
self.Portrait = CreateFrame('PlayerModel', bar, self) |
self.Portrait.type = '3D' |
self.Portrait:SetAllPoints(bar) |
if self.group then |
self.Portrait:SetFrameLevel(2) |
else |
self.Portrait:SetFrameLevel(1) |
end |
self.PortraitShade = self.Portrait:CreateTexture(nil, 'OVERLAY') |
self.PortraitShade:SetTexture(config.Textures.pshade) |
self.PortraitShade:SetPoint('TOPLEFT', self.Portrait, -1, 1) |
self.PortraitShade:SetPoint('BOTTOMRIGHT', self.Portrait, 1, -1) |
self.PortraitShade:SetBlendMode('BLEND') |
self.PortraitShade:SetVertexColor(0, 0, 0, .95) |
if ok.kui:getSaved('bars', 'transparent') then |
bar:SetAlpha(.8) |
end |
end |
------------------------------------------------------------ Create auras -- |
local function CreateAuras(self) |
local unit = self.unit |
if unit == 'target' then |
-- buffs ----------------------------------------------------------- |
self.Buffs = CreateFrame('Frame', nil, self) |
self.Buffs.num = 18 |
self.Buffs.size = 21 |
self.Buffs.spacing = 1 |
self.Buffs.initialAnchor = 'TOPLEFT' |
self.Buffs['growth-y'] = 'DOWN' |
self.Buffs['growth-x'] = 'RIGHT' |
self.Buffs:SetWidth(132) |
self.Buffs:SetPoint('TOPLEFT', self, 'TOPRIGHT', -3, -5) |
self.Buffs.PostCreateIcon = ok.PostCreateIcon |
self.Buffs.PostUpdate = ok.PostUpdateAura |
end |
if unit == 'target' or unit == 'focus' or self.group then |
-- important auras on the target/focus/group frame ----------------- |
self.Auras = CreateFrame('Frame', nil, self) |
self.Auras['growth-y'] = 'UP' |
self.Auras['growth-x'] = 'RIGHT' |
if self.party then |
self.Auras.numBuffs = 6 |
self.Auras.numDebuffs = 6 |
self.Auras.size = 23 |
self.Auras.spacing = 2 |
self.Auras:SetWidth((self.Auras.size * 6) + (self.Auras.spacing * 5)) |
self.Auras:SetHeight(self.sizes.h) |
if ok.kui:getSaved('group', 'healmode') then |
self.Auras.PreUpdate = ok.GroupAurasPreUpdate |
else |
self.Auras:SetPoint('LEFT', self, 'RIGHT', -3, 0) |
self.Auras.initialAnchor = 'LEFT' |
self.Auras['growth-x'] = 'RIGHT' |
end |
elseif self.raid then |
-- tiny icons |
self.Auras.numBuffs = 6 |
self.Auras.numDebuffs = 6 |
self.Auras.size = 6 |
self.Auras.spacing = 2 |
self.Auras:SetWidth(self.sizes.w) |
self.Auras:SetHeight(self.sizes.h) |
self.Auras:SetPoint('BOTTOMLEFT', self.Health, 0, 0) |
self.Auras.initialAnchor = 'BOTTOMLEFT' |
self.Auras['growth-x'] = 'RIGHT' |
else |
-- focus or target |
local rows = (unit == 'focus' and 3 or 2) |
self.Auras.numBuffs = 12 |
self.Auras.numDebuffs = 12 |
self.Auras.spacing = 3 |
-- proper sizing |
self.Auras.size |
= (self.sizes.w - (self.Auras.spacing * ((self.Auras.numBuffs / rows) - 1))) / (self.Auras.numBuffs / rows) |
-- i forgot this so: 3 = spacing, 2 = rows |
self.Auras.initialAnchor = 'BOTTOMLEFT' |
self.Auras:SetPoint('BOTTOM', self, 'TOP', 0, -4) |
self.Auras:SetWidth(self.sizes.w) |
self.Auras:SetHeight(self.Auras.size * 2) |
end |
if self.raid then |
self.Auras.CustomFilter = ok.CustomAuraFilterRaid |
else |
self.Auras.CustomFilter = ok.CustomAuraFilter |
end |
if ok.kui:getSaved('all', 'sortauras') then |
self.Auras.PreSetPosition = ok.AurasPreSetPosition |
end |
self.Auras.CustomCooldown = true |
self.Auras.PostCreateIcon = ok.PostCreateIcon |
self.Auras.PostUpdateIcon = ok.PostUpdateIcon |
end |
if not self.group then |
-- debuffs --------------------------------------------------------- |
self.Debuffs = CreateFrame('Frame', nil, self) |
self.Debuffs.spacing = 1 |
self.Debuffs.initialAnchor = 'TOPLEFT' |
self.Debuffs['growth-y'] = 'DOWN' |
self.Debuffs['growth-x'] = 'RIGHT' |
if unit == 'target' then |
-- anchor below the target buffs frame |
self.Debuffs.num = 18 |
self.Debuffs.size = 21 |
self.Debuffs:SetWidth(self.Buffs:GetWidth()) |
self.Debuffs:SetPoint('TOPLEFT', self.Buffs, 'BOTTOMLEFT', 0, -2) |
elseif unit == 'targettarget' or unit == 'focus' then |
-- anchor to the bottom of the target-target frame |
self.Debuffs.num = (unit == 'focus' and 10 or 16) |
local rows = 2 |
self.Debuffs.size = |
(self.sizes.w - ((self.Debuffs.num / rows) - 1)) / (self.Debuffs.num / rows) |
self.Debuffs:SetWidth(self.sizes.w) |
self.Debuffs:SetPoint('LEFT', self, 5, 0) |
self.Debuffs:SetPoint('RIGHT', self, -5, 0) |
self.Debuffs:SetPoint('TOP', self, 'BOTTOM', 0, 3) |
elseif unit == 'pet' then |
-- anchor to the left of the pet frame |
-- this essentially looks like the group frames Auras |
self.Debuffs['growth-x'] = 'LEFT' |
self.Debuffs.initialAnchor = 'RIGHT' |
self.Debuffs.num = 6 |
self.Debuffs.size = 23 |
self.Debuffs.spacing = 2 |
self.Debuffs:SetWidth((self.Debuffs.size * 6) + (self.Debuffs.spacing * 5)) |
self.Debuffs:SetPoint('RIGHT', self, 'LEFT', 3, 0) |
self.Debuffs.CustomCooldown = true |
self.Debuffs.PostUpdateIcon = ok.PostUpdateIconDebuff |
end |
self.Debuffs.PostCreateIcon = ok.PostCreateIcon |
self.Debuffs.PostUpdate = ok.PostUpdateAura |
end |
end |
--------------------------------------------------------- Create cast bar -- |
local function CreateCastBar(self) |
local unit = self.unit |
self.Castbar = ok:CreateStatusBar({ |
parent = self, |
reverse = self.reverseBars |
}) |
local b, n, t, m = |
self.Castbar |
if not self.mini and not (self.small and self.thin) then |
-- Create text ----------------------------------------------------- |
b.Text = ok:FontTemplate(b, { |
size = (self.small and config.Fonts.ss+2 or nil) |
}) |
n = b.Text |
if not self.small and not self.thin then |
b.Time = ok:FontTemplate(b) |
b.Max = ok:FontTemplate(b, { temp = 'small' }) |
t, m = |
b.Time, |
b.Max |
end |
end |
b:SetStatusBarTexture(config.Textures.bar) |
b:SetStatusBarColor(.23, .27, .35) |
if not self.mini then |
b:SetBackdrop({ |
bgFile = config.Textures.bar, |
insets = {top = -1, left = -1, bottom = -1, right = -1}}) |
b:SetBackdropColor(0, 0, 0) |
else |
b:SetAlpha(.75) |
end |
-- Sizes --------------------------------------------------------------- |
local s |
if self.thin and self.small then |
s = { w = 28, h = 8 } |
elseif self.small then |
s = { h = 18, w = self.sizes.w + 30 } |
else |
s = { |
w = config.CastBar.width or (self.sizes.w - 2), |
h = config.CastBar.height or 23 |
} |
end |
b:SetHeight(s.h) |
b:SetWidth(s.w) |
if n then |
n:SetSize(s.w, s.h) |
end |
-- Positions ----------------------------------------------------------- |
local anchor, inverse = 'LEFT' |
if unit == 'player' then |
b:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', 6, 0) |
elseif unit == 'target' then |
b:SetPoint('TOPRIGHT', self, 'BOTTOMRIGHT', -6, 0) |
anchor = 'RIGHT' |
elseif unit == 'focus' then |
b:SetPoint('BOTTOM', self.Auras, 'TOP', 0, 4) |
elseif self.thin and self.small then |
b:SetPoint('LEFT', self.Health, 'LEFT', 5, 0) |
b:SetFrameLevel(self.Health:GetFrameLevel() + 1) |
elseif self.mini then |
b:SetAllPoints(self.Health) |
b:SetFrameLevel(self.Health:GetFrameLevel() + 1) |
end |
inverse = (anchor == 'RIGHT' and 'LEFT' or 'RIGHT') |
if n then |
n:SetPoint(anchor, b, (anchor == 'RIGHT' and -2 or 2), 0) |
if unit == 'focus' then |
n:SetJustifyH('CENTER') |
else |
n:SetJustifyH(anchor) |
end |
end |
if t and m then |
t:SetPoint(inverse, b, (anchor == 'LEFT' and -2 or 2), 0) |
t:SetJustifyH(inverse) |
m:SetPoint('BOTTOM'..inverse, t, 'BOTTOM'..anchor, (anchor == 'LEFT' and -2 or 2), 0) |
m:SetJustifyH(inverse) |
end |
if config.CastBar.showSpellIcons and |
(unit == 'player' or unit == 'target' or unit == 'focus' or unit == 'pet') |
then |
-- Create spell icon ----------------------------------------------- |
b.Icon = b:CreateTexture(nil, 'ARTWORK') |
local i = b.Icon |
i:SetSize(b:GetHeight(), b:GetHeight()) |
i:SetPoint(anchor, b, inverse, (anchor == 'RIGHT' and -3 or 3), 0) |
i:SetTexCoord(.1, .9, .1, .9) |
i.bg = b:CreateTexture(nil, 'BACKGROUND') |
i.bg:SetTexture(kui.m.t.solid) |
i.bg:SetVertexColor(0, 0, 0) |
i.bg:SetPoint('TOPLEFT', i, 'TOPLEFT', -1, 1) |
i.bg:SetPoint('BOTTOMRIGHT', i, 'BOTTOMRIGHT', 1, -1) |
end |
if unit == 'player' and config.CastBar.showSafeZone then |
-- Create safe zone ------------------------------------------------ |
b.SafeZone = b:CreateTexture(nil, 'OVERLAY') |
local sz = b.SafeZone |
sz:SetTexture(config.Textures.bar) |
sz:SetPoint('TOPRIGHT') |
sz:SetPoint('BOTTOMRIGHT') |
sz:SetVertexColor(.1, .9, .1, .3) |
end |
b.PostCastStart = ok.PostCastStart |
end |
------------------------------------------------------- Create unit frame -- |
-- TODO: split functions; background & bars |
local function MakeUnitFrame(self, s) |
-- Handles bars and sizes |
self.group = (self.party or self.raid) |
local unit = self.unit |
if type(s) ~= 'table' then |
if s == 'small' then |
self.small = true |
elseif s == 'thin' then |
self.thin = true |
elseif s == 'thinsmall' then |
self.thin = true |
self.small = true |
elseif s == 'mini' then |
self.mini = true |
end |
if config.Sizes[s] then |
s = config.Sizes[s] |
else |
-- use default sizes |
s = {} |
end |
end |
self.sizes = { |
w = s.w or config.Sizes.def.w, |
h = s.h or config.Sizes.def.h, |
hb = s.hb or config.Sizes.def.hb, |
pb = s.pb or config.Sizes.def.pb, |
} |
if |
((not self.group and ok.kui:getSaved('bars', 'vertical')) or |
(self.group and ok.kui:getSaved('group', 'vertical'))) and |
not self.mini |
then |
self.sizes.hb = self.sizes.hb + self.sizes.pb + 1 |
self.sizes.pb = 2 |
end |
self:SetWidth(self.sizes.w + 10) |
self:SetHeight(self.sizes.h + 10) |
-- background: |
self:SetBackdrop({ |
bgFile = config.Textures.bar, tile = false, |
edgeFile = config.Textures.frame, edgeSize = 5, |
insets = { top = 5, right = 5, bottom = 5, left = 5 } |
}) |
self:SetBackdropColor(0, 0, 0) |
self:SetBackdropBorderColor(0, 0, 0, .3) |
if ok.kui:getSaved('bars', 'reverse') then |
self.reverseBars = ( |
unit == 'target' or |
unit == 'targettarget' or |
unit == 'pettarget' |
) |
end |
if self.group and ok.kui:getSaved('group', 'fade') then |
self.Range = { insideAlpha = 1, outsideAlpha = .5 } |
end |
---------------------------------------------------------- Health bar -- |
self.Health = ok:CreateStatusBar({ |
parent = self, |
invert = (not self.group and ok.kui:getSaved('bars', 'invert')) or |
(self.group and ok.kui:getSaved('group', 'invert')), |
reverse = self.reverseBars |
}) |
self.Health:SetHeight(self.sizes.hb) |
self.Health:SetPoint("TOP", 0, -6) |
self.Health:SetPoint("RIGHT", -6, 0) |
-- left is set when power bar is created |
self.Health.frequentUpdates = true |
self.Health.Smooth = true |
-- colours |
self.Health.colorHappiness = true |
self.Health.colorReaction = true |
self.Health.colorClass = true |
self.Health.colorClassNPC = ok.kui:getSaved('bars', 'npcclass') |
self.Health.colorDisconnected = true |
self.Health.colorTapping = true |
----------------------------------------------------------- Power bar -- |
if not self.mini then |
self.Power = ok:CreateStatusBar({ |
parent = self, |
small = true, |
reverse = self.reverseBars |
}) |
-- orientation |
if |
(not self.group and ok.kui:getSaved('bars', 'vertical')) or |
(self.group and ok.kui:getSaved('group', 'vertical')) |
then |
-- vertical |
self.Health:SetPoint("LEFT", 7 + self.sizes.pb, 0) |
self.Power:SetOrientation("VERTICAL") |
self.Power:SetWidth(self.sizes.pb) |
self.Power:SetPoint("LEFT", 6, 0) |
self.Power:SetPoint("TOP", 0, -6) |
self.Power:SetPoint("BOTTOM", 0, 6) |
else |
-- horizontal |
self.Health:SetPoint("LEFT", 6, 0) |
self.Power:SetHeight(self.sizes.pb) |
self.Power:SetPoint("BOTTOM", 0, 6) |
self.Power:SetPoint("LEFT", 6, 0) |
self.Power:SetPoint("RIGHT", -6, 0) |
end |
self.Power.frequentUpdates = true |
self.Power.PostUpdate = ok.PostUpdatePower |
-- colours |
self.Power.Smooth = true |
self.Power.colorTapping = true |
self.Power.colorDisconnected = true |
self.Power.colorPower = true |
end |
end |
local function CreateComboPoints(self) |
self.cpoints = ok:FontTemplate(self, { size = 16, shadow = true }) |
self.cpoints:SetPoint('CENTER', UIParent, 0, ok.kui:getSaved('pos', 'ypos')) |
self.cpoints:SetJustifyH('CENTER') |
-- these can be on vehicles I believe |
self:RegisterEvent('UNIT_COMBO_POINTS', ok.ComboPointsUpdate) |
self:RegisterEvent('PLAYER_TARGET_CHANGED', ok.ComboPointsUpdate) |
if whitelist.CountSpells[ok.class] then |
-- things like maelstrom weapon |
self:RegisterEvent('UNIT_AURA', ok.ComboPointsUpdate) |
self.cpoints.aura = 0 |
end |
end |
local function InitFrame(self) |
self:SetScale(ok.scale or 1) |
self.menu = ok.menu |
self:SetScript('OnEnter', UnitFrame_OnEnter) |
self:SetScript('OnLeave', UnitFrame_OnLeave) |
self:RegisterForClicks('AnyUp') |
end |
-------------------------------------------------- Individual unit layout -- |
local function MainLayout(self, unit) |
InitFrame(self) |
if unit == 'targettarget' then |
MakeUnitFrame(self, 'thin') |
elseif unit == 'pet' or unit == 'pettarget' then |
MakeUnitFrame(self, 'thinsmall') |
elseif unit == 'focus' then |
MakeUnitFrame(self, 'small') |
elseif unit == 'focustarget' then |
MakeUnitFrame(self, 'mini') |
else |
MakeUnitFrame(self) |
end |
if not self.mini then |
CreateHealthTexts(self, self.Health) |
if ok.kui:getSaved('bars', 'portraits') then |
CreatePortrait(self, self.Health) |
end |
end |
if ok.kui:getSaved('bars', 'heal') then |
CreateHealPrediction(self) |
end |
if unit == 'target' or |
unit == 'targettarget' or |
unit == 'pet' or |
unit == 'focus' |
then |
CreateAuras(self) |
end |
if config.CastBar.enabled and |
(unit == 'player' or unit == 'target' or unit == 'focus' or unit == 'pet') |
then |
CreateCastBar(self) |
end |
if unit == 'player' then |
CreateRestText(self, self.Health) |
if ok.kui:getSaved('self', 'combo') then |
CreateComboPoints(self) |
end |
end |
-- elements ------------------------------------------------------------ |
self.KuiThreat = ok.kui:getSaved('all', 'threat') |
self.KuiDebuffPulse = { |
f = self.Health, |
h = ok.kui:getSaved('all', 'debuffhighlight'), |
i = ok.kui:getSaved('all', 'debufficon') |
} |
if ok.kui:getSaved('self', 'fade') and (unit == 'player' or unit == 'pet') then |
self.BarFade = true |
end |
if unit == 'player' or unit == 'target' or unit == 'pet' or unit == 'focus' then |
CreateCombatFeedbackText(self) |
end |
if ok.kui:getSaved('self', 'class') and unit == 'player' then |
self.ClassBars = { |
class = ok.class, |
width = 8, |
height = (self:GetHeight() - 10) |
} |
end |
end |
oUF:RegisterStyle("KuiMain", MainLayout) |
------------------------------------------------------------ Group layout -- |
local function GroupLayout(self, unit) |
InitFrame(self) |
self.party = true |
MakeUnitFrame(self, 'thinsmall') |
CreateHealthTexts(self, self.Health) |
CreateAuras(self) |
if ok.kui:getSaved('group', 'portraits') then |
CreatePortrait(self, self.Health) |
end |
if ok.kui:getSaved('group', 'heal') then |
CreateHealPrediction(self) |
end |
self.KuiThreat = ok.kui:getSaved('all', 'threat') |
self.KuiDebuffPulse = { |
f = self.Health, |
h = ok.kui:getSaved('all', 'debuffhighlight'), |
i = ok.kui:getSaved('all', 'debufficon') |
} |
CreateCombatFeedbackText(self) |
end |
oUF:RegisterStyle("KuiGroup", GroupLayout) |
------------------------------------------------------------- Raid layout -- |
local function RaidLayout(self, unit) |
InitFrame(self) |
self.raid = true |
MakeUnitFrame(self, 'raid') |
CreateHealthTexts(self, self.Health) |
CreateAuras(self) |
if ok.kui:getSaved('group', 'heal') then |
CreateHealPrediction(self) |
end |
self.KuiThreat = ok.kui:getSaved('all', 'threat') |
self.KuiDebuffPulse = { |
f = self.Health, |
h = ok.kui:getSaved('all', 'debuffhighlight'), |
i = ok.kui:getSaved('all', 'debufficon') |
} |
CreateCombatFeedbackText(self) |
end |
oUF:RegisterStyle("KuiRaid", RaidLayout) |
local oufkui = {} |
--------------------------------------------------------- Arbitrary stuff -- |
function oufkui:Spawned() |
if config.CastBar.enabled and config.CastBar.dynamicPositioning then |
-- Castbar dynamic positioning ------------------------------------- |
-- TODO: should perhaps move this into preCastStart or something |
self.targettarget:HookScript('OnShow', function(self) |
oufkui.target.Castbar:ClearAllPoints() |
oufkui.target.Castbar:SetPoint('TOPRIGHT', self.Debuffs, 'BOTTOMRIGHT', -1, -3) |
end) |
self.targettarget:HookScript('OnHide', function(self) |
oufkui.target.Castbar:ClearAllPoints() |
oufkui.target.Castbar:SetPoint('TOPRIGHT', oufkui.target, 'BOTTOMRIGHT', -6, 0) |
end) |
self.pet:HookScript('OnShow', function(self) |
oufkui.player.Castbar:ClearAllPoints() |
oufkui.player.Castbar:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', 6, 0) |
end) |
self.pet:HookScript('OnHide', function(self) |
oufkui.player.Castbar:ClearAllPoints() |
oufkui.player.Castbar:SetPoint('TOPLEFT', oufkui.player, 'BOTTOMLEFT', 6, 0) |
end) |
if self.pet:IsVisible() then |
self.pet:GetScript('OnShow')(self.pet) |
end |
if self.targettarget:IsVisible() then |
self.targettarget:GetScript('OnShow')(self.targettarget) |
end |
end |
end |
function oufkui:Spawn(unit, point) |
self[unit] = oUF:Spawn(unit) |
self[unit]:SetPoint(unpack(point)) |
end |
function oufkui:SpawnParty() |
local unshared, point |
-- TODO: these positions should be configurable |
if ok.kui:getSaved('group', 'healmode') then |
unshared = { |
'point', 'LEFT', |
'maxColumns', 2, |
'unitsPerColumn', 2, |
'columnAnchorPoint', 'BOTTOM' |
} |
point = { "BOTTOMLEFT", self.player, "TOPLEFT", 0, -6 } |
else |
-- DPS mode |
unshared = { |
'point', 'BOTTOM', |
'maxColumns', 1, |
'unitsPerColumn', 4, |
'columnAnchorPoint', 'TOP' |
} |
point = { "TOPLEFT", UIParent, "TOPLEFT", 5, -5 } |
end |
self.party = oUF:SpawnHeader("oUF_Party", nil, 'party', |
--self.party = oUF:SpawnHeader("oUF_Party", nil, "solo,party,raid", 'showSolo', true, 'showPlayer', true, |
'showParty', true, |
'xOffset', -8, |
'columnSpacing', -6.5, |
unpack(unshared)) |
self.party:SetPoint(unpack(point)) |
end |
function oufkui:SpawnRaid() |
local point, unshared, colDir |
if ok.kui:getSaved('group', 'healmode') then |
point = { 'BOTTOMRIGHT', self.player, 'TOPRIGHT', 0, -6 } |
colDir = { 'LEFT', 'BOTTOM' } |
unshared = { |
'point', 'TOP', |
'sortDir', 'DESC' |
} |
else |
point = { 'TOPLEFT', UIParent, 5, -5 } |
colDir = { 'RIGHT', 'TOP' } |
unshared = { |
'point', 'BOTTOM', |
'sortDir', 'ASC' |
} |
end |
local colSpace = { 7, 135 } |
local colDirI = (colDir[1] == 'RIGHT' and 'LEFT' or 'RIGHT') |
-- invert spacing values |
if colDir[1] == 'RIGHT' then |
colSpace[1] = -colSpace[1] |
end |
if colDir[2] == 'TOP' then |
colSpace[2] = -colSpace[2] |
end |
for i = 1, 8 do |
self['raid'..i] = oUF:SpawnHeader("oUF_Raid"..i, nil, 'raid' |
--self['raid'..i] = oUF:SpawnHeader("oUF_Raid"..i, nil, 'solo,party,raid' |
,'showSolo', true, 'showParty', true |
,'showRaid', true |
,'yOffset', colSpace[1] |
,'unitsPerColumn', 5 |
,'groupBy', 'GROUP' |
,'groupingOrder', '1,2,3,4,5,6,7,8' |
,'sortMethod', 'INDEX' |
,'groupFilter', i |
,unpack(unshared) |
) |
-- TDOO: Config: columns, sorting method |
--[[ |
self['raid'..i]:SetBackdrop({bgFile=kui.m.t.solid}) |
if i % 2 == 1 then |
self['raid'..i]:SetBackdropColor(0, 0, 0) |
end |
]] |
if i == 1 then |
self['raid'..i]:SetPoint(unpack(point)) |
elseif i % (ok.kui:getSaved('group', 'healmode') and 2 or 4) == 1 then |
-- next to the previous column |
self['raid'..i]:SetPoint( |
'BOTTOM'..colDirI, |
self['raid'..i-(ok.kui:getSaved('group', 'healmode') and 2 or 4)], |
'BOTTOM'..colDir[1], |
colSpace[1], 0) |
else |
-- above the previous group header (so groups are always at the same point) |
self['raid'..i]:SetPoint( |
colDir[2], |
self['raid'..i-1], |
colDir[2], |
0, colSpace[2]) |
end |
end |
end |
oUF:Factory(function(self) |
if ok.kui:getSaved('bars', 'newcolours') then |
-- change reaction colours [TODO this could be a load function for this setting actually] |
oUF.colors.reaction[1] = { .7, .2, .1 } -- hated |
oUF.colors.reaction[2] = { .7, .2, .1 } -- hostile |
oUF.colors.reaction[3] = { .9, .4, .1 } -- unfriendly |
oUF.colors.reaction[4] = { 1, .8, 0 } -- neutral |
oUF.colors.reaction[5] = { .2, .6, .1 } -- friendly |
oUF.colors.reaction[6] = { .4, .8, .2 } -- honored |
oUF.colors.reaction[7] = { .3, .8, .4 } -- revered |
oUF.colors.reaction[8] = { .3, .9, .6 } -- exalted |
end |
-- suggested scaling |
local uiscale = string.format('%.2f', UIParent:GetScale()) |
ok.scale = (1 - (uiscale - .64)) + ok.kui:getSaved(nil, 'scale') |
local xdist, ypos |
= ok.kui:getSaved('pos', 'xdist'), ok.kui:getSaved('pos', 'ypos') |
-- Spawn individual units ---------------------------------------------- |
self:SetActiveStyle("KuiMain") |
-- Parent: player |
oufkui:Spawn('player', {'CENTER', -xdist, ypos}) |
oufkui:Spawn('pet', {'TOPLEFT', oufkui.player, 'BOTTOMLEFT', 0, 6}) |
oufkui:Spawn('pettarget', {'TOPRIGHT', oufkui.player, 'BOTTOMRIGHT', 0, 6}) |
-- Parent: target |
oufkui:Spawn('target', {'CENTER', xdist, ypos}) |
oufkui:Spawn('targettarget', {'TOPRIGHT', oufkui.target, 'BOTTOMRIGHT', 0, 6}) |
-- Parent: focus |
oufkui:Spawn('focus', {'CENTER', 0, ypos + 37 }) |
oufkui:Spawn('focustarget', { 'TOPLEFT', oufkui.focus, 5, -5 }) |
oufkui.focustarget:SetParent(oufkui.focus) |
oufkui.focustarget:SetFrameLevel(3) |
-- Spawn group style units --------------------------------------------- |
self:SetActiveStyle("KuiGroup") |
oufkui:SpawnParty() |
-- Spawn raid style units ---------------------------------------------- |
self:SetActiveStyle("KuiRaid") |
oufkui:SpawnRaid() |
oufkui:Spawned() |
end) |
--[[ |
oUF Kui |
Kesava-Auchindoun |
Functions, callbacks |
]] |
local addon, ns = ... |
local config, whitelist, ok, oUF |
= ns.c, ns.w, ns.ok, oUF |
ok.class = select(2, UnitClass("player")) |
----------------------------------------------------------------- Colours -- |
oUF.colors.power['MANA'] = { 78/255, 95/255, 190/255 } |
---------------------------------------------------------------- oUF tags -- |
oUF.Tags['kes:name'] = function(u, r) |
local name, away, busy = UnitName(u or r), UnitIsAFK(u), UnitIsDND(u) |
return (away and '[Away] ' or busy and '[Busy] ' or '')..name |
end |
oUF.TagEvents["kes:name"] = "UNIT_NAME_UPDATE PLAYER_FLAGS_CHANGED" |
oUF.Tags['kes:shortname'] = function(u, r) |
local Name = UnitName(u or r):kuisub(4) |
return Name |
end |
oUF.TagEvents["kes:shortname"] = "UNIT_NAME_UPDATE" |
oUF.Tags['kes:level'] = function(u) |
local level, class, diff = kui.UnitLevel(u) |
return string.format("|cff%02x%02x%02x", diff.r*255, diff.g*255, diff.b*255) .. level .. class .. '|r' |
end |
oUF.TagEvents["kes:level"] = "UNIT_LEVEL PLAYER_LEVEL_UP" |
oUF.Tags['kes:role'] = function(u) |
local role = UnitGroupRolesAssigned(u) |
if role == 'NONE' then return end |
if role == 'DAMAGER' then |
role = 'DPS' |
else |
-- capitalise |
role = role:sub(1, 1)..role:sub(2):lower() |
end |
return role |
end |
oUF.TagEvents["kes:role"] = "PARTY_MEMBERS_CHANGED PLAYER_ROLES_ASSIGNED" |
oUF.Tags['kes:rest'] = function() |
local final |
if UnitAffectingCombat('player') then |
final = '|cffffaaaaCombat|r' |
end |
if IsResting() then |
final = (final and final..' ' or '')..'|cffffffaaResting|r' |
end |
if UnitIsPVP('player') and GetPVPDesired() == 0 then |
if IsPVPTimerRunning() then |
local timer = math.floor(GetPVPTimer() / 1000) |
final = (final and final..' ' or '').. |
'|cffbbffbb'..(timer >= 60 and |
math.floor(timer / 60)..'m' or |
timer..'s')..'|r' |
else |
final = (final and final..' ' or '')..'|cffaaffaaPvP|r' |
end |
end |
return final |
end |
oUF.TagEvents["kes:rest"] = "PLAYER_UPDATE_RESTING PLAYER_REGEN_DISABLED PLAYER_REGEN_ENABLED UNIT_FACTION" |
----------------------------------------------------------- Menu function -- |
function ok.menu(frame) |
local unit = frame.unit:sub(1, -2) |
local cunit = frame.unit:gsub("(.)", string.upper, 1) |
if (unit == "party" or unit == "partypet") then |
ToggleDropDownMenu(1, nil, _G["PartyMemberFrame"..frame.id.."DropDown"], "cursor", 0, 0) |
elseif (_G[cunit.."FrameDropDown"]) then |
ToggleDropDownMenu(1, nil, _G[cunit.."FrameDropDown"], "cursor", 0, 0) |
end |
end |
------------------------------------------------------- Utility functions -- |
function ok:FontTemplate(parent, args) |
if not args then args = {} end |
if args.temp == 'small' then |
args.size = args.size or config.Fonts.ss |
args.alpha = args.alpha or .5 |
end |
args.size = args.size or config.Fonts.s |
args.font = args.font or config.Fonts.n |
args.outline = args.outline or config.Fonts.o |
return kui.CreateFontString(parent, args) |
end |
function ok:CreateStatusBar(args) |
local bar, texture |
if args.parent then |
bar = CreateFrame('StatusBar', nil, args.parent) |
else |
bar = CreateFrame('StatusBar') |
end |
texture = small and config.Textures.sbar or config.Textures.bar |
bar:SetStatusBarTexture(texture) |
if args.invert then |
-- background for inverted filling |
bar.bg = bar:CreateTexture(nil, "BACKGROUND") |
bar.bg:SetTexture(texture) |
bar.bg:SetAllPoints(bar) |
bar:SetAlpha(.8) |
end |
if args.reverse then |
-- i could use something similar to this for inverting but... |
local function OnUpdateReverser(self) |
local bar, tex, max, width, value |
bar = self:GetParent() |
tex, max, width, value = |
bar:GetStatusBarTexture(), |
select(2, bar:GetMinMaxValues()), |
bar:GetWidth(), |
bar:GetValue() |
tex:ClearAllPoints() |
tex:SetPoint('BOTTOMRIGHT') |
tex:SetPoint('TOPLEFT', bar, 'TOPRIGHT', -((value / max) * width), 0) |
end |
local function OnChange(self) |
self.reverser:Show() |
end |
bar.reverser = CreateFrame('Frame', nil, bar) |
bar.reverser:Hide() |
bar.reverser:SetScript('OnUpdate', OnUpdateReverser) |
bar:SetScript('OnSizeChanged', OnChange) |
bar:SetScript('OnValueChanged', OnChange) |
bar:SetScript('OnMinMaxChanged', OnChange) |
end |
return bar |
end |
-------------------------------------------------------- Custom callbacks -- |
function ok.ComboPointsUpdate(self, event, ...) |
if event == 'UNIT_AURA' and ... ~= 'player' then return end |
local cp, size, blue, max = nil, 16, 100, 5 |
if UnitExists('vehicle') then |
cp = GetComboPoints('vehicle', 'target') |
else |
cp = GetComboPoints('player', 'target') |
end |
-- backdraft doesn't call COMBAT_LOG_EVENT |
if cp == 0 and event == 'UNIT_AURA' then |
self.cpoints.aura = nil |
local _, name, icon, count, duration, expirationTime |
for name,maxVal in pairs(whitelist.CountSpells[ok.class]) do |
_, _, icon, count, _, duration, expirationTime = UnitAura('player', name) |
if count then |
self.cpoints.max = maxVal |
self.cpoints.aura = count |
break |
end |
end |
end |
if cp == 0 and self.cpoints.aura then |
-- combo points displayed are actually stacks of an aura: |
cp = self.cpoints.aura |
max = self.cpoints.max |
end |
if cp > 0 then |
-- dynamic resizing |
-- not for dummies any more |
-- actually it was because i forgot to remove the loop |
size = (16 + ((24 - 16) / max) * cp) |
blue = (1 - (1 / max) * cp) |
self.cpoints:SetText(cp) |
self.cpoints:SetFont(config.Fonts.n, size, config.Fonts.o) |
self.cpoints:SetTextColor(1, 1, blue) |
else |
self.cpoints:SetText '' |
end |
end |
function ok.BuffTimer(self, elapsed) |
-- update custom cooldown timer |
if self.cdc.nextUpdate > 0 then |
self.cdc.nextUpdate = self.cdc.nextUpdate - elapsed |
else |
self.cdc.remaining = self.cdc.expires - GetTime() |
if self.Tiny then |
if self.cdc.remaining < 4 then |
-- act like a progress bar |
self:SetHeight(self.cdc.remaining+2) |
end |
return |
end |
self.cdc.fTime, self.cdc.nextUpdate |
= kui.FormatTime(self.cdc.remaining) |
if self.cdc.remaining > 0 and self.cdc.remaining <= 20 then |
self.cdc:SetText(self.cdc.fTime) |
self.cdc:Show() |
else |
self.cdc:Hide() |
end |
if self.cdc.remaining <= 5 and not self.cdc.redText then |
-- make the text big and red. |
self.cdc = ok:FontTemplate(self.cdc, { reset = true, size = 18 }) |
self.cdc:SetTextColor(1, 0, 0) |
self.cdc.redText = true |
elseif self.cdc.remaining > 5 and self.cdc.redText then |
-- normal text. |
self.cdc = ok:FontTemplate(self.cdc, { reset = true, size = 12 }) |
self.cdc:SetTextColor(1, 1, 0) |
self.cdc.redText = false |
end |
end |
end |
-- show/hide the power bar based on its current setting OR force it to be |
-- hidden. Used by PostUpdateHealth & PostUpdatePower. |
function ok.TogglePowerBar(self, forceHide) |
if not self.Power then return end |
if forceHide then self.Power.show = false end |
if self.Power.show or self.Power.show == nil then |
if self.Power:IsVisible() then return end |
self.Power:Show() |
if self.Power:GetOrientation() == "VERTICAL" then |
self.Health:SetPoint("LEFT", 7 + self.sizes.pb, 0) |
else |
self.Health:SetHeight(self.sizes.hb) |
end |
else |
if not self.Power:IsVisible() then return end |
self.Power:Hide() |
if self.Power:GetOrientation() == "VERTICAL" then |
self.Health:SetPoint("LEFT", 6, 0) |
else |
self.Health:SetHeight(self.sizes.hb + self.sizes.pb + 1) |
end |
end |
end |
--------------------------------------------------------------- oUF callbacks -- |
-- set health text and visibility ---------------------------------------------- |
function ok.PostUpdateHealth(ele, unit, min, max) |
local btxt, stxt |
local self, current, b, s, offline, dead, ghost = |
ele:GetParent(), |
UnitHealth(unit), |
ele.big, |
ele.sml, |
not UnitIsConnected(unit), |
UnitIsDead(unit), |
UnitIsGhost(unit) |
local deficit, percent = |
max - current, |
floor(current/max * 100) |
if current < 1 then |
dead = true |
end |
if offline or dead or ghost then |
ok.TogglePowerBar(self, true) |
-- hide values |
ele:SetValue(0) |
if ghost then |
btxt = 'Ghost' |
elseif offline then |
btxt = 'Offline' |
end |
elseif current >= 1 then |
if self.Power --[[and not self.Power:IsVisible()]] then |
-- force a refresh of the show boolean |
-- fixes issue where power bar wouldn't show after resurrection |
-- why didn't PostUpatePower do that anyway? Who knows! |
self.Power.show = (UnitPowerMax(self.unit) > 0) |
-- remove IsVisible due to problem introduced by ouf 1.5.8 |
end |
ok.TogglePowerBar(self) |
if UnitIsFriend("player", unit) then |
-- friend: |
if current == max then |
-- show only maximum hp |
btxt = kui.num(max) |
else |
-- show deficit and current hp |
btxt = '-' .. kui.num(deficit) |
stxt = kui.num(current) |
end |
else |
btxt = percent |
stxt = kui.num(current) |
end |
end |
if b then b:SetText(btxt) end |
if s then s:SetText(stxt) end |
if ele.bg then |
-- inverted bar colour |
ele:SetStatusBarColor(0, 0, 0, .8) |
end |
if self.group then |
if current == max then |
b:Hide() |
else |
b:Show() |
end |
if ele.role then |
if s and (not s:GetText() or not s:IsVisible()) or |
not s and (not b:GetText() or not b:IsVisible()) |
then |
ele.role:Show() |
else |
ele.role:Hide() |
end |
end |
if ele.name then |
if not b:GetText() or not b:IsVisible() then |
ele.name:Show() |
else |
ele.name:Hide() |
end |
end |
end |
end |
function ok.PostUpdatePower(ele, unit, min, max) |
-- Hide power bar when maximum power is zero |
local self = ele:GetParent() |
ele.show = (max > 0) |
if not ele.show then |
-- this ONLY hides as showing is handled by PostUpdateHealth |
-- if this did both, it'd show the power bar while the unit was dead |
ok.TogglePowerBar(self) |
end |
end |
function ok.PostCastStart(ele, unit, name, rank, castid) |
if ele.Max and ele.max then |
ele.Max:SetText(string.format("%.1f", ele.max)) |
end |
end |
function ok.GroupAurasPreUpdate(ele, unit) |
local self, column = ele:GetParent(), 1 |
if unit ~= 'player' then |
local pid = string.gsub(unit, '[^%d]+', '') |
if pid ~= "" then |
pid = tonumber(pid) |
column = pid % 2 |
end |
end |
if column == 1 then |
-- left column |
ele:SetPoint('RIGHT', self, 'LEFT', 3, 0) |
ele.initialAnchor = 'RIGHT' |
ele['growth-x'] = 'LEFT' |
else |
-- right column |
ele:SetPoint('LEFT', self, 'RIGHT', -3, 0) |
ele.initialAnchor = 'LEFT' |
ele['growth-x'] = 'RIGHT' |
end |
ele.PreUpdate = nil |
end |
-- dynamically set the height of the given aura frame -------------------------- |
function ok.ScaleAuraFrame(frame, visible) |
if not frame then return end |
local rows, height |
if not frame[visible] then |
frame[visible] = 0 |
end |
rows = (frame[visible] == 0 and 0) or ceil(( |
(frame.size * frame[visible]) |
+ (frame.spacing * (frame[visible] - 1)) |
) / frame:GetWidth()) |
height = |
(frame.size * rows) + (frame.spacing * (rows - 1)) |
-- Setting point onto a 0 height frame doesn't work apparently |
frame:SetHeight(height > 0 and height or .001) |
end |
-- keep aura frames the right height ------------------------------------------- |
function ok.PostUpdateAura(ele, unit) |
local self = ele:GetParent() |
ok.ScaleAuraFrame(self.Buffs, 'visibleBuffs') |
ok.ScaleAuraFrame(self.Debuffs, 'visibleDebuffs') |
ok.ScaleAuraFrame(self.Auras, 'visibleAuras') |
if unit == 'target' and self.Debuffs and self.Buffs then |
self.Debuffs:ClearAllPoints() |
-- Remove space above debuffs if there are no buffs on the target |
if self.Buffs.visibleBuffs == 0 then |
self.Debuffs:SetPoint('TOPLEFT', self.Buffs, 'BOTTOMLEFT', 0, 0) |
else |
self.Debuffs:SetPoint('TOPLEFT', self.Buffs, 'BOTTOMLEFT', 0, -4) |
end |
end |
end |
-- replace blizzard icon borders, etc ------------------------------------------ |
function ok.PostCreateIcon(ele, button) |
button.icon:ClearAllPoints() |
button.icon:SetPoint('TOPLEFT', button, 'TOPLEFT', 1, -1) |
button.icon:SetPoint('BOTTOMRIGHT', button, 'BOTTOMRIGHT', -1, 1) |
button.icon:SetTexCoord(.07, .93, .07, .93) |
-- without a container frame, text displays beneath the cooldown |
button.texts = CreateFrame("Frame", nil, button) |
button.texts:SetAllPoints(button) |
if ele.CustomCooldown then |
button.cdc = ok:FontTemplate(button.texts, { size = 12 }) |
button.cdc:SetPoint('CENTER', 1, 0) |
button.cdc:SetTextColor(1, 1, 0) |
button.cdc.redText = false |
button.cdc.expires = (button.cd.start or 0) + (button.cd.duration or math.huge) |
button.cd.noCooldownCount = true |
end |
if ele:GetParent().raid then |
-- state that it is a raid indicator |
button:EnableMouse(false) |
button.count:Hide() |
button.cd:Hide() |
button.cd.Show = button.cd.Hide |
button.Tiny = true |
else |
-- custom icon border |
button.overlay:SetTexture(config.Textures.buff) |
button.overlay:SetTexCoord(0,1,0,1) |
button.overlay.Hide = function(self) self:SetVertexColor(.22, .27, .35) end |
button.count = ok:FontTemplate(button.count, { reset = true, size = 10 }) |
button.count:SetParent(button.texts) |
button.count:SetJustifyH('RIGHT') |
button.count:ClearAllPoints() |
button.count:SetPoint('BOTTOMRIGHT', button, 4, -1) |
button.cd:SetReverse(true) |
end |
end |
-- used by pet frame |
function ok.PostUpdateIconDebuff(ele, unit, icon, index, offset) |
local name, _, _, count, _, duration, expirationTime, caster |
= UnitDebuff(unit, index) |
ok.PostUpdateIcon(ele, unit, icon, index, offset, name, count, duration, expirationTime, caster) |
end |
-- used by group, target and focus frames |
function ok.PostUpdateIcon(ele, unit, icon, index, offset, name, count, duration, expirationTime, caster) |
if not name then |
-- try to find an aura |
name, _, _, count, _, duration, expirationTime, caster |
= UnitBuff(unit, index) |
if not name then |
name, _, _, count, _, duration, expirationTime, caster |
= UnitDebuff(unit, index) |
end |
end |
if not name then return end |
if icon.Tiny then |
-- reset alpha/`progress bar` height |
icon:SetAlpha(1) |
icon:SetHeight(6) |
if icon.colour then |
-- convert icon to raid indicator |
icon.icon:SetTexture(kui.m.t.solid) |
icon.icon:SetVertexColor(icon.colour[1], icon.colour[2], icon.colour[3]) |
end |
if icon.maxc then |
-- fade according to current count/max count |
icon:SetAlpha(count/icon.maxc) |
end |
--[[ |
TODO: this function is generally only called for player auras |
so i need to add more callbacks to this or find another function |
elseif config.greyScaleOtherAuras then |
if caster == 'player' or caster == 'vehicle' then |
icon.icon:SetDesaturated(false) |
else |
icon.icon:SetDesaturated(true) |
end]] |
end |
if icon.cdc then |
-- show/hide the cooldown count |
local show |
if duration and duration > 0 then |
icon.cdc.expires = expirationTime |
icon.cdc.nextUpdate = 0 |
show = true |
end |
if show then |
icon:SetScript('onUpdate', ok.BuffTimer) |
else |
icon.cdc.expires = nil |
icon:SetScript('onUpdate', nil) |
icon.cdc:Hide() |
end |
end |
end |
function ok.CustomAuraFilterRaid(icons, unit, icon, name, rank, texture, count, dtype, duration, timeLeft, caster) |
if caster == 'player' then |
if type(whitelist[ok.class][name]) == 'table' and |
whitelist[ok.class][name].colour |
then |
icon.colour = whitelist[ok.class][name].colour |
icon.maxc = whitelist[ok.class][name].maxc or nil |
return true |
end |
end |
end |
function ok.CustomAuraFilter(icons, unit, icon, name, rank, texture, count, dtype, duration, timeLeft, caster) |
if caster == 'player' then |
if whitelist[ok.class][name] then |
return true |
end |
end |
end |
-- sort auras by time remaining ------------------------------------------------ |
function ok.AurasPreSetPosition(icons, max) |
table.sort(icons, function(a, b) |
local tA, tB = |
a.cdc.expires or math.huge, |
b.cdc.expires or math.huge |
return tA < tB |
end) |
end |
ns.ok = ok |