205 lines
6.1 KiB
Lua
205 lines
6.1 KiB
Lua
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
|