Files
Nanami-DPS/NanamiPlates-ThreatIntegration.md
2026-03-25 00:57:35 +08:00

222 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Nanami-Plates 仇恨系统对接需求文档
## 概述
Nanami-DPS 已完成仇恨监控系统的全面重做采用自适应双轨混合架构TWThreat API 服务端直读 + 本地战斗日志推演)。本文档定义 Nanami-Plates 姓名板插件需要对接的数据接口、渲染要求和交互规范。
---
## 一、数据接口
### 1.1 全局引用
```lua
local TE = NanamiDPS.ThreatEngine -- 仇恨引擎实例
local TC = NanamiDPS.ThreatCoefficients -- 系数常量
```
### 1.2 核心 API 函数
| 函数签名 | 返回值 | 说明 |
|----------|--------|------|
| `TE:GetActiveTargetKey()` | `string``nil` | 获取当前激活目标的唯一键优先API目标键回退到本地目标 |
| `TE:GetCurrentTargetKey()` | `string``nil` | 获取玩家当前 target 的唯一键 |
| `TE.GetTargetKey(unitID)` | `string``nil` | 根据 unitID 计算目标唯一键(格式: `G:GUID` / `I:RaidIcon` / `V:Name:MaxHP` |
| `TE:GetThreatList(targetKey)` | `table` | 返回按仇恨降序排列的列表,每项包含 `{name, threat, tps, perc, isTanking, isMelee, relativePercent}` |
| `TE:GetOTStatus(targetKey)` | `table` | 返回当前玩家的 OT 分析: `{safe, pct, threshold, otPoint, buffer, myThreat, tankThreat, tankName, isMelee}` |
| `TE:IsAPIActiveForTarget(targetKey)` | `boolean` | 判断该目标是否使用服务端 API 数据(精确模式) |
| `TE.IsEliteOrBoss(unitID)` | `boolean` | 判断目标是否为精英/Boss |
| `TE.IsInGroup()` | `boolean` | 判断玩家是否在小队/团队中 |
### 1.3 状态字段(只读)
| 字段 | 类型 | 说明 |
|------|------|------|
| `TE.inCombat` | `boolean` | 当前是否在战斗中 |
| `TE.apiActive` | `boolean` | API 直读引擎是否激活 |
| `TE.playerName` | `string` | 当前玩家名称 |
| `TE.playerClass` | `string` | 当前玩家职业 token大写 |
| `TE.targets` | `table` | 三维数据表,结构见下文 |
### 1.4 三维数据结构
```
TE.targets[targetKey] = {
players = {
[playerName] = {
threat = number, -- 绝对仇恨值
tps = number, -- 每秒仇恨制造率
isTanking = boolean, -- 是否持有仇恨
isMelee = boolean, -- 是否在近战范围
perc = number, -- 相对百分比 (0-100)
history = table, -- TPS 计算用历史数据
lastThreatTime = number, -- 最后一次仇恨更新时间
},
...
},
tankName = string, -- 当前坦克名称
tankThreat = number, -- 坦克仇恨值
lastUpdate = number, -- 最后更新时间戳
source = string, -- "api" | "api_tm" | "local"
}
```
### 1.5 回调注册
```lua
-- 仇恨数据更新时触发API 报文到达或本地计算完成)
NanamiDPS:RegisterCallback("threat_update", "NanamiPlates", function()
-- 在此刷新姓名板仇恨显示
end)
```
### 1.6 OT 阈值常量
```lua
TC.OT_MELEE_THRESHOLD = 1.10 -- 近战 110%
TC.OT_RANGED_THRESHOLD = 1.30 -- 远程 130%
```
---
## 二、姓名板渲染要求
### 2.1 仇恨百分比指示器
**位置**: 锚定在每个敌方姓名板的名称文字正上方或正下方
**格式**: `XX%` 数字文本,字号 10-12
**更新频率**: 跟随 `threat_update` 回调,约 0.5 秒一次
### 2.2 颜色渐变规则
根据玩家在当前目标上的仇恨百分比(相对于 OT 阈值)分级着色:
| 百分比区间 | 颜色 | 含义 |
|-----------|------|------|
| 0% - 49% | 绿色 `(0.2, 1.0, 0.2)` | 安全 |
| 50% - 79% | 黄色 `(1.0, 1.0, 0.0)` | 警戒 |
| 80% - 100%+ | 红色 `(1.0, 0.2, 0.0)` | 危险,即将 OT |
### 2.3 仇恨条背景色
为已持有仇恨(`isTanking = true`)的目标姓名板生命条添加边框高亮:
- 坦克视角: 正在坦克的怪物边框为**绿色**
- DPS/治疗视角: 自己正在被攻击的怪物边框为**红色**
### 2.4 数据来源标识(可选)
在仇恨百分比旁边显示小图标区分数据来源:
- API 数据: 小圆点 (绿色) — 表示服务端精确数据
- 本地推算: 小圆点 (灰色) — 表示基于战斗日志估算
---
## 三、Tank Mode 姓名板增强
当玩家为坦克角色(防御姿态/巨熊形态)时:
### 3.1 多目标仇恨概览
在每个姓名板上显示**仇恨排名第二**的玩家名称和百分比,格式:
```
[怪物名称]
██████████████ 100% ← 仇恨条(自己)
紧随: Mage_A 85% ← 第二名信息
```
### 3.2 松动目标高亮
如果某个怪物上的第二名仇恨超过坦克仇恨的 80%(接近 110% OT 线),该姓名板整体加红色闪烁边框,提示坦克需要立即补仇恨技能。
### 3.3 快速目标切换SuperWoW 依赖)
如果检测到 SuperWoW/SuperAPI 可用:
- 姓名板上的仇恨区域可点击
- 点击后调用 `TargetUnit``SetTarget` 切换到该怪物
- 方便坦克无需 TAB 键即可快速切换目标
---
## 四、Healer Mode 姓名板增强
当玩家为治疗角色时:
### 4.1 主坦锁定
允许设置一个"主坦克焦点"(通过 `/nanami mt [name]` 或右键团队框架)
### 4.2 未稳固目标标记
在姓名板上对**主坦克仇恨不是最高**的怪物添加特殊标记(橙色感叹号),提示治疗者该怪物仇恨不稳定,可能随时转向治疗者。
---
## 五、性能要求
| 项目 | 要求 |
|------|------|
| 姓名板遍历频率 | 最大 0.5 秒一次(跟随 `threat_update` 回调) |
| 内存开销 | 单个姓名板附加元素不超过 3 个 FontString + 1 个 Texture |
| 不可见姓名板 | 必须隐藏对应的仇恨指示器,避免孤立 UI 元素 |
| 战斗外 | 所有仇恨指示器隐藏,不做任何查询 |
| 数据清理 | 离开战斗后清除所有姓名板附加元素 |
---
## 六、对接代码示例
```lua
-- Nanami-Plates 中的对接示例
local TE = NanamiDPS and NanamiDPS.ThreatEngine
local TC = NanamiDPS and NanamiDPS.ThreatCoefficients
-- 获取某个 nameplate 对应怪物的玩家仇恨百分比
local function GetMyThreatPct(unitID)
if not TE or not TE.inCombat then return nil end
local targetKey = TE.GetTargetKey(unitID)
if not targetKey then return nil end
local td = TE.targets[targetKey]
if not td then return nil end
local pd = td.players[TE.playerName]
if not pd then return nil end
return pd.perc, pd.isTanking, pd.isMelee
end
-- 获取该怪物仇恨第二名
local function GetSecondThreat(unitID)
if not TE or not TE.inCombat then return nil end
local targetKey = TE.GetTargetKey(unitID)
if not targetKey then return nil end
local list = TE:GetThreatList(targetKey)
if list and list[2] then
return list[2].name, list[2].perc, list[2].threat
end
return nil
end
-- 注册回调
if NanamiDPS then
NanamiDPS:RegisterCallback("threat_update", "NanamiPlates_Threat", function()
-- 遍历所有可见姓名板,刷新仇恨数据
NanamiPlates:RefreshAllThreatIndicators()
end)
end
```
---
## 七、版本兼容性
- **必须依赖**: Nanami-DPS >= 1.0.0(含 ThreatEngine 模块)
- **可选依赖**: SuperWoW / SuperAPI用于姓名板高级交互
- **WoW 客户端**: 1.12.x (Turtle WoW)
- **Lua 环境**: 不支持现代 Lua 特性(使用 `table.getn` 代替 `#``pairs` 代替 `next`