Files
ice-hud/modules/Threat.lua
Parnic e003fab854 - removed most of the rest of the garbage that was being generated during combat or when changing targets
- 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.)
2010-10-25 02:05:58 +00:00

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()