Hi everyone, i have not very much hope but i need your help for making this ability to work (its the best chain heal code i have found so far, its based on GridStatusChainHealTarget) i have clean the code but it remains very complex.
Code:
local QuickHealth = LibStub and LibStub("LibQuickHealth-2.0", true) -- don't error if not found
local MapFiles = LibStub("LibMapData-1.0")
local GridStatus = Grid:GetModule("GridStatus")
-- upvalues
local GridRoster = Grid:GetModule("GridRoster")
local GridFrame = Grid:GetModule("GridFrame")
local UnitGUID = UnitGUID
local GetPlayerMapPosition = GetPlayerMapPosition
local SetMapToCurrentZone = SetMapToCurrentZone
local GetCurrentMapDungeonLevel = GetCurrentMapDungeonLevel
local GetMapInfo = GetMapInfo
local UnitHealth = QuickHealth and QuickHealth.UnitHealth or UnitHealth
local UnitHealthMax = UnitHealthMax
local UnitIsVisible = UnitIsVisible
local UnitIsDeadOrGhost = UnitIsDeadOrGhost
local UnitIsConnected = UnitIsConnected
local UnitIsEnemy = UnitIsEnemy
local UnitIsCharmed = UnitIsCharmed
local math_min = math.min
local math_floor = math.floor
local tinsert = table.insert
local tsort = table.sort
-- local data
local update_timer = 0
local ch_testrange_sq = 12.5 ^ 2
local settings = {
enable = true,
showjumps = true,
range = true,
cycle_time = 0.5,
minjumps = 2,
maxhealth = 85,
}
local refresh_state = {
map_width = 0,
map_height = 0,
player_x = 0,
player_y = 0,
player_data = nil
}
function GridStatusChainHealTarget:UnitsInRange(x1, y1, x2, y2, test_dist_sq)
local xx = (x2 - x1) * refresh_state.map_width
local yy = (y2 - y1) * refresh_state.map_height
local dist_sq = xx*xx + yy*yy
if dist_sq <= test_dist_sq then
return true
end
return false
end
function GridStatusChainHealTarget:IsValidTarget(unitid)
return not UnitIsDeadOrGhost(unitid) and
UnitIsConnected(unitid) and
UnitIsVisible(unitid) and
not (UnitIsCharmed(unitid) and UnitIsEnemy("player", unitid))
end
function GridStatusChainHealTarget:RefreshMapData()
-- check player position
refresh_state.player_x, refresh_state.player_y = GetPlayerMapPosition("player")
if refresh_state.player_x <= 0 and refresh_state.player_y <= 0 then
if WorldMapFrame:IsVisible() then
return false
end
-- continue only if map supported
if (refresh_state.player_x > 0 or refresh_state.player_y > 0) then
local fileName = GetMapInfo()
local currentLevel = GetCurrentMapDungeonLevel()
refresh_state.map_width, refresh_state.map_height = MapFiles:MapArea(fileName, currentLevel)
if refresh_state.map_width ~= 0 and refresh_state.map_height ~= 0 then
return true
end
end
return false
end
function GridStatusChainHealTarget:RefreshAll()
local refresh_state = refresh_state
if not self:RefreshMapData() then
self:ClearChStatus()
else
-- cache player data
refresh_state.player_data = {}
for cguid, unitid in GridRoster:IterateRoster() do
local cx, cy = GetPlayerMapPosition(unitid)
if (cx ~= 0 or cy ~= 0) and self:IsValidTarget(unitid) then
local health = UnitHealth(unitid)
local health_max = UnitHealthMax(unitid)
local pdata = {
guid = cguid,
x = cx,
y = cy,
deficit = health_max - health,
percent = health / health_max,
inrange = {} -- list of unitids candidates to jump to
}
-- make list of players in range of everyone
for tunitid, tdata in pairs(refresh_state.player_data) do
-- Only include targets below maxhealth %
if unitid ~= tunitid and self:UnitsInRange(pdata.x, pdata.y, tdata.x, tdata.y, ch_testrange_sq) then
if tdata.percent < (85 * 0.01) then
tinsert(pdata.inrange, tunitid)
end
if pdata.percent < (85 * 0.01) then
tinsert(tdata.inrange, unitid)
end
end
end
refresh_state.player_data[unitid] = pdata
end
end
self:RefreshCh()
end
end
function GridStatusChainHealTarget:RefreshCh()
local refresh_state = refresh_state
local ch_best_uid = nil
local ch_best_pdata = nil
local ch_best_jumps = 0
-- check all
for unitid, p1 in pairs(refresh_state.player_data) do
if not settings.range or GridFrame:UnitInRange(unitid, 40) then
local curbest = nil
local curbest_unitid = nil
local curjumps = math_min(#(p1.inrange), 3)
-- We're only interested in players that will generate at least minjumps number of jumps
if curjumps >= settings.minjumps then
for _, tunitid in pairs(p1.inrange) do
local p2 = refresh_state.player_data[tunitid]
if (not curbest) or (p2.deficit > curbest.deficit) then
curbest = p2
curbest_unitid = tunitid
end
end
-- Check if we found a better target, based on number of jumps and health deficit
if curbest and (curjumps >= ch_best_jumps) and ((not ch_best_pdata) or (curbest.deficit > ch_best_pdata.deficit)) then
ch_best_pdata = curbest
ch_best_uid = curbest_unitid
ch_best_jumps = curjumps
end
end
end
end
-- Clear and update status
self:ClearChStatus()
if ch_best_pdata then
self.core:SendStatusGained( ch_best_pdata.guid,
tostring(ch_best_jumps))
if settings.showjumps then
for _, tunitid in pairs(ch_best_pdata.inrange) do
if tunitid ~= ch_best_uid then
local p1 = refresh_state.player_data[tunitid]
if mana >= 4404 and moving == 0 then
-- return true
SilentCast(1064,p1) ??
end
end
end
end
end
end
end