NanamiPlates_Threat = {} local NP = NanamiPlates local string_find = string.find local string_sub = string.sub local string_format = string.format local string_gfind = string.gfind local pairs = pairs local ipairs = ipairs local tonumber = tonumber local tostring = tostring local GetTime = GetTime local UnitName = UnitName local UnitExists = UnitExists local UnitIsUnit = UnitIsUnit local UnitInRaid = UnitInRaid local UnitInParty = UnitInParty local SendAddonMessage = SendAddonMessage local GP_TankModeThreats = {} local GP_Threats = {} local GP_TankPlayers = {} NanamiPlates_Threat.GP_TankModeThreats = GP_TankModeThreats NanamiPlates_Threat.GP_Threats = GP_Threats NanamiPlates_Threat.GP_TankPlayers = GP_TankPlayers local function GP_Split(str, delimiter) local result = {} local pattern = "([^" .. delimiter .. "]+)" for match in string_gfind(str, pattern) do table.insert(result, match) end return result end local function GP_HandleTankModePacket(packet) local startPos = string_find(packet, "TMTv1=") if not startPos then return end local dataStr = string_sub(packet, startPos + 6) for k in pairs(GP_TankModeThreats) do GP_TankModeThreats[k] = nil end local entries = GP_Split(dataStr, ";") for _, entry in ipairs(entries) do local parts = GP_Split(entry, ":") if parts[1] and parts[2] and parts[3] and parts[4] then GP_TankModeThreats[parts[2]] = { creature = parts[1], name = parts[3], perc = tonumber(parts[4]) or 0 } end end end local function GP_HandleThreatPacket(packet) local startPos = string_find(packet, "TWTv4=") if not startPos then return end local dataStr = string_sub(packet, startPos + 6) for k in pairs(GP_Threats) do GP_Threats[k] = nil end local entries = GP_Split(dataStr, ";") for _, entry in ipairs(entries) do local parts = GP_Split(entry, ":") if parts[1] and parts[3] and parts[4] then GP_Threats[parts[1]] = { threat = tonumber(parts[3]) or 0, perc = tonumber(parts[4]) or 0, tank = (parts[6] == "1") } end end end local NP_ADDON_PREFIX = "NanamiPlates" local TANK_BROADCAST_DEBOUNCE = 5 local lastTankBroadcast = 0 function NanamiPlates_Threat.BroadcastTankMode(force) local now = GetTime() if not force and (now - lastTankBroadcast) < TANK_BROADCAST_DEBOUNCE then return end local playerRole = NP and NP.playerRole local isTank = (playerRole == "TANK") local msg = isTank and "TM=1" or "TM=0" local myName = UnitName("player") if myName then GP_TankPlayers[myName] = isTank or nil end if UnitInRaid("player") then SendAddonMessage(NP_ADDON_PREFIX, msg, "RAID") lastTankBroadcast = now elseif UnitInParty() then SendAddonMessage(NP_ADDON_PREFIX, msg, "PARTY") lastTankBroadcast = now end end function NanamiPlates_Threat.IsPlayerTank(playerName) if not playerName then return false end return GP_TankPlayers[playerName] == true end local function GP_HandleTankModeMessage(sender, msg) if string_find(msg, "TM=") then local isTank = string_sub(msg, 4, 4) == "1" GP_TankPlayers[sender] = isTank or nil end end function NanamiPlates_Threat.GetTWTankModeThreat(mobGUID, mobName) local playerName = UnitName("player") if mobGUID then local data = GP_TankModeThreats[mobGUID] if data then local playerHasAggro = (data.name == playerName) return true, playerHasAggro, data.name, data.perc or 0 end end if mobName then for guid, data in pairs(GP_TankModeThreats) do if data.creature == mobName then local playerHasAggro = (data.name == playerName) return true, playerHasAggro, data.name, data.perc or 0 end end end return false, false, nil, 0 end function NanamiPlates_Threat.GetGPThreatData() local playerName = UnitName("player") local playerPct = 0 local highestOtherPct = 0 local hasData = false local threatHolderName = nil for name, data in pairs(GP_Threats) do hasData = true local pct = data.perc or 0 if name == playerName then playerPct = pct else if pct > highestOtherPct then highestOtherPct = pct end end if pct >= 100 then threatHolderName = name end end return hasData, (playerPct >= 100), playerPct, highestOtherPct, threatHolderName end function NanamiPlates_Threat.IsInPlayerGroup(unit) if not unit or not UnitExists(unit) then return false end if UnitIsUnit(unit, "player") then return true end for i = 1, 4 do if UnitIsUnit(unit, "party" .. i) then return true end end if UnitInRaid("player") then for i = 1, 40 do if UnitIsUnit(unit, "raid" .. i) then return true end end end if UnitIsUnit(unit, "pet") then return true end for i = 1, 4 do if UnitIsUnit(unit, "partypet" .. i) then return true end end return false end local NP_ThreatFrame = CreateFrame("Frame") NP_ThreatFrame:RegisterEvent("CHAT_MSG_ADDON") NP_ThreatFrame:RegisterEvent("PARTY_MEMBERS_CHANGED") NP_ThreatFrame:RegisterEvent("RAID_ROSTER_UPDATE") NP_ThreatFrame:RegisterEvent("ZONE_CHANGED_NEW_AREA") NP_ThreatFrame:RegisterEvent("PLAYER_ENTERING_WORLD") NP_ThreatFrame:SetScript("OnEvent", function() if event == "CHAT_MSG_ADDON" then local prefix = arg1 local msg = arg2 or "" local sender = arg4 if string_find(msg, "TMTv1=") then GP_HandleTankModePacket(msg) end if string_find(msg, "TWTv4=") then GP_HandleThreatPacket(msg) end if prefix == NP_ADDON_PREFIX and msg and sender then GP_HandleTankModeMessage(sender, msg) end elseif event == "PARTY_MEMBERS_CHANGED" or event == "RAID_ROSTER_UPDATE" or event == "ZONE_CHANGED_NEW_AREA" or event == "PLAYER_ENTERING_WORLD" then NanamiPlates_Threat.BroadcastTankMode(true) end end) NanamiPlates.Threat = NanamiPlates_Threat