内置属性实现参考
早期 WA1 的属性下拉内置了近百种预置类型(2026-08 删除,属性系统改为「自定义代码 + 属性库」)。 本文档从历史版本中提取全部旧实现,并按最新版 WA1 调整为可直接粘贴的自定义代码,供模块作者参考。 客户端:正式服(Midnight)与怀旧服都支持、共用一条代码路径。下面的代码按正式服的 API 面与 secret 规则书写——secret 消毒(
SuperDPS.SN)在怀旧服是无副作用的空转,照写即可;但正式服独有的接口(如C_AssistedCombat)在怀旧服取不到值,个别C_Spell结构体字段两端也可能不同,搬到怀旧服请先在游戏里验一次。来源:早期 WA1 版本的属性表与插件查询函数库,2026-08-19 整理。
在最新版 WA1 中如何使用
Section titled “在最新版 WA1 中如何使用”- 模块编辑器 → 属性卡片 → 属性下拉选「自定义代码」(或从属性库选现成条目)。
- 点「编辑」粘贴本文档的代码;参数列填逗号分隔的值(最多 3 段),代码里以
arg1/arg2/arg3读取——纯数字段按数字传入,其余按字符串,空段为nil。 - 代码的
return值经条码带回传电脑端,与其他属性一致。
同一段代码可被多行属性复用(代码写 arg1,两行参数分别填 player / target)。
属性代码 vs 初始化代码(性能守则)
Section titled “属性代码 vs 初始化代码(性能守则)”- 属性代码是高频热路径:每 0.02 秒执行一次、每行属性各执行一次。里面只做读取与必要查询,不要放一次性工作——
CreateFrame/RegisterEvent、建共享表、定义共享函数等,即使加了if not ...守卫,每帧也在白跑判断,漏写守卫更会每帧泄漏一个帧对象。 - 一次性工作放模块的「初始化代码」(模块编辑器 → 初始化代码按钮):它在插件加载时执行一次,先于属性注册,与属性代码同环境(同 chunk,可用兼容层与
SuperDPS.*接口),适合创建事件帧、初始化共享表、定义共享函数。本文档需要事件跟踪的条目(代码 1/6/12)与多行共用重逻辑的条目(代码 22)均已按「初始化代码 + 属性代码」两段给出。 - 初始化代码保留
if not SuperDPS.XxxFrame守卫是刻意的:插件重装/重载时初始化代码会再次执行,帧对象不可销毁,守卫防止重复创建与重复计数;这个判断只在加载时跑一次,无热路径成本。 - 初始化代码抛错会中断整个插件启动(它不在属性那层 pcall 保护内),事件回调内注意 nil 守卫、逻辑要稳。
旧模块迁移:旧 .wa1 文件里属性行的 "p" 键是下表的「旧 Key」;载入新版后这些行会被归为自定义代码,但其值仍是旧「参数」而非代码,需按本文档补上代码、把旧值移入参数列。
自定义代码可用的环境
Section titled “自定义代码可用的环境”- 与插件同 chunk,可直接调 WoW API;
GetSpellInfo/GetSpellCooldown/GetSpellCharges/UnitAura/UnitBuff/UnitDebuff是已适配C_Spell/C_UnitAuras新接口的兼容层(旧多返回值签名)。 - 保留接口:
SuperDPS.GetUnitAura/GetUnitBuff/GetUnitDebuff(按名称或法术 ID 查光环,duration/expirationTime/count 已消毒)、SuperDPS.SN(v, "标记")(受保护值消毒,归 0)、SuperDPS.HekeliPrimary、SuperDPS.Prop(共享值表)。 - 函数体内
UnitHealth/UnitHealthMax/UnitPower/UnitPowerMax是原生 Raw 版本,战斗中可能返回受保护值。
Midnight 数值保护三规则(旧实现失效的主因)
Section titled “Midnight 数值保护三规则(旧实现失效的主因)”- 直传/传参/真值判断可以:受保护值可直接
return(条带照常回传)、可X or 0、if not X(非 boolean)。 - 比较与算术必先消毒:
>、==、四则运算碰到受保护值立刻抛错,先过SuperDPS.SN(v, "标记")(受保护归 0)。 - 例外:
C_Spell.GetSpellCooldown()的isActive/isOnGCD官方保证永不受保护,可安全做逻辑。
旧实现中大量 %255、×100、/100 缩放是旧「像素色块」单字节通道的遗留;新条码带支持完整数值,已一律去除——沿用旧模块阈值时注意单位换算(各条目有注记)。
图例:📦 = 新版属性库已有预置条目,直接用;✅ = 用下方编号代码;❌ = Midnight 下不可实现,已注明原因。
| 旧属性 | 旧 Key | 旧实现 | 新版 |
|---|---|---|---|
| 战斗中 In Combat | PropC4Ca | SuperDPS.InCombatLockdown() |
📦 预置「战斗中」 |
| 目标背后 Behind Target | PropC4Cb | getBehind()(UI_ERROR_MESSAGE 事件跟踪) |
✅ 代码 1 |
| 公共冷却 Global CD | PropC81E | GCD()(61304 冷却 ×100,>255 归 0) |
📦 预置「公共冷却」(单位改为秒) |
| WA 全局属性 | PropC81F | WaProp(name) 读 SuperDPS.Prop |
📦 预置「全局属性」 |
| Hekili 推荐 | PropC82F | 客户端专用通道(已删) | 📦 预置「Hekili推荐」;另有零依赖的「内置推荐」 |
代码 1:目标背后(参数:无)。旧版靠插件主事件帧记录「必须在目标背后」报错;新版插件已不注册该事件,由模块自建事件帧,语义不变(报错后 0.6 秒内视为不在背后)。
放入初始化代码:
if not SuperDPS.BehindFrame then SuperDPS.BehindAt = 0 local f = CreateFrame("Frame") f:RegisterEvent("UI_ERROR_MESSAGE") f:SetScript("OnEvent", function(_, _, _, msg) if msg == SPELL_FAILED_NOT_BEHIND then SuperDPS.BehindAt = GetTime() end end) SuperDPS.BehindFrame = fend属性代码:
if GetTime() - SuperDPS.BehindAt > 0.6 then return 1 endreturn 0旧版公共冷却返回「厘秒」(剩余秒 ×100、超 255 归 0),预置「公共冷却」返回秒;沿用旧阈值除以 100 即可。
| 旧属性 | 旧 Key | 旧实现 | 新版 |
|---|---|---|---|
| 自身血量百分比 | PropEccb | getHeal("player")(Health/Max×100) |
📦 预置「生命百分比」(0~1 小数) 或 ✅ 代码 2 |
| 目标血量百分比 | PropA87F | getHeal("target") |
同上,参数 target |
| 宠物血量百分比 | Prop1679 | getHeal("pet") |
同上,参数 pet |
| 目标实际血量(千) | PropE4Da | getHeal2 = UnitHealth/1000 |
✅ 代码 3(直传原值,除法会撞保护) |
| 目标实际血量(万) | PropE4Db | getHeal3 = UnitHealth/10000 |
同代码 3 |
旧版 UnitHealth/UnitHealthMax 除法在 Midnight 战斗中直接抛错(受保护值不可运算)。
代码 2:血量百分比(0~100 旧刻度)(参数:player / target / pet)。经 SN 消毒后才能乘 100,战斗中若被保护按 0;若能接受 0~1 刻度,优先用预置「生命百分比」(直传,不受消毒降级影响):
local g = UnitGUID(arg1)if not g then return 0 endlocal v = SuperDPS.SN(UnitPercentHealthFromGUID(g), "healpct", arg1)return v * 100代码 3:实际血量(参数:target)。直接回传原值(受保护值也能上条带),千/万换算放到电脑端做:
return UnitHealth(arg1)三、能量与距离
Section titled “三、能量与距离”| 旧属性 | 旧 Key | 旧实现 | 新版 |
|---|---|---|---|
| 自身主能量 | Prop8F14 | getPower("player")(百分比) |
✅ 代码 4(百分比,降级) 或 📦「能量」(直传) |
| 自身能量(按类型) | PropC9F0 | UnitPower("player", 类型) |
📦 预置「能量」/「连击点」,参数 player,类型 |
| 目标能量(按类型) | Prop45C4 | UnitPower("target", 类型) |
同上,参数 target,类型 |
| 自身能量百分比 | PropD3D9 | getPowerById("player", 类型) |
✅ 代码 4 |
| 目标能量百分比 | Prop6512 | getPowerById("target", 类型) |
✅ 代码 4 |
| 目标距离 | Prop45C5 | getTargetRange()(多 API 逐级探测) |
✅ 代码 5(降级) 或 📦「技能射程内」 |
| 目标可施法(视线) | Prop45C6 | UnitInLos2()(报错事件跟踪) |
✅ 代码 6 |
能量类型对照(旧下拉提示):-2 HealthCost,0 法力,1 怒气,2 集中,3 能量,4 连击点,5 符文,6 符能,7 灵魂碎片,8 星能,9 神圣能量,11 漩涡值,12 真气,13 疯狂值,16 奥术充能,17 恶魔怒气,18 痛苦,不填 = 当前主资源。
代码 4:能量百分比(参数 1:单位,参数 2:类型可空)。战斗中双值被保护则按 0。新版属性库已有预置「能量百分比」📦:正式服有 UnitPowerPercent 就直传,没有才退回本段相除写法;建议尽量用直传版在电脑端判断:
local p = SuperDPS.SN(UnitPower(arg1, arg2), "powpct", arg1)local m = SuperDPS.SN(UnitPowerMax(arg1, arg2), "powpct", arg1)if m == 0 then return 0 endreturn p / m * 100代码 5:目标距离(参数:无;无目标/读不到返回 255,同旧语义)。UnitDistanceSquared 在 Midnight 对敌对单位可能受限,可用性以实测为准;按具体技能判射程请改用预置「技能射程内」:
if not UnitExists("target") then return 255 endlocal ok, d2 = pcall(UnitDistanceSquared, "target")if ok then d2 = SuperDPS.SN(d2, "range") if d2 > 0 then return math.sqrt(d2) endendreturn 255代码 6:目标可施法(视线/超距冷却)(参数:无)。旧语义:目标存在且可见,且 1.5 秒内没对它报过「超出范围/视线阻挡」。
放入初始化代码(与代码 1 共用一个帧也可以——同一帧可注册多个事件、回调里分支处理,两段合并时只建一个帧):
if not SuperDPS.LosFrame then SuperDPS.LosSeen = {} local f = CreateFrame("Frame") f:RegisterEvent("UI_ERROR_MESSAGE") f:SetScript("OnEvent", function(_, _, _, msg) if msg == ERR_OUT_OF_RANGE or msg == SPELL_FAILED_LINE_OF_SIGHT then local g = UnitGUID("target") if g then SuperDPS.LosSeen[g] = GetTime() end end end) SuperDPS.LosFrame = fend属性代码:
local g = UnitGUID("target")if not g or not UnitIsVisible("target") then return 0 endlocal t = SuperDPS.LosSeen[g]if not t or GetTime() - t >= 1.5 then return 1 endreturn 0四、连击点、DK 符文与宠物
Section titled “四、连击点、DK 符文与宠物”| 旧属性 | 旧 Key | 旧实现 | 新版 |
|---|---|---|---|
| 连击点 | PropC20A | GetComboPoints("player","target") |
📦 预置「连击点」(UnitPower(unit,4)) |
| DK 可用符文总数 | PropC20B | GetRune() |
✅ 代码 7 |
| DK 符文槽冷却 | PropC20B2 | GetRuneByType2(槽位) |
✅ 代码 8 |
| DK 鲜血符文 | PropC20C | GetRuneByType(1) |
❌ 正式服自军团起无符文类型之分;怀旧服客户端仍有类型,但旧实现依赖暴雪符文框架内部字段,需自行改写验证 |
| DK 冰霜符文 | PropC20D | GetRuneByType(3) |
❌ 同上 |
| DK 邪恶符文 | PropC20E | GetRuneByType(2) |
❌ 同上 |
| DK 死亡符文 | PropC20F | GetRuneByType(4) |
❌ 同上 |
| 有召唤宠物 | PropC20G | hasPet()(HasPetUI) |
📦 预置「有宠物」;需区分猎人宠物用 ✅ 代码 9 |
符文冷却在战斗中有受保护风险(官方预置因此未移植),以下实现已消毒,被保护时按 0:
代码 7:可用符文总数(参数:无):
local n = 0for i = 1, 6 do local _, _, ready = GetRuneCooldown(i) if SuperDPS.SN(ready, "rune") == true then n = n + 1 endendreturn n代码 8:符文槽冷却剩余(参数:1~6):
local start, duration = GetRuneCooldown(arg1)start = SuperDPS.SN(start, "runecd")duration = SuperDPS.SN(duration, "runecd")if start == 0 or duration == 0 then return 0 endlocal remain = start + duration - GetTime()if remain > 0 then return remain endreturn 0代码 9:有召唤宠物(旧三态语义)(参数:无;2=猎人宠物,1=其他宠物,0=无):
local hasUI, isHunterPet = HasPetUI()if hasUI and isHunterPet then return 2 endif hasUI then return 1 endreturn 0五、法术与物品
Section titled “五、法术与物品”| 旧属性 | 旧 Key | 旧实现 | 新版 |
|---|---|---|---|
| 远程武器速度 | PropC51C | UnitRangedDamage("player")*100 |
❌ 攻速家族在 Midnight 返回受保护值(同挥砍计时器死因) |
| 技能冷却 | PropAab3 | GetSpellTime(id)(start+duration−now) |
📦 预置「技能冷却」/「技能可用」(旧算法战斗中撞保护) |
| 技能充能冷却 | PropAab4 | GetSpellTime2(id) |
✅ 代码 10 |
| 技能施法时间 | Prop9Bf3 | SkillCastingTime(id)(实测并缓存) |
✅ 代码 11 |
| 技能施放后经过时间 | Prop9Bf4 | getSpellCastTime(id)(事件跟踪) |
✅ 代码 12 |
| 技能施放后经过时间(按目标) | Prop9Bf5 | getSpellCastTime2(id) |
✅ 代码 12(注释切换) |
| DoT 跳伤计时(按目标) | Prop9Bf6 | getSpellCastDamage(CLEU 被封后已是 debuff 近似) |
📦 预置「自施减益剩余」 |
| 技能充能层数 | PropC74D | GetSpellCharges(id) |
📦 预置「技能充能」 |
| 技能可用次数 | Prop70Ef | GetSpellCount(id) |
✅ 代码 13 |
| 物品数量 | Prop6F49 | GetItemCount(id) |
📦 预置「物品数量」 |
| 团队增益人数 | Prop1F0E | getRaidBuffCount(id) |
✅ 代码 14 |
| 团队增益人数(自施) | Prop98F1 | getRaidBuffCountByPlayer(id) |
✅ 代码 14,参数加 ,1 |
代码 10:技能充能冷却剩余(参数:技能 ID):
local _, _, start, duration = GetSpellCharges(arg1)start = SuperDPS.SN(start, "chargecd")duration = SuperDPS.SN(duration, "chargecd")if start == 0 or duration == 0 then return 0 endlocal remain = start + duration - GetTime()if remain > 0 then return remain endreturn 0代码 11:技能施法时间(参数:技能 ID;返回秒,旧版单位是毫秒/10 即厘秒 ×10,沿用旧阈值注意换算)。改用法术静态数据,不再实测缓存:
local info = C_Spell.GetSpellInfo(arg1)if not info then return 0 endreturn SuperDPS.SN(info.castTime, "casttime") / 1000代码 12:技能施放后经过时间(参数:技能 ID;上限 120,从未施放返回 120,同旧语义)。旧版靠插件主事件帧,新版由模块自建;注意键从法术名改为法术 ID。
放入初始化代码:
if not SuperDPS.CastLogFrame then SuperDPS.CastAt = {} SuperDPS.CastAtTarget = {} local f = CreateFrame("Frame") f:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED") f:SetScript("OnEvent", function(_, _, unit, _, spellID) if unit == "player" and spellID then SuperDPS.CastAt[spellID] = GetTime() SuperDPS.CastAtTarget[spellID .. "_" .. (UnitGUID("target") or "")] = GetTime() end end) SuperDPS.CastLogFrame = fend属性代码:
local t = SuperDPS.CastAt[arg1]-- 「按目标」版:改用下一行(同一技能对不同目标分别计时)-- local t = SuperDPS.CastAtTarget[arg1 .. "_" .. (UnitGUID("target") or "")]if not t then return 120 endreturn math.min(GetTime() - t, 120)代码 13:技能可用次数(参数:技能 ID;如灭杀标记类「还能施放几次」):
return C_Spell.GetSpellCastCount and C_Spell.GetSpellCastCount(arg1) or 0代码 14:团队增益人数(参数 1:光环 ID 或名称,参数 2:填 1 只统计自己施放的):
local n = 0for i = 1, 40 do local u = "raid" .. i if UnitExists(u) and not UnitIsDeadOrGhost(u) and UnitIsPlayer(u) then local name, _, _, _, _, _, source = SuperDPS.GetUnitBuff(u, arg1) if name and (not arg2 or source == "player") then n = n + 1 end endendreturn n六、光环(增益/减益)
Section titled “六、光环(增益/减益)”旧版这一族共 31 个属性,全部是「单位 × 增益/减益 × 剩余时间/层数 × 是否限自施」的组合;新版用 4 段通用代码 + 参数覆盖全部组合。单位填 player/pet/target/focus,光环填法术 ID(推荐,免语言差异)或名称。
| 旧属性(按组) | 旧 Key | 新版 |
|---|---|---|
| 自身/宠物增益剩余 | Prop6Ea9 / Prop3417 | 📦 预置「增益剩余」,参数 player,ID / pet,ID |
| 自身增益层数 | PropC16A | 📦 预置「增益层数」 |
| 自身增益剩余/层数(自施) | Prop6364 / Prop182B | ✅ 代码 15/16,参数加 ,1 |
| 自身减益剩余/层数 | PropE369 / Prop1C38 | 📦「减益剩余」/「减益层数」,参数 player,ID |
| 目标增益剩余/层数(±自施) | Prop19Ca / PropA5Bf / PropA577 / PropD67D | ✅ 代码 15/16,单位 target |
| 焦点增益剩余/层数(±自施) | Prop19Ca1 / PropA5Bf1 / PropA5771 / PropD67D1 | ✅ 代码 15/16,单位 focus |
| 目标减益剩余/层数(±自施) | PropD645 / Prop3416 / PropA1D0 / Prop17E6 | 📦「减益剩余」「减益层数」「自施减益剩余」或 ✅ 代码 17 |
| 焦点减益剩余/层数(±自施) | PropD6451 / Prop34161 / PropA1D01 / Prop17E61 | 同上,单位 focus |
| 增益图标剩余/层数(±自施) | Prop3C59 / PropB6D7 / Prop3769 / Prop1Ff1(自身) Prop8E29 / Prop4E73 / Prop02E7 / Prop33E7(目标) |
✅ 代码 18(增益+减益全表搜索) |
代码 15:增益剩余时间(通用)(参数:单位,光环[,1限自施])。保留旧语义:永久增益与刚到期返回 1,不存在返回 0——预置「增益剩余」对永久增益返回 0,逻辑依赖此差异的旧模块用本版:
local name, _, _, _, _, expire, source = SuperDPS.GetUnitBuff(arg1, arg2)if not name or (arg3 and source ~= "player") then return 0 endexpire = SuperDPS.SN(expire, "bufftime", arg1)local remain = expire - GetTime()if remain < 0 then return 1 endreturn remain代码 16:增益层数(通用)(参数:单位,光环[,1限自施]):
local name, _, count, _, _, _, source = SuperDPS.GetUnitBuff(arg1, arg2)if not name or (arg3 and source ~= "player") then return 0 endreturn count or 0代码 17:减益剩余/层数(通用)(参数:单位,光环[,1限自施])。减益无「到期→1」钳制(历史行为,与增益版刻意不同):
local name, _, count, _, _, expire, source = SuperDPS.GetUnitDebuff(arg1, arg2)if not name or (arg3 and source ~= "player") then return 0 endexpire = SuperDPS.SN(expire, "debufftime", arg1)if expire == 0 then return 0 endreturn expire - GetTime()-- 层数版:删掉上面三行,改为 return count or 0代码 18:光环图标剩余(增益+减益全表搜索)(参数:单位,光环[,1限自施])。旧「图标」族不区分增益/减益、按名称或 ID 全搜——对应新版不带过滤器的 GetUnitAura:
local name, _, count, _, _, expire, source = SuperDPS.GetUnitAura(arg1, arg2)if not name or (arg3 and source ~= "player") then return 0 endexpire = SuperDPS.SN(expire, "auratime", arg1)local remain = expire - GetTime()if remain < 0 then return 1 endreturn remain-- 层数版:删掉上面四行,改为 return count or 0| 旧属性 | 旧 Key | 旧实现 | 新版 |
|---|---|---|---|
| 姓名板自施减益数 | Prop17E7 | getNamePlateDebuffCountByPlayer(id) |
✅ 代码 19 |
| 姓名板距离内数量 | Prop17E8 | getNamePlateRangeCount(码数) |
✅ 代码 20(距离 API 有风险) 或 📦「敌对目标数」(不限距) |
姓名板单位受游戏内「敌对姓名板」显示开关(默认 V 键)与显示距离限制。
代码 19:身上有我 DoT 的姓名板数量(参数:减益 ID;AOE 补 DoT 判断):
local n = 0for i = 1, 40 do local u = "nameplate" .. i if UnitExists(u) then local name, _, _, _, _, _, source = SuperDPS.GetUnitDebuff(u, arg1) if name and source == "player" then n = n + 1 end endendreturn n代码 20:指定码数内姓名板数量(参数:码数,如 8)。依赖 UnitDistanceSquared,Midnight 对敌对单位可用性以实测为准,读不到的单位不计入:
local n = 0local r2 = arg1 * arg1for i = 1, 40 do local u = "nameplate" .. i if UnitExists(u) then local ok, d2 = pcall(UnitDistanceSquared, u) if ok then d2 = SuperDPS.SN(d2, "nprange") if d2 > 0 and d2 <= r2 then n = n + 1 end end endendreturn n| 旧属性 | 旧 Key | 旧实现 | 新版 |
|---|---|---|---|
| 目标施法代码 | PropF717 | CastingInfo("target")(ID%255) |
📦 预置「目标施法」(完整 ID,不再 %255) |
| 焦点施法代码 | PropF718 | CastingInfo("focus") |
同上,参数 focus |
| 自身施法代码 | Prop6C83 | CastingInfo("player") |
同上,参数 player |
| 自身施法进度 | Prop7F39 | CastingTime("player")((end−now)/100) |
📦 预置「施法剩余」(单位秒),参数 player |
| 目标施法进度 | Prop7F38 | CastingTime("target") |
同上,参数 target |
旧「施法代码」把法术 ID 对 255 取模(单字节通道限制),旧模块里按取模值写的判断需换成完整法术 ID;旧「施法进度」单位是 0.1 秒(毫秒/100),预置版是秒。
| 旧属性 | 旧 Key | 旧实现 | 新版 |
|---|---|---|---|
| 目标在技能射程内 | PropD9D4 | IsSpellInRange(id) |
📦 预置「技能射程内」 |
| 队友驱散类型检查 | Prop67C6 | GetDeBuffType(类型) |
✅ 代码 21 |
| 最低血量队友编号 | Prop642E | getDamagePlayer() |
✅ 代码 22 |
| 最低血量队友掉血比例 | PropF457 | getDamagePlayerHealth() |
✅ 代码 22(返回值切换) |
| 最低血量队友编号(有增益) | PropC0C7 | getDamagePlayerBuff(id) |
✅ 代码 22,模式 hasBuff |
| 最低血量掉血比例(有增益) | Prop2838 | getDamagePlayerHealthBuff(id) |
同上 |
| 最低血量队友编号(无增益) | Prop9A11 | getDamagePlayerNoBuff(id) |
✅ 代码 22,模式 noBuff |
| 最低血量掉血比例(无增益) | PropD82C | getDamagePlayerHealthNoBuff(id) |
同上 |
| 最低血量队友编号(无减益) | PropA684 | getDamagePlayerNoDeBuff(id) |
✅ 代码 22,模式 noDebuff |
| 最低血量掉血比例(无减益) | PropB53B | getDamagePlayerHealthNoDeBuff(id) |
同上 |
编号约定(与旧版一致,用于电脑端按编号选宏目标):1=自己,24,5=party1640;单人只算自己,小队算自己+party,团队只算 raid 单位。45=raid1
代码 21:队友驱散类型检查(参数:Curse/Disease/Magic/Poison;返回首个中招队友编号,无人中招返回 0):
local function hit(unit) if UnitIsDeadOrGhost(unit) or not UnitIsPlayer(unit) then return false end for j = 1, 40 do local name, _, _, dispelType = UnitDebuff(unit, j) if not name then return false end if dispelType == arg1 then return true end end return falseendif UnitPlayerOrPetInRaid("player") then for i = 1, 40 do local u = "raid" .. i if UnitExists(u) and hit(u) then return i + 5 end endelseif UnitPlayerOrPetInParty("player") then if hit("player") then return 1 end for i = 1, 4 do local u = "party" .. i if UnitExists(u) and hit(u) then return i + 1 end endelseif hit("player") then return 1endreturn 0代码 22:最低血量队友(全家族统一)(参数 1:模式,空/hasBuff/noBuff/noDebuff;参数 2:光环 ID,模式为空可不填)。8 个旧属性共用同一扫描逻辑,按「初始化代码定义共享函数 + 属性行薄调用」组织,多行同用零重复。Midnight 重要提示:血量百分比经消毒,战斗中被保护的成员按满血跳过,激烈战斗中此族可能整体降级——官方预置刻意未移植,治疗模块谨慎依赖。旧版还叠加了视线过滤(报错事件),需要的话按代码 6 的 LosSeen 自行加一段。另一处语义微调:旧版掉血基准为 -1(全员满血也会选中首个合格成员),本版基准为 0(无人掉血返回 0)。
放入初始化代码:
-- 最低血量队友扫描,供多行属性共用。返回: 编号, 掉血百分比(0~100)function SuperDPS.ScanLowHp(mode, aura) local best, bestDamage = 0, 0 local function consider(idx, unit) if not UnitExists(unit) or UnitIsDeadOrGhost(unit) or not UnitIsPlayer(unit) then return end if mode == "hasBuff" or mode == "noBuff" then local name = SuperDPS.GetUnitBuff(unit, aura) if (mode == "hasBuff") ~= (name ~= nil) then return end elseif mode == "noDebuff" then if SuperDPS.GetUnitDebuff(unit, aura) then return end end local g = UnitGUID(unit) if not g then return end local hp = SuperDPS.SN(UnitPercentHealthFromGUID(g), "lowhp", unit) if hp == 0 then return end -- 死亡/读不到/受保护 → 跳过 local damage = (1 - hp) * 100 if damage > bestDamage then best, bestDamage = idx, damage end end if UnitPlayerOrPetInRaid("player") then for i = 1, 40 do consider(i + 5, "raid" .. i) end else consider(1, "player") if UnitPlayerOrPetInParty("player") then for i = 1, 4 do consider(i + 1, "party" .. i) end end end return best, bestDamageend属性代码(「编号」版):
local idx = SuperDPS.ScanLowHp(arg1, arg2)return idx属性代码(「掉血比例」版):
local _, damage = SuperDPS.ScanLowHp(arg1, arg2)return damage| 旧属性 | 旧 Key | 旧实现 | 新版 |
|---|---|---|---|
| 主手武器 CD | Prop9F61 | getSwingTimer("main") |
❌ UnitAttackSpeed 在 Midnight 返回受保护值,挥砍计时无法实现(实测,整个子系统因此删除) |
| 主手武器 CD(正值) | Prop9F62 | getSwingTimer2("main") |
❌ 同上 |
| 副手武器 CD | Prop72B3 | getSwingTimer("off") |
❌ 同上 |
| 远程武器 CD | Prop072B | getSwingTimer("ranged") |
❌ 同上 |
| 主手临时附魔 ID | Prop66F0 | GetWeaponEnchantInfoMain()(%255) |
✅ 代码 23 |
| 副手临时附魔 ID | Prop093F | GetWeaponEnchantInfoOff() |
✅ 代码 23 |
代码 23:武器临时附魔 ID(参数:4 主手 / 8 副手;完整 ID,不再 %255,旧模块按取模值写的判断需换成完整附魔 ID):
local id = select(arg1, GetWeaponEnchantInfo())return id or 0十一、UI、地图与其他
Section titled “十一、UI、地图与其他”| 旧属性 | 旧 Key | 旧实现 | 新版 |
|---|---|---|---|
| 按钮高亮检测 | Prop44F6 | checkButtonOverlay(按钮) |
✅ 代码 24 |
| UI 可见检查 | Prop44F7 | UiCheck(框体) |
✅ 代码 25 |
| 当前地图 ID | Prop44F8 | MapId()(%255) |
✅ 代码 26 |
| 团队总掉血比例 | Prop03Af | getAllHealth()(平均掉血%) |
✅ 代码 27(同代码 22 的降级提示) |
| 法术强度 | Prop0311 | GetSpellPower(除数) |
✅ 代码 28 |
代码 24:按钮高亮检测(参数:ActionButton1~ActionButton12)。旧版查 overlay 字段;新版客户端的技能高亮框架字段已改名,两者都查:
local b = _G[arg1]if b and (b.overlay or b.SpellActivationAlert) then return 1 endreturn 0代码 25:UI 可见检查(参数:框体全局名,如 PVPFrame):
local f = _G[arg1]if f and f.IsVisible and f:IsVisible() then return 1 endreturn 0代码 26:当前地图 ID(参数:无;完整 ID,不再 %255):
return C_Map.GetBestMapForUnit("player") or 0代码 27:团队平均掉血百分比(参数:无;0~100):
local total, n = 0, 0local function acc(unit) if not UnitExists(unit) or UnitIsDeadOrGhost(unit) then return end local g = UnitGUID(unit) if not g then return end local hp = SuperDPS.SN(UnitPercentHealthFromGUID(g), "allhp", unit) if hp == 0 then return end total = total + (1 - hp) n = n + 1endif UnitPlayerOrPetInRaid("player") then for i = 1, 40 do acc("raid" .. i) endelse acc("player") if UnitPlayerOrPetInParty("player") then for i = 1, 4 do acc("party" .. i) end endendif n == 0 then return 0 endreturn total / n * 100代码 28:法术强度(参数:除数,旧版用它把大数值压进单字节通道,新版可填 1 取原值)。属性数值在战斗中可能受保护,消毒后按 0:
local v = SuperDPS.SN(GetSpellBonusDamage(7), "spellpower")return v / (arg1 or 1)无法移植清单(汇总)
Section titled “无法移植清单(汇总)”| 旧属性 | 原因 |
|---|---|
| 挥砍计时器全家族(主手/副手/远程 CD、远程武器速度) | UnitAttackSpeed/UnitRangedDamage 在 Midnight 返回受保护值,比较即抛错(实测 2026-08,旧插件的挥砍子系统因此整体删除) |
| DK 分类型符文(鲜血/冰霜/邪恶/死亡) | 正式服自军团版本起符文无类型之分,只在怀旧服有意义;旧实现还依赖暴雪符文框架内部字段 _G["Rune"..i].rune.runeType(非公开 API,版本间易失效),要用需自行改写并在目标客户端验证 |
| 基于 CLEU 的 DoT 跳伤计时 | 战斗记录事件对插件硬性封锁(旧版后期已退化为 debuff 存在性近似,直接用预置「自施减益剩余」) |
降级可用清单(战斗中可能读不到,按 0 处理)
Section titled “降级可用清单(战斗中可能读不到,按 0 处理)”- 百分比类(代码 2/4/22/27):除法/比较必须消毒,被保护的值归 0;
- 符文类(代码 7/8):冷却值有受保护风险;
- 距离类(代码 5/20):
UnitDistanceSquared对敌对单位可用性以实测为准; - 法术强度(代码 28)。
触发降级时游戏内聊天框会提示一次「被客户端保护,已按 0 处理」,明细 /dump SuperDPS.SecretSeen。