Skip to content

Commit e18b155

Browse files
committed
Improve kill detection
Add new tracking for if damage has been dealt at all to a mob by the player or the group, to more accurately detect kills when we can't rely on tapped status.
1 parent 26e9a38 commit e18b155

File tree

1 file changed

+41
-20
lines changed

1 file changed

+41
-20
lines changed

KillTrack.lua

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ local FirstDamage = {} -- Tracks first damage to a mob registered by CLEU
122122
---@type { [string]: string? }
123123
local LastDamage = {} -- Tracks whoever did the most recent damage to a mob
124124

125+
---@type { [string]: boolean? }
126+
local HasPlayerDamage = {} -- Tracks whether the player (or pet) has dealt damage to a mob
127+
128+
---@type { [string]: boolean? }
129+
local HasGroupDamage = {} -- Tracks whether a group member has dealt damage to a mob
130+
125131
---@type { [string]: boolean? }
126132
local DamageValid = {} -- Determines if mob is tapped by player/group
127133

@@ -284,6 +290,12 @@ function KT.Events.COMBAT_LOG_EVENT_UNFILTERED(self)
284290

285291
LastDamage[d_guid] = s_guid
286292

293+
if s_guid == self.PlayerGUID or s_guid == UnitGUID("pet") then
294+
HasPlayerDamage[d_guid] = true
295+
elseif self:IsInGroup(s_guid) then
296+
HasGroupDamage[d_guid] = true
297+
end
298+
287299
if not DamageValid[d_guid] then
288300
-- if DamageValid returns true for a GUID, we can tell with 100% certainty that it's valid
289301
-- But this relies on one of the valid unit names currently being the damaged mob
@@ -305,32 +317,41 @@ function KT.Events.COMBAT_LOG_EVENT_UNFILTERED(self)
305317
local firstDamage = FirstDamage[d_guid]
306318
local lastDamage = LastDamage[d_guid]
307319
local damageValid = DamageValid[d_guid]
320+
local hasPlayerDamage = HasPlayerDamage[d_guid]
321+
local hasGroupDamage = HasGroupDamage[d_guid]
308322
FirstDamage[d_guid] = nil
309323
LastDamage[d_guid] = nil
310324
DamageValid[d_guid] = nil
311-
local firstByPlayer = firstDamage == self.PlayerGUID or firstDamage == UnitGUID("pet")
325+
HasPlayerDamage[d_guid] = nil
326+
HasGroupDamage[d_guid] = nil
327+
328+
-- If we can't identify the mob there's no point continuing
329+
if d_id == nil or d_id == 0 then return end
330+
331+
local petGUID = UnitGUID("pet")
332+
local firstByPlayer = firstDamage == self.PlayerGUID or firstDamage == petGUID
312333
local firstByGroup = self:IsInGroup(firstDamage)
313-
local lastByPlayer = lastDamage == self.PlayerGUID or lastDamage == UnitGUID("pet")
314-
local pass
334+
local lastByPlayer = lastDamage == self.PlayerGUID or lastDamage == petGUID
315335

316-
-- The checks after DamageValid are not 100% failsafe
336+
-- The checks when DamageValid is non-false are not 100% failsafe
317337
-- Scenario: You deal the killing blow to an already tapped mob <- Would count as kill with current code
318338

319-
-- if DamageValid[guid] is set, it can be used to decide if the kill was valid with 100% certainty
320-
if damageValid ~= nil then
321-
pass = damageValid
322-
else
323-
-- The one who dealt the very first bit of damage was probably the one who got the tag on the mob
324-
-- This should apply in most (if not all) situations and is probably a safe fallback when we couldn't
325-
-- retrieve tapped status from GUID->Unit
326-
pass = firstByPlayer or firstByGroup
339+
-- If damageValid is false, it means tap is denied on the mob and there is no way the kill would count
340+
if damageValid == false then return end
341+
342+
-- If neither the player not group was involved in the battle, we don't count the kill
343+
if not hasPlayerDamage and not hasGroupDamage then return end
344+
345+
if damageValid == nil and not firstByPlayer and not firstByGroup then
346+
-- If we couldn't get a proper tapped status and the first recorded damage was not by player or group,
347+
-- we can't be sure the kill was valid, so ignore it
348+
return
327349
end
328350

329-
if not self.Global.COUNT_GROUP and pass and not lastByPlayer then
330-
pass = false -- Player or player's pet did not deal the killing blow and addon only tracks player kills
351+
if not lastByPlayer and not self.Global.COUNT_GROUP then
352+
return -- Player or player's pet did not deal the killing blow and addon only tracks player kills
331353
end
332354

333-
if not pass or d_id == nil or d_id == 0 then return end
334355
self:AddKill(d_id, d_name)
335356
if self.Timer:IsRunning() then
336357
self.Timer:SetData("Kills", self.Timer:GetData("Kills", true) + 1)
@@ -420,12 +441,12 @@ function KT:ToggleDebug()
420441
end
421442
end
422443

423-
---@param unit string?
444+
---@param guid string?
424445
---@return boolean
425-
function KT:IsInGroup(unit)
426-
if not unit or unit == "" then return false end
427-
if unit == self.PlayerName or unit == self.PlayerGUID then return true end
428-
return IsGUIDInGroup(unit)
446+
function KT:IsInGroup(guid)
447+
if not guid or guid == "" then return false end
448+
if guid == self.PlayerName or guid == self.PlayerGUID then return true end
449+
return IsGUIDInGroup(guid)
429450
end
430451

431452
---@param threshold integer

0 commit comments

Comments
 (0)