diff --git a/libs/oUF_Plugins/oUF_BetterHealthPrediction/LICENSE b/libs/oUF_Plugins/oUF_BetterHealthPrediction/LICENSE new file mode 100644 index 0000000..cf1ab25 --- /dev/null +++ b/libs/oUF_Plugins/oUF_BetterHealthPrediction/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/libs/oUF_Plugins/oUF_BetterHealthPrediction/oUF_BetterHealthPrediction.lua b/libs/oUF_Plugins/oUF_BetterHealthPrediction/oUF_BetterHealthPrediction.lua new file mode 100644 index 0000000..a3b4f6e --- /dev/null +++ b/libs/oUF_Plugins/oUF_BetterHealthPrediction/oUF_BetterHealthPrediction.lua @@ -0,0 +1,293 @@ +--[[ +# Element: Better Health Prediction Bars + +Handles the visibility and updating of incoming heals and heal/damage absorbs. With + +## Widget + +BetterHealthPrediction - A `table` containing references to sub-widgets and options. + +## Sub-Widgets + +otherBeforeBar - A `StatusBar` used to represent incoming heals from others that will land before mine. +myBar - A `StatusBar` used to represent incoming heals from the player. +otherAfterBar - A `StatusBar` used to represent incoming heals from others that will land after mine. +hotBar - A `StatusBar` used to represent healing over time. + +## Notes + +A default texture will be applied to the StatusBar widgets if they don"t have a texture set. +A default texture will be applied to the Texture widgets if they don"t have a texture or a color set. + +## Options + +.disableHots - Disable heal over time effects +.timeFrame - The amount of time into the future used for healing prediction. Defaults to 4 (number) +.maxOverflow - The maximum amount of overflow past the end of the health bar. Set this to 1 to disable the overflow. + Defaults to 1.05 (number) + +## Examples + + -- Position and size + local otherBeforeBar = CreateFrame("StatusBar", nil, self.Health) + otherBeforeBar:SetPoint("TOP") + otherBeforeBar:SetPoint("BOTTOM") + otherBeforeBar:SetPoint("LEFT", self.Health:GetStatusBarTexture(), "RIGHT") + otherBeforeBar:SetWidth(self.Health:GetWidth()) + + local myBar = CreateFrame("StatusBar", nil, self.Health) + myBar:SetPoint("TOP") + myBar:SetPoint("BOTTOM") + myBar:SetPoint("LEFT", otherBeforeBar:GetStatusBarTexture(), "RIGHT") + myBar:SetWidth(self.Health:GetWidth()) + + local otherAfterBar = CreateFrame("StatusBar", nil, self.Health) + otherAfterBar:SetPoint("TOP") + otherAfterBar:SetPoint("BOTTOM") + otherAfterBar:SetPoint("LEFT", myBar:GetStatusBarTexture(), "RIGHT") + otherAfterBar:SetWidth(self.Health:GetWidth()) + + -- Register with oUF + self.BetterHealthPrediction = { + otherBeforeBar = otherBeforeBar, + myBar = myBar, + otherAfterBar = otherAfterBar, + 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 + + local element = self.BetterHealthPrediction + + --[[ Callback: BetterHealthPrediction:PreUpdate(unit) + Called before the element has been updated. + + * self - the BetterHealthPrediction element + * unit - the unit for which the update has been triggered (string) + --]] + if(element.PreUpdate) then + element:PreUpdate(unit) + end + + local guid = UnitGUID(unit) + local timeFrame = GetTime() + element.timeFrame + local preHeal, myHeal, afterHeal, hotHeal, totalHeal = 0, 0, 0, 0, 0 + local health, maxHealth = UnitHealth(unit), UnitHealthMax(unit) + local mod = HealComm:GetHealModifier(guid) or 1 + + totalHeal = HealComm:GetHealAmount(guid, HealComm.DIRECT_HEALS, timeFrame) or 0 + myHeal = HealComm:GetHealAmount(guid, HealComm.DIRECT_HEALS, timeFrame, myGUID) or 0 + -- We can only scout up to 2 direct heals that would land before ours but thats good enough for most cases + local healTime, healFrom, healAmount = HealComm:GetNextHealAmount(guid, HealComm.DIRECT_HEALS, timeFrame) + if healFrom and healFrom ~= UnitGUID("player") and myHeal > 0 then + preHeal = healAmount + healTime, healFrom, healAmount = HealComm:GetNextHealAmount(guid, HealComm.DIRECT_HEALS, timeFrame, healFrom) + if healFrom and healFrom ~= UnitGUID("player") then + preHeal = preHeal + healAmount + end + end + afterHeal = totalHeal - preHeal - myHeal + if element.disableHots then + hotHeal = 0 + else + hotHeal = HealComm:GetHealAmount(guid, bit.bor(HealComm.HOT_HEALS, HealComm.CHANNEL_HEALS), timeFrame) or 0 + end + totalHeal = totalHeal + hotHeal + + local maxBar = (maxHealth * element.maxOverflow - health) + if preHeal >= maxBar then + preHeal = maxBar + myHeal = 0 + afterHeal = 0 + hotHeal = 0 + elseif (preHeal + myHeal) >= maxBar then + myHeal = maxBar - preHeal + afterHeal = 0 + hotHeal = 0 + elseif (preHeal + myHeal + afterHeal) >= maxBar then + afterHeal = maxBar - preHeal - myHeal + hotHeal = 0 + elseif (preHeal + myHeal + afterHeal + hotHeal) >= maxBar then + hotHeal = maxBar - preHeal - myHeal - afterHeal + end + + if(element.otherBeforeBar) then + element.otherBeforeBar:SetMinMaxValues(0, maxHealth) + element.otherBeforeBar:SetValue(preHeal*mod) + if totalHeal > 0 then -- This needs to be totalHeal because only shown bars are size updated and bars might depend on another like in the example + element.otherBeforeBar:Show() + else + element.otherBeforeBar:Hide() + end + end + + if(element.myBar) then + element.myBar:SetMinMaxValues(0, maxHealth) + element.myBar:SetValue(myHeal*mod) + if totalHeal > 0 then + element.myBar:Show() + else + element.myBar:Hide() + end + end + + if(element.otherAfterBar) then + element.otherAfterBar:SetMinMaxValues(0, maxHealth) + element.otherAfterBar:SetValue(afterHeal*mod) + if totalHeal > 0 then + element.otherAfterBar:Show() + else + element.otherAfterBar:Hide() + end + end + + if(element.hotBar) then + element.hotBar:SetMinMaxValues(0, maxHealth) + element.hotBar:SetValue(hotHeal*mod) + if totalHeal > 0 then + element.hotBar:Show() + else + element.hotBar:Hide() + end + end + + --[[ Callback: BetterHealthPrediction:PostUpdate(unit, myIncomingHeal, otherIncomingHeal, absorb, healAbsorb, hasOverAbsorb, hasOverHealAbsorb) + Called after the element has been updated. + + * self - the BetterHealthPrediction 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) + * otherIncomingHeal - the amount of incoming healing done by others (number) + * hotHeal - the amount of incoming healing done by others (number) + --]] + if(element.PostUpdate) then + -- return element:PostUpdate(unit, myIncomingHeal, otherIncomingHeal, absorb, healAbsorb, hasOverAbsorb, hasOverHealAbsorb) + return element:PostUpdate(unit, myIncomingHeal, otherIncomingHeal) + end +end + +local function Path(self, ...) + --[[ Override: BetterHealthPrediction.Override(self, event, unit) + Used to completely override the internal update function. + + * self - the parent object + * event - the event triggering the update (string) + * unit - the unit accompanying the event + --]] + return (self.BetterHealthPrediction.Override or Update) (self, ...) +end + +local function ForceUpdate(element) + return Path(element.__owner, "ForceUpdate", element.__owner.unit) +end + +local function Enable(self) + local element = self.BetterHealthPrediction + if(element) then + element.__owner = self + element.ForceUpdate = ForceUpdate + + self:RegisterEvent("UNIT_HEALTH_FREQUENT", Path) + self:RegisterEvent("UNIT_MAXHEALTH", Path) + + local function HealCommUpdate(...) + if self.BetterHealthPrediction 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) + + if(not element.timeFrame) then + element.timeFrame = 4 + end + + if(not element.maxOverflow) then + element.maxOverflow = 1.05 + end + + if(element.otherBeforeBar) then + if(element.otherBeforeBar:IsObjectType("StatusBar") and not element.otherBeforeBar:GetStatusBarTexture()) then + element.otherBeforeBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + end + end + + if(element.myBar) then + if(element.myBar:IsObjectType("StatusBar") and not element.myBar:GetStatusBarTexture()) then + element.myBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + end + end + + if(element.otherAfterBar) then + if(element.otherAfterBar:IsObjectType("StatusBar") and not element.otherAfterBar:GetStatusBarTexture()) then + element.otherAfterBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + end + end + + if(element.hotBar) then + if(element.hotBar:IsObjectType("StatusBar") and not element.hotBar:GetStatusBarTexture()) then + element.hotBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + end + end + + return true + end +end + +local function Disable(self) + local element = self.BetterHealthPrediction + if(element) then + if(element.otherBeforeBar) then + element.otherBeforeBar:Hide() + end + + if(element.myBar) then + element.myBar:Hide() + end + + if(element.otherAfterBar) then + element.otherAfterBar:Hide() + end + + if(element.hotBar) then + element.hotBar: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") + + self:UnregisterEvent("UNIT_MAXHEALTH", Path) + self:UnregisterEvent("UNIT_HEALTH_FREQUENT", Path) + end +end + +oUF:AddElement("BetterHealthPrediction", Path, Enable, Disable) diff --git a/libs/oUF_Plugins/oUF_BorderHighlight/LICENSE b/libs/oUF_Plugins/oUF_BorderHighlight/LICENSE new file mode 100644 index 0000000..cf1ab25 --- /dev/null +++ b/libs/oUF_Plugins/oUF_BorderHighlight/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/libs/oUF_Plugins/oUF_BorderHighlight/oUF_BorderHighlight.lua b/libs/oUF_Plugins/oUF_BorderHighlight/oUF_BorderHighlight.lua new file mode 100644 index 0000000..63fe810 --- /dev/null +++ b/libs/oUF_Plugins/oUF_BorderHighlight/oUF_BorderHighlight.lua @@ -0,0 +1,226 @@ +--[[ +# Element: Border Highlight + +Show a "glowing" texture when certain conditions are met. + +## Widget + +BorderHighlight - A "Table". + +## Options + +.target - Highlight when this is your current target (boolean) +.mouseover - Highlight when your mouse is over this unit (boolean) +.aggro - Highlight when this unit has aggro (boolean) +.debuff - Highlight when this unit has a debuff (integer) + 1 - off (same as nil) + 2 - Only highlight on debuffs you can dispel + 3 - Highlight on all dispellable debuffs + +#colors +.targetColor - {1, 1, 1} +.mouseoverColor - {1, 1, 1} + +## Notes + +A default texture will be applied if the widget is a Texture and doesn't have a texture set. + +## Examples + + -- Position and size + local BorderHighlight = {} + + -- Register it with oUF + self.BorderHighlight = BorderHighlight +--]] + +local _, ns = ... +local oUF = ns.oUF + +local playerClass = select(2, UnitClass("player")) +local canCure = {} +local cures = { + ["DRUID"] = {[2782] = {"Curse"}, [2893] = {"Poison"}, [8946] = {"Poison"}}, + ["PRIEST"] = {[528] = {"Disease"}, [552] = {"Disease"}, [527] = {"Magic"}, [988] = {"Magic"}}, + ["PALADIN"] = {[4987] = {"Poison", "Disease", "Magic"}, [1152] = {"Poison", "Disease"}}, + ["SHAMAN"] = {[2870] = {"Disease"}, [526] = {"Poison"}}, + ["MAGE"] = {[475] = {"Curse"}}, +} +cures = cures[playerClass] + +local function OnSizeChanged(self) + if not self then return end + local x, y = self:GetWidth(), self:GetHeight() + if x == 0 or y == 0 then return end + self.top:SetSize(x, self.size) + self.bottom:SetSize(x, self.size) + self.left:SetSize(self.size, y + (self.size * 2)) + self.right:SetSize(self.size, y + (self.size * 2)) +end + +local function Update(self, event) + local element = self.BorderHighlight + local unit = self.unit + if not UnitExists(unit) then return end + + if element.center.size ~= element.size then + element.center.size = element.size + OnSizeChanged(element.center) + end + + --[[ Callback: BorderHighlight:PreUpdate() + Called before the element has been updated. + + * self - the BorderHighlight element + --]] + if(element.PreUpdate) then + element:PreUpdate() + end + + local hasMouseover = self == GetMouseFocus() + local isTarget = UnitIsUnit("target", unit) + local hasAggro = (UnitThreatSituation(unit) or 0) > 1 + local showOwn, showAll, hasDebuff, highlightReason = element.debuff == 2, element.debuff == 3 + if UnitIsFriend(unit, "player") then + for i=1, 16 do + local name, _, _, auraType = UnitDebuff(unit, i) + if( not name ) then break end + + if( showOwn and canCure[auraType] and UnitCanAssist("player", unit) or (showAll and auraType) ) then + hasDebuff = auraType + break + end + end + end + + local color + if element.debuff and element.debuff ~= 1 and hasDebuff then + color = oUF.colors.debuff[hasDebuff] + highlightReason = "debuff" + elseif element.aggro and hasAggro then + color = oUF.colors.threat[4] + highlightReason = "aggro" + elseif element.target and isTarget then + color = element.targetColor + highlightReason = "target" + elseif element.mouseover and hasMouseover then + color = element.mouseoverColor + highlightReason = "mouseover" + end + + if not color then + element.center:Hide() + else + element.center:Show() + element.center.top:SetVertexColor(unpack(color)) + element.center.bottom:SetVertexColor(unpack(color)) + element.center.left:SetVertexColor(unpack(color)) + element.center.right:SetVertexColor(unpack(color)) + end + + --[[ Callback: BorderHighlight:PostUpdate(highlightReason) + Called after the element has been updated. + + * self - the BorderHighlight element + * highlightReason - what type of highlight is shown (nil, "mouseover", "target", "aggro", "debuff") (string) + --]] + if(element.PostUpdate) then + return element:PostUpdate(highlightReason) + end +end + +local function checkCurableSpells(self, event, arg1) + if event == "UNIT_PET" and (arg1 ~= "player" or playerClass ~= "WARLOCK") then return end + table.wipe(canCure) + + if playerClass == "WARLOCK" then + if IsUsableSpell(GetSpellInfo(19505)) then + canCure["Magic"] = true + end + elseif cures then + for spellID, types in pairs(cures) do + if( IsPlayerSpell(spellID) ) then + for _, type in pairs(types) do + canCure[type] = true + end + end + end + else + return + end + Update(self, event, self.unit) +end + +local function Path(self, ...) + --[[ Override: BorderHighlight.Override(self, event, ...) + Used to completely override the internal update function. + + * self - the parent object + * event - the event triggering the update (string) + * ... - the arguments accompanying the event + --]] + return (self.BorderHighlight.Override or Update) (self, ...) +end + +local function ForceUpdate(element) + return Path(element.__owner, "ForceUpdate", element.__owner.unit) +end + +local function Enable(self) + local element = self.BorderHighlight + if(element) then + element.__owner = self + element.ForceUpdate = ForceUpdate + + self:RegisterEvent("UPDATE_MOUSEOVER_UNIT", Path, true) + self:RegisterEvent("UNIT_AURA", Path) + self:RegisterEvent("UNIT_THREAT_SITUATION_UPDATE", Path) + self:RegisterEvent("PLAYER_TARGET_CHANGED", Path, true) + + self:RegisterEvent("LEARNED_SPELL_IN_TAB", checkCurableSpells, true) + self:RegisterEvent("PLAYER_LOGIN", checkCurableSpells, true) + self:RegisterEvent("UNIT_PET", checkCurableSpells, true) + + if not element.center then + element.center = CreateFrame("Frame", nil, self) + element.center:SetScript("OnSizeChanged", OnSizeChanged) + element.center:SetAllPoints(self) + element.center.top = element.center:CreateTexture(nil, "BACKGROUND") + element.center.top:SetTexture([[Interface\Buttons\WHITE8X8]]) + element.center.top:SetPoint("BOTTOMLEFT", element.center, "TOPLEFT") + element.center.bottom = element.center:CreateTexture(nil, "BACKGROUND") + element.center.bottom:SetTexture([[Interface\Buttons\WHITE8X8]]) + element.center.bottom:SetPoint("TOPLEFT", element.center, "BOTTOMLEFT") + element.center.left = element.center:CreateTexture(nil, "BACKGROUND") + element.center.left:SetTexture([[Interface\Buttons\WHITE8X8]]) + element.center.left:SetPoint("BOTTOMRIGHT", element.center.bottom, "BOTTOMLEFT") + element.center.right = element.center:CreateTexture(nil, "BACKGROUND") + element.center.right:SetTexture([[Interface\Buttons\WHITE8X8]]) + element.center.right:SetPoint("BOTTOMLEFT", element.center.bottom, "BOTTOMRIGHT") + end + element.size = element.size or 1 + element.center:Hide() + + checkCurableSpells(self) + + return true + end +end + +local function Disable(self) + local element = self.BorderHighlight + if(element) then + element.center:Hide() + + self:UnregisterEvent("UPDATE_MOUSEOVER_UNIT", Path) + self:UnregisterEvent("UNIT_AURA", Path) + self:UnregisterEvent("UNIT_THREAT_SITUATION_UPDATE", Path) + self:UnregisterEvent("PLAYER_TARGET_CHANGED", Path) + + self:UnregisterEvent("LEARNED_SPELL_IN_TAB", checkCurableSpells) + self:UnregisterEvent("PLAYER_LOGIN", checkCurableSpells) + self:UnregisterEvent("UNIT_PET", checkCurableSpells) + end +end + +oUF:AddElement("BorderHighlight", Path, Enable, Disable) \ No newline at end of file diff --git a/libs/oUF_Plugins/oUF_ClassIndicator/LICENSE b/libs/oUF_Plugins/oUF_ClassIndicator/LICENSE new file mode 100644 index 0000000..cf1ab25 --- /dev/null +++ b/libs/oUF_Plugins/oUF_ClassIndicator/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/libs/oUF_Plugins/oUF_ClassIndicator/oUF_ClassIndicator.lua b/libs/oUF_Plugins/oUF_ClassIndicator/oUF_ClassIndicator.lua new file mode 100644 index 0000000..08c3b8b --- /dev/null +++ b/libs/oUF_Plugins/oUF_ClassIndicator/oUF_ClassIndicator.lua @@ -0,0 +1,94 @@ +--[[ +# Element: Class Indicator + +Displays a corresponding class icon. + +## Widget + +ClassIndicator - A Texture. + +## Examples + + -- Position and size + local ClassIndicator = self:CreateTexture(nil, 'OVERLAY') + ClassIndicator:SetSize(16, 16) + ClassIndicator:SetPoint('BOTTOM', self, 'TOP') + + -- Register it with oUF + self.ClassIndicator = ClassIndicator +--]] + +local _, ns = ... +local oUF = _G.oUF or ns.oUF + +local UnitIsPlayer = UnitIsPlayer +local UnitClass = UnitClass +local CLASS_ICON_TCOORDS = CLASS_ICON_TCOORDS + +local function Update(self, event) + local element = self.ClassIndicator + local unit = self.unit + + --[[ Callback: ClassIndicator:PreUpdate() + Called before the element has been updated. + + * self - the ClassIndicator element + --]] + if(element.PreUpdate) then + element:PreUpdate() + end + + local className = select(2,UnitClass(unit)) + if( UnitIsPlayer(unit) and className ) then + local coords = CLASS_ICON_TCOORDS[className] + element:SetTexture("Interface\\Glues\\CharacterCreate\\UI-CharacterCreate-Classes") + element:SetTexCoord(coords[1], coords[2], coords[3], coords[4]) + element:Show() + else + element:Hide() + end + + --[[ Callback: ClassIndicator:PostUpdate(className) + Called after the element has been updated. + + * self - the ClassIndicator element + * className - indicates whether the element is shown (boolean) + --]] + if(element.PostUpdate) then + return element:PostUpdate(className) + end +end + +local function Path(self, ...) + --[[ Override: ClassIndicator.Override(self, event, ...) + Used to completely override the internal update function. + + * self - the parent object + * event - the event triggering the update (string) + * ... - the arguments accompanying the event + --]] + return (self.ClassIndicator.Override or Update) (self, ...) +end + +local function ForceUpdate(element) + return Path(element.__owner, "ForceUpdate") +end + +local function Enable(self) + local element = self.ClassIndicator + if(element) then + element.__owner = self + element.ForceUpdate = ForceUpdate + + return true + end +end + +local function Disable(self) + local element = self.ClassIndicator + if(element) then + element:Hide() + end +end + +oUF:AddElement("ClassIndicator", Path, Enable, Disable) \ No newline at end of file diff --git a/libs/oUF_Plugins/oUF_CombatText/LICENSE b/libs/oUF_Plugins/oUF_CombatText/LICENSE new file mode 100644 index 0000000..cf1ab25 --- /dev/null +++ b/libs/oUF_Plugins/oUF_CombatText/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/libs/oUF_Plugins/oUF_CombatText/oUF_CombatText.lua b/libs/oUF_Plugins/oUF_CombatText/oUF_CombatText.lua new file mode 100644 index 0000000..a6f22d8 --- /dev/null +++ b/libs/oUF_Plugins/oUF_CombatText/oUF_CombatText.lua @@ -0,0 +1,108 @@ +--[[ +# Element: Combat Text + +Flashes combat values (heal, damage, ...). + +## Widget + +CombatText - A frame. + +## Options + +.feedbackFontHeight Font Height (integer) +.font Font (string) + +## Examples + + -- Register with oUF + self.CombatText = CreateFrame("Frame", nil, self) + self.CombatText.feedbackFontHeight = 10 + self.CombatText.font = "Fonts\FRIZQT__.TTF" +--]] + +local _, ns = ... +local oUF = ns.oUF + +local function Update(self, event, unit) + local element = self.CombatText + local unit = self.unit + + --[[ Callback: CombatText:PreUpdate() + Called before the element has been updated. + + * self - the CombatText element + --]] + if(element.PreUpdate) then + element:PreUpdate() + end + + element.feedbackText:SetFont(element.font, element.feedbackFontHeight, "OUTLINE") + + --[[ Callback: CombatText:PostUpdate(object) + Called after the element has been updated. + + * self - the CombatText element + * object - the parent object + * inRange - indicates if the unit was within 40 yards of the player (boolean) + --]] + if(element.PostUpdate) then + return element:PostUpdate(self, inRange, checkedRange, connected) + end +end + +local function Eventhandler(self, event, unit, eventtype, flags, amount, type) + local element = self.CombatText + + if( type == "IMMUNE" ) then + element.feedbackText:SetTextHeight((element.feedbackFontHeight + 1) * 0.75) + end + + local scale = element.feedbackText:GetStringHeight() / element.feedbackFontHeight + if( scale > 0 ) then + element.feedbackText:SetScale(scale) + end + + CombatFeedback_OnCombatEvent(element, eventtype, flags, amount, type) +end + +local function Path(self, ...) + --[[ Override: CombatText.Override(self, event) + Used to completely override the internal update function. + + * self - the parent object + * event - the event triggering the update (string) + --]] + return (self.CombatText.Override or Update) (self, ...) +end + +local function Enable(self) + local element = self.CombatText + if(element) then + element.__owner = self + + if not element.feedbackText or not element.feedbackText:IsObjectType("FontString") then + element.feedbackText = element:CreateFontString(nil, "ARTWORK") + element.feedbackText:SetFont("Fonts\FRIZQT__.TTF", 10) + element.feedbackText:SetShadowColor(0, 0, 0, 1.0) + element.feedbackText:SetShadowOffset(0.80, -0.80) + element.feedbackText:SetPoint("CENTER", element, "CENTER") + end + + self:RegisterEvent("UNIT_COMBAT", Eventhandler) + element:SetScript("OnUpdate", CombatFeedback_OnUpdate) + element.feedbackStartTime = 0 + + return true + end +end + +local function Disable(self) + local element = self.CombatText + if(element) then + element:SetScript("OnUpdate", nil) + element:Hide() + self:UnregisterEvent("UNIT_COMBAT") + end +end + +oUF:AddElement('CombatText', Path, Enable, Disable) \ No newline at end of file diff --git a/libs/oUF_Plugins/oUF_ComboPoints/LICENSE b/libs/oUF_Plugins/oUF_ComboPoints/LICENSE new file mode 100644 index 0000000..cf1ab25 --- /dev/null +++ b/libs/oUF_Plugins/oUF_ComboPoints/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/libs/oUF_Plugins/oUF_ComboPoints/oUF_ComboPoints.lua b/libs/oUF_Plugins/oUF_ComboPoints/oUF_ComboPoints.lua new file mode 100644 index 0000000..dfbea5d --- /dev/null +++ b/libs/oUF_Plugins/oUF_ComboPoints/oUF_ComboPoints.lua @@ -0,0 +1,273 @@ +--[[ +# Element: ComboPoints + +Handles the visibility and updating of the player"s class resources (like Chi Orbs or Holy Power) and combo points. + +## Widget + +ComboPoints - A `table` consisting of 5 StatusBars as the maximum return of [UnitPowerMax](http://wowprogramming.com/docs/api/UnitPowerMax.html). + +## Sub-Widgets + +.bg - A `Texture` used as a background. It will inherit the color of the main StatusBar. + +## Sub-Widget Options + +.multiplier - Used to tint the background based on the widget"s R, G and B values. Defaults to 1 (number)[0-1] + +## Notes + +A default texture will be applied if the sub-widgets are StatusBars and don"t have a texture set. +If the sub-widgets are StatusBars, their minimum and maximum values will be set to 0 and 1 respectively. + +Supported class powers: +- All - Combo Points + +## Examples + + local ComboPoints = {} + for index = 1, 5 do + local Bar = CreateFrame("StatusBar", nil, self) + + -- Position and size. + Bar:SetSize(16, 16) + Bar:SetPoint("TOPLEFT", self, "BOTTOMLEFT", (index - 1) * Bar:GetWidth(), 0) + + ComboPoints[index] = Bar + end + + -- Register with oUF + self.ComboPoints = ComboPoints +--]] + +local _, ns = ... +local oUF = ns.oUF + +local _, PlayerClass = UnitClass("player") + +-- sourced from FrameXML/Constants.lua +local SPELL_POWER_ENERGY = Enum.PowerType.Energy or 3 +local SPELL_POWER_COMBO_POINTS = Enum.PowerType.ComboPoints or 4 + +-- Holds the class specific stuff. +local ClassPowerID, ClassPowerType +local ComboPointsEnable, ComboPointsDisable +local RequirePower, RequireSpell + +local function UpdateColor(element, powerType) + local color = element.__owner.colors.power[powerType] + local r, g, b = color[1], color[2], color[3] + for i = 1, #element do + local bar = element[i] + bar:SetStatusBarColor(r, g, b) + + local bg = bar.bg + if(bg) then + local mu = bg.multiplier or 1 + bg:SetVertexColor(r * mu, g * mu, b * mu) + end + end +end + +local function Update(self, event, unit, powerType) + if (not (unit and (UnitIsUnit(unit, "player") and powerType == ClassPowerType))) then + return + end + + local element = self.ComboPoints + + --[[ Callback: ComboPoints:PreUpdate(event) + Called before the element has been updated. + + * self - the ComboPoints element + ]] + if(element.PreUpdate) then + element:PreUpdate() + end + + local cur, max, mod, oldMax + if(event ~= "ComboPointsDisable") then + local powerID = ClassPowerID + cur = UnitPower(unit, powerID, true) + max = UnitPowerMax(unit, powerID) + mod = UnitPowerDisplayMod(powerID) + + -- mod should never be 0, but according to Blizz code it can actually happen + cur = mod == 0 and 0 or cur / mod + + local numActive = cur + 0.9 + for i = 1, max do + if(i > numActive) then + element[i]:Hide() + element[i]:SetValue(0) + else + element[i]:Show() + element[i]:SetValue(cur - i + 1) + end + end + + oldMax = element.__max + if(max ~= oldMax) then + if(max < oldMax) then + for i = max + 1, oldMax do + element[i]:Hide() + element[i]:SetValue(0) + end + end + + element.__max = max + end + end + --[[ Callback: ComboPoints:PostUpdate(cur, max, hasMaxChanged, powerType) + Called after the element has been updated. + + * self - the ComboPoints element + * cur - the current amount of power (number) + * max - the maximum amount of power (number) + * hasMaxChanged - indicates whether the maximum amount has changed since the last update (boolean) + * powerType - the active power type (string) + --]] + if(element.PostUpdate) then + return element:PostUpdate(cur, max, oldMax ~= max, powerType) + end +end + +local function Path(self, ...) + --[[ Override: ComboPoints.Override(self, event, unit, ...) + Used to completely override the internal update function. + + * self - the parent object + * event - the event triggering the update (string) + * unit - the unit accompanying the event (string) + * ... - the arguments accompanying the event + --]] + return (self.ComboPoints.Override or Update) (self, ...) +end + +local function Visibility(self, event, unit) + local element = self.ComboPoints + local shouldEnable + + if(ClassPowerID) then + -- use "player" instead of unit because "SPELLS_CHANGED" is a unitless event + if(not RequirePower or RequirePower == UnitPowerType("player")) then + if(not RequireSpell or IsPlayerSpell(RequireSpell)) then + self:UnregisterEvent("SPELLS_CHANGED", Visibility) + shouldEnable = true + unit = "player" + else + self:RegisterEvent("SPELLS_CHANGED", Visibility, true) + end + end + end + + local isEnabled = element.isEnabled + local powerType = ClassPowerType + + if(shouldEnable) then + --[[ Override: ComboPoints:UpdateColor(powerType) + Used to completely override the internal function for updating the widgets" colors. + + * self - the ComboPoints element + * powerType - the active power type (string) + --]] + (element.UpdateColor or UpdateColor) (element, powerType) + end + + if(shouldEnable and not isEnabled) then + ComboPointsEnable(self) + elseif(not shouldEnable and (isEnabled or isEnabled == nil)) then + ComboPointsDisable(self) + elseif(shouldEnable and isEnabled) then + Path(self, event, unit, powerType) + end +end + +local function VisibilityPath(self, ...) + --[[ Override: ComboPoints.OverrideVisibility(self, event, unit) + Used to completely override the internal visibility function. + + * self - the parent object + * event - the event triggering the update (string) + * unit - the unit accompanying the event (string) + --]] + return (self.ComboPoints.OverrideVisibility or Visibility) (self, ...) +end + +local function ForceUpdate(element) + return VisibilityPath(element.__owner, "ForceUpdate", element.__owner.unit) +end + +do + function ComboPointsEnable(self) + self:RegisterEvent("UNIT_POWER_FREQUENT", Path, true) + self:RegisterEvent("UNIT_MAXPOWER", Path, true) + + self.ComboPoints.isEnabled = true + + Path(self, "ComboPointsEnable", "player", ClassPowerType) + end + + function ComboPointsDisable(self) + self:UnregisterEvent("UNIT_POWER_FREQUENT", Path) + self:UnregisterEvent("UNIT_MAXPOWER", Path) + + local element = self.ComboPoints + for i = 1, #element do + element[i]:Hide() + end + + self.ComboPoints.isEnabled = false + Path(self, "ComboPointsDisable", "player", ClassPowerType) + end + + if(PlayerClass == "ROGUE" or PlayerClass == "DRUID") then + ClassPowerID = SPELL_POWER_COMBO_POINTS + ClassPowerType = "COMBO_POINTS" + + if(PlayerClass == "DRUID") then + RequirePower = SPELL_POWER_ENERGY + RequireSpell = 768 -- Cat Form + end + end +end + +local function Enable(self, unit) + local element = self.ComboPoints + if element then + element.__owner = self + element.__max = #element + element.ForceUpdate = ForceUpdate + + if(RequirePower) then + self:RegisterEvent("UNIT_DISPLAYPOWER", VisibilityPath, true) -- needs to be unitless for target + end + + element.ComboPointsEnable = ComboPointsEnable + element.ComboPointsDisable = ComboPointsDisable + + for i = 1, #element do + local bar = element[i] + if(bar:IsObjectType("StatusBar")) then + if(not bar:GetStatusBarTexture()) then + bar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + end + + bar:SetMinMaxValues(0, 1) + end + end + + return true + end +end + +local function Disable(self) + if(self.ComboPoints) then + ComboPointsDisable(self) + + self:UnregisterEvent("UNIT_DISPLAYPOWER", VisibilityPath) + self:UnregisterEvent("SPELLS_CHANGED", Visibility) + end +end + +oUF:AddElement("ComboPoints", VisibilityPath, Enable, Disable) diff --git a/libs/oUF_Plugins/oUF_EmptyBar/LICENSE b/libs/oUF_Plugins/oUF_EmptyBar/LICENSE new file mode 100644 index 0000000..cf1ab25 --- /dev/null +++ b/libs/oUF_Plugins/oUF_EmptyBar/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/libs/oUF_Plugins/oUF_EmptyBar/oUF_EmptyBar.lua b/libs/oUF_Plugins/oUF_EmptyBar/oUF_EmptyBar.lua new file mode 100644 index 0000000..ec69b24 --- /dev/null +++ b/libs/oUF_Plugins/oUF_EmptyBar/oUF_EmptyBar.lua @@ -0,0 +1,141 @@ +--[[ +# Element: Empty Bar + +An empty bar to fill space / place tags on. + +## Widget + +Empty - A `StatusBar`. + +## Notes + +A default texture will be applied if the widget is a StatusBar and doesn't have a texture set. + +## Options + +.smoothGradient - 9 color values to be used with the .colorSmooth option (table) +.alpha............................- Transparency (number)[0-1] + +The following options are listed by priority. The first check that returns true decides the color of the bar. + +.colorReaction - Use to color by reaction (string) + 'player' = players only + 'NPC/hostile player' = npcs and hostile players + 'npc' = npc only + 'both' = players and npcs +.colorClass - Use `self.colors.class[class]` to color the bar based on unit class. `class` is defined by the + second return of [UnitClass](http://wowprogramming.com/docs/api/UnitClass.html) (boolean) + +## Sub-Widgets Options + +.multiplier - Used to tint the background based on the main widgets R, G and B values. Defaults to 1 (number)[0-1] + +## Examples + + -- Position and size + local Empty = CreateFrame('StatusBar', nil, self) + Empty:SetHeight(20) + Empty:SetPoint('TOP') + Empty:SetPoint('LEFT') + Empty:SetPoint('RIGHT') + + -- Options + Empty.colorClass = true + Empty.colorReaction = "npc" + + -- Register it with oUF + self.Empty = Empty +--]] + +local _, ns = ... +local oUF = ns.oUF + +local function Update(self, event, unit) + if(not unit or self.unit ~= unit) then return end + local element = self.Empty + + --[[ Callback: Empty:PreUpdate(unit) + Called before the element has been updated. + + * self - the Empty element + * unit - the unit for which the update has been triggered (string) + --]] + if(element.PreUpdate) then + element:PreUpdate(unit) + end + + local r, g, b, t + if element.colorReaction and (element.colorReaction == "both" or element.colorReaction == "npc" and not UnitIsPlayer(unit) or element.colorReaction == "player" and UnitIsPlayer(unit) or element.colorReaction == "NPC/hostile player" and (not UnitIsPlayer(unit) or not UnitIsFriend(unit, "player"))) then + t = self.colors.reaction[UnitReaction(unit, 'player')] + elseif element.colorClass and UnitIsPlayer(unit) then + local _, class = UnitClass(unit) + t = self.colors.class[class] + end + + if(t) then + r, g, b = t[1], t[2], t[3] + end + + if(b) then + element:SetStatusBarColor(r, g, b, element.alpha or 1) + element:SetValue(1) + else + element:SetValue(0) + end + + --[[ Callback: Empty:PostUpdate(unit) + Called after the element has been updated. + + * self - the Empty element + * unit - the unit for which the update has been triggered (string) + --]] + if(element.PostUpdate) then + element:PostUpdate(unit) + end +end + +local function Path(self, event, ...) + --[[ Override: Empty.Override(self, event, unit) + Used to completely override the internal update function. + + * self - the parent object + * event - the event triggering the update (string) + * unit - the unit accompanying the event (string) + --]] + (self.Empty.Override or Update) (self, event, ...); +end + +local function ForceUpdate(element) + Path(element.__owner, 'ForceUpdate', element.__owner.unit) +end + +local function Enable(self, unit) + local element = self.Empty + if(element) then + element.__owner = self + element.ForceUpdate = ForceUpdate + + self:RegisterEvent('UNIT_FACTION', Path) + + if(element:IsObjectType('StatusBar') and not element:GetStatusBarTexture()) then + element:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + end + + element:SetMinMaxValues(0,1) + + element:Show() + + return true + end +end + +local function Disable(self) + local element = self.Empty + if(element) then + element:Hide() + + self:UnregisterEvent('UNIT_FACTION', Path) + end +end + +oUF:AddElement('Empty', Path, Enable, Disable) diff --git a/libs/oUF_Plugins/oUF_Highlight/LICENSE b/libs/oUF_Plugins/oUF_Highlight/LICENSE new file mode 100644 index 0000000..cf1ab25 --- /dev/null +++ b/libs/oUF_Plugins/oUF_Highlight/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/libs/oUF_Plugins/oUF_Highlight/oUF_Highlight.lua b/libs/oUF_Plugins/oUF_Highlight/oUF_Highlight.lua new file mode 100644 index 0000000..dc07e6f --- /dev/null +++ b/libs/oUF_Plugins/oUF_Highlight/oUF_Highlight.lua @@ -0,0 +1,194 @@ +--[[ +# Element: Highlight + +Show a "glowing" texture when certain conditions are met. + +## Widget + +Highlight - A "Texture". + +## Options + +.target - Highlight when this is your current target (boolean) +.mouseover - Highlight when your mouse is over this unit (boolean) +.aggro - Highlight when this unit has aggro (boolean) +.debuff - Highlight when this unit has a debuff (integer) + 1 - off (same as nil) + 2 - Only highlight on debuffs you can dispel + 3 - Highlight on all dispellable debuffs + +#colors +.targetColor - {1, 1, 1} +.mouseoverColor - {1, 1, 1} + +## Notes + +A default texture will be applied if the widget is a Texture and doesn't have a texture set. + +## Examples + + -- Position and size + local Highlight = self:CreateTexture(nil, "OVERLAY") + Highlight:SetAllPoints(self) + + -- Register it with oUF + self.Highlight = Highlight +--]] + +local _, ns = ... +local oUF = ns.oUF + +local playerClass = select(2, UnitClass("player")) +local canCure = {} +local cures = { + ["DRUID"] = {[2782] = {"Curse"}, [2893] = {"Poison"}, [8946] = {"Poison"}}, + ["PRIEST"] = {[528] = {"Disease"}, [552] = {"Disease"}, [527] = {"Magic"}, [988] = {"Magic"}}, + ["PALADIN"] = {[4987] = {"Poison", "Disease", "Magic"}, [1152] = {"Poison", "Disease"}}, + ["SHAMAN"] = {[2870] = {"Disease"}, [526] = {"Poison"}}, + ["MAGE"] = {[475] = {"Curse"}}, +} +cures = cures[playerClass] + +local function Update(self, event) + local element = self.Highlight + local unit = self.unit + if not UnitExists(unit) then return end + + --[[ Callback: Highlight:PreUpdate() + Called before the element has been updated. + + * self - the Highlight element + --]] + if(element.PreUpdate) then + element:PreUpdate() + end + + local hasMouseover = self == GetMouseFocus() + local isTarget = UnitIsUnit("target", unit) + local hasAggro = (UnitThreatSituation(unit) or 0) > 1 + local showOwn, showAll, hasDebuff, highlightReason = element.debuff == 2, element.debuff == 3 + if UnitIsFriend(unit, "player") then + for i=1, 16 do + local name, _, _, auraType = UnitDebuff(unit, i) + if( not name ) then break end + + if( showOwn and canCure[auraType] and UnitCanAssist("player", unit) or (showAll and auraType) ) then + hasDebuff = auraType + break + end + end + end + + local color + if element.debuff and element.debuff ~= 1 and hasDebuff then + color = oUF.colors.debuff[hasDebuff] + highlightReason = "debuff" + elseif element.aggro and hasAggro then + color = oUF.colors.threat[4] + highlightReason = "aggro" + elseif element.target and isTarget then + color = element.targetColor + highlightReason = "target" + elseif element.mouseover and hasMouseover then + color = element.mouseoverColor + highlightReason = "mouseover" + end + + if not color then + element:Hide() + else + element:Show() + element:SetVertexColor(unpack(color)) + end + + --[[ Callback: Highlight:PostUpdate(highlightReason) + Called after the element has been updated. + + * self - the Highlight element + * highlightReason - what type of highlight is shown (nil, "mouseover", "target", "aggro", "debuff") (string) + --]] + if(element.PostUpdate) then + return element:PostUpdate(highlightReason) + end +end + +local function checkCurableSpells(self, event, arg1) + if event == "UNIT_PET" and (arg1 ~= "player" or playerClass ~= "WARLOCK") then return end + table.wipe(canCure) + + if playerClass == "WARLOCK" then + if IsUsableSpell(GetSpellInfo(19505)) then + canCure["Magic"] = true + end + elseif cures then + for spellID, types in pairs(cures) do + if( IsPlayerSpell(spellID) ) then + for _, type in pairs(types) do + canCure[type] = true + end + end + end + else + return + end + Update(self, event, self.unit) +end + +local function Path(self, ...) + --[[ Override: Highlight.Override(self, event, ...) + Used to completely override the internal update function. + + * self - the parent object + * event - the event triggering the update (string) + * ... - the arguments accompanying the event + --]] + return (self.Highlight.Override or Update) (self, ...) +end + +local function ForceUpdate(element) + return Path(element.__owner, "ForceUpdate", element.__owner.unit) +end + +local function Enable(self) + local element = self.Highlight + if(element) then + element.__owner = self + element.ForceUpdate = ForceUpdate + + self:RegisterEvent("UPDATE_MOUSEOVER_UNIT", Path, true) + self:RegisterEvent("UNIT_AURA", Path) + self:RegisterEvent("UNIT_THREAT_SITUATION_UPDATE", Path) + self:RegisterEvent("PLAYER_TARGET_CHANGED", Path, true) + + self:RegisterEvent("LEARNED_SPELL_IN_TAB", checkCurableSpells, true) + self:RegisterEvent("PLAYER_LOGIN", checkCurableSpells, true) + self:RegisterEvent("UNIT_PET", checkCurableSpells, true) + + if(element:IsObjectType("Texture") and not element:GetTexture()) then + element:SetTexture([[Interface\FriendsFrame\UI-FriendsFrame-HighlightBar-Blue]]) + element:SetBlendMode("ADD") + end + + checkCurableSpells(self) + + return true + end +end + +local function Disable(self) + local element = self.Highlight + if(element) then + element:Hide() + + self:UnregisterEvent("UPDATE_MOUSEOVER_UNIT", Path) + self:UnregisterEvent("UNIT_AURA", Path) + self:UnregisterEvent("UNIT_THREAT_SITUATION_UPDATE", Path) + self:UnregisterEvent("PLAYER_TARGET_CHANGED", Path) + + self:UnregisterEvent("LEARNED_SPELL_IN_TAB", checkCurableSpells) + self:UnregisterEvent("PLAYER_LOGIN", checkCurableSpells) + self:UnregisterEvent("UNIT_PET", checkCurableSpells) + end +end + +oUF:AddElement("Highlight", Path, Enable, Disable) \ No newline at end of file diff --git a/libs/oUF_Plugins/oUF_Plugins.xml b/libs/oUF_Plugins/oUF_Plugins.xml new file mode 100644 index 0000000..e9899b0 --- /dev/null +++ b/libs/oUF_Plugins/oUF_Plugins.xml @@ -0,0 +1,21 @@ + +