From b8956a45feb611abf7565f7606845d7b755b58b0 Mon Sep 17 00:00:00 2001 From: iceroth Date: Sat, 2 Sep 2006 20:20:01 +0000 Subject: [PATCH] Version 0.6 - Improved TargetInfo and ToT module - RoundBar texture looks better than ever - PlayerHealth and TargetHealth modules have an option to turn off Blizzard default frames - Fixed MH3 rounding bug --- IceBarElement.lua | 8 +- IceElement.lua | 6 + IceHUD.toc | 4 +- IceUnitBar.lua | 6 +- modules/ComboPoints.lua | 2 +- modules/MirrorBar.lua | 4 + modules/PlayerHealth.lua | 92 +++++- modules/PlayerMana.lua | 4 +- modules/TargetHealth.lua | 78 ++++- modules/TargetInfo.lua | 592 ++++++++++++++++++++++++++----------- modules/TargetMana.lua | 1 + modules/TargetOfTarget.lua | 155 +++++++--- textures/RoundBar.blp | Bin 44900 -> 175972 bytes textures/RoundBarBG.blp | Bin 44900 -> 175972 bytes textures/smooth.tga | Bin 0 -> 32812 bytes 15 files changed, 716 insertions(+), 236 deletions(-) create mode 100644 textures/smooth.tga diff --git a/IceBarElement.lua b/IceBarElement.lua index c83aecb..aeabd60 100644 --- a/IceBarElement.lua +++ b/IceBarElement.lua @@ -194,11 +194,13 @@ end -- OVERRIDE function IceBarElement.prototype:Redraw() IceBarElement.super.prototype.Redraw(self) - + + if (not self.moduleSettings.enabled) then + return + end + self.alpha = self.settings.alphaooc - self:CreateFrame() - self.frame:SetAlpha(self.alpha) end diff --git a/IceElement.lua b/IceElement.lua index 3c007b1..967264f 100644 --- a/IceElement.lua +++ b/IceElement.lua @@ -187,6 +187,7 @@ function IceElement.prototype:GetColor(color, alpha) return self.colors[color].r, self.colors[color].g, self.colors[color].b, alpha end + function IceElement.prototype:GetHexColor(color, alpha) local r, g, b, a = self:GetColor(color) return string.format("%02x%02x%02x%02x", a * 255, r * 255, g * 255, b * 255) @@ -213,6 +214,11 @@ function IceElement.prototype:GetClassColor(class) end +function IceElement.prototype:ConvertToHex(color) + return string.format("ff%02x%02x%02x", color.r*255, color.g*255, color.b*255) +end + + function IceElement.prototype:FontFactory(weight, size, frame, font) local weightString = "" if (weight) then diff --git a/IceHUD.toc b/IceHUD.toc index cbe45e9..7f168e4 100644 --- a/IceHUD.toc +++ b/IceHUD.toc @@ -3,9 +3,9 @@ ## Name: IceHUD ## Title: IceHUD |cff7fff7f -Ace2-|r ## Notes: Another HUD mod -## Version: 0.5 ($Revision$) +## Version: 0.6 ($Revision$) ## SavedVariables: IceCoreDB -## OptionalDeps: FuBar_ToFu, DruidBar, SoleManax, MobHealth +## OptionalDeps: Ace2, DewdropLib, FuBar_ToFu, DruidBar, SoleManax, MobHealth ## X-Category: UnitFrame ## X-Date: $Date$ ## X-eMail: iceroth@iceroth.net diff --git a/IceUnitBar.lua b/IceUnitBar.lua index e1d342e..794fceb 100644 --- a/IceUnitBar.lua +++ b/IceUnitBar.lua @@ -52,7 +52,9 @@ end function IceUnitBar.prototype:Redraw() IceUnitBar.super.prototype.Redraw(self) - self:Update(self.unit) + if (self.moduleSettings.enabled) then + self:Update(self.unit) + end end -- 'Protected' methods -------------------------------------------------------- @@ -69,6 +71,8 @@ function IceUnitBar.prototype:Update() self.mana = UnitMana(self.unit) self.maxMana = UnitManaMax(self.unit) self.manaPercentage = math.floor( (self.mana/self.maxMana)*100 ) + + _, self.unitClass = UnitClass(self.unit) end diff --git a/modules/ComboPoints.lua b/modules/ComboPoints.lua index 902466f..6dd3991 100644 --- a/modules/ComboPoints.lua +++ b/modules/ComboPoints.lua @@ -86,7 +86,7 @@ end -- OVERRIDE function ComboPoints.prototype:GetDefaultSettings() local defaults = ComboPoints.super.prototype.GetDefaultSettings(self) - defaults["vpos"] = -30 + defaults["vpos"] = 0 defaults["comboFontSize"] = 20 defaults["comboMode"] = "Graphical" return defaults diff --git a/modules/MirrorBar.lua b/modules/MirrorBar.lua index 430a644..a50fd60 100644 --- a/modules/MirrorBar.lua +++ b/modules/MirrorBar.lua @@ -337,6 +337,10 @@ end function MirrorBarHandler.prototype:Redraw() MirrorBarHandler.super.prototype.Redraw(self) + if (not self.moduleSettings.enabled) then + return + end + for i = 1, table.getn(self.bars) do self:SetSettings(self.bars[i]) self.bars[i]:UpdatePosition(self.moduleSettings.side, self.moduleSettings.offset + (i-1)) diff --git a/modules/PlayerHealth.lua b/modules/PlayerHealth.lua index dd47fc3..ca818f4 100644 --- a/modules/PlayerHealth.lua +++ b/modules/PlayerHealth.lua @@ -14,6 +14,7 @@ function PlayerHealth.prototype:GetDefaultSettings() local settings = PlayerHealth.super.prototype.GetDefaultSettings(self) settings["side"] = IceCore.Side.Left settings["offset"] = 1 + settings["hideBlizz"] = true return settings end @@ -24,24 +25,77 @@ function PlayerHealth.prototype:Enable(core) self:RegisterEvent("UNIT_HEALTH", "Update") self:RegisterEvent("UNIT_MAXHEALTH", "Update") - + if (self.moduleSettings.hideBlizz) then + self:HideBlizz() + end + self:Update(self.unit) end +-- OVERRIDE +function PlayerHealth.prototype:GetOptions() + local opts = PlayerHealth.super.prototype.GetOptions(self) + + opts["classColor"] = { + type = "toggle", + name = "Class color bar", + desc = "Use class color as the bar color instead of default color", + get = function() + return self.moduleSettings.classColor + end, + set = function(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 = "Hide Blizzard Frame", + desc = "Hides Blizzard Player frame and disables all events related to it", + get = function() + return self.moduleSettings.hideBlizz + end, + set = function(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 + } + + return opts +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 not (self.alive) then color = "dead" end - - + self:UpdateBar(self.health/self.maxHealth, color) self:SetBottomText1(self.healthPercentage) self:SetBottomText2(self:GetFormattedText(self.health, self.maxHealth), color) @@ -49,5 +103,35 @@ end + +function PlayerHealth.prototype:ShowBlizz() + PlayerFrame:Show() + + PlayerFrame:RegisterEvent("UNIT_LEVEL"); + PlayerFrame:RegisterEvent("UNIT_COMBAT"); + PlayerFrame:RegisterEvent("UNIT_FACTION"); + PlayerFrame:RegisterEvent("UNIT_MAXMANA"); + PlayerFrame:RegisterEvent("PLAYER_ENTERING_WORLD"); + PlayerFrame:RegisterEvent("PLAYER_ENTER_COMBAT"); + PlayerFrame:RegisterEvent("PLAYER_LEAVE_COMBAT"); + PlayerFrame:RegisterEvent("PLAYER_REGEN_DISABLED"); + PlayerFrame:RegisterEvent("PLAYER_REGEN_ENABLED"); + PlayerFrame:RegisterEvent("PLAYER_UPDATE_RESTING"); + PlayerFrame:RegisterEvent("PARTY_MEMBERS_CHANGED"); + PlayerFrame:RegisterEvent("PARTY_LEADER_CHANGED"); + PlayerFrame:RegisterEvent("PARTY_LOOT_METHOD_CHANGED"); + PlayerFrame:RegisterEvent("RAID_ROSTER_UPDATE"); + PlayerFrame:RegisterEvent("PLAYTIME_CHANGED"); +end + + +function PlayerHealth.prototype:HideBlizz() + PlayerFrame:Hide() + + PlayerFrame:UnregisterAllEvents() +end + + + -- Load us up PlayerHealth:new() diff --git a/modules/PlayerMana.lua b/modules/PlayerMana.lua index 3924700..38198e9 100644 --- a/modules/PlayerMana.lua +++ b/modules/PlayerMana.lua @@ -95,7 +95,9 @@ end function PlayerMana.prototype:Redraw() PlayerMana.super.prototype.Redraw(self) - self:CreateTickerFrame() + if (self.moduleSettings.enabled) then + self:CreateTickerFrame() + end end diff --git a/modules/TargetHealth.lua b/modules/TargetHealth.lua index 364187e..66b64cd 100644 --- a/modules/TargetHealth.lua +++ b/modules/TargetHealth.lua @@ -20,6 +20,8 @@ function TargetHealth.prototype:GetDefaultSettings() settings["side"] = IceCore.Side.Left settings["offset"] = 2 settings["mobhealth"] = false + settings["classColor"] = false + settings["hideBlizz"] = true return settings end @@ -40,12 +42,47 @@ function TargetHealth.prototype:GetOptions() self:Update(self.unit) end, disabled = function() - return (MobHealth3 == nil) + return (not self.moduleSettings.enabled) and (MobHealth3 == nil) + end, + order = 40 + } + + opts["classColor"] = { + type = "toggle", + name = "Class color bar", + desc = "Use class color as the bar color instead of reaction color", + get = function() + return self.moduleSettings.classColor + end, + set = function(value) + self.moduleSettings.classColor = value + self:Update(self.unit) end, disabled = function() return not self.moduleSettings.enabled end, - order = 40 + order = 41 + } + + opts["hideBlizz"] = { + type = "toggle", + name = "Hide Blizzard Frame", + desc = "Hides Blizzard Target frame and disables all events related to it", + get = function() + return self.moduleSettings.hideBlizz + end, + set = function(value) + self.moduleSettings.hideBlizz = value + if (value) then + self:HideBlizz() + else + self:ShowBlizz() + end + end, + disabled = function() + return not self.moduleSettings.enabled + end, + order = 42 } return opts @@ -57,6 +94,7 @@ function TargetHealth.prototype:Enable(core) self:RegisterEvent("UNIT_HEALTH", "Update") self:RegisterEvent("UNIT_MAXHEALTH", "Update") + self:RegisterEvent("UNIT_FLAGS", "Update") self:Update(self.unit) end @@ -80,9 +118,9 @@ function TargetHealth.prototype:Update(unit) else self.frame:Show() end - + self.color = "targetHealthFriendly" -- friendly > 4 - + local reaction = UnitReaction("target", "player") if (reaction and (reaction == 4)) then self.color = "targetHealthNeutral" @@ -90,6 +128,10 @@ function TargetHealth.prototype:Update(unit) self.color = "targetHealthHostile" end + if (self.moduleSettings.classColor) then + self.color = self.unitClass + end + if (self.tapped) then self.color = "tapped" end @@ -119,7 +161,7 @@ end function TargetHealth.prototype:Round(health) if (health > 1000000) then - return self:MathRound(health/100000, 1) .. "M" + return self:MathRound(health/1000000, 1) .. "M" end if (health > 1000) then return self:MathRound(health/1000, 1) .. "k" @@ -134,5 +176,31 @@ function TargetHealth.prototype:MathRound(num, idp) end + + + +function TargetHealth.prototype:ShowBlizz() + TargetFrame:Show() + + TargetFrame:RegisterEvent("PLAYER_TARGET_CHANGED") + TargetFrame:RegisterEvent("UNIT_HEALTH") + TargetFrame:RegisterEvent("UNIT_LEVEL") + TargetFrame:RegisterEvent("UNIT_FACTION") + TargetFrame:RegisterEvent("UNIT_CLASSIFICATION_CHANGED") + TargetFrame:RegisterEvent("UNIT_AURA") + TargetFrame:RegisterEvent("PLAYER_FLAGS_CHANGED") + TargetFrame:RegisterEvent("PARTY_MEMBERS_CHANGED") + TargetFrame:RegisterEvent("RAID_TARGET_UPDATE") +end + + +function TargetHealth.prototype:HideBlizz() + TargetFrame:Hide() + + TargetFrame:UnregisterAllEvents() +end + + + -- Load us up TargetHealth:new() diff --git a/modules/TargetInfo.lua b/modules/TargetInfo.lua index 92d029a..8333da4 100644 --- a/modules/TargetInfo.lua +++ b/modules/TargetInfo.lua @@ -2,16 +2,34 @@ local AceOO = AceLibrary("AceOO-2.0") local TargetInfo = AceOO.Class(IceElement) +local target = "target" +local internal = "internal" -TargetInfo.Width = 260 TargetInfo.prototype.buffSize = nil +TargetInfo.prototype.width = nil + +TargetInfo.prototype.name = nil +TargetInfo.prototype.guild = nil +TargetInfo.prototype.realm = nil +TargetInfo.prototype.rank = nil +TargetInfo.prototype.classLocale = nil +TargetInfo.prototype.classEnglish = nil +TargetInfo.prototype.leader = nil + +TargetInfo.prototype.combat = nil +TargetInfo.prototype.pvp = nil +TargetInfo.prototype.level = nil +TargetInfo.prototype.classification = nil +TargetInfo.prototype.reaction = nil +TargetInfo.prototype.tapped = nil + +TargetInfo.prototype.isPlayer = nil + -- Constructor -- function TargetInfo.prototype:init() TargetInfo.super.prototype.init(self, "TargetInfo") - self.buffSize = math.floor((TargetInfo.Width - 15) / 16) - self.scalingEnabled = true end @@ -19,6 +37,22 @@ end -- 'Public' methods ----------------------------------------------------------- +-- OVERRIDE +function TargetInfo.prototype:Enable(core) + TargetInfo.super.prototype.Enable(self, core) + + self:RegisterEvent("PLAYER_TARGET_CHANGED", "TargetChanged") + self:RegisterEvent("UNIT_AURA", "AuraChanged") + + self:RegisterEvent("UNIT_FACTION", "TargetFaction") + self:RegisterEvent("UNIT_LEVEL", "TargetLevel") + + self:RegisterEvent("UNIT_FLAGS", "TargetFlags") + self:RegisterEvent("UNIT_DYNAMIC_FLAGS", "TargetFlags") + + self:RegisterEvent("RAID_TARGET_UPDATE", "UpdateRaidTargetIcon") +end + -- OVERRIDE function TargetInfo.prototype:GetOptions() @@ -63,6 +97,47 @@ function TargetInfo.prototype:GetOptions() end, order = 32 } + + opts["zoom"] = { + type = 'range', + name = 'Buff zoom', + desc = 'Buff/debuff icon zoom', + get = function() + return self.moduleSettings.zoom + end, + set = function(v) + self.moduleSettings.zoom = v + self:Redraw() + end, + min = 0, + max = 0.2, + step = 0.01, + disabled = function() + return not self.moduleSettings.enabled + end, + isPercent = true, + order = 33 + } + + opts["buffSize"] = { + type = 'range', + name = 'Buff size', + desc = 'Buff/debuff icon size', + get = function() + return self.moduleSettings.buffSize + end, + set = function(v) + self.moduleSettings.buffSize = v + self:Redraw() + end, + min = 8, + max = 20, + step = 1, + disabled = function() + return not self.moduleSettings.enabled + end, + order = 34 + } return opts end @@ -73,6 +148,8 @@ function TargetInfo.prototype:GetDefaultSettings() local defaults = TargetInfo.super.prototype.GetDefaultSettings(self) defaults["fontSize"] = 13 defaults["vpos"] = -50 + defaults["zoom"] = 0.2 + defaults["buffSize"] = 13 return defaults end @@ -81,23 +158,10 @@ end function TargetInfo.prototype:Redraw() TargetInfo.super.prototype.Redraw(self) - self:CreateFrame() -end - - -function TargetInfo.prototype:Enable(core) - TargetInfo.super.prototype.Enable(self, core) - - self:RegisterEvent("PLAYER_TARGET_CHANGED", "TargetChanged") - self:RegisterEvent("UNIT_AURA", "AuraChanged") - - self:RegisterEvent("UNIT_FACTION", "InfoTextChanged") - self:RegisterEvent("UNIT_LEVEL", "InfoTextChanged") - self:RegisterEvent("UNIT_CLASSIFICATION_CHANGED", "InfoTextChanged") - self:RegisterEvent("PLAYER_FLAGS_CHANGED", "InfoTextChanged") - self:RegisterEvent("UNIT_DYNAMIC_FLAGS", "InfoTextChanged") - - self:RegisterEvent("RAID_TARGET_UPDATE", "RaidIconChanged") + if (self.moduleSettings.enabled) then + self:CreateFrame(true) + self:TargetChanged() + end end @@ -107,182 +171,280 @@ end -- OVERRIDE function TargetInfo.prototype:CreateFrame() TargetInfo.super.prototype.CreateFrame(self) + + self.width = self.settings.gap + 50 + self.frame:SetFrameStrata("BACKGROUND") - self.frame:SetWidth(TargetInfo.Width) + self.frame:SetWidth(self.width) self.frame:SetHeight(42) self.frame:ClearAllPoints() self.frame:SetPoint("TOP", self.parent, "BOTTOM", 0, self.moduleSettings.vpos) self.frame:SetScale(self.moduleSettings.scale) - + self.frame:Show() - + self:CreateTextFrame() self:CreateInfoTextFrame() + self:CreateGuildTextFrame() + self:CreateBuffFrame() self:CreateDebuffFrame() + self:CreateRaidIconFrame() end function TargetInfo.prototype:CreateTextFrame() + if (not self.frame.target) then + self.frame.target = CreateFrame("Button", nil, self.frame) + end + + self.frame.target.unit = target -- for blizz default tooltip handling + self.frame.target:RegisterForClicks("LeftButtonUp", "RightButtonUp") + self.frame.target:SetScript("OnClick", function() self:TargetOnClick(arg1) end) + self.frame.target:SetScript("OnEnter", function() UnitFrame_OnEnter() end) + self.frame.target:SetScript("OnLeave", function() UnitFrame_OnLeave() end) + + + self.frame.target:SetWidth(self.width) + self.frame.target:SetHeight(14) + self.frame.target:SetPoint("TOP", self.frame, "TOP", 0, -2) + self.frame.targetName = self:FontFactory("Bold", self.moduleSettings.fontSize+1, nil, self.frame.targetName) - - self.frame.targetName:SetWidth(TargetInfo.Width - 120) - self.frame.targetName:SetHeight(14) - self.frame.targetName:SetJustifyH("LEFT") - self.frame.targetName:SetJustifyV("BOTTOM") - - self.frame.targetName:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 2, -2) - self.frame.targetName:Show() + self.frame.targetName:SetJustifyH("CENTER") + self.frame.targetName:SetJustifyV("TOP") + self.frame.targetName:SetAllPoints(self.frame.target) + + self.frame.target:Show() end function TargetInfo.prototype:CreateInfoTextFrame() self.frame.targetInfo = self:FontFactory(nil, self.moduleSettings.fontSize, nil, self.frame.targetInfo) - - self.frame.targetInfo:SetWidth(TargetInfo.Width) + + self.frame.targetInfo:SetWidth(self.width) self.frame.targetInfo:SetHeight(14) - self.frame.targetInfo:SetJustifyH("LEFT") + self.frame.targetInfo:SetJustifyH("CENTER") self.frame.targetInfo:SetJustifyV("TOP") - - self.frame.targetInfo:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 2, -16) + + self.frame.targetInfo:SetPoint("TOP", self.frame, "TOP", 0, -16) self.frame.targetInfo:Show() end +function TargetInfo.prototype:CreateGuildTextFrame() + self.frame.targetGuild = self:FontFactory(nil, self.moduleSettings.fontSize, nil, self.frame.targetGuild) + + self.frame.targetGuild:SetHeight(14) + self.frame.targetGuild:SetJustifyH("CENTER") + self.frame.targetGuild:SetJustifyV("TOP") + + self.frame.targetGuild:SetAlpha(0.6) + + self.frame.targetGuild:SetPoint("TOP", self.frame, "TOP", 0, -30) + self.frame.targetGuild:Show() +end + + function TargetInfo.prototype:CreateRaidIconFrame() - if (self.frame.raidIcon) then - return + if (not self.frame.raidIcon) then + self.frame.raidIcon = CreateFrame("Frame", nil, self.frame) + end + + if (not self.frame.raidIcon.icon) then + self.frame.raidIcon.icon = self.frame.raidIcon:CreateTexture(nil, "BACKGROUND") + self.frame.raidIcon.icon:SetTexture("Interface\\TargetingFrame\\UI-RaidTargetingIcons") end - self.frame.raidIcon = self.frame:CreateTexture(nil, "BACKGROUND") - - self.frame.raidIcon:SetTexture("Interface\\TargetingFrame\\UI-RaidTargetingIcons") - self.frame.raidIcon:SetPoint("TOPRIGHT", self.frame, "TOPLEFT", -5, -5) + self.frame.raidIcon:SetPoint("BOTTOM", self.frame, "TOP", 0, 1) self.frame.raidIcon:SetWidth(16) self.frame.raidIcon:SetHeight(16) - SetRaidTargetIconTexture(self.frame.raidIcon, 0) - self.frame:Hide() + + self.frame.raidIcon.icon:SetAllPoints(self.frame.raidIcon) + SetRaidTargetIconTexture(self.frame.raidIcon.icon, 0) + self.frame.raidIcon:Hide() end function TargetInfo.prototype:CreateBuffFrame() - if (self.frame.buffFrame) then - return + if (not self.frame.buffFrame) then + self.frame.buffFrame = CreateFrame("Frame", nil, self.frame) end - self.frame.buffFrame = CreateFrame("Frame", nil, self.frame) - self.frame.buffFrame:SetFrameStrata("BACKGROUND") - self.frame.buffFrame:SetWidth(TargetInfo.Width) - self.frame.buffFrame:SetHeight(20) - - self.frame.buffFrame:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 2, -32) + self.frame.buffFrame:SetWidth(1) + self.frame.buffFrame:SetHeight(1) + + self.frame.buffFrame:ClearAllPoints() + self.frame.buffFrame:SetPoint("TOPRIGHT", self.frame, "TOPLEFT", -5, 0) self.frame.buffFrame:Show() - - self.frame.buffFrame.buffs = self:CreateIconFrames(self.frame.buffFrame) + + if (not self.frame.buffFrame.buffs) then + self.frame.buffFrame.buffs = {} + end + self.frame.buffFrame.buffs = self:CreateIconFrames(self.frame.buffFrame, -1, self.frame.buffFrame.buffs, "buff") end function TargetInfo.prototype:CreateDebuffFrame() - if (self.frame.debuffFrame) then - return + if (not self.frame.debuffFrame) then + self.frame.debuffFrame = CreateFrame("Frame", nil, self.frame) end - - self.frame.debuffFrame = CreateFrame("Frame", nil, self.frame) - + self.frame.debuffFrame:SetFrameStrata("BACKGROUND") - self.frame.debuffFrame:SetWidth(TargetInfo.Width) - self.frame.debuffFrame:SetHeight(20) - - self.frame.debuffFrame:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 2, -34 - self.buffSize) + self.frame.debuffFrame:SetWidth(1) + self.frame.debuffFrame:SetHeight(1) + + self.frame.debuffFrame:ClearAllPoints() + self.frame.debuffFrame:SetPoint("TOPLEFT", self.frame, "TOPRIGHT", 5, 0) self.frame.debuffFrame:Show() - - self.frame.debuffFrame.buffs = self:CreateIconFrames(self.frame.debuffFrame) + + if (not self.frame.debuffFrame.buffs) then + self.frame.debuffFrame.buffs = {} + end + self.frame.debuffFrame.buffs = self:CreateIconFrames(self.frame.debuffFrame, 1, self.frame.debuffFrame.buffs, "debuff") end - -function TargetInfo.prototype:CreateIconFrames(parent) - local buffs = {} - +function TargetInfo.prototype:CreateIconFrames(parent, direction, buffs, type) for i = 1, 16 do - buffs[i] = CreateFrame("Frame", nil, parent) + if (not buffs[i]) then + buffs[i] = CreateFrame("Frame", nil, parent) + buffs[i].icon = CreateFrame("Frame", nil, buffs[i]) + end + buffs[i]:SetFrameStrata("BACKGROUND") - buffs[i]:SetWidth(self.buffSize) - buffs[i]:SetHeight(self.buffSize) - buffs[i]:SetPoint("LEFT", (i-1) * self.buffSize + (i-1), 0) + buffs[i]:SetWidth(self.moduleSettings.buffSize) + buffs[i]:SetHeight(self.moduleSettings.buffSize) + + buffs[i].icon:SetFrameStrata("BACKGROUND") + buffs[i].icon:SetWidth(self.moduleSettings.buffSize-2) + buffs[i].icon:SetHeight(self.moduleSettings.buffSize-2) + + local pos = (i > 8) and i-8 or i + local x = (((pos-1) * self.moduleSettings.buffSize) + (pos-0)) * direction + local y = (i > 8) and -self.moduleSettings.buffSize-0 or 0 + + buffs[i]:ClearAllPoints() + buffs[i]:SetPoint("TOP", x, y) + + buffs[i].icon:ClearAllPoints() + buffs[i].icon:SetPoint("CENTER", 0, 0) + buffs[i]:Show() + buffs[i].icon:Show() + + if (not buffs[i].texture) then + buffs[i].texture = buffs[i]:CreateTexture() + buffs[i].texture:ClearAllPoints() + buffs[i].texture:SetAllPoints(buffs[i]) + + buffs[i].icon.texture = buffs[i].icon:CreateTexture() + buffs[i].icon.texture:SetTexture(nil) + + buffs[i].icon.texture:ClearAllPoints() + buffs[i].icon.texture:SetAllPoints(buffs[i].icon) + + buffs[i].icon.stack = self:FontFactory("Bold", 11, buffs[i].icon) + + buffs[i].icon.stack:ClearAllPoints() + buffs[i].icon.stack:SetPoint("BOTTOMRIGHT" , buffs[i].icon, "BOTTOMRIGHT", 1, -1) + end - buffs[i].texture = buffs[i]:CreateTexture() - buffs[i].texture:SetTexture(nil) - buffs[i].texture:SetAllPoints(buffs[i]) - - buffs[i].stack = self:FontFactory("Bold", 15, buffs[i]) - buffs[i].stack:SetPoint("BOTTOMRIGHT" , buffs[i], "BOTTOMRIGHT", 0, -1) + buffs[i]:EnableMouse(true) + buffs[i].id = i + buffs[i]:SetScript("OnEnter", function() self:BuffOnEnter(type) end) + buffs[i]:SetScript("OnLeave", function() GameTooltip:Hide() end) end + return buffs end + + function TargetInfo.prototype:UpdateBuffs() + local zoom = self.moduleSettings.zoom + for i = 1, 16 do local buffTexture, buffApplications = UnitBuff("target", i) + + --buffTexture = buffTexture or "Interface\\Icons\\Spell_Nature_Regeneration" + + self.frame.buffFrame.buffs[i].icon.texture:SetTexture(buffTexture) + self.frame.buffFrame.buffs[i].icon.texture:SetTexCoord(zoom, 1-zoom, zoom, 1-zoom) - self.frame.buffFrame.buffs[i].texture:SetTexture(buffTexture) - + local alpha = buffTexture and 0.3 or 0 + self.frame.buffFrame.buffs[i].texture:SetTexture(0, 0, 0, alpha) + + self.frame.buffFrame.buffs[i].texture:SetVertexColor(color.r, color.g, color.b) + + + --buffApplications = 2 + if (buffApplications and (buffApplications > 1)) then - self.frame.buffFrame.buffs[i].stack:SetText(buffApplications) + self.frame.buffFrame.buffs[i].icon.stack:SetText(buffApplications) else - self.frame.buffFrame.buffs[i].stack:SetText(nil) + self.frame.buffFrame.buffs[i].icon.stack:SetText(nil) end + + if (buffTexture) then + self.frame.buffFrame.buffs[i]:Show() + else + self.frame.buffFrame.buffs[i]:Hide() + end + end - + for i = 1, 16 do - local buffTexture, buffApplications = UnitDebuff("target", i) - - self.frame.debuffFrame.buffs[i].texture:SetTexture(buffTexture) - + local buffTexture, buffApplications, debuffDispelType = UnitDebuff("target", i) + + --buffTexture = buffTexture or "Interface\\Icons\\Ability_Creature_Disease_04" + + local color = debuffDispelType and DebuffTypeColor[debuffDispelType] or DebuffTypeColor["none"] + local alpha = buffTexture and 1 or 0 + self.frame.debuffFrame.buffs[i].texture:SetTexture(1, 1, 1, alpha) + + self.frame.debuffFrame.buffs[i].texture:SetVertexColor(color.r, color.g, color.b) + + + self.frame.debuffFrame.buffs[i].icon.texture:SetTexture(buffTexture) + self.frame.debuffFrame.buffs[i].icon.texture:SetTexCoord(zoom, 1-zoom, zoom, 1-zoom) + if (buffApplications and (buffApplications > 1)) then - self.frame.debuffFrame.buffs[i].stack:SetText(buffApplications) + self.frame.debuffFrame.buffs[i].icon.stack:SetText(buffApplications) else - self.frame.debuffFrame.buffs[i].stack:SetText(nil) + self.frame.debuffFrame.buffs[i].icon.stack:SetText(nil) + end + + + if (buffTexture) then + self.frame.debuffFrame.buffs[i]:Show() + else + self.frame.debuffFrame.buffs[i]:Hide() end end end -function TargetInfo.prototype:InfoTextChanged(unit) - if (unit == "target") then - self.frame.targetInfo:SetText(self:GetInfoString()) - end -end - - function TargetInfo.prototype:AuraChanged(unit) - if (unit == "target") then + if (unit == target) then self:UpdateBuffs() end end -function TargetInfo.prototype:RaidIconChanged(unit) - if (unit == "target") then - self:UpdateRaidTargetIcon() - end -end - - function TargetInfo.prototype:UpdateRaidTargetIcon() - if not (UnitExists("target")) then + if not (UnitExists(target)) then self.frame.raidIcon:Hide() return end - local index = GetRaidTargetIndex("target"); + local index = GetRaidTargetIndex(target); + if (index and (index > 0)) then - SetRaidTargetIconTexture(self.frame.raidIcon, index) + SetRaidTargetIconTexture(self.frame.raidIcon.icon, index) self.frame.raidIcon:Show() else self.frame.raidIcon:Hide() @@ -291,85 +453,169 @@ end function TargetInfo.prototype:TargetChanged() - local name = UnitName("target") - local _, unitClass = UnitClass("target") + if (not UnitExists(target)) then + self.frame.targetName:SetText() + self.frame.targetInfo:SetText() + self.frame.targetGuild:SetText() + + self:UpdateBuffs() + self:UpdateRaidTargetIcon() + return + end + + self.name, self.realm = UnitName(target) + self.classLocale, self.classEnglish = UnitClass(target) + self.isPlayer = UnitIsPlayer(target) + + local guildName, guildRankName, guildRankIndex = GetGuildInfo(target); + self.guild = guildName and "<" .. guildName .. ">" or "" + + + if (self.classLocale and self.isPlayer) then + self.classLocale = "|c" .. self:GetHexColor(self.classEnglish) .. self.classLocale .. "|r" + else + self.classLocale = UnitCreatureType(target) + end + + + self.leader = UnitIsPartyLeader(target) and " Leader" or "" + + + -- pass "internal" as a paramater so event handler code doesn't execute + -- self:Update() unnecassarily + self:TargetLevel(internal) + self:TargetReaction(internal) + self:TargetFaction(internal) + self:TargetFlags(internal) - self.frame.targetName:SetTextColor(self:GetColor(unitClass, 1)) - self.frame.targetName:SetText(name) - self.frame.targetInfo:SetText(self:GetInfoString()) self:UpdateBuffs() self:UpdateRaidTargetIcon() + + self:Update(target) end -function TargetInfo.prototype:GetInfoString() - local u = "target" - - if not (UnitExists(u)) then - return "" - end - - local class, unitClass = UnitClass(u) - local creatureType = UnitCreatureType(u) - local classification = UnitClassification(u) - local level = UnitLevel(u) - - local isPlayer = UnitIsPlayer(u) - - local classColor = self:GetHexColor(unitClass) - - local sLevel = "[??] " - if (level > 0) then - sLevel = "[L" .. level - if (UnitIsPlusMob(u)) then - sLevel = sLevel .. "+" - end - sLevel = sLevel .. "] " - end - - local sClass = "" - if (class and isPlayer) then - sClass = "|c" .. classColor .. class .. "|r " - elseif (creatureType) then - sClass = creatureType .. " " - end - - local sPVP = "" - if (isPlayer) then - if (UnitIsPVP(u)) then - local color = "ff10ff10" -- friendly - if (UnitFactionGroup("target") ~= UnitFactionGroup("player")) then - color = "ffff1010" +function TargetInfo.prototype:TargetLevel(unit) + if (unit == target or unit == internal) then + self.level = UnitLevel(target) + + local color = GetDifficultyColor((self.level > 0) and self.level or 100) + + if (self.level > 0) then + if (UnitIsPlusMob(target)) then + self.level = self.level .. "+" end - sPVP = "|c" .. color .. "[PvP]|r " else - sPVP = "|cff1010ff[PvE]|r " + self.level = "??" end - end - - local sClassification = "" - if (classification == "rare" or classification == "rareelite") then - sClassification = "[Rare] " - end - if (classification == "worldboss") then - sClassification = "[World Boss] " - end - local sLeader = "" - if (UnitIsPartyLeader(u)) then - sLeader = "[Leader] " + self.level = "|c" .. self:ConvertToHex(color) .. self.level .. "|r" + + self:Update(unit) end - - local sCombat = "" - --if (UnitAffectingCombat(u)) then - -- sCombat = " +Combat+" - --end - - return string.format("%s%s%s%s%s%s", - sLevel, sClass, sPVP, sClassification, sLeader, sCombat) end +function TargetInfo.prototype:TargetReaction(unit) + if (unit == target or unit == internal) then + self.reaction = UnitReaction(target, "player") + + -- if we don't get reaction, unit is out of range - has to be friendly + -- to be targettable (party/raid) + if (not self.reaction) then + self.reaction = 5 + end + self:Update(unit) + end +end + + +-- PVP status +function TargetInfo.prototype:TargetFaction(unit) + if (unit == target or unit == internal) then + if (self.isPlayer) then + if (UnitIsPVP(target)) then + local color = "ff10ff10" -- friendly + if (UnitFactionGroup(target) ~= UnitFactionGroup("player")) then + color = "ffff1010" -- hostile + end + self.pvp = " |c" .. color .. "PvP|r" + else + self.pvp = " |cff1010ffPvE|r" + end + else + self.pvp = "" + end + + self:Update(unit) + end +end + + +function TargetInfo.prototype:TargetFlags(unit) + if (unit == target or unit == internal) then + self.tapped = UnitIsTapped(target) and (not UnitIsTappedByPlayer(target)) + self.combat = UnitAffectingCombat(target) and " |cffee4030Combat|r" or "" + self:Update(unit) + end +end + + +function TargetInfo.prototype:Update(unit) + if (unit ~= target) then + return + end + + local reactionColor = self:ConvertToHex(UnitReactionColor[self.reaction]) + if (self.tapped) then + reactionColor = self:GetHexColor("tapped") + end + + local line1 = string.format("|c%s%s|r", reactionColor, self.name or '') + self.frame.targetName:SetText(line1) + + local line2 = string.format("%s %s%s%s%s", + self.level or '', self.classLocale or '', self.pvp or '', self.leader or '', self.combat or '') + self.frame.targetInfo:SetText(line2) + + local realm = self.realm and " " .. self.realm or "" + local line3 = string.format("%s%s", self.guild or '', realm) + self.frame.targetGuild:SetText(line3) +end + + + +function TargetInfo.prototype:TargetOnClick(button) + -- copy&paste from blizz code, it better work ;) + if (SpellIsTargeting() and button == "RightButton") then + SpellStopTargeting() + return + end + + if (button == "LeftButton") then + if (SpellIsTargeting()) then + SpellTargetUnit(target) + elseif (CursorHasItem()) then + DropItemOnUnit(target) + end + else + ToggleDropDownMenu(1, nil, TargetFrameDropDown, "cursor") + end +end + + +function TargetInfo.prototype:BuffOnEnter(type) + if (not this:IsVisible()) then + return + end + + GameTooltip:SetOwner(this, "ANCHOR_BOTTOMRIGHT") + if (type == "buff") then + GameTooltip:SetUnitBuff(target, this.id) + else + GameTooltip:SetUnitDebuff(target, this.id) + end +end -- Load us up TargetInfo:new() diff --git a/modules/TargetMana.lua b/modules/TargetMana.lua index 7f92692..d497cc1 100644 --- a/modules/TargetMana.lua +++ b/modules/TargetMana.lua @@ -32,6 +32,7 @@ function TargetMana.prototype:Enable(core) self:RegisterEvent("UNIT_ENERGY", "Update") self:RegisterEvent("UNIT_MAXENERGY", "Update") self:RegisterEvent("UNIT_AURA", "Update") + self:RegisterEvent("UNIT_FLAGS", "Update") self:Update("target") end diff --git a/modules/TargetOfTarget.lua b/modules/TargetOfTarget.lua index 11f6aad..351d01c 100644 --- a/modules/TargetOfTarget.lua +++ b/modules/TargetOfTarget.lua @@ -4,6 +4,8 @@ local TargetOfTarget = AceOO.Class(IceElement, "Metrognome-2.0") TargetOfTarget.prototype.stackedDebuffs = nil TargetOfTarget.prototype.buffSize = nil +TargetOfTarget.prototype.height = nil +TargetOfTarget.prototype.unit = nil -- Constructor -- @@ -13,9 +15,11 @@ function TargetOfTarget.prototype:init() self:SetColor("totHostile", 0.8, 0.1, 0.1) self:SetColor("totFriendly", 0.2, 1, 0.2) self:SetColor("totNeutral", 0.9, 0.9, 0) - - self.buffSize = 15 + + self.buffSize = 12 + self.height = 12 self.stackedDebuffs = {} + self.unit = "targettarget" self.scalingEnabled = true end @@ -99,8 +103,10 @@ end -- OVERRIDE function TargetOfTarget.prototype:Redraw() TargetOfTarget.super.prototype.Redraw(self) - - self:CreateFrame() + + if (self.moduleSettings.enabled) then + self:CreateFrame() + end end @@ -126,43 +132,80 @@ end -- OVERRIDE function TargetOfTarget.prototype:CreateFrame() - TargetOfTarget.super.prototype.CreateFrame(self) - + if not (self.frame) then + self.frame = CreateFrame("Button", "IceHUD_"..self.name, self.parent) + end + self.frame:SetFrameStrata("BACKGROUND") - self.frame:SetWidth(260) - self.frame:SetHeight(50) - self.frame:SetPoint("TOP", self.parent, "BOTTOM", 0, self.moduleSettings.vpos) + self.frame:SetWidth(self.settings.gap) + self.frame:SetHeight(self.height) + self.frame:SetPoint("TOP", self.parent, "TOP", 0, self.moduleSettings.vpos) self.frame:SetScale(self.moduleSettings.scale) - self.frame:Show() + + if (not self.frame.texture) then + self.frame.texture = self.frame:CreateTexture() + self.frame.texture:SetTexture(IceElement.TexturePath .. "smooth") + self.frame.texture:SetVertexColor(0.2, 0.2, 0.2, 0.3) + self.frame.texture:SetAllPoints(self.frame) + end + self.frame.unit = self.unit -- for blizz default tooltip handling + self.frame:RegisterForClicks("LeftButtonUp", "RightButtonUp") + self.frame:SetScript("OnClick", function() self:OnClick(arg1) end) + self.frame:SetScript("OnEnter", function() UnitFrame_OnEnter() end) + self.frame:SetScript("OnLeave", function() UnitFrame_OnLeave() end) + + self:CreateBarFrame() self:CreateToTFrame() self:CreateToTHPFrame() self:CreateDebuffFrame() end +function TargetOfTarget.prototype:CreateBarFrame() + if (not self.frame.bar) then + self.frame.bar = CreateFrame("StatusBar", nil, self.frame) + end + + self.frame.bar:SetFrameStrata("BACKGROUND") + self.frame.bar:SetWidth(self.settings.gap) + self.frame.bar:SetHeight(self.height) + + self.frame.bar:SetPoint("LEFT", self.frame, "LEFT", 0, 0) + + if (not self.frame.bar.texture) then + self.frame.bar.texture = self.frame.bar:CreateTexture() + self.frame.bar.texture:SetTexture(IceElement.TexturePath .. "smooth") + self.frame.bar.texture:SetAllPoints(self.frame.bar) + self.frame.bar:SetStatusBarTexture(self.frame.bar.texture) + end + + self.frame.bar:Show() +end + + function TargetOfTarget.prototype:CreateToTFrame() - self.frame.totName = self:FontFactory("Bold", self.moduleSettings.fontSize+1, nil, self.frame.totName) + self.frame.totName = self:FontFactory("Bold", self.moduleSettings.fontSize, self.frame.bar, self.frame.totName) - self.frame.totName:SetWidth(120) - self.frame.totName:SetHeight(14) - self.frame.totName:SetJustifyH("RIGHT") - self.frame.totName:SetJustifyV("BOTTOM") - - self.frame.totName:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", 0, -2) + self.frame.totName:SetWidth(self.settings.gap-40) + self.frame.totName:SetHeight(self.height) + self.frame.totName:SetJustifyH("LEFT") + self.frame.totName:SetJustifyV("TOP") + + self.frame.totName:SetPoint("LEFT", self.frame, "LEFT", 0, 0) self.frame.totName:Show() end function TargetOfTarget.prototype:CreateToTHPFrame() - self.frame.totHealth = self:FontFactory(nil, self.moduleSettings.fontSize, nil, self.frame.totHealth) - - self.frame.totHealth:SetWidth(120) - self.frame.totHealth:SetHeight(14) + self.frame.totHealth = self:FontFactory("Bold", self.moduleSettings.fontSize, self.frame.bar, self.frame.totHealth) + + self.frame.totHealth:SetWidth(40) + self.frame.totHealth:SetHeight(self.height) self.frame.totHealth:SetJustifyH("RIGHT") self.frame.totHealth:SetJustifyV("TOP") - - self.frame.totHealth:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", 0, -16) + + self.frame.totHealth:SetPoint("RIGHT", self.frame, "RIGHT", 0, 0) self.frame.totHealth:Show() end @@ -199,7 +242,7 @@ function TargetOfTarget.prototype:CreateIconFrames(parent) buffs[i].texture:SetTexture(nil) buffs[i].texture:SetAllPoints(buffs[i]) - buffs[i].stack = self:FontFactory("Bold", 15, buffs[i]) + buffs[i].stack = self:FontFactory("Bold", 11, buffs[i]) buffs[i].stack:SetPoint("BOTTOMRIGHT" , buffs[i], "BOTTOMRIGHT", 0, -1) end return buffs @@ -211,8 +254,8 @@ function TargetOfTarget.prototype:UpdateBuffs() if (self.moduleSettings.showDebuffs) then for i = 1, 16 do - local buffTexture, buffApplications = UnitDebuff("targettarget", i) - + local buffTexture, buffApplications = UnitDebuff(self.unit, i) + if (buffApplications and (buffApplications > 1)) then debuffs = debuffs + 1 @@ -241,36 +284,56 @@ end function TargetOfTarget.prototype:Update() self:UpdateBuffs() - if not (UnitExists("targettarget")) then + if not (UnitExists(self.unit)) then self.frame.totName:SetText() self.frame.totHealth:SetText() + self.frame:Hide() return end - - local _, unitClass = UnitClass("targettarget") - local name = UnitName("targettarget") - - self.frame.totName:SetTextColor(self:GetColor(unitClass, 1)) - self.frame.totName:SetText(name) - - - local color = "totFriendly" -- friendly > 4 - local reaction = UnitReaction("targettarget", "player") - if (reaction and (reaction == 4)) then - color = "totNeutral" - elseif (reaction and (reaction < 4)) then - color = "totHostile" - end - - local health = UnitHealth("targettarget") - local maxHealth = UnitHealthMax("targettarget") + + self.frame:Show() + + local _, unitClass = UnitClass(self.unit) + local name = UnitName(self.unit) + local reaction = UnitReaction(self.unit, "player") + + local health = UnitHealth(self.unit) + local maxHealth = UnitHealthMax(self.unit) local healthPercentage = math.floor( (health/maxHealth)*100 ) - self.frame.totHealth:SetTextColor(self:GetColor(color, 1)) + local rColor = UnitReactionColor[reaction or 5] + + self.frame.totName:SetTextColor(rColor.r, rColor.g, rColor.b, 0.9) + self.frame.totName:SetText(name) + + self.frame.totHealth:SetTextColor(rColor.r, rColor.g, rColor.b, 0.9) self.frame.totHealth:SetText(healthPercentage .. "%") + + self.frame.bar.texture:SetVertexColor(self:GetColor(unitClass, 0.7)) + self.frame.bar:SetMinMaxValues(0, maxHealth) + self.frame.bar:SetValue(health) end +function TargetOfTarget.prototype:OnClick(button) + -- copy&paste from blizz code, it better work ;) + if (SpellIsTargeting() and button == "RightButton") then + SpellStopTargeting() + return + end + + if (button == "LeftButton") then + if (SpellIsTargeting()) then + SpellTargetUnit(self.unit) + elseif (CursorHasItem()) then + DropItemOnUnit(self.unit) + end + else + ToggleDropDownMenu(1, nil, TargetFrameDropDown, "cursor") + end +end + + -- load us up TargetOfTarget:new() diff --git a/textures/RoundBar.blp b/textures/RoundBar.blp index afbc2e9111fb012accbd04beea019450fa041ebb..c3194a9e923e16b717d8bc186a063292180a0498 100644 GIT binary patch literal 175972 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 U?~b8Af)2Uhm&e{2<@(eA4^`7Y<^TWy literal 44900 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 diff --git a/textures/RoundBarBG.blp b/textures/RoundBarBG.blp index ddaa90d055847f738541753047b7869710f3144b..5e501ca039119171e5abf066c37ebc0b4f6e034e 100644 GIT binary patch literal 175972 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 z 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 H^W^^z#o~E@ diff --git a/textures/smooth.tga b/textures/smooth.tga new file mode 100644 index 0000000000000000000000000000000000000000..9ad81ad91ac1c9e2b98ed8ea8983054e8b0a4865 GIT binary patch literal 32812 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 We&ipI{OzxQJp1QI{_^mj&in_%iDNtf literal 0 HcmV?d00001