第一次发版v0.1.0
This commit is contained in:
204
Threat.lua
Normal file
204
Threat.lua
Normal file
@@ -0,0 +1,204 @@
|
||||
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
|
||||
Reference in New Issue
Block a user