Puppeteer/core/UnitTracker.lua
2025-09-08 18:29:45 -07:00

142 lines
4.4 KiB
Lua

PTUtil.SetEnvironment(Puppeteer)
local _G = getfenv(0)
UnitTrackerFrame = CreateFrame("Frame", "PTUnitTrackerFrame", UIParent)
local util = PTUtil
local GetTime = GetTime
local compost = AceLibrary("Compost-2.0")
local TRACKING_EVAL_INTERVAL = 1.25
local RANGE_MIN_DIST = 20
local RANGE_MAX_DIST = 60
local SIGHT_MAX_DIST = 80
local DISTANCE_UPDATE_INTERVAL = 0.1
local SIGHT_UPDATE_INTERVAL = 0.1
local AllUnits = util.AllUnits
local distanceTrackedUnits = {}
local sightTrackedUnits = {}
local preciseDistance = util.CanClientGetPreciseDistance()
local sightTrackingEnabled = util.CanClientSightCheck()
local nextEval = GetTime() + 0.5
local nextRangeUpdate = GetTime() + 0.6
local nextSightUpdate = GetTime() + 0.6
if not preciseDistance then
nextRangeUpdate = nextRangeUpdate + 99999999 -- Effectively disable updates
end
if not sightTrackingEnabled then
nextSightUpdate = nextSightUpdate + 99999999
end
function LoadTrackingOptions()
local opts = PTOptions.Tracking
TRACKING_EVAL_INTERVAL = opts.EvaluateInterval
RANGE_MIN_DIST = opts.MinDistanceTracking
RANGE_MAX_DIST = opts.MaxDistanceTracking
SIGHT_MAX_DIST = opts.MaxSightTracking
DISTANCE_UPDATE_INTERVAL = opts.DistanceUpdateInterval
SIGHT_UPDATE_INTERVAL = opts.SightUpdateInterval
end
function RunTrackingScan()
local UnitFrames = UnitFrames
local time = GetTime()
if time > nextEval then
--StartTiming("TrackingEval")
nextEval = time + TRACKING_EVAL_INTERVAL
compost:Erase(distanceTrackedUnits)
local prevSightTrackedUnits = sightTrackedUnits
sightTrackedUnits = compost:GetTable()
if PTGuidRoster then
for guid, cache in pairs(PTUnit.GetAllUnits()) do
EvaluateTracking(guid)
end
else
for _, unit in ipairs(AllUnits) do
EvaluateTracking(unit)
end
end
for _, unit in ipairs(prevSightTrackedUnits) do
for ui in UnitFrames(unit) do
ui:UpdateSight()
end
end
compost:Reclaim(prevSightTrackedUnits)
--EndTiming("TrackingEval")
end
if time > nextRangeUpdate then
nextRangeUpdate = time + DISTANCE_UPDATE_INTERVAL
for _, unit in ipairs(distanceTrackedUnits) do
local cache = PTUnit.Get(unit)
if cache and cache:UpdateDistance() then
for ui in UnitFrames(unit) do
ui:UpdateRange()
end
end
end
end
if time > nextSightUpdate then
nextSightUpdate = time + SIGHT_UPDATE_INTERVAL
for _, unit in ipairs(sightTrackedUnits) do
local cache = PTUnit.Get(unit)
--StartTiming("SightScan")
if cache and cache:UpdateSight() then
for ui in UnitFrames(unit) do
ui:UpdateSight()
end
end
--EndTiming("SightScan")
end
end
end
function EvaluateTracking(unit, update)
local UnitFrames = UnitFrames
local cache = PTUnit.Get(unit)
local distanceChanged = cache:UpdateDistance()
local sightChanged = cache:UpdateSight()
local new = cache:CheckNew()
local dist = cache:GetDistance()
if distanceChanged or sightChanged or new then
for ui in UnitFrames(unit) do
if distanceChanged or new then
ui:UpdateRange()
end
if sightChanged or new then
ui:UpdateSight()
end
end
end
if cache:UpdatePVP() then
for ui in UnitFrames(unit) do
ui:UpdatePVP()
end
end
local isTarget = UnitIsUnit(unit, "target")
if PTGuidRoster then
unit = PTGuidRoster.ResolveUnitGuid(unit)
end
-- Only closely track units that are close to the range threshold
if isTarget or (dist < RANGE_MAX_DIST and dist > RANGE_MIN_DIST) then
if not update or not util.ArrayContains(distanceTrackedUnits, unit) then
table.insert(distanceTrackedUnits, unit)
end
end
if sightTrackingEnabled and (isTarget or (dist > 0 and dist < SIGHT_MAX_DIST)) then
if not update or not util.ArrayContains(sightTrackedUnits, unit) then
table.insert(sightTrackedUnits, unit)
end
end
end
function StartUnitTracker()
LoadTrackingOptions()
UnitTrackerFrame:SetScript("OnUpdate", RunTrackingScan)
end