Files
ice-hud/modules/PlayerHealth.lua

1424 lines
44 KiB
Lua

local L = LibStub("AceLocale-3.0"):GetLocale("IceHUD", false)
local PlayerHealth = IceCore_CreateClass(IceUnitBar)
local IceHUD = _G.IceHUD
PlayerHealth.prototype.resting = nil
PlayerHealth.prototype.pendingBlizzardPartyHide = false
local configMode = false
local HealComm
local incomingHealAmt = 0
-- Constructor --
function PlayerHealth.prototype:init()
PlayerHealth.super.prototype.init(self, "PlayerHealth", "player")
self:SetDefaultColor("PlayerHealth", 37, 164, 30)
self:SetDefaultColor("PlayerHealthHealAmount", 37, 164, 30)
end
function PlayerHealth.prototype:GetDefaultSettings()
local settings = PlayerHealth.super.prototype.GetDefaultSettings(self)
settings["side"] = IceCore.Side.Left
settings["offset"] = 1
settings["hideBlizz"] = false
settings["hideBlizzParty"] = false
settings["upperText"] = "[PercentHP:Round]"
settings["lowerText"] = "[FractionalHP:HPColor:Bracket]"
settings["allowMouseInteraction"] = false
settings["allowMouseInteractionCombat"] = false
settings["healAlpha"] = 0.6
settings["lockIconAlpha"] = false
settings["showIncomingHeals"] = true
settings["showStatusIcon"] = true
settings["statusIconOffset"] = {x=110, y=0}
settings["statusIconScale"] = 1
settings["showStatusCombat"] = true
settings["showStatusResting"] = true
settings["showLeaderIcon"] = true
settings["leaderIconOffset"] = {x=135, y=15}
settings["leaderIconScale"] = 0.9
settings["showLootMasterIcon"] = true
settings["lootMasterIconOffset"] = {x=100, y=-20}
settings["lootMasterIconScale"] = 0.9
settings["showPvPIcon"] = true
settings["PvPIconOffset"] = {x=95, y=-40}
settings["PvPIconScale"] = 0.9
settings["showPartyRoleIcon"] = true
settings["PartyRoleIconOffset"] = {x=90, y=-59}
settings["PartyRoleIconScale"] = 0.9
return settings
end
function PlayerHealth.prototype:Enable(core)
PlayerHealth.super.prototype.Enable(self, core)
self:RegisterEvent("UNIT_HEALTH", "UpdateEvent")
self:RegisterEvent("UNIT_MAXHEALTH", "UpdateEvent")
self:RegisterEvent("PLAYER_ENTERING_WORLD", "EnteringWorld")
self:RegisterEvent("PLAYER_UPDATE_RESTING", "Resting")
self:RegisterEvent("PLAYER_REGEN_ENABLED", "CheckCombat")
self:RegisterEvent("PLAYER_REGEN_DISABLED", "CheckCombat")
self:RegisterEvent("PARTY_LEADER_CHANGED", "CheckLeader")
if IceHUD.WowVer >= 50000 then
self:RegisterEvent("GROUP_ROSTER_UPDATE", "CheckLeader")
else
self:RegisterEvent("PARTY_MEMBERS_CHANGED", "CheckLeader")
end
self:RegisterEvent("LFG_PROPOSAL_UPDATE", "CheckPartyRole")
self:RegisterEvent("LFG_PROPOSAL_FAILED", "CheckPartyRole")
self:RegisterEvent("LFG_ROLE_UPDATE", "CheckPartyRole")
--self:RegisterEvent("PARTY_MEMBERS_CHANGED", "CheckPartyFrameStatus")
self:RegisterEvent("PARTY_LOOT_METHOD_CHANGED", "CheckLootMaster")
self:RegisterEvent("UPDATE_FACTION", "CheckPvP")
self:RegisterEvent("PLAYER_FLAGS_CHANGED", "CheckPvP")
self:RegisterEvent("UNIT_FACTION", "CheckPvP")
self:RegisterEvent("UNIT_ENTERED_VEHICLE", "EnteringVehicle")
self:RegisterEvent("UNIT_EXITED_VEHICLE", "ExitingVehicle")
if IceHUD.WowVer < 40000 then
HealComm = LibStub("LibHealComm-4.0", true)
if HealComm then
HealComm.RegisterCallback(self, "HealComm_HealStarted", function(event, casterGUID, spellID, spellType, endTime, ...) self:HealComm_HealEvent(event, casterGUID, spellID, spellType, endTime, ...) end)
HealComm.RegisterCallback(self, "HealComm_HealUpdated", function(event, casterGUID, spellID, spellType, endTime, ...) self:HealComm_HealEvent(event, casterGUID, spellID, spellType, endTime, ...) end)
HealComm.RegisterCallback(self, "HealComm_HealDelayed", function(event, casterGUID, spellID, spellType, endTime, ...) self:HealComm_HealEvent(event, casterGUID, spellID, spellType, endTime, ...) end)
HealComm.RegisterCallback(self, "HealComm_HealStopped", function(event, casterGUID, spellID, spellType, interrupted, ...) self:HealComm_HealEvent(event, casterGUID, spellID, spellType, interrupted, ...) end)
HealComm.RegisterCallback(self, "HealComm_ModifierChanged", function(event, guid) self:HealComm_ModifierChanged(event, guid) end)
end
else
self:RegisterEvent("UNIT_HEAL_PREDICTION", "IncomingHealPrediction")
end
if (self.moduleSettings.hideBlizz) then
self:HideBlizz()
end
if (self.moduleSettings.hideBlizzParty) then
self:HideBlizzardParty()
end
self:Resting()
--self:Update(self.unit)
end
function PlayerHealth.prototype:Disable(core)
PlayerHealth.super.prototype.Disable(self, core)
if self.moduleSettings.hideBlizz then
self:ShowBlizz()
end
end
function PlayerHealth.prototype:HealComm_HealEvent(event, casterGUID, spellID, spellType, endTime, ...)
local bFoundMe = false
for i=1, select("#", ...) do
if select(i, ...) == UnitGUID("player") then
bFoundMe = true
break
end
end
if not bFoundMe then
return
end
incomingHealAmt = HealComm:GetHealAmount(UnitGUID("player"), HealComm.ALL_HEALS)
if incomingHealAmt == nil then
incomingHealAmt = 0
end
self:Update()
end
function PlayerHealth.prototype:HealComm_ModifierChanged(event, guid)
if guid == UnitGUID("player") then
incomingHealAmt = incomingHealAmt * HealComm:GetHealModifier(guid)
self:Update()
end
end
function PlayerHealth.prototype:IncomingHealPrediction(event, unit)
if IceHUD.WowVer >= 40000 then
if unit and unit ~= self.unit then
return
end
incomingHealAmt = UnitGetIncomingHeals(self.unit)
self:Update()
end
end
-- OVERRIDE
function PlayerHealth.prototype:GetOptions()
local opts = PlayerHealth.super.prototype.GetOptions(self)
opts["classColor"] = {
type = "toggle",
name = L["Class color bar"],
desc = L["Use class color as the bar color instead of default color"],
get = function()
return self.moduleSettings.classColor
end,
set = function(info, value)
self.moduleSettings.classColor = value
self:Update(self.unit)
end,
disabled = function()
return not self.moduleSettings.enabled
end,
order = 40
}
opts["hideBlizz"] = {
type = "toggle",
name = L["Hide Blizzard Frame"],
desc = L["Hides Blizzard Player frame and disables all events related to it"],
get = function()
return self.moduleSettings.hideBlizz
end,
set = function(info, value)
self.moduleSettings.hideBlizz = value
if (value) then
self:HideBlizz()
else
self:ShowBlizz()
end
end,
disabled = function()
return not self.moduleSettings.enabled
end,
order = 41
}
opts["hideBlizzParty"] = {
type = "toggle",
name = L["Hide Blizzard Party"],
desc = L["Hides Blizzard's default party frame and disables all events related to them"],
get = function()
return self.moduleSettings.hideBlizzParty
end,
set = function(info, value)
self.moduleSettings.hideBlizzParty = value
if (value) then
self:HideBlizzardParty()
else
self:ShowBlizzardParty()
end
end,
disabled = function()
return not self.moduleSettings.enabled
end,
order = 41.1
}
opts["scaleHealthColor"] = {
type = "toggle",
name = L["Color bar by health %"],
desc = L["Colors the health bar from MaxHealthColor to MinHealthColor based on current health %"],
get = function()
return self.moduleSettings.scaleHealthColor
end,
set = function(info, value)
self.moduleSettings.scaleHealthColor = value
self:Redraw()
end,
disabled = function()
return not self.moduleSettings.enabled
end,
order = 42
}
opts["allowClickTarget"] = {
type = 'toggle',
name = L["Allow click-targeting"],
desc = L["Whether or not to allow click targeting/casting and the player drop-down menu for this bar (Note: does not work properly with HiBar, have to click near the base of the bar)"],
get = function()
return self.moduleSettings.allowMouseInteraction
end,
set = function(info, v)
self.moduleSettings.allowMouseInteraction = v
self:CreateBackground(true)
end,
disabled = function()
return not self.moduleSettings.enabled
end,
order = 43
}
opts["allowClickTargetCombat"] = {
type = 'toggle',
name = L["Allow click-targeting in combat"],
desc = L["Whether or not to allow click targeting/casting and the player drop-down menu for this bar while the player is in combat (Note: does not work properly with HiBar, have to click near the base of the bar)"],
width = 'double',
get = function()
return self.moduleSettings.allowMouseInteractionCombat
end,
set = function(info, v)
self.moduleSettings.allowMouseInteractionCombat = v
self:CreateBackground(true)
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.allowMouseInteraction
end,
order = 43.5
}
opts["showIncomingHeals"] =
{
type = 'toggle',
name = L["Show incoming heals"],
desc = L["Whether or not to show incoming heals as a lighter-colored bar on top of your current health (requires LibHealComm-4.0 or official patch 4.0)"],
get = function()
return self.moduleSettings.showIncomingHeals
end,
set = function(info, v)
if not v then
self.healFrame.bar:Hide()
else
self.healFrame.bar:Show()
end
self.moduleSettings.showIncomingHeals = v
incomingHealAmt = 0
self:Update()
end,
disabled = function()
return not (self.moduleSettings.enabled and (IceHUD.WowVer >= 40000 or HealComm))
end,
order = 43.6
}
opts["healAlpha"] =
{
type = "range",
name = L["Incoming heal bar alpha"],
desc = L["What alpha value to use for the bar that displays how much health you'll have after an incoming heal (This gets multiplied by the bar's current alpha to stay in line with the bar on top of it)"],
min = 0,
max = 100,
step = 5,
get = function()
return self.moduleSettings.healAlpha * 100
end,
set = function(info, v)
self.moduleSettings.healAlpha = v / 100.0
self:Redraw()
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showIncomingHeals
end,
order = 43.7
}
opts["iconSettings"] =
{
type = 'group',
name = "|c"..self.configColor..L["Icon Settings"].."|r",
desc = L["Settings related to icons"],
args = {
iconConfigMode = {
type = "toggle",
name = L["Icon config mode"],
desc = L["With this enabled, all icons draw so you can configure their placement\n\nNote: the combat and status icons are actually the same texture so you'll only see combat in config mode (unless you're already resting)"],
get = function()
return configMode
end,
set = function(info, v)
configMode = v
self:EnteringWorld()
end,
disabled = function()
return not self.moduleSettings.enabled
end,
order = 5
},
lockIconAlpha = {
type = "toggle",
name = L["Lock all icons to 100% alpha"],
desc = L["With this enabled, all icons will be 100% visible regardless of the alpha settings for this bar."],
get = function()
return self.moduleSettings.lockIconAlpha
end,
set = function(info, v)
self.moduleSettings.lockIconAlpha = v
self:Redraw()
end,
disabled = function()
return not self.moduleSettings.enabled
end,
order = 6
},
headerStatusIcon = {
type = 'header',
name = L["Status icon"],
order = 9.9
},
statusIcon = {
type = "toggle",
name = L["Show status icon"],
desc = L["Whether or not to show the status icon (resting/combat) above this bar\n\nNote: You can configure resting/combat separately below, but disabling both resting and combat is the same as disabling the icon altogether"],
get = function()
return self.moduleSettings.showStatusIcon
end,
set = function(info, value)
self.moduleSettings.showStatusIcon = value
self:Resting()
self:CheckCombat()
end,
disabled = function()
return not self.moduleSettings.enabled
end,
order = 10
},
showStatusCombat = {
type = "toggle",
name = L["Show combat status"],
desc = L["Whether or not to show the combat status portion of the status icon (for example, if you only care when you're resting, not when you're in combat)"],
get = function()
return self.moduleSettings.showStatusCombat
end,
set = function(info, value)
self.moduleSettings.showStatusCombat = value
self:Resting()
self:CheckCombat()
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showStatusIcon
end,
order = 10.1
},
showStatusResting = {
type = "toggle",
name = L["Show resting status"],
desc = L["Whether or not to show the resting status portion of the status icon (for example, if you only care when you're in combat, but not when you're resting)"],
get = function()
return self.moduleSettings.showStatusResting
end,
set = function(info, value)
self.moduleSettings.showStatusResting = value
self:Resting()
self:CheckCombat()
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showStatusIcon
end,
order = 10.2
},
statusIconOffsetX = {
type = "range",
name = L["Status Icon Horizontal Offset"],
desc = L["How much to offset the status icon (resting/combat) from the bar horizontally"],
min = 0,
max = 250,
step = 1,
get = function()
return self.moduleSettings.statusIconOffset['x']
end,
set = function(info, v)
self.moduleSettings.statusIconOffset['x'] = v
self:SetTexLoc(self.frame.statusIcon, self.moduleSettings.statusIconOffset['x'], self.moduleSettings.statusIconOffset['y'])
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showStatusIcon
end,
order = 11
},
statusIconOffsetY = {
type = "range",
name = L["Status Icon Vertical Offset"],
desc = L["How much to offset the status icon (resting/combat) from the bar vertically"],
min = -300,
max = 50,
step = 1,
get = function()
return self.moduleSettings.statusIconOffset['y']
end,
set = function(info, v)
self.moduleSettings.statusIconOffset['y'] = v
self:SetTexLoc(self.frame.statusIcon, self.moduleSettings.statusIconOffset['x'], self.moduleSettings.statusIconOffset['y'])
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showStatusIcon
end,
order = 12
},
statusIconScale = {
type = "range",
name = L["Status Icon Scale"],
desc = L["How much to scale the status icon"],
min = 0.05,
max = 2,
step = 0.05,
get = function()
return self.moduleSettings.statusIconScale
end,
set = function(info, v)
self.moduleSettings.statusIconScale = v
self:SetTexScale(self.frame.statusIcon, 20, 20, v)
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showStatusIcon
end,
order = 13
},
headerLeaderIcon = {
type = 'header',
name = L["Leader icon"],
order = 19.9
},
leaderIcon = {
type = "toggle",
name = L["Show leader icon"],
desc = L["Whether or not to show the party leader icon above this bar"],
get = function()
return self.moduleSettings.showLeaderIcon
end,
set = function(info, value)
self.moduleSettings.showLeaderIcon = value
self:CheckLeader()
end,
disabled = function()
return not self.moduleSettings.enabled
end,
order = 20
},
leaderIconOffsetX = {
type = "range",
name = L["Leader Icon Horizontal Offset"],
desc = L["How much to offset the leader icon from the bar horizontally"],
min = 0,
max = 250,
step = 1,
get = function()
return self.moduleSettings.leaderIconOffset['x']
end,
set = function(info, v)
self.moduleSettings.leaderIconOffset['x'] = v
self:SetTexLoc(self.frame.leaderIcon, self.moduleSettings.leaderIconOffset['x'], self.moduleSettings.leaderIconOffset['y'])
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showLeaderIcon
end,
order = 21
},
leaderIconOffsetY = {
type = "range",
name = L["Leader Icon Vertical Offset"],
desc = L["How much to offset the leader icon from the bar vertically"],
min = -300,
max = 50,
step = 1,
get = function()
return self.moduleSettings.leaderIconOffset['y']
end,
set = function(info, v)
self.moduleSettings.leaderIconOffset['y'] = v
self:SetTexLoc(self.frame.leaderIcon, self.moduleSettings.leaderIconOffset['x'], self.moduleSettings.leaderIconOffset['y'])
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showLeaderIcon
end,
order = 22
},
leaderIconScale = {
type = "range",
name = L["Leader Icon Scale"],
desc = L["How much to scale the leader icon"],
min = 0.05,
max = 2,
step = 0.05,
get = function()
return self.moduleSettings.leaderIconScale
end,
set = function(info, v)
self.moduleSettings.leaderIconScale = v
self:SetTexScale(self.frame.leaderIcon, 20, 20, v)
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showLeaderIcon
end,
order = 23
},
headerLootMasterIcon = {
type = 'header',
name = L["Loot Master icon"],
order = 29.9
},
lootMasterIcon = {
type = "toggle",
name = L["Show loot master icon"],
desc = L["Whether or not to show the loot master icon"],
get = function()
return self.moduleSettings.showLootMasterIcon
end,
set = function(info, value)
self.moduleSettings.showLootMasterIcon = value
self:CheckLootMaster()
end,
disabled = function()
return not self.moduleSettings.enabled
end,
order = 30
},
lootMasterIconOffsetX = {
type = "range",
name = L["Loot Master Icon Horizontal Offset"],
desc = L["How much to offset the loot master icon from the bar horizontally"],
min = 0,
max = 250,
step = 1,
get = function()
return self.moduleSettings.lootMasterIconOffset['x']
end,
set = function(info, v)
self.moduleSettings.lootMasterIconOffset['x'] = v
self:SetTexLoc(self.frame.lootMasterIcon, self.moduleSettings.lootMasterIconOffset['x'], self.moduleSettings.lootMasterIconOffset['y'])
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showLootMasterIcon
end,
order = 31
},
lootMasterIconOffsetY = {
type = "range",
name = L["Loot Master Icon Vertical Offset"],
desc = L["How much to offset the loot master icon from the bar vertically"],
min = -300,
max = 50,
step = 1,
get = function()
return self.moduleSettings.lootMasterIconOffset['y']
end,
set = function(info, v)
self.moduleSettings.lootMasterIconOffset['y'] = v
self:SetTexLoc(self.frame.lootMasterIcon, self.moduleSettings.lootMasterIconOffset['x'], self.moduleSettings.lootMasterIconOffset['y'])
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showLootMasterIcon
end,
order = 32
},
lootMasterIconScale = {
type = "range",
name = L["Loot Master Icon Scale"],
desc = L["How much to scale the loot master icon"],
min = 0.05,
max = 2,
step = 0.05,
get = function()
return self.moduleSettings.lootMasterIconScale
end,
set = function(info, v)
self.moduleSettings.lootMasterIconScale = v
self:SetTexScale(self.frame.lootMasterIcon, 20, 20, v)
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showLootMasterIcon
end,
order = 33
},
headerPvPIcon = {
type = 'header',
name = L["PvP icon"],
order = 39.9
},
PvPIcon = {
type = "toggle",
name = L["Show PvP icon"],
desc = L["Whether or not to show the PvP icon"],
get = function()
return self.moduleSettings.showPvPIcon
end,
set = function(info, value)
self.moduleSettings.showPvPIcon = value
self:CheckPvP()
end,
disabled = function()
return not self.moduleSettings.enabled
end,
order = 40
},
PvPIconOffsetX = {
type = "range",
name = L["PvP Icon Horizontal Offset"],
desc = L["How much to offset the PvP icon from the bar horizontally"],
min = 0,
max = 250,
step = 1,
get = function()
return self.moduleSettings.PvPIconOffset['x']
end,
set = function(info, v)
self.moduleSettings.PvPIconOffset['x'] = v
self:SetTexLoc(self.frame.PvPIcon, self.moduleSettings.PvPIconOffset['x'], self.moduleSettings.PvPIconOffset['y'])
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showPvPIcon
end,
order = 41
},
PvPIconOffsetY = {
type = "range",
name = L["PvP Icon Vertical Offset"],
desc = L["How much to offset the PvP icon from the bar vertically"],
min = -300,
max = 50,
step = 1,
get = function()
return self.moduleSettings.PvPIconOffset['y']
end,
set = function(info, v)
self.moduleSettings.PvPIconOffset['y'] = v
self:SetTexLoc(self.frame.PvPIcon, self.moduleSettings.PvPIconOffset['x'], self.moduleSettings.PvPIconOffset['y'])
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showPvPIcon
end,
order = 42
},
PvPIconScale = {
type = "range",
name = L["PvP Icon Scale"],
desc = L["How much to scale the PvP icon"],
min = 0.05,
max = 2,
step = 0.05,
get = function()
return self.moduleSettings.PvPIconScale
end,
set = function(info, v)
self.moduleSettings.PvPIconScale = v
self:SetTexScale(self.frame.PvPIcon, 20, 20, v)
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showPvPIcon
end,
order = 43
},
headerPartyRoleIcon = {
type = 'header',
name = L["Party Role icon"],
order = 49.9
},
PartyRoleIcon = {
type = "toggle",
name = L["Show Party Role icon"],
desc = L["Whether or not to show the Party Role icon"],
get = function()
return self.moduleSettings.showPartyRoleIcon
end,
set = function(info, value)
self.moduleSettings.showPartyRoleIcon = value
self:CheckPartyRole()
end,
disabled = function()
return not self.moduleSettings.enabled
end,
order = 50
},
PartyRoleIconOffsetX = {
type = "range",
name = L["Party Role Icon Horizontal Offset"],
desc = L["How much to offset the Party Role icon from the bar horizontally"],
min = 0,
max = 250,
step = 1,
get = function()
return self.moduleSettings.PartyRoleIconOffset['x']
end,
set = function(info, v)
self.moduleSettings.PartyRoleIconOffset['x'] = v
self:SetTexLoc(self.frame.PartyRoleIcon, self.moduleSettings.PartyRoleIconOffset['x'], self.moduleSettings.PartyRoleIconOffset['y'])
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showPartyRoleIcon
end,
order = 51
},
PartyRoleIconOffsetY = {
type = "range",
name = L["Party Role Icon Vertical Offset"],
desc = L["How much to offset the Party Role icon from the bar vertically"],
min = -300,
max = 50,
step = 1,
get = function()
return self.moduleSettings.PartyRoleIconOffset['y']
end,
set = function(info, v)
self.moduleSettings.PartyRoleIconOffset['y'] = v
self:SetTexLoc(self.frame.PartyRoleIcon, self.moduleSettings.PartyRoleIconOffset['x'], self.moduleSettings.PartyRoleIconOffset['y'])
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showPartyRoleIcon
end,
order = 52
},
PartyRoleIconScale = {
type = "range",
name = L["Party Role Icon Scale"],
desc = L["How much to scale the Party Role icon"],
min = 0.05,
max = 2,
step = 0.05,
get = function()
return self.moduleSettings.PartyRoleIconScale
end,
set = function(info, v)
self.moduleSettings.PartyRoleIconScale = v
self:SetTexScale(self.frame.PartyRoleIcon, 20, 20, v)
end,
disabled = function()
return not self.moduleSettings.enabled or not self.moduleSettings.showPartyRoleIcon
end,
order = 53
}
}
}
return opts
end
function PlayerHealth.prototype:EnteringVehicle(event, unit, arg2)
if (self.unit == "player" and IceHUD:ShouldSwapToVehicle(unit, arg2)) then
self.unit = "vehicle"
self:RegisterFontStrings()
self:Update(self.unit)
end
end
function PlayerHealth.prototype:ExitingVehicle(event, unit)
if (unit == "player" and self.unit == "vehicle") then
self.unit = "player"
self:RegisterFontStrings()
self:Update(self.unit)
end
end
function PlayerHealth.prototype:CreateFrame()
PlayerHealth.super.prototype.CreateFrame(self)
self:CreateHealBar()
end
function PlayerHealth.prototype:CreateBackground(redraw)
PlayerHealth.super.prototype.CreateBackground(self)
if not self.frame.button then
self.frame.button = CreateFrame("Button", "IceHUD_PlayerClickFrame", self.frame, "SecureUnitButtonTemplate")
end
self.frame.button:ClearAllPoints()
-- Parnic - kinda hacky, but in order to fit this region to multiple types of bars, we need to do this...
-- would be nice to define this somewhere in data, but for now...here we are
if self:GetMyBarTexture() == "HiBar" then
self.frame.button:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", 0, 0)
self.frame.button:SetPoint("BOTTOMLEFT", self.frame, "BOTTOMRIGHT", -1 * self.frame:GetWidth(), 0)
elseif self:GetMyBarTexture() == "ArcHUD" then
if self.moduleSettings.side == IceCore.Side.Left then
self.frame.button:SetPoint("TOPLEFT", self.frame, "TOPLEFT")
self.frame.button:SetPoint("BOTTOMRIGHT", self.frame, "BOTTOMLEFT", self.frame:GetWidth() / 3, 0)
else
self.frame.button:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT")
self.frame.button:SetPoint("BOTTOMLEFT", self.frame, "BOTTOMRIGHT", -1 * self.frame:GetWidth() / 3, 0)
end
else
if self.moduleSettings.side == IceCore.Side.Left then
self.frame.button:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", -6, 0)
self.frame.button:SetPoint("BOTTOMLEFT", self.frame, "BOTTOMRIGHT", -1 * self.frame:GetWidth() / 3, 0)
else
self.frame.button:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 6, 0)
self.frame.button:SetPoint("BOTTOMRIGHT", self.frame, "BOTTOMRIGHT", -1 * self.frame:GetWidth() / 1.5, 0)
end
end
if not self.frame.button.menu then
self.frame.button.menu = function(this, unit)
IceHUD.DropdownUnit = unit
ToggleDropDownMenu(1, nil, IceHUD_UnitFrame_DropDown, "cursor")
end
end
self:EnableClickTargeting(self.moduleSettings.allowMouseInteraction)
end
function PlayerHealth.prototype:CreateHealBar()
self.healFrame = self:BarFactory(self.healFrame, "LOW","BACKGROUND")
self.healFrame.bar:SetVertexColor(self:GetColor("PlayerHealthHealAmount", self.alpha * self.moduleSettings.healAlpha))
self:UpdateBar(1, "undef")
if not self.moduleSettings.showIncomingHeals or (IceHUD.WowVer < 40000 and not HealComm) then
self.healFrame.bar:Hide()
end
end
function PlayerHealth.prototype:EnableClickTargeting(bEnable)
if bEnable then
self.frame.button:EnableMouse(true)
self.frame.button:RegisterForClicks("AnyUp")
self.frame.button:SetAttribute("type1", "target")
self.frame.button:SetAttribute("type2", "menu")
self.frame.button:SetAttribute("unit", self.unit)
-- set up click casting
ClickCastFrames = ClickCastFrames or {}
ClickCastFrames[self.frame.button] = true
-- Parnic - debug code for showing the clickable region on this bar
-- self.frame.button:SetBackdrop({bgFile = "Interface/Tooltips/UI-Tooltip-Background",
-- edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
-- tile = false,
-- insets = { left = 0, right = 0, top = 0, bottom = 0 }})
-- self.frame.button:SetBackdropColor(0,0,0,1)
else
self.frame.button:EnableMouse(false)
self.frame.button:RegisterForClicks()
self.frame.button:SetAttribute("type1")
self.frame.button:SetAttribute("type2")
self.frame.button:SetAttribute("unit")
-- set up click casting
--ClickCastFrames = ClickCastFrames or {}
--ClickCastFrames[self.frame.button] = false
end
end
function PlayerHealth.prototype:EnteringWorld()
self:CheckVehicle()
self:CheckCombat()
self:CheckLeader()
self:CheckPartyRole()
self:CheckPvP()
-- Parnic - moved :Resting to the end because it calls Update which sets alpha on everything
self:Resting()
end
function PlayerHealth.prototype:CheckVehicle()
if UnitHasVehicleUI("player") then
self:EnteringVehicle(nil, "player", true)
else
self:ExitingVehicle(nil, "player")
end
end
function PlayerHealth.prototype:Resting()
self.resting = IsResting()
-- moved icon logic above :Update so that it will trigger the alpha settings properly
if (self.resting) then
if self.moduleSettings.showStatusIcon and self.moduleSettings.showStatusResting then
if not self.frame.statusIcon then
self.frame.statusIcon = self:CreateTexCoord(self.frame.statusIcon, "Interface\\CharacterFrame\\UI-StateIcon", 20, 20,
self.moduleSettings.statusIconScale, 0.0625, 0.4475, 0.0625, 0.4375)
self:SetTexLoc(self.frame.statusIcon, self.moduleSettings.statusIconOffset['x'], self.moduleSettings.statusIconOffset['y'])
self:SetIconAlpha()
else
self.frame.statusIcon:SetTexCoord(0.0625, 0.4475, 0.0625, 0.4375)
end
elseif (not self.moduleSettings.showStatusIcon or not self.moduleSettings.showStatusResting) and self.frame.statusIcon and not self.combat then
self.frame.statusIcon = self:DestroyTexFrame(self.frame.statusIcon)
end
else
if not self.combat and not configMode and self.frame.statusIcon then
self.frame.statusIcon = self:DestroyTexFrame(self.frame.statusIcon)
end
end
self:Update(self.unit)
end
function PlayerHealth.prototype:CheckCombat()
local preCombatValue = self.combat
PlayerHealth.super.prototype.CheckCombat(self)
local postCombatValue = self.combat
if preCombatValue ~= postCombatValue then
if postCombatValue then
self:InCombat()
else
self:OutCombat()
end
end
if self.combat then
if self.moduleSettings.allowMouseInteraction and not self.moduleSettings.allowMouseInteractionCombat then
self:EnableClickTargeting(false)
end
else
if self.moduleSettings.allowMouseInteraction and not self.moduleSettings.allowMouseInteractionCombat then
self:EnableClickTargeting(true)
end
end
if self.combat or configMode then
if (configMode or (self.moduleSettings.showStatusIcon and self.moduleSettings.showStatusCombat)) then
if not self.frame.statusIcon then
self.frame.statusIcon = self:CreateTexCoord(self.frame.statusIcon, "Interface\\CharacterFrame\\UI-StateIcon", 20, 20,
self.moduleSettings.statusIconScale, 0.5625, 0.9375, 0.0625, 0.4375)
self:SetTexLoc(self.frame.statusIcon, self.moduleSettings.statusIconOffset['x'], self.moduleSettings.statusIconOffset['y'])
self:SetIconAlpha()
else
self.frame.statusIcon:SetTexCoord(0.5625, 0.9375, 0.0625, 0.4375)
end
elseif not configMode and not self.resting and (not self.moduleSettings.showStatusIcon or not self.moduleSettings.showStatusCombat) and self.frame.statusIcon then
self.frame.statusIcon = self:DestroyTexFrame(self.frame.statusIcon)
end
else
if (not self.resting or not self.moduleSettings.showStatusResting) and self.frame.statusIcon then
self.frame.statusIcon = self:DestroyTexFrame(self.frame.statusIcon)
elseif self.resting then
self:Resting()
end
end
end
function PlayerHealth.prototype:CheckPartyRole()
if configMode or IceHUD:GetIsInLFGGroup() then
if (configMode or self.moduleSettings.showPartyRoleIcon) and not self.frame.PartyRoleIcon then
local isTank, isHeal, isDPS
local proposalExists, typeID, id, name
local texture, role, hasResponded, totalEncounters, completedEncounters, numMembers, isleader
proposalExists, typeID, id, name, texture, role, hasResponded, totalEncounters, completedEncounters, numMembers, isleader = GetLFGProposal()
local p = self.unit
if IceHUD.WowVer < 40000 then
isTank, isHeal, isDPS = UnitGroupRolesAssigned(p)
else
local grpRole = UnitGroupRolesAssigned(p)
isTank = (grpRole == "TANK")
isHeal = (grpRole == "HEALER")
isDPS = (grpRole == "DAMAGER")
end
IceHUD:Debug(".......")
IceHUD:Debug(p.."="..tostring(UnitName(p)))
IceHUD:Debug( tostring(proposalExists) .."**".. tostring(typeID) .."**".. tostring(id) .."**".. tostring(name) .."**".. tostring(texture) .."**".. tostring(role) .."**".. tostring(hasResponded) .."**".. tostring(totalEncounters) .."**".. tostring(completedEncounters) .."**".. tostring(numMembers) .."**".. tostring(isleader) )
if proposalExists == true then
IceHUD:Debug(tostring(typeID).." "..role)
isTank = (role == "TANK")
isHeal = (role == "HEALER")
isDPS = (role == "DAMAGER")
else
IceHUD:Debug("NoProposal")
end
IceHUD:Debug("---")
if proposalExists == nil then
hasResponded = false
proposalExists = false
end
if hasResponded == false then
if proposalExists == true then
isTank = (role == "TANK")
isHeal = (role == "HEALER")
isDPS = (role == "DAMAGER")
end
else
isTank = not hasResponded
isHeal = not hasResponded
isDPS = not hasResponded
end
IceHUD:Debug("Tank:"..tostring(isTank))
IceHUD:Debug("Heal:"..tostring(isHeal))
IceHUD:Debug("DPS:"..tostring(isDPS))
if isTank then
IceHUD:Debug("Loading Tank")
self.frame.PartyRoleIcon = self:CreateTexCoord(self.frame.PartyRoleIcon, "Interface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES", 20, 20, self.moduleSettings.PartyRoleIconScale, 0/64, 19/64, 22/64, 41/64)
elseif isHeal then
IceHUD:Debug("Loading Heal")
self.frame.PartyRoleIcon = self:CreateTexCoord(self.frame.PartyRoleIcon, "Interface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES", 20, 20, self.moduleSettings.PartyRoleIconScale, 20/64, 39/64, 1/64, 20/64)
elseif isDPS then
IceHUD:Debug("Loading DPS")
self.frame.PartyRoleIcon = self:CreateTexCoord(self.frame.PartyRoleIcon, "Interface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES", 20, 20, self.moduleSettings.PartyRoleIconScale, 20/64, 39/64, 22/64, 41/64)
elseif configMode then
IceHUD:Debug("No Roles==Defaulting to Leader icon")
self.frame.PartyRoleIcon = self:CreateTexCoord(self.frame.PartyRoleIcon, "Interface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES", 20, 20, self.moduleSettings.PartyRoleIconScale, 0/64, 19/64, 1/64, 20/64)
else
IceHUD:Debug("Clearing Frame")
self.frame.PartyRoleIcon = self:DestroyTexFrame(self.frame.PartyRoleIcon)
end
self:SetTexLoc(self.frame.PartyRoleIcon, self.moduleSettings.PartyRoleIconOffset['x'], self.moduleSettings.PartyRoleIconOffset['y'])
self:SetIconAlpha()
elseif not configMode and not self.moduleSettings.showPartyRoleIcon and self.frame.PartyRoleIcon then
IceHUD:Debug("Clearing Frame")
self.frame.PartyRoleIcon = self:DestroyTexFrame(self.frame.PartyRoleIcon)
end
else
if self.frame.PartyRoleIcon then
IceHUD:Debug("Clearing Frame")
self.frame.PartyRoleIcon = self:DestroyTexFrame(self.frame.PartyRoleIcon)
end
end
self:CheckLootMaster()
end
function PlayerHealth.prototype:CheckLeader()
local isLeader
if IceHUD.WowVer >= 50000 then
isLeader = UnitIsGroupLeader("player")
else
isLeader = IsPartyLeader()
end
if configMode or isLeader then
if (configMode or self.moduleSettings.showLeaderIcon) and not self.frame.leaderIcon then
self.frame.leaderIcon = self:CreateTexCoord(self.frame.leaderIcon, "Interface\\GroupFrame\\UI-Group-LeaderIcon", 20, 20,
self.moduleSettings.leaderIconScale, 0, 1, 0, 1)
self:SetTexLoc(self.frame.leaderIcon, self.moduleSettings.leaderIconOffset['x'], self.moduleSettings.leaderIconOffset['y'])
self:SetIconAlpha()
elseif not configMode and not self.moduleSettings.showLeaderIcon and self.frame.leaderIcon then
self.frame.leaderIcon = self:DestroyTexFrame(self.frame.leaderIcon)
end
else
if self.frame.leaderIcon then
self.frame.leaderIcon = self:DestroyTexFrame(self.frame.leaderIcon)
end
end
self:CheckPartyRole()
end
function PlayerHealth.prototype:CheckLootMaster()
local _, lootmaster = GetLootMethod()
if configMode or lootmaster == 0 then
if (configMode or self.moduleSettings.showLootMasterIcon) and not self.frame.lootMasterIcon then
self.frame.lootMasterIcon = self:CreateTexCoord(self.frame.lootMasterIcon, "Interface\\GroupFrame\\UI-Group-MasterLooter", 20, 20,
self.moduleSettings.lootMasterIconScale, 0, 1, 0, 1)
self:SetTexLoc(self.frame.lootMasterIcon, self.moduleSettings.lootMasterIconOffset['x'], self.moduleSettings.lootMasterIconOffset['y'])
self:SetIconAlpha()
elseif not configMode and not self.moduleSettings.showLootMasterIcon and self.frame.lootMasterIcon then
self.frame.lootMasterIcon = self:DestroyTexFrame(self.frame.lootMasterIcon)
end
else
if self.frame.lootMasterIcon then
self.frame.lootMasterIcon = self:DestroyTexFrame(self.frame.lootMasterIcon)
end
end
self:CheckPartyFrameStatus()
end
function PlayerHealth.prototype:CheckPartyFrameStatus()
if (self.moduleSettings.hideBlizzParty) then
self:HideBlizzardParty()
end
end
function PlayerHealth.prototype:CheckPvP()
local pvpMode = nil
local minx, maxx, miny, maxy
if configMode or UnitIsPVPFreeForAll(self.unit) then
pvpMode = "FFA"
minx, maxx, miny, maxy = 0.05, 0.605, 0.015, 0.57
elseif UnitIsPVP(self.unit) then
pvpMode = UnitFactionGroup(self.unit)
if pvpMode == "Neutral" then
pvpMode = "FFA"
end
if pvpMode == "Alliance" then
minx, maxx, miny, maxy = 0.07, 0.58, 0.06, 0.57
else
minx, maxx, miny, maxy = 0.08, 0.58, 0.045, 0.545
end
end
if pvpMode then
if (configMode or self.moduleSettings.showPvPIcon) and not self.frame.PvPIcon then
self.frame.PvPIcon = self:CreateTexCoord(self.frame.PvPIcon, "Interface\\TargetingFrame\\UI-PVP-"..pvpMode, 20, 20,
self.moduleSettings.PvPIconScale, minx, maxx, miny, maxy)
self:SetTexLoc(self.frame.PvPIcon, self.moduleSettings.PvPIconOffset['x'], self.moduleSettings.PvPIconOffset['y'])
self:SetIconAlpha()
elseif not configMode and not self.moduleSettings.showPvPIcon and self.frame.PvPIcon then
self.frame.PvPIcon = self:DestroyTexFrame(self.frame.PvPIcon)
end
else
if self.frame.PvPIcon then
self.frame.PvPIcon = self:DestroyTexFrame(self.frame.PvPIcon)
end
end
end
function PlayerHealth.prototype:UpdateEvent(event, unit)
self:Update(unit)
end
function PlayerHealth.prototype:Update(unit)
PlayerHealth.super.prototype.Update(self)
if (unit and (unit ~= self.unit)) then
return
end
local color = "PlayerHealth"
if (self.moduleSettings.classColor) then
color = self.unitClass
end
if (self.moduleSettings.scaleHealthColor) then
color = "ScaledHealthColor"
end
if not (self.alive) then
color = "Dead"
end
local textColor = color
if (self.resting) then
textColor = "Text"
end
self:UpdateBar(self.healthPercentage, color)
-- sadly, animation uses bar-local variables so we can't use the animation for 2 bar textures on the same bar element
if self.moduleSettings.showIncomingHeals and self.healFrame and self.healFrame.bar and incomingHealAmt then
local percent
if incomingHealAmt > 0 then
percent = self.maxHealth ~= 0 and ((self.health + incomingHealAmt) / self.maxHealth) or 0
if self.moduleSettings.reverse then
percent = 1 - percent
-- Rokiyo: I'm thinking the frama strata should also to be set to medium if we're in reverse.
end
else
percent = 0
end
percent = IceHUD:Clamp(percent, 0, 1)
self:SetBarCoord(self.healFrame, percent)
end
if not IceHUD.IceCore:ShouldUseDogTags() then
self:SetBottomText1(math.floor(self.healthPercentage * 100))
self:SetBottomText2(self:GetFormattedText(self.health, self.maxHealth), textColor)
end
--self:CheckPartyRole()
self:SetIconAlpha()
end
function PlayerHealth.prototype:SetIconAlpha()
if self.frame.statusIcon then
self.frame.statusIcon:SetAlpha(self.moduleSettings.lockIconAlpha and 1 or self.alpha)
end
if self.frame.leaderIcon then
self.frame.leaderIcon:SetAlpha(self.moduleSettings.lockIconAlpha and 1 or self.alpha)
end
if self.frame.lootMasterIcon then
self.frame.lootMasterIcon:SetAlpha(self.moduleSettings.lockIconAlpha and 1 or self.alpha)
end
if self.frame.PvPIcon then
self.frame.PvPIcon:SetAlpha(self.moduleSettings.lockIconAlpha and 1 or self.alpha)
end
if self.frame.PartyRoleIcon then
self.frame.PartyRoleIcon:SetAlpha(self.moduleSettings.lockIconAlpha and 1 or self.alpha)
end
end
function PlayerHealth.prototype:CreateTexCoord(texframe, icon, width, height, scale, left, right, top, bottom)
if not texframe then
texframe = self.masterFrame:CreateTexture(nil, "BACKGROUND")
end
texframe:SetTexture(icon)
texframe:SetTexCoord(left, right, top, bottom)
self:SetTexScale(texframe, width, height, scale)
return texframe
end
function PlayerHealth.prototype:SetTexLoc(texframe, xpos, ypos, anchorFrom, anchorTo)
if not texframe then
return
end
texframe:ClearAllPoints()
texframe:SetPoint(anchorFrom and anchorFrom or "TOPLEFT", self.frame, anchorTo and anchorTo or "TOPLEFT", xpos, ypos)
end
function PlayerHealth.prototype:SetTexScale(texframe, width, height, scale)
if not texframe then
return
end
texframe:SetWidth(width * scale)
texframe:SetHeight(height * scale)
end
function PlayerHealth.prototype:DestroyTexFrame(texframe)
if not texframe then
return nil
end
texframe:SetTexture(nil)
texframe:Hide()
texframe:ClearAllPoints()
return nil
end
function PlayerHealth.prototype:ShowBlizz()
PlayerFrame:Show()
PlayerFrame:GetScript("OnLoad")(PlayerFrame)
end
function PlayerHealth.prototype:HideBlizz()
PlayerFrame:Hide()
PlayerFrame:UnregisterAllEvents()
end
function PlayerHealth.prototype:HideBlizzardParty()
if self.combat then
self.pendingBlizzardPartyHide = true
return
end
-- Both Pitbull 4 and Xperl use these exact code, so we use it too.
for i = 1, MAX_PARTY_MEMBERS do
local party = _G['PartyMemberFrame'..i]
party:UnregisterAllEvents()
party:Hide()
party.Show = function() end
end
UIParent:UnregisterEvent('RAID_ROSTER_UPDATE')
end
function PlayerHealth.prototype:ShowBlizzardParty()
-- Both Pitbull 4 and Xperl use these exact code, so we use it too.
for i = 1, MAX_PARTY_MEMBERS do
local frame = _G["PartyMemberFrame"..i]
if frame then
frame.Show = nil
frame:GetScript("OnLoad")(frame)
if IceHUD.WowVer >= 50000 then
frame:GetScript("OnEvent")(frame, "GROUP_ROSTER_UPDATE")
else
frame:GetScript("OnEvent")(frame, "PARTY_MEMBERS_CHANGED")
end
PartyMemberFrame_UpdateMember(frame)
end
end
UIParent:RegisterEvent("RAID_ROSTER_UPDATE")
end
--function PlayerHealth.prototype:ShowBlizzParty()
-- This loop exists because we need to unregister for events in case the party composition changes.
-- for i = 1, MAX_PARTY_MEMBERS do
-- local party = _G['PartyMemberFrame'..i]
-- party.Show = nil
-- party:RegisterEvent('PARTY_MEMBERS_CHANGED')
-- party:RegisterEvent('PARTY_LEADER_CHANGED')
-- party:RegisterEvent('PARTY_MEMBER_ENABLE')
-- party:RegisterEvent('PARTY_MEMBER_DISABLE')
-- party:RegisterEvent('PARTY_LOOT_METHOD_CHANGED')
-- party:RegisterEvent('MUTELIST_UPDATE')
-- party:RegisterEvent('IGNORELIST_UPDATE')
-- party:RegisterEvent('UNIT_PVP_UPDATE')
-- party:RegisterEvent('UNIT_AURA')
-- party:RegisterEvent('UNIT_PET')
-- party:RegisterEvent('VARIABLES_LOADED')
-- party:RegisterEvent('UNIT_NAME_UPDATE')
-- party:RegisterEvent('UNIT_PORTRAIT_UPDATE')
-- party:RegisterEvent('UNIT_DISPLAYPOWER')
-- party:RegisterEvent('UNIT_ENTERED_VEHICLE')
-- party:RegisterEvent('UNIT_EXITED_VEHICLE')
-- party:RegisterEvent('VOICE_START')
-- party:RegisterEvent('VOICE_STOP')
-- party:RegisterEvent('VOICE_STATUS_UPDATE')
-- party:RegisterEvent('READY_CHECK')
-- party:RegisterEvent('READY_CHECK_CONFIRM')
-- party:RegisterEvent('READY_CHECK_FINISHED')
-- UnitFrame_OnEvent('PARTY_MEMBERS_CHANGED')
-- end
-- UIParent:RegisterEvent('RAID_ROSTER_UPDATE')
--
-- ShowPartyFrame() -- Just call Blizzard default method
--end
function PlayerHealth.prototype:UpdateBar(scale, color, alpha)
PlayerHealth.super.prototype.UpdateBar(self, scale, color, alpha)
if self.healFrame and self.healFrame.bar then
self.healFrame.bar:SetVertexColor(self:GetColor("PlayerHealthHealAmount", self.alpha * self.moduleSettings.healAlpha))
end
--[[ seems to be causing taint. oh well
if self.frame.button then
if self.alpha == 0 then
self.frame.button:Hide()
else
self.frame.button:Show()
end
end
]]
end
function PlayerHealth.prototype:OutCombat()
PlayerHealth.super.prototype.OutCombat(self)
if self.pendingBlizzardPartyHide then
self.pendingBlizzardPartyHide = false
self:HideBlizzardParty()
end
end
-- Load us up
IceHUD.PlayerHealth = PlayerHealth.new()