mirror of
https://github.com/parnic/ice-hud.git
synced 2025-06-16 06:40:13 -05:00
- reduced cpu usage by 33%-50% across the board (and more in some cases) by changing how updates are registered and how often they run. now the 'update period' slider actually matters. it defaults to 0.033 meaning that frames update about 30 times a second instead of every frame - fixed the "always" display mode for cooldown bars to respect alpha settings (ooc/with target/in combat/etc.)
480 lines
13 KiB
Lua
480 lines
13 KiB
Lua
local L = LibStub("AceLocale-3.0"):GetLocale("IceHUD", false)
|
|
--[[
|
|
Name: IceThreat
|
|
Author: Caryna/Turalyon EU (Alliance) (updated for Threat-2.0 by 'acapela' of WoWI and merged into IceHUD by Parnic)
|
|
Description: adds a threat bar to IceHUD
|
|
]]
|
|
|
|
IceThreat = IceCore_CreateClass(IceUnitBar)
|
|
|
|
local IceHUD = _G.IceHUD
|
|
|
|
IceThreat.prototype.color = nil
|
|
IceThreat.aggroBar = nil
|
|
IceThreat.aggroBarMulti = nil
|
|
IceThreat.prototype.scheduledEvent = nil
|
|
|
|
local MAX_NUM_RAID_MEMBERS = 40
|
|
local MAX_NUM_PARTY_MEMBERS = 5
|
|
|
|
-- constructor
|
|
function IceThreat.prototype:init(name, unit)
|
|
if not name or not unit then
|
|
IceThreat.super.prototype.init(self, "Threat", "target")
|
|
else
|
|
IceThreat.super.prototype.init(self, name, unit)
|
|
end
|
|
|
|
self:SetDefaultColor("ThreatLow", 102, 204, 51)
|
|
self:SetDefaultColor("ThreatMedium", 0, 204, 204)
|
|
self:SetDefaultColor("ThreatHigh", 204, 0, 153)
|
|
self:SetDefaultColor("ThreatDanger", 255, 0, 0)
|
|
self:SetDefaultColor("ThreatCustom", 255, 255, 0)
|
|
self:SetDefaultColor("ThreatPullAggro", 255, 0, 0)
|
|
self:SetDefaultColor("ThreatSecondPlace", 255, 255, 0)
|
|
|
|
self.bTreatEmptyAsFull = true
|
|
end
|
|
|
|
-- default settings
|
|
function IceThreat.prototype:GetDefaultSettings()
|
|
local settings = IceThreat.super.prototype.GetDefaultSettings(self)
|
|
settings["side"] = IceCore.Side.Left
|
|
settings["offset"] = 4
|
|
settings["enabled"] = false
|
|
settings["aggroAlpha"] = 0.7
|
|
settings["usesDogTagStrings"] = false
|
|
settings["onlyShowInGroups"] = true
|
|
settings["showScaledThreat"] = false
|
|
settings["displaySecondPlaceThreat"] = true
|
|
settings["secondPlaceThreatAlpha"] = 0.75
|
|
return settings
|
|
end
|
|
|
|
-- options stuff
|
|
function IceThreat.prototype:GetOptions()
|
|
local opts = IceThreat.super.prototype.GetOptions(self)
|
|
|
|
opts["enabled"] = {
|
|
type = "toggle",
|
|
name = L["Enabled"],
|
|
desc = L["Enable/disable module"],
|
|
get = function()
|
|
return self.moduleSettings.enabled
|
|
end,
|
|
set = function(info, value)
|
|
self.moduleSettings.enabled = value
|
|
if (value) then
|
|
self:Enable(true)
|
|
else
|
|
self:Disable()
|
|
end
|
|
end,
|
|
order = 20
|
|
}
|
|
|
|
opts["aggroAlpha"] =
|
|
{
|
|
type = 'range',
|
|
name = L["Aggro Indicator alpha"],
|
|
desc = L["Aggro indicator alpha (0 is disabled)"],
|
|
min = 0,
|
|
max = 1,
|
|
step = 0.1,
|
|
get = function()
|
|
return self.moduleSettings.aggroAlpha
|
|
end,
|
|
set = function(info, value)
|
|
self.moduleSettings.aggroAlpha = value
|
|
self:Redraw()
|
|
end,
|
|
disabled = function()
|
|
return not self.moduleSettings.enabled
|
|
end,
|
|
order = 27.5
|
|
}
|
|
|
|
opts["onlyShowInGroups"] = {
|
|
type = 'toggle',
|
|
name = L["Only show in groups"],
|
|
desc = L["Only show the threat bar if you are in a group or you have an active pet"],
|
|
get = function()
|
|
return self.moduleSettings.onlyShowInGroups
|
|
end,
|
|
set = function(info, v)
|
|
self.moduleSettings.onlyShowInGroups = v
|
|
self:Redraw()
|
|
end,
|
|
disabled = function()
|
|
return not self.moduleSettings.enabled
|
|
end,
|
|
order = 27.6
|
|
}
|
|
|
|
opts["showScaledThreat"] = {
|
|
type = 'toggle',
|
|
name = L["Show scaled threat"],
|
|
desc = L["Whether to show threat in scaled values or raw values. Scaled threat means that you will pull aggro when it hits 100%. Raw threat means you will pull aggro at either 110% (melee) or 130% (ranged). Omen uses raw threat which can cause this mod to disagree with Omen if it is in scaled mode."],
|
|
get = function()
|
|
return self.moduleSettings.showScaledThreat
|
|
end,
|
|
set = function(info, v)
|
|
self.moduleSettings.showScaledThreat = v
|
|
self:Redraw()
|
|
end,
|
|
disabled = function()
|
|
return not self.moduleSettings.enabled
|
|
end,
|
|
order = 27.7
|
|
}
|
|
|
|
opts["displaySecondPlaceThreat"] = {
|
|
type = 'toggle',
|
|
name = L["Show second highest threat"],
|
|
desc = L["When tanking, this toggles whether or not the second-highest threat value found in your party or raid is displayed on top of your actual threat value"],
|
|
width = 'double',
|
|
get = function()
|
|
return self.moduleSettings.displaySecondPlaceThreat
|
|
end,
|
|
set = function(info, v)
|
|
self.moduleSettings.displaySecondPlaceThreat = v
|
|
self:Redraw()
|
|
end,
|
|
disabled = function()
|
|
return not self.moduleSettings.enabled
|
|
end,
|
|
order = 27.8
|
|
}
|
|
|
|
opts["secondPlaceThreatAlpha"] = {
|
|
type = 'range',
|
|
name = L["Second place threat alpha"],
|
|
desc = L["The alpha value for the second-place threat bar to be (this is multiplied by the bar's alpha so it's always proportionate)"],
|
|
get = function()
|
|
return self.moduleSettings.secondPlaceThreatAlpha
|
|
end,
|
|
set = function(info, v)
|
|
self.moduleSettings.secondPlaceThreatAlpha = v
|
|
self:Redraw()
|
|
end,
|
|
disabled = function()
|
|
return not self.moduleSettings.enabled
|
|
end,
|
|
min = 0,
|
|
max = 1,
|
|
step = 0.05,
|
|
order = 27.9
|
|
}
|
|
|
|
return opts
|
|
end
|
|
|
|
-- enable plugin
|
|
function IceThreat.prototype:Enable(core)
|
|
IceThreat.super.prototype.Enable(self, core)
|
|
|
|
self.scheduledEvent = self:ScheduleRepeatingTimer("Update", 0.2)
|
|
|
|
self:Update(self.unit)
|
|
end
|
|
|
|
-- disable plugin
|
|
function IceThreat.prototype:Disable(core)
|
|
IceThreat.super.prototype.Disable(self, core)
|
|
|
|
self:CancelTimer(self.scheduledEvent, true)
|
|
end
|
|
|
|
-- OVERRIDE
|
|
function IceThreat.prototype:CreateFrame()
|
|
IceThreat.super.prototype.CreateFrame(self)
|
|
|
|
self:CreateAggroBar()
|
|
self:CreateSecondThreatBar()
|
|
end
|
|
|
|
-- create the aggro range indicator bar
|
|
function IceThreat.prototype:CreateAggroBar()
|
|
if not (self.aggroBar) then
|
|
self.aggroBar = CreateFrame("Frame", nil, self.frame)
|
|
end
|
|
|
|
local aggroTop = not IceHUD:xor(self.moduleSettings.reverse, self.moduleSettings.inverse)
|
|
|
|
self.aggroBar:SetFrameStrata("BACKGROUND")
|
|
self.aggroBar:SetWidth(self.settings.barWidth + (self.moduleSettings.widthModifier or 0))
|
|
self.aggroBar:SetHeight(self.settings.barHeight)
|
|
self.aggroBar:ClearAllPoints()
|
|
if aggroTop then
|
|
self.aggroBar:SetPoint("TOPLEFT", self.frame, "TOPLEFT")
|
|
else
|
|
self.aggroBar:SetPoint("BOTTOMLEFT", self.frame, "BOTTOMLEFT")
|
|
end
|
|
|
|
if not (self.aggroBar.bar) then
|
|
self.aggroBar.bar = self.aggroBar:CreateTexture(nil, "LOW")
|
|
end
|
|
|
|
self.aggroBar.bar:SetTexture(IceElement.TexturePath .. self:GetMyBarTexture())
|
|
self.aggroBar.bar:SetAllPoints(self.aggroBar)
|
|
|
|
local r, g, b = self:GetColor("ThreatPullAggro")
|
|
if (self.settings.backgroundToggle) then
|
|
r, g, b = self:GetColor("CastCasting")
|
|
end
|
|
self.aggroBar.bar:SetVertexColor(r, g, b, self.moduleSettings.aggroAlpha)
|
|
|
|
if (self.moduleSettings.side == IceCore.Side.Left) then
|
|
self.aggroBar.bar:SetTexCoord(1, 0, 0, 0)
|
|
else
|
|
self.aggroBar.bar:SetTexCoord(0, 1, 0, 0)
|
|
end
|
|
end
|
|
|
|
function IceThreat.prototype:CreateSecondThreatBar()
|
|
if not (self.secondThreatBar) then
|
|
self.secondThreatBar = CreateFrame("Frame", nil, self.frame)
|
|
end
|
|
|
|
self.secondThreatBar:SetFrameStrata("MEDIUM")
|
|
self.secondThreatBar:SetWidth(self.settings.barWidth + (self.moduleSettings.widthModifier or 0))
|
|
self.secondThreatBar:SetHeight(self.settings.barHeight)
|
|
self:SetBarFramePoints(self.secondThreatBar)
|
|
|
|
if not (self.secondThreatBar.bar) then
|
|
self.secondThreatBar.bar = self.secondThreatBar:CreateTexture(nil, "OVERLAY")
|
|
end
|
|
|
|
self.secondThreatBar.bar:SetTexture(IceElement.TexturePath .. self:GetMyBarTexture())
|
|
self.secondThreatBar.bar:SetAllPoints(self.secondThreatBar)
|
|
|
|
local r, g, b = self:GetColor("ThreatSecondPlace")
|
|
self.secondThreatBar.bar:SetVertexColor(r, g, b, self.alpha)
|
|
|
|
if (self.moduleSettings.side == IceCore.Side.Left) then
|
|
self.secondThreatBar.bar:SetTexCoord(1, 0, 0, 0)
|
|
else
|
|
self.secondThreatBar.bar:SetTexCoord(0, 1, 0, 0)
|
|
end
|
|
end
|
|
|
|
-- bar stuff
|
|
function IceThreat.prototype:Update(unit)
|
|
IceThreat.super.prototype.Update(self)
|
|
|
|
if (unit and (unit ~= self.unit)) then
|
|
return
|
|
end
|
|
|
|
if not unit then
|
|
unit = self.unit
|
|
end
|
|
|
|
if self.moduleSettings.onlyShowInGroups and (GetNumPartyMembers() == 0 and not UnitExists("pet")) then
|
|
self:Show(false)
|
|
return
|
|
end
|
|
|
|
if not UnitExists(self.unit) or not UnitCanAttack("player", self.unit) or UnitIsDead(self.unit)
|
|
or UnitIsFriend("player", self.unit) or UnitPlayerControlled(self.unit) then
|
|
self:Show(false)
|
|
return
|
|
else
|
|
self:Show(true)
|
|
end
|
|
|
|
local isTanking, threatState, scaledPercent, rawPercent, threatValue = UnitDetailedThreatSituation("player", self.unit)
|
|
local tankThreat = 0
|
|
local secondHighestThreat = 0
|
|
local rangeMulti = 1.1
|
|
local scaledPercentZeroToOne
|
|
|
|
if not isTanking then
|
|
_, _, _, _, tankThreat = UnitDetailedThreatSituation("targettarget", self.unit) -- highest threat target of target (i.e. the tank)
|
|
elseif self.moduleSettings.displaySecondPlaceThreat then
|
|
secondHighestThreat = self:GetSecondHighestThreat()
|
|
end
|
|
|
|
if threatValue and threatValue < 0 then
|
|
threatValue = threatValue + 410065408 -- the corrected threat while under MI or Fade
|
|
if isTanking then
|
|
tankThreat = threatValue
|
|
end
|
|
|
|
if threatValue and tankThreat then -- Corrects rawPercent and scaledPercent while under MI or Fade
|
|
rawPercent = ((threatValue / tankThreat) * 100)
|
|
|
|
if GetItemInfo(37727) then -- 5 yards for melee range (Ruby Acorn - http://www.wowhead.com/?item=37727)
|
|
rangeMulti = tankThreat * (IsItemInRange(37727, "target") == 1 and 1.1 or 1.3)
|
|
else -- 9 yards compromise
|
|
rangeMulti = tankThreat * (CheckInteractDistance("target", 3) and 1.1 or 1.3)
|
|
end
|
|
scaledPercent = ((threatValue / rangeMulti) * 100)
|
|
end
|
|
end
|
|
|
|
if not self.combat and (scaledPercent == 0 or rawPercent == 0) then
|
|
self:Show(false)
|
|
return
|
|
end
|
|
|
|
if not rawPercent then
|
|
rawPercent = 0
|
|
end
|
|
|
|
if rawPercent < 0 then
|
|
rawPercent = 0
|
|
elseif isTanking then
|
|
rawPercent = 100
|
|
scaledPercent = 100
|
|
end
|
|
|
|
if not threatState or not scaledPercent or not rawPercent then
|
|
scaledPercentZeroToOne = 0
|
|
scaledPercent = 0
|
|
|
|
IceHUD:Debug( "Threat: nil threat on valid target" )
|
|
else
|
|
if self.moduleSettings.showScaledThreat then
|
|
scaledPercentZeroToOne = scaledPercent / 100
|
|
else
|
|
scaledPercentZeroToOne = rawPercent / 100
|
|
end
|
|
|
|
IceHUD:Debug( "isTanking="..(isTanking or "nil").." threatState="..(threatState or "nil").." scaledPercent="..(scaledPercent or "nil").." rawPercent="..(rawPercent or "nil") )
|
|
end
|
|
|
|
-- set percentage text
|
|
self:SetBottomText1( IceHUD:MathRound(self.moduleSettings.showScaledThreat and scaledPercent or rawPercent) .. "%" )
|
|
self:SetBottomText2()
|
|
|
|
if ( isTanking ) then
|
|
rangeMulti = 1
|
|
end
|
|
|
|
-- Parnic: this should probably be switched to use the new api colors for threat...
|
|
-- set bar color
|
|
if( isTanking == 1 ) then
|
|
self.color = "ThreatDanger"
|
|
elseif( scaledPercent < 50 ) then
|
|
self.color = "ThreatLow"
|
|
elseif ( scaledPercent < 80 ) then
|
|
self.color = "ThreatMedium"
|
|
else
|
|
self.color = "ThreatHigh"
|
|
end
|
|
|
|
-- set the bar value
|
|
self:UpdateBar( scaledPercentZeroToOne, self.color )
|
|
|
|
-- do the aggro indicator bar stuff, but only if it has changed
|
|
--if ( self.aggroBarMulti ~= rangeMulti ) then
|
|
self.aggroBarMulti = rangeMulti
|
|
|
|
local pos = IceHUD:Clamp(1 - (1 / rangeMulti), 0, 1)
|
|
local fromTop = not IceHUD:xor(self.moduleSettings.reverse, self.moduleSettings.inverse)
|
|
|
|
local min_y = 0
|
|
local max_y = pos
|
|
if not fromTop then
|
|
min_y = 1-pos
|
|
max_y = 1
|
|
end
|
|
|
|
if ( self.moduleSettings.side == IceCore.Side.Left ) then
|
|
self.aggroBar.bar:SetTexCoord(1, 0, min_y, max_y)
|
|
else
|
|
self.aggroBar.bar:SetTexCoord(0, 1, min_y, max_y)
|
|
end
|
|
|
|
if pos == 0 then
|
|
self.aggroBar.bar:Hide()
|
|
else
|
|
self.aggroBar.bar:Show()
|
|
end
|
|
|
|
self.aggroBar:SetHeight(self.settings.barHeight * pos)
|
|
--end
|
|
|
|
self:UpdateAlpha()
|
|
self:UpdateSecondHighestThreatBar(secondHighestThreat, threatValue)
|
|
end
|
|
|
|
function IceThreat.prototype:UpdateSecondHighestThreatBar(secondHighestThreat, threatValue)
|
|
if secondHighestThreat <= 0 or not threatValue or threatValue == 0 then
|
|
self.secondThreatBar:Hide()
|
|
else
|
|
local pos = IceHUD:Clamp(secondHighestThreat / threatValue, 0, 1)
|
|
|
|
if self.moduleSettings.reverse then
|
|
pos = 1-pos
|
|
end
|
|
|
|
if (self.moduleSettings.reverse) then
|
|
pos = 1 - pos
|
|
end
|
|
if (self.moduleSettings.inverse) then
|
|
min_y = 0
|
|
max_y = pos
|
|
else
|
|
min_y = 1-pos
|
|
max_y = 1
|
|
end
|
|
|
|
if ( self.moduleSettings.side == IceCore.Side.Left ) then
|
|
self.secondThreatBar.bar:SetTexCoord(1, 0, min_y, max_y)
|
|
else
|
|
self.secondThreatBar.bar:SetTexCoord(0, 1, min_y, max_y)
|
|
end
|
|
|
|
local r, g, b = self:GetColor("ThreatSecondPlace")
|
|
self.secondThreatBar.bar:SetVertexColor(r, g, b, self.alpha * self.moduleSettings.secondPlaceThreatAlpha)
|
|
|
|
self.secondThreatBar:SetHeight(pos * self.settings.barHeight)
|
|
self.secondThreatBar:Show()
|
|
end
|
|
end
|
|
|
|
function IceThreat.prototype:GetSecondHighestThreat()
|
|
local secondHighestThreat = 0
|
|
local i = 1
|
|
local numFound = 0
|
|
local numMembers = 0
|
|
|
|
if UnitInRaid("player") then
|
|
numMembers = GetNumRaidMembers()
|
|
|
|
while numFound < numMembers and i <= MAX_NUM_RAID_MEMBERS do
|
|
if UnitExists("raid"..i) and not UnitIsUnit("player", "raid"..i) then
|
|
numFound = numFound + 1
|
|
local _, _, _, _, temp = UnitDetailedThreatSituation("raid"..i, self.unit)
|
|
if temp ~= nil and temp > secondHighestThreat then
|
|
secondHighestThreat = temp
|
|
end
|
|
end
|
|
|
|
i = i + 1
|
|
end
|
|
elseif UnitInParty("player") then
|
|
numMembers = GetNumPartyMembers()
|
|
|
|
while numFound < numMembers and i <= MAX_NUM_PARTY_MEMBERS do
|
|
if UnitExists("party"..i) and not UnitIsUnit("player", "party"..i) then
|
|
numFound = numFound + 1
|
|
local _, _, _, _, temp = UnitDetailedThreatSituation("party"..i, self.unit)
|
|
if temp ~= nil and temp > secondHighestThreat then
|
|
secondHighestThreat = temp
|
|
end
|
|
end
|
|
|
|
i = i + 1
|
|
end
|
|
end
|
|
|
|
return secondHighestThreat
|
|
end
|
|
|
|
|
|
-- Load us up
|
|
IceHUD.IceThreat = IceThreat:new()
|