local MAJOR_VERSION = "LibHealComm-3.0"; |
local MINOR_VERSION = 90000 + tonumber(("$Revision: 48 $"):match("%d+")); |
|
local lib = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION); |
if not lib then return end |
|
local playerName = UnitName('player'); |
local playerRealm = GetRealmName(); |
local playerClass = select(2, UnitClass('player')); |
local isHealer = (playerClass == "PRIEST") or (playerClass == "SHAMAN") or (playerClass == "DRUID") or (playerClass == "PALADIN"); |
|
|
----------------- |
-- Event Frame -- |
----------------- |
|
lib.EventFrame = lib.EventFrame or CreateFrame("Frame"); |
lib.EventFrame:SetScript("OnEvent", function (this, event, ...) lib[event](lib, ...) end); |
lib.EventFrame:UnregisterAllEvents(); |
|
-- Register Events |
lib.EventFrame:RegisterEvent("PLAYER_ALIVE"); |
lib.EventFrame:RegisterEvent("LEARNED_SPELL_IN_TAB"); |
lib.EventFrame:RegisterEvent("CHAT_MSG_ADDON"); |
lib.EventFrame:RegisterEvent("UNIT_SPELLCAST_DELAYED"); |
lib.EventFrame:RegisterEvent("UNIT_AURA"); |
lib.EventFrame:RegisterEvent("UNIT_TARGET"); |
lib.EventFrame:RegisterEvent("PLAYER_TARGET_CHANGED"); |
lib.EventFrame:RegisterEvent("PLAYER_FOCUS_CHANGED"); |
lib.EventFrame:RegisterEvent("GLYPH_ADDED"); |
lib.EventFrame:RegisterEvent("GLYPH_REMOVED"); |
lib.EventFrame:RegisterEvent("GLYPH_UPDATED"); |
|
-- For keeping track of versions |
lib.EventFrame:RegisterEvent("PARTY_MEMBERS_CHANGED"); |
lib.EventFrame:RegisterEvent("RAID_ROSTER_UPDATE"); |
|
-- Prune data at zone change |
lib.EventFrame:RegisterEvent("PLAYER_ENTERING_WORLD"); |
|
-- Only listen to these events if player is healing class |
if (isHealer) then |
lib.EventFrame:RegisterEvent("UNIT_SPELLCAST_SENT"); |
lib.EventFrame:RegisterEvent("UNIT_SPELLCAST_START"); |
lib.EventFrame:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED"); |
lib.EventFrame:RegisterEvent("UNIT_SPELLCAST_STOP"); |
end |
|
|
---------------------- |
-- Scanning Tooltip -- |
---------------------- |
|
if (not lib.Tooltip) then |
lib.Tooltip = CreateFrame("GameTooltip"); |
lib.Tooltip:SetOwner(UIParent, "ANCHOR_NONE"); |
for i = 1, 4 do |
lib["TooltipTextLeft" .. i] = lib.Tooltip:CreateFontString(); |
lib["TooltipTextRight" .. i] = lib.Tooltip:CreateFontString(); |
lib.Tooltip:AddFontStrings(lib["TooltipTextLeft" .. i], lib["TooltipTextRight" .. i]); |
end |
end |
|
|
------------------------------- |
-- Embed CallbackHandler-1.0 -- |
------------------------------- |
|
lib.Callbacks = LibStub("CallbackHandler-1.0"):New(lib); |
|
|
----------------- |
-- Static Data -- |
----------------- |
|
-- Cache of spells and heal sizes |
local SpellCache = {}; |
|
-- Cache of glyphs |
local GlyphCache = {}; |
|
-- Info about spells being cast by other players |
local HealTime = {}; |
local HealTarget = {}; |
local HealSize = {}; |
|
-- Healing Modifiers (by name) |
local HealModifier = {}; |
|
-- Last target name from UNIT_SPELLCAST_SENT |
local SentTargetName; |
|
-- Last spellCastIndex from UNIT_SPELLCAST_STOP |
local LastSpellCastIndex; |
|
-- Info about the spell being cast by the player |
local CastInfoIsCasting; |
local CastInfoHealingTargetUnitID; |
local CastInfoHealingTargetNames; |
local CastInfoHealingSize; |
local CastInfoEndTime; |
|
-- Latency Measurement |
local SentTime = 0; |
local Latency = 0; |
|
-- Version Information Table |
local Versions = {}; |
|
-- Battleground/Arena/Group Indicators |
local InBattlegroundOrArena; |
local InRaidOrParty; |
|
|
--------------------------------- |
-- Frequently Accessed Globals -- |
--------------------------------- |
|
local type = type; |
local tonumber = tonumber; |
local math = math; |
local string = string; |
local select = select; |
local pairs = pairs; |
local unpack = unpack; |
local UnitName = UnitName; |
local SendAddonMessage = SendAddonMessage; |
local IsInInstance = IsInInstance; |
local UnitBuff = UnitBuff; |
local UnitDebuff = UnitDebuff; |
local UnitLevel = UnitLevel; |
local GetInventoryItemLink = GetInventoryItemLink; |
local GetTime = GetTime; |
local UnitCastingInfo = UnitCastingInfo; |
local GetSpellBonusHealing = GetSpellBonusHealing; |
local GetTalentInfo = GetTalentInfo; |
local UnitExists = UnitExists; |
local tinsert = table.insert; |
local tconcat = table.concat; |
|
|
--------------- |
-- Utilities -- |
--------------- |
|
local function unitFullName(unit) |
local name, realm = UnitName(unit); |
if (realm and realm ~= "") then |
return name .. "-" .. realm; |
else |
return name; |
end |
end |
|
local function extractRealm(fullName) |
return fullName:match("^[^%-]+%-(.+)$"); |
end |
|
-- Convert a remotely generated fully qualified name to |
-- a local fully qualified name. |
local function convertRealm(fullName, remoteRealm) |
if (remoteRealm) then |
local name, realm = fullName:match("^([^%-]+)%-(.+)$"); |
if (not realm) then |
-- Apply remote realm if there is no realm on the target |
return fullName .. "-" .. remoteRealm; |
elseif (realm == playerRealm) then |
-- Strip realm if it is equal to the local realm |
return name; |
end |
end |
return fullName; |
end |
|
local function commSend(contents, distribution, target) |
SendAddonMessage("HealComm", contents, distribution or (InBattlegroundOrArena and "BATTLEGROUND" or "RAID"), target); |
end |
|
-- Spellbook Scanner -- |
local function getBaseHealSize(name) |
|
-- Check if info is already cached |
if (SpellCache[name]) then |
return SpellCache[name]; |
end |
|
SpellCache[name] = {}; |
|
-- Gather info (only done if not in cache) |
local i = 1; |
|
while true do |
|
local spellName, spellRank = GetSpellName(i, BOOKTYPE_SPELL); |
|
if (not spellName) then |
break |
end |
|
if (spellName == name) then |
-- This is the spell we're looking for, gather info |
|
-- Determine rank |
spellRank = tonumber(spellRank:match("(%d+)")); |
lib.Tooltip:SetSpell(i, BOOKTYPE_SPELL); |
|
-- Determine healing |
local HealMin, HealMax = select(3, string.find(lib.TooltipTextLeft4:GetText() or lib.TooltipTextLeft3:GetText() or "", "(%d+) ?[\195\160tobisa到~\-]+ ?(%d+)")); |
HealMin, HealMax = tonumber(HealMin) or 0, tonumber(HealMax) or 0; |
local Heal = (HealMin + HealMax) / 2; |
|
SpellCache[spellName][spellRank] = Heal; |
end |
i = i + 1; |
end |
|
return SpellCache[name]; |
end |
|
local function detectGlyph(id) |
|
-- Check if info is already cached |
if (GlyphCache[id] ~= nil) then |
return GlyphCache[id]; |
end |
|
GlyphCache[id] = false; |
|
-- Gather info (only done if not in cache) |
for i = 1, GetNumGlyphSockets() do |
local enabled, _, glyphId = GetGlyphSocketInfo(i); |
if (enabled and glyphId) then |
GlyphCache[glyphId] = true; |
end |
end |
|
return GlyphCache[id]; |
end |
|
-- Detects if a buff is present on the unit and returns the application number. |
-- Optionally, if the third argument is provided and is true, then only return |
-- true if the buff was placed by the player. |
local function detectBuff(unit, buffName, mineOnly) |
local name, _, _, count, _, _, _, isMine = UnitBuff(unit, buffName); |
return name and (not mineOnly or isMine) and count or false; |
end |
|
--[[ |
[GetSpellInfo(604)] = -20, -- Dampen Magic (Rank 1) |
[GetSpellInfo(8450)] = -40, -- Dampen Magic (Rank 2) |
[GetSpellInfo(8451)] = -80, -- Dampen Magic (Rank 3) |
[GetSpellInfo(10173)] = -120, -- Dampen Magic (Rank 4) |
[GetSpellInfo(10174)] = -180, -- Dampen Magic (Rank 5) |
[GetSpellInfo(33944)] = -240, -- Dampen Magic (Rank 6) |
[GetSpellInfo(1008)] = 30, -- Amplify Magic (Rank 1) |
[GetSpellInfo(8455)] = 60, -- Amplify Magic (Rank 2) |
[GetSpellInfo(10169)] = 100, -- Amplify Magic (Rank 3) |
[GetSpellInfo(10170)] = 150, -- Amplify Magic (Rank 4) |
[GetSpellInfo(27130)] = 180, -- Amplify Magic (Rank 5) |
[GetSpellInfo(33946)] = 240, -- Amplify Magic (Rank 6) |
[GetSpellInfo(32858)] = -345 -- Touch of the Forgotten (Auchenai Crypts) |
[GetSpellInfo(38377)] = -690 -- Touch of the Forgotten (Auchenai Crypts) |
]]-- |
|
local healingBuffs = |
{ |
[GetSpellInfo(706)] = 1.20, -- Demon Armor |
[GetSpellInfo(45234)] = function (count, rank) return (1.0 + (0.04 + 0.03 * (rank - 1)) * count) end, -- Focused Will |
[GetSpellInfo(34123)] = 1.06, -- Tree of Life |
[GetSpellInfo(58549)] = function (count, rank, texture) return ((texture == "Interface\\Icons\\Ability_Warrior_StrengthOfArms") and (1.18 ^ count) or 1.0) end, -- Tenacity (Wintergrasp) |
} |
|
local healingDebuffs = |
{ |
[GetSpellInfo(25646)] = function (count) return (1.0 - count * 0.10) end, -- Mortal Wound (Temporus - The Black Morass) |
[GetSpellInfo(45347)] = function (count) return (1.0 - count * 0.04) end, -- Dark Touched (Grand Warlock Alythess - Sunwell Plateau) |
[GetSpellInfo(30423)] = function (count) return (1.0 - count * 0.01) end, -- Nether Portal - Dominance (Netherspite - Karazhan) |
[GetSpellInfo(13218)] = function (count) return (1.0 - count * 0.10) end, -- Wound Poison |
[GetSpellInfo(19434)] = 0.50, -- Aimed Shot |
[GetSpellInfo(12294)] = 0.50, -- Mortal Strike |
[GetSpellInfo(40599)] = 0.50, -- Arcing Smash (Gurtogg Bloodboil) |
[GetSpellInfo(23169)] = 0.50, -- Brood Affliction: Green (Chromaggus) |
[GetSpellInfo(34073)] = 0.85, -- Curse of the Bleeding Hollow (Hellfire Peninsula) |
[GetSpellInfo(13583)] = 0.50, -- Curse of the Deadwood (Deadwood Furbolgs - Felwood) |
[GetSpellInfo(36023)] = 0.50, -- Deathblow |
[GetSpellInfo(34625)] = 0.25, -- Demolish (Negatron - Netherstorm) |
[GetSpellInfo(34366)] = 0.75, -- Ebon Poison (Black Morass) |
[GetSpellInfo(32378)] = 0.50, -- Filet (Spectral Chef - Karazhan) |
[GetSpellInfo(19716)] = 0.25, -- Gehennas' Curse (Gehennas - Molten Core) |
[GetSpellInfo(36917)] = 0.50, -- Magma-Thrower's Curse (Sulfuron Magma-Thrower - The Arcatraz) |
[GetSpellInfo(22859)] = 0.50, -- Mortal Cleave (High Priestess Thekal - Zul'Gurub) |
[GetSpellInfo(38572)] = 0.50, -- Mortal Cleave (High Priestess Thekal - Zul'Gurub) |
[GetSpellInfo(39595)] = 0.50, -- Mortal Cleave (High Priestess Thekal - Zul'Gurub) |
[GetSpellInfo(28776)] = 0.10, -- Necrotic Poison (Maexxna - Naxxramas) |
[GetSpellInfo(35189)] = 0.50, -- Solar Strike (The Mechanar) |
[GetSpellInfo(32315)] = 0.50, -- Soul Strike (Ethereal Crypt Raiders - Mana-Tombs) |
[GetSpellInfo(7068)] = 0.25, -- Veil of Shadow (Nefarian - Blackwing Lair) |
[GetSpellInfo(38387)] = 1.50, -- Bane of Infinity (CoT: Escape from Durholde) |
[GetSpellInfo(31977)] = 1.50, -- Curse of Infinity (CoT: Escape from Durholde) |
[GetSpellInfo(41292)] = 0.00, -- Aura of Suffering (Essence of Souls - Black Temple) |
[GetSpellInfo(41350)] = 2.00, -- Aura of Desire (Essence of Souls - Black Temple) |
[GetSpellInfo(30843)] = 0.00, -- Enfeeble (Prince Malchezaar - Karazhan) |
} |
|
local function calculateHealModifier(unit) |
local modifier = 1.0; |
|
for i = 1, 40 do |
local name, rank, texture, count = UnitDebuff(unit, i); |
if (not name) then |
break; |
end |
local mark = healingDebuffs[name]; |
if (mark) then |
if (type(mark) == "function") then |
mark = mark(count); |
end |
if (mark < modifier) then |
modifier = mark; |
end |
end |
end |
for i = 1, 40 do |
local name, rank, texture, count = UnitBuff(unit, i); |
if (not name) then |
break; |
end |
local mark = healingBuffs[name]; |
if (mark) then |
if (type(mark) == "function") then |
mark = mark(count, rank and tonumber(rank:match("(%d+)")), texture); |
end |
modifier = modifier * mark; |
end |
end |
|
return modifier; |
end |
|
local function getDownrankingFactor(spellLevel, playerLevel) |
local factor = 0.05 * ((spellLevel + 7) - playerLevel) + 1; |
if (factor > 1.0) then |
return 1; |
elseif (factor < 0.0) then |
return 0; |
else |
return factor; |
end |
end |
|
local relicSlotNumber = GetInventorySlotInfo("RangedSlot"); |
local function getEquippedRelicID() |
local itemLink = GetInventoryItemLink('player', relicSlotNumber); |
if (itemLink) then |
return tonumber(itemLink:match("(%d+):")); |
end |
end |
|
|
----------------------------- |
-- Healing Data Management -- |
----------------------------- |
|
local function entryDelete(healerName) |
local targetNames = HealTarget[healerName]; |
HealTime[healerName] = nil; |
HealTarget[healerName] = nil; |
if (type(targetNames) == "table") then |
for i, targetName in pairs(targetNames) do |
if HealSize[targetName] then |
HealSize[targetName][healerName] = nil; |
end |
end |
elseif (targetNames and HealSize[targetNames]) then |
HealSize[targetNames][healerName] = nil; |
end |
end |
|
local function entryUpdate(healerName, targetNames, healSize, healTime) |
entryDelete(healerName); |
HealTime[healerName] = healTime; |
HealTarget[healerName] = targetNames; |
if (type(targetNames) == "table") then |
for i, targetName in pairs(targetNames) do |
if (not HealSize[targetName]) then |
HealSize[targetName] = {}; |
end |
HealSize[targetName][healerName] = healSize; |
end |
elseif (targetNames) then |
if (not HealSize[targetNames]) then |
HealSize[targetNames] = {}; |
end |
HealSize[targetNames][healerName] = healSize; |
end |
end |
|
local function entryRetrieve(healerName) |
local healTime = HealTime[healerName]; |
if (healTime) then |
local targetNames = HealTarget[healerName]; |
if (type(targetNames) == "table") then |
return targetNames, HealSize[targetNames[1]][healerName], healTime; |
elseif (targetNames) then |
return targetNames, HealSize[targetNames][healerName], healTime; |
end |
end |
end |
|
|
---------------------- |
-- Public Functions -- |
---------------------- |
|
--[[ UnitIncomingHealGet(unit, time) |
|
Description: Retrieve info about the incoming heals to a specific |
target. The second argument specifies a boundary time, |
relative to the current time. Examples: |
|
UnitIncomingHealGet("Kaki", GetTime() + 3) |
UnitIncomingHealGet("Kaki-Emerald Dream", GetTime() + 3) |
UnitIncomingHealGet("player", GetTime() + 3) |
UnitIncomingHealGet("raid10", GetTime() + 3) |
UnitIncomingHealGet("target", GetTime() + 3) |
|
Retrieves info about the incoming heals on the specified |
target. incomingHealBefore will contain the sum of heals |
that will land within the next 3 seconds, and |
incomingHealAfter will contain the sum of heals that will |
land after 3 seconds. |
|
Input: |
unit - The exact name or UnitID of the unit to retrieve information about. |
time - the desired boundary time of the inquiry. |
|
Output: |
incomingHealBefore - The total size of the incoming heals before the boundary time. |
incomingHealAfter - The total size of the incoming heals after the boundary time. |
nextTime - the time left until the next incoming heal will land. |
nextSize - the size of the next incoming heal. |
nextName - the name of the healer casting the next incoming heal. |
|
]]-- |
|
function lib:UnitIncomingHealGet(unit, time) |
if (type(unit) ~= "string") then return end |
if (type(time) ~= "number") then return end |
|
local targetName = unitFullName(unit); |
if (HealSize[targetName]) then |
local now = GetTime(); |
local incomingHealBefore, incomingHealAfter = 0, 0; |
local nextTime, nextSize, nextName; |
for healerName, size in pairs(HealSize[targetName]) do |
local healTime = HealTime[healerName]; |
if (size and healTime) then |
healTime = healTime + Latency; |
if (healTime > now) then |
if (healTime < time) then |
-- Due before boundary time |
incomingHealBefore = incomingHealBefore + size; |
else |
-- Due after boundary time |
incomingHealAfter = incomingHealAfter + size; |
end |
if ((not nextTime) or (healTime < nextTime)) then |
nextTime = healTime; |
nextSize = size; |
nextName = healerName; |
end |
end |
end |
end |
if ((incomingHealBefore > 0) or (incomingHealAfter > 0)) then |
return incomingHealBefore, incomingHealAfter, nextTime, nextSize, nextName; |
end |
end |
end |
|
--[[ UnitCastingHealGet(unit) |
|
Description: Retrieve info about the direct healing spell |
currently being cast by any unit. Examples: |
|
UnitCastingHealGet("Kaki"); |
UnitCastingHealGet("Kaki-Emerald Dream"); |
UnitCastingHealGet("player") |
UnitCastingHealGet("raid10") |
UnitCastingHealGet("target") |
|
Input: |
unit - The name or UnitID of the unit to retrieve information about. |
|
Output: |
healSize - Size of the healing being cast. |
endTime - The time when the healing completes. |
targetName - Name of the unit(s) being targeted for heal. |
|
]]-- |
|
function lib:UnitCastingHealGet(unit) |
if (type(unit) ~= "string") then return end |
local healerName = unitFullName(unit); |
|
if (healerName == playerName) then |
if (CastInfoIsCasting) then |
return CastInfoHealingSize, CastInfoEndTime, CastInfoHealingTargetNames; |
end |
else |
local targetNames, healSize, endTime = entryRetrieve(healerName); |
if (targetNames) then |
return healSize, endTime, targetNames; |
end |
end |
end |
|
--[[ UnitHealModifierGet(unit) |
|
Description: Returns the modifier to healing (as a factor) |
caused by buffs and debuffs. Examples: |
|
UnitHealModifierGet("Kaki"); |
UnitHealModifierGet("Kaki-Emerald Dream"); |
UnitHealModifierGet("player", 3) |
UnitHealModifierGet("raid10", 3) |
UnitHealModifierGet("target", 3) |
|
Input: |
unit - The name or UnitID of the unit to retrieve information about. |
|
Output: |
factor - Always a fractional number - will be 1.0 if no buffs/debuffs |
affect healing. |
|
]]-- |
|
function lib:UnitHealModifierGet(unit) |
if (type(unit) ~= "string") then return end |
|
local targetName = unitFullName(unit); |
return HealModifier[targetName] or calculateHealModifier(unit); |
end |
|
|
function lib:GetRaidOrPartyVersions() |
local tab = {}; |
|
if (GetNumRaidMembers() > 0) then |
for i = 1, GetNumRaidMembers() do |
local name = unitFullName('raid' .. i); |
if (not (name == playerName)) then |
tab[name] = Versions[name] or false; |
end |
end |
elseif (GetNumPartyMembers() > 0) then |
for i = 1, GetNumPartyMembers() do |
local name = unitFullName('party' .. i); |
tab[name] = Versions[name] or false; |
end |
end |
|
tab[playerName] = MINOR_VERSION; |
|
return tab; |
end |
|
function lib:GetGuildVersions() |
local tab = {}; |
|
if (IsInGuild()) then |
GuildRoster(); |
|
for i = 1, GetNumGuildMembers(false) do |
local name, rank, rankIndex, level, class, zone, note, officernote, online, status = GetGuildRosterInfo(i); |
if (online and not (name == playerName)) then |
tab[name] = Versions[name] or false; |
end |
end |
end |
|
tab[playerName] = MINOR_VERSION; |
|
return tab; |
end |
|
function lib:GetUnitVersion(unit) |
if (type(unit) ~= "string") then return end |
|
local targetName = unitFullName(unit); |
if (targetName == playerName) then return MINOR_VERSION end |
return Versions[targetName] or false; |
end |
|
|
-------------------- |
-- Class Specific -- |
-------------------- |
|
local HealingSpells; |
--local HotSpells; |
local GetHealSize; |
|
-- Druid -- |
|
-- TODO: |
-- Talent: Empowered Rejuvenation. Increase effect of all HOTs by 4%-20% |
-- Idol: Idol of Rejuvenation |
|
if (playerClass == "DRUID") then |
|
local tHealingTouch = GetSpellInfo(5185); |
local tRegrowth = GetSpellInfo(8936); |
local tNourish = GetSpellInfo(50464); |
local tRejuvenation = GetSpellInfo(774); |
local tLifebloom = GetSpellInfo(33763); |
local tWildGrowth = GetSpellInfo(48438); |
|
--[[HotSpells = |
{ |
[tRegrowth] = |
{ |
Level = {17, 23, 29, 35, 41, 47, 53, 59, 65, 70, 76, 80}, |
Duration = 21, |
Ticks = 7, |
Pattern = "(%d+)[^0-9]+%d+[^0-9]+$", |
Type = "HoT", |
}, |
[tRejuvenation] = |
{ |
Level = {9, 15, 21, 27, 33, 39, 45, 51, 57, 59, 62, 68, 74, 79, 80}, |
Duration = 12, |
Ticks = 4, |
Pattern = "(%d+)", |
Type = "HoT", |
}, |
[tLifebloom] = |
{ |
Level = {71, 79, 80}, |
Duration = 7, |
Ticks = 7, |
Pattern = "(%d+)" |
Type = "Lifebloom", |
}, |
}]]-- |
|
HealingSpells = |
{ |
[tHealingTouch] = |
{ |
Level = {1, 8, 14, 20, 26, 32, 38, 44, 50, 56, 60, 62, 69, 74, 79}, |
Type = "Direct", |
}, |
[tRegrowth] = |
{ |
Level = {12, 18, 24, 30, 36, 42, 48, 54, 60, 65, 71, 77}, |
Type = "Direct", |
}, |
[tNourish] = |
{ |
Level = {80}; |
Type = "Direct", |
} |
} |
|
local idolsHealingTouch = |
{ |
[28568] = 136, -- Idol of the Avian Heart |
[22399] = 100, -- Idol of Health |
} |
|
GetHealSize = function(name, rank, target) |
local i, effectiveHeal; |
|
-- Get static spell info |
local baseHealSize = getBaseHealSize(name)[rank]; |
local nBonus = 0; |
local effectiveHealModifier = 1.0; |
|
if (not baseHealSize) then |
return nil; |
end |
|
-- Get +healing bonus |
local bonus = GetSpellBonusHealing(); |
|
local spellTab = HealingSpells[name]; |
|
-- Gift of Nature Talent - Increases effective healing by 2% per rank on all spells |
effectiveHealModifier = effectiveHealModifier * (2 * select(5, GetTalentInfo(3, 13)) / 100 + 1); |
|
-- Process individual spells |
if (name == tHealingTouch) then |
local idolBonus = idolsHealingTouch[getEquippedRelicID()] or 0; |
baseHealSize = baseHealSize + idolBonus; |
|
-- Glyph of Healing Touch (decreases amount healed by 50%) |
if (detectGlyph(54825)) then |
effectiveHealModifier = effectiveHealModifier * 0.5 |
end |
|
-- Empowered Touch Talent (increases bonus healing effects by 20% per rank) |
local talentEmpoweredTouch = 20 * select(5, GetTalentInfo(3, 15)) / 100; |
|
if (rank < 5) then |
nBonus = bonus * (1.88 * (1.0 + rank * 0.5) / 3.5 + talentEmpoweredTouch); |
else |
nBonus = bonus * (1.88 + talentEmpoweredTouch); |
end |
elseif (name == tRegrowth) then |
-- Glyph of Regrowth (increases effective healing by 20% if player's Regrowth is on target) |
if (detectGlyph(54743) and detectBuff(target, tRegrowth, true)) then |
effectiveHealModifier = effectiveHealModifier * 1.2; |
end |
nBonus = bonus * 1.88 * (2.0 / 3.5) * 0.5; |
elseif (name == tNourish) then |
-- Nourish heals for 20% more if player's HoT is on the target. |
if (detectBuff(target, tRejuvenation, true) or detectBuff(target, tRegrowth, true) or detectBuff(target, tLifebloom, true) or detectBuff(target, tWildGrowth, true)) then |
effectiveHealModifier = effectiveHealModifier * 1.2 |
end |
nBonus = bonus * 1.88 * (1.5 / 3.5); |
end |
|
effectiveHeal = effectiveHealModifier * (baseHealSize + nBonus * getDownrankingFactor(spellTab.Level[rank], UnitLevel('player'))); |
return effectiveHeal; |
end |
|
end |
|
-- Paladin -- |
-- TODO: Track Beacon of Light (GetSpellInfo(53563) for name). |
if (playerClass == "PALADIN") then |
|
local tHolyLight = GetSpellInfo(635); |
local tFlashOfLight = GetSpellInfo(19750); |
local tDivineFavor = GetSpellInfo(20216); |
local tSealOfLight = GetSpellInfo(20167); |
local tAvengingWrath = GetSpellInfo(31884); |
local tDivinePlea = GetSpellInfo(54428); |
|
HealingSpells = |
{ |
[tHolyLight] = |
{ |
Level = {1, 6, 14, 22, 30, 38, 46, 54, 60, 62, 70, 75, 80}, |
Type = "Direct", |
}, |
[tFlashOfLight] = |
{ |
Level = {20, 26, 34, 42, 50, 58, 66, 74, 79}, |
Type = "Direct", |
}, |
} |
|
local libramsFlashOfLight = |
{ |
[42614] = 267, -- Deadly Gladiator's Libram of Justice |
[42613] = 236, -- Hateful Gladiator's Libram of Justice |
[42612] = 204, -- Savage Gladiator's Libram of Justice |
[28592] = 89, -- Libram of Souls Redeemed (TODO: may be changed to affect Holy Light in 3.0.3) |
[25644] = 79, -- Blessed Book of Nagrand |
[23006] = 43, -- Libram of Light |
[23201] = 28, -- Libram of Divinity |
} |
|
local libramsHolyLight = |
{ |
[40268] = 141, -- Libram of Tolerance |
[28296] = 47, -- Libram of the Lightbringer |
} |
|
GetHealSize = function(name, rank, target) |
local i, effectiveHeal; |
|
-- Get static spell info |
local baseHealSize = getBaseHealSize(name)[rank]; |
local nBonus = 0; |
local effectiveHealModifier = 1.0; |
|
if (not baseHealSize) then |
return nil; |
end |
|
-- Get +healing bonus |
local bonus = GetSpellBonusHealing(); |
|
local spellTab = HealingSpells[name]; |
|
-- Divine Favor (100% crit chance on heal spell) |
if (detectBuff('player', tDivineFavor)) then |
effectiveHealModifier = effectiveHealModifier * 1.5; |
end |
|
-- Avenging Wrath (increase all healing by 20%) |
if (detectBuff('player', tAvengingWrath)) then |
effectiveHealModifier = effectiveHealModifier * 1.2; |
end |
|
-- Divine Plea (decrease all healing by 50%) |
if (detectBuff('player', tDivinePlea)) then |
effectiveHealModifier = effectiveHealModifier * 0.5; |
end |
|
-- Glyph of Seal of Light (increases healing by 5% if Seal of Light is active) |
if (detectGlyph(54943) and detectBuff('player', tSealOfLight)) then |
effectiveHealModifier = effectiveHealModifier * 1.05; |
end |
|
-- Healing Light - Increases healing by 4% per rank on all spells |
effectiveHealModifier = effectiveHealModifier * (4 * select(5, GetTalentInfo(1, 3)) / 100 + 1); |
|
-- Process individual spells |
if (name == tFlashOfLight) then |
local libramBonus = libramsFlashOfLight[getEquippedRelicID()] or 0; |
nBonus = (bonus + libramBonus) * 1.88 * (1.5 / 3.5) * 1.25; |
elseif (name == tHolyLight) then |
local libramBonus = libramsHolyLight[getEquippedRelicID()] or 0; |
nBonus = (bonus + libramBonus) * 1.88 * (2.5 / 3.5) * 1.25; |
end |
|
effectiveHeal = effectiveHealModifier * (baseHealSize + nBonus * getDownrankingFactor(spellTab.Level[rank], UnitLevel('player'))); |
return effectiveHeal; |
end |
|
end |
|
-- Priest -- |
|
-- TODO: Talent: Improved Renew: increases renew by 5%-10%-15% |
-- Healing_Done = (Renew_Base + (Healbonus * Downrankfactor) ) * Improved_Renew * Spiritual_Healing |
if (playerClass == "PRIEST") then |
|
local tLesserHeal = GetSpellInfo(2050); |
local tHeal = GetSpellInfo(2054); |
local tGreaterHeal = GetSpellInfo(2060); |
local tFlashHeal = GetSpellInfo(2061); |
local tBindingHeal = GetSpellInfo(32546); |
local tPrayerOfHealing = GetSpellInfo(596); |
local tPowerWordFortitude = GetSpellInfo(1243); |
--local tRenew = GetSpellInfo(139); |
local tGrace = GetSpellInfo(47930); |
|
--[[HotSpells = |
{ |
[tRenew] = |
{ |
Level = {8, 14, 20, 26, 32, 38, 44, 50, 56, 60, 65, 74, 79, 80}, |
Duration = 15, |
Ticks = 5, |
Pattern = "(%d+)", |
Type = "HoT", |
}, |
}]]-- |
|
HealingSpells = |
{ |
[tLesserHeal] = |
{ |
Level = {1, 4, 10}, |
Type = "Direct" |
}, |
[tHeal] = |
{ |
Level = {16, 22, 28, 34}, |
Type = "Direct" |
}, |
[tGreaterHeal] = |
{ |
Level = {40, 46, 52, 58, 60, 63, 68, 73, 78}, |
Type = "Direct", |
}, |
[tFlashHeal] = |
{ |
Level = {20, 26, 32, 38, 44, 50, 56, 61, 67, 73, 79}, |
Type = "Direct", |
}, |
[tBindingHeal] = |
{ |
Level = {64, 72, 78}, |
Type = "Binding" |
}, |
[tPrayerOfHealing] = |
{ |
Level = {30, 40, 50, 60, 60, 68, 76}, |
Type = "Party", |
InRange = function(unit) return IsSpellInRange(tPowerWordFortitude, unit) == 1 end |
}, |
} |
|
GetHealSize = function(name, rank, target) |
local i, effectiveHeal; |
|
-- Get static spell info |
local baseHealSize = getBaseHealSize(name)[rank]; |
local nBonus = 0; |
local effectiveHealModifier = 1.0; |
|
if (not baseHealSize) then |
return nil; |
end |
|
-- Get +healing bonus |
local bonus = GetSpellBonusHealing(); |
|
local spellTab = HealingSpells[name]; |
|
-- Focused Power - Increases healing by 2% per rank on all spells |
effectiveHealModifier = effectiveHealModifier * (2 * select(5, GetTalentInfo(1, 16)) / 100 + 1); |
|
-- Spiritual Healing - Increases healing by 2% per rank on all spells |
effectiveHealModifier = effectiveHealModifier * (2 * select(5, GetTalentInfo(2, 16)) / 100 + 1); |
|
-- Grace (increases healing by 2% per application on target if buff was placed by the player) |
if (target) then |
local grace = detectBuff(target, tGrace, true); |
if (grace) then |
effectiveHealModifier = effectiveHealModifier * (1.0 + 0.02 * grace); |
end |
end |
|
-- Process individual spells |
if (name == tLesserHeal) then |
nBonus = bonus * 1.88 * (1.0 + rank * 0.5) / 3.5; |
elseif (name == tHeal) then |
nBonus = bonus * 1.88 * (3.0 / 3.5); |
elseif (name == tGreaterHeal) then |
local empoweredHealing = 8 * select(5, GetTalentInfo(2, 20)) / 100; |
nBonus = bonus * (1.88 * (3.0 / 3.5) + empoweredHealing); |
elseif (name == tFlashHeal) then |
local empoweredHealing = 4 * select(5, GetTalentInfo(2, 20)) / 100; |
nBonus = bonus * (1.88 * (1.5 / 3.5) + empoweredHealing); |
elseif (name == tBindingHeal) then |
local empoweredHealing = 4 * select(5, GetTalentInfo(2, 20)) / 100; |
nBonus = bonus * (1.88 * (1.5 / 3.5) + empoweredHealing); |
elseif (name == tPrayerOfHealing) then |
nBonus = bonus * 1.88 * (3.0 / 3.5) * 0.5; |
end |
|
effectiveHeal = effectiveHealModifier * (baseHealSize + nBonus * getDownrankingFactor(spellTab.Level[rank], UnitLevel('player'))); |
return effectiveHeal; |
end |
|
end |
|
-- Shaman -- |
-- TODO: Nature's Blessing (GetTalentInfo(3, 21)) is probably not accounted for automatically anymore (or is it?) |
-- TODO: Riptide 51point resto spell (instant cast regrowth (direct + hot)) |
-- TODO: Glyph of Healing Wave (binding heal, but self-heal is percentage of actual target healed) |
if (playerClass == "SHAMAN") then |
|
local tLesserHealingWave = GetSpellInfo(8004); |
local tHealingWave = GetSpellInfo(331); |
local tChainHeal = GetSpellInfo(1064); |
local tHealingWay = GetSpellInfo(29206); |
local tTidalWaves = GetSpellInfo(51562); |
local tRiptide = GetSpellInfo(61295); |
local tEarthShield = GetSpellInfo(974); |
|
--[[HotSpells = |
{ |
[tRiptide] = |
{ |
Level = {60, 70, 75, 80}, |
Duration = 15, |
Ticks = 5, |
Pattern = "(%d+)", |
Type = "HoT", |
}, |
}]]-- |
|
HealingSpells = |
{ |
[tLesserHealingWave] = |
{ |
Level = {20, 28, 36, 44, 52, 60, 66, 72, 77}, |
Type = "Direct", |
}, |
[tHealingWave] = |
{ |
Level = {1, 6, 12, 18, 24, 32, 40, 48, 56, 60, 63, 70, 75, 80}, |
Type = "Direct", |
}, |
[tChainHeal] = |
{ |
Level = {40, 46, 54, 61, 68, 74, 80}, |
Type = "Direct", |
}, |
} |
|
local totemsLesserHealingWave = |
{ |
[42597] = 267, -- Deadly Gladiator's Totem of the Third Wind |
[42596] = 236, -- Hateful Gladiator's Totem of the Third Wind |
[42595] = 204, -- Savage Gladiator's Totem of the Third Wind |
[25645] = 79, -- Totem of The Plains |
[22396] = 80, -- Totem of Life |
[23200] = 53, -- Totem of Sustaining |
} |
|
local totemsHealingWave = |
{ |
[27544] = 88, -- Totem of Spontaneous Regrowth |
} |
|
local totemsChainHeal = |
{ |
[38368] = 102, -- Totem of the Bay |
[28523] = 87, -- Totem of Healing Rains |
} |
|
GetHealSize = function(name, rank, target) |
local i, effectiveHeal; |
|
-- Get static spell info |
local baseHealSize = getBaseHealSize(name)[rank]; |
local nBonus = 0; |
local effectiveHealModifier = 1.0; |
|
if (not baseHealSize) then |
return nil; |
end |
|
-- Get +healing bonus |
local bonus = GetSpellBonusHealing(); |
|
-- Purification Talent (increases healing by 2% per rank). |
-- This is factored into effectiveHealModifier in the individual spell section below due to interaction with Improved Chain Heal. |
local talentPurification = 2 * select(5, GetTalentInfo(3, 15)) / 100 + 1; |
|
local spellTab = HealingSpells[name]; |
|
-- Process individual spells |
if (name == tLesserHealingWave) then |
local totemBonus = totemsLesserHealingWave[getEquippedRelicID()] or 0; |
effectiveHealModifier = effectiveHealModifier * talentPurification; |
|
-- Glyph of Lesser Healing Wave (increases effective healing by 20% if player's Earth Shield is on target) |
if (detectGlyph(55438) and detectBuff(target, tEarthShield, true)) then |
effectiveHealModifier = effectiveHealModifier * 1.2; |
end |
|
-- Tidal Waves Talent (increases bonus healing effects by 2% per rank) |
local talentTidalWaves = 2 * select(5, GetTalentInfo(3, 25)) / 100; |
|
nBonus = (bonus + totemBonus) * (1.88 * (1.5 / 3.5) + talentTidalWaves); |
elseif (name == tHealingWave) then |
local totemBonus = totemsHealingWave[getEquippedRelicID()] or 0; |
effectiveHealModifier = effectiveHealModifier * talentPurification; |
|
-- Healing Way Buff (target buff that increases effective healing by 18%) |
if (detectBuff(target, tHealingWay)) then |
effectiveHealModifier = effectiveHealModifier * 1.18; |
end; |
|
-- Tidal Waves Talent (increases bonus healing effects by 4% per rank) |
local talentTidalWaves = 4 * select(5, GetTalentInfo(3, 25)) / 100; |
|
-- Determine normalisation |
if (rank < 4) then |
nBonus = (bonus + totemBonus) * (1.88 * (1.0 + rank * 0.5) / 3.5 + talentTidalWaves); |
else |
nBonus = (bonus + totemBonus) * (1.88 * (3.0 / 3.5) + talentTidalWaves); |
end |
elseif (name == tChainHeal) then |
local totemBonus = totemsChainHeal[getEquippedRelicID()] or 0; |
baseHealSize = baseHealSize + totemBonus; |
|
-- Improved Chain Heal Talent (increases healing by 10% per rank) |
local talentImprovedChainHeal = 10 * select(5, GetTalentInfo(3, 20)) / 100; |
|
effectiveHealModifier = effectiveHealModifier * (talentPurification + talentImprovedChainHeal); |
|
-- Riptide Buff (target buff that increases effective healing by 25%) |
if (detectBuff(target, tRiptide, true)) then |
effectiveHealModifier = effectiveHealModifier * 1.25; |
end |
|
nBonus = bonus * 1.88 * (2.5 / 3.5); |
end |
|
effectiveHeal = effectiveHealModifier * (baseHealSize + nBonus * getDownrankingFactor(spellTab.Level[rank], UnitLevel('player'))); |
return effectiveHeal; |
end |
|
end |
|
|
-------------------- |
-- Event Handlers -- |
-------------------- |
|
function lib:PLAYER_FOCUS_CHANGED() |
if (UnitExists('focus')) then |
self:UNIT_AURA('focus'); |
end |
if (UnitExists('focustarget')) then |
self:UNIT_AURA('focustarget'); |
end |
end |
|
function lib:PLAYER_TARGET_CHANGED() |
if (UnitExists('target')) then |
self:UNIT_AURA('target'); |
end |
if (UnitExists('targettarget')) then |
self:UNIT_AURA('targettarget'); |
end |
end |
|
function lib:UNIT_TARGET(unit) |
if ((unit == 'target') or (unit == 'focus')) then |
local unitTarget = unit .. "target"; |
if (UnitExists(unitTarget)) then |
self:UNIT_AURA(unitTarget); |
end |
end |
end |
|
function lib:UNIT_AURA(unit) |
local targetName = unitFullName(unit); |
|
local oldModifier = HealModifier[targetName]; |
local newModifier = calculateHealModifier(unit); |
if (oldModifier) then |
if (newModifier == oldModifier) then |
return |
end |
else |
if (newModifier == 1.0) then |
return |
end |
end |
HealModifier[targetName] = newModifier; |
|
self.Callbacks:Fire("HealComm_HealModifierUpdate", unit, targetName, newModifier); |
end |
|
function lib:LEARNED_SPELL_IN_TAB() |
-- Invalidate cached spell data when learning new spells |
SpellCache = {}; |
end |
|
function lib:GLYPH_ADDED() |
-- Invalidate cached glyph data when updating glyphs |
GlyphCache = {}; |
end |
|
function lib:GLYPH_REMOVED() |
-- Invalidate cached glyph data when updating glyphs |
GlyphCache = {}; |
end |
|
function lib:GLYPH_UPDATED() |
-- Invalidate cached glyph data when updating glyphs |
GlyphCache = {}; |
end |
|
function lib:UNIT_SPELLCAST_SENT(unit, spellName, spellRank, targetName) |
if (unit ~= 'player') then return end |
|
-- Latency measurement |
SentTime = GetTime(); |
|
SentTargetName = targetName; |
end |
|
function lib:UNIT_SPELLCAST_START(unit, spellName, spellRank) |
if (unit ~= 'player') then return end |
|
-- Latency measurement |
local currentLatency = GetTime() - SentTime; |
if (currentLatency > 1) then -- Limit to 1 sec |
currentLatency = 1; |
end |
Latency = 0.5 * Latency + 0.70 * currentLatency; |
|
local spellInfo = HealingSpells[spellName]; |
|
-- Only process healing spells |
if (spellInfo) then |
if (spellInfo.Type == "Direct") then |
CastInfoHealingTargetNames = SentTargetName; |
CastInfoHealingSize = GetHealSize(spellName, tonumber(spellRank:match("(%d+)")), SentTargetName) or 0; |
CastInfoIsCasting = true; |
CastInfoEndTime = (select(6, UnitCastingInfo('player')) or 0) / 1000; |
self.Callbacks:Fire("HealComm_DirectHealStart", playerName, CastInfoHealingSize, CastInfoEndTime, SentTargetName); |
commSend(string.format("000%05d%s", math.min(CastInfoHealingSize, 99999), SentTargetName)); |
elseif (spellInfo.Type == "Binding") then |
CastInfoHealingTargetNames = {playerName, SentTargetName}; |
CastInfoHealingSize = GetHealSize(spellName, tonumber(spellRank:match("(%d+)")), SentTargetName) or 0; |
CastInfoIsCasting = true; |
CastInfoEndTime = (select(6, UnitCastingInfo('player')) or 0) / 1000; |
self.Callbacks:Fire("HealComm_DirectHealStart", playerName, CastInfoHealingSize, CastInfoEndTime, unpack(CastInfoHealingTargetNames)); |
commSend(string.format("002%05d%s", math.min(CastInfoHealingSize, 99999), SentTargetName)); |
elseif (spellInfo.Type == "Party") then |
CastInfoHealingTargetNames = {}; |
if (spellInfo.InRange('party1')) then tinsert(CastInfoHealingTargetNames, unitFullName('party1')) end |
if (spellInfo.InRange('party2')) then tinsert(CastInfoHealingTargetNames, unitFullName('party2')) end |
if (spellInfo.InRange('party3')) then tinsert(CastInfoHealingTargetNames, unitFullName('party3')) end |
if (spellInfo.InRange('party4')) then tinsert(CastInfoHealingTargetNames, unitFullName('party4')) end |
CastInfoHealingSize = GetHealSize(spellName, tonumber(spellRank:match("(%d+)"))) or 0; |
CastInfoIsCasting = true; |
CastInfoEndTime = (select(6, UnitCastingInfo('player')) or 0) / 1000; |
commSend(string.format("002%05d%s", math.min(CastInfoHealingSize, 99999), tconcat(CastInfoHealingTargetNames, ":"))); |
tinsert(CastInfoHealingTargetNames, 1, playerName); |
self.Callbacks:Fire("HealComm_DirectHealStart", playerName, CastInfoHealingSize, CastInfoEndTime, unpack(CastInfoHealingTargetNames)); |
end |
end |
end |
|
function lib:CHAT_MSG_ADDON(prefix, msg, distribution, sender) |
if (prefix ~= "HealComm") then return end |
if (sender == playerName) then return end |
|
-- Workaround: Sometimes in battlegrounds the sender argument is not a |
-- fully qualified name (the realm is missing), even though the sender is |
-- from a different realm. |
if (distribution == "BATTLEGROUND") then |
sender = unitFullName(sender) or sender; |
end |
|
-- Get message type |
local msgtype = tonumber(msg:sub(1, 3)); |
if (not msgtype) then return end |
|
if (msgtype == 0) then -- DirectHealStart |
local healSize = tonumber(msg:sub(4, 8)); |
local targetName = msg:sub(9, -1); |
|
if (healSize and targetName) then |
local endTime = select(6, UnitCastingInfo(sender)); |
|
if (endTime) then |
if (distribution == "BATTLEGROUND") then |
targetName = convertRealm(targetName, extractRealm(sender)); |
end |
endTime = endTime / 1000; |
entryUpdate(sender, targetName, healSize, endTime); |
self.Callbacks:Fire("HealComm_DirectHealStart", sender, healSize, endTime, targetName); |
end |
end |
elseif (msgtype == 1) then -- HealStop |
local targetNames, healSize = entryRetrieve(sender); |
entryDelete(sender); |
if (type(targetNames) == "table") then |
self.Callbacks:Fire("HealComm_DirectHealStop", sender, healSize, msg:sub(4, 4) == "S", unpack(targetNames)); |
elseif (targetNames) then |
self.Callbacks:Fire("HealComm_DirectHealStop", sender, healSize, msg:sub(4, 4) == "S", targetNames); |
end |
elseif (msgtype == 2) then -- MultiTargetHealStart |
local healSize = tonumber(msg:sub(4, 8)); |
local targetNames = {strsplit(":", msg:sub(9, -1))}; |
|
if (healSize) then |
local endTime = select(6, UnitCastingInfo(sender)); |
|
if (endTime) then |
if (distribution == "BATTLEGROUND") then |
local senderRealm = extractRealm(sender); |
for k, targetName in pairs(targetNames) do |
targetNames[k] = convertRealm(targetName, senderRealm); |
end |
end |
endTime = endTime / 1000; |
tinsert(targetNames, 1, sender); |
entryUpdate(sender, targetNames, healSize, endTime); |
self.Callbacks:Fire("HealComm_DirectHealStart", sender, healSize, endTime, unpack(targetNames)); |
end |
end |
elseif (msgtype >= 998) then -- AnnounceVersion |
local version = tonumber(msg:sub(4, -1)); |
if (version) then |
Versions[sender] = version; |
|
if (msgtype == 999) then -- RequestVersion |
if (distribution ~= "BATTLEGROUND") then |
-- Reply in whisper if possible |
commSend("998" .. tostring(MINOR_VERSION), "WHISPER", sender); |
else |
-- Reply to inbound distribution channel |
commSend("998" .. tostring(MINOR_VERSION), distribution); |
end |
end |
end |
end |
end |
|
function lib:UNIT_SPELLCAST_DELAYED(unit) |
if (unit == 'player') then |
if (CastInfoIsCasting) then |
local endTime = select(6, UnitCastingInfo('player')); |
if (endTime) then |
CastInfoEndTime = endTime / 1000; |
if (type(CastInfoHealingTargetNames) == "table") then |
self.Callbacks:Fire("HealComm_DirectHealDelayed", playerName, CastInfoHealingSize, CastInfoEndTime, unpack(CastInfoHealingTargetNames)); |
elseif (CastInfoHealingTargetNames) then |
self.Callbacks:Fire("HealComm_DirectHealDelayed", playerName, CastInfoHealingSize, CastInfoEndTime, CastInfoHealingTargetNames); |
end |
end |
end |
elseif (unit ~= 'target' and unit ~= 'focus') then |
local healerName = unitFullName(unit); |
local targetNames, healSize = entryRetrieve(healerName) |
if (targetNames) then |
local endTime = select(6, UnitCastingInfo(healerName)); |
if (endTime) then |
endTime = endTime / 1000; |
HealTime[healerName] = endTime; |
if (type(targetNames) == "table") then |
self.Callbacks:Fire("HealComm_DirectHealDelayed", healerName, healSize, endTime, unpack(targetNames)); |
elseif (targetNames) then |
self.Callbacks:Fire("HealComm_DirectHealDelayed", healerName, healSize, endTime, targetNames); |
end |
end |
end |
end |
end |
|
function lib:UNIT_SPELLCAST_SUCCEEDED(unit, spellName, spellRank, spellCastIndex) |
if (unit ~= 'player') then return end |
|
if (CastInfoIsCasting) then |
CastInfoIsCasting = false; |
commSend("001S"); |
|
if (type(CastInfoHealingTargetNames) == "table") then |
self.Callbacks:Fire("HealComm_DirectHealStop", playerName, CastInfoHealingSize, true, unpack(CastInfoHealingTargetNames)); |
elseif (CastInfoHealingTargetNames) then |
self.Callbacks:Fire("HealComm_DirectHealStop", playerName, CastInfoHealingSize, true, CastInfoHealingTargetNames); |
end |
else |
if (LastSpellCastIndex ~= spellCastIndex) then |
-- Instant Cast Spells |
end |
end |
end |
|
function lib:UNIT_SPELLCAST_STOP(unit, spellName, spellRank, spellCastIndex) |
if (unit == 'player' and CastInfoIsCasting) then |
LastSpellCastIndex = spellCastIndex; |
CastInfoIsCasting = false; |
commSend("001F"); |
if (type(CastInfoHealingTargetNames) == "table") then |
self.Callbacks:Fire("HealComm_DirectHealStop", playerName, CastInfoHealingSize, false, unpack(CastInfoHealingTargetNames)); |
elseif (CastInfoHealingTargetNames) then |
self.Callbacks:Fire("HealComm_DirectHealStop", playerName, CastInfoHealingSize, false, CastInfoHealingTargetNames); |
end |
end |
end |
|
function lib:PLAYER_ALIVE() |
-- This event is only fired at initial login, not at reloadui or load-on-demand loading. |
-- The initialisation is triggered again, since none of the initialisation had any effect |
-- prior to this event firing (no messages sent and InBattlegroundOrArena and InRaidOrParty |
-- are probably not correctly initialised). |
lib:Initialise(); |
|
-- Only receive once |
self.EventFrame:UnregisterEvent("PLAYER_ALIVE"); |
end |
|
function lib:PLAYER_ENTERING_WORLD() |
HealTime = {}; |
HealTarget = {}; |
HealSize = {}; |
HealModifier = {}; |
end |
|
function lib:PARTY_MEMBERS_CHANGED() |
local wasInRaidOrParty = InRaidOrParty; |
InRaidOrParty = (GetNumRaidMembers() > 0) or (GetNumPartyMembers() > 0); |
|
-- Announce and request version when joining a group |
if (not wasInRaidOrParty and InRaidOrParty) then |
commSend("999" .. tostring(MINOR_VERSION)); |
end |
end |
|
function lib:RAID_ROSTER_UPDATE() |
self:PARTY_MEMBERS_CHANGED(); |
end |
|
function lib:Initialise() |
local it = select(2, IsInInstance()); |
InBattlegroundOrArena = (it == "pvp") or (it == "arena"); |
|
InRaidOrParty = (GetNumRaidMembers() > 0) or (GetNumPartyMembers() > 0); |
|
-- Announce and request version in group and in guild |
commSend("999" .. tostring(MINOR_VERSION)); |
if (IsInGuild()) then |
commSend("999" .. tostring(MINOR_VERSION), "GUILD"); |
end |
end |
|
lib:Initialise(); |