226 lines
7.2 KiB
Lua
226 lines
7.2 KiB
Lua
local addonname, shared = ...
|
|
---@cast shared HeimdallShared
|
|
---@cast addonname string
|
|
local ModuleName = "Spotter"
|
|
|
|
---@diagnostic disable-next-line: missing-fields
|
|
shared.Spotter = {}
|
|
function shared.Spotter.Init()
|
|
local function FormatHP(hp)
|
|
if hp > 1e9 then
|
|
return string.format("%.1fB", hp / 1e9)
|
|
elseif hp > 1e6 then
|
|
return string.format("%.1fM", hp / 1e6)
|
|
elseif hp > 1e3 then
|
|
return string.format("%.1fK", hp / 1e3)
|
|
else
|
|
return hp
|
|
end
|
|
end
|
|
|
|
---@type table<string, number>
|
|
local throttleTable = {}
|
|
|
|
---@param unit string
|
|
---@param name string
|
|
---@param faction string
|
|
---@param hostile boolean
|
|
---@return boolean
|
|
---@return string? error
|
|
local function ShouldNotify(unit, name, faction, hostile)
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Checking notification criteria for %s (%s)", ModuleName, name, faction))
|
|
end
|
|
|
|
if Heimdall_Data.config.agents[name] then
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Skipping agent: %s", ModuleName, name))
|
|
end
|
|
return false
|
|
end
|
|
|
|
if Heimdall_Data.config.spotter.stinky then
|
|
if shared.IsStinky(name) then
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Notifying - Found stinky: %s", ModuleName, name))
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
|
|
if Heimdall_Data.config.spotter.alliance then
|
|
if faction == "Alliance" then
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Notifying - Found Alliance player: %s", ModuleName, name))
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
|
|
if Heimdall_Data.config.spotter.hostile then
|
|
if hostile then
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Notifying - Found hostile player: %s", ModuleName, name))
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(
|
|
string.format(
|
|
"[%s] Using everyone setting: %s",
|
|
ModuleName,
|
|
tostring(Heimdall_Data.config.spotter.everyone)
|
|
)
|
|
)
|
|
end
|
|
return Heimdall_Data.config.spotter.everyone
|
|
end
|
|
|
|
---@param unit string
|
|
---@return string?
|
|
local function NotifySpotted(unit)
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Processing spotted unit: %s", ModuleName, unit))
|
|
end
|
|
|
|
if not unit then return string.format("Could not find unit %s", tostring(unit)) end
|
|
if not UnitIsPlayer(unit) then
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Ignoring non-player unit: %s", ModuleName, unit))
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local name = UnitName(unit)
|
|
if not name then return string.format("Could not find name for unit %s", tostring(unit)) end
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Processing player: %s", ModuleName, name))
|
|
end
|
|
|
|
local time = GetTime()
|
|
if throttleTable[name] and time - throttleTable[name] < Heimdall_Data.config.spotter.throttleTime then
|
|
if Heimdall_Data.config.spotter.debug then
|
|
local remainingTime = Heimdall_Data.config.spotter.throttleTime - (time - throttleTable[name])
|
|
print(string.format("[%s] Player %s throttled for %.1f more seconds", ModuleName, name, remainingTime))
|
|
end
|
|
return string.format("Throttled %s", tostring(name))
|
|
end
|
|
throttleTable[name] = time
|
|
|
|
local race = UnitRace(unit)
|
|
if not race then return string.format("Could not find race for unit %s", tostring(unit)) end
|
|
local faction = shared.raceMap[race]
|
|
if not faction then return string.format("Could not find faction for race %s", tostring(race)) end
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Player %s is %s (%s)", ModuleName, name, race, faction))
|
|
end
|
|
|
|
local hostile = UnitCanAttack("player", unit)
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Player %s is %s", ModuleName, name, hostile and "hostile" or "friendly"))
|
|
end
|
|
|
|
local doNotify = ShouldNotify(unit, name, faction, hostile)
|
|
if not doNotify then
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Skipping notification for %s", ModuleName, name))
|
|
end
|
|
return string.format("Not notifying for %s", tostring(name))
|
|
end
|
|
|
|
local hp = UnitHealth(unit)
|
|
if not hp then return string.format("Could not find hp for unit %s", tostring(unit)) end
|
|
local maxHp = UnitHealthMax(unit)
|
|
if not maxHp then return string.format("Could not find maxHp for unit %s", tostring(unit)) end
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Player %s health: %s/%s", ModuleName, name, FormatHP(hp), FormatHP(maxHp)))
|
|
end
|
|
|
|
local class = UnitClass(unit)
|
|
if not class then return string.format("Could not find class for unit %s", tostring(unit)) end
|
|
|
|
local zone, subzone = GetZoneText() or "Unknown", GetSubZoneText() or "Unknown"
|
|
if Heimdall_Data.config.spotter.zoneOverride then
|
|
zone = Heimdall_Data.config.spotter.zoneOverride or ""
|
|
subzone = ""
|
|
end
|
|
|
|
local x, y = GetPlayerMapPosition("player")
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Player %s coordinates: %.2f, %.2f", ModuleName, name, x * 100, y * 100))
|
|
end
|
|
|
|
local pvpOn = UnitIsPVP(unit)
|
|
local stinky = shared.IsStinky(name) or false
|
|
SetMapToCurrentZone()
|
|
SetMapByID(GetCurrentMapAreaID())
|
|
local areaId = tostring(GetCurrentMapAreaID())
|
|
|
|
for _, channel in pairs(Heimdall_Data.config.spotter.channels) do
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Processing channel: %s", ModuleName, channel))
|
|
end
|
|
local locale = shared.GetLocaleForChannel(channel)
|
|
local text = string.format(
|
|
shared._L("spotterSpotted", locale),
|
|
hostile and shared._L("hostile", locale) or shared._L("friendly", locale),
|
|
name,
|
|
shared._L(class, locale),
|
|
stinky and string.format("(%s)", "!!!!") or "",
|
|
shared._L(race, locale),
|
|
shared._L(faction, locale),
|
|
pvpOn and shared._L("pvpOn", locale) or shared._L("pvpOff", locale),
|
|
string.gsub(FormatHP(hp), "M", "kk"),
|
|
string.gsub(FormatHP(maxHp), "M", "kk"),
|
|
shared._L(zone, locale),
|
|
shared._L(subzone, locale),
|
|
areaId,
|
|
x * 100,
|
|
y * 100
|
|
)
|
|
|
|
---@type Message
|
|
local msg = {
|
|
channel = "C",
|
|
data = channel,
|
|
message = text,
|
|
}
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Queuing spotter message", ModuleName))
|
|
shared.dumpTable(msg)
|
|
end
|
|
table.insert(shared.messenger.queue, msg)
|
|
end
|
|
end
|
|
|
|
local frame = CreateFrame("Frame")
|
|
frame:RegisterEvent("NAME_PLATE_UNIT_ADDED")
|
|
frame:RegisterEvent("UNIT_TARGET")
|
|
frame:SetScript("OnEvent", function(self, event, unit)
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Event received: %s for unit: %s", ModuleName, event, unit or "target"))
|
|
end
|
|
|
|
if not Heimdall_Data.config.spotter.enabled then
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Module disabled, ignoring event", ModuleName))
|
|
end
|
|
return
|
|
end
|
|
|
|
if event == "UNIT_TARGET" then unit = "target" end
|
|
|
|
local err = NotifySpotted(unit)
|
|
if err then
|
|
if Heimdall_Data.config.spotter.debug then
|
|
print(string.format("[%s] Error processing unit %s: %s", ModuleName, unit, err))
|
|
end
|
|
end
|
|
end)
|
|
|
|
if Heimdall_Data.config.spotter.debug then print(string.format("[%s] Module initialized", ModuleName)) end
|
|
print("[Heimdall] Spotter loaded")
|
|
end
|