Files
wow-Heimdall/Modules/AchievementSniffer.lua
PhatPhuckDave 1da1e7bf9f
Some checks failed
Release Workflow / release (push) Failing after 23s
Code format
2025-05-04 15:09:47 +02:00

295 lines
8.1 KiB
Lua

local addonname, shared = ...
---@cast shared HeimdallShared
---@cast addonname string
local ModuleName = "AchievementSniffer"
local HeimdallRoot = "Interface\\AddOns\\Heimdall\\"
local TextureRoot = HeimdallRoot .. "Texture\\"
local Achievements = {
15,
958,
1266,
2078,
2141,
2200,
4958,
5456,
5749,
6460,
6753,
7382,
7383,
7384,
8929,
8982,
9017,
9038,
9493,
10059,
10079,
10278,
10657,
10672,
10684,
10688,
10689,
10692,
10693,
10698,
10790,
10875,
11124,
11126,
11127,
11128,
11153,
11157,
11164,
11188,
11189,
11190,
11446,
11473,
11610,
11657,
11658,
11659,
11660,
11674,
11992,
11993,
11994,
11995,
11996,
11997,
11998,
11999,
12000,
12001,
12020,
12026,
12074,
12445,
12447,
12448,
}
---@diagnostic disable-next-line: missing-fields
shared.AchievementSniffer = {}
function shared.AchievementSniffer.Init()
if Heimdall_Data.config.achievementSniffer.debug then
print(string.format("[%s] Module initialized", ModuleName))
end
local guidMap = {}
---@class AchievementData
---@field id number
---@field date string
---@field completed boolean
---@class Heimdall_Achievements
---@field players table<string, table<number, AchievementData>>
---@field alreadySeen table<string, boolean>
---@field rescan boolean
if not Heimdall_Achievements then Heimdall_Achievements = {} end
if not Heimdall_Achievements.players then Heimdall_Achievements.players = {} end
if not Heimdall_Achievements.alreadySeen then Heimdall_Achievements.alreadySeen = {} end
--local framePool = {}
--for i = 1, 40 do
-- local frame = CreateFrame("Frame", "HeimdallAchievementSnifferNameplate" .. i, UIParent)
-- local texture = frame:CreateTexture(nil, "ARTWORK")
-- texture:SetAllPoints(frame)
-- texture:SetTexture(TextureRoot .. Heimdall_Data.config.achievementSniffer.texture)
-- frame.texture = texture
-- frame:Hide()
-- table.insert(framePool, frame)
--end
---@param name string
---@return boolean
local function ShouldInspect(name)
local should = false
if not Heimdall_Achievements.players[name] then
if Heimdall_Data.config.achievementSniffer.debug then
print(string.format("[%s] Player %s does not have prior achievement data", ModuleName, name))
end
should = true
end
if Heimdall_Achievements.alreadySeen[name] then
if Heimdall_Data.config.achievementSniffer.debug then
print(string.format("[%s] Player %s has already been seen", ModuleName, name))
end
-- Save some memory
Heimdall_Achievements.players[name] = nil
should = false
end
if Heimdall_Data.config.achievementSniffer.rescan then
if Heimdall_Data.config.achievementSniffer.debug then
print(string.format("[%s] Rescan is enabled", ModuleName))
end
should = true
end
return should
end
-- It's not working well AT ALL
-- I don't know how to do it better
-- It simply just does not work...
--local function UpdateFrames()
-- for i, frame in ipairs(framePool) do
-- local unit = "nameplate" .. i
-- if not UnitExists(unit) then
-- --if Heimdall_Data.config.achievementSniffer.debug then
-- -- print(string.format("[%s] Unit %s does not exist, hiding frame", ModuleName, unit))
-- --end
-- frame:Hide()
-- else
-- --local unitFrame = _G[string.format("ElvUI_NamePlate%dHealthBar", i)]
-- local unitFrame = _G[string.format("NamePlate%d", i)]
-- if unitFrame == nil then
-- if Heimdall_Data.config.achievementSniffer.debug then
-- print(string.format("[%s] Unit frame for %s not found", ModuleName, unit))
-- end
-- frame:Hide()
-- else
-- local unitName = UnitName(unit)
-- if Heimdall_Data.config.achievementSniffer.debug then
-- print(string.format("[%s] Unit frame found for %s (%s)", ModuleName, unit, unitName))
-- end
-- frame:Show()
-- frame:SetSize(32, 32)
-- frame:SetFrameStrata("HIGH")
-- frame:SetFrameLevel(100)
-- frame:SetScale(Heimdall_Data.config.achievementSniffer.iconScale)
-- frame.texture:SetTexture(TextureRoot .. Heimdall_Data.config.achievementSniffer.texture)
-- frame:SetPoint("CENTER", unitFrame, "CENTER",
-- Heimdall_Data.config.achievementSniffer.offsetX,
-- Heimdall_Data.config.achievementSniffer.offsetY)
-- frame:SetParent(unitFrame)
-- frame:SetAlpha(1)
-- local exists = ShouldInspect(unitName)
-- if exists then
-- frame.texture:SetVertexColor(1, 0, 0, 1)
-- else
-- frame.texture:SetVertexColor(0, 1, 0, 1)
-- end
-- if Heimdall_Data.config.achievementSniffer.debug then
-- print(string.format("[%s] Frame updated for %s", ModuleName, unitName))
-- end
-- end
-- end
-- end
--end
---@param unit string
local function TryInspect(unit)
local targetPlayer = UnitIsPlayer(unit)
if not targetPlayer then return end
local targetName = UnitName(unit)
local targetGuid = UnitGUID(unit)
guidMap[targetGuid] = targetName
if not ShouldInspect(targetName) then
if Heimdall_Data.config.achievementSniffer.debug then
print(string.format("[%s] Not inspecting player: %s", ModuleName, targetName))
end
return
end
local canInspect = CheckInteractDistance(unit, 1)
if canInspect then
if Heimdall_Data.config.achievementSniffer.debug then
print(string.format("[%s] Inspecting player: %s", ModuleName, targetName))
end
SetAchievementComparisonUnit(unit)
else
if Heimdall_Data.config.achievementSniffer.debug then
print(string.format("[%s] Cannot inspect player (too far?): %s", ModuleName, targetName))
end
end
end
---@param name string
local function Scan(name)
if Heimdall_Data.config.achievementSniffer.debug then
print(string.format("[%s] Scanning achievements for %s", ModuleName, name))
end
Heimdall_Achievements.players[name] = {}
for i, aid in ipairs(Achievements) do
local completed, month, day, year = GetAchievementComparisonInfo(aid)
if completed then
---@type string
local yearstr = "" .. year
if year < 100 then yearstr = "20" .. year end
local date = string.format("%04d-%02d-%02d", yearstr, month, day)
local data = {
id = aid,
date = date,
completed = completed,
}
if Heimdall_Data.config.achievementSniffer.debug then
print(string.format("[%s] Achievement %d completed on %s", ModuleName, aid, date))
end
Heimdall_Achievements.players[name][aid] = data
end
end
--UpdateFrames()
end
local nameplateFrame = CreateFrame("Frame")
nameplateFrame:RegisterEvent("NAME_PLATE_UNIT_ADDED")
nameplateFrame:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
nameplateFrame:SetScript("OnEvent", function(self, event, unit)
if not Heimdall_Data.config.achievementSniffer.enabled then return end
if Heimdall_Data.config.achievementSniffer.debug then
print(string.format("[%s] Event triggered: %s for unit: %s", ModuleName, event, unit))
end
if event == "NAME_PLATE_UNIT_ADDED" then TryInspect(unit) end
--UpdateFrames()
end)
local inspectFrame = CreateFrame("Frame")
inspectFrame:RegisterEvent("INSPECT_ACHIEVEMENT_READY")
inspectFrame:SetScript("OnEvent", function(self, event, guid)
if not Heimdall_Data.config.achievementSniffer.enabled then return end
local name = guidMap[guid]
if not name then
if Heimdall_Data.config.achievementSniffer.debug then
print(string.format("[%s] No name found for guid: %s", ModuleName, guid))
end
return
end
if Heimdall_Data.config.achievementSniffer.debug then
print(string.format("[%s] Event triggered: %s for player: %s", ModuleName, event, name))
end
Scan(name)
end)
local function Tick()
C_Timer.NewTimer(Heimdall_Data.config.achievementSniffer.scanInterval, Tick)
if not Heimdall_Data.config.achievementSniffer.enabled then return end
if Heimdall_Data.config.achievementSniffer.debug then
print(string.format("[%s] Scanning achievements for everyone on screen", ModuleName))
end
for i = 1, 40 do
local unit = "nameplate" .. i
if UnitExists(unit) then
TryInspect(unit)
--else
-- if Heimdall_Data.config.achievementSniffer.debug then
-- print(string.format("[%s] Unit %s does not exist, nothing to inspect", ModuleName, unit))
-- end
end
end
--UpdateFrames()
end
Tick()
print("[Heimdall] AchievementSniffer loaded")
end