Verified Commit 1d4bcbfb authored by Luckyone's avatar Luckyone
Browse files

Merge branch 'development' into main

parents 3ec69a21 1db0be13
### Version 2.15 [08-09-2021]
**Added back old player UnitFrame classbar for Shaman totems**
**Blizzard added heal prediction API. This version will support it.**
**Fixed an issue with Prayer of Shadow Protection AuraWatch**
**Removed absorb and overabsorb options. Not available in TBC.**
___
### Version 2.14 [02-09-2021]
**Fixed Merchant skin (Repair All, Guild Repair)**
___
......
......@@ -1073,7 +1073,7 @@ function E:ToggleOptionsUI(msg)
LoadAddOn('ElvUI_OptionsUI')
-- version check elvui options if it's actually enabled
if GetAddOnMetadata('ElvUI_OptionsUI', 'Version') ~= '2.14' then
if GetAddOnMetadata('ElvUI_OptionsUI', 'Version') ~= '2.15' then
self:StaticPopup_Show('CLIENT_UPDATE_REQUEST')
end
else
......
## Interface: 20502
## Author: Elv, Simpy
## Version: 2.14
## Version: 2.15
## Title: |cff1784d1ElvUI TBC|r
## Notes: User Interface replacement AddOn for World of Warcraft.
## SavedVariables: ElvDB, ElvPrivateDB
......
This diff is collapsed.
......@@ -14,7 +14,6 @@
<Script file='LibSimpleSticky\LibSimpleSticky.lua'/>
<Include file='LibQuestXP\LibQuestXP.xml'/>
<Script file='LibHealComm-4.0\LibHealComm-4.0.lua'/>
<Script file='LibClassicSpellActionCount-1.0\LibClassicSpellActionCount-1.0.lua'/>
<Include file='oUF\oUF.xml'/>
......
......@@ -204,6 +204,7 @@ end
do
function ClassPowerEnable(self)
self:RegisterEvent('UNIT_POWER_FREQUENT', Path)
self:RegisterEvent('UNIT_TARGET', Path)
self:RegisterEvent('UNIT_MAXPOWER', Path)
self.ClassPower.isEnabled = true
......@@ -213,6 +214,7 @@ do
function ClassPowerDisable(self)
self:UnregisterEvent('UNIT_POWER_FREQUENT', Path)
self:UnregisterEvent('UNIT_TARGET', Path)
self:UnregisterEvent('UNIT_MAXPOWER', Path)
local element = self.ClassPower
......
--[[
# Element: Health Prediction Bars
Handles the visibility and updating of incoming heals.
Handles the visibility and updating of incoming heals and heal/damage absorbs.
## Widget
......@@ -11,6 +11,10 @@ HealthPrediction - A `table` containing references to sub-widgets and options.
myBar - A `StatusBar` used to represent incoming heals from the player.
otherBar - A `StatusBar` used to represent incoming heals from others.
absorbBar - A `StatusBar` used to represent damage absorbs.
healAbsorbBar - A `StatusBar` used to represent heal absorbs.
overAbsorb - A `Texture` used to signify that the amount of damage absorb is greater than the unit's missing health.
overHealAbsorb - A `Texture` used to signify that the amount of heal absorb is greater than the unit's current health.
## Notes
......@@ -37,18 +41,45 @@ A default texture will be applied to the Texture widgets if they don't have a te
otherBar:SetPoint('LEFT', myBar:GetStatusBarTexture(), 'RIGHT')
otherBar:SetWidth(200)
local absorbBar = CreateFrame('StatusBar', nil, self.Health)
absorbBar:SetPoint('TOP')
absorbBar:SetPoint('BOTTOM')
absorbBar:SetPoint('LEFT', otherBar:GetStatusBarTexture(), 'RIGHT')
absorbBar:SetWidth(200)
local healAbsorbBar = CreateFrame('StatusBar', nil, self.Health)
healAbsorbBar:SetPoint('TOP')
healAbsorbBar:SetPoint('BOTTOM')
healAbsorbBar:SetPoint('RIGHT', self.Health:GetStatusBarTexture())
healAbsorbBar:SetWidth(200)
healAbsorbBar:SetReverseFill(true)
local overAbsorb = self.Health:CreateTexture(nil, "OVERLAY")
overAbsorb:SetPoint('TOP')
overAbsorb:SetPoint('BOTTOM')
overAbsorb:SetPoint('LEFT', self.Health, 'RIGHT')
overAbsorb:SetWidth(10)
local overHealAbsorb = self.Health:CreateTexture(nil, "OVERLAY")
overHealAbsorb:SetPoint('TOP')
overHealAbsorb:SetPoint('BOTTOM')
overHealAbsorb:SetPoint('RIGHT', self.Health, 'LEFT')
overHealAbsorb:SetWidth(10)
-- Register with oUF
self.HealthPrediction = {
myBar = myBar,
otherBar = otherBar,
absorbBar = absorbBar,
healAbsorbBar = healAbsorbBar,
overAbsorb = overAbsorb,
overHealAbsorb = overHealAbsorb,
maxOverflow = 1.05,
}
--]]
local _, ns = ...
local oUF = ns.oUF
local myGUID = UnitGUID('player')
local HealComm = LibStub("LibHealComm-4.0")
local function Update(self, event, unit)
if(self.unit ~= unit) then return end
......@@ -65,21 +96,40 @@ local function Update(self, event, unit)
element:PreUpdate(unit)
end
local guid = UnitGUID(unit)
local allIncomingHeal = HealComm:GetHealAmount(guid, element.healType) or 0
local myIncomingHeal = (HealComm:GetHealAmount(guid, element.healType, nil, myGUID) or 0) * (HealComm:GetHealModifier(myGUID) or 1)
local myIncomingHeal = UnitGetIncomingHeals(unit, 'player') or 0
local allIncomingHeal = UnitGetIncomingHeals(unit) or 0
local absorb = 0
local healAbsorb = 0
local health, maxHealth = UnitHealth(unit), UnitHealthMax(unit)
local otherIncomingHeal = 0
local hasOverHealAbsorb = false
if(health + allIncomingHeal > maxHealth * element.maxOverflow) then
allIncomingHeal = maxHealth * element.maxOverflow - health
end
if(healAbsorb > allIncomingHeal) then
healAbsorb = healAbsorb - allIncomingHeal
allIncomingHeal = 0
myIncomingHeal = 0
if(allIncomingHeal < myIncomingHeal) then
myIncomingHeal = allIncomingHeal
if(health < healAbsorb) then
hasOverHealAbsorb = true
end
else
otherIncomingHeal = HealComm:GetOthersHealAmount(guid, HealComm.ALL_HEALS) or 0
allIncomingHeal = allIncomingHeal - healAbsorb
healAbsorb = 0
if(health + allIncomingHeal > maxHealth * element.maxOverflow) then
allIncomingHeal = maxHealth * element.maxOverflow - health
end
if(allIncomingHeal < myIncomingHeal) then
myIncomingHeal = allIncomingHeal
else
otherIncomingHeal = allIncomingHeal - myIncomingHeal
end
end
local hasOverAbsorb = false
if(health + allIncomingHeal + absorb >= maxHealth) and (absorb > 0) then
hasOverAbsorb = true
end
if(element.myBar) then
......@@ -94,16 +144,20 @@ local function Update(self, event, unit)
element.otherBar:Show()
end
--[[ Callback: HealthPrediction:PostUpdate(unit, myIncomingHeal, otherIncomingHeal)
--[[ Callback: HealthPrediction:PostUpdate(unit, myIncomingHeal, otherIncomingHeal, absorb, healAbsorb, hasOverAbsorb, hasOverHealAbsorb)
Called after the element has been updated.
* self - the HealthPrediction element
* unit - the unit for which the update has been triggered (string)
* myIncomingHeal - the amount of incoming healing done by the player (number)
* otherIncomingHeal - the amount of incoming healing done by others (number)
* absorb - the amount of damage the unit can absorb without losing health (number)
* healAbsorb - the amount of healing the unit can absorb without gaining health (number)
* hasOverAbsorb - indicates if the amount of damage absorb is higher than the unit's missing health (boolean)
* hasOverHealAbsorb - indicates if the amount of heal absorb is higher than the unit's current health (boolean)
--]]
if(element.PostUpdate) then
return element:PostUpdate(unit, myIncomingHeal, otherIncomingHeal)
return element:PostUpdate(unit, myIncomingHeal, otherIncomingHeal, absorb, healAbsorb, hasOverAbsorb, hasOverHealAbsorb, health, maxHealth)
end
end
......@@ -127,35 +181,10 @@ local function Enable(self)
if(element) then
element.__owner = self
element.ForceUpdate = ForceUpdate
element.healType = element.healType or HealComm.ALL_HEALS
self:RegisterEvent('UNIT_HEALTH_FREQUENT', Path)
self:RegisterEvent('UNIT_MAXHEALTH', Path)
local function HealCommUpdate(...)
if self.HealthPrediction and self:IsVisible() then
for i = 1, select('#', ...) do
if self.unit and UnitGUID(self.unit) == select(i, ...) then
Path(self, nil, self.unit)
end
end
end
end
local function HealComm_Heal_Update(event, casterGUID, spellID, healType, _, ...)
HealCommUpdate(...)
end
local function HealComm_Modified(event, guid)
HealCommUpdate(guid)
end
HealComm.RegisterCallback(element, 'HealComm_HealStarted', HealComm_Heal_Update)
HealComm.RegisterCallback(element, 'HealComm_HealUpdated', HealComm_Heal_Update)
HealComm.RegisterCallback(element, 'HealComm_HealDelayed', HealComm_Heal_Update)
HealComm.RegisterCallback(element, 'HealComm_HealStopped', HealComm_Heal_Update)
HealComm.RegisterCallback(element, 'HealComm_ModifierChanged', HealComm_Modified)
HealComm.RegisterCallback(element, 'HealComm_GUIDDisappeared', HealComm_Modified)
self:RegisterEvent('UNIT_HEAL_PREDICTION', Path)
if(not element.maxOverflow) then
element.maxOverflow = 1.05
......@@ -188,15 +217,13 @@ local function Disable(self)
element.otherBar:Hide()
end
HealComm.UnregisterCallback(element, 'HealComm_HealStarted')
HealComm.UnregisterCallback(element, 'HealComm_HealUpdated')
HealComm.UnregisterCallback(element, 'HealComm_HealDelayed')
HealComm.UnregisterCallback(element, 'HealComm_HealStopped')
HealComm.UnregisterCallback(element, 'HealComm_ModifierChanged')
HealComm.UnregisterCallback(element, 'HealComm_GUIDDisappeared')
if(element.absorbBar) then
element.absorbBar:Hide()
end
self:UnregisterEvent('UNIT_MAXHEALTH', Path)
self:UnregisterEvent('UNIT_HEALTH_FREQUENT', Path)
self:UnregisterEvent('UNIT_MAXHEALTH', Path)
self:UnregisterEvent('UNIT_HEAL_PREDICTION', Path)
end
end
......
......@@ -22,50 +22,44 @@ OnEnter and OnLeave script handlers will be set to display a Tooltip if the `Tot
## Examples
local Totems = {}
for index = 1, 5 do
-- Position and size of the totem indicator
local Totem = CreateFrame('Button', nil, self)
Totem:SetSize(40, 40)
Totem:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', index * Totem:GetWidth(), 0)
local Totems = {}
for index = 1, 5 do
-- Position and size of the totem indicator
local Totem = CreateFrame('Button', nil, self)
Totem:SetSize(40, 40)
Totem:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', index * Totem:GetWidth(), 0)
local Icon = Totem:CreateTexture(nil, 'OVERLAY')
Icon:SetAllPoints()
local Icon = Totem:CreateTexture(nil, 'OVERLAY')
Icon:SetAllPoints()
local Cooldown = CreateFrame('Cooldown', nil, Totem, 'CooldownFrameTemplate')
Cooldown:SetAllPoints()
local Cooldown = CreateFrame('Cooldown', nil, Totem, 'CooldownFrameTemplate')
Cooldown:SetAllPoints()
Totem.Icon = Icon
Totem.Cooldown = Cooldown
Totem.Icon = Icon
Totem.Cooldown = Cooldown
Totems[index] = Totem
end
Totems[index] = Totem
end
-- Register with oUF
self.Totems = Totems
-- Register with oUF
self.Totems = Totems
--]]
local _, ns = ...
local oUF = ns.oUF
local GameTooltip = GameTooltip
local function UpdateTooltip(self)
if GameTooltip:IsForbidden() then return end
GameTooltip:SetTotem(self:GetID())
end
local function OnEnter(self)
if GameTooltip:IsForbidden() or not self:IsVisible() then return end
if(not self:IsVisible()) then return end
GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT')
self:UpdateTooltip()
end
local function OnLeave()
if GameTooltip:IsForbidden() then return end
GameTooltip:Hide()
end
......@@ -92,9 +86,21 @@ local function UpdateTotem(self, event, slot)
totem.Cooldown:SetCooldown(start, duration)
end
totem:Show()
else
totem:Hide()
if totem:IsObjectType("Statusbar") then
totem:SetValue(0)
totem:SetScript("OnUpdate",function(self,elapsed)
self.total = (self.total or 0) + elapsed
if (self.total >= .01) then
self.total = 0
local _, _, startTime, expiration = GetTotemInfo(slot)
if ((GetTime() - startTime) == 0) then
self:SetValue(0)
else
self:SetValue(1 - ((GetTime() - startTime) / expiration))
end
end
end)
end
end
--[[ Callback: Totems:PostUpdate(slot, haveTotem, name, start, duration, icon)
......@@ -162,11 +168,6 @@ local function Enable(self)
self:RegisterEvent('PLAYER_TOTEM_UPDATE', Path, true)
TotemFrame:UnregisterEvent('PLAYER_TOTEM_UPDATE')
TotemFrame:UnregisterEvent('PLAYER_ENTERING_WORLD')
TotemFrame:UnregisterEvent('UPDATE_SHAPESHIFT_FORM')
TotemFrame:UnregisterEvent('PLAYER_TALENT_UPDATE')
return true
end
end
......@@ -178,11 +179,6 @@ local function Disable(self)
element[i]:Hide()
end
TotemFrame:RegisterEvent('PLAYER_TOTEM_UPDATE')
TotemFrame:RegisterEvent('PLAYER_ENTERING_WORLD')
TotemFrame:RegisterEvent('UPDATE_SHAPESHIFT_FORM')
TotemFrame:RegisterEvent('PLAYER_TALENT_UPDATE')
self:UnregisterEvent('PLAYER_TOTEM_UPDATE', Path)
end
end
......
......@@ -96,9 +96,8 @@ function UF:Configure_ClassBar(frame)
bars:Width(CLASSBAR_WIDTH - SPACING)
bars:Height(frame.CLASSBAR_HEIGHT - SPACING)
if frame.ClassBar == 'ClassPower' then
local maxClassBarButtons = max(UF.classMaxResourceBar[E.myclass] or 0, MAX_COMBO_POINTS)
if (frame.ClassBar == 'ClassPower' or frame.ClassBar == 'Totems') then
local maxClassBarButtons = max(UF.classMaxResourceBar[E.myclass] or 0, frame.ClassBar == 'Totems' and 4 or MAX_COMBO_POINTS)
for i = 1, maxClassBarButtons do
bars[i].backdrop:Hide()
......@@ -153,7 +152,7 @@ function UF:Configure_ClassBar(frame)
end
--Fix missing backdrop colors on Combo Points when using Spaced style
if frame.ClassBar == 'ClassPower' then
if frame.ClassBar == 'ClassPower' or frame.ClassBar == 'Totems' then
if frame.USE_MINI_CLASSBAR then
bars[i].bg:SetParent(bars[i].backdrop)
else
......@@ -239,8 +238,8 @@ function UF:Configure_ClassBar(frame)
if frame.AdditionalPower and not frame:IsElementEnabled('AdditionalPower') then
frame:EnableElement('AdditionalPower')
end
if frame.AlternativePower and not frame:IsElementEnabled('AlternativePower') then
frame:EnableElement('AlternativePower')
if frame.Totems and not frame:IsElementEnabled("Totems") then
frame:EnableElement("Totems")
end
else
if frame.ClassPower and frame:IsElementEnabled('ClassPower') then
......@@ -249,8 +248,8 @@ function UF:Configure_ClassBar(frame)
if frame.AdditionalPower and frame:IsElementEnabled('AdditionalPower') then
frame:DisableElement('AdditionalPower')
end
if frame.AlternativePower and frame:IsElementEnabled('AlternativePower') then
frame:DisableElement('AlternativePower')
if frame.Totems and frame:IsElementEnabled("Totems") then
frame:DisableElement("Totems")
end
end
end
......@@ -413,3 +412,48 @@ function UF:PostVisibilityAdditionalPower(enabled)
UF:PostVisibility_ClassBars(frame)
end
-----------------------------------------------------------
-- Totems
-----------------------------------------------------------
local TotemColors = {
[1] = {.58,.23,.10},
[2] = {.23,.45,.13},
[3] = {.19,.48,.60},
[4] = {.42,.18,.74},
}
function UF:Construct_Totems(frame)
local totems = CreateFrame("Frame", nil, frame)
totems:CreateBackdrop(nil, nil, nil, self.thinBorders, true)
totems.Destroy = {}
for i = 1, 4 do
local r, g, b = unpack(TotemColors[i])
totems[i] = CreateFrame("StatusBar", frame:GetName().."Totem"..i, totems)
totems[i]:CreateBackdrop(nil, nil, nil, self.thinBorders, true)
totems[i].backdrop:SetParent(totems)
totems[i]:SetStatusBarTexture(E.media.blankTex)
totems[i]:SetStatusBarColor(r, g, b)
UF.statusbars[totems[i]] = true
totems[i]:SetMinMaxValues(0, 1)
totems[i]:SetValue(0)
totems[i].bg = totems[i]:CreateTexture(nil, "BORDER")
totems[i].bg:SetAllPoints(totems[i])
totems[i].bg:SetTexture(E['media'].blankTex)
totems[i].bg.multiplier = 0.3
totems[i].bg:SetVertexColor(r * .3, g * .3, b * .3)
end
frame.MAX_CLASS_BAR = 4
frame.ClassBar = 'Totems'
return totems
end
local E, L, V, P, G = unpack(select(2, ...)) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local UF = E:GetModule('UnitFrames')
local HealComm = LibStub('LibHealComm-4.0')
local CreateFrame = CreateFrame
function UF.HealthClipFrame_HealComm(frame)
local pred = frame.HealthPrediction
if pred then
UF:SetAlpha_HealComm(pred, true)
UF:SetVisibility_HealComm(pred)
if frame.HealthPrediction then
UF:SetAlpha_HealComm(frame.HealthPrediction, 1)
end
end
function UF:SetAlpha_HealComm(obj, show)
obj.myBar:SetAlpha(show and 1 or 0)
obj.otherBar:SetAlpha(show and 1 or 0)
function UF:SetAlpha_HealComm(obj, alpha)
obj.myBar:SetAlpha(alpha)
obj.otherBar:SetAlpha(alpha)
end
function UF:SetVisibility_HealComm(obj)
-- the first update is from `HealthClipFrame_HealComm`
-- we set this variable to allow `Configure_HealComm` to
-- update the elements overflow lock later on by option
if not obj.allowClippingUpdate then
obj.allowClippingUpdate = true
end
function UF:SetTexture_HealComm(obj, texture)
if type(texture) == 'number' then texture = E.media.blankTex end
if obj.maxOverflow > 1 then
obj.myBar:SetParent(obj.health)
obj.otherBar:SetParent(obj.health)
else
obj.myBar:SetParent(obj.parent)
obj.otherBar:SetParent(obj.parent)
end
obj.myBar:SetStatusBarTexture(texture)
obj.otherBar:SetStatusBarTexture(texture)
end
function UF:SetFrameLevel_HealComm(obj, level)
obj.myBar:SetFrameLevel(level)
obj.otherBar:SetFrameLevel(level)
end
function UF:Construct_HealComm(frame)
......@@ -41,17 +32,7 @@ function UF:Construct_HealComm(frame)
local myBar = CreateFrame('StatusBar', nil, parent)
local otherBar = CreateFrame('StatusBar', nil, parent)
myBar:SetFrameLevel(11)
otherBar:SetFrameLevel(11)
UF.statusbars[myBar] = true
UF.statusbars[otherBar] = true
local texture = (not health.isTransparent and health:GetStatusBarTexture()) or E.media.blankTex
UF:Update_StatusBar(myBar, texture)
UF:Update_StatusBar(otherBar, texture)
local healPrediction = {
local prediction = {
myBar = myBar,
otherBar = otherBar,
maxOverflow = 1,
......@@ -60,79 +41,114 @@ function UF:Construct_HealComm(frame)
frame = frame
}
UF:SetAlpha_HealComm(healPrediction)
UF:SetAlpha_HealComm(prediction, 0)
UF:SetFrameLevel_HealComm(prediction, 11)
UF:SetTexture_HealComm(prediction, E.media.blankTex)
return prediction
end
function UF:SetSize_HealComm(frame)
local health = frame.Health
local pred = frame.HealthPrediction
local orientation = health:GetOrientation()
local db = frame.db.healPrediction
local width, height = health:GetSize()
if orientation == 'HORIZONTAL' then
local barHeight = db.height
if barHeight == -1 or barHeight > height then barHeight = height end
pred.myBar:SetSize(width, barHeight)
pred.otherBar:SetSize(width, barHeight)
pred.parent:SetSize(width * (pred.maxOverflow or 0), height)
else
local barWidth = db.height -- this is really width now not height
if barWidth == -1 or barWidth > width then barWidth = width end
return healPrediction
pred.myBar:SetSize(barWidth, height)
pred.otherBar:SetSize(barWidth, height)
pred.parent:SetSize(width, height * (pred.maxOverflow or 0))
end
end
function UF:Configure_HealComm(frame)
if frame.db.healPrediction and frame.db.healPrediction.enable then
local healPrediction = frame.HealthPrediction
local myBar = healPrediction.myBar
local otherBar = healPrediction.otherBar
local c = self.db.colors.healPrediction
healPrediction.maxOverflow = 1 + (c.maxOverflow or 0)
if healPrediction.allowClippingUpdate then
UF:SetVisibility_HealComm(healPrediction)
end
local db = frame.db.healPrediction
if db and db.enable then
local pred = frame.HealthPrediction
local parent = pred.parent
local myBar = pred.myBar
local otherBar = pred.otherBar
local colors = UF.db.colors.healPrediction
pred.maxOverflow = 1 + (colors.maxOverflow or 0)
if not frame:IsElementEnabled('HealthPrediction') then
frame:EnableElement('HealthPrediction')
end