local GridStatus = Grid:GetModule("GridStatus"); local GridRoster = Grid:GetModule("GridRoster"); local SmartHealing = GridStatus:GetModule("GridStatusSmartHealing"); local GridStatusSmartHealing_ChainHeal = SmartHealing:NewModule("GridStatusSmartHealing_ChainHeal", "AceEvent-3.0"); local CenterTextOptions = { bestTarget = "Best Target #", estimatedHeal = "Total Estimated Heal" }; GridStatusSmartHealing_ChainHeal.defaultDB = { enable = false, color = { r = 0, g = 0, b = 1, a = 1 }, priority = 50, -- minjumps = 2, color2 = { r = 0, g = 0.5, b = 1, a = 1 }, maxTargets = 25, centerTextOption = "bestTarget", } local options = { ["minjumps"] = { order = 100, type = "range", name = "Min Jumps", desc = "Threshold for a target to have, before it shows.", min = 0, max = 3, step = 1, width = "full", get = function() return GridStatusSmartHealing_ChainHeal.db.profile.minjumps; end, set = function(info, v) GridStatusSmartHealing_ChainHeal.db.profile.minjumps = v; GridStatusSmartHealing_ChainHeal:ClearAll(); GridStatusSmartHealing_ChainHeal:RefreshAll(); end }, ["color2"] = { order = 21, type = "color", name = "Color x2", desc = string.format("Color for Chain Heal x2", desc), hasAlpha = true, get = function() local color = GridStatusSmartHealing_ChainHeal.db.profile.color2; return color.r, color.g, color.b, color.a; end, set = function(info, r, g, b, a) local color = GridStatusSmartHealing_ChainHeal.db.profile.color2; color.r = r; color.g = g; color.b = b; color.a = a or 1; end, }, ["maxTargets"] = { order = 110, type = "range", name = "Max Status Targets", desc = "Max number of targets to show", min = 1, max = 40, step = 1, width = "full", get = function() return GridStatusSmartHealing_ChainHeal.db.profile.maxTargets; end, set = function(info, v) GridStatusSmartHealing_ChainHeal.db.profile.maxTargets = v; GridStatusSmartHealing_ChainHeal:ClearAll(); GridStatusSmartHealing_ChainHeal:RefreshAll(); end, }, ["centerTextOption"] = { order = 120, type = "select", name = "Center Text Option", desc = "What center text will display (if selected in indicators)", values = CenterTextOptions, style = "radio", get = function() return GridStatusSmartHealing_ChainHeal.db.profile.centerTextOption; end, set = function(info, v) GridStatusSmartHealing_ChainHeal.db.profile.centerTextOption = v; GridStatusSmartHealing_ChainHeal:ClearAll(); GridStatusSmartHealing_ChainHeal:RefreshAll(); end, } } local thisStatus = "alert_gssh_chainheal"; local chainHealGlyph = 55437; function GridStatusSmartHealing_ChainHeal:PostInitialize() SmartHealing:RegisterStatus(self, thisStatus, "Smart Healing - Chain Heal", options, false); Settings = self.db.profile; end function GridStatusSmartHealing_ChainHeal:OnStatusEnable(status) SmartHealing:DoEnable(); self.spellInfo = { healingPower = nil, crit = nil, --sparkOfLife = nil, restoSpec = nil, --chGlyph = false, coef = 1, }; self.chainHeal = { distance = 12.5^2, -- square yards -- non-talented coef = 0.3535, -- http://elitistjerks.com/f79/t121202-resto_raiding_4_1_updating_4_3_a/ base = 3515, -- added by UpdateCoefs jumps = {}, }; self:RegisterEvent('PLAYER_EQUIPMENT_CHANGED', 'UpdateCoefs'); self:RegisterEvent('PLAYER_TALENT_UPDATE', 'UpdateCoefs'); -- skip for now. --self:RegisterEvent('UNIT_AURA', 'UpdateAuraCoefs'); self:RefreshAll(); end function GridStatusSmartHealing_ChainHeal:OnStatusDisable(status) SmartHealing:DoDisable(); self:UnregisterEvent('PLAYER_EQUIPMENT_CHANGED'); self:UnregisterEvent('PLAYER_TALENT_UPDATE'); self:ClearAll(); end function GridStatusSmartHealing_ChainHeal:ClearAll() self.core:SendStatusLostAllUnits(thisStatus); end function GridStatusSmartHealing_ChainHeal:RefreshAll() self:UpdateCoefs(nil, nil); end function GridStatusSmartHealing_ChainHeal:Update() self:ClearAll(); -- all players missing health local deficits = {}; for guid, unitId in GridRoster:IterateRoster() do local info = SmartHealing:GetUnitInfo(guid); -- if info == nil, probably a pet. if (info ~= nil and unitId and info.missingHealth > 0 and SmartHealing:IsValidHealTarget(unitId)) then table.insert(deficits, info); end end -- sort highest missing health first table.sort(deficits, function(a, b) return a.missingHealth > b.missingHealth; end); -- Chain Heal Paths local paths = {}; local numDeficits = #deficits; self:Debug("NumDeficts", numDeficits); for i = 1, numDeficits do local curUnit = deficits[i]; --[[ local unitDistance = SmartHealing:Distance(SmartHealing.state, curUnit); if (UnitInRange(curUnit.unitId)) then end ]]-- -- TotalHeal that can be made curUnit.totalHeal = curUnit.missingHealth; curUnit.jumps = {}; -- targets are other units jumped to curUnit.targets = {}; -- TODO count for earth shield.. -- TODO count for riptide curUnit.jumps[1] = (self.chainHeal.jumps[1] > curUnit.missingHealth) and curUnit.missingHealth or self.chainHeal.jumps[1]; -- now find who we can jump to for x = 1, numDeficits do -- cant jump to self : ) if (i ~= x) then local curUnit2 = deficits[x]; local distance = SmartHealing:Distance(curUnit, curUnit2); local jump = #curUnit.jumps + 1; if (jump > 4) then break; end if (distance and distance <= self.chainHeal.distance) then curUnit.jumps[jump] = (self.chainHeal.jumps[jump] > curUnit2.missingHealth) and curUnit2.missingHealth or self.chainHeal.jumps[jump]; curUnit.totalHeal = curUnit.totalHeal + curUnit.jumps[jump]; -- add curUnit2 to targets table.insert(curUnit.targets, curUnit2); end end end if (curUnit and curUnit.jumps and #curUnit.jumps >= (Settings.minjumps + 1)) then table.insert(paths, curUnit); end end table.sort(paths, function(a, b) return a.totalHeal > b.totalHeal; end); self:Debug("Paths found: ", #paths); if (#paths == 0) then return; end for i, path in pairs(paths) do if (i > Settings.maxTargets) then return; end local text = ''; if (Settings.centerTextOption == "bestTarget") then text = string.format("#%s", i); else text = string.format("^%.1fk", path.totalHeal / 1000); --text = path.totalHeal; end self.core:SendStatusGained(path.guid, thisStatus, Settings.priority, nil, i == 1 and Settings.color or Settings.color2, string.format("%s", text), 1, nil, nil); end end function GridStatusSmartHealing_ChainHeal:UpdateCoefs(e, ...) self.spellInfo.healingPower = GetSpellBonusHealing(); self.spellInfo.crit = GetSpellCritChance(2); self.spellInfo.restoSpec = GetSpecialization() == 3; --self.spellInfo.restoSpec = GetSpecialization() local _, _, _, _, spark = GetTalentInfo(3, 3); -- 2%, 4%, 6% -- 3 differnt ranks -- spark = 1-3 --self.spellInfo.sparkOfLife = (spark * 2) / 100; --self.spellInfo.chGlyph = SmartHealing:HasGlyph(ChainHealGlyph); if (self.spellInfo.restoSpec) then self.spellInfo.coef = 1 + 0.25; end -- jump1 really isnt a jump its the main target. local jump1, jump2, jump3, jump4; --[[ if (self.spellInfo.chGlyph) then local coef = self.spellInfo.coef - 0.10; jump1 = (self.chainHeal.base + self.spellInfo.healingPower * self.chainHeal.coef) * coef; jump2 = (jump1 * 0.70) * 1.15; jump3 = (jump2 * 0.70) * 1.15; jump4 = (jump3 * 0.70) * 1.15; else ]]-- jump1 = (self.chainHeal.base + self.spellInfo.healingPower * self.chainHeal.coef) * self.spellInfo.coef; jump2 = (jump1 * 0.70); jump3 = (jump2 * 0.70); jump4 = (jump3 * 0.70); --end self.chainHeal.jumps[1] = jump1; self.chainHeal.jumps[2] = jump2; self.chainHeal.jumps[3] = jump3; self.chainHeal.jumps[4] = jump4; end