diff --git a/IceHUD.toc b/IceHUD.toc index 94e960d..351fbea 100644 --- a/IceHUD.toc +++ b/IceHUD.toc @@ -63,3 +63,8 @@ modules\PetInfo.lua modules\TargetOfTargetCast.lua modules\CustomCDBar.lua modules\Totems.lua +# - PlayerCC must be after TargetCC +modules\PlayerCC.lua +modules\TargetInvuln.lua +# - PlayerInvuln must be after TargetInvuln +modules\PlayerInvuln.lua diff --git a/modules/PlayerCC.lua b/modules/PlayerCC.lua new file mode 100644 index 0000000..79dce4f --- /dev/null +++ b/modules/PlayerCC.lua @@ -0,0 +1,27 @@ +local AceOO = AceLibrary("AceOO-2.0") + +-- changed to inherit from the TargetCC bar since the only difference is the unit and the default placement +-- helps keep changes in one place and we don't have to duplicate the CC spell tables and they don't have to be globals +local PlayerCC = AceOO.Class(TargetCC) + +-- Constructor -- +function PlayerCC.prototype:init() + PlayerCC.super.prototype.init(self, "PlayerCC", "player") +end + +-- 'Public' methods ----------------------------------------------------------- + +-- OVERRIDE +function PlayerCC.prototype:GetDefaultSettings() + local settings = PlayerCC.super.prototype.GetDefaultSettings(self) + + settings["side"] = IceCore.Side.Left + settings["offset"] = 5 + + return settings +end + +-- 'Protected' methods -------------------------------------------------------- + +-- Load us up +IceHUD.PlayerCC = PlayerCC:new() diff --git a/modules/PlayerInvuln.lua b/modules/PlayerInvuln.lua new file mode 100644 index 0000000..38b7307 --- /dev/null +++ b/modules/PlayerInvuln.lua @@ -0,0 +1,27 @@ +local AceOO = AceLibrary("AceOO-2.0") + +-- changed to inherit from the TargetInvuln bar since the only difference is the unit and the default placement +-- helps keep changes in one place and we don't have to duplicate the Invuln spell tables and they don't have to be globals +local PlayerInvuln = AceOO.Class(TargetInvuln) + +-- Constructor -- +function PlayerInvuln.prototype:init() + PlayerInvuln.super.prototype.init(self, "PlayerInvuln", "player") +end + +-- 'Public' methods ----------------------------------------------------------- + +-- OVERRIDE +function PlayerInvuln.prototype:GetDefaultSettings() + local settings = PlayerInvuln.super.prototype.GetDefaultSettings(self) + + settings["side"] = IceCore.Side.Left + settings["offset"] = 3 + + return settings +end + +-- 'Protected' methods -------------------------------------------------------- + +-- Load us up +IceHUD.PlayerInvuln = PlayerInvuln:new() diff --git a/modules/TargetCC.lua b/modules/TargetCC.lua index d6072bb..582d4a6 100644 --- a/modules/TargetCC.lua +++ b/modules/TargetCC.lua @@ -35,6 +35,8 @@ local StunCCList = { 12809, -- bash 5211, + -- Maim + 22570, -- pounce 9005, -- improved concussive shot @@ -47,8 +49,10 @@ local StunCCList = { 44572, -- shockwave 46968, - -- Entangling Roots (more of a snare than a stun, but we don't have a snare category) - 19975, + -- Gnaw + 47481, + -- stun proc + 20170, } local IncapacitateCCList = { @@ -78,20 +82,22 @@ local IncapacitateCCList = { 3355, -- Chastise 44041, - -- Maim - 22570, -- Banish 710, -- Shackle Undead 9484, -- Cyclone 33786, - -- Chains of Ice - 45524, -- Hungering Cold 49203, - -- Hex - 51514, + -- Seduction + 6358, + -- Freezing Arrow + 60210, + -- Shackle + 10955, + -- Turn Evil + 10326, } local FearCCList = { @@ -101,10 +107,82 @@ local FearCCList = { 5782, -- Howl of Terror 5484, + -- Death Coil + 47860, -- Intimidating Shout 5246, + -- Hex + 51514, + -- Scare Beast + 14327, } +local SilenceCCList = { + -- Shield of the Templar + 63529, + -- Silence + 15487, + -- Silencing Shot + 34490, + -- Spell Lock + 19647, + -- Gag Order + 18498, + -- Arcane Torrent + 50613, + -- Arcane Torrent + 28730, + -- Arcane Torrent + 25046, + -- Improved Kick + 13867, + -- Improved Counterspell + 55021, + -- Strangulate + 47476, + -- Garotte - Silence + 1330, + -- Disarm + 676, + -- Dismantle + 51722, + -- Psychic Horror + 64058, + -- Chimera Shot - Scorpid + 53359, +} + +local RootCCList = { + -- Entangling Roots + 53308, + -- Entangling Roots - Nature's Grasp + 53313, + -- Frost Nova + 42917, + -- Earthbind Effect + 64695, + -- Shattered Barrier + 55080, + -- Imp Hamstring + 23694, + -- Freeze + 33395, + -- Frostbite + 12494, + -- Entrapment + 64804, + -- Web + 4167, + -- Pin + 53548, + -- Venom Web Spray + 55509, + -- Chains of Ice + 45524, +} + + + -- Constructor -- function TargetCC.prototype:init(moduleName, unit) -- not sure if this is necessary...i think it is...this way, we can instantiate this bar on its own or as a parent class @@ -121,11 +199,15 @@ function TargetCC.prototype:init(moduleName, unit) self:SetDefaultColor("CC:Stun", 0.85, 0.55, 0.2) self:SetDefaultColor("CC:Incapacitate", 0.90, 0.6, 0.2) self:SetDefaultColor("CC:Fear", 0.85, 0.2, 0.65) + self:SetDefaultColor("CC:Silence", 1, 0.5, 0.04) + self:SetDefaultColor("CC:Root", .1, 0.5, 1) self.debuffList = {} self:PopulateSpellList(self.debuffList, StunCCList, "Stun") self:PopulateSpellList(self.debuffList, IncapacitateCCList, "Incapacitate") self:PopulateSpellList(self.debuffList, FearCCList, "Fear") + self:PopulateSpellList(self.debuffList, SilenceCCList, "Silence") + self:PopulateSpellList(self.debuffList, RootCCList, "Root") self.previousDebuff = nil self.previousDebuffTarget = nil diff --git a/modules/TargetInvuln.lua b/modules/TargetInvuln.lua new file mode 100644 index 0000000..93d79e4 --- /dev/null +++ b/modules/TargetInvuln.lua @@ -0,0 +1,246 @@ +local AceOO = AceLibrary("AceOO-2.0") + +-- needs to not be local so that we can inherit from it +TargetInvuln = AceOO.Class(IceUnitBar) + +TargetInvuln.prototype.buffName = nil +TargetInvuln.prototype.buffRemaining = 0 +TargetInvuln.prototype.buffDuration = 0 + +-- list of spell ID's for each CC type so we can avoid localization issues +local InvulnList= { + -- Anti-Magic Shell + 48707, + -- Hand of Protection + 10278, + -- Divine Shield + 642, + -- Deterrence + 19263, + -- Spell Reflection + 23920, + -- Ice Block + 45438, + -- Pain Suppression + 33206, + -- Cloak of Shadows + 31224, + -- Hand of Freedom + 1044, + -- Dispersion + 47585, + -- Bladestorm + 46924, + -- Grounding Totem Effect + 8178, + -- Aura Mastery + 31821, + -- Lichborne + 49039, + -- Killing Spree + 51690, +} + + + +-- Constructor -- +function TargetInvuln.prototype:init(moduleName, unit) + -- not sure if this is necessary...i think it is...this way, we can instantiate this bar on its own or as a parent class + if moduleName == nil or unit == nil then + TargetInvuln.super.prototype.init(self, "TargetInvuln", "target") + else + TargetInvuln.super.prototype.init(self, moduleName, unit) + end + + self.moduleSettings = {} + self.moduleSettings.desiredLerpTime = 0 +-- self.moduleSettings.shouldAnimate = false + + self:SetDefaultColor("CC:Invuln", 0.99, 0.99, 0.99) + + self.buffList = {} + self:PopulateSpellList(self.buffList, InvulnList,"Invuln") + + self.previousbuff = nil + self.previousbuffTarget = nil + self.previousbuffTime = nil +end + +-- grabs the list of CC's and pulls the localized spell name using the wow api +function TargetInvuln.prototype:PopulateSpellList(buffListVar, ccList, ccName) + local spellName + + for i=1,#ccList do + spellName = GetSpellInfo(ccList[i]) + + if spellName and spellName ~= "" then + buffListVar[spellName] = ccName + end + end +end + +-- 'Public' methods ----------------------------------------------------------- + +-- OVERRIDE +function TargetInvuln.prototype:Enable(core) + TargetInvuln.super.prototype.Enable(self, core) + + self:RegisterEvent("UNIT_AURA", "UpdateTargetBuffs") + self:RegisterEvent("PLAYER_TARGET_CHANGED", "UpdateTargetBuffs") + +-- self:ScheduleRepeatingEvent(self.elementName, self.UpdateTargetBuffs, 0.1, self) + + self:Show(false) +end + +function TargetInvuln.prototype:Disable(core) + TargetInvuln.super.prototype.Disable(self, core) + +-- self:CancelScheduledEvent(self.elementName) +end + +-- OVERRIDE +function TargetInvuln.prototype:GetDefaultSettings() + local settings = TargetInvuln.super.prototype.GetDefaultSettings(self) + + settings["enabled"] = false + settings["shouldAnimate"] = false + settings["desiredLerpTime"] = nil + settings["lowThreshold"] = 0 + settings["side"] = IceCore.Side.Left + settings["offset"] = 7 + settings["usesDogTagStrings"] = false + + return settings +end + +-- OVERRIDE +function TargetInvuln.prototype:GetOptions() + local opts = TargetInvuln.super.prototype.GetOptions(self) + + opts["shouldAnimate"] = nil + opts["desiredLerpTime"] = nil + opts["lowThreshold"] = nil + opts["textSettings"].args["upperTextString"] = nil + opts["textSettings"].args["lowerTextString"] = nil + + opts["alertParty"] = { + type = "toggle", + name = "Alert Party", + desc = "Broadcasts crowd control effects you apply to your target via the party chat channel", + get = function() + return self.moduleSettings.alertParty + end, + set = function(v) + self.moduleSettings.alertParty = v + end, + disabled = function() + return not self.moduleSettings.enabled + end, + } + + return opts +end + +-- 'Protected' methods -------------------------------------------------------- + +function TargetInvuln.prototype:GetMaxbuffDuration(unitName, buffNames) + local i = 1 + local buff, rank, texture, count, buffType, duration, endTime, unitCaster = UnitAura(unitName, i, "HELPFUL") + local isMine = unitCaster == "player" + local result = {nil, nil, nil} + local remaining + + while buff do + remaining = endTime - GetTime() + + + if (duration == 0) and (remaining<0) then + + duration =100000 + remaining =100000 + end + + if buffNames[buff] and (not self.moduleSettings.onlyShowForMybuffs or isMine) then + if result[0] then + if result[2] <= remaining then + result = {buff, duration, remaining} + end + else + result = {buff, duration, remaining} + end + end + + i = i + 1; + + buff, rank, texture, count, buffType, duration, endTime, unitCaster = UnitAura(unitName, i, "HELPFUL") + isMine = unitCaster == "player" + end + + return unpack(result) +end + +function TargetInvuln.prototype:UpdateTargetBuffs(unit, isUpdate) + local name, duration, remaining + if not isUpdate then + self.frame:SetScript("OnUpdate", function() self:UpdateTargetBuffs(self.unit, true) end) + self.buffName, self.buffDuration, self.buffRemaining = self:GetMaxbuffDuration(self.unit, self.buffList) + + else + self.buffRemaining = math.max(0, self.buffRemaining - (1.0 / GetFramerate())) + + if self.buffRemaining <= 0 then + self.buffName = nil + self.frame:SetScript("OnUpdate", nil) + end + end + + name = self.buffName + duration = self.buffDuration + remaining = self.buffRemaining + + + + local targetName = UnitName(self.unit) + + if (name ~= nil) and (self.previousbuff == nil) and (duration ~= nil) and (remaining ~= nil) then + if (duration > 1) and (self.moduleSettings.alertParty) and ((GetNumPartyMembers() >= 1) or (GetNumRaidMembers() >= 1)) then + SendChatMessage(targetName .. ": " .. name .. " (" .. tostring(floor(remaining * 10) / 10) .. "/" .. tostring(duration) .. "s)", "PARTY") + end + + self.previousbuff = name + self.previousbuffTarget = targetName + self.previousbuffTime = GetTime() + duration + -- Parnic: Force the CurrScale to 1 so that the lerping doesn't make it animate up and back down + self.CurrScale = 1.0 + elseif (self.previousbuff ~= nil) then + if (targetName ~= self.previousbuffTarget) then + self.previousbuff = nil + self.previousbuffTarget = nil + self.previousbuffTime = nil + elseif (GetTime() > self.previousbuffTime) then + self.previousbuff = nil + self.previousbuffTarget = nil + self.previousbuffTime = nil + end + end + + if (name ~= nil) then + self:Show(true) + + if (duration ~= nil and duration >= 0) then + self:UpdateBar(duration ~= 0 and remaining / duration or 0, "CC:" .. self.buffList[name]) + self:SetBottomText2(floor(remaining * 10) / 10) + else + self:UpdateBar(0, "CC:" .. self.buffList[name]) + self:SetBottomText2("") + end + + self:SetBottomText1(name) + else + self:Show(false) + end +end + +-- Load us up +IceHUD.TargetInvuln = TargetInvuln:new()