mirror of
https://github.com/brues-code/pfUI.git
synced 2026-09-22 15:46:56 +00:00
performance update
performance update
This commit is contained in:
+106
-18
@@ -53,14 +53,50 @@ local scanner = libtipscan:GetScanner("libcast")
|
||||
local libcast = CreateFrame("Frame", "pfEnemyCast")
|
||||
local player = UnitName("player")
|
||||
|
||||
UnitChannelInfo = _G.UnitChannelInfo or function(unit)
|
||||
-- Store original SuperWoW UnitChannelInfo if it exists
|
||||
local SuperWoW_UnitChannelInfo = _G.UnitChannelInfo
|
||||
|
||||
UnitChannelInfo = function(unit)
|
||||
-- convert to name if unitstring was given
|
||||
unit = pfValidUnits[unit] and UnitName(unit) or unit
|
||||
local unitName = pfValidUnits[unit] and UnitName(unit) or unit
|
||||
|
||||
-- For player: ALWAYS use libcast.db because it handles channel updates correctly
|
||||
local isPlayer = unit == "player" or unitName == player
|
||||
|
||||
if isPlayer then
|
||||
local cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
|
||||
local db = libcast.db[player]
|
||||
|
||||
if db and db.cast and db.start + db.casttime / 1000 > GetTime() then
|
||||
if not db.channel then return end
|
||||
cast = db.cast
|
||||
nameSubtext = db.rank
|
||||
text = ""
|
||||
texture = db.icon
|
||||
startTime = db.start * 1000
|
||||
endTime = startTime + db.casttime
|
||||
isTradeSkill = nil
|
||||
elseif db then
|
||||
db.cast = nil
|
||||
db.rank = nil
|
||||
db.start = nil
|
||||
db.casttime = nil
|
||||
db.icon = nil
|
||||
db.channel = nil
|
||||
end
|
||||
|
||||
return cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
|
||||
end
|
||||
|
||||
-- For non-player units: use SuperWoW if available, otherwise use libcast.db
|
||||
if SuperWoW_UnitChannelInfo then
|
||||
return SuperWoW_UnitChannelInfo(unit)
|
||||
end
|
||||
|
||||
-- Fallback to libcast.db for non-player units
|
||||
local cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
|
||||
local db = libcast.db[unit]
|
||||
local db = libcast.db[unitName]
|
||||
|
||||
-- clean legacy values
|
||||
if db and db.cast and db.start + db.casttime / 1000 > GetTime() then
|
||||
if not db.channel then return end
|
||||
cast = db.cast
|
||||
@@ -71,7 +107,6 @@ UnitChannelInfo = _G.UnitChannelInfo or function(unit)
|
||||
endTime = startTime + db.casttime
|
||||
isTradeSkill = nil
|
||||
elseif db then
|
||||
-- remove cast action to the database
|
||||
db.cast = nil
|
||||
db.rank = nil
|
||||
db.start = nil
|
||||
@@ -83,14 +118,51 @@ UnitChannelInfo = _G.UnitChannelInfo or function(unit)
|
||||
return cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
|
||||
end
|
||||
|
||||
UnitCastingInfo = _G.UnitCastingInfo or function(unit)
|
||||
-- Store original SuperWoW UnitCastingInfo if it exists
|
||||
local SuperWoW_UnitCastingInfo = _G.UnitCastingInfo
|
||||
|
||||
UnitCastingInfo = function(unit)
|
||||
-- convert to name if unitstring was given
|
||||
unit = pfValidUnits[unit] and UnitName(unit) or unit
|
||||
local unitName = pfValidUnits[unit] and UnitName(unit) or unit
|
||||
|
||||
-- For player: ALWAYS use libcast.db because it handles pushback correctly
|
||||
-- SuperWoW's UnitCastingInfo doesn't track SPELLCAST_DELAYED events
|
||||
local isPlayer = unit == "player" or unitName == player
|
||||
|
||||
if isPlayer then
|
||||
local cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
|
||||
local db = libcast.db[player]
|
||||
|
||||
if db and db.cast and db.start + db.casttime / 1000 > GetTime() then
|
||||
if db.channel then return end
|
||||
cast = db.cast
|
||||
nameSubtext = db.rank or ""
|
||||
text = ""
|
||||
texture = db.icon
|
||||
startTime = db.start * 1000
|
||||
endTime = startTime + db.casttime
|
||||
isTradeSkill = nil
|
||||
elseif db then
|
||||
db.cast = nil
|
||||
db.rank = nil
|
||||
db.start = nil
|
||||
db.casttime = nil
|
||||
db.icon = nil
|
||||
db.channel = nil
|
||||
end
|
||||
|
||||
return cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
|
||||
end
|
||||
|
||||
-- For non-player units: use SuperWoW if available, otherwise use libcast.db
|
||||
if SuperWoW_UnitCastingInfo then
|
||||
return SuperWoW_UnitCastingInfo(unit)
|
||||
end
|
||||
|
||||
-- Fallback to libcast.db for non-player units
|
||||
local cast, nameSubtext, text, texture, startTime, endTime, isTradeSkill
|
||||
local db = libcast.db[unit]
|
||||
local db = libcast.db[unitName]
|
||||
|
||||
-- clean legacy values
|
||||
if db and db.cast and db.start + db.casttime / 1000 > GetTime() then
|
||||
if db.channel then return end
|
||||
cast = db.cast
|
||||
@@ -101,7 +173,6 @@ UnitCastingInfo = _G.UnitCastingInfo or function(unit)
|
||||
endTime = startTime + db.casttime
|
||||
isTradeSkill = nil
|
||||
elseif db then
|
||||
-- remove cast action to the database
|
||||
db.cast = nil
|
||||
db.rank = nil
|
||||
db.start = nil
|
||||
@@ -182,17 +253,31 @@ libcast:RegisterEvent("SPELLCAST_CHANNEL_STOP")
|
||||
libcast:RegisterEvent("SPELLCAST_CHANNEL_UPDATE")
|
||||
|
||||
local mob, spell, icon, _
|
||||
|
||||
libcast:SetScript("OnEvent", function()
|
||||
-- Fill database with player casts
|
||||
if event == "SPELLCAST_START" then
|
||||
icon = L["spells"][arg1] and L["spells"][arg1].icon and string.format("%s%s", "Interface\\Icons\\", L["spells"][arg1].icon) or lastcasttex
|
||||
-- add cast action to the database
|
||||
this.db[player].cast = arg1
|
||||
this.db[player].rank = lastrank
|
||||
this.db[player].start = GetTime()
|
||||
this.db[player].casttime = arg2
|
||||
this.db[player].icon = icon
|
||||
this.db[player].channel = nil
|
||||
|
||||
-- Check if SuperWoW already set the cast data (with correct haste-adjusted casttime)
|
||||
-- If so, only update icon if needed, don't overwrite casttime
|
||||
local superWowAlreadySet = this.db[player].cast == arg1 and this.db[player].casttime and this.db[player].casttime > 0
|
||||
|
||||
if superWowAlreadySet then
|
||||
-- SuperWoW already set correct casttime, only update icon if better
|
||||
if icon and not this.db[player].icon then
|
||||
this.db[player].icon = icon
|
||||
end
|
||||
else
|
||||
-- No SuperWoW data, use SPELLCAST_START data
|
||||
this.db[player].cast = arg1
|
||||
this.db[player].rank = lastrank
|
||||
this.db[player].start = GetTime()
|
||||
this.db[player].casttime = arg2
|
||||
this.db[player].icon = icon
|
||||
this.db[player].channel = nil
|
||||
end
|
||||
|
||||
if not L["spells"][arg1] or not L["spells"][arg1].icon or not L["spells"][arg1].t then
|
||||
L["spells"][arg1] = L["spells"][arg1] or { }
|
||||
L["spells"][arg1].icon = L["spells"][arg1].icon or icon
|
||||
@@ -214,7 +299,9 @@ libcast:SetScript("OnEvent", function()
|
||||
end
|
||||
elseif event == "SPELLCAST_DELAYED" then
|
||||
if this.db[player].cast then
|
||||
this.db[player].start = this.db[player].start + arg1/1000
|
||||
-- Pushback: increase casttime instead of shifting start
|
||||
-- arg1 is the delay amount in milliseconds
|
||||
this.db[player].casttime = this.db[player].casttime + arg1
|
||||
end
|
||||
elseif event == "SPELLCAST_CHANNEL_START" then
|
||||
-- add cast action to the database
|
||||
@@ -224,6 +311,7 @@ libcast:SetScript("OnEvent", function()
|
||||
this.db[player].casttime = arg1
|
||||
this.db[player].icon = L["spells"][arg2] and L["spells"][arg2].icon and string.format("%s%s", "Interface\\Icons\\", L["spells"][arg2].icon) or lastcasttex
|
||||
this.db[player].channel = true
|
||||
|
||||
lastcasttex, lastrank = nil, nil
|
||||
elseif event == "SPELLCAST_CHANNEL_STOP" then
|
||||
if this.db[player] and this.db[player].channel then
|
||||
|
||||
+17
-60
@@ -9,10 +9,9 @@ setfenv(1, pfUI:GetEnvironment())
|
||||
-- UnitGetIncomingHeals(unit)
|
||||
-- UnitHasIncomingResurrection(unit)
|
||||
--
|
||||
-- The library is able to receive and send compatible messages to HealComm (vanilla)
|
||||
-- and HealComm (tbc) including the ressurections of both versions. It has an option
|
||||
-- to disable the sending of those messages in case one of the mentioned libraries
|
||||
-- is already active.
|
||||
-- The library is able to receive and send compatible messages to HealComm
|
||||
-- including resurrections. It has an option to disable the sending of those
|
||||
-- messages in case HealComm is already active.
|
||||
|
||||
-- return instantly when another libpredict is already active
|
||||
if pfUI.api.libpredict then return end
|
||||
@@ -457,15 +456,6 @@ libpredict.sender:SetScript("OnUpdate", function()
|
||||
end
|
||||
end)
|
||||
|
||||
-- tbc
|
||||
libpredict.sender:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_START")
|
||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_STOP")
|
||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_FAILED")
|
||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED")
|
||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_SENT")
|
||||
|
||||
-- vanilla
|
||||
libpredict.sender:RegisterEvent("CHAT_MSG_SPELL_SELF_BUFF")
|
||||
libpredict.sender:RegisterEvent("SPELLCAST_START")
|
||||
libpredict.sender:RegisterEvent("SPELLCAST_STOP")
|
||||
@@ -502,24 +492,9 @@ libpredict.sender:SetScript("OnEvent", function()
|
||||
if spell == spell_queue[1] then UpdateCache(spell_queue[2], heal, true) end
|
||||
return
|
||||
end
|
||||
elseif event == "COMBAT_LOG_EVENT_UNFILTERED" and arg2 == "SPELL_HEAL" and arg4 == player then -- tbc
|
||||
local spell, heal, crit = arg10, arg12, arg13
|
||||
if spell and heal and crit then
|
||||
if spell == spell_queue[1] then UpdateCache(spell_queue[2], heal, true) end
|
||||
elseif spell and heal then
|
||||
if spell == spell_queue[1] then UpdateCache(spell_queue[2], heal) end
|
||||
end
|
||||
elseif event == "UNIT_SPELLCAST_SENT" and arg4 then -- fix tbc mouseover macros
|
||||
senttarget = arg4
|
||||
elseif strfind(event, "SPELLCAST_START", 1) then
|
||||
elseif event == "SPELLCAST_START" then
|
||||
local spell, time = arg1, arg2
|
||||
|
||||
if strfind(event, "UNIT_", 1) then -- tbc
|
||||
if arg1 ~= "player" then return end
|
||||
local spellname, _, _, _, starttime, endtime = UnitCastingInfo("player")
|
||||
spell, time = spellname, endtime - starttime
|
||||
end
|
||||
|
||||
if spell_queue[1] == spell and cache[spell_queue[2]] then
|
||||
local sender = player
|
||||
local target = senttarget or spell_queue[3]
|
||||
@@ -540,22 +515,14 @@ libpredict.sender:SetScript("OnEvent", function()
|
||||
for i=1,4 do
|
||||
if CheckInteractDistance("party"..i, 4) then
|
||||
libpredict:Heal(player, UnitName("party"..i), amount, casttime)
|
||||
if pfUI.client < 20000 then -- vanilla
|
||||
libpredict.sender:SendHealCommMsg("Heal/" .. UnitName("party"..i) .. "/" .. amount .. "/" .. casttime .. "/")
|
||||
else -- tbc
|
||||
libpredict.sender:SendHealCommMsg(string.format("002%05d%s", math.min(amount, 99999), UnitName("party"..i)))
|
||||
end
|
||||
libpredict.sender:SendHealCommMsg("Heal/" .. UnitName("party"..i) .. "/" .. amount .. "/" .. casttime .. "/")
|
||||
libpredict.sender.healing = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
libpredict:Heal(player, target, amount, casttime)
|
||||
if pfUI.client < 20000 then -- vanilla
|
||||
libpredict.sender:SendHealCommMsg("Heal/" .. target .. "/" .. amount .. "/" .. casttime .. "/")
|
||||
else -- tbc
|
||||
libpredict.sender:SendHealCommMsg(string.format("002%05d%s", math.min(amount, 99999), target))
|
||||
end
|
||||
libpredict.sender:SendHealCommMsg("Heal/" .. target .. "/" .. amount .. "/" .. casttime .. "/")
|
||||
libpredict.sender.healing = true
|
||||
|
||||
elseif spell_queue[1] == spell and L["resurrections"][spell] then
|
||||
@@ -565,15 +532,10 @@ libpredict.sender:SetScript("OnEvent", function()
|
||||
libpredict.sender:SendResCommMsg("RES " .. target)
|
||||
libpredict.sender.resurrecting = true
|
||||
end
|
||||
elseif strfind(event, "SPELLCAST_FAILED", 1) or strfind(event, "SPELLCAST_INTERRUPTED", 1) then
|
||||
if strfind(event, "UNIT_", 1) and arg1 ~= "player" then return end
|
||||
elseif event == "SPELLCAST_FAILED" or event == "SPELLCAST_INTERRUPTED" then
|
||||
if libpredict.sender.healing then
|
||||
libpredict:HealStop(player)
|
||||
if pfUI.client < 20000 then -- vanilla
|
||||
libpredict.sender:SendHealCommMsg("HealStop")
|
||||
else -- tbc
|
||||
libpredict.sender:SendHealCommMsg("001F")
|
||||
end
|
||||
libpredict.sender:SendHealCommMsg("HealStop")
|
||||
libpredict.sender.healing = nil
|
||||
elseif libpredict.sender.resurrecting then
|
||||
local target = senttarget or spell_queue[3]
|
||||
@@ -590,21 +552,16 @@ libpredict.sender:SetScript("OnEvent", function()
|
||||
libpredict:HealDelay(player, arg1)
|
||||
libpredict.sender:SendHealCommMsg("Healdelay/" .. arg1 .. "/")
|
||||
end
|
||||
elseif strfind(event, "SPELLCAST_STOP", 1) then
|
||||
if strfind(event, "UNIT_", 1) and arg1 ~= "player" then return end
|
||||
elseif event == "SPELLCAST_STOP" then
|
||||
libpredict:HealStop(player)
|
||||
if pfUI.client < 20000 then -- vanilla
|
||||
if spell_queue[1] == REJUVENATION then
|
||||
libpredict:Hot(player, spell_queue[3], "Reju", rejuvDuration)
|
||||
libpredict.sender:SendHealCommMsg("Reju/"..spell_queue[3].."/"..rejuvDuration.."/")
|
||||
elseif spell_queue[1] == RENEW then
|
||||
libpredict:Hot(player, spell_queue[3], "Renew", renewDuration)
|
||||
libpredict.sender:SendHealCommMsg("Renew/"..spell_queue[3].."/"..renewDuration.."/")
|
||||
elseif spell_queue[1] == REGROWTH then
|
||||
this.regrowth_timer = GetTime() + 0.1
|
||||
end
|
||||
else -- tbc
|
||||
--todo
|
||||
if spell_queue[1] == REJUVENATION then
|
||||
libpredict:Hot(player, spell_queue[3], "Reju", rejuvDuration)
|
||||
libpredict.sender:SendHealCommMsg("Reju/"..spell_queue[3].."/"..rejuvDuration.."/")
|
||||
elseif spell_queue[1] == RENEW then
|
||||
libpredict:Hot(player, spell_queue[3], "Renew", renewDuration)
|
||||
libpredict.sender:SendHealCommMsg("Renew/"..spell_queue[3].."/"..renewDuration.."/")
|
||||
elseif spell_queue[1] == REGROWTH then
|
||||
this.regrowth_timer = GetTime() + 0.1
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
+28
-12
@@ -39,10 +39,10 @@ local spells = {
|
||||
},
|
||||
}
|
||||
|
||||
-- use native IsSpellInRange checker for tbc and skip
|
||||
-- the whole targeting approach that is required for vanilla
|
||||
if pfUI.expansion == "tbc" then
|
||||
local spell
|
||||
-- Use Nampower's IsSpellInRange if available (vanilla only)
|
||||
-- This provides more accurate range checking without needing to find spell slots
|
||||
local nampower_spell
|
||||
if GetNampowerVersion then
|
||||
librange:RegisterEvent("LEARNED_SPELL_IN_TAB")
|
||||
librange:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
librange:SetScript("OnEvent", function()
|
||||
@@ -53,12 +53,14 @@ if pfUI.expansion == "tbc" then
|
||||
local _, _, offset, num = GetSpellTabInfo(i)
|
||||
for id = offset + 1, offset + num do
|
||||
local name, rank = GetSpellName(id, BOOKTYPE_SPELL)
|
||||
local texture = GetSpellTexture(name)
|
||||
local texture = GetSpellTexture(id, BOOKTYPE_SPELL)
|
||||
|
||||
for _, tex in pairs(spells[class]) do
|
||||
if tex == texture then
|
||||
spell = name
|
||||
return
|
||||
if texture then
|
||||
for _, tex in pairs(spells[class]) do
|
||||
if tex == texture then
|
||||
nampower_spell = name
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -66,8 +68,12 @@ if pfUI.expansion == "tbc" then
|
||||
end)
|
||||
|
||||
function librange:UnitInSpellRange(unit)
|
||||
if not spell then return nil end
|
||||
return IsSpellInRange(spell, unit) == 1 and true or nil
|
||||
if not nampower_spell then return nil end
|
||||
-- Nampower's IsSpellInRange returns 1 if in range, 0 if not, -1 if invalid
|
||||
local result = IsSpellInRange(nampower_spell, unit)
|
||||
if result == 1 then return 1
|
||||
elseif result == 0 then return nil
|
||||
else return nil end
|
||||
end
|
||||
|
||||
-- add librange to pfUI API
|
||||
@@ -161,7 +167,17 @@ librange:SetScript("OnUpdate", function()
|
||||
if this.id <= numunits and librange.slot then
|
||||
local unit = units[this.id]
|
||||
if not UnitIsUnit("target", unit) then
|
||||
-- try to read distance via superwow first
|
||||
-- Try UnitXP_SP3 first (most accurate distance measurement)
|
||||
local unitxp_success, unitxp_distance = pcall(function()
|
||||
return UnitXP("distanceBetween", "player", unit)
|
||||
end)
|
||||
if unitxp_success and unitxp_distance then
|
||||
unitdata[unit] = unitxp_distance < 45 and 1 or 0
|
||||
this.id = this.id + 1
|
||||
return
|
||||
end
|
||||
|
||||
-- try to read distance via superwow second
|
||||
if superwow_active then
|
||||
local x1, y1, z1 = UnitPosition("player")
|
||||
local x2, y2, z2 = UnitPosition(unit)
|
||||
|
||||
Reference in New Issue
Block a user