修复猎人野兽训练展示技能所需训练点数错误问题

修复拾取问题
修复其他已知问题
修复自动下马问题以及带来的猎人守护自动关闭问题
彻底修复拾取界面问题
修复目标框架的施法条监控
修复其他已知问题
调整dps插件对仇恨的估算方式
优化dps插件
修复远程攻击条问题
This commit is contained in:
rucky
2026-03-25 00:56:49 +08:00
parent c0f1ecc713
commit c7dd0f4848
9 changed files with 393 additions and 266 deletions

View File

@@ -6,8 +6,7 @@
-- 4. Cooldown Numbers - show remaining cooldown time as text overlay
-- 5. Dark UI - darken the entire interface
-- 6. WorldMap Window - turn fullscreen map into a movable/scalable window
-- 7. Auto Dismount - cancel shapeshift/mount when casting incompatible spells
-- 8. Hunter Aspect Guard - auto switch to Hawk when taking damage with Cheetah/Pack
-- 7. Hunter Aspect Guard - cancel Cheetah/Pack when taking damage in combat (avoid OOC false positives)
--------------------------------------------------------------------------------
SFrames.Tweaks = SFrames.Tweaks or {}
@@ -75,120 +74,6 @@ local function InitAutoStance()
end)
end
--------------------------------------------------------------------------------
-- Auto Dismount / Cancel Shapeshift
-- When casting a spell that fails because you are mounted or shapeshifted,
-- automatically cancel the mount/shapeshift buff so the next cast succeeds.
--------------------------------------------------------------------------------
local function InitAutoDismount()
local dismount = CreateFrame("Frame", "NanamiAutoDismount")
local _, playerClass = UnitClass("player")
local scanner = CreateFrame("GameTooltip", "NanamiDismountScan", nil, "GameTooltipTemplate")
scanner:SetOwner(WorldFrame, "ANCHOR_NONE")
scanner:SetAlpha(0)
scanner:Hide()
local mountStrings = {
"^Increases speed by (.+)%%",
"^Erhöht Tempo um (.+)%%",
"^Aumenta la velocidad en un (.+)%%",
"^Augmente la vitesse de (.+)%%",
"^Скорость увеличена на (.+)%%",
"^이동 속도 (.+)%%만큼 증가",
"^速度提高(.+)%%", "^移动速度提高(.+)%%",
"speed based on", "Slow and steady...", "Riding",
"Lento y constante...", "Aumenta la velocidad según tu habilidad de Montar.",
"根据您的骑行技能提高速度。", "根据骑术技能提高速度。", "又慢又稳......",
}
local shapeshiftIcons = {
"ability_racial_bearform", "ability_druid_catform",
"ability_druid_travelform", "spell_nature_forceofnature",
"ability_druid_aquaticform", "spell_nature_spiritwolf",
"ability_druid_treeoflife", "ability_druid_stagform",
}
local hunterAspectIcons = {
"ability_mount_jungletiger",
"ability_mount_packhorse",
}
local errorStrings = {}
local errorGlobals = {
"SPELL_FAILED_NOT_MOUNTED", "ERR_ATTACK_MOUNTED", "ERR_TAXIPLAYERALREADYMOUNTED",
"ERR_NOT_WHILE_MOUNTED",
"SPELL_FAILED_NOT_SHAPESHIFT", "SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED",
"SPELL_NOT_SHAPESHIFTED", "SPELL_NOT_SHAPESHIFTED_NOSPACE",
"ERR_CANT_INTERACT_SHAPESHIFTED", "ERR_NOT_WHILE_SHAPESHIFTED",
"ERR_NO_ITEMS_WHILE_SHAPESHIFTED", "ERR_TAXIPLAYERSHAPESHIFTED",
"ERR_MOUNT_SHAPESHIFTED",
}
for _, name in pairs(errorGlobals) do
local val = getfenv(0)[name]
if val then table.insert(errorStrings, val) end
end
dismount:RegisterEvent("UI_ERROR_MESSAGE")
dismount:SetScript("OnEvent", function()
if arg1 == SPELL_FAILED_NOT_STANDING then
SitOrStand()
return
end
local matched = false
for _, err in pairs(errorStrings) do
if arg1 == err then matched = true break end
end
if not matched then return end
for i = 0, 31 do
local buff = GetPlayerBuffTexture(i)
if buff then
local lowerBuff = string.lower(buff)
local skip = false
if playerClass == "HUNTER" then
for _, tex in pairs(hunterAspectIcons) do
if string.find(lowerBuff, tex) then
skip = true
break
end
end
end
if not skip then
scanner:ClearLines()
scanner:SetPlayerBuff(i)
for line = 1, scanner:NumLines() do
local text = getfenv(0)["NanamiDismountScanTextLeft" .. line]
if text and text:GetText() then
for _, str in pairs(mountStrings) do
if string.find(text:GetText(), str) then
CancelPlayerBuff(i)
return
end
end
end
end
for _, icon in pairs(shapeshiftIcons) do
if string.find(lowerBuff, icon) then
CancelPlayerBuff(i)
return
end
end
if string.find(lowerBuff, "ability_mount_") then
CancelPlayerBuff(i)
return
end
end
end
end
end)
end
--------------------------------------------------------------------------------
-- SuperWoW Compatibility
-- Provides GUID-based cast/channel data when SuperWoW client mod is active.
@@ -389,6 +274,78 @@ local function TimeConvert(remaining)
end
end
local _activeCooldowns = {}
local _cdTickTimer = 0
local _cdUpdaterFrame
local function CooldownSharedUpdate()
_cdTickTimer = _cdTickTimer + arg1
if _cdTickTimer < 0.1 then return end
_cdTickTimer = 0
local now = GetTime()
local sysTime = time()
local n = table.getn(_activeCooldowns)
local i = 1
while i <= n do
local cdFrame = _activeCooldowns[i]
if cdFrame and cdFrame:IsShown() then
local parent = cdFrame:GetParent()
if parent then
cdFrame:SetAlpha(parent:GetAlpha())
end
if cdFrame.start < now then
local remaining = cdFrame.duration - (now - cdFrame.start)
if remaining > 0 then
cdFrame.text:SetText(TimeConvert(remaining))
else
cdFrame:Hide()
_activeCooldowns[i] = _activeCooldowns[n]
_activeCooldowns[n] = nil
n = n - 1
i = i - 1
end
else
local startupTime = sysTime - now
local cdTime = (2 ^ 32) / 1000 - cdFrame.start
local cdStartTime = startupTime - cdTime
local cdEndTime = cdStartTime + cdFrame.duration
local remaining = cdEndTime - sysTime
if remaining >= 0 then
cdFrame.text:SetText(TimeConvert(remaining))
else
cdFrame:Hide()
_activeCooldowns[i] = _activeCooldowns[n]
_activeCooldowns[n] = nil
n = n - 1
i = i - 1
end
end
i = i + 1
else
_activeCooldowns[i] = _activeCooldowns[n]
_activeCooldowns[n] = nil
n = n - 1
end
end
if n == 0 and _cdUpdaterFrame then
_cdUpdaterFrame:Hide()
end
end
local function RegisterCooldownFrame(cdFrame)
for i = 1, table.getn(_activeCooldowns) do
if _activeCooldowns[i] == cdFrame then return end
end
table.insert(_activeCooldowns, cdFrame)
if not _cdUpdaterFrame then
_cdUpdaterFrame = CreateFrame("Frame", "NanamiCDSharedUpdater", UIParent)
_cdUpdaterFrame:SetScript("OnUpdate", CooldownSharedUpdate)
end
_cdUpdaterFrame:Show()
end
local function CooldownOnUpdate()
local parent = this:GetParent()
if not parent then this:Hide() return end
@@ -494,7 +451,7 @@ local function CreateCoolDown(cooldown, start, duration)
cooldown.cooldowntext.text:SetPoint("CENTER", cooldown.cooldowntext, "CENTER", 0, 0)
end
cooldown.cooldowntext:SetScript("OnUpdate", CooldownOnUpdate)
RegisterCooldownFrame(cooldown.cooldowntext)
end
local function SetCooldown(frame, start, duration, enable)
@@ -520,12 +477,13 @@ local function SetCooldown(frame, start, duration, enable)
if start > 0 and duration > 0 and (not enable or enable > 0) then
if frame.cooldownmask then frame.cooldownmask:Show() end
frame.cooldowntext:Show()
frame.cooldowntext.start = start
frame.cooldowntext.duration = duration
RegisterCooldownFrame(frame.cooldowntext)
else
if frame.cooldownmask then frame.cooldownmask:Hide() end
frame.cooldowntext:Hide()
end
frame.cooldowntext.start = start
frame.cooldowntext.duration = duration
end
end
@@ -1061,8 +1019,8 @@ end
--------------------------------------------------------------------------------
-- Hunter Aspect Guard
-- When a Hunter takes damage with Aspect of the Cheetah or Aspect of the Pack
-- active, automatically cancel the aspect to prevent repeated dazing.
-- When a Hunter takes damage in combat with Aspect of the Cheetah or Pack
-- active, cancel the aspect to reduce daze chains. OOC HP changes are ignored.
--------------------------------------------------------------------------------
local function InitHunterAspectGuard()
local _, playerClass = UnitClass("player")
@@ -1104,7 +1062,7 @@ local function InitHunterAspectGuard()
return
end
if lastHP > 0 and hp < lastHP then
if lastHP > 0 and hp < lastHP and UnitAffectingCombat("player") then
if GetTime() - lastCancel >= 1.0 then
if CancelDangerousAspect() then
lastCancel = GetTime()
@@ -1129,13 +1087,6 @@ function Tweaks:Initialize()
end
end
if cfg.autoDismount ~= false then
local ok, err = pcall(InitAutoDismount)
if not ok then
DEFAULT_CHAT_FRAME:AddMessage("|cffff4444Nanami-UI: AutoDismount init failed: " .. tostring(err) .. "|r")
end
end
if cfg.superWoW ~= false then
local ok, err = pcall(InitSuperWoW)
if not ok then