277 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			277 lines
		
	
	
		
			9.0 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 location = Heimdall_Data.config.spotter.zoneOverride
 | 
						|
		if not location or location == "" then
 | 
						|
			local zone = GetZoneText()
 | 
						|
			if not zone then return string.format("Could not find zone for unit %s", tostring(unit)) end
 | 
						|
			local subzone = GetSubZoneText()
 | 
						|
			if not subzone then subzone = "" end
 | 
						|
			if Heimdall_Data.config.spotter.debug then
 | 
						|
				print(string.format("[%s] Player %s location: %s (%s)", ModuleName, name, zone, subzone))
 | 
						|
			end
 | 
						|
			location = string.format("%s (%s)", zone, 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 text = string.format(shared.L.en.spotterSpotted,
 | 
						|
			hostile and shared.L.en.tidbits.hostile or shared.L.en.tidbits.friendly,
 | 
						|
			name,
 | 
						|
			class,
 | 
						|
			stinky and string.format("(%s)", "!!!!") or "",
 | 
						|
			race,
 | 
						|
			faction,
 | 
						|
			pvpOn and shared.L.en.tidbits.pvpOn or shared.L.en.tidbits.pvpOff,
 | 
						|
			string.gsub(FormatHP(hp), "M", "kk"),
 | 
						|
			string.gsub(FormatHP(maxHp), "M", "kk"),
 | 
						|
			location,
 | 
						|
			tostring(GetCurrentMapAreaID()),
 | 
						|
			x * 100, y * 100)
 | 
						|
 | 
						|
		if Heimdall_Data.config.spotter.debug then
 | 
						|
			print(string.format("[%s] Sending notification: %s", ModuleName, text))
 | 
						|
		end
 | 
						|
 | 
						|
		---@type Message
 | 
						|
		local msg = {
 | 
						|
			channel = "C",
 | 
						|
			data = Heimdall_Data.config.spotter.notifyChannel,
 | 
						|
			message = text
 | 
						|
		}
 | 
						|
		table.insert(shared.messenger.queue, msg)
 | 
						|
 | 
						|
		local ruClass = shared.L.ru.classes[class]
 | 
						|
		if not ruClass then
 | 
						|
			print(string.format("[%s] Class %s not found in ru.classes", ModuleName, class))
 | 
						|
		end
 | 
						|
		local ruRace = shared.L.ru.races[race]
 | 
						|
		if not ruRace then
 | 
						|
			print(string.format("[%s] Race %s not found in ru.races", ModuleName, race))
 | 
						|
		end
 | 
						|
		local ruFaction = shared.L.ru.factions[faction]
 | 
						|
		if not ruFaction then
 | 
						|
			print(string.format("[%s] Faction %s not found in ru.factions", ModuleName, faction))
 | 
						|
		end
 | 
						|
		local zone, subzone = GetZoneText(), GetSubZoneText()
 | 
						|
		local ruZone = shared.L.ru.zones[zone]
 | 
						|
		if not ruZone then
 | 
						|
			print(string.format("[%s] Zone %s not found in ru.zones", ModuleName, zone))
 | 
						|
		end
 | 
						|
		local ruSubzone = shared.L.ru.zones[subzone]
 | 
						|
		if not ruSubzone then
 | 
						|
			print(string.format("[%s] Subzone %s not found in ru.zones", ModuleName, subzone))
 | 
						|
		end
 | 
						|
 | 
						|
		text = string.format(shared.L.ru.spotterSpotted,
 | 
						|
			hostile and shared.L.ru.tidbits.hostile or shared.L.ru.tidbits.friendly,
 | 
						|
			name,
 | 
						|
			ruClass or class,
 | 
						|
			stinky and string.format("(%s)", "!!!!") or "",
 | 
						|
			ruRace or race,
 | 
						|
			ruFaction or faction,
 | 
						|
			pvpOn and shared.L.ru.tidbits.pvpOn or shared.L.ru.tidbits.pvpOff,
 | 
						|
			string.gsub(FormatHP(hp), "M", "kk"),
 | 
						|
			string.gsub(FormatHP(maxHp), "M", "kk"),
 | 
						|
			string.format("%s (%s)", ruZone or zone, ruSubzone or subzone),
 | 
						|
			tostring(GetCurrentMapAreaID()),
 | 
						|
			x * 100, y * 100)
 | 
						|
		if Heimdall_Data.config.essencex.spotter and Heimdall_Data.config.essencex.enabled then
 | 
						|
			local msg = {
 | 
						|
				channel = "C",
 | 
						|
				data = Heimdall_Data.config.essencex.masterChannel,
 | 
						|
				message = text
 | 
						|
			}
 | 
						|
			table.insert(shared.messenger.queue, msg)
 | 
						|
		end
 | 
						|
 | 
						|
		if Heimdall_Data.config.spotter.debug then
 | 
						|
			print(string.format("[%s] Sending notification: %s", ModuleName, text))
 | 
						|
		end
 | 
						|
 | 
						|
		if Heimdall_Data.config.echoToRussian then
 | 
						|
			-- Russian message
 | 
						|
			local ruMsg = {
 | 
						|
				channel = "C",
 | 
						|
				data = Heimdall_Data.config.spotter.notifyChannel .. "ru",
 | 
						|
				message = text
 | 
						|
			}
 | 
						|
			table.insert(shared.messenger.queue, ruMsg)
 | 
						|
		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
 |