So I am a Holy priest and anytime there are more than a couple people hurt I will hit CoH everytime its off cooldown, I also try to keep mending up and then flash heal whenever I have Surge of Light or just feel like it. However on some encounters where the entire raid is getting owned (think Hodir, Yogg, Ignis, etc), there are times when CoH is on cooldown, mending is on cooldown, and I also have Serendipity up to 3 stacks reducing the Prayer of Healing cast time by 36%, making it a good filler spell. However I have the problem that my unit frames are sorted by class then name, so its not obvious who to cast it on. And here is my solution. I created a set that will determine who is in the 'best' group to cast PoH on. This set will only put people in it when you have Serendipity up to 3 stacks, CoH with at least 2s on its cooldown, and there is a group missing at least 10k hp across it (may actually be less than this, I bias the missing hp up if multiple people in the group are below max health).
I hope this is useful for any priests out there.
Code:
-- BestGroupToHealSet.lua
-- (C)2009 David Erickson, all rights reserved.
--
-- A set class matching units in the group that is the best candidate for a group heal.
-- Locals
local gmap = {};
for i=1,8 do gmap[i] = {}; end
local minimumHPToHeal = 10000;
local updatePeriod = 0.2;
local strlower = string.lower;
local GetUnitByName = RDX.GetUnitByNameIfInGroup;
local GetUnitByNumber = RDX.GetUnitByNumber;
-- The set
local bestGroupToHealSet = RDX.Set:new();
bestGroupToHealSet.name = "Best Group to Heal<>";
RDX.RegisterSet(bestGroupToHealSet);
local function UpdateBestGroupToHeal()
local buffs, group, hpDiff, player;
local cohOnCD = false;
local hasSerendipity = false;
local now = GetTime()
-- check if we have serendipity
player = RDX.GetUnitByName(strlower(UnitName("player")));
buffs = player:Buffs()
for i=1,#buffs do
if buffs[i].name == "Serendipity" and buffs[i].count == 3 and buffs[i].expirationTime > now then
hasSerendipity = true;
break;
end
end
-- check if CoH has at least 2s left on CD
local cohCDStart, cohCDDuration, cohEnabled = GetSpellCooldown("Circle of Healing")
if (cohEnabled == 0 and (cohCDStart + cohCDDuration > now + 2)) then
cohOnCD = true
end
-- First clear our accumulation tables
for i=1,8 do wipe(gmap[i]); end
-- Walk each unit and push their missing health into the associated group table
for i=1,40 do
unit = GetUnitByNumber(i);
group = unit:GetGroup();
if unit:IsCacheValid() and unit:GetGroup() > 0 and not unit:IsDead() and
unit:IsOnline() then
hpDiff = unit:MaxHealth() - unit:Health()
if (hpDiff > 0) then
tinsert(gmap[group], hpDiff);
end
end
-- clear the set
bestGroupToHealSet:_Set(i, false);
end
local bestGroup, coeff, gHP, gSize, mostHp;
bestGroup = 0
mostHp = 0
-- determine the best group to heal
for i=1,8 do
gHP = 0
gSize = #gmap[i];
coeff = 1.0;
-- set our coeffecient to bias for more hp missing across the group
if (gSize > 1) then
coeff = coeff + (gSize * 0.1)
end
-- apply the coefficient on a per group member basis
for k,v in pairs(gmap[i]) do
gHP = gHP + v * coeff
end
if (gHP > mostHp) then
bestGroup = i
mostHp = gHP
end
end
-- set true for all units in this group
if (cohOnCD and hasSerendipity and mostHp > minimumHPToHeal) then
for i=1,40 do
unit = GetUnitByNumber(i);
group = unit:GetGroup();
if unit:IsCacheValid() and unit:GetGroup() > 0 then
if (group == bestGroup) then
bestGroupToHealSet:_Set(i, true);
end
end
end
end
end
function bestGroupToHealSet:_OnActivate()
VFL.AdaptiveUnschedule("UpdateBestGroupToHeal");
VFL.AdaptiveSchedule("UpdateBestGroupToHeal", updatePeriod, UpdateBestGroupToHeal);
end
function bestGroupToHealSet:_OnDeactivate()
VFL.AdaptiveUnschedule("UpdateBestGroupToHeal");
end
RDX.RegisterSetClass({
name = "bgths"; title = i18n("Best Group to Heal");
GetUI = RDX.TrivialSetFinderUI("bgths");
FindSet = function() return bestGroupToHealSet; end;
});