mirror of
https://github.com/brues-code/pfUI.git
synced 2026-10-07 14:10:01 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62e0d4eb07 | ||
|
|
a4ceb8ba53 | ||
|
|
80b677a6f8 | ||
|
|
f6683b31af | ||
|
|
b47df9272d | ||
|
|
c0b717878d | ||
|
|
31c95606d0 | ||
|
|
3fe072c594 | ||
|
|
9706a74d16 | ||
|
|
f9b0b5983a | ||
|
|
176e131d6b | ||
|
|
a17229abb1 | ||
|
|
e0cf01772c | ||
|
|
c2d4106170 | ||
|
|
dbfd337d42 | ||
|
|
d834be9f0b | ||
|
|
82a07e1e35 | ||
|
|
703d7770ca | ||
|
|
bd722b0f0f | ||
|
|
e5c51fff48 | ||
|
|
6570afb70a | ||
|
|
0f97e8b0bd | ||
|
|
64c62a2a25 | ||
|
|
4d316ed43a | ||
|
|
db0195f0f7 | ||
|
|
3d2d5f9254 | ||
|
|
dfbeeb454a | ||
|
|
439d5a397a | ||
|
|
5524ad3b91 | ||
|
|
0f59a3a9b5 | ||
|
|
ffdf376ac4 | ||
|
|
9bdde06150 | ||
|
|
8bf6672114 | ||
|
|
29b948e6fa | ||
|
|
5f61f94a24 | ||
|
|
65678da3d2 | ||
|
|
9b7aca8541 | ||
|
|
60525eec3a | ||
|
|
c3829c2bd2 | ||
|
|
28de6fd835 | ||
|
|
fc75e091a4 | ||
|
|
ef478b0552 | ||
|
|
760d8992b6 | ||
|
|
62a99ac410 | ||
|
|
deeec89955 | ||
|
|
cca9771ef0 | ||
|
|
371872bb90 | ||
|
|
591045a606 | ||
|
|
f657a9e7e8 | ||
|
|
0cbd9ecf98 | ||
|
|
6ca482fcaa | ||
|
|
8902d43f40 | ||
|
|
8f006c0643 |
+2
-2
@@ -1,2 +1,2 @@
|
|||||||
github: [shagu]
|
github: [brues]
|
||||||
ko_fi: shagu
|
buy_me_a_coffee: brues
|
||||||
|
|||||||
@@ -4,16 +4,18 @@ about: Report a bug or issue with pfUI
|
|||||||
title: "[Bug Description] "
|
title: "[Bug Description] "
|
||||||
labels: bug
|
labels: bug
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<!-- Please fill out ALL fields below. Issues without this info may be closed. -->
|
<!-- Please fill out ALL fields below. Issues without this info may be closed. -->
|
||||||
|
|
||||||
**pfUI Branch:**
|
**pfUI Version:**
|
||||||
- [ ] Master
|
|
||||||
- [ ] experiment
|
**Your ClassicAPI Version:**
|
||||||
|
|
||||||
|
**Your Nampower Version:**
|
||||||
|
|
||||||
|
|
||||||
**Your Nampower Version:** (e.g. latest, or specific commit/date)
|
|
||||||
<!-- Skip if using Compat branch -->
|
|
||||||
|
|
||||||
**Other Addons installed:**
|
**Other Addons installed:**
|
||||||
<!-- List any other addons you are using, or "none" -->
|
<!-- List any other addons you are using, or "none" -->
|
||||||
@@ -45,4 +47,3 @@ Paste error log here
|
|||||||
## Screenshot / Video
|
## Screenshot / Video
|
||||||
<!-- Attach a screenshot or video showing the issue. This is REQUIRED. -->
|
<!-- Attach a screenshot or video showing the issue. This is REQUIRED. -->
|
||||||
<!-- Drag & drop images here or paste a link -->
|
<!-- Drag & drop images here or paste a link -->
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ about: Suggest a new feature or improvement for pfUI
|
|||||||
title: "[Feature] "
|
title: "[Feature] "
|
||||||
labels: enhancement
|
labels: enhancement
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Feature Description
|
## Feature Description
|
||||||
@@ -20,4 +21,3 @@ assignees: ''
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
<!-- If possible, show examples from other addons or screenshots/mockups of how it could look -->
|
<!-- If possible, show examples from other addons or screenshots/mockups of how it could look -->
|
||||||
|
|
||||||
|
|||||||
+13
-17
@@ -28,14 +28,6 @@ function pfUI.api.HasNampower()
|
|||||||
return GetNampowerVersion and true or false
|
return GetNampowerVersion and true or false
|
||||||
end
|
end
|
||||||
|
|
||||||
local isTurtleWoW
|
|
||||||
function pfUI.api.IsTurtleWoW()
|
|
||||||
if isTurtleWoW == nil then
|
|
||||||
isTurtleWoW = C_Spell.GetSpellTexture(46050) == "Interface\\Icons\\Trade_Survival"
|
|
||||||
end
|
|
||||||
return isTurtleWoW
|
|
||||||
end
|
|
||||||
|
|
||||||
-- [ GetUnitDistance ]
|
-- [ GetUnitDistance ]
|
||||||
-- Returns distance to unit using best available method
|
-- Returns distance to unit using best available method
|
||||||
-- 'unit1' [string] first unit (default: "player")
|
-- 'unit1' [string] first unit (default: "player")
|
||||||
@@ -208,7 +200,7 @@ function pfUI.api.GetUnbuffedRoster(name)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if UnitInRaid("player") then
|
if IsInRaid() then
|
||||||
for i=1,40 do check("raid"..i) end
|
for i=1,40 do check("raid"..i) end
|
||||||
else
|
else
|
||||||
check("player")
|
check("player")
|
||||||
@@ -434,13 +426,17 @@ function pfUI.api.GetBagFamily(bag)
|
|||||||
|
|
||||||
local id = GetInventoryItemID("player", ContainerIDToInventoryID(bag))
|
local id = GetInventoryItemID("player", ContainerIDToInventoryID(bag))
|
||||||
if id then
|
if id then
|
||||||
local _, _, _, _, _, itemType, subType = GetItemInfo(id)
|
-- classID 1 = Container (bags), 11 = Quiver
|
||||||
local bagsubtype = L["bagtypes"][subType]
|
-- Container subclasses: 0 = Bag (default), 1 = Soul Bag, 2+ = specialty (herb/enchanting/etc.)
|
||||||
|
-- Quiver subclasses: 2 = Quiver (arrows), 3 = Ammo Pouch (bullets)
|
||||||
if bagsubtype == "DEFAULT" then return "BAG" end
|
local _, _, _, _, _, classID, subClassID = C_Item.GetItemInfoInstant(id)
|
||||||
if bagsubtype == "SOULBAG" then return "SOULBAG" end
|
if classID == 1 then
|
||||||
if bagsubtype == "QUIVER" then return "QUIVER" end
|
if subClassID == 0 then return "BAG" end
|
||||||
if bagsubtype == nil then return "SPECIAL" end
|
if subClassID == 1 then return "SOULBAG" end
|
||||||
|
return "SPECIAL"
|
||||||
|
elseif classID == 11 then
|
||||||
|
return "QUIVER"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -485,7 +481,7 @@ end
|
|||||||
-- 'msg' [string] the message to send
|
-- 'msg' [string] the message to send
|
||||||
function pfUI.api.SendChatMessageWide(msg)
|
function pfUI.api.SendChatMessageWide(msg)
|
||||||
local channel = "SAY"
|
local channel = "SAY"
|
||||||
if UnitInRaid("player") then
|
if IsInRaid() then
|
||||||
if ( IsRaidLeader() or IsRaidOfficer() ) then
|
if ( IsRaidLeader() or IsRaidOfficer() ) then
|
||||||
channel = "RAID_WARNING"
|
channel = "RAID_WARNING"
|
||||||
else
|
else
|
||||||
|
|||||||
+14
-2
@@ -748,6 +748,7 @@ function pfUI:LoadConfig()
|
|||||||
pfUI:UpdateConfig("tooltip", nil, "cursoroffset", "20")
|
pfUI:UpdateConfig("tooltip", nil, "cursoroffset", "20")
|
||||||
pfUI:UpdateConfig("tooltip", nil, "extguild", "1")
|
pfUI:UpdateConfig("tooltip", nil, "extguild", "1")
|
||||||
pfUI:UpdateConfig("tooltip", nil, "itemid", "0")
|
pfUI:UpdateConfig("tooltip", nil, "itemid", "0")
|
||||||
|
pfUI:UpdateConfig("tooltip", nil, "movespeed", "0")
|
||||||
pfUI:UpdateConfig("tooltip", nil, "alpha", "0.8")
|
pfUI:UpdateConfig("tooltip", nil, "alpha", "0.8")
|
||||||
pfUI:UpdateConfig("tooltip", nil, "alwaysperc", "0")
|
pfUI:UpdateConfig("tooltip", nil, "alwaysperc", "0")
|
||||||
pfUI:UpdateConfig("tooltip", "compare", "basestats", "1")
|
pfUI:UpdateConfig("tooltip", "compare", "basestats", "1")
|
||||||
@@ -1371,7 +1372,6 @@ function pfUI:MigrateConfig()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Remove "Show only own debuffs" from unitframes and nameplates
|
-- Remove "Show only own debuffs" from unitframes and nameplates
|
||||||
-- (feature was removed; only Target Debuff Bar in buffwatch keeps it)
|
-- (feature was removed; only Target Debuff Bar in buffwatch keeps it)
|
||||||
if pfUI_config.nameplates then
|
if pfUI_config.nameplates then
|
||||||
@@ -1387,5 +1387,17 @@ function pfUI:MigrateConfig()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
pfUI_config.version = pfUI.version.string
|
-- Stamp the version we've migrated to. Dev / git-cloned builds carry
|
||||||
|
-- "@project-version@" in the toc, which pfUI.lua normalizes to "dev" —
|
||||||
|
-- writing that here would have checkversion() parse it back as 0/0/0 on
|
||||||
|
-- the next /reload and re-fire every migration block, clobbering user
|
||||||
|
-- toggles (notably the >3.6.1 buff migration that rewrites
|
||||||
|
-- buffs.{buffs,debuffs,weapons} from the deprecated global.hide{,w}buff
|
||||||
|
-- knobs). Stamp a far-future sentinel instead so checkversion() can't
|
||||||
|
-- flip true again on subsequent loads.
|
||||||
|
if pfUI.version.string == "dev" then
|
||||||
|
pfUI_config.version = "999.999.999"
|
||||||
|
else
|
||||||
|
pfUI_config.version = pfUI.version.string
|
||||||
|
end
|
||||||
end
|
end
|
||||||
+2
-3
@@ -1172,10 +1172,9 @@ function pfUI.api.CreateQuestionDialog(text, yes, no, editbox, onclose)
|
|||||||
local width = 200
|
local width = 200
|
||||||
|
|
||||||
-- delay the auto sizing, to make sure the font rendering happened
|
-- delay the auto sizing, to make sure the font rendering happened
|
||||||
question:SetScript("OnUpdate", function()
|
RunNextFrame(function()
|
||||||
if question.text:GetStringWidth() > width then width = question.text:GetStringWidth() end
|
if question.text:GetStringWidth() > width then width = question.text:GetStringWidth() end
|
||||||
question:SetWidth( width + 2*padding)
|
question:SetWidth(width + 2*padding)
|
||||||
this:SetScript("OnUpdate", nil)
|
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+19
-13
@@ -73,8 +73,8 @@ end
|
|||||||
|
|
||||||
local function BuffOnClick()
|
local function BuffOnClick()
|
||||||
if this:GetParent().label == "player" then
|
if this:GetParent().label == "player" then
|
||||||
local bid = GetPlayerBuff(PLAYER_BUFF_START_ID + this.id, "HELPFUL")
|
local aura = C_UnitAuras.GetAuraDataByIndex("player", this.id, "HELPFUL")
|
||||||
if bid >= 0 then CancelPlayerBuff(bid) end
|
if aura and aura.spellId then C_Spell.CancelSpellByID(aura.spellId) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -114,8 +114,8 @@ end
|
|||||||
|
|
||||||
local function DebuffOnClick()
|
local function DebuffOnClick()
|
||||||
if this:GetParent().label == "player" then
|
if this:GetParent().label == "player" then
|
||||||
local bid = GetPlayerBuff(PLAYER_BUFF_START_ID + this.id, "HARMFUL")
|
local aura = C_UnitAuras.GetAuraDataByIndex("player", this.id, "HARMFUL")
|
||||||
if bid >= 0 then CancelPlayerBuff(bid) end
|
if aura and aura.spellId then C_Spell.CancelSpellByID(aura.spellId) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -305,12 +305,12 @@ function pfUI.uf:UpdateVisibility()
|
|||||||
local id = self.cache_raid
|
local id = self.cache_raid
|
||||||
|
|
||||||
-- always show self in raidframes
|
-- always show self in raidframes
|
||||||
if not UnitInRaid("player") and GetNumPartyMembers() == 0 and C.unitframes.selfinraid == "1" and id == 1 then
|
if not IsInRaid() and IsInGroup() and C.unitframes.selfinraid == "1" and id == 1 then
|
||||||
self.id = ""
|
self.id = ""
|
||||||
self.label = "player"
|
self.label = "player"
|
||||||
|
|
||||||
-- use raidframes for groups
|
-- use raidframes for groups
|
||||||
elseif not UnitInRaid("player") and GetNumPartyMembers() > 0 and C.unitframes.raidforgroup == "1" then
|
elseif not IsInRaid() and IsInGroup() and C.unitframes.raidforgroup == "1" then
|
||||||
if id == 1 then
|
if id == 1 then
|
||||||
self.id = ""
|
self.id = ""
|
||||||
self.label = "player"
|
self.label = "player"
|
||||||
@@ -347,12 +347,12 @@ function pfUI.uf:UpdateVisibility()
|
|||||||
-- frame shall not be visible
|
-- frame shall not be visible
|
||||||
visibility = "hide"
|
visibility = "hide"
|
||||||
self.visible = nil
|
self.visible = nil
|
||||||
elseif C["unitframes"]["group"]["hide_in_raid"] == "1" and self.label and strsub(self.label,0,5) == "party" and UnitInRaid("player") then
|
elseif C["unitframes"]["group"]["hide_in_raid"] == "1" and self.label and strsub(self.label,0,5) == "party" and IsInRaid() then
|
||||||
-- hide group while in raid and option is set
|
-- hide group while in raid and option is set
|
||||||
visibility = "hide"
|
visibility = "hide"
|
||||||
self.visible = nil
|
self.visible = nil
|
||||||
elseif ( self.fname == "Group0" or self.fname == "PartyPet0" or self.fname == "Party0Target" )
|
elseif ( self.fname == "Group0" or self.fname == "PartyPet0" or self.fname == "Party0Target" )
|
||||||
and (GetNumPartyMembers() <= 0 or (C["unitframes"]["group"]["hide_in_raid"] == "1" and UnitInRaid("player"))) then
|
and (not IsInGroup() or (C["unitframes"]["group"]["hide_in_raid"] == "1" and IsInRaid())) then
|
||||||
-- hide self in group if solo or hide in raid is set
|
-- hide self in group if solo or hide in raid is set
|
||||||
visibility = "hide"
|
visibility = "hide"
|
||||||
self.visible = nil
|
self.visible = nil
|
||||||
@@ -1014,7 +1014,7 @@ function pfUI.uf.OnEvent()
|
|||||||
-- Raid frames: update_full is set by raid.lua GUID tracker
|
-- Raid frames: update_full is set by raid.lua GUID tracker
|
||||||
elseif this.label == "pet" and event == "UNIT_PET" then
|
elseif this.label == "pet" and event == "UNIT_PET" then
|
||||||
this.update_full = true
|
this.update_full = true
|
||||||
elseif this.label == "player" and (event == "PLAYER_AURAS_CHANGED" or event == "UNIT_INVENTORY_CHANGED") then
|
elseif this.label == "player" and (event == "PLAYER_AURAS_CHANGED" or event == "PLAYER_EQUIPMENT_CHANGED") then
|
||||||
this.update_aura = true
|
this.update_aura = true
|
||||||
elseif this.label == "pet" and event == "UNIT_HAPPINESS" then
|
elseif this.label == "pet" and event == "UNIT_HAPPINESS" then
|
||||||
this.update_full = true
|
this.update_full = true
|
||||||
@@ -1552,7 +1552,7 @@ function pfUI.uf:EnableEvents()
|
|||||||
f:RegisterEvent("UNIT_FACTION")
|
f:RegisterEvent("UNIT_FACTION")
|
||||||
f:RegisterEvent("UNIT_AURA") -- frame=buff, frame=debuff
|
f:RegisterEvent("UNIT_AURA") -- frame=buff, frame=debuff
|
||||||
f:RegisterEvent("PLAYER_AURAS_CHANGED") -- label=player && frame=buff
|
f:RegisterEvent("PLAYER_AURAS_CHANGED") -- label=player && frame=buff
|
||||||
f:RegisterEvent("UNIT_INVENTORY_CHANGED") -- label=player && frame=buff
|
f:RegisterEvent("PLAYER_EQUIPMENT_CHANGED") -- label=player && frame=buff (ClassicAPI: weapon-enchant buffs)
|
||||||
f:RegisterEvent("PARTY_MEMBERS_CHANGED") -- label=party, frame=leaderIcon
|
f:RegisterEvent("PARTY_MEMBERS_CHANGED") -- label=party, frame=leaderIcon
|
||||||
f:RegisterEvent("PARTY_LEADER_CHANGED") -- frame=leaderIcon
|
f:RegisterEvent("PARTY_LEADER_CHANGED") -- frame=leaderIcon
|
||||||
f:RegisterEvent("RAID_ROSTER_UPDATE") -- label=raidIcon
|
f:RegisterEvent("RAID_ROSTER_UPDATE") -- label=raidIcon
|
||||||
@@ -1773,7 +1773,7 @@ function pfUI.uf:RefreshIndicators(unit)
|
|||||||
local unitstr = unit.label .. unit.id
|
local unitstr = unit.label .. unit.id
|
||||||
|
|
||||||
if unit.leaderIcon then -- Leader Icon
|
if unit.leaderIcon then -- Leader Icon
|
||||||
if unit.config.leadericon == "1" and UnitIsPartyLeader(unitstr) and ( GetNumPartyMembers() > 0 or GetNumRaidMembers() > 0 ) then
|
if unit.config.leadericon == "1" and UnitIsPartyLeader(unitstr) and IsInGroup() then
|
||||||
unit.leaderIcon:Show()
|
unit.leaderIcon:Show()
|
||||||
else
|
else
|
||||||
unit.leaderIcon:Hide()
|
unit.leaderIcon:Hide()
|
||||||
@@ -1902,6 +1902,8 @@ function pfUI.uf:RefreshUnit(unit, component)
|
|||||||
end
|
end
|
||||||
if duration > 0 then
|
if duration > 0 then
|
||||||
CooldownFrame_SetTimer(unit.buffs[i].cd, start, duration, 1)
|
CooldownFrame_SetTimer(unit.buffs[i].cd, start, duration, 1)
|
||||||
|
else
|
||||||
|
CooldownFrame_SetTimer(unit.buffs[i].cd, 0, 0, 0)
|
||||||
end
|
end
|
||||||
elseif aura.duration > 0 then
|
elseif aura.duration > 0 then
|
||||||
local guid = UnitGUID(unitstr)
|
local guid = UnitGUID(unitstr)
|
||||||
@@ -1912,6 +1914,8 @@ function pfUI.uf:RefreshUnit(unit, component)
|
|||||||
else
|
else
|
||||||
CooldownFrame_SetTimer(unit.buffs[i].cd, 0, 0, 0)
|
CooldownFrame_SetTimer(unit.buffs[i].cd, 0, 0, 0)
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
CooldownFrame_SetTimer(unit.buffs[i].cd, 0, 0, 0)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
unit.buffs[i]:Hide()
|
unit.buffs[i]:Hide()
|
||||||
@@ -2005,7 +2009,11 @@ function pfUI.uf:RefreshUnit(unit, component)
|
|||||||
end
|
end
|
||||||
if duration > 0 then
|
if duration > 0 then
|
||||||
CooldownFrame_SetTimer(unit.debuffs[i].cd, start, duration, 1)
|
CooldownFrame_SetTimer(unit.debuffs[i].cd, start, duration, 1)
|
||||||
|
else
|
||||||
|
CooldownFrame_SetTimer(unit.debuffs[i].cd, 0, 0, 0)
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
CooldownFrame_SetTimer(unit.debuffs[i].cd, 0, 0, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
if stacks > 1 then
|
if stacks > 1 then
|
||||||
@@ -2838,8 +2846,6 @@ function pfUI.uf:GetStatusValue(unit, pos)
|
|||||||
-- Use libhealth for mob health estimation (overrides Nampower/Standard)
|
-- Use libhealth for mob health estimation (overrides Nampower/Standard)
|
||||||
if pfUI.libhealth and pfUI.libhealth.enabled then
|
if pfUI.libhealth and pfUI.libhealth.enabled then
|
||||||
rhp, rhpmax = pfUI.libhealth:GetUnitHealth(unitstr)
|
rhp, rhpmax = pfUI.libhealth:GetUnitHealth(unitstr)
|
||||||
elseif unit.label == "target" and (MobHealth3 or MobHealthFrame) and MobHealth_GetTargetCurHP() then
|
|
||||||
rhp, rhpmax = MobHealth_GetTargetCurHP(), MobHealth_GetTargetMaxHP()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if config == "unit" then
|
if config == "unit" then
|
||||||
|
|||||||
+10
-26
@@ -28,32 +28,16 @@ ACTIONBAR_SECURE_TEMPLATE_BUTTON = nil
|
|||||||
UNITFRAME_SECURE_TEMPLATE = nil
|
UNITFRAME_SECURE_TEMPLATE = nil
|
||||||
|
|
||||||
--[[ Vanilla API Extensions ]]--
|
--[[ Vanilla API Extensions ]]--
|
||||||
function hooksecurefunc(tbl, name, func, prepend)
|
-- Safe post-hook helper. The global `hooksecurefunc` belongs to ClassicAPI
|
||||||
if type(tbl) == "string" then
|
-- (its C implementation); this wrapper only adds pfUI's missing-target guard:
|
||||||
prepend, func, name, tbl = func, name, tbl, _G
|
-- ClassicAPI errors when target[name] isn't a function, whereas a lot of our
|
||||||
end
|
-- call sites hook optional/late-loaded frames and rely on a silent no-op.
|
||||||
|
-- Normalizes the string form, skips when the target is absent, then delegates
|
||||||
if not tbl or not tbl[name] then return end
|
-- to the C version (uncapped args, callback-pcall, taint parity).
|
||||||
|
function pfUI.hooksecurefunc(tbl, name, func)
|
||||||
pfUI.hooks[tostring(func)] = {}
|
if type(tbl) == "string" then tbl, name, func = _G, tbl, name end
|
||||||
pfUI.hooks[tostring(func)]["old"] = tbl[name]
|
if not tbl or type(tbl[name]) ~= "function" then return end
|
||||||
pfUI.hooks[tostring(func)]["new"] = func
|
return _G.hooksecurefunc(tbl, name, func)
|
||||||
|
|
||||||
if prepend then
|
|
||||||
pfUI.hooks[tostring(func)]["function"] = function(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16)
|
|
||||||
pfUI.hooks[tostring(func)]["new"](a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16)
|
|
||||||
return pfUI.hooks[tostring(func)]["old"](a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
pfUI.hooks[tostring(func)]["function"] = function(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16)
|
|
||||||
local ok, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16 = pcall(pfUI.hooks[tostring(func)]["old"], a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16)
|
|
||||||
if not ok then return end
|
|
||||||
pfUI.hooks[tostring(func)]["new"](a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16)
|
|
||||||
return r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
tbl[name] = pfUI.hooks[tostring(func)]["function"]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do -- GetItemInfo
|
do -- GetItemInfo
|
||||||
|
|||||||
Vendored
-2620
File diff suppressed because it is too large
Load Diff
Vendored
-2634
File diff suppressed because it is too large
Load Diff
Vendored
-2628
File diff suppressed because it is too large
Load Diff
Vendored
-2625
File diff suppressed because it is too large
Load Diff
Vendored
-2591
File diff suppressed because it is too large
Load Diff
Vendored
-2628
File diff suppressed because it is too large
Load Diff
Vendored
-2612
File diff suppressed because it is too large
Load Diff
+33
-162
@@ -14,7 +14,7 @@ setfenv(1, pfUI:GetEnvironment())
|
|||||||
-- The public per-aura readers (UnitDebuff, UnitOwnDebuff) were retired in favor
|
-- The public per-aura readers (UnitDebuff, UnitOwnDebuff) were retired in favor
|
||||||
-- of ClassicAPI's C_UnitAuras (which now provides sourceUnit/sourceGUID and
|
-- of ClassicAPI's C_UnitAuras (which now provides sourceUnit/sourceGUID and
|
||||||
-- non-player expirationTime). What remains in libdebuff is the cast-event
|
-- non-player expirationTime). What remains in libdebuff is the cast-event
|
||||||
-- bookkeeping consumed by GetBestAuraCast / GetEnhancedDebuffs and the
|
-- bookkeeping consumed by GetBestAuraCast (libpredict HoT tracking) and the
|
||||||
-- libdebuff_*_hooks broadcast surface (subscribers in actionbar / swingtimer
|
-- libdebuff_*_hooks broadcast surface (subscribers in actionbar / swingtimer
|
||||||
-- / libtotem react to SPELL_GO and SPELL_FAILED).
|
-- / libtotem react to SPELL_GO and SPELL_FAILED).
|
||||||
|
|
||||||
@@ -43,16 +43,8 @@ if GetNampowerVersion then
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Nampower startup check: show version info and ensure CVars are set.
|
EventUtil.ContinueOnPlayerLogin(function()
|
||||||
-- Runs on first OnUpdate after PLAYER_ENTERING_WORLD to give Nampower time to initialize.
|
RunNextFrame(function()
|
||||||
local nampowerCheckFrame = CreateFrame("Frame")
|
|
||||||
nampowerCheckFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
|
||||||
nampowerCheckFrame:SetScript("OnEvent", function()
|
|
||||||
-- Defer to next frame so Nampower is fully initialized
|
|
||||||
this:SetScript("OnUpdate", function()
|
|
||||||
this:SetScript("OnUpdate", nil)
|
|
||||||
this:UnregisterAllEvents()
|
|
||||||
this:SetScript("OnEvent", nil)
|
|
||||||
|
|
||||||
if GetNampowerVersion then
|
if GetNampowerVersion then
|
||||||
local major, minor, patch = GetNampowerVersion()
|
local major, minor, patch = GetNampowerVersion()
|
||||||
@@ -60,8 +52,6 @@ nampowerCheckFrame:SetScript("OnEvent", function()
|
|||||||
local versionString = major .. "." .. minor .. "." .. patch
|
local versionString = major .. "." .. minor .. "." .. patch
|
||||||
|
|
||||||
if major > 3 or (major == 3 and minor > 0) or (major == 3 and minor == 0 and patch >= 0) then
|
if major > 3 or (major == 3 and minor > 0) or (major == 3 and minor == 0 and patch >= 0) then
|
||||||
DEFAULT_CHAT_FRAME:AddMessage("|cff33ff99[libdebuff]|r Nampower v" .. versionString .. " detected - GetUnitField mode enabled!")
|
|
||||||
|
|
||||||
if SetCVar and GetCVar then
|
if SetCVar and GetCVar then
|
||||||
local cvarsToEnable = {
|
local cvarsToEnable = {
|
||||||
"NP_EnableSpellStartEvents",
|
"NP_EnableSpellStartEvents",
|
||||||
@@ -91,8 +81,6 @@ nampowerCheckFrame:SetScript("OnEvent", function()
|
|||||||
|
|
||||||
if enabledCount > 0 then
|
if enabledCount > 0 then
|
||||||
DEFAULT_CHAT_FRAME:AddMessage("|cff33ff99[libdebuff]|r Enabled " .. enabledCount .. " Nampower CVars")
|
DEFAULT_CHAT_FRAME:AddMessage("|cff33ff99[libdebuff]|r Enabled " .. enabledCount .. " Nampower CVars")
|
||||||
elseif alreadyEnabledCount == table.getn(cvarsToEnable) then
|
|
||||||
DEFAULT_CHAT_FRAME:AddMessage("|cff33ff99[libdebuff]|r All required Nampower CVars already enabled")
|
|
||||||
end
|
end
|
||||||
if failedCount > 0 then
|
if failedCount > 0 then
|
||||||
DEFAULT_CHAT_FRAME:AddMessage("|cffffcc00[libdebuff]|r Warning: Could not check/set " .. failedCount .. " CVars")
|
DEFAULT_CHAT_FRAME:AddMessage("|cffffcc00[libdebuff]|r Warning: Could not check/set " .. failedCount .. " CVars")
|
||||||
@@ -204,10 +192,6 @@ pfUI.libdebuff_spell_cast_hooks = pfUI.libdebuff_spell_cast_hooks or {}
|
|||||||
pfUI.libdebuff_downrank_blocked_hooks = pfUI.libdebuff_downrank_blocked_hooks or {}
|
pfUI.libdebuff_downrank_blocked_hooks = pfUI.libdebuff_downrank_blocked_hooks or {}
|
||||||
local AURA_CAST_DEDUPE_WINDOW = 0.1 -- Ignore duplicates within 100ms
|
local AURA_CAST_DEDUPE_WINDOW = 0.1 -- Ignore duplicates within 100ms
|
||||||
|
|
||||||
-- Captured combo points from SPELL_CAST_EVENT (before client consumes them)
|
|
||||||
-- SPELL_CAST_EVENT fires BEFORE UnitAura updates, so GetComboPoints() still works
|
|
||||||
local capturedCP = nil
|
|
||||||
|
|
||||||
-- Pending cast info for libpredict (heal prediction target tracking)
|
-- Pending cast info for libpredict (heal prediction target tracking)
|
||||||
-- SPELL_CAST_EVENT fires with targetGuid BEFORE SPELLCAST_START,
|
-- SPELL_CAST_EVENT fires with targetGuid BEFORE SPELLCAST_START,
|
||||||
-- which allows libpredict to know the correct target for queued casts.
|
-- which allows libpredict to know the correct target for queued casts.
|
||||||
@@ -280,50 +264,10 @@ local debuffOverwritePairs = {
|
|||||||
["Demoralizing Roar"] = "Demoralizing Shout",
|
["Demoralizing Roar"] = "Demoralizing Shout",
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Combopoint-based abilities: Only show timers for OUR casts
|
|
||||||
-- Format: [spellName] = { base = N, perCP = N }
|
|
||||||
-- Duration formula: duration = base + combopoints * perCP
|
|
||||||
local combopointAbilities = {
|
|
||||||
-- Druid
|
|
||||||
["Rip"] = { base = 8, perCP = 2 },
|
|
||||||
|
|
||||||
-- Rogue
|
|
||||||
["Rupture"] = { base = 6, perCP = 2 },
|
|
||||||
["Kidney Shot"] = { base = 1, perCP = 1 },
|
|
||||||
["Slice and Dice"] = { base = 9, perCP = 3 },
|
|
||||||
["Expose Armor"] = { base = 30, perCP = 0 }, -- fixed 30s
|
|
||||||
}
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- HELPER FUNCTIONS
|
-- HELPER FUNCTIONS
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
|
||||||
-- Check if spell is a combo-point ability
|
|
||||||
local function IsComboPointAbility(spellName)
|
|
||||||
if not spellName then return false end
|
|
||||||
return combopointAbilities[spellName] ~= nil
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Get combo-point spell data (base duration and per-CP bonus)
|
|
||||||
local function GetComboPointData(spellName)
|
|
||||||
if not spellName then return nil, nil end
|
|
||||||
local cpData = combopointAbilities[spellName]
|
|
||||||
if cpData then
|
|
||||||
return cpData.base, cpData.perCP
|
|
||||||
end
|
|
||||||
return nil, nil
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Player GUID Cache
|
|
||||||
local playerGUID = nil
|
|
||||||
local function GetPlayerGUID()
|
|
||||||
if not playerGUID and UnitGUID then
|
|
||||||
local guid = UnitGUID("player")
|
|
||||||
playerGUID = guid
|
|
||||||
end
|
|
||||||
return playerGUID
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Debug Stats
|
-- Debug Stats
|
||||||
pfUI.libdebuff_debugstats = pfUI.libdebuff_debugstats or {
|
pfUI.libdebuff_debugstats = pfUI.libdebuff_debugstats or {
|
||||||
enabled = false,
|
enabled = false,
|
||||||
@@ -427,7 +371,7 @@ local function GetDebuffSlotMap(guid)
|
|||||||
local spellId = auras[auraSlot]
|
local spellId = auras[auraSlot]
|
||||||
if spellId and spellId > 0 then
|
if spellId and spellId > 0 then
|
||||||
displaySlot = displaySlot + 1
|
displaySlot = displaySlot + 1
|
||||||
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name")
|
local spellName = C_Spell.GetSpellName(spellId)
|
||||||
local texture = libdebuff:GetSpellIcon(spellId)
|
local texture = libdebuff:GetSpellIcon(spellId)
|
||||||
local stacks = (auraApps and auraApps[auraSlot] or 0) + 1
|
local stacks = (auraApps and auraApps[auraSlot] or 0) + 1
|
||||||
local dtype = nil
|
local dtype = nil
|
||||||
@@ -463,7 +407,7 @@ local function GetSlotCaster(guid, auraSlot, spellName)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Fallback: Check ownDebuffs
|
-- Fallback: Check ownDebuffs
|
||||||
local myGuid = GetPlayerGUID()
|
local myGuid = GetPlayerGuid()
|
||||||
if ownDebuffs[guid] and ownDebuffs[guid][spellName] then
|
if ownDebuffs[guid] and ownDebuffs[guid][spellName] then
|
||||||
return myGuid, true
|
return myGuid, true
|
||||||
end
|
end
|
||||||
@@ -654,16 +598,7 @@ function libdebuff:GetDuration(effect, rank)
|
|||||||
local rank = L["debuffs"][effect][rank] and rank or libdebuff:GetMaxRank(effect)
|
local rank = L["debuffs"][effect][rank] and rank or libdebuff:GetMaxRank(effect)
|
||||||
local duration = L["debuffs"][effect][rank]
|
local duration = L["debuffs"][effect][rank]
|
||||||
|
|
||||||
if effect == L["dyndebuffs"]["Rupture"] then
|
if effect == L["dyndebuffs"]["Demoralizing Shout"] then
|
||||||
local cp = GetComboPoints() or 0
|
|
||||||
duration = duration + cp*2
|
|
||||||
elseif effect == L["dyndebuffs"]["Kidney Shot"] then
|
|
||||||
local cp = GetComboPoints() or 0
|
|
||||||
duration = duration + cp*1
|
|
||||||
elseif effect == "Rip" or effect == L["dyndebuffs"]["Rip"] then
|
|
||||||
local cp = GetComboPoints() or 0
|
|
||||||
duration = 8 + cp*2
|
|
||||||
elseif effect == L["dyndebuffs"]["Demoralizing Shout"] then
|
|
||||||
local _,_,_,_,count = GetTalentInfo(2,1)
|
local _,_,_,_,count = GetTalentInfo(2,1)
|
||||||
if count and count > 0 then duration = duration + ( duration / 100 * (count*10)) end
|
if count and count > 0 then duration = duration + ( duration / 100 * (count*10)) end
|
||||||
elseif effect == L["dyndebuffs"]["Shadow Word: Pain"] then
|
elseif effect == L["dyndebuffs"]["Shadow Word: Pain"] then
|
||||||
@@ -800,7 +735,7 @@ function libdebuff:GetBestAuraCast(guid, spellName)
|
|||||||
local data = ownDebuffs[guid][spellName]
|
local data = ownDebuffs[guid][spellName]
|
||||||
local timeleft = (data.startTime + data.duration) - GetTime()
|
local timeleft = (data.startTime + data.duration) - GetTime()
|
||||||
if timeleft > 0 then
|
if timeleft > 0 then
|
||||||
return data.startTime, data.duration, timeleft, data.rank, GetPlayerGUID()
|
return data.startTime, data.duration, timeleft, data.rank, GetPlayerGuid()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -827,33 +762,6 @@ function libdebuff:GetBestAuraCast(guid, spellName)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ============================================================================
|
|
||||||
-- API: GetEnhancedDebuffs (for external modules)
|
|
||||||
-- ============================================================================
|
|
||||||
|
|
||||||
function libdebuff:GetEnhancedDebuffs(targetGUID)
|
|
||||||
if not targetGUID then return nil end
|
|
||||||
local result = {}
|
|
||||||
|
|
||||||
if ownDebuffs[targetGUID] then
|
|
||||||
local myGuid = GetPlayerGUID()
|
|
||||||
for spellName, data in pairs(ownDebuffs[targetGUID]) do
|
|
||||||
local timeleft = (data.startTime + data.duration) - GetTime()
|
|
||||||
if timeleft > 0 then
|
|
||||||
result[spellName] = result[spellName] or {}
|
|
||||||
result[spellName][myGuid] = {
|
|
||||||
startTime = data.startTime,
|
|
||||||
duration = data.duration,
|
|
||||||
texture = data.texture,
|
|
||||||
rank = data.rank
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- NAMPOWER EVENT HANDLING
|
-- NAMPOWER EVENT HANDLING
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
@@ -885,7 +793,7 @@ if hasNampower then
|
|||||||
-- Carnage triggered! Refresh Rip & Rake
|
-- Carnage triggered! Refresh Rip & Rake
|
||||||
local guid = carnageState.targetGuid
|
local guid = carnageState.targetGuid
|
||||||
local refreshTime = GetTime()
|
local refreshTime = GetTime()
|
||||||
local myGuid = GetPlayerGUID()
|
local myGuid = GetPlayerGuid()
|
||||||
|
|
||||||
-- Refresh in ownDebuffs - only if timer still active
|
-- Refresh in ownDebuffs - only if timer still active
|
||||||
if ownDebuffs[guid] then
|
if ownDebuffs[guid] then
|
||||||
@@ -967,7 +875,7 @@ if hasNampower then
|
|||||||
-- Channel interrupted by player - clear ownDebuffs for the channeled spell
|
-- Channel interrupted by player - clear ownDebuffs for the channeled spell
|
||||||
-- via C_Spell.ChannelInfo. DEBUFF_REMOVED fires later (0.5-1s server lag),
|
-- via C_Spell.ChannelInfo. DEBUFF_REMOVED fires later (0.5-1s server lag),
|
||||||
-- causing phantom debuff display without this pre-clear.
|
-- causing phantom debuff display without this pre-clear.
|
||||||
local spellName = select(1, C_Spell.ChannelInfo())
|
local spellName = C_Spell.ChannelInfo()
|
||||||
if spellName then
|
if spellName then
|
||||||
local targetGuid = UnitGUID and UnitGUID("target")
|
local targetGuid = UnitGUID and UnitGUID("target")
|
||||||
if targetGuid and ownDebuffs[targetGuid] and ownDebuffs[targetGuid][spellName] then
|
if targetGuid and ownDebuffs[targetGuid] and ownDebuffs[targetGuid][spellName] then
|
||||||
@@ -978,14 +886,8 @@ if hasNampower then
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
elseif event == "PLAYER_ENTERING_WORLD" or event == "PLAYER_TALENT_UPDATE" then
|
||||||
elseif event == "PLAYER_ENTERING_WORLD" then
|
|
||||||
GetPlayerGUID()
|
|
||||||
UpdateCarnageRank()
|
UpdateCarnageRank()
|
||||||
|
|
||||||
elseif event == "PLAYER_TALENT_UPDATE" then
|
|
||||||
UpdateCarnageRank()
|
|
||||||
|
|
||||||
elseif event == "UNIT_HEALTH" then
|
elseif event == "UNIT_HEALTH" then
|
||||||
local guid = arg1
|
local guid = arg1
|
||||||
if guid and UnitIsDead and UnitIsDead(guid) then
|
if guid and UnitIsDead and UnitIsDead(guid) then
|
||||||
@@ -1024,7 +926,7 @@ if hasNampower then
|
|||||||
local targetGuid = arg4
|
local targetGuid = arg4
|
||||||
local numHit = arg6 or 0
|
local numHit = arg6 or 0
|
||||||
local numMissed = arg7 or 0
|
local numMissed = arg7 or 0
|
||||||
|
|
||||||
-- Fire registered SPELL_GO_SELF hooks BEFORE miss guard
|
-- Fire registered SPELL_GO_SELF hooks BEFORE miss guard
|
||||||
-- (Swingtimer needs to see ALL casts, even misses, for swing reset)
|
-- (Swingtimer needs to see ALL casts, even misses, for swing reset)
|
||||||
if event == "SPELL_GO_SELF" and pfUI.libdebuff_spell_go_hooks then
|
if event == "SPELL_GO_SELF" and pfUI.libdebuff_spell_go_hooks then
|
||||||
@@ -1035,15 +937,15 @@ if hasNampower then
|
|||||||
|
|
||||||
if numMissed > 0 or numHit == 0 then return end
|
if numMissed > 0 or numHit == 0 then return end
|
||||||
|
|
||||||
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name")
|
local spellName = C_Spell.GetSpellName(spellId)
|
||||||
local spellRankString = GetSpellRecField and GetSpellRecField(spellId, "rank")
|
|
||||||
if not spellName then return end
|
if not spellName then return end
|
||||||
|
local spellRankString = C_Spell.GetSpellSubtext(spellId)
|
||||||
|
|
||||||
local castRank = 0
|
local castRank = 0
|
||||||
if spellRankString and spellRankString ~= "" then
|
if spellRankString and spellRankString ~= "" then
|
||||||
castRank = tonumber((string.gsub(spellRankString, "Rank ", ""))) or 0
|
castRank = tonumber((string.gsub(spellRankString, "Rank ", ""))) or 0
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Store in pendingCasts for DEBUFF_ADDED correlation.
|
-- Store in pendingCasts for DEBUFF_ADDED correlation.
|
||||||
-- If this cast is a downrank of an already active debuff, fire the downrank blocked hook
|
-- If this cast is a downrank of an already active debuff, fire the downrank blocked hook
|
||||||
-- so external addons (e.g. SuperCleveRoidMacros) don't need to re-implement this check.
|
-- so external addons (e.g. SuperCleveRoidMacros) don't need to re-implement this check.
|
||||||
@@ -1080,7 +982,7 @@ if hasNampower then
|
|||||||
local selfdebuffMode = pfUI_config and pfUI_config.buffbar and
|
local selfdebuffMode = pfUI_config and pfUI_config.buffbar and
|
||||||
pfUI_config.buffbar.tdebuff and pfUI_config.buffbar.tdebuff.selfdebuff == "1"
|
pfUI_config.buffbar.tdebuff and pfUI_config.buffbar.tdebuff.selfdebuff == "1"
|
||||||
if selfdebuffMode then
|
if selfdebuffMode then
|
||||||
local myGuid2 = GetPlayerGUID()
|
local myGuid2 = GetPlayerGuid()
|
||||||
if casterGuid == myGuid2 then
|
if casterGuid == myGuid2 then
|
||||||
local duration = libdebuff:GetDuration(spellName, castRank) or 0
|
local duration = libdebuff:GetDuration(spellName, castRank) or 0
|
||||||
if duration > 0 then
|
if duration > 0 then
|
||||||
@@ -1110,7 +1012,7 @@ if hasNampower then
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Store rank for our casts
|
-- Store rank for our casts
|
||||||
local myGuid = GetPlayerGUID()
|
local myGuid = GetPlayerGuid()
|
||||||
if casterGuid == myGuid then
|
if casterGuid == myGuid then
|
||||||
lastCastRanks[spellName] = {
|
lastCastRanks[spellName] = {
|
||||||
rank = castRank,
|
rank = castRank,
|
||||||
@@ -1183,11 +1085,6 @@ if hasNampower then
|
|||||||
pfUI.libpredict_pending_cast.time = nil
|
pfUI.libpredict_pending_cast.time = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Only capture CPs for combo-point abilities
|
|
||||||
if spellName and IsComboPointAbility(spellName) then
|
|
||||||
capturedCP = GetComboPoints() or 0
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Fire registered SPELL_CAST_EVENT hooks
|
-- Fire registered SPELL_CAST_EVENT hooks
|
||||||
if pfUI.libdebuff_spell_cast_hooks then
|
if pfUI.libdebuff_spell_cast_hooks then
|
||||||
for _, fn in pairs(pfUI.libdebuff_spell_cast_hooks) do
|
for _, fn in pairs(pfUI.libdebuff_spell_cast_hooks) do
|
||||||
@@ -1209,7 +1106,7 @@ if hasNampower then
|
|||||||
if not spellId then return end
|
if not spellId then return end
|
||||||
if not targetGuid or targetGuid == "" or targetGuid == "0x0000000000000000" then return end
|
if not targetGuid or targetGuid == "" or targetGuid == "0x0000000000000000" then return end
|
||||||
|
|
||||||
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name")
|
local spellName = C_Spell.GetSpellName(spellId)
|
||||||
if not spellName then return end
|
if not spellName then return end
|
||||||
|
|
||||||
-- Deduplicate: Ignore if we processed this exact cast recently (within 100ms)
|
-- Deduplicate: Ignore if we processed this exact cast recently (within 100ms)
|
||||||
@@ -1235,37 +1132,17 @@ if hasNampower then
|
|||||||
|
|
||||||
local duration = durationMs and (durationMs / 1000) or 0
|
local duration = durationMs and (durationMs / 1000) or 0
|
||||||
local startTime = GetTime()
|
local startTime = GetTime()
|
||||||
local myGuid = GetPlayerGUID()
|
local myGuid = GetPlayerGuid()
|
||||||
local isOurs = (myGuid and casterGuid == myGuid)
|
local isOurs = (myGuid and casterGuid == myGuid)
|
||||||
|
|
||||||
if debugStats.enabled and isOurs then
|
if debugStats.enabled and isOurs then
|
||||||
debugStats.aura_cast = debugStats.aura_cast + 1
|
debugStats.aura_cast = debugStats.aura_cast + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Combo-point abilities: Calculate duration based on CPs used
|
-- Duration comes from nampower's AURA_CAST event. ClassicAPI's
|
||||||
if IsComboPointAbility(spellName) then
|
-- C_UnitAuras now resolves combo-scaled durations server-side, so
|
||||||
if isOurs then
|
-- libdebuff only needs the database fallback when AURA_CAST reports 0.
|
||||||
-- OWN casts: use captured CPs from SPELL_CAST_EVENT (if available)
|
if duration == 0 then
|
||||||
local cp = capturedCP or 0
|
|
||||||
local base, perCP = GetComboPointData(spellName)
|
|
||||||
if base and perCP then
|
|
||||||
duration = base + cp * perCP
|
|
||||||
else
|
|
||||||
-- Fallback to legacy database
|
|
||||||
duration = libdebuff:GetDuration(spellName, rankNum)
|
|
||||||
end
|
|
||||||
capturedCP = nil -- consumed
|
|
||||||
else
|
|
||||||
-- OTHER players: CP unknown, no timer (except Expose Armor = fixed 30s)
|
|
||||||
local base, perCP = GetComboPointData(spellName)
|
|
||||||
if perCP and perCP == 0 and base then
|
|
||||||
duration = base -- fixed duration (Expose Armor)
|
|
||||||
else
|
|
||||||
duration = 0 -- CP unknown for other players
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif duration == 0 then
|
|
||||||
-- Non-CP managed spells: use database if AURA_CAST returned 0
|
|
||||||
duration = libdebuff:GetDuration(spellName, rankNum) or 0
|
duration = libdebuff:GetDuration(spellName, rankNum) or 0
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1367,15 +1244,12 @@ if hasNampower then
|
|||||||
|
|
||||||
-- Notify unitframes of debuff updates (UNIT_AURA doesn't fire on refreshes!)
|
-- Notify unitframes of debuff updates (UNIT_AURA doesn't fire on refreshes!)
|
||||||
-- Check player
|
-- Check player
|
||||||
if UnitGUID("player") then
|
if IsPlayerGuid(targetGuid) and pfPlayer then
|
||||||
local playerGuid = UnitGUID("player")
|
pfPlayer.update_aura = true
|
||||||
if playerGuid == targetGuid and pfPlayer then
|
|
||||||
pfPlayer.update_aura = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check target
|
-- Check target
|
||||||
if UnitGUID("target") then
|
if UnitExists("target") then
|
||||||
local tarUnitGUID = UnitGUID("target")
|
local tarUnitGUID = UnitGUID("target")
|
||||||
if tarUnitGUID == targetGuid and pfTarget then
|
if tarUnitGUID == targetGuid and pfTarget then
|
||||||
pfTarget.update_aura = true
|
pfTarget.update_aura = true
|
||||||
@@ -1469,7 +1343,7 @@ if hasNampower then
|
|||||||
|
|
||||||
-- Invalidate slot map cache for this GUID
|
-- Invalidate slot map cache for this GUID
|
||||||
|
|
||||||
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name")
|
local spellName = C_Spell.GetSpellName(spellId)
|
||||||
if not spellName then return end
|
if not spellName then return end
|
||||||
|
|
||||||
if debugStats.enabled then
|
if debugStats.enabled then
|
||||||
@@ -1522,7 +1396,7 @@ if hasNampower then
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local myGuid = GetPlayerGUID()
|
local myGuid = GetPlayerGuid()
|
||||||
local isOurs = (myGuid and casterGuid == myGuid)
|
local isOurs = (myGuid and casterGuid == myGuid)
|
||||||
|
|
||||||
-- Fallback: Check ownDebuffs timing
|
-- Fallback: Check ownDebuffs timing
|
||||||
@@ -1557,7 +1431,6 @@ if hasNampower then
|
|||||||
-- CRITICAL FIX: Update ownDebuffs here too for refresh timing!
|
-- CRITICAL FIX: Update ownDebuffs here too for refresh timing!
|
||||||
-- This prevents the gap between DEBUFF_REMOVED and AURA_CAST where buffwatch shows nothing
|
-- This prevents the gap between DEBUFF_REMOVED and AURA_CAST where buffwatch shows nothing
|
||||||
if isOurs and casterGuid then
|
if isOurs and casterGuid then
|
||||||
local myGuid = GetPlayerGUID()
|
|
||||||
if myGuid and casterGuid == myGuid then
|
if myGuid and casterGuid == myGuid then
|
||||||
-- Check if we have timer data from allAuraCasts
|
-- Check if we have timer data from allAuraCasts
|
||||||
if allAuraCasts[guid] and allAuraCasts[guid][spellName] and allAuraCasts[guid][spellName][casterGuid] then
|
if allAuraCasts[guid] and allAuraCasts[guid][spellName] and allAuraCasts[guid][spellName][casterGuid] then
|
||||||
@@ -1599,9 +1472,9 @@ if hasNampower then
|
|||||||
local auraSlot = auraSlot_0based and (auraSlot_0based + 1) or nil
|
local auraSlot = auraSlot_0based and (auraSlot_0based + 1) or nil
|
||||||
|
|
||||||
-- Invalidate slot map cache for this GUID
|
-- Invalidate slot map cache for this GUID
|
||||||
|
|
||||||
local spellName = (GetSpellRecField and GetSpellRecField(spellId, "name")) or "?"
|
local spellName = C_Spell.GetSpellName(spellId) or "?"
|
||||||
|
|
||||||
if debugStats.enabled then
|
if debugStats.enabled then
|
||||||
debugStats.debuff_removed = debugStats.debuff_removed + 1
|
debugStats.debuff_removed = debugStats.debuff_removed + 1
|
||||||
if IsCurrentTarget(guid) then
|
if IsCurrentTarget(guid) then
|
||||||
@@ -1609,13 +1482,13 @@ if hasNampower then
|
|||||||
GetDebugTimestamp(), displaySlot, auraSlot or -1, auraSlot_0based or -1, spellName))
|
GetDebugTimestamp(), displaySlot, auraSlot or -1, auraSlot_0based or -1, spellName))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- If unit is dead, cleanup all
|
-- If unit is dead, cleanup all
|
||||||
if UnitIsDead and UnitIsDead(guid) then
|
if UnitIsDead and UnitIsDead(guid) then
|
||||||
CleanupUnit(guid)
|
CleanupUnit(guid)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Get auraSlot from event parameter (Nampower 2.29+)
|
-- Get auraSlot from event parameter (Nampower 2.29+)
|
||||||
-- Fallback to displayToAura mapping if not available
|
-- Fallback to displayToAura mapping if not available
|
||||||
local foundAuraSlot = auraSlot
|
local foundAuraSlot = auraSlot
|
||||||
@@ -1811,5 +1684,3 @@ _G.SlashCmdList["MEMCHECK"] = function()
|
|||||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00No ownSlots/allSlots (eliminated by GetUnitField approach!)|r")
|
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00No ownSlots/allSlots (eliminated by GetUnitField approach!)|r")
|
||||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ffff============================================================|r")
|
DEFAULT_CHAT_FRAME:AddMessage("|cff00ffff============================================================|r")
|
||||||
end
|
end
|
||||||
|
|
||||||
DEFAULT_CHAT_FRAME:AddMessage("|cff33ff99[libdebuff]|r GetUnitField Edition loaded!")
|
|
||||||
+37
-102
@@ -44,78 +44,13 @@ local healGuidToName = {} -- [casterGuid] = casterName, for SPELL_FAILED_OTHER c
|
|||||||
local ress_timers = {} -- [target][sender] = expiry_timestamp (60s rez window)
|
local ress_timers = {} -- [target][sender] = expiry_timestamp (60s rez window)
|
||||||
local RESS_TIMEOUT = 60 -- Vanilla: rez offer expires after 60s
|
local RESS_TIMEOUT = 60 -- Vanilla: rez offer expires after 60s
|
||||||
|
|
||||||
local PRAYER_OF_HEALING
|
-- Localized spell names resolved once from canonical rank-1 spellIDs.
|
||||||
do -- Prayer of Healing
|
-- Every rank shares the same name, so per-rank comparisons elsewhere can
|
||||||
local locales = {
|
-- be done against these constants without per-locale or per-rank tables.
|
||||||
["deDE"] = "Gebet der Heilung",
|
local PRAYER_OF_HEALING = C_Spell.GetSpellName(596) -- Prayer of Healing (Rank 1)
|
||||||
["enUS"] = "Prayer of Healing",
|
local REJUVENATION = C_Spell.GetSpellName(774) -- Rejuvenation (Rank 1)
|
||||||
["esES"] = "Rezo de curación",
|
local RENEW = C_Spell.GetSpellName(139) -- Renew (Rank 1)
|
||||||
["frFR"] = "Prière de soins",
|
local REGROWTH = C_Spell.GetSpellName(8936) -- Regrowth (Rank 1)
|
||||||
["koKR"] = "치유의 기원",
|
|
||||||
["ruRU"] = "Молитва исцеления",
|
|
||||||
["zhCN"] = "治疗祷言",
|
|
||||||
}
|
|
||||||
|
|
||||||
PRAYER_OF_HEALING = locales[GetLocale()] or locales["enUS"]
|
|
||||||
end
|
|
||||||
|
|
||||||
local REJUVENATION
|
|
||||||
do -- Rejuvenation
|
|
||||||
local locales = {
|
|
||||||
["deDE"] = "Verjüngung",
|
|
||||||
["enUS"] = "Rejuvenation",
|
|
||||||
["esES"] = "Rejuvenecimiento",
|
|
||||||
["frFR"] = "Récupération",
|
|
||||||
["koKR"] = "회복",
|
|
||||||
["ruRU"] = "Омоложение",
|
|
||||||
["zhCN"] = "回春术",
|
|
||||||
}
|
|
||||||
|
|
||||||
REJUVENATION = locales[GetLocale()] or locales["enUS"]
|
|
||||||
end
|
|
||||||
|
|
||||||
local RENEW
|
|
||||||
do -- Renew
|
|
||||||
local locales = {
|
|
||||||
["deDE"] = "Erneuerung",
|
|
||||||
["enUS"] = "Renew",
|
|
||||||
["esES"] = "Renovar",
|
|
||||||
["frFR"] = "Rénovation",
|
|
||||||
["koKR"] = "소생",
|
|
||||||
["ruRU"] = "Обновление",
|
|
||||||
["zhCN"] = "恢复",
|
|
||||||
}
|
|
||||||
|
|
||||||
RENEW = locales[GetLocale()] or locales["enUS"]
|
|
||||||
end
|
|
||||||
|
|
||||||
local REGROWTH
|
|
||||||
do -- Regrowth
|
|
||||||
local locales = {
|
|
||||||
["deDE"] = "Nachwachsen",
|
|
||||||
["enUS"] = "Regrowth",
|
|
||||||
["esES"] = "Recrecimiento",
|
|
||||||
["frFR"] = "Rétablissement",
|
|
||||||
["koKR"] = "재생",
|
|
||||||
["ruRU"] = "Восстановление",
|
|
||||||
["zhCN"] = "愈合",
|
|
||||||
}
|
|
||||||
|
|
||||||
REGROWTH = locales[GetLocale()] or locales["enUS"]
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Spell IDs for SPELL_GO_SELF callback (Nampower) - Instant HoT detection
|
|
||||||
local SPELL_IDS = {
|
|
||||||
-- Rejuvenation (all ranks)
|
|
||||||
[774] = "Reju", [1058] = "Reju", [1430] = "Reju", [2090] = "Reju", [2091] = "Reju",
|
|
||||||
[3627] = "Reju", [8910] = "Reju", [9839] = "Reju", [9840] = "Reju", [9841] = "Reju",
|
|
||||||
[25299] = "Reju", [26981] = "Reju", [26982] = "Reju",
|
|
||||||
-- Renew (all ranks)
|
|
||||||
[139] = "Renew", [6074] = "Renew", [6075] = "Renew", [6076] = "Renew", [6077] = "Renew",
|
|
||||||
[6078] = "Renew", [10927] = "Renew", [10928] = "Renew", [10929] = "Renew", [25315] = "Renew",
|
|
||||||
[25221] = "Renew", [25222] = "Renew",
|
|
||||||
}
|
|
||||||
|
|
||||||
local libpredict = CreateFrame("Frame")
|
local libpredict = CreateFrame("Frame")
|
||||||
libpredict:RegisterEvent("UNIT_HEALTH")
|
libpredict:RegisterEvent("UNIT_HEALTH")
|
||||||
@@ -173,7 +108,7 @@ end
|
|||||||
|
|
||||||
local function isRezSpell(spellId)
|
local function isRezSpell(spellId)
|
||||||
if not L["resurrections"] then return false end
|
if not L["resurrections"] then return false end
|
||||||
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name")
|
local spellName = C_Spell.GetSpellName(spellId)
|
||||||
return spellName and L["resurrections"][spellName]
|
return spellName and L["resurrections"][spellName]
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -192,7 +127,7 @@ end)
|
|||||||
-- SPELL_START_SELF: own cast started (heals + rez)
|
-- SPELL_START_SELF: own cast started (heals + rez)
|
||||||
pfUI.libdebuff_spell_start_self_hooks = pfUI.libdebuff_spell_start_self_hooks or {}
|
pfUI.libdebuff_spell_start_self_hooks = pfUI.libdebuff_spell_start_self_hooks or {}
|
||||||
pfUI.libdebuff_spell_start_self_hooks["libpredict"] = function(spellId, casterGuid, targetGuid, castTime)
|
pfUI.libdebuff_spell_start_self_hooks["libpredict"] = function(spellId, casterGuid, targetGuid, castTime)
|
||||||
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name")
|
local spellName = C_Spell.GetSpellName(spellId)
|
||||||
if not spellName then return end
|
if not spellName then return end
|
||||||
|
|
||||||
local pendingTarget = nil
|
local pendingTarget = nil
|
||||||
@@ -255,7 +190,7 @@ pfUI.libdebuff_spell_start_self_hooks["libpredict"] = function(spellId, casterGu
|
|||||||
-- selfcast (ALT) = player, otherwise = current target
|
-- selfcast (ALT) = player, otherwise = current target
|
||||||
-- Use this to find the correct group to heal
|
-- Use this to find the correct group to heal
|
||||||
local pohTarget = target or player
|
local pohTarget = target or player
|
||||||
if GetNumRaidMembers() > 0 then
|
if IsInRaid() then
|
||||||
-- Raid: find pohTarget's subgroup and heal only those members
|
-- Raid: find pohTarget's subgroup and heal only those members
|
||||||
-- (Turtle WoW changed PoH to heal the target's group, not the caster's group)
|
-- (Turtle WoW changed PoH to heal the target's group, not the caster's group)
|
||||||
local targetGroup
|
local targetGroup
|
||||||
@@ -319,7 +254,7 @@ end
|
|||||||
-- SPELL_GO_SELF: own cast landed (HealStop + Regrowth timer)
|
-- SPELL_GO_SELF: own cast landed (HealStop + Regrowth timer)
|
||||||
pfUI.libdebuff_spell_go_hooks["libpredict_sender"] = function(spellId)
|
pfUI.libdebuff_spell_go_hooks["libpredict_sender"] = function(spellId)
|
||||||
libpredict:HealStop(player)
|
libpredict:HealStop(player)
|
||||||
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name")
|
local spellName = C_Spell.GetSpellName(spellId)
|
||||||
if spellName == REGROWTH then
|
if spellName == REGROWTH then
|
||||||
local now = pfUI.uf.now or GetTime()
|
local now = pfUI.uf.now or GetTime()
|
||||||
if libpredict.sender.regrowth_timer then
|
if libpredict.sender.regrowth_timer then
|
||||||
@@ -337,7 +272,7 @@ end
|
|||||||
-- Signature: fn(spellId, casterGuid, targetGuid, castTime)
|
-- Signature: fn(spellId, casterGuid, targetGuid, castTime)
|
||||||
pfUI.libdebuff_spell_start_other_hooks = pfUI.libdebuff_spell_start_other_hooks or {}
|
pfUI.libdebuff_spell_start_other_hooks = pfUI.libdebuff_spell_start_other_hooks or {}
|
||||||
pfUI.libdebuff_spell_start_other_hooks["libpredict"] = function(spellId, casterGuid, targetGuid, castTime)
|
pfUI.libdebuff_spell_start_other_hooks["libpredict"] = function(spellId, casterGuid, targetGuid, castTime)
|
||||||
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name")
|
local spellName = C_Spell.GetSpellName(spellId)
|
||||||
if not spellName then return end
|
if not spellName then return end
|
||||||
|
|
||||||
local casterName = resolveNameFromGuid(casterGuid)
|
local casterName = resolveNameFromGuid(casterGuid)
|
||||||
@@ -364,7 +299,7 @@ pfUI.libdebuff_spell_start_other_hooks["libpredict"] = function(spellId, casterG
|
|||||||
|
|
||||||
-- Prayer of Healing: heal entire subgroup of the target
|
-- Prayer of Healing: heal entire subgroup of the target
|
||||||
if spellName == PRAYER_OF_HEALING then
|
if spellName == PRAYER_OF_HEALING then
|
||||||
if GetNumRaidMembers() > 0 then
|
if IsInRaid() then
|
||||||
local targetGroup
|
local targetGroup
|
||||||
for i = 1, GetNumRaidMembers() do
|
for i = 1, GetNumRaidMembers() do
|
||||||
local rname, _, subgroup = GetRaidRosterInfo(i)
|
local rname, _, subgroup = GetRaidRosterInfo(i)
|
||||||
@@ -404,8 +339,13 @@ end
|
|||||||
-- Signature: fn(spellId, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
-- Signature: fn(spellId, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||||
pfUI.libdebuff_spell_go_hooks = pfUI.libdebuff_spell_go_hooks or {}
|
pfUI.libdebuff_spell_go_hooks = pfUI.libdebuff_spell_go_hooks or {}
|
||||||
pfUI.libdebuff_spell_go_hooks["libpredict"] = function(spellId, a1, a2, a3, a4, a5, a6, a7)
|
pfUI.libdebuff_spell_go_hooks["libpredict"] = function(spellId, a1, a2, a3, a4, a5, a6, a7)
|
||||||
-- Instant HoTs
|
-- Instant HoTs — classify by name (rank-independent) instead of a
|
||||||
local hotType = SPELL_IDS[spellId]
|
-- hardcoded per-rank ID table.
|
||||||
|
local spellName = C_Spell.GetSpellName(spellId)
|
||||||
|
local hotType
|
||||||
|
if spellName == REJUVENATION then hotType = "Reju"
|
||||||
|
elseif spellName == RENEW then hotType = "Renew"
|
||||||
|
end
|
||||||
if hotType then
|
if hotType then
|
||||||
local targetGuid = a4
|
local targetGuid = a4
|
||||||
local targetName = resolveNameFromGuid(targetGuid)
|
local targetName = resolveNameFromGuid(targetGuid)
|
||||||
@@ -426,9 +366,9 @@ pfUI.libdebuff_spell_go_hooks["libpredict"] = function(spellId, a1, a2, a3, a4,
|
|||||||
local rankStr = tostring(rank)
|
local rankStr = tostring(rank)
|
||||||
if libpredict.sender and libpredict.sender.SendHealCommMsg then
|
if libpredict.sender and libpredict.sender.SendHealCommMsg then
|
||||||
libpredict.sender:SendHealCommMsg(hotType .. "/" .. targetName .. "/" .. duration .. "/" .. rankStr .. "/")
|
libpredict.sender:SendHealCommMsg(hotType .. "/" .. targetName .. "/" .. duration .. "/" .. rankStr .. "/")
|
||||||
elseif GetNumRaidMembers() > 0 then
|
elseif IsInRaid() then
|
||||||
SendAddonMessage("HealComm", hotType .. "/" .. targetName .. "/" .. duration .. "/" .. rankStr .. "/", "RAID")
|
SendAddonMessage("HealComm", hotType .. "/" .. targetName .. "/" .. duration .. "/" .. rankStr .. "/", "RAID")
|
||||||
elseif GetNumPartyMembers() > 0 then
|
elseif IsInGroup() then
|
||||||
SendAddonMessage("HealComm", hotType .. "/" .. targetName .. "/" .. duration .. "/" .. rankStr .. "/", "PARTY")
|
SendAddonMessage("HealComm", hotType .. "/" .. targetName .. "/" .. duration .. "/" .. rankStr .. "/", "PARTY")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -878,7 +818,7 @@ local hotsetbonus = libtipscan:GetScanner("hotsetbonus")
|
|||||||
resetcache:RegisterEvent("PLAYER_ENTERING_WORLD")
|
resetcache:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
resetcache:RegisterEvent("LEARNED_SPELL_IN_TAB")
|
resetcache:RegisterEvent("LEARNED_SPELL_IN_TAB")
|
||||||
resetcache:RegisterEvent("CHARACTER_POINTS_CHANGED")
|
resetcache:RegisterEvent("CHARACTER_POINTS_CHANGED")
|
||||||
resetcache:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
resetcache:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
|
||||||
resetcache:SetScript("OnEvent", function()
|
resetcache:SetScript("OnEvent", function()
|
||||||
if event == "PLAYER_ENTERING_WORLD" then
|
if event == "PLAYER_ENTERING_WORLD" then
|
||||||
-- load and initialize previous caches of spell amounts
|
-- load and initialize previous caches of spell amounts
|
||||||
@@ -889,10 +829,7 @@ resetcache:SetScript("OnEvent", function()
|
|||||||
cache = pfUI_cache["prediction"][realm][player]["heals"]
|
cache = pfUI_cache["prediction"][realm][player]["heals"]
|
||||||
end
|
end
|
||||||
|
|
||||||
if event == "UNIT_INVENTORY_CHANGED" or "PLAYER_ENTERING_WORLD" then
|
if event == "PLAYER_EQUIPMENT_CHANGED" or event == "PLAYER_ENTERING_WORLD" then
|
||||||
-- skip non-player events
|
|
||||||
if arg1 and arg1 ~= "player" then return end
|
|
||||||
|
|
||||||
local gear = ""
|
local gear = ""
|
||||||
for id = 1, 18 do
|
for id = 1, 18 do
|
||||||
gear = gear .. (GetInventoryItemLink("player",id) or "")
|
gear = gear .. (GetInventoryItemLink("player",id) or "")
|
||||||
@@ -962,7 +899,7 @@ local INSTANT_HOT_COOLDOWN = 1.0 -- 1 Sekunde Cooldown (GCD ist 1.5s)
|
|||||||
local pendingHots = {}
|
local pendingHots = {}
|
||||||
|
|
||||||
-- Gather Data by User Actions
|
-- Gather Data by User Actions
|
||||||
hooksecurefunc("CastSpell", function(id, bookType)
|
pfUI.hooksecurefunc("CastSpell", function(id, bookType)
|
||||||
if not libpredict.sender.enabled then return end
|
if not libpredict.sender.enabled then return end
|
||||||
local effect, rank = libspell.GetSpellInfo(id, bookType)
|
local effect, rank = libspell.GetSpellInfo(id, bookType)
|
||||||
if not effect then return end
|
if not effect then return end
|
||||||
@@ -1015,12 +952,10 @@ hooksecurefunc("CastSpell", function(id, bookType)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
hooksecurefunc("CastSpellByName", function(effect, target)
|
pfUI.hooksecurefunc("CastSpellByName", function(effect, target)
|
||||||
if not libpredict.sender.enabled then return end
|
if not libpredict.sender.enabled then return end
|
||||||
local effect, rank = libspell.GetSpellInfo(effect)
|
local effect, rank = libspell.GetSpellInfo(effect)
|
||||||
if not effect then return end
|
if not effect then return end
|
||||||
local mouseover = pfUI and pfUI.uf and pfUI.uf.mouseover and pfUI.uf.mouseover.unit
|
|
||||||
mouseover = mouseover and UnitCanAssist("player", mouseover) and UnitName(mouseover)
|
|
||||||
|
|
||||||
local default = UnitName("target") and UnitCanAssist("player", "target") and UnitName("target") or UnitName("player")
|
local default = UnitName("target") and UnitCanAssist("player", "target") and UnitName("target") or UnitName("player")
|
||||||
|
|
||||||
@@ -1039,13 +974,13 @@ hooksecurefunc("CastSpellByName", function(effect, target)
|
|||||||
if not libpredict.sender.current_cast then
|
if not libpredict.sender.current_cast then
|
||||||
spell_queue[1] = effect
|
spell_queue[1] = effect
|
||||||
spell_queue[2] = effect.. ( rank or "" )
|
spell_queue[2] = effect.. ( rank or "" )
|
||||||
spell_queue[3] = target or mouseover or default
|
spell_queue[3] = target or default
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Instant HoTs: libdebuff/Nampower via GetHotDuration, hook method as fallback
|
-- Instant HoTs: libdebuff/Nampower via GetHotDuration, hook method as fallback
|
||||||
|
|
||||||
if effect == REJUVENATION then
|
if effect == REJUVENATION then
|
||||||
local hotTarget = target or mouseover or default
|
local hotTarget = target or default
|
||||||
local now = pfUI.uf.now or GetTime()
|
local now = pfUI.uf.now or GetTime()
|
||||||
local key = "Reju" .. hotTarget
|
local key = "Reju" .. hotTarget
|
||||||
|
|
||||||
@@ -1062,7 +997,7 @@ hooksecurefunc("CastSpellByName", function(effect, target)
|
|||||||
local rankStr = rankNum and tostring(rankNum) or "0"
|
local rankStr = rankNum and tostring(rankNum) or "0"
|
||||||
libpredict.sender:SendHealCommMsg("Reju/"..hotTarget.."/"..rejuvDuration.."/"..rankStr.."/")
|
libpredict.sender:SendHealCommMsg("Reju/"..hotTarget.."/"..rejuvDuration.."/"..rankStr.."/")
|
||||||
elseif effect == RENEW then
|
elseif effect == RENEW then
|
||||||
local hotTarget = target or mouseover or default
|
local hotTarget = target or default
|
||||||
local now = pfUI.uf.now or GetTime()
|
local now = pfUI.uf.now or GetTime()
|
||||||
local key = "Renew" .. hotTarget
|
local key = "Renew" .. hotTarget
|
||||||
|
|
||||||
@@ -1081,7 +1016,7 @@ hooksecurefunc("CastSpellByName", function(effect, target)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
hooksecurefunc("UseAction", function(slot, target, selfcast)
|
pfUI.hooksecurefunc("UseAction", function(slot, target, selfcast)
|
||||||
if not libpredict.sender.enabled then return end
|
if not libpredict.sender.enabled then return end
|
||||||
if not IsCurrentAction(slot) then return end
|
if not IsCurrentAction(slot) then return end
|
||||||
local kind, id = GetActionInfo(slot)
|
local kind, id = GetActionInfo(slot)
|
||||||
@@ -1145,10 +1080,10 @@ libpredict.sender = CreateFrame("Frame", "pfPredictionSender", UIParent)
|
|||||||
libpredict.sender.enabled = true
|
libpredict.sender.enabled = true
|
||||||
libpredict.sender.SendHealCommMsg = function(self, msg)
|
libpredict.sender.SendHealCommMsg = function(self, msg)
|
||||||
-- Smart channel selection: Only send to relevant channel to avoid duplicates
|
-- Smart channel selection: Only send to relevant channel to avoid duplicates
|
||||||
if GetNumRaidMembers() > 0 then
|
if IsInRaid() then
|
||||||
-- In raid: Only send to RAID (includes all raid members)
|
-- In raid: Only send to RAID (includes all raid members)
|
||||||
SendAddonMessage("HealComm", msg, "RAID")
|
SendAddonMessage("HealComm", msg, "RAID")
|
||||||
elseif GetNumPartyMembers() > 0 then
|
elseif IsInGroup() then
|
||||||
-- In party: Only send to PARTY
|
-- In party: Only send to PARTY
|
||||||
SendAddonMessage("HealComm", msg, "PARTY")
|
SendAddonMessage("HealComm", msg, "PARTY")
|
||||||
end
|
end
|
||||||
@@ -1157,10 +1092,10 @@ libpredict.sender.SendHealCommMsg = function(self, msg)
|
|||||||
end
|
end
|
||||||
libpredict.sender.SendResCommMsg = function(self, msg)
|
libpredict.sender.SendResCommMsg = function(self, msg)
|
||||||
-- Smart channel selection: Only send to relevant channel to avoid duplicates
|
-- Smart channel selection: Only send to relevant channel to avoid duplicates
|
||||||
if GetNumRaidMembers() > 0 then
|
if IsInRaid() then
|
||||||
-- In raid: Only send to RAID (includes all raid members)
|
-- In raid: Only send to RAID (includes all raid members)
|
||||||
SendAddonMessage("CTRA", msg, "RAID")
|
SendAddonMessage("CTRA", msg, "RAID")
|
||||||
elseif GetNumPartyMembers() > 0 then
|
elseif IsInGroup() then
|
||||||
-- In party: Only send to PARTY
|
-- In party: Only send to PARTY
|
||||||
SendAddonMessage("CTRA", msg, "PARTY")
|
SendAddonMessage("CTRA", msg, "PARTY")
|
||||||
end
|
end
|
||||||
@@ -1236,7 +1171,7 @@ libpredict.sender:SetScript("OnEvent", function()
|
|||||||
local amount = arg4
|
local amount = arg4
|
||||||
local isCrit = arg5 == 1
|
local isCrit = arg5 == 1
|
||||||
local isPeriodic = arg6 == 1
|
local isPeriodic = arg6 == 1
|
||||||
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name")
|
local spellName = C_Spell.GetSpellName(spellId)
|
||||||
if spellName and spell_queue[1] == spellName then
|
if spellName and spell_queue[1] == spellName then
|
||||||
UpdateCache(spell_queue[2], amount, isCrit)
|
UpdateCache(spell_queue[2], amount, isCrit)
|
||||||
end
|
end
|
||||||
@@ -1256,9 +1191,9 @@ libpredict.sender:SetScript("OnEvent", function()
|
|||||||
local casterName = resolveNameFromGuid(casterGuid)
|
local casterName = resolveNameFromGuid(casterGuid)
|
||||||
if not casterName or casterName == player then return end -- own heals handled by SPELL_HEAL_BY_SELF
|
if not casterName or casterName == player then return end -- own heals handled by SPELL_HEAL_BY_SELF
|
||||||
|
|
||||||
local spellName = GetSpellRecField and GetSpellRecField(spellId, "name")
|
local spellName = C_Spell.GetSpellName(spellId)
|
||||||
if not spellName then return end
|
if not spellName then return end
|
||||||
local rankStr = GetSpellRecField and GetSpellRecField(spellId, "rank") or ""
|
local rankStr = C_Spell.GetSpellSubtext(spellId)
|
||||||
local spellKey = spellName .. (rankStr or "")
|
local spellKey = spellName .. (rankStr or "")
|
||||||
|
|
||||||
foreignCache[casterName] = foreignCache[casterName] or {}
|
foreignCache[casterName] = foreignCache[casterName] or {}
|
||||||
|
|||||||
+1
-1
@@ -54,6 +54,6 @@ end
|
|||||||
|
|
||||||
pfUI.api.libtooltip = libtooltip
|
pfUI.api.libtooltip = libtooltip
|
||||||
|
|
||||||
hooksecurefunc(GameTooltip, "SetBagItem", function(self, container, slot)
|
pfUI.hooksecurefunc(GameTooltip, "SetBagItem", function(self, container, slot)
|
||||||
_, libtooltip.itemCount = GetContainerItemInfo(container, slot)
|
_, libtooltip.itemCount = GetContainerItemInfo(container, slot)
|
||||||
end)
|
end)
|
||||||
|
|||||||
+3
-3
@@ -241,14 +241,14 @@ pfUI.libdebuff_spell_go_hooks["libtotem"] = function(spellId)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Hook CastSpellByName to store pending name/icon per slot
|
-- Hook CastSpellByName to store pending name/icon per slot
|
||||||
hooksecurefunc("CastSpellByName", function(effect, target)
|
pfUI.hooksecurefunc("CastSpellByName", function(effect, target)
|
||||||
local name, rank, icon, _, _, _, spellId = libspell.GetSpellInfo(effect)
|
local name, rank, icon, _, _, _, spellId = libspell.GetSpellInfo(effect)
|
||||||
if not name then return end
|
if not name then return end
|
||||||
libtotem:CheckAddQueue(name, rank, icon, spellId)
|
libtotem:CheckAddQueue(name, rank, icon, spellId)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Hook CastSpell to store pending name/icon per slot
|
-- Hook CastSpell to store pending name/icon per slot
|
||||||
hooksecurefunc("CastSpell", function(id, bookType)
|
pfUI.hooksecurefunc("CastSpell", function(id, bookType)
|
||||||
if not id or not bookType then return end
|
if not id or not bookType then return end
|
||||||
if bookType ~= BOOKTYPE_SPELL and bookType ~= BOOKTYPE_PET then return end
|
if bookType ~= BOOKTYPE_SPELL and bookType ~= BOOKTYPE_PET then return end
|
||||||
local name, rank, icon, _, _, _, spellId = libspell.GetSpellInfo(id, bookType)
|
local name, rank, icon, _, _, _, spellId = libspell.GetSpellInfo(id, bookType)
|
||||||
@@ -259,7 +259,7 @@ end)
|
|||||||
-- Hook UseAction. GetActionInfo + GetMacroSpell give us the spellID
|
-- Hook UseAction. GetActionInfo + GetMacroSpell give us the spellID
|
||||||
-- directly for both spell-action and macro-action slots, so the
|
-- directly for both spell-action and macro-action slots, so the
|
||||||
-- tooltip-scan fallback (and the "no spellId available" caveat) goes away.
|
-- tooltip-scan fallback (and the "no spellId available" caveat) goes away.
|
||||||
hooksecurefunc("UseAction", function(slot, target, selfcast)
|
pfUI.hooksecurefunc("UseAction", function(slot, target, selfcast)
|
||||||
if not IsCurrentAction(slot) then return end
|
if not IsCurrentAction(slot) then return end
|
||||||
local kind, id = GetActionInfo(slot)
|
local kind, id = GetActionInfo(slot)
|
||||||
local name, rank, spellID
|
local name, rank, spellID
|
||||||
|
|||||||
@@ -1013,10 +1013,8 @@ pfUI:RegisterModule("actionbar", function ()
|
|||||||
-- no button available, create a new one
|
-- no button available, create a new one
|
||||||
if not exists then
|
if not exists then
|
||||||
-- prepare the button for vanilla
|
-- prepare the button for vanilla
|
||||||
if not f.HookScript then
|
if not f.HookScript then f.HookScript = HookScript end
|
||||||
f.HookScript = HookScript
|
f:SetScript("OnClick", ButtonClick)
|
||||||
f:SetScript("OnClick", ButtonClick)
|
|
||||||
end
|
|
||||||
|
|
||||||
if bar ~= 11 then
|
if bar ~= 11 then
|
||||||
f:RegisterForDrag("LeftButton", "RightButton")
|
f:RegisterForDrag("LeftButton", "RightButton")
|
||||||
|
|||||||
+4
-14
@@ -134,19 +134,9 @@ pfUI:RegisterModule("addoncompat", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- run the addonconflict queue when firstrun is ready
|
-- run the addonconflict queue when firstrun is ready
|
||||||
local delay = CreateFrame("Frame")
|
if pfUI.firstrun and pfUI.firstrun.completed then
|
||||||
delay:SetScript("OnUpdate", function()
|
|
||||||
-- throttle to to one query per .1 second
|
|
||||||
if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + .1 end
|
|
||||||
|
|
||||||
-- make sure the firstrun dialog has finished
|
|
||||||
if pfUI.firstrun and pfUI.firstrun.steps then
|
|
||||||
for _, step in pairs(pfUI.firstrun.steps) do
|
|
||||||
if not pfUI_init[step.name] then return end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
RunQueue()
|
RunQueue()
|
||||||
this:SetScript("OnUpdate", nil)
|
else
|
||||||
end)
|
pfUI.events:RegisterCallback("firstrun:complete", RunQueue, "addoncompat")
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|||||||
+4
-5
@@ -1,5 +1,4 @@
|
|||||||
pfUI:RegisterModule("afkcam", function ()
|
pfUI:RegisterModule("afkcam", function ()
|
||||||
local MARKED_AFK_CAPTURE = SanitizePattern(MARKED_AFK_MESSAGE)
|
|
||||||
local social_chats = {
|
local social_chats = {
|
||||||
"CHAT_MSG_SAY",
|
"CHAT_MSG_SAY",
|
||||||
"CHAT_MSG_WHISPER",
|
"CHAT_MSG_WHISPER",
|
||||||
@@ -165,10 +164,10 @@ pfUI:RegisterModule("afkcam", function ()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
afkcam:SetScript("OnEvent", function()
|
afkcam:SetScript("OnEvent", function()
|
||||||
if event == "CHAT_MSG_SYSTEM" then
|
if event == "PLAYER_FLAGS_CHANGED" then
|
||||||
if (arg1 == _G.MARKED_AFK) or strfind(arg1, MARKED_AFK_CAPTURE) then
|
if UnitIsAFK('player') then
|
||||||
delay:Show()
|
delay:Show()
|
||||||
elseif (arg1 == _G.CLEARED_AFK) then
|
elseif delay:IsVisible() then
|
||||||
delay:Hide()
|
delay:Hide()
|
||||||
this:stop()
|
this:stop()
|
||||||
end
|
end
|
||||||
@@ -180,7 +179,7 @@ pfUI:RegisterModule("afkcam", function ()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
afkcam:RegisterEvent("CHAT_MSG_SYSTEM")
|
afkcam:RegisterEvent("PLAYER_FLAGS_CHANGED")
|
||||||
afkcam:RegisterEvent("PLAYER_REGEN_DISABLED")
|
afkcam:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||||
afkcam:RegisterEvent("PLAYER_LEAVING_WORLD") -- reseting cvars on PLAYER_LOGOUT crashes the client ¯\_(ツ)_/¯
|
afkcam:RegisterEvent("PLAYER_LEAVING_WORLD") -- reseting cvars on PLAYER_LOGOUT crashes the client ¯\_(ツ)_/¯
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -19,12 +19,7 @@ pfUI:RegisterModule("autovendor", function ()
|
|||||||
local startGold = GetMoney()
|
local startGold = GetMoney()
|
||||||
C_MerchantFrame.SellAllJunkItems()
|
C_MerchantFrame.SellAllJunkItems()
|
||||||
|
|
||||||
local reporter = CreateFrame("Frame")
|
C_Timer.After(0.3, function()
|
||||||
reporter.deadline = GetTime() + 0.3
|
|
||||||
reporter:SetScript("OnUpdate", function()
|
|
||||||
if GetTime() < this.deadline then return end
|
|
||||||
this:SetScript("OnUpdate", nil)
|
|
||||||
this:Hide()
|
|
||||||
local income = GetMoney() - startGold
|
local income = GetMoney() - startGold
|
||||||
if income > 0 then
|
if income > 0 then
|
||||||
DEFAULT_CHAT_FRAME:AddMessage(T["Your vendor trash has been sold and you earned"] .. " " .. CreateGoldString(income))
|
DEFAULT_CHAT_FRAME:AddMessage(T["Your vendor trash has been sold and you earned"] .. " " .. CreateGoldString(income))
|
||||||
|
|||||||
+3
-3
@@ -12,7 +12,9 @@ pfUI:RegisterModule("bubbles", function ()
|
|||||||
pfUI.bubbles:RegisterEvent("CHAT_MSG_MONSTER_PARTY")
|
pfUI.bubbles:RegisterEvent("CHAT_MSG_MONSTER_PARTY")
|
||||||
|
|
||||||
pfUI.bubbles:SetScript("OnEvent", function()
|
pfUI.bubbles:SetScript("OnEvent", function()
|
||||||
pfUI.bubbles:SetScript("OnUpdate", pfUI.bubbles.ScanBubbles)
|
-- Bubble frames are attached to WorldFrame after the chat event fires,
|
||||||
|
-- so wait one tick before scanning.
|
||||||
|
RunNextFrame(function() pfUI.bubbles:ScanBubbles() end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
function pfUI.bubbles:IsBubble(f)
|
function pfUI.bubbles:IsBubble(f)
|
||||||
@@ -66,7 +68,5 @@ pfUI:RegisterModule("bubbles", function ()
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
pfUI.bubbles:SetScript("OnUpdate", nil)
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|||||||
+4
-4
@@ -60,6 +60,7 @@ pfUI:RegisterModule("buff", function ()
|
|||||||
buff.mode = buff.btype
|
buff.mode = buff.btype
|
||||||
buff.expirationTime = aura.expirationTime
|
buff.expirationTime = aura.expirationTime
|
||||||
buff.stackCount = aura.applications
|
buff.stackCount = aura.applications
|
||||||
|
buff.spellId = aura.spellId
|
||||||
buff.texture:SetTexture(aura.icon)
|
buff.texture:SetTexture(aura.icon)
|
||||||
|
|
||||||
if buff.btype == "HARMFUL" then
|
if buff.btype == "HARMFUL" then
|
||||||
@@ -146,9 +147,8 @@ pfUI:RegisterModule("buff", function ()
|
|||||||
CancelItemTempEnchantment(1)
|
CancelItemTempEnchantment(1)
|
||||||
elseif CancelItemTempEnchantment and this.mode and this.mode == "OFFHAND" then
|
elseif CancelItemTempEnchantment and this.mode and this.mode == "OFFHAND" then
|
||||||
CancelItemTempEnchantment(2)
|
CancelItemTempEnchantment(2)
|
||||||
else
|
elseif this.spellId then
|
||||||
local bid = GetPlayerBuff(PLAYER_BUFF_START_ID + this.id, this.btype)
|
C_Spell.CancelSpellByID(this.spellId)
|
||||||
if bid >= 0 then CancelPlayerBuff(bid) end
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ pfUI:RegisterModule("buff", function ()
|
|||||||
|
|
||||||
pfUI.buff = CreateFrame("Frame", "pfGlobalBuffFrame", UIParent)
|
pfUI.buff = CreateFrame("Frame", "pfGlobalBuffFrame", UIParent)
|
||||||
pfUI.buff:RegisterEvent("PLAYER_AURAS_CHANGED")
|
pfUI.buff:RegisterEvent("PLAYER_AURAS_CHANGED")
|
||||||
pfUI.buff:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
pfUI.buff:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
|
||||||
pfUI.buff:RegisterEvent("UNIT_MODEL_CHANGED")
|
pfUI.buff:RegisterEvent("UNIT_MODEL_CHANGED")
|
||||||
pfUI.buff:RegisterEvent("BUFF_UPDATE_DURATION_SELF")
|
pfUI.buff:RegisterEvent("BUFF_UPDATE_DURATION_SELF")
|
||||||
pfUI.buff:RegisterEvent("DEBUFF_UPDATE_DURATION_SELF")
|
pfUI.buff:RegisterEvent("DEBUFF_UPDATE_DURATION_SELF")
|
||||||
|
|||||||
@@ -99,8 +99,8 @@ pfUI:RegisterModule("buffwatch", function ()
|
|||||||
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffcc" .. skill .. "|r" .. T["is now blacklisted."])
|
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffcc" .. skill .. "|r" .. T["is now blacklisted."])
|
||||||
end
|
end
|
||||||
elseif this.parent.unit == "player" then
|
elseif this.parent.unit == "player" then
|
||||||
local bid = GetPlayerBuff(PLAYER_BUFF_START_ID + this.id, this.type)
|
local aura = C_UnitAuras.GetAuraDataByIndex("player", this.id, this.type)
|
||||||
if bid >= 0 then CancelPlayerBuff(bid) end
|
if aura and aura.spellId then C_Spell.CancelSpellByID(aura.spellId) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -241,7 +241,10 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if not this.endTime then return end
|
if not this.endTime then
|
||||||
|
if this:GetAlpha() ~= 0 then this:SetAlpha(0) end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
-- Non-player bars: if the unit disappears (target died / detarget),
|
-- Non-player bars: if the unit disappears (target died / detarget),
|
||||||
-- drop the bar immediately.
|
-- drop the bar immediately.
|
||||||
@@ -487,7 +490,7 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
-- (the config knob is read at event time so toggling takes effect on the
|
-- (the config knob is read at event time so toggling takes effect on the
|
||||||
-- next craft without a /reload). DoTradeSkill is synchronous; the server
|
-- next craft without a /reload). DoTradeSkill is synchronous; the server
|
||||||
-- roundtrip to SPELLCAST_START gives us plenty of time after this hook.
|
-- roundtrip to SPELLCAST_START gives us plenty of time after this hook.
|
||||||
hooksecurefunc("DoTradeSkill", function(index, num)
|
pfUI.hooksecurefunc("DoTradeSkill", function(index, num)
|
||||||
if pfUI.castbar.player then
|
if pfUI.castbar.player then
|
||||||
pfUI.castbar.player.pendingTradeskillCount = tonumber(num) or 1
|
pfUI.castbar.player.pendingTradeskillCount = tonumber(num) or 1
|
||||||
end
|
end
|
||||||
|
|||||||
+2
-2
@@ -24,7 +24,7 @@ pfUI:RegisterModule("chat", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
hooksecurefunc("UnitPopup_OnClick", function(self)
|
pfUI.hooksecurefunc("UnitPopup_OnClick", function(self)
|
||||||
if this.value == "IGNORE_PLAYER" then
|
if this.value == "IGNORE_PLAYER" then
|
||||||
AddIgnore(_G[UIDROPDOWNMENU_INIT_MENU].name)
|
AddIgnore(_G[UIDROPDOWNMENU_INIT_MENU].name)
|
||||||
end
|
end
|
||||||
@@ -449,7 +449,7 @@ pfUI:RegisterModule("chat", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
hooksecurefunc("FCF_SaveDock", pfUI.chat.RefreshChat)
|
pfUI.hooksecurefunc("FCF_SaveDock", pfUI.chat.RefreshChat)
|
||||||
|
|
||||||
if C.chat.global.tabmouse == "1" then
|
if C.chat.global.tabmouse == "1" then
|
||||||
pfUI.chat.mouseovertab = CreateFrame("Frame")
|
pfUI.chat.mouseovertab = CreateFrame("Frame")
|
||||||
|
|||||||
@@ -136,5 +136,5 @@ pfUI:RegisterModule("cooldown", function ()
|
|||||||
|
|
||||||
-- vanilla does not have a cooldown frame type, so we hook the
|
-- vanilla does not have a cooldown frame type, so we hook the
|
||||||
-- regular SetTimer function that each one is calling.
|
-- regular SetTimer function that each one is calling.
|
||||||
hooksecurefunc("CooldownFrame_SetTimer", SetCooldown)
|
pfUI.hooksecurefunc("CooldownFrame_SetTimer", SetCooldown)
|
||||||
end)
|
end)
|
||||||
@@ -8,9 +8,9 @@ pfUI:RegisterModule("easteregg", function ()
|
|||||||
local pvpking = CreateFrame("Frame", "pfPvPKing", UIParent)
|
local pvpking = CreateFrame("Frame", "pfPvPKing", UIParent)
|
||||||
pvpking:Hide()
|
pvpking:Hide()
|
||||||
|
|
||||||
pvpking:RegisterEvent("CHAT_MSG_SYSTEM")
|
pvpking:RegisterEvent("PLAYER_FLAGS_CHANGED")
|
||||||
pvpking:SetScript("OnEvent", function()
|
pvpking:SetScript("OnEvent", function()
|
||||||
if strfind(arg1, "You are now", 1) and strfind(arg1, "(AFK)", 1) then
|
if UnitIsAFK('player') then
|
||||||
_G.CHAT_FLAG_AFK = title .. " "
|
_G.CHAT_FLAG_AFK = title .. " "
|
||||||
this.time = GetTime()
|
this.time = GetTime()
|
||||||
this:Show()
|
this:Show()
|
||||||
@@ -61,14 +61,13 @@ pfUI:RegisterModule("easteregg", function ()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
-- trigger fireworks when being AFK
|
-- trigger fireworks when being AFK
|
||||||
fireworks:RegisterEvent("CHAT_MSG_SYSTEM")
|
fireworks:RegisterEvent("PLAYER_FLAGS_CHANGED")
|
||||||
fireworks:SetScript("OnEvent", function()
|
fireworks:SetScript("OnEvent", function()
|
||||||
if strfind(arg1, _G.MARKED_AFK) or strfind(arg1, _G.MARKED_AFK_MESSAGE) then
|
local isAFK = UnitIsAFK('player')
|
||||||
|
if isAFK then
|
||||||
this:SetAlpha(0)
|
this:SetAlpha(0)
|
||||||
this:Show()
|
|
||||||
elseif strfind(arg1, _G.CLEARED_AFK) then
|
|
||||||
this:Hide()
|
|
||||||
end
|
end
|
||||||
|
this:SetShown(isAFK)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- basic explosion animation
|
-- basic explosion animation
|
||||||
|
|||||||
+126
-219
@@ -1,243 +1,150 @@
|
|||||||
pfUI:RegisterModule("eqcompare", function ()
|
pfUI:RegisterModule("eqcompare", function ()
|
||||||
local sides = { "Left", "Right" }
|
pfUI.eqcompare = {}
|
||||||
local loc = pfUI.cache["locale"]
|
|
||||||
for key, value in pairs(L["itemtypes"]) do setglobal(key, value) end
|
|
||||||
INVTYPE_WEAPON_OTHER = INVTYPE_WEAPON.."_other"
|
|
||||||
INVTYPE_FINGER_OTHER = INVTYPE_FINGER.."_other"
|
|
||||||
INVTYPE_TRINKET_OTHER = INVTYPE_TRINKET.."_other"
|
|
||||||
|
|
||||||
local function AddHeader(tooltip)
|
local function ShowCompareItem(self, link, shift)
|
||||||
local name = tooltip:GetName()
|
self = self or GameTooltip
|
||||||
|
shift = shift or IsShiftKeyDown()
|
||||||
|
|
||||||
-- shift all entries one line down
|
if not link or (not shift and (C.tooltip.compare.showalways ~= "1" or C_Item.IsEquippedItem(link))) then
|
||||||
for i=tooltip:NumLines(), 1, -1 do
|
return
|
||||||
for _, side in pairs(sides) do
|
end
|
||||||
local current = _G[name.."Text"..side..i]
|
|
||||||
local below = _G[name.."Text"..side..i+1]
|
|
||||||
|
|
||||||
if current and current:IsShown() then
|
local shoppingTooltip1, shoppingTooltip2 = unpack(self.shoppingTooltips or { ShoppingTooltip1, ShoppingTooltip2 });
|
||||||
local text = current:GetText()
|
|
||||||
local r, g, b = current:GetTextColor()
|
|
||||||
|
|
||||||
if text and text ~= "" then
|
local SEPARATION = 6;
|
||||||
if tooltip:NumLines() < i+1 then
|
local backdrop = shoppingTooltip1.GetBackdrop and shoppingTooltip1:GetBackdrop();
|
||||||
-- add new line if required
|
local GAP = SEPARATION + ((type(backdrop) == "table" and backdrop.edgeSize) or 0);
|
||||||
tooltip:AddLine(text, r, g, b, true)
|
|
||||||
else
|
|
||||||
-- update existing lines
|
|
||||||
below:SetText(text)
|
|
||||||
below:SetTextColor(r, g, b)
|
|
||||||
below:Show()
|
|
||||||
|
|
||||||
-- hide processed line
|
local item1 = nil;
|
||||||
current:Hide()
|
local item2 = nil;
|
||||||
end
|
local side = "left";
|
||||||
end
|
if ( shoppingTooltip1:SetHyperlinkCompareItem(link, 1, shift, self) ) then
|
||||||
end
|
item1 = true;
|
||||||
|
end
|
||||||
|
if ( shoppingTooltip2:SetHyperlinkCompareItem(link, 2, shift, self) ) then
|
||||||
|
item2 = true;
|
||||||
|
end
|
||||||
|
|
||||||
|
-- find correct side
|
||||||
|
local rightDist = 0;
|
||||||
|
local leftPos = self:GetLeft();
|
||||||
|
local rightPos = self:GetRight();
|
||||||
|
if ( not rightPos ) then
|
||||||
|
rightPos = 0;
|
||||||
|
end
|
||||||
|
if ( not leftPos ) then
|
||||||
|
leftPos = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
rightDist = GetScreenWidth() - rightPos;
|
||||||
|
|
||||||
|
if (leftPos and (rightDist < leftPos)) then
|
||||||
|
side = "left";
|
||||||
|
else
|
||||||
|
side = "right";
|
||||||
|
end
|
||||||
|
|
||||||
|
-- see if we should slide the tooltip
|
||||||
|
if ( self:GetAnchorType() and self:GetAnchorType() ~= "ANCHOR_PRESERVE" ) then
|
||||||
|
local totalWidth = 0;
|
||||||
|
if ( item1 ) then
|
||||||
|
totalWidth = totalWidth + shoppingTooltip1:GetWidth();
|
||||||
|
end
|
||||||
|
if ( item2 ) then
|
||||||
|
totalWidth = totalWidth + shoppingTooltip2:GetWidth();
|
||||||
|
end
|
||||||
|
|
||||||
|
if ( (side == "left") and (totalWidth > leftPos) ) then
|
||||||
|
self:SetAnchorType(self:GetAnchorType(), (totalWidth - leftPos), 0);
|
||||||
|
elseif ( (side == "right") and (rightPos + totalWidth) > GetScreenWidth() ) then
|
||||||
|
self:SetAnchorType(self:GetAnchorType(), -((rightPos + totalWidth) - GetScreenWidth()), 0);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- add label to first line
|
if ( item1 ) then
|
||||||
_G[name.."TextLeft1"]:SetTextColor(.5, .5, .5, 1)
|
shoppingTooltip1:SetOwner(self, "ANCHOR_NONE");
|
||||||
_G[name.."TextLeft1"]:SetText(CURRENTLY_EQUIPPED)
|
shoppingTooltip1:ClearAllPoints();
|
||||||
_G[name.."TextLeft1"]:Show()
|
if ( side and side == "left" ) then
|
||||||
|
shoppingTooltip1:SetPoint("TOPRIGHT", self, "TOPLEFT", -GAP, -10);
|
||||||
|
else
|
||||||
|
shoppingTooltip1:SetPoint("TOPLEFT", self, "TOPRIGHT", GAP, -10);
|
||||||
|
end
|
||||||
|
shoppingTooltip1:SetHyperlinkCompareItem(link, 1, shift, self);
|
||||||
|
shoppingTooltip1:Show();
|
||||||
|
|
||||||
-- update tooltip sizes
|
if ( item2 ) then
|
||||||
tooltip:Show()
|
shoppingTooltip2:SetOwner(shoppingTooltip1, "ANCHOR_NONE");
|
||||||
|
shoppingTooltip2:ClearAllPoints();
|
||||||
|
if ( side and side == "left" ) then
|
||||||
|
shoppingTooltip2:SetPoint("TOPRIGHT", shoppingTooltip1, "TOPLEFT", -GAP, 0);
|
||||||
|
else
|
||||||
|
shoppingTooltip2:SetPoint("TOPLEFT", shoppingTooltip1, "TOPRIGHT", GAP, 0);
|
||||||
|
end
|
||||||
|
shoppingTooltip2:SetHyperlinkCompareItem(link, 2, shift, self);
|
||||||
|
shoppingTooltip2:Show();
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local slotTable = {
|
local prevMerchant = ShoppingTooltip1.SetMerchantCompareItem
|
||||||
[INVTYPE_2HWEAPON] = "MainHandSlot",
|
local function SetMerchantCompareItem(self, index, compareItem)
|
||||||
[INVTYPE_BODY] = "ShirtSlot",
|
if C.tooltip.compare.basestats == "1" and compareItem == 1 then
|
||||||
[INVTYPE_CHEST] = "ChestSlot",
|
ShowCompareItem(nil, GetMerchantItemLink(index), 1)
|
||||||
[INVTYPE_CLOAK] = "BackSlot",
|
return false
|
||||||
[INVTYPE_FEET] = "FeetSlot",
|
end
|
||||||
[INVTYPE_FINGER] = "Finger0Slot",
|
return prevMerchant and prevMerchant(self, index, compareItem)
|
||||||
[INVTYPE_FINGER_OTHER] = "Finger1Slot",
|
end
|
||||||
[INVTYPE_HAND] = "HandsSlot",
|
|
||||||
[INVTYPE_HEAD] = "HeadSlot",
|
|
||||||
[INVTYPE_HOLDABLE] = "SecondaryHandSlot",
|
|
||||||
[INVTYPE_LEGS] = "LegsSlot",
|
|
||||||
[INVTYPE_NECK] = "NeckSlot",
|
|
||||||
[INVTYPE_RANGED] = "RangedSlot",
|
|
||||||
[INVTYPE_RELIC] = "RangedSlot",
|
|
||||||
[INVTYPE_ROBE] = "ChestSlot",
|
|
||||||
[INVTYPE_SHIELD] = "SecondaryHandSlot",
|
|
||||||
[INVTYPE_SHOULDER] = "ShoulderSlot",
|
|
||||||
[INVTYPE_TABARD] = "TabardSlot",
|
|
||||||
[INVTYPE_TRINKET] = "Trinket0Slot",
|
|
||||||
[INVTYPE_TRINKET_OTHER] = "Trinket1Slot",
|
|
||||||
[INVTYPE_WAIST] = "WaistSlot",
|
|
||||||
[INVTYPE_WEAPON] = "MainHandSlot",
|
|
||||||
[INVTYPE_WEAPON_OTHER] = "SecondaryHandSlot",
|
|
||||||
[INVTYPE_WEAPONMAINHAND] = "MainHandSlot",
|
|
||||||
[INVTYPE_WEAPONOFFHAND] = "SecondaryHandSlot",
|
|
||||||
[INVTYPE_WRIST] = "WristSlot",
|
|
||||||
|
|
||||||
[INVTYPE_WAND] = "RangedSlot",
|
local prevAuction = ShoppingTooltip1.SetAuctionCompareItem
|
||||||
[INVTYPE_GUN] = "RangedSlot",
|
local function SetAuctionCompareItem(self, type, index, compareItem)
|
||||||
[INVTYPE_PROJECTILE] = "AmmoSlot",
|
if C.tooltip.compare.basestats == "1" and compareItem == 1 then
|
||||||
[INVTYPE_CROSSBOW] = "RangedSlot",
|
ShowCompareItem(nil, GetAuctionItemLink(type, index), 1)
|
||||||
[INVTYPE_THROWN] = "RangedSlot",
|
return false
|
||||||
|
end
|
||||||
|
return prevAuction and prevAuction(self, type, index, compareItem)
|
||||||
|
end
|
||||||
|
|
||||||
|
ShoppingTooltip1.SetMerchantCompareItem = SetMerchantCompareItem
|
||||||
|
ShoppingTooltip2.SetMerchantCompareItem = SetMerchantCompareItem
|
||||||
|
ShoppingTooltip1.SetAuctionCompareItem = SetAuctionCompareItem
|
||||||
|
ShoppingTooltip2.SetAuctionCompareItem = SetAuctionCompareItem
|
||||||
|
|
||||||
|
local TooltipHooks = {
|
||||||
|
SetLootRollItem = GetLootRollItemLink,
|
||||||
|
SetLootItem = GetLootSlotLink,
|
||||||
|
SetQuestLogItem = GetQuestLogItemLink,
|
||||||
|
SetQuestItem = GetQuestItemLink,
|
||||||
|
SetHyperlink = function(link) return link end,
|
||||||
|
SetBagItem = GetContainerItemLink,
|
||||||
|
SetInboxItem = GetInboxItemLink,
|
||||||
|
SetInventoryItem = GetInventoryItemLink,
|
||||||
|
SetTradeSkillItem = function(skillIndex, reagentIndex)
|
||||||
|
if reagentIndex then
|
||||||
|
return GetTradeSkillReagentItemLink(skillIndex, reagentIndex)
|
||||||
|
else
|
||||||
|
return GetTradeSkillItemLink(skillIndex)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
SetAuctionSellItem = GetAuctionSellItemLink,
|
||||||
|
SetTradePlayerItem = GetTradePlayerItemLink,
|
||||||
|
SetTradeTargetItem = GetTradeTargetItemLink
|
||||||
}
|
}
|
||||||
|
|
||||||
local function startsWith(str, start)
|
local function makeHook(getter)
|
||||||
return string.sub(str, 1, string.len(start)) == start
|
return function(tooltip, arg1, arg2, arg3)
|
||||||
end
|
if C.tooltip.compare.basestats == "1" then
|
||||||
|
ShowCompareItem(tooltip, getter(arg1, arg2, arg3))
|
||||||
local function ExtractAttributes(tooltip)
|
|
||||||
local name = tooltip:GetName()
|
|
||||||
|
|
||||||
-- get the name/header of the last set comparison tooltip
|
|
||||||
local comparetooltip = pfUI.eqcompare.tooltip:GetName()
|
|
||||||
local iname = _G[comparetooltip .. "TextLeft1"] and _G[comparetooltip .. "TextLeft1"]:GetText()
|
|
||||||
|
|
||||||
-- only run once per item
|
|
||||||
if tooltip.pfCompLastName == iname then return end
|
|
||||||
|
|
||||||
tooltip.pfCompData = {}
|
|
||||||
tooltip.pfCompLastName = iname
|
|
||||||
|
|
||||||
for i=1,30 do
|
|
||||||
local widget = _G[name.."TextLeft"..i]
|
|
||||||
if widget and widget:GetObjectType() == "FontString" then
|
|
||||||
local text = widget:GetText()
|
|
||||||
if text and not string.find(text, "-", 1, true) then
|
|
||||||
local start = 1
|
|
||||||
if startsWith(text, "\+") or startsWith(text, "\(") then start = 2 end
|
|
||||||
|
|
||||||
local space = string.find(text, " ", 1, true)
|
|
||||||
if space then
|
|
||||||
local value = tonumber(string.sub(text, start, space-1))
|
|
||||||
if value and text then
|
|
||||||
-- we've found an attr
|
|
||||||
local attr = string.sub(text, space, string.len(text))
|
|
||||||
tooltip.pfCompData[attr] = { value = tonumber(value), widget = widget }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function CompareAttributes(data, targetData)
|
local function HookTooltip(tooltip)
|
||||||
if not data then return end
|
for setter, getter in pairs(TooltipHooks) do
|
||||||
|
pfUI.hooksecurefunc(tooltip, setter, makeHook(getter))
|
||||||
for attr,v in pairs(data) do
|
|
||||||
if targetData then
|
|
||||||
local target = targetData[attr]
|
|
||||||
if target then
|
|
||||||
if v.value ~= target.value and v.widget:GetText() then
|
|
||||||
if v.value > target.value then
|
|
||||||
if not strfind(v.widget:GetText(), "|cff88ff88") and not strfind(v.widget:GetText(), "|cffff8888") then
|
|
||||||
v.widget:SetText(v.widget:GetText() .. "|cff88ff88 (+" .. round(v.value - target.value, 1) .. ")")
|
|
||||||
end
|
|
||||||
elseif not v.widget.compSet then
|
|
||||||
if not strfind(v.widget:GetText(), "|cff88ff88") and not strfind(v.widget:GetText(), "|cffff8888") then
|
|
||||||
v.widget:SetText(v.widget:GetText() .. "|cffff8888 (-" .. round(target.value - v.value, 1) .. ")")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
target.processed = true
|
|
||||||
else
|
|
||||||
target.processed = true
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- this attribute doesnt exist in target
|
|
||||||
if v.widget and v.widget:GetText() then
|
|
||||||
if not strfind(v.widget:GetText(), "|cff88ff88") and not strfind(v.widget:GetText(), "|cffff8888") then
|
|
||||||
v.widget:SetText(v.widget:GetText() .. "|cff88ff88 (+" .. v.value .. ")")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for _,target in pairs(targetData) do
|
|
||||||
if target and not target.processed then
|
|
||||||
-- we are an extra value
|
|
||||||
local text = target.widget:GetText()
|
|
||||||
if text and not strfind(text, "|cff88ff88") and not strfind(text, "|cffff8888") then
|
|
||||||
target.widget:SetText(text .. "|cff88ff88 (+" .. target.value .. ")")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
pfUI.eqcompare = {}
|
HookTooltip(GameTooltip)
|
||||||
pfUI.eqcompare.GameTooltipShow = function()
|
|
||||||
-- use this tooltip for the next comparison
|
|
||||||
pfUI.eqcompare.tooltip = this
|
|
||||||
|
|
||||||
if not IsShiftKeyDown() and C.tooltip.compare.showalways ~= "1" then return end
|
pfUI.eqcompare.HookTooltip = HookTooltip
|
||||||
local rawborder, border = GetBorderSize()
|
|
||||||
|
|
||||||
for i=1,this:NumLines() do
|
|
||||||
local tmpText = _G[this:GetName() .. "TextLeft"..i]
|
|
||||||
for slotType, slotName in pairs(slotTable) do
|
|
||||||
if tmpText:GetText() == slotType then
|
|
||||||
local slotID = GetInventorySlotInfo(slotTable[slotType])
|
|
||||||
|
|
||||||
-- determine screen part
|
|
||||||
local ltrigger = GetScreenWidth() / 2
|
|
||||||
local x = GetCursorPosition()
|
|
||||||
x = x / UIParent:GetEffectiveScale()
|
|
||||||
if x > ltrigger then ltrigger = nil end
|
|
||||||
|
|
||||||
-- first tooltip
|
|
||||||
ShoppingTooltip1:SetOwner(this, "ANCHOR_NONE")
|
|
||||||
ShoppingTooltip1:ClearAllPoints()
|
|
||||||
|
|
||||||
if ltrigger then
|
|
||||||
ShoppingTooltip1:SetPoint("BOTTOMLEFT", this, "BOTTOMRIGHT", 0, 0)
|
|
||||||
else
|
|
||||||
ShoppingTooltip1:SetPoint("BOTTOMRIGHT", this, "BOTTOMLEFT", -border*2-1, 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
ShoppingTooltip1:SetInventoryItem("player", slotID)
|
|
||||||
ShoppingTooltip1:Show()
|
|
||||||
AddHeader(ShoppingTooltip1)
|
|
||||||
|
|
||||||
-- second tooltip
|
|
||||||
if slotTable[slotType .. "_other"] then
|
|
||||||
local slotID_other = GetInventorySlotInfo(slotTable[slotType .. "_other"])
|
|
||||||
|
|
||||||
ShoppingTooltip2:SetOwner(this, "ANCHOR_NONE")
|
|
||||||
ShoppingTooltip2:ClearAllPoints()
|
|
||||||
|
|
||||||
if ltrigger then
|
|
||||||
ShoppingTooltip2:SetPoint("BOTTOMLEFT", ShoppingTooltip1, "BOTTOMRIGHT", 0, 0)
|
|
||||||
else
|
|
||||||
ShoppingTooltip2:SetPoint("BOTTOMRIGHT", ShoppingTooltip1, "BOTTOMLEFT", -border*2-1, 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
ShoppingTooltip2:SetInventoryItem("player", slotID_other)
|
|
||||||
ShoppingTooltip2:Show()
|
|
||||||
AddHeader(ShoppingTooltip2)
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add HookScript method if not already existing
|
|
||||||
GameTooltip.HookScript = GameTooltip.HookScript or HookScript
|
|
||||||
ShoppingTooltip1.HookScript = ShoppingTooltip1.HookScript or HookScript
|
|
||||||
ShoppingTooltip2.HookScript = ShoppingTooltip2.HookScript or HookScript
|
|
||||||
|
|
||||||
pfUI.eqcompare.ShoppingTooltipShow = function()
|
|
||||||
-- abort if no comparison tooltip has been set
|
|
||||||
if not pfUI.eqcompare.tooltip then return end
|
|
||||||
|
|
||||||
ExtractAttributes(this)
|
|
||||||
ExtractAttributes(pfUI.eqcompare.tooltip)
|
|
||||||
CompareAttributes(pfUI.eqcompare.tooltip.pfCompData, this.pfCompData)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Add Gametooltip Hooks
|
|
||||||
GameTooltip:HookScript("OnShow", pfUI.eqcompare.GameTooltipShow)
|
|
||||||
if C.tooltip.compare.basestats == "1" then
|
|
||||||
ShoppingTooltip1:HookScript("OnShow", pfUI.eqcompare.ShoppingTooltipShow)
|
|
||||||
ShoppingTooltip2:HookScript("OnShow", pfUI.eqcompare.ShoppingTooltipShow)
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -1048,11 +1048,10 @@ pfUI:RegisterModule("equipmentmanager", function()
|
|||||||
events:RegisterEvent("EQUIPMENT_SETS_CHANGED")
|
events:RegisterEvent("EQUIPMENT_SETS_CHANGED")
|
||||||
events:RegisterEvent("EQUIPMENT_SWAP_FINISHED")
|
events:RegisterEvent("EQUIPMENT_SWAP_FINISHED")
|
||||||
events:RegisterEvent("EQUIPMENT_SWAP_PENDING")
|
events:RegisterEvent("EQUIPMENT_SWAP_PENDING")
|
||||||
events:RegisterEvent("BAG_UPDATE_DELAYED") -- ClassicAPI debounced; ~4x fewer refreshes than BAG_UPDATE
|
events:RegisterEvent("BAG_UPDATE_DELAYED")
|
||||||
events:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
events:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
|
||||||
events:SetScript("OnEvent", function()
|
events:SetScript("OnEvent", function()
|
||||||
if not frame:IsShown() then return end
|
if not frame:IsShown() then return end
|
||||||
if event == "UNIT_INVENTORY_CHANGED" and arg1 ~= "player" then return end
|
|
||||||
pfUI.equipmentmanager.Refresh()
|
pfUI.equipmentmanager.Refresh()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,11 @@ pfUI:RegisterModule("firstrun", function ()
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not self.completed then
|
||||||
|
self.completed = true
|
||||||
|
pfUI.events:TriggerEvent("firstrun:complete")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- main function to create wizard windows
|
-- main function to create wizard windows
|
||||||
|
|||||||
+1
-3
@@ -50,10 +50,8 @@ function SlashCmdList.PFFOCUSNAME(msg)
|
|||||||
FocusUnit("target")
|
FocusUnit("target")
|
||||||
end
|
end
|
||||||
|
|
||||||
local restore = CreateFrame("Frame")
|
RunNextFrame(function()
|
||||||
restore:SetScript("OnUpdate", function()
|
|
||||||
UIErrorsFrame:RegisterEvent("UI_ERROR_MESSAGE")
|
UIErrorsFrame:RegisterEvent("UI_ERROR_MESSAGE")
|
||||||
restore:SetScript("OnUpdate", nil)
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if prevGUID and prevGUID ~= "0x0000000000000000" then
|
if prevGUID and prevGUID ~= "0x0000000000000000" then
|
||||||
|
|||||||
+2
-2
@@ -150,7 +150,7 @@ pfUI:RegisterSkin("Friends", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- set positions
|
-- set positions
|
||||||
hooksecurefunc("WhoList_Update", function()
|
pfUI.hooksecurefunc("WhoList_Update", function()
|
||||||
for i = 1, WHOS_TO_DISPLAY do
|
for i = 1, WHOS_TO_DISPLAY do
|
||||||
local level = _G["WhoFrameButton"..i.."Level"]
|
local level = _G["WhoFrameButton"..i.."Level"]
|
||||||
level:ClearAllPoints()
|
level:ClearAllPoints()
|
||||||
@@ -231,7 +231,7 @@ pfUI:RegisterSkin("Friends", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- set positions
|
-- set positions
|
||||||
hooksecurefunc("GuildStatus_Update", function()
|
pfUI.hooksecurefunc("GuildStatus_Update", function()
|
||||||
for i = 1, GUILDMEMBERS_TO_DISPLAY do
|
for i = 1, GUILDMEMBERS_TO_DISPLAY do
|
||||||
local level = _G["GuildFrameButton"..i.."Level"]
|
local level = _G["GuildFrameButton"..i.."Level"]
|
||||||
level:ClearAllPoints()
|
level:ClearAllPoints()
|
||||||
|
|||||||
+1
-1
@@ -86,7 +86,7 @@ pfUI:RegisterModule("gm", function ()
|
|||||||
-- pet dropdown
|
-- pet dropdown
|
||||||
-- table.insert(UnitPopupMenus["PET"], "GM_HEADER")
|
-- table.insert(UnitPopupMenus["PET"], "GM_HEADER")
|
||||||
|
|
||||||
hooksecurefunc("UnitPopup_OnClick", function()
|
pfUI.hooksecurefunc("UnitPopup_OnClick", function()
|
||||||
local dropdownFrame = _G[UIDROPDOWNMENU_INIT_MENU]
|
local dropdownFrame = _G[UIDROPDOWNMENU_INIT_MENU]
|
||||||
local button = this.value
|
local button = this.value
|
||||||
local unit = dropdownFrame.unit
|
local unit = dropdownFrame.unit
|
||||||
|
|||||||
+23
-6
@@ -212,6 +212,7 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
if not this:GetParent():IsShown() then
|
if not this:GetParent():IsShown() then
|
||||||
category[config] = r .. "," .. g .. "," .. b .. "," .. a
|
category[config] = r .. "," .. g .. "," .. b .. "," .. a
|
||||||
if ufunc then ufunc() else pfUI.gui.settingChanged = true end
|
if ufunc then ufunc() else pfUI.gui.settingChanged = true end
|
||||||
|
pfUI.events:TriggerEvent("config:changed", category, config)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -278,6 +279,7 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
if this:GetText() ~= this:GetParent().category[this:GetParent().config] then
|
if this:GetText() ~= this:GetParent().category[this:GetParent().config] then
|
||||||
this:GetParent().category[this:GetParent().config] = this:GetText()
|
this:GetParent().category[this:GetParent().config] = this:GetText()
|
||||||
if ufunc then ufunc() else pfUI.gui.settingChanged = true end
|
if ufunc then ufunc() else pfUI.gui.settingChanged = true end
|
||||||
|
pfUI.events:TriggerEvent("config:changed", category, config)
|
||||||
end
|
end
|
||||||
this:SetTextColor(.2,1,.8,1)
|
this:SetTextColor(.2,1,.8,1)
|
||||||
else
|
else
|
||||||
@@ -328,6 +330,7 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
if ufunc then ufunc() else pfUI.gui.settingChanged = true end
|
if ufunc then ufunc() else pfUI.gui.settingChanged = true end
|
||||||
|
pfUI.events:TriggerEvent("config:changed", category, config)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if category[config] == "1" then frame.input:SetChecked() end
|
if category[config] == "1" then frame.input:SetChecked() end
|
||||||
@@ -360,6 +363,7 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
if category and category[config] ~= value then
|
if category and category[config] ~= value then
|
||||||
category[config] = value
|
category[config] = value
|
||||||
if ufunc then ufunc() else pfUI.gui.settingChanged = true end
|
if ufunc then ufunc() else pfUI.gui.settingChanged = true end
|
||||||
|
pfUI.events:TriggerEvent("config:changed", category, config)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -394,6 +398,7 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
end
|
end
|
||||||
category[config] = newconf
|
category[config] = newconf
|
||||||
if ufunc then ufunc() else pfUI.gui.settingChanged = true end
|
if ufunc then ufunc() else pfUI.gui.settingChanged = true end
|
||||||
|
pfUI.events:TriggerEvent("config:changed", category, config)
|
||||||
frame.input:UpdateMenu()
|
frame.input:UpdateMenu()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -409,6 +414,7 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
CreateQuestionDialog(T["New entry:"], function()
|
CreateQuestionDialog(T["New entry:"], function()
|
||||||
category[config] = category[config] .. "#" .. this:GetParent().input:GetText()
|
category[config] = category[config] .. "#" .. this:GetParent().input:GetText()
|
||||||
if ufunc then ufunc() else pfUI.gui.settingChanged = true end
|
if ufunc then ufunc() else pfUI.gui.settingChanged = true end
|
||||||
|
pfUI.events:TriggerEvent("config:changed", category, config)
|
||||||
frame.input:UpdateMenu()
|
frame.input:UpdateMenu()
|
||||||
end, false, true)
|
end, false, true)
|
||||||
end)
|
end)
|
||||||
@@ -2380,11 +2386,7 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
|
|
||||||
if c == "player" then
|
if c == "player" then
|
||||||
CreateConfig(nil, T["Player SP/Haste Display"], nil, nil, "header")
|
CreateConfig(nil, T["Player SP/Haste Display"], nil, nil, "header")
|
||||||
CreateConfig(nil, T["Haste Display"], C.unitframes[c], "display_haste", "dropdown", {
|
CreateConfig(nil, T["Haste Display"], C.unitframes[c], "display_haste", "checkbox")
|
||||||
"0:"..T["None"],
|
|
||||||
"1:"..T["Haste (cast speed increase)"],
|
|
||||||
"2:"..T["Effective Haste (Haste * cast time reduction)"], -- Only affects mages/warlocks I believe
|
|
||||||
})
|
|
||||||
CreateConfig(nil, T["Haste Display Color"], C.unitframes[c], "display_haste_color", "color")
|
CreateConfig(nil, T["Haste Display Color"], C.unitframes[c], "display_haste_color", "color")
|
||||||
CreateConfig(nil, T["Display Spell Power"], C.unitframes[c], "display_spellpower", "checkbox")
|
CreateConfig(nil, T["Display Spell Power"], C.unitframes[c], "display_spellpower", "checkbox")
|
||||||
CreateConfig(nil, T["Use Custom Spell Power Color (unchecked = biggest school color)"], C.unitframes[c], "display_sp_color_override", "checkbox")
|
CreateConfig(nil, T["Use Custom Spell Power Color (unchecked = biggest school color)"], C.unitframes[c], "display_sp_color_override", "checkbox")
|
||||||
@@ -2749,10 +2751,25 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
CreateConfig(nil, T["Enable Extended Guild Information"], C.tooltip, "extguild", "checkbox")
|
CreateConfig(nil, T["Enable Extended Guild Information"], C.tooltip, "extguild", "checkbox")
|
||||||
CreateConfig(nil, T["Always Show Health In Percent"], C.tooltip, "alwaysperc", "checkbox")
|
CreateConfig(nil, T["Always Show Health In Percent"], C.tooltip, "alwaysperc", "checkbox")
|
||||||
CreateConfig(nil, T["Show Item IDs"], C.tooltip, "itemid", "checkbox")
|
CreateConfig(nil, T["Show Item IDs"], C.tooltip, "itemid", "checkbox")
|
||||||
|
CreateConfig(nil, T["Show Movement Speed"], C.tooltip, "movespeed", "checkbox")
|
||||||
CreateConfig(nil, T["Custom Transparency"], C.tooltip, "alpha")
|
CreateConfig(nil, T["Custom Transparency"], C.tooltip, "alpha")
|
||||||
CreateConfig(nil, T["Status Bar Texture"], C.tooltip.statusbar, "texture", "dropdown", pfUI.gui.dropdowns.uf_bartexture)
|
CreateConfig(nil, T["Status Bar Texture"], C.tooltip.statusbar, "texture", "dropdown", pfUI.gui.dropdowns.uf_bartexture)
|
||||||
CreateConfig(nil, T["Compare Item Base Stats"], C.tooltip.compare, "basestats", "checkbox")
|
CreateConfig(nil, T["Compare Item Base Stats"], C.tooltip.compare, "basestats", "checkbox")
|
||||||
CreateConfig(nil, T["Always Show Item Comparison"], C.tooltip.compare, "showalways", "checkbox")
|
local showAlways = CreateConfig(nil, T["Always Show Item Comparison"], C.tooltip.compare, "showalways", "checkbox")
|
||||||
|
local function gate()
|
||||||
|
local on = C.tooltip.compare.basestats == "1"
|
||||||
|
if on then
|
||||||
|
showAlways.input:Enable()
|
||||||
|
showAlways.caption:SetTextColor(1, 1, 1)
|
||||||
|
else
|
||||||
|
showAlways.input:Disable()
|
||||||
|
showAlways.caption:SetTextColor(0.5, 0.5, 0.5)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
gate()
|
||||||
|
pfUI.events:RegisterCallback("config:changed", function(_, cat, key)
|
||||||
|
if cat == C.tooltip.compare and key == "basestats" then gate() end
|
||||||
|
end, "eqcompare-showalways-gate")
|
||||||
CreateConfig(nil, T["Always Show Extended Vendor Values"], C.tooltip.vendor, "showalways", "checkbox")
|
CreateConfig(nil, T["Always Show Extended Vendor Values"], C.tooltip.vendor, "showalways", "checkbox")
|
||||||
CreateConfig(U["questitem"], T["Show Related Quest On Questitems"], C.tooltip.questitem, "showquest", "checkbox")
|
CreateConfig(U["questitem"], T["Show Related Quest On Questitems"], C.tooltip.questitem, "showquest", "checkbox")
|
||||||
CreateConfig(U["questitem"], T["Show Required Questitem Count"], C.tooltip.questitem, "showcount", "checkbox")
|
CreateConfig(U["questitem"], T["Show Required Questitem Count"], C.tooltip.questitem, "showcount", "checkbox")
|
||||||
|
|||||||
@@ -13,15 +13,6 @@ pfUI:RegisterModule("innervatecall", function ()
|
|||||||
|
|
||||||
local INNERVATE_SPELLID = 29166
|
local INNERVATE_SPELLID = 29166
|
||||||
|
|
||||||
-- Cache player GUID
|
|
||||||
local playerGuid = nil
|
|
||||||
local function GetPlayerGuid()
|
|
||||||
if not playerGuid and UnitGUID then
|
|
||||||
playerGuid = UnitGUID("player")
|
|
||||||
end
|
|
||||||
return playerGuid
|
|
||||||
end
|
|
||||||
|
|
||||||
-- GUID → name resolution for the target. UnitTokenFromGUID walks the
|
-- GUID → name resolution for the target. UnitTokenFromGUID walks the
|
||||||
-- engine's known unit tokens (player, party, raid, target, ...) and
|
-- engine's known unit tokens (player, party, raid, target, ...) and
|
||||||
-- returns the first one currently bound to the GUID, so we don't have
|
-- returns the first one currently bound to the GUID, so we don't have
|
||||||
@@ -39,11 +30,11 @@ pfUI:RegisterModule("innervatecall", function ()
|
|||||||
return "BATTLEGROUND"
|
return "BATTLEGROUND"
|
||||||
end
|
end
|
||||||
|
|
||||||
if GetNumRaidMembers() > 0 then
|
if IsInRaid() then
|
||||||
return "RAID"
|
return "RAID"
|
||||||
end
|
end
|
||||||
|
|
||||||
if GetNumPartyMembers() > 0 then
|
if IsInGroup() then
|
||||||
return "PARTY"
|
return "PARTY"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -75,7 +66,7 @@ pfUI:RegisterModule("innervatecall", function ()
|
|||||||
if spellId ~= INNERVATE_SPELLID then return end
|
if spellId ~= INNERVATE_SPELLID then return end
|
||||||
|
|
||||||
-- Only announce our own casts
|
-- Only announce our own casts
|
||||||
if casterGuid ~= GetPlayerGuid() then return end
|
if not IsPlayerGuid(casterGuid) then return end
|
||||||
|
|
||||||
-- Resolve target name from GUID
|
-- Resolve target name from GUID
|
||||||
local targetName = ResolveTargetName(targetGuid) or "Unknown"
|
local targetName = ResolveTargetName(targetGuid) or "Unknown"
|
||||||
@@ -96,14 +87,10 @@ pfUI:RegisterModule("innervatecall", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local readyAt = GetTime() + cdRemaining
|
C_Timer.After(cdRemaining, function()
|
||||||
frame:SetScript("OnUpdate", function()
|
local ch = GetAnnounceChannel()
|
||||||
if GetTime() >= readyAt then
|
if ch then
|
||||||
frame:SetScript("OnUpdate", nil)
|
SendChatMessage(">> Innervate is ready <<", ch)
|
||||||
local ch = GetAnnounceChannel()
|
|
||||||
if ch then
|
|
||||||
SendChatMessage(">> Innervate is ready <<", ch)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ pfUI:RegisterModule("itemcount", function ()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
hooksecurefunc("SetItemRef", function()
|
pfUI.hooksecurefunc("SetItemRef", function()
|
||||||
if ItemRefTooltip:HasItem() then
|
if ItemRefTooltip:HasItem() then
|
||||||
local _, _, id = ItemRefTooltip:GetItem()
|
local _, _, id = ItemRefTooltip:GetItem()
|
||||||
if id then AddCounts(ItemRefTooltip, id) end
|
if id then AddCounts(ItemRefTooltip, id) end
|
||||||
|
|||||||
+3
-3
@@ -323,7 +323,7 @@ pfUI:RegisterModule("loot", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function pfUI.loot:InitGroupDropDown()
|
function pfUI.loot:InitGroupDropDown()
|
||||||
local inRaid = UnitInRaid("player")
|
local inRaid = IsInRaid()
|
||||||
if UIDROPDOWNMENU_MENU_LEVEL == 1 then
|
if UIDROPDOWNMENU_MENU_LEVEL == 1 then
|
||||||
if ( inRaid ) then
|
if ( inRaid ) then
|
||||||
pfUI.loot:BuildRaidMenu(UIDROPDOWNMENU_MENU_LEVEL)
|
pfUI.loot:BuildRaidMenu(UIDROPDOWNMENU_MENU_LEVEL)
|
||||||
@@ -392,7 +392,7 @@ pfUI:RegisterModule("loot", function ()
|
|||||||
end
|
end
|
||||||
pfUI.loot:RemoveMasterlootMenus() -- remove then add to ensure no duplicate menus
|
pfUI.loot:RemoveMasterlootMenus() -- remove then add to ensure no duplicate menus
|
||||||
pfUI.loot:AddMasterLootMenus()
|
pfUI.loot:AddMasterLootMenus()
|
||||||
hooksecurefunc("UnitPopup_OnClick",function()
|
pfUI.hooksecurefunc("UnitPopup_OnClick",function()
|
||||||
local dropdownFrame = _G[UIDROPDOWNMENU_INIT_MENU]
|
local dropdownFrame = _G[UIDROPDOWNMENU_INIT_MENU]
|
||||||
if not dropdownFrame then return end
|
if not dropdownFrame then return end
|
||||||
local button = this.value
|
local button = this.value
|
||||||
@@ -405,7 +405,7 @@ pfUI:RegisterModule("loot", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
hooksecurefunc("UnitPopup_HideButtons",function()
|
pfUI.hooksecurefunc("UnitPopup_HideButtons",function()
|
||||||
local dropdownFrame = _G[UIDROPDOWNMENU_INIT_MENU]
|
local dropdownFrame = _G[UIDROPDOWNMENU_INIT_MENU]
|
||||||
local unit = dropdownFrame.unit
|
local unit = dropdownFrame.unit
|
||||||
local name = dropdownFrame.name
|
local name = dropdownFrame.name
|
||||||
|
|||||||
@@ -66,9 +66,5 @@ pfUI:RegisterModule("macrotweak", function ()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
-- Check conflicts after one tick so all addons have finished loading
|
-- Check conflicts after one tick so all addons have finished loading
|
||||||
local watcher = CreateFrame("Frame")
|
RunNextFrame(CheckConflicts)
|
||||||
watcher:SetScript("OnUpdate", function()
|
|
||||||
this:SetScript("OnUpdate", nil)
|
|
||||||
CheckConflicts()
|
|
||||||
end)
|
|
||||||
end)
|
end)
|
||||||
@@ -50,7 +50,7 @@ pfUI:RegisterModule("mapcolors", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function UpdateUnitFrames(unit_button_name)
|
local function UpdateUnitFrames(unit_button_name)
|
||||||
if GetNumRaidMembers() > 0 then
|
if IsInRaid() then
|
||||||
for i=1, MAX_RAID_MEMBERS do
|
for i=1, MAX_RAID_MEMBERS do
|
||||||
local frame_name = unit_button_name.."Raid"..i
|
local frame_name = unit_button_name.."Raid"..i
|
||||||
local frame = _G[frame_name]
|
local frame = _G[frame_name]
|
||||||
@@ -68,7 +68,7 @@ pfUI:RegisterModule("mapcolors", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif GetNumPartyMembers() > 0 then
|
elseif IsInGroup() then
|
||||||
for i=1, MAX_PARTY_MEMBERS do
|
for i=1, MAX_PARTY_MEMBERS do
|
||||||
local frame_name = unit_button_name.."Party"..i
|
local frame_name = unit_button_name.."Party"..i
|
||||||
local frame = _G[frame_name]
|
local frame = _G[frame_name]
|
||||||
@@ -125,13 +125,13 @@ pfUI:RegisterModule("mapcolors", function ()
|
|||||||
|
|
||||||
-- WorldMap
|
-- WorldMap
|
||||||
Initialize('WorldMap')
|
Initialize('WorldMap')
|
||||||
hooksecurefunc('WorldMapButton_OnUpdate', function()
|
pfUI.hooksecurefunc('WorldMapButton_OnUpdate', function()
|
||||||
if ( this.tick or .5) > GetTime() then return else this.tick = GetTime() + .5 end
|
if ( this.tick or .5) > GetTime() then return else this.tick = GetTime() + .5 end
|
||||||
UpdateUnitFrames('WorldMap')
|
UpdateUnitFrames('WorldMap')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if C.appearance.worldmap.colornames == "1" then
|
if C.appearance.worldmap.colornames == "1" then
|
||||||
hooksecurefunc('WorldMapUnit_OnEnter', function()
|
pfUI.hooksecurefunc('WorldMapUnit_OnEnter', function()
|
||||||
if ( this.tick or .5) > GetTime() then return else this.tick = GetTime() + .5 end
|
if ( this.tick or .5) > GetTime() then return else this.tick = GetTime() + .5 end
|
||||||
UpdateUnitColors('WorldMap', WorldMapTooltip)
|
UpdateUnitColors('WorldMap', WorldMapTooltip)
|
||||||
end)
|
end)
|
||||||
@@ -141,13 +141,13 @@ pfUI:RegisterModule("mapcolors", function ()
|
|||||||
HookAddonOrVariable("Blizzard_BattlefieldMinimap", function()
|
HookAddonOrVariable("Blizzard_BattlefieldMinimap", function()
|
||||||
Initialize('BattlefieldMinimap')
|
Initialize('BattlefieldMinimap')
|
||||||
|
|
||||||
hooksecurefunc('BattlefieldMinimap_OnUpdate', function()
|
pfUI.hooksecurefunc('BattlefieldMinimap_OnUpdate', function()
|
||||||
if ( this.tick or .5) > GetTime() then return else this.tick = GetTime() + .5 end
|
if ( this.tick or .5) > GetTime() then return else this.tick = GetTime() + .5 end
|
||||||
UpdateUnitFrames('BattlefieldMinimap')
|
UpdateUnitFrames('BattlefieldMinimap')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if C.appearance.worldmap.colornames == "1" then
|
if C.appearance.worldmap.colornames == "1" then
|
||||||
hooksecurefunc('BattlefieldMinimapUnit_OnEnter', function()
|
pfUI.hooksecurefunc('BattlefieldMinimapUnit_OnEnter', function()
|
||||||
if ( this.tick or .5) > GetTime() then return else this.tick = GetTime() + .5 end
|
if ( this.tick or .5) > GetTime() then return else this.tick = GetTime() + .5 end
|
||||||
UpdateUnitColors('BattlefieldMinimap', GameTooltip)
|
UpdateUnitColors('BattlefieldMinimap', GameTooltip)
|
||||||
end)
|
end)
|
||||||
|
|||||||
+1
-1
@@ -58,7 +58,7 @@ pfUI:RegisterModule("minimap", function ()
|
|||||||
|
|
||||||
pfUI.minimap:UpdateConfig()
|
pfUI.minimap:UpdateConfig()
|
||||||
|
|
||||||
hooksecurefunc("ToggleMinimap", function()
|
pfUI.hooksecurefunc("ToggleMinimap", function()
|
||||||
if pfUI.farmmap and pfUI.farmmap:IsShown() then
|
if pfUI.farmmap and pfUI.farmmap:IsShown() then
|
||||||
Minimap:Hide()
|
Minimap:Hide()
|
||||||
return
|
return
|
||||||
|
|||||||
+9
-75
@@ -1,39 +1,6 @@
|
|||||||
pfUI:RegisterModule("mouseover", function ()
|
pfUI:RegisterModule("mouseover", function ()
|
||||||
pfUI.uf.mouseover = CreateFrame("Frame", "pfMouseOver", UIParent)
|
|
||||||
|
|
||||||
-- Prepare a list of units that can be used via SpellTargetUnit
|
|
||||||
local st_units = { [1] = "player", [2] = "target", [3] = "mouseover" }
|
|
||||||
for i=1, MAX_PARTY_MEMBERS do table.insert(st_units, "party"..i) end
|
|
||||||
for i=1, MAX_RAID_MEMBERS do table.insert(st_units, "raid"..i) end
|
|
||||||
|
|
||||||
-- Try to find a valid (friendly) unitstring that can be used for
|
|
||||||
-- SpellTargetUnit(unit) to avoid another target switch
|
|
||||||
local function GetUnitString(unit)
|
|
||||||
for index, unitstr in pairs(st_units) do
|
|
||||||
if UnitIsUnit(unit, unitstr) then
|
|
||||||
return unitstr
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Same as CastSpellByName but with disabled AutoSelfCast
|
|
||||||
local function NoSelfCast(spell, onself)
|
|
||||||
local cvar_selfcast = GetCVar("AutoSelfCast")
|
|
||||||
|
|
||||||
if cvar_selfcast ~= "0" then
|
|
||||||
SetCVar("AutoSelfCast", "0")
|
|
||||||
pcall(CastSpellByName, spell, onself)
|
|
||||||
SetCVar("AutoSelfCast", cvar_selfcast)
|
|
||||||
else
|
|
||||||
CastSpellByName(spell, onself)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
_G.SLASH_PFCAST1, _G.SLASH_PFCAST2 = "/pfcast", "/pfmouse"
|
_G.SLASH_PFCAST1, _G.SLASH_PFCAST2 = "/pfcast", "/pfmouse"
|
||||||
function SlashCmdList.PFCAST(msg)
|
function SlashCmdList.PFCAST(msg)
|
||||||
local restore_target = true
|
|
||||||
local func = pfUI.api.TryMemoizedFuncLoadstringForSpellCasts(msg)
|
local func = pfUI.api.TryMemoizedFuncLoadstringForSpellCasts(msg)
|
||||||
local unit = "mouseover"
|
local unit = "mouseover"
|
||||||
|
|
||||||
@@ -50,51 +17,18 @@ pfUI:RegisterModule("mouseover", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Nampower: CastSpellByName supports a second unit parameter directly.
|
-- Spell-name path: Nampower's CastSpellByName takes a second unit
|
||||||
-- unit is already resolved to "mouseover", "target" or "player" at this point.
|
-- parameter directly, no target swap dance required.
|
||||||
if not func and GetNampowerVersion then
|
if not func then
|
||||||
CastSpellByName(msg, unit)
|
CastSpellByName(msg, unit)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- If target and mouseover are friendly units, we can't use spell target as it
|
-- Macro path: switch target so the macro's spell calls land on `unit`,
|
||||||
-- would cast on the target instead of the mouseover. However, if the mouseover
|
-- then restore.
|
||||||
-- is friendly and the target is not, we can try to obtain the best unitstring
|
local restore_target = not UnitIsUnit("target", unit)
|
||||||
-- for the later SpellTargetUnit() call.
|
if restore_target then TargetUnit(unit) end
|
||||||
local unitstr = not UnitCanAssist("player", "target") and UnitCanAssist("player", unit) and GetUnitString(unit)
|
func()
|
||||||
|
if restore_target then TargetLastTarget() end
|
||||||
if UnitIsUnit("target", unit) or (not func and unitstr) then
|
|
||||||
-- no target change required, we can either use spell target
|
|
||||||
-- or the unit is already our current target.
|
|
||||||
restore_target = false
|
|
||||||
else
|
|
||||||
-- The spelltarget can't be used here, we need to switch
|
|
||||||
-- and restore the target during spell cast
|
|
||||||
TargetUnit(unit)
|
|
||||||
end
|
|
||||||
|
|
||||||
if func then
|
|
||||||
func()
|
|
||||||
else
|
|
||||||
-- write temporary unit name
|
|
||||||
pfUI.uf.mouseover.unit = unit
|
|
||||||
|
|
||||||
-- cast without self cast cvar setting
|
|
||||||
-- to allow spells to use spelltarget
|
|
||||||
NoSelfCast(msg)
|
|
||||||
|
|
||||||
-- set spell target to unitstring (or selfcast)
|
|
||||||
if SpellIsTargeting() then SpellTargetUnit(unitstr or "player") end
|
|
||||||
|
|
||||||
-- clean up spell target in error case
|
|
||||||
if SpellIsTargeting() then SpellStopTargeting() end
|
|
||||||
|
|
||||||
-- remove temporary mouseover unit
|
|
||||||
pfUI.uf.mouseover.unit = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
if restore_target then
|
|
||||||
TargetLastTarget()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
+6
-14
@@ -100,12 +100,6 @@ pfUI:RegisterModule("nameplates", function ()
|
|||||||
-- PERF: visiblePlateCount maintained event-driven (NAME_PLATE_UNIT_ADDED/_REMOVED)
|
-- PERF: visiblePlateCount maintained event-driven (NAME_PLATE_UNIT_ADDED/_REMOVED)
|
||||||
local visiblePlateCount = 0
|
local visiblePlateCount = 0
|
||||||
|
|
||||||
-- wipe polyfill
|
|
||||||
local wipe = wipe or function(t) for k in pairs(t) do t[k] = nil end end
|
|
||||||
|
|
||||||
-- Player GUID for filtering
|
|
||||||
local PlayerGUID = UnitGUID("player")
|
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- OPTIMIZATION: Config caching
|
-- OPTIMIZATION: Config caching
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
@@ -492,7 +486,6 @@ end
|
|||||||
|
|
||||||
elseif event == "PLAYER_ENTERING_WORLD" or event == "ZONE_CHANGED_NEW_AREA" then
|
elseif event == "PLAYER_ENTERING_WORLD" or event == "ZONE_CHANGED_NEW_AREA" then
|
||||||
if event == "PLAYER_ENTERING_WORLD" then
|
if event == "PLAYER_ENTERING_WORLD" then
|
||||||
_, PlayerGUID = UnitExists("player")
|
|
||||||
CacheConfig()
|
CacheConfig()
|
||||||
this:SetGameVariables()
|
this:SetGameVariables()
|
||||||
RebuildRaidGuidCache()
|
RebuildRaidGuidCache()
|
||||||
@@ -937,10 +930,15 @@ end
|
|||||||
-- name — name alone misses pool reuse between same-named units (e.g. plate
|
-- name — name alone misses pool reuse between same-named units (e.g. plate
|
||||||
-- held a player "Ironforge Guard" and is now reassigned to the NPC by the
|
-- held a player "Ironforge Guard" and is now reassigned to the NPC by the
|
||||||
-- same name), which would leak a stale "PLAYER" hint into GetUnitInfo.
|
-- same name), which would leak a stale "PLAYER" hint into GetUnitInfo.
|
||||||
|
-- Wipe the whole cache table: the PERF gates below ("only update X when
|
||||||
|
-- X changed") would otherwise skip bar/color/text updates when the new
|
||||||
|
-- unit happens to share a cached value with the previous occupant
|
||||||
|
-- (e.g., both at 60% HP percentage on plate pool reuse → bar stays at
|
||||||
|
-- the old fill until the new mob actually changes HP).
|
||||||
if plate.cache.name ~= name or plate.cache.guid ~= plate.cachedGuid then
|
if plate.cache.name ~= name or plate.cache.guid ~= plate.cachedGuid then
|
||||||
|
table.wipe(plate.cache)
|
||||||
plate.cache.name = name
|
plate.cache.name = name
|
||||||
plate.cache.guid = plate.cachedGuid
|
plate.cache.guid = plate.cachedGuid
|
||||||
plate.cache.player = nil
|
|
||||||
plate.cdCache = nil -- new unit, reset spell-keyed timer cache
|
plate.cdCache = nil -- new unit, reset spell-keyed timer cache
|
||||||
plate.name:SetText(GetNameString(name))
|
plate.name:SetText(GetNameString(name))
|
||||||
end
|
end
|
||||||
@@ -987,12 +985,6 @@ end
|
|||||||
-- remove unitstr on unit name mismatch
|
-- remove unitstr on unit name mismatch
|
||||||
if unitstr and UnitName(unitstr) ~= name then unitstr = nil end
|
if unitstr and UnitName(unitstr) ~= name then unitstr = nil end
|
||||||
|
|
||||||
-- use mobhealth values if addon is running
|
|
||||||
if (MobHealth3 or MobHealthFrame) and target and name == UnitName('target') and MobHealth_GetTargetCurHP() then
|
|
||||||
hp = MobHealth_GetTargetCurHP() > 0 and MobHealth_GetTargetCurHP() or hp
|
|
||||||
hpmax = MobHealth_GetTargetMaxHP() > 0 and MobHealth_GetTargetMaxHP() or hpmax
|
|
||||||
end
|
|
||||||
|
|
||||||
-- always make sure to keep plate visible
|
-- always make sure to keep plate visible
|
||||||
plate:Show()
|
plate:Show()
|
||||||
|
|
||||||
|
|||||||
+3
-4
@@ -424,7 +424,8 @@ pfUI:RegisterModule("panel", function()
|
|||||||
widget:RegisterEvent("PLAYER_REGEN_ENABLED")
|
widget:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||||
widget:RegisterEvent("PLAYER_DEAD")
|
widget:RegisterEvent("PLAYER_DEAD")
|
||||||
widget:RegisterEvent("PLAYER_UNGHOST")
|
widget:RegisterEvent("PLAYER_UNGHOST")
|
||||||
widget:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
widget:RegisterEvent("PLAYER_EQUIPMENT_CHANGED") -- ClassicAPI: equip/unequip changes total durability
|
||||||
|
widget:RegisterEvent("UPDATE_INVENTORY_DURABILITY") -- ClassicAPI: combat wear / repair
|
||||||
|
|
||||||
widget.Click = function() ToggleCharacter("PaperDollFrame") end
|
widget.Click = function() ToggleCharacter("PaperDollFrame") end
|
||||||
widget.Tooltip = function()
|
widget.Tooltip = function()
|
||||||
@@ -456,8 +457,6 @@ pfUI:RegisterModule("panel", function()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
widget:SetScript("OnEvent", function()
|
widget:SetScript("OnEvent", function()
|
||||||
if event == "UNIT_INVENTORY_CHANGED" and arg1 ~= "player" then return end
|
|
||||||
|
|
||||||
local totalCurr, totalMax = 0, 0
|
local totalCurr, totalMax = 0, 0
|
||||||
for id = INVSLOT_FIRST_EQUIPPED, INVSLOT_LAST_EQUIPPED do
|
for id = INVSLOT_FIRST_EQUIPPED, INVSLOT_LAST_EQUIPPED do
|
||||||
local cur, max = GetInventoryItemDurability(id)
|
local cur, max = GetInventoryItemDurability(id)
|
||||||
@@ -533,7 +532,7 @@ pfUI:RegisterModule("panel", function()
|
|||||||
-- Hearthstone bind location
|
-- Hearthstone bind location
|
||||||
local hearth = CreateFrame("Frame", "pfPanelBindLocation", UIParent)
|
local hearth = CreateFrame("Frame", "pfPanelBindLocation", UIParent)
|
||||||
hearth:RegisterEvent("PLAYER_ENTERING_WORLD")
|
hearth:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
hearth:RegisterEvent("CHAT_MSG_SYSTEM")
|
hearth:RegisterEvent("HEARTHSTONE_BOUND")
|
||||||
hearth:SetScript("OnEvent", function()
|
hearth:SetScript("OnEvent", function()
|
||||||
pfUI.panel:OutputPanel("bindlocation", T["Hearthstone"] .. ": " .. (GetBindLocation() or T["Not Set"]))
|
pfUI.panel:OutputPanel("bindlocation", T["Hearthstone"] .. ": " .. (GetBindLocation() or T["Not Set"]))
|
||||||
end)
|
end)
|
||||||
|
|||||||
+17
-50
@@ -38,38 +38,6 @@ pfUI:RegisterModule("player", function ()
|
|||||||
playerFrame.myclass = myclass
|
playerFrame.myclass = myclass
|
||||||
playerFrame.isSpellCaster = myclass ~= "WARRIOR" and myclass ~= "ROGUE" and myclass ~= "HUNTER"
|
playerFrame.isSpellCaster = myclass ~= "WARRIOR" and myclass ~= "ROGUE" and myclass ~= "HUNTER"
|
||||||
|
|
||||||
-- Compute class-based casting speed modifier and cache on the frame.
|
|
||||||
-- This is re-evaluated on LEARNED_SPELL_IN_TAB (with 1s delay) so talent changes are handled.
|
|
||||||
-- Not sure if there are any other effects that give % cast reduction time
|
|
||||||
local function UpdatePlayerModCastingTime()
|
|
||||||
playerFrame.modCastingTime = 1
|
|
||||||
if myclass == "MAGE" then
|
|
||||||
local _, _, _, _, acceleratedArcana = GetTalentInfo(1, 16)
|
|
||||||
if acceleratedArcana and acceleratedArcana > 0 then
|
|
||||||
playerFrame.modCastingTime = 0.95
|
|
||||||
end
|
|
||||||
elseif myclass == "WARLOCK" then
|
|
||||||
local _, _, _, _, rapidDeter = GetTalentInfo(1, 14)
|
|
||||||
if rapidDeter and rapidDeter > 0 then
|
|
||||||
playerFrame.modCastingTime = 1 - (rapidDeter * 0.03)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local talentFrame = CreateFrame("Frame")
|
|
||||||
talentFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
|
||||||
talentFrame:RegisterEvent("LEARNED_SPELL_IN_TAB")
|
|
||||||
talentFrame:SetScript("OnEvent", function()
|
|
||||||
-- Delay 1s for both PLAYER_ENTERING_WORLD and LEARNED_SPELL_IN_TAB
|
|
||||||
local checkAt = GetTime() + 1
|
|
||||||
talentFrame:SetScript("OnUpdate", function()
|
|
||||||
if GetTime() >= checkAt then
|
|
||||||
talentFrame:SetScript("OnUpdate", nil)
|
|
||||||
UpdatePlayerModCastingTime()
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Convert "r,g,b,a" config color string to a 6-char hex string, or nil if unset
|
-- Convert "r,g,b,a" config color string to a 6-char hex string, or nil if unset
|
||||||
local function cfgColorToHex(colorStr)
|
local function cfgColorToHex(colorStr)
|
||||||
if not colorStr or colorStr == "" then return nil end
|
if not colorStr or colorStr == "" then return nil end
|
||||||
@@ -98,26 +66,25 @@ pfUI:RegisterModule("player", function ()
|
|||||||
if not cfg then
|
if not cfg then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local hasteMode = cfg.display_haste -- "0"=none, "1"=modCastSpeed, "2"=modCastSpeed*modCastingTime
|
-- display_haste: "0"=hidden, "1"=show modCastSpeed (gear haste). Talent-
|
||||||
|
-- side cast-time reductions show up in the actual cast bar via
|
||||||
|
-- C_Spell.UnitCastingInfo; double-folding them into this overlay was
|
||||||
|
-- mixing two different concepts into one number.
|
||||||
|
local showHaste = cfg.display_haste == "1"
|
||||||
local showSP = cfg.display_spellpower == "1"
|
local showSP = cfg.display_spellpower == "1"
|
||||||
|
|
||||||
local isSpellCaster = playerFrame.isSpellCaster
|
local isSpellCaster = playerFrame.isSpellCaster
|
||||||
if (hasteMode == "0" or not isSpellCaster) and not showSP then
|
if (not showHaste or not isSpellCaster) and not showSP then
|
||||||
playerFrame.infoTopCenterText:SetText("")
|
playerFrame.infoTopCenterText:SetText("")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local haste = GetUnitField("player", "modCastSpeed")
|
local haste = GetUnitField("player", "modCastSpeed")
|
||||||
local modCastingTime = playerFrame.modCastingTime or 1
|
|
||||||
local text = ""
|
local text = ""
|
||||||
|
|
||||||
if isSpellCaster and haste then
|
if showHaste and isSpellCaster and haste then
|
||||||
local hasteHex = cfgColorToHex(cfg.display_haste_color) or "FFFFFF"
|
local hasteHex = cfgColorToHex(cfg.display_haste_color) or "FFFFFF"
|
||||||
if hasteMode == "1" then
|
text = string.format("|cff%s%.1f%%|r", hasteHex, (1 / haste - 1) * 100)
|
||||||
text = string.format("|cff%s%.1f%%|r", hasteHex, (1 / haste - 1) * 100)
|
|
||||||
elseif hasteMode == "2" then
|
|
||||||
text = string.format("|cff%s%.1f%%|r", hasteHex, (1 / (haste * modCastingTime) - 1) * 100)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if showSP and isSpellCaster then
|
if showSP and isSpellCaster then
|
||||||
@@ -151,21 +118,21 @@ pfUI:RegisterModule("player", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Add throttle to player frame OnUpdate
|
-- Add throttle to player frame OnUpdate
|
||||||
|
-- Throttle the unit frame's existing OnUpdate to ~20 FPS so the per-frame
|
||||||
|
-- work stays cheap.
|
||||||
if pfUI.uf.player:GetScript("OnUpdate") then
|
if pfUI.uf.player:GetScript("OnUpdate") then
|
||||||
local originalOnUpdate = pfUI.uf.player:GetScript("OnUpdate")
|
local originalOnUpdate = pfUI.uf.player:GetScript("OnUpdate")
|
||||||
pfUI.uf.player:SetScript("OnUpdate", function()
|
pfUI.uf.player:SetScript("OnUpdate", function()
|
||||||
if (this.throttleTick or 0) > GetTime() then
|
if (this.throttleTick or 0) > GetTime() then return end
|
||||||
return
|
this.throttleTick = GetTime() + 0.05
|
||||||
end
|
|
||||||
this.throttleTick = GetTime() + 0.05 -- Default: 20 FPS
|
|
||||||
originalOnUpdate()
|
originalOnUpdate()
|
||||||
if (this.infoTextTick or 0) <= GetTime() then
|
|
||||||
this.infoTextTick = GetTime() + 0.25 -- Don't need to update haste/SP text as often
|
|
||||||
UpdateInfoText()
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Haste / spell-power overlay text — refreshes 4×/sec on its own ticker,
|
||||||
|
-- independent of the unit frame's OnUpdate cadence.
|
||||||
|
C_Timer.NewTicker(0.25, UpdateInfoText)
|
||||||
|
|
||||||
-- Replace default's RESET_INSTANCES button with an always working one
|
-- Replace default's RESET_INSTANCES button with an always working one
|
||||||
UnitPopupButtons["RESET_INSTANCES_FIX"] = { text = RESET_INSTANCES, dist = 0 }
|
UnitPopupButtons["RESET_INSTANCES_FIX"] = { text = RESET_INSTANCES, dist = 0 }
|
||||||
for id, text in pairs(UnitPopupMenus["SELF"]) do
|
for id, text in pairs(UnitPopupMenus["SELF"]) do
|
||||||
@@ -174,7 +141,7 @@ pfUI:RegisterModule("player", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
hooksecurefunc("UnitPopup_OnClick", function()
|
pfUI.hooksecurefunc("UnitPopup_OnClick", function()
|
||||||
local button = this.value
|
local button = this.value
|
||||||
if button == "RESET_INSTANCES_FIX" then
|
if button == "RESET_INSTANCES_FIX" then
|
||||||
StaticPopup_Show("CONFIRM_RESET_INSTANCES")
|
StaticPopup_Show("CONFIRM_RESET_INSTANCES")
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ pfUI:RegisterModule("questitem", function ()
|
|||||||
-- itemref tooltip (chat link clicks): hooksecurefunc runs after SetItemRef
|
-- itemref tooltip (chat link clicks): hooksecurefunc runs after SetItemRef
|
||||||
-- populates ItemRefTooltip, so we just read the item back out of the tooltip
|
-- populates ItemRefTooltip, so we just read the item back out of the tooltip
|
||||||
-- instead of re-parsing the "item:NNN" out of the link string.
|
-- instead of re-parsing the "item:NNN" out of the link string.
|
||||||
hooksecurefunc("SetItemRef", function()
|
pfUI.hooksecurefunc("SetItemRef", function()
|
||||||
if IsModifierKeyDown() then return end
|
if IsModifierKeyDown() then return end
|
||||||
if ItemRefTooltip:HasItem() then
|
if ItemRefTooltip:HasItem() then
|
||||||
local _, _, id = ItemRefTooltip:GetItem()
|
local _, _, id = ItemRefTooltip:GetItem()
|
||||||
|
|||||||
+2
-2
@@ -106,7 +106,7 @@ pfUI:RegisterModule("raid", function ()
|
|||||||
this.pendingUpdate = nil
|
this.pendingUpdate = nil
|
||||||
|
|
||||||
-- don't proceed without raid
|
-- don't proceed without raid
|
||||||
if not UnitInRaid("player") then return end
|
if not IsInRaid() then return end
|
||||||
|
|
||||||
-- clear all existing frames
|
-- clear all existing frames
|
||||||
for i=1, maxraid do SetRaidIndex(pfUI.uf.raid[i], 0) end
|
for i=1, maxraid do SetRaidIndex(pfUI.uf.raid[i], 0) end
|
||||||
@@ -164,7 +164,7 @@ pfUI:RegisterModule("raid", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
hooksecurefunc("UnitPopup_OnClick", function()
|
pfUI.hooksecurefunc("UnitPopup_OnClick", function()
|
||||||
local dropdownFrame = UIDROPDOWNMENU_INIT_MENU and _G[UIDROPDOWNMENU_INIT_MENU]
|
local dropdownFrame = UIDROPDOWNMENU_INIT_MENU and _G[UIDROPDOWNMENU_INIT_MENU]
|
||||||
if not dropdownFrame then return end
|
if not dropdownFrame then return end
|
||||||
local button = this.value
|
local button = this.value
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ pfUI:RegisterModule("sellvalue", function ()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
hooksecurefunc("SetItemRef", function()
|
pfUI.hooksecurefunc("SetItemRef", function()
|
||||||
if IsModifierKeyDown() then return end
|
if IsModifierKeyDown() then return end
|
||||||
if ItemRefTooltip:HasItem() then
|
if ItemRefTooltip:HasItem() then
|
||||||
local _, _, id = ItemRefTooltip:GetItem()
|
local _, _, id = ItemRefTooltip:GetItem()
|
||||||
|
|||||||
+131
-194
@@ -1,93 +1,78 @@
|
|||||||
pfUI:RegisterModule("share", function ()
|
pfUI:RegisterModule("share", function ()
|
||||||
local function serialize(tbl, comp, name, ignored, spacing)
|
-- Profile sharing rides ClassicAPI's C_EncodingUtil:
|
||||||
local spacing = spacing or ""
|
-- export: diff vs defaults -> SerializeCBOR -> CompressString (zlib)
|
||||||
local match = nil
|
-- -> EncodeBase64, prefixed with the format magic
|
||||||
local tname = ( spacing == "" and "" or "[\"" ) .. name .. ( spacing == "" and "" or "\"]" )
|
-- import: the reverse, into a plain table — no loadstring, so a
|
||||||
local str = spacing .. tname .. " = {\n"
|
-- pasted profile can't execute code
|
||||||
|
-- The Decode/Encode button converts between the transport blob and an
|
||||||
|
-- editable JSON view of the same table.
|
||||||
|
local MAGIC = "!pf1!"
|
||||||
|
|
||||||
|
-- Deep-diff `tbl` against `default`, keeping only changed or added
|
||||||
|
-- values. `ignored` keys are skipped at the top level only (matches the
|
||||||
|
-- old serializer: "position"/"disabled" when Ignore Layout is checked).
|
||||||
|
-- Returns nil when nothing differs.
|
||||||
|
local function DiffConfig(tbl, default, ignored)
|
||||||
|
local diff = nil
|
||||||
for k, v in pairs(tbl) do
|
for k, v in pairs(tbl) do
|
||||||
if not ( ignored[k] and spacing == "" ) and ( not comp or not comp[k] or comp[k] ~= tbl[k] ) then
|
if not ( ignored and ignored[k] ) then
|
||||||
|
local dv = default and default[k]
|
||||||
if type(v) == "table" then
|
if type(v) == "table" then
|
||||||
local result = serialize(tbl[k], comp and comp[k], k, ignored, spacing .. " ")
|
local sub = DiffConfig(v, type(dv) == "table" and dv or nil)
|
||||||
if result then
|
if sub then
|
||||||
match = true
|
diff = diff or {}
|
||||||
str = str .. result
|
diff[k] = sub
|
||||||
end
|
end
|
||||||
elseif type(v) == "string" then
|
elseif v ~= dv and ( type(v) == "string" or type(v) == "number" or type(v) == "boolean" ) then
|
||||||
match = true
|
diff = diff or {}
|
||||||
local escaped = string.gsub(v, "\\", "\\\\")
|
diff[k] = v
|
||||||
escaped = string.gsub(escaped, "\"", "\\\"")
|
|
||||||
str = str .. spacing .. " [\""..k.."\"] = \"".. escaped .."\",\n"
|
|
||||||
elseif type(v) == "number" then
|
|
||||||
match = true
|
|
||||||
str = str .. spacing .. " [\""..k.."\"] = ".. string.gsub(v, "\\", "\\\\") ..",\n"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return diff
|
||||||
str = str .. spacing .. "}" .. ( spacing == "" and "" or "," ) .. "\n"
|
|
||||||
return match and str or nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function compress(input)
|
-- EditBoxes don't soft-wrap one giant unbroken line; chunk the blob.
|
||||||
-- based on Rochet2's lzw compression
|
local function wrap(str, width)
|
||||||
if type(input) ~= "string" then
|
local out = {}
|
||||||
return nil
|
for i = 1, strlen(str), width do
|
||||||
|
table.insert(out, strsub(str, i, i + width - 1))
|
||||||
end
|
end
|
||||||
local len = strlen(input)
|
return table.concat(out, "\n")
|
||||||
if len <= 1 then
|
|
||||||
return "u"..input
|
|
||||||
end
|
|
||||||
|
|
||||||
local dict = {}
|
|
||||||
for i = 0, 255 do
|
|
||||||
local ic, iic = strchar(i), strchar(i, 0)
|
|
||||||
dict[ic] = iic
|
|
||||||
end
|
|
||||||
local a, b = 0, 1
|
|
||||||
|
|
||||||
local result = {"c"}
|
|
||||||
local resultlen = 1
|
|
||||||
local n = 2
|
|
||||||
local word = ""
|
|
||||||
for i = 1, len do
|
|
||||||
local c = strsub(input, i, i)
|
|
||||||
local wc = word..c
|
|
||||||
if not dict[wc] then
|
|
||||||
local write = dict[word]
|
|
||||||
if not write then
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
result[n] = write
|
|
||||||
resultlen = resultlen + strlen(write)
|
|
||||||
n = n+1
|
|
||||||
if len <= resultlen then
|
|
||||||
return "u"..input
|
|
||||||
end
|
|
||||||
local str = wc
|
|
||||||
if a >= 256 then
|
|
||||||
a, b = 0, b+1
|
|
||||||
if b >= 256 then
|
|
||||||
dict = {}
|
|
||||||
b = 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
dict[str] = strchar(a,b)
|
|
||||||
a = a+1
|
|
||||||
word = c
|
|
||||||
else
|
|
||||||
word = wc
|
|
||||||
end
|
|
||||||
end
|
|
||||||
result[n] = dict[word]
|
|
||||||
resultlen = resultlen+strlen(result[n])
|
|
||||||
n = n+1
|
|
||||||
if len <= resultlen then
|
|
||||||
return "u"..input
|
|
||||||
end
|
|
||||||
return table.concat(result)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function Encode(tbl)
|
||||||
|
return MAGIC .. wrap(C_EncodingUtil.EncodeBase64(
|
||||||
|
C_EncodingUtil.CompressString(
|
||||||
|
C_EncodingUtil.SerializeCBOR(tbl))), 92)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Decode(text)
|
||||||
|
if not text then return nil end
|
||||||
|
text = gsub(text, "%s", "")
|
||||||
|
if strsub(text, 1, strlen(MAGIC)) ~= MAGIC then return nil end
|
||||||
|
local ok, result = pcall(function()
|
||||||
|
return C_EncodingUtil.DeserializeCBOR(
|
||||||
|
C_EncodingUtil.DecompressString(
|
||||||
|
C_EncodingUtil.DecodeBase64(strsub(text, strlen(MAGIC) + 1))))
|
||||||
|
end)
|
||||||
|
if ok and type(result) == "table" then return result end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function DecodeJSON(text)
|
||||||
|
if not text or gsub(text, "%s", "") == "" then return nil end
|
||||||
|
local ok, result = pcall(function()
|
||||||
|
return C_EncodingUtil.DeserializeJSON(text)
|
||||||
|
end)
|
||||||
|
if ok and type(result) == "table" then return result end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Legacy import (pre-!pf1! exports): base64 -> LZW -> Lua source
|
||||||
|
-- "pfUI_config = {...}". The base64 layer is standard and handled by
|
||||||
|
-- C_EncodingUtil.DecodeBase64; only the custom LZW format needs the old
|
||||||
|
-- Lua decoder. Import-only — new exports always use the CBOR pipeline.
|
||||||
local function decompress(input)
|
local function decompress(input)
|
||||||
-- based on Rochet2's lzw compression
|
-- based on Rochet2's lzw compression
|
||||||
if type(input) ~= "string" or strlen(input) < 1 then
|
if type(input) ~= "string" or strlen(input) < 1 then
|
||||||
@@ -159,92 +144,32 @@ pfUI:RegisterModule("share", function ()
|
|||||||
return table.concat(result)
|
return table.concat(result)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function enc(to_encode)
|
local function DecodeLegacy(text)
|
||||||
local index_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
if not text or gsub(text, "%s", "") == "" then return nil end
|
||||||
local bit_pattern = ''
|
|
||||||
local encoded = ''
|
|
||||||
local trailing = ''
|
|
||||||
|
|
||||||
for i = 1, string.len(to_encode) do
|
-- encoded blob? peel base64 + LZW down to Lua source. Raw (already
|
||||||
local remaining = tonumber(string.byte(string.sub(to_encode, i, i)))
|
-- decoded) source pastes are accepted as-is.
|
||||||
local bin_bits = ''
|
local source = text
|
||||||
for i = 7, 0, -1 do
|
local stripped = gsub(text, "%s", "")
|
||||||
local current_power = math.pow(2, i)
|
local ok, decoded = pcall(function()
|
||||||
if remaining >= current_power then
|
return C_EncodingUtil.DecodeBase64(stripped)
|
||||||
bin_bits = bin_bits .. '1'
|
end)
|
||||||
remaining = remaining - current_power
|
if ok and decoded then
|
||||||
else
|
local decompressed = decompress(decoded)
|
||||||
bin_bits = bin_bits .. '0'
|
if decompressed then source = decompressed end
|
||||||
end
|
|
||||||
end
|
|
||||||
bit_pattern = bit_pattern .. bin_bits
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if mod(string.len(bit_pattern), 3) == 2 then
|
local chunk = loadstring(source)
|
||||||
trailing = '=='
|
if not chunk then return nil end
|
||||||
bit_pattern = bit_pattern .. '0000000000000000'
|
|
||||||
elseif mod(string.len(bit_pattern), 3) == 1 then
|
|
||||||
trailing = '='
|
|
||||||
bit_pattern = bit_pattern .. '00000000'
|
|
||||||
end
|
|
||||||
|
|
||||||
local count = 0
|
-- Sandbox the chunk: an empty environment means it can assign its
|
||||||
for i = 1, string.len(bit_pattern), 6 do
|
-- config table but can't reach any global or API function — a legacy
|
||||||
local byte = string.sub(bit_pattern, i, i+5)
|
-- profile string is data, never code.
|
||||||
local offset = tonumber(tonumber(byte, 2))
|
local sandbox = {}
|
||||||
encoded = encoded .. string.sub(index_table, offset+1, offset+1)
|
setfenv(chunk, sandbox)
|
||||||
count = count + 1
|
if not pcall(chunk) then return nil end
|
||||||
if count >= 92 then
|
if type(sandbox.pfUI_config) == "table" then return sandbox.pfUI_config end
|
||||||
encoded = encoded .. "\n"
|
return nil
|
||||||
count = 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return string.sub(encoded, 1, -1 - string.len(trailing)) .. trailing
|
|
||||||
end
|
|
||||||
|
|
||||||
local function dec(to_decode)
|
|
||||||
local index_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
|
||||||
local padded = gsub(to_decode,"%s", "")
|
|
||||||
local unpadded = gsub(padded,"=", "")
|
|
||||||
local bit_pattern = ''
|
|
||||||
local decoded = ''
|
|
||||||
|
|
||||||
to_decode = gsub(to_decode,"\n", "")
|
|
||||||
to_decode = gsub(to_decode," ", "")
|
|
||||||
|
|
||||||
for i = 1, string.len(unpadded) do
|
|
||||||
local char = string.sub(to_decode, i, i)
|
|
||||||
local offset, _ = string.find(index_table, char)
|
|
||||||
if offset == nil then return nil end
|
|
||||||
|
|
||||||
local remaining = tonumber(offset-1)
|
|
||||||
local bin_bits = ''
|
|
||||||
for i = 7, 0, -1 do
|
|
||||||
local current_power = math.pow(2, i)
|
|
||||||
if remaining >= current_power then
|
|
||||||
bin_bits = bin_bits .. '1'
|
|
||||||
remaining = remaining - current_power
|
|
||||||
else
|
|
||||||
bin_bits = bin_bits .. '0'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
bit_pattern = bit_pattern .. string.sub(bin_bits, 3)
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, string.len(bit_pattern), 8 do
|
|
||||||
local byte = string.sub(bit_pattern, i, i+7)
|
|
||||||
decoded = decoded .. strchar(tonumber(byte, 2))
|
|
||||||
end
|
|
||||||
|
|
||||||
local padding_length = string.len(padded)-string.len(unpadded)
|
|
||||||
|
|
||||||
if (padding_length == 1 or padding_length == 2) then
|
|
||||||
decoded = string.sub(decoded,1,-2)
|
|
||||||
end
|
|
||||||
|
|
||||||
return decoded
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do -- Window
|
do -- Window
|
||||||
@@ -309,33 +234,43 @@ pfUI:RegisterModule("share", function ()
|
|||||||
this:GetParent():UpdateScrollChildRect()
|
this:GetParent():UpdateScrollChildRect()
|
||||||
this:GetParent():UpdateScrollState()
|
this:GetParent():UpdateScrollState()
|
||||||
|
|
||||||
local _, error = loadstring(f.scroll.text:GetText())
|
local text = this:GetText()
|
||||||
if error or string.gsub(this:GetText(), " ", "") == "" then
|
local blob = Decode(text)
|
||||||
f.loadButton:Disable()
|
local json = not blob and DecodeJSON(text) or nil
|
||||||
f.loadButton.text:SetTextColor(1,.5,.5,1)
|
local legacy = not blob and not json and DecodeLegacy(text) or nil
|
||||||
else
|
|
||||||
|
if blob or json or legacy then
|
||||||
f.loadButton:Enable()
|
f.loadButton:Enable()
|
||||||
f.loadButton.text:SetTextColor(.5,1,.5,1)
|
f.loadButton.text:SetTextColor(.5,1,.5,1)
|
||||||
|
else
|
||||||
|
f.loadButton:Disable()
|
||||||
|
f.loadButton.text:SetTextColor(1,.5,.5,1)
|
||||||
end
|
end
|
||||||
|
|
||||||
local trydec = dec(this:GetText())
|
if blob or legacy then
|
||||||
if string.gsub(this:GetText(), " ", "") == "" then
|
-- decoding a legacy string yields the JSON view; re-encoding it
|
||||||
f.readButton.text:SetText(T["N/A"])
|
-- from there produces a new-format blob (migration path)
|
||||||
f.readButton:Disable()
|
|
||||||
elseif not trydec or trydec == "" then
|
|
||||||
f.readButton:Enable()
|
|
||||||
f.readButton.text:SetText(T["Encode"])
|
|
||||||
f.readButton.func = function()
|
|
||||||
local compressed = enc(compress(f.scroll.text:GetText()))
|
|
||||||
f.scroll.text:SetText(compressed)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
f.readButton:Enable()
|
f.readButton:Enable()
|
||||||
f.readButton.text:SetText(T["Decode"])
|
f.readButton.text:SetText(T["Decode"])
|
||||||
f.readButton.func = function()
|
f.readButton.func = function()
|
||||||
local uncompressed = decompress(dec(f.scroll.text:GetText()))
|
local current = f.scroll.text:GetText()
|
||||||
f.scroll.text:SetText(uncompressed)
|
local config = Decode(current) or DecodeLegacy(current)
|
||||||
|
if config then
|
||||||
|
f.scroll.text:SetText(C_EncodingUtil.SerializeJSON(config))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
elseif json then
|
||||||
|
f.readButton:Enable()
|
||||||
|
f.readButton.text:SetText(T["Encode"])
|
||||||
|
f.readButton.func = function()
|
||||||
|
local config = DecodeJSON(f.scroll.text:GetText())
|
||||||
|
if config then
|
||||||
|
f.scroll.text:SetText(Encode(config))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
f.readButton:Disable()
|
||||||
|
f.readButton.text:SetText(T["N/A"])
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
f.scroll:SetScrollChild(f.scroll.text)
|
f.scroll:SetScrollChild(f.scroll.text)
|
||||||
@@ -387,21 +322,23 @@ pfUI:RegisterModule("share", function ()
|
|||||||
f.loadButton.text:SetFont(pfUI.font_default, pfUI_config.global.font_size, "OUTLINE")
|
f.loadButton.text:SetFont(pfUI.font_default, pfUI_config.global.font_size, "OUTLINE")
|
||||||
f.loadButton.text:SetText(T["Import"])
|
f.loadButton.text:SetText(T["Import"])
|
||||||
f.loadButton:SetScript("OnClick", function()
|
f.loadButton:SetScript("OnClick", function()
|
||||||
local ImportConfig, error = loadstring(f.scroll.text:GetText())
|
local text = f.scroll.text:GetText()
|
||||||
if not error and f.scroll.text:GetText() ~= "" then
|
local config = Decode(text) or DecodeJSON(text) or DecodeLegacy(text)
|
||||||
ImportConfig()
|
if not config then return end
|
||||||
pfUI:LoadConfig()
|
|
||||||
|
|
||||||
-- Skip firstrun wizard when importing a shared profile
|
_G.pfUI_config = config
|
||||||
-- The imported config is a complete setup, no wizard needed
|
C = _G.pfUI_config
|
||||||
if pfUI.firstrun and pfUI.firstrun.steps then
|
pfUI:LoadConfig()
|
||||||
for _, step in pairs(pfUI.firstrun.steps) do
|
|
||||||
pfUI_init[step.name] = true
|
-- Skip firstrun wizard when importing a shared profile
|
||||||
end
|
-- The imported config is a complete setup, no wizard needed
|
||||||
|
if pfUI.firstrun and pfUI.firstrun.steps then
|
||||||
|
for _, step in pairs(pfUI.firstrun.steps) do
|
||||||
|
pfUI_init[step.name] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
CreateQuestionDialog(T["Some settings need to reload the UI to take effect.\nDo you want to reloadUI now?"], ReloadUI)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
CreateQuestionDialog(T["Some settings need to reload the UI to take effect.\nDo you want to reloadUI now?"], ReloadUI)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -445,9 +382,9 @@ pfUI:RegisterModule("share", function ()
|
|||||||
ignored["position"] = f.ignorePosition:GetChecked()
|
ignored["position"] = f.ignorePosition:GetChecked()
|
||||||
ignored["disabled"] = f.ignorePosition:GetChecked()
|
ignored["disabled"] = f.ignorePosition:GetChecked()
|
||||||
|
|
||||||
local compressed = enc(compress(serialize(myconfig, defconfig, "pfUI_config", ignored)))
|
local encoded = Encode(DiffConfig(myconfig, defconfig, ignored) or {})
|
||||||
f.scroll.text:SetText(compressed)
|
f.scroll.text:SetText(encoded)
|
||||||
f.scroll.text.value = compressed
|
f.scroll.text.value = encoded
|
||||||
f.scroll:SetVerticalScroll(0)
|
f.scroll:SetVerticalScroll(0)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
@@ -457,4 +394,4 @@ pfUI:RegisterModule("share", function ()
|
|||||||
f:Show()
|
f:Show()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|||||||
+2
-2
@@ -51,12 +51,12 @@ pfUI:RegisterModule("skin", function ()
|
|||||||
DurabilityFrame.SetPoint = function() return end
|
DurabilityFrame.SetPoint = function() return end
|
||||||
|
|
||||||
if C.appearance.cd.blizzard == "1" then
|
if C.appearance.cd.blizzard == "1" then
|
||||||
hooksecurefunc("PaperDollItemSlotButton_Update", function()
|
pfUI.hooksecurefunc("PaperDollItemSlotButton_Update", function()
|
||||||
local cooldown = _G[this:GetName().."Cooldown"]
|
local cooldown = _G[this:GetName().."Cooldown"]
|
||||||
if cooldown then cooldown.pfCooldownType = "BLIZZARD" end
|
if cooldown then cooldown.pfCooldownType = "BLIZZARD" end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
hooksecurefunc("SpellButton_UpdateButton", function()
|
pfUI.hooksecurefunc("SpellButton_UpdateButton", function()
|
||||||
local cooldown = _G[this:GetName().."Cooldown"]
|
local cooldown = _G[this:GetName().."Cooldown"]
|
||||||
if cooldown then cooldown.pfCooldownType = "BLIZZARD" end
|
if cooldown then cooldown.pfCooldownType = "BLIZZARD" end
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pfUI:RegisterModule("socialmod", function ()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
do -- add colors to guild list
|
do -- add colors to guild list
|
||||||
hooksecurefunc("GuildStatus_Update", function()
|
pfUI.hooksecurefunc("GuildStatus_Update", function()
|
||||||
local playerzone = GetRealZoneText()
|
local playerzone = GetRealZoneText()
|
||||||
local off = FauxScrollFrame_GetOffset(GuildListScrollFrame)
|
local off = FauxScrollFrame_GetOffset(GuildListScrollFrame)
|
||||||
for i=1, GUILDMEMBERS_TO_DISPLAY, 1 do
|
for i=1, GUILDMEMBERS_TO_DISPLAY, 1 do
|
||||||
@@ -70,7 +70,7 @@ pfUI:RegisterModule("socialmod", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
do -- add colors to friend list
|
do -- add colors to friend list
|
||||||
hooksecurefunc("FriendsList_Update", function()
|
pfUI.hooksecurefunc("FriendsList_Update", function()
|
||||||
if GetNumFriends() == 0 then return end
|
if GetNumFriends() == 0 then return end
|
||||||
|
|
||||||
local playerzone = GetRealZoneText()
|
local playerzone = GetRealZoneText()
|
||||||
@@ -123,7 +123,7 @@ pfUI:RegisterModule("socialmod", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
do -- add colors to who list
|
do -- add colors to who list
|
||||||
hooksecurefunc("WhoList_Update", function()
|
pfUI.hooksecurefunc("WhoList_Update", function()
|
||||||
local num, max = GetNumWhoResults()
|
local num, max = GetNumWhoResults()
|
||||||
local off = FauxScrollFrame_GetOffset(WhoListScrollFrame)
|
local off = FauxScrollFrame_GetOffset(WhoListScrollFrame)
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,13 @@ SlashCmdList["PFDLLSTATUS"] = function()
|
|||||||
chat:AddMessage(" |cffff0000Nampower|r: Not detected")
|
chat:AddMessage(" |cffff0000Nampower|r: Not detected")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- ClassicAPI
|
||||||
|
if CLASSIC_API_VERSION then
|
||||||
|
chat:AddMessage(" |cff00ff00ClassicAPI|r: v" .. CLASSIC_API_VERSION)
|
||||||
|
else
|
||||||
|
chat:AddMessage(" |cffff0000ClassicAPI|r: Not detected")
|
||||||
|
end
|
||||||
|
|
||||||
-- Check if castbar exists for indicator positioning
|
-- Check if castbar exists for indicator positioning
|
||||||
if pfUI.castbar and pfUI.castbar.player then
|
if pfUI.castbar and pfUI.castbar.player then
|
||||||
chat:AddMessage(" |cff00ff00Castbar|r: Available for indicator anchoring")
|
chat:AddMessage(" |cff00ff00Castbar|r: Available for indicator anchoring")
|
||||||
|
|||||||
+107
-97
@@ -10,6 +10,11 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
local ON_SWING_QUEUED = 0
|
local ON_SWING_QUEUED = 0
|
||||||
local ON_SWING_QUEUE_POPPED = 1
|
local ON_SWING_QUEUE_POPPED = 1
|
||||||
|
|
||||||
|
-- Spell.dbc bits used to mirror server-side swing-reset rules.
|
||||||
|
local FLAG_AUTOATTACK = tonumber("0x08", 16) -- SPELL_INTERRUPT_FLAG_AUTOATTACK
|
||||||
|
local ATTR_KEEP_SWINGS = tonumber("0x20000", 16) -- SPELL_ATTR_EX2_NOT_RESET_AUTO_ACTIONS
|
||||||
|
local ATTR_ON_NEXT_SWING = tonumber("0x04", 16) -- SPELL_ATTR_ON_NEXT_SWING
|
||||||
|
|
||||||
-- Consolidate state into a table to avoid Lua 5.0 upvalue limit (32 max)
|
-- Consolidate state into a table to avoid Lua 5.0 upvalue limit (32 max)
|
||||||
local S = {
|
local S = {
|
||||||
mhTimer = 0, mhTimerMax = 1,
|
mhTimer = 0, mhTimerMax = 1,
|
||||||
@@ -27,56 +32,30 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
isDruid = false,
|
isDruid = false,
|
||||||
cachedHSSlots = {}, cachedCleaveSlots = {},
|
cachedHSSlots = {}, cachedCleaveSlots = {},
|
||||||
useSpellQueueEvent = false,
|
useSpellQueueEvent = false,
|
||||||
playerGUID = nil,
|
|
||||||
swingThrottle = 0,
|
swingThrottle = 0,
|
||||||
onSwingCache = {},
|
onSwingCache = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Ranged spell IDs
|
-- Wand "Shoot" runs on the ranged bar but is INDEPENDENT of the melee
|
||||||
local RANGED_SPELLIDS = {
|
-- swing clock — casters melee-weave between mainhand swings and wand
|
||||||
[75] = true, -- Auto Shot (Hunter)
|
-- fires, both timers tick concurrently. Every other ranged-auto-attack
|
||||||
[2764] = true, -- Throw (Warrior/Rogue)
|
-- (Hunter Auto Shot, any future auto-repeat ranged spell) replaces MH.
|
||||||
}
|
local WAND_SHOOT_SPELLID = 5019
|
||||||
|
local THROW_SPELLID = 2764 -- one-shot ranged, not auto-repeat
|
||||||
|
|
||||||
-- Spells that DELAY the swing timer by their cast duration but do NOT reset it.
|
-- ATTR_ON_NEXT_SWING: spell replaces next auto-attack swing.
|
||||||
-- Slam: vanilla behavior on Turtle WoW - delays swing, does not reset.
|
|
||||||
-- Hammer of Wrath: Turtle WoW changed behavior - does not reset swing timer.
|
|
||||||
local swingDelaySpells = {
|
|
||||||
[1464] = true, [8820] = true, [11604] = true, [11605] = true, -- Slam R1-R4
|
|
||||||
[24275] = true, [24274] = true, [24239] = true, -- Hammer of Wrath R1-R3
|
|
||||||
}
|
|
||||||
|
|
||||||
-- SPELL_ATTR_ON_NEXT_SWING (bit 2, value 4): spell replaces next auto-attack swing.
|
|
||||||
-- Covers Raptor Strike, Maul, Mongoose Bite, Holy Strike, etc. automatically.
|
-- Covers Raptor Strike, Maul, Mongoose Bite, Holy Strike, etc. automatically.
|
||||||
local ATTR_ON_NEXT_SWING = 4
|
|
||||||
local function IsOnSwingSpell(spellId)
|
local function IsOnSwingSpell(spellId)
|
||||||
if S.onSwingCache[spellId] ~= nil then return S.onSwingCache[spellId] end
|
if S.onSwingCache[spellId] ~= nil then return S.onSwingCache[spellId] end
|
||||||
local rec = GetSpellRec(spellId)
|
local attr = GetSpellRecField(spellId, "attributes") or 0
|
||||||
local result = rec and bit.band(rec.attributes, ATTR_ON_NEXT_SWING) ~= 0 or false
|
local result = bit.band(attr, ATTR_ON_NEXT_SWING) ~= 0
|
||||||
S.onSwingCache[spellId] = result
|
S.onSwingCache[spellId] = result
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Heroic Strike spell IDs (all ranks)
|
-- HS / Cleave / Maul are detected dynamically via IsOnSwingSpell (the
|
||||||
local hsSpellIDs = {
|
-- SPELL_ATTR_ON_NEXT_SWING bit) + name comparison against the rank-1
|
||||||
[78] = true, [284] = true, [285] = true, [1608] = true,
|
-- canonical names cached below — no per-rank ID maintenance.
|
||||||
[11564] = true, [11565] = true, [11566] = true, [11567] = true,
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Cleave spell IDs (all ranks)
|
|
||||||
local cleaveSpellIDs = {
|
|
||||||
[845] = true, [7369] = true, [11608] = true, [11609] = true,
|
|
||||||
[20569] = true,
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Maul spell IDs (all ranks 1 to 7)
|
|
||||||
local maulSpellIDs = {
|
|
||||||
[6807] = true,
|
|
||||||
[6808] = true,
|
|
||||||
[6809] = true,
|
|
||||||
[8972] = true,
|
|
||||||
[9745] = true, [9880] = true, [9881] = true,
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Read config
|
-- Read config
|
||||||
local sw_width = tonumber(C.unitframes.swingtimerwidth) or 200
|
local sw_width = tonumber(C.unitframes.swingtimerwidth) or 200
|
||||||
@@ -355,14 +334,17 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
pfUI.swingtimer:Show()
|
pfUI.swingtimer:Show()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Reset ranged countdown
|
-- Reset ranged countdown. replaceMH=true (Hunter Auto Shot, Throw) stops
|
||||||
local function ResetRanged()
|
-- the melee swing clock while ranged ticks; replaceMH=false (wand Shoot)
|
||||||
|
-- leaves it running for melee weaving.
|
||||||
|
local function ResetRanged(replaceMH)
|
||||||
if not sw_showranged then return end
|
if not sw_showranged then return end
|
||||||
UpdateWeaponSpeeds()
|
UpdateWeaponSpeeds()
|
||||||
if S.raSpeed <= 0 then return end
|
if S.raSpeed <= 0 then return end
|
||||||
-- Ranged replaces MH bar
|
if replaceMH then
|
||||||
S.mhActive = false
|
S.mhActive = false
|
||||||
pfUI.swingtimer.mainhand:Hide()
|
pfUI.swingtimer.mainhand:Hide()
|
||||||
|
end
|
||||||
S.raTimerMax = S.raSpeed
|
S.raTimerMax = S.raSpeed
|
||||||
S.raTimer = S.raSpeed
|
S.raTimer = S.raSpeed
|
||||||
S.raActive = true
|
S.raActive = true
|
||||||
@@ -406,11 +388,35 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
pfUI.swingtimer:Hide()
|
pfUI.swingtimer:Hide()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- HS/Cleave helpers. Canonical rank-1 spellIDs resolve to the localized
|
-- HS/Cleave/Maul helpers. Canonical rank-1 spellIDs resolve to the
|
||||||
-- spell name once, so the per-slot comparison is locale-independent without
|
-- localized spell name once, so per-spell classification is rank- and
|
||||||
-- per-rank hardcoding (every rank of Heroic Strike returns the same name).
|
-- locale-independent without per-rank ID hardcoding (every rank of
|
||||||
local HS_NAME = C_Spell.GetSpellName(78) -- Heroic Strike (Rank 1)
|
-- Heroic Strike etc. returns the same name).
|
||||||
local CLEAVE_NAME = C_Spell.GetSpellName(845) -- Cleave (Rank 1)
|
local HS_NAME = C_Spell.GetSpellName(78) -- Heroic Strike (Rank 1)
|
||||||
|
local CLEAVE_NAME = C_Spell.GetSpellName(845) -- Cleave (Rank 1)
|
||||||
|
local MAUL_NAME = C_Spell.GetSpellName(6807) -- Maul (Rank 1)
|
||||||
|
|
||||||
|
-- Classify an on-next-swing spell as "hs" / "cleave" / "maul" / nil.
|
||||||
|
-- IsOnSwingSpell gates the family (ATTR_ON_NEXT_SWING bit 0x04) so
|
||||||
|
-- unrelated spells return nil cheaply.
|
||||||
|
local function ClassifyOnSwingSpell(spellId)
|
||||||
|
if not IsOnSwingSpell(spellId) then return nil end
|
||||||
|
local name = C_Spell.GetSpellName(spellId)
|
||||||
|
if name == HS_NAME then return "hs"
|
||||||
|
elseif name == CLEAVE_NAME then return "cleave"
|
||||||
|
elseif name == MAUL_NAME then return "maul"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set the queue flags from a ClassifyOnSwingSpell result. nil = no-op
|
||||||
|
-- (preserves prior flag state when the queued spell isn't one we
|
||||||
|
-- color-code, matching the legacy table-lookup behavior).
|
||||||
|
local function SetQueuedKind(kind)
|
||||||
|
if not kind then return end
|
||||||
|
S.hsQueued = (kind == "hs")
|
||||||
|
S.cleaveQueued = (kind == "cleave")
|
||||||
|
S.maulQueued = (kind == "maul")
|
||||||
|
end
|
||||||
|
|
||||||
local function RebuildQueueSlotCache()
|
local function RebuildQueueSlotCache()
|
||||||
if not S.isWarrior or not sw_hsqueue or S.useSpellQueueEvent then return end
|
if not S.isWarrior or not sw_hsqueue or S.useSpellQueueEvent then return end
|
||||||
@@ -694,11 +700,17 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
local spellStartFrame = CreateFrame("Frame")
|
local spellStartFrame = CreateFrame("Frame")
|
||||||
spellStartFrame:RegisterEvent("SPELL_START_SELF")
|
spellStartFrame:RegisterEvent("SPELL_START_SELF")
|
||||||
spellStartFrame:SetScript("OnEvent", function()
|
spellStartFrame:SetScript("OnEvent", function()
|
||||||
if arg1 and arg1 > 0 then
|
if not (arg1 and arg1 > 0) then return end
|
||||||
S.pendingCastSpellId = arg1
|
S.pendingCastSpellId = arg1
|
||||||
-- Slam (and other delay-only spells): freeze the swing timer during cast
|
-- Freeze the swing timer for cast-time spells that DON'T reset auto-
|
||||||
-- so it pauses instead of ticking down and expiring mid-cast
|
-- attack on completion (Slam, Hammer of Wrath on Turtle, etc.) — those
|
||||||
if swingDelaySpells[arg1] and S.mhActive then
|
-- let the swing resume from where it paused. Detect dynamically via the
|
||||||
|
-- absent AUTOATTACK interrupt flag (8); spells with that bit reset on
|
||||||
|
-- SPELL_GO_SELF so freezing isn't necessary. Subsumes the old hardcoded
|
||||||
|
-- swingDelaySpells list (no list maintenance for new Slam-style spells).
|
||||||
|
if S.mhActive then
|
||||||
|
local iflags = GetSpellRecField(arg1, "interruptFlags") or 0
|
||||||
|
if bit.band(iflags, FLAG_AUTOATTACK) == 0 then
|
||||||
S.mhFrozenAt = GetTime()
|
S.mhFrozenAt = GetTime()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -718,52 +730,57 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
-- SPELL_GO hook via libdebuff
|
-- SPELL_GO hook via libdebuff
|
||||||
pfUI.libdebuff_spell_go_hooks = pfUI.libdebuff_spell_go_hooks or {}
|
pfUI.libdebuff_spell_go_hooks = pfUI.libdebuff_spell_go_hooks or {}
|
||||||
pfUI.libdebuff_spell_go_hooks["swingtimer"] = function(spellId)
|
pfUI.libdebuff_spell_go_hooks["swingtimer"] = function(spellId)
|
||||||
if RANGED_SPELLIDS[spellId] then
|
-- C_Spell.IsRangedAutoAttackSpell catches both Auto Shot (75) and
|
||||||
ResetRanged()
|
-- wand Shoot (5019) via Spell.dbc's AUTO_REPEAT attribute (covers
|
||||||
|
-- any future auto-repeat ranged spell automatically). Wand is the
|
||||||
|
-- one independent of the MH swing — everything else replaces it.
|
||||||
|
-- Throw isn't auto-repeat (single-shot) so it's handled explicitly.
|
||||||
|
if C_Spell.IsRangedAutoAttackSpell(spellId) then
|
||||||
|
ResetRanged(spellId ~= WAND_SHOOT_SPELLID)
|
||||||
return
|
return
|
||||||
elseif swingDelaySpells[spellId] then
|
elseif spellId == THROW_SPELLID then
|
||||||
-- Swing-delay spells (Slam, Hammer of Wrath on Turtle WoW):
|
ResetRanged(true)
|
||||||
-- Delay the swing timer by cast duration, do NOT reset it.
|
|
||||||
if S.mhFrozenAt then
|
|
||||||
local castDuration = GetTime() - S.mhFrozenAt
|
|
||||||
S.mhTimer = S.mhTimer + castDuration
|
|
||||||
S.mhTimerMax = S.mhTimerMax + castDuration
|
|
||||||
S.mhFrozenAt = nil
|
|
||||||
end
|
|
||||||
S.pendingCastSpellId = nil
|
|
||||||
return
|
return
|
||||||
elseif hsSpellIDs[spellId] or cleaveSpellIDs[spellId] or maulSpellIDs[spellId] or IsOnSwingSpell(spellId) then
|
elseif IsOnSwingSpell(spellId) then
|
||||||
S.hsQueued = false; S.cleaveQueued = false
|
-- On-next-swing ability (HS / Cleave / Maul / Raptor Strike / etc.)
|
||||||
S.maulQueued = false
|
-- — the swing fires as the spell consumes it. Drop the queued color.
|
||||||
ResetMH()
|
S.hsQueued = false; S.cleaveQueued = false; S.maulQueued = false
|
||||||
elseif cleaveSpellIDs[spellId] then
|
|
||||||
S.hsQueued = false; S.cleaveQueued = false
|
|
||||||
ResetMH()
|
ResetMH()
|
||||||
else
|
else
|
||||||
-- Any spell with interruptFlags > 0 resets the swing timer
|
-- Mirror the server rule for "does this spell reset the auto-attack
|
||||||
-- (Moonfire, Faerie Fire, Wrath, Starfire etc. - NOT Insect Swarm which has flags=0)
|
-- swing" (Spell::IsMeleeAttackResetSpell in Turtle's core):
|
||||||
local _rec = GetSpellRec(spellId)
|
-- InterruptFlags has SPELL_INTERRUPT_FLAG_AUTOATTACK (0x08)
|
||||||
if _rec and _rec.interruptFlags and _rec.interruptFlags > 0 then
|
-- AND AttributesEx2 lacks NOT_RESET_AUTO_ACTIONS (0x20000).
|
||||||
|
-- If neither path resets and we're holding a frozen-swing-during-cast
|
||||||
|
-- (mhFrozenAt set by SPELL_START_SELF for non-AUTOATTACK spells), this
|
||||||
|
-- is a Slam-style cast — push the timer forward by the cast duration
|
||||||
|
-- so the bar resumes from where it paused.
|
||||||
|
local iflags = GetSpellRecField(spellId, "interruptFlags") or 0
|
||||||
|
if bit.band(iflags, FLAG_AUTOATTACK) ~= 0
|
||||||
|
and bit.band(GetSpellRecField(spellId, "attributesEx2") or 0, ATTR_KEEP_SWINGS) == 0 then
|
||||||
if S.mhActive and S.mhSpeed > 0 then
|
if S.mhActive and S.mhSpeed > 0 then
|
||||||
UpdateWeaponSpeeds()
|
UpdateWeaponSpeeds()
|
||||||
S.mhTimerMax = S.mhSpeed
|
S.mhTimerMax = S.mhSpeed
|
||||||
S.mhTimer = S.mhSpeed
|
S.mhTimer = S.mhSpeed
|
||||||
end
|
end
|
||||||
|
if S.ohActive and S.ohSpeed > 0 then
|
||||||
|
S.ohTimerMax = S.ohSpeed
|
||||||
|
S.ohTimer = S.ohSpeed
|
||||||
|
end
|
||||||
|
elseif S.mhFrozenAt then
|
||||||
|
local castDuration = GetTime() - S.mhFrozenAt
|
||||||
|
S.mhTimer = S.mhTimer + castDuration
|
||||||
|
S.mhTimerMax = S.mhTimerMax + castDuration
|
||||||
|
S.mhFrozenAt = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
S.pendingCastSpellId = nil
|
S.pendingCastSpellId = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
-- SPELL_CAST_EVENT hook: HS/Cleave queue tracking
|
-- SPELL_CAST_EVENT hook: HS/Cleave/Maul queue tracking
|
||||||
pfUI.libdebuff_spell_cast_hooks = pfUI.libdebuff_spell_cast_hooks or {}
|
pfUI.libdebuff_spell_cast_hooks = pfUI.libdebuff_spell_cast_hooks or {}
|
||||||
pfUI.libdebuff_spell_cast_hooks["swingtimer"] = function(success, spellId)
|
pfUI.libdebuff_spell_cast_hooks["swingtimer"] = function(success, spellId)
|
||||||
if hsSpellIDs[spellId] then
|
SetQueuedKind(ClassifyOnSwingSpell(spellId))
|
||||||
S.hsQueued = true; S.cleaveQueued = false; S.maulQueued = false
|
|
||||||
elseif cleaveSpellIDs[spellId] then
|
|
||||||
S.cleaveQueued = true; S.hsQueued = false; S.maulQueued = false
|
|
||||||
elseif maulSpellIDs[spellId] then
|
|
||||||
S.maulQueued = true; S.hsQueued = false; S.cleaveQueued = false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -771,7 +788,7 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
events:RegisterEvent("AUTO_ATTACK_SELF")
|
events:RegisterEvent("AUTO_ATTACK_SELF")
|
||||||
events:RegisterEvent("AUTO_ATTACK_OTHER")
|
events:RegisterEvent("AUTO_ATTACK_OTHER")
|
||||||
events:RegisterEvent("PLAYER_ENTERING_WORLD")
|
events:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
events:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
events:RegisterEvent("PLAYER_EQUIPMENT_CHANGED") -- ClassicAPI: per-slot, equipment-only
|
||||||
events:RegisterEvent("PLAYER_REGEN_DISABLED")
|
events:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||||
events:RegisterEvent("PLAYER_REGEN_ENABLED")
|
events:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||||
events:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
|
events:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
|
||||||
@@ -814,8 +831,7 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
elseif event == "AUTO_ATTACK_OTHER" then
|
elseif event == "AUTO_ATTACK_OTHER" then
|
||||||
-- Parry haste: enemy attacked the player and player parried
|
-- Parry haste: enemy attacked the player and player parried
|
||||||
local targetGuid = arg2
|
local targetGuid = arg2
|
||||||
if not targetGuid or not S.playerGUID then return end
|
if not targetGuid or not IsPlayerGuid(targetGuid) then return end
|
||||||
if targetGuid ~= S.playerGUID then return end
|
|
||||||
local victimState = arg5 or 0
|
local victimState = arg5 or 0
|
||||||
-- VICTIMSTATE_PARRY = 3
|
-- VICTIMSTATE_PARRY = 3
|
||||||
-- Vanilla: parry reduces the NEXT swing timer by 40% of weapon speed,
|
-- Vanilla: parry reduces the NEXT swing timer by 40% of weapon speed,
|
||||||
@@ -847,13 +863,7 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
local spellId = arg2 or 0
|
local spellId = arg2 or 0
|
||||||
if eventCode == ON_SWING_QUEUED then
|
if eventCode == ON_SWING_QUEUED then
|
||||||
S.useSpellQueueEvent = true
|
S.useSpellQueueEvent = true
|
||||||
if hsSpellIDs[spellId] then
|
SetQueuedKind(ClassifyOnSwingSpell(spellId))
|
||||||
S.hsQueued = true; S.cleaveQueued = false; S.maulQueued = false
|
|
||||||
elseif cleaveSpellIDs[spellId] then
|
|
||||||
S.cleaveQueued = true; S.hsQueued = false; S.maulQueued = false
|
|
||||||
elseif maulSpellIDs[spellId] then
|
|
||||||
S.maulQueued = true; S.hsQueued = false; S.cleaveQueued = false
|
|
||||||
end
|
|
||||||
elseif eventCode == ON_SWING_QUEUE_POPPED then
|
elseif eventCode == ON_SWING_QUEUE_POPPED then
|
||||||
S.hsQueued = false; S.cleaveQueued = false; S.maulQueued = false
|
S.hsQueued = false; S.cleaveQueued = false; S.maulQueued = false
|
||||||
end
|
end
|
||||||
@@ -868,12 +878,12 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
local _, class = UnitClass("player")
|
local _, class = UnitClass("player")
|
||||||
S.isWarrior = (class == "WARRIOR")
|
S.isWarrior = (class == "WARRIOR")
|
||||||
S.isDruid = (class == "DRUID")
|
S.isDruid = (class == "DRUID")
|
||||||
S.playerGUID = UnitGUID("player")
|
|
||||||
UpdateWeaponSpeeds()
|
UpdateWeaponSpeeds()
|
||||||
RebuildQueueSlotCache()
|
RebuildQueueSlotCache()
|
||||||
|
|
||||||
elseif event == "UNIT_INVENTORY_CHANGED" then
|
elseif event == "PLAYER_EQUIPMENT_CHANGED" then
|
||||||
if arg1 and arg1 ~= "player" then return end
|
-- arg1 = changed slot; only weapon slots (main/off/ranged) affect swing speed
|
||||||
|
if not INVSLOTS_EQUIPABLE_IN_COMBAT[arg1] then return end
|
||||||
UpdateWeaponSpeeds()
|
UpdateWeaponSpeeds()
|
||||||
if S.ohSpeed == 0 then
|
if S.ohSpeed == 0 then
|
||||||
S.ohActive = false
|
S.ohActive = false
|
||||||
@@ -898,7 +908,7 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
S.maulQueued = false
|
S.maulQueued = false
|
||||||
|
|
||||||
elseif event == "UNIT_DIED" then
|
elseif event == "UNIT_DIED" then
|
||||||
if arg1 and arg1 == S.playerGUID then
|
if IsPlayerGuid(arg1) then
|
||||||
ResetAll()
|
ResetAll()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -530,7 +530,7 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- replace wim class colors with pfUI ones
|
-- replace wim class colors with pfUI ones
|
||||||
hooksecurefunc("WIM_InitClassProps", function()
|
pfUI.hooksecurefunc("WIM_InitClassProps", function()
|
||||||
for class in pairs(PFUI_CLASS_COLORS) do
|
for class in pairs(PFUI_CLASS_COLORS) do
|
||||||
local wimclass = _G[format("WIM_LOCALIZED_%s",class)]
|
local wimclass = _G[format("WIM_LOCALIZED_%s",class)]
|
||||||
local colorstr = "|c" .. PFUI_CLASS_COLORS[class].colorStr
|
local colorstr = "|c" .. PFUI_CLASS_COLORS[class].colorStr
|
||||||
@@ -547,7 +547,7 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
|||||||
btnClose:SetWidth(13)
|
btnClose:SetWidth(13)
|
||||||
btnClose:SetHeight(13)
|
btnClose:SetHeight(13)
|
||||||
end
|
end
|
||||||
hooksecurefunc("WIM_Icon_DropDown_Update", function()
|
pfUI.hooksecurefunc("WIM_Icon_DropDown_Update", function()
|
||||||
for i=1,_G.WIM_MaxMenuCount do
|
for i=1,_G.WIM_MaxMenuCount do
|
||||||
local btn = _G["WIM_ConversationMenuTellButton"..i]
|
local btn = _G["WIM_ConversationMenuTellButton"..i]
|
||||||
if i==1 and btn:IsEnabled() == 0 then return end
|
if i==1 and btn:IsEnabled() == 0 then return end
|
||||||
@@ -729,7 +729,7 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
|||||||
SkinScrollbar(WIM_HelpScrollFrameScrollBar)
|
SkinScrollbar(WIM_HelpScrollFrameScrollBar)
|
||||||
end
|
end
|
||||||
|
|
||||||
hooksecurefunc("WIM_WindowOnShow", function()
|
pfUI.hooksecurefunc("WIM_WindowOnShow", function()
|
||||||
if this.backdrop then return end -- already skinned
|
if this.backdrop then return end -- already skinned
|
||||||
|
|
||||||
local windowname = this:GetName()
|
local windowname = this:GetName()
|
||||||
@@ -904,7 +904,7 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- trigger the event whenever SuperMacro got an update
|
-- trigger the event whenever SuperMacro got an update
|
||||||
hooksecurefunc("SM_UpdateActionSpell", function()
|
pfUI.hooksecurefunc("SM_UpdateActionSpell", function()
|
||||||
for slot=1,120 do pfUI.bars.update[slot] = true end
|
for slot=1,120 do pfUI.bars.update[slot] = true end
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
@@ -922,7 +922,7 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
|||||||
pfUI.bars.skip_macro = true
|
pfUI.bars.skip_macro = true
|
||||||
|
|
||||||
-- send clevermacro events to pfUI actionbars
|
-- send clevermacro events to pfUI actionbars
|
||||||
hooksecurefunc("ActionButton_OnEvent", function(event)
|
pfUI.hooksecurefunc("ActionButton_OnEvent", function(event)
|
||||||
events(this, event)
|
events(this, event)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
@@ -943,7 +943,7 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
|||||||
CreateBackdropShadow(AtlasLootTooltip)
|
CreateBackdropShadow(AtlasLootTooltip)
|
||||||
|
|
||||||
if pfUI.eqcompare then
|
if pfUI.eqcompare then
|
||||||
HookScript(AtlasLootTooltip, "OnShow", pfUI.eqcompare.GameTooltipShow)
|
pfUI.eqcompare.HookTooltip(AtlasLootTooltip)
|
||||||
HookScript(AtlasLootTooltip, "OnHide", function()
|
HookScript(AtlasLootTooltip, "OnHide", function()
|
||||||
ShoppingTooltip1:Hide()
|
ShoppingTooltip1:Hide()
|
||||||
ShoppingTooltip2:Hide()
|
ShoppingTooltip2:Hide()
|
||||||
@@ -1182,7 +1182,7 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
|||||||
-- use pfUI frames to draw healComm predictions
|
-- use pfUI frames to draw healComm predictions
|
||||||
local pfHookHealCommSendAddonMessage = HealComm.SendAddonMessage
|
local pfHookHealCommSendAddonMessage = HealComm.SendAddonMessage
|
||||||
function HealComm.SendAddonMessage(this, msg)
|
function HealComm.SendAddonMessage(this, msg)
|
||||||
if not UnitInRaid("player") and GetNumPartyMembers() < 1 then
|
if not IsInGroup() then
|
||||||
libpredict:ParseChatMessage(UnitName("player"), msg, "HealComm")
|
libpredict:ParseChatMessage(UnitName("player"), msg, "HealComm")
|
||||||
end
|
end
|
||||||
pfHookHealCommSendAddonMessage(this, msg)
|
pfHookHealCommSendAddonMessage(this, msg)
|
||||||
|
|||||||
+8
-8
@@ -146,14 +146,6 @@ pfUI:RegisterModule("tooltip", function ()
|
|||||||
rhp, rhpmax = hp, hpmax
|
rhp, rhpmax = hp, hpmax
|
||||||
elseif pfUI.libhealth and pfUI.libhealth.enabled then
|
elseif pfUI.libhealth and pfUI.libhealth.enabled then
|
||||||
rhp, rhpmax, estimated = pfUI.libhealth:GetUnitHealthByName(this.name, this.level, tonumber(hp), tonumber(hpmax))
|
rhp, rhpmax, estimated = pfUI.libhealth:GetUnitHealthByName(this.name, this.level, tonumber(hp), tonumber(hpmax))
|
||||||
elseif MobHealthFrame then
|
|
||||||
local index = (this.name or "") .. ":" .. (this.level or "")
|
|
||||||
local ppp = MobHealth_PPP(index)
|
|
||||||
if perc and ppp and ppp > 0 and not UnitIsUnit("mouseover", "pet") then
|
|
||||||
rhp = round(hp * ppp)
|
|
||||||
rhpmax = round(100 * ppp)
|
|
||||||
estimated = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if C.tooltip.alwaysperc == "0" and ( estimated or hpmax > 100 or round(hpmax/100*hp) ~= hp ) then
|
if C.tooltip.alwaysperc == "0" and ( estimated or hpmax > 100 or round(hpmax/100*hp) ~= hp ) then
|
||||||
@@ -241,6 +233,14 @@ pfUI:RegisterModule("tooltip", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if C.tooltip.movespeed == "1" then
|
||||||
|
local currentSpeed = GetUnitSpeed(unit)
|
||||||
|
if currentSpeed and currentSpeed > 0 then
|
||||||
|
local pct = floor(currentSpeed / 7 * 100 + 0.5)
|
||||||
|
GameTooltip:AddLine(T["Speed"] .. ": " .. pct .. "%", 0.7, 0.7, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if hp and hpm then
|
if hp and hpm then
|
||||||
if hp >= 1000 then hp = round(hp / 1000, 1) .. "k" end
|
if hp >= 1000 then hp = round(hp / 1000, 1) .. "k" end
|
||||||
if hpm >= 1000 then hpm = round(hpm / 1000, 1) .. "k" end
|
if hpm >= 1000 then hpm = round(hpm / 1000, 1) .. "k" end
|
||||||
|
|||||||
+5
-63
@@ -1,5 +1,5 @@
|
|||||||
-- skip module initialization on every other client than turtle-wow
|
-- skip module initialization on every other client than turtle-wow
|
||||||
if not TargetHPText or not TargetHPPercText then return end
|
if not TURTLE_WOW_VERSION then return end
|
||||||
|
|
||||||
pfUI:RegisterModule("turtle-wow", function ()
|
pfUI:RegisterModule("turtle-wow", function ()
|
||||||
-- Manage Turtle WoW's GroupUI (Turtle_GroupUI addon) vs pfUI frames.
|
-- Manage Turtle WoW's GroupUI (Turtle_GroupUI addon) vs pfUI frames.
|
||||||
@@ -47,7 +47,7 @@ pfUI:RegisterModule("turtle-wow", function ()
|
|||||||
-- Check if pfUI is handling group or raid for the current situation
|
-- Check if pfUI is handling group or raid for the current situation
|
||||||
local function pfUIHandlesGroupOrRaid()
|
local function pfUIHandlesGroupOrRaid()
|
||||||
local disabled = C["disabled"] or {}
|
local disabled = C["disabled"] or {}
|
||||||
if GetNumRaidMembers() > 0 then
|
if IsInRaid() then
|
||||||
if not C.unitframes.raid then return false end
|
if not C.unitframes.raid then return false end
|
||||||
-- Hide Turtle frames if: pfUI raid module is active, OR player disabled visibility
|
-- Hide Turtle frames if: pfUI raid module is active, OR player disabled visibility
|
||||||
if disabled["raid"] == "1" then
|
if disabled["raid"] == "1" then
|
||||||
@@ -65,14 +65,14 @@ pfUI:RegisterModule("turtle-wow", function ()
|
|||||||
|
|
||||||
HookAddonOrVariable("GroupFrame", function()
|
HookAddonOrVariable("GroupFrame", function()
|
||||||
-- After Turtle's own init, hide frames if pfUI handles them
|
-- After Turtle's own init, hide frames if pfUI handles them
|
||||||
hooksecurefunc("GroupFrame_Toggle", function()
|
pfUI.hooksecurefunc("GroupFrame_Toggle", function()
|
||||||
if pfUIHandlesGroupOrRaid() then
|
if pfUIHandlesGroupOrRaid() then
|
||||||
DisableTurtleGroupFrames()
|
DisableTurtleGroupFrames()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- After every group/raid update, re-hide if pfUI handles them
|
-- After every group/raid update, re-hide if pfUI handles them
|
||||||
hooksecurefunc("GroupFrame_Update", function()
|
pfUI.hooksecurefunc("GroupFrame_Update", function()
|
||||||
if pfUIHandlesGroupOrRaid() then
|
if pfUIHandlesGroupOrRaid() then
|
||||||
DisableTurtleGroupFrames()
|
DisableTurtleGroupFrames()
|
||||||
end
|
end
|
||||||
@@ -86,64 +86,6 @@ pfUI:RegisterModule("turtle-wow", function ()
|
|||||||
L["debuffs"]['Moonfire'] = {[1]=9.0,[2]=18.0,[3]=18.0,[4]=18.0,[5]=18.0,[6]=18.0,[7]=18.0,[8]=18.0,[9]=18.0,[10]=18.0,[0]=18.0}
|
L["debuffs"]['Moonfire'] = {[1]=9.0,[2]=18.0,[3]=18.0,[4]=18.0,[5]=18.0,[6]=18.0,[7]=18.0,[8]=18.0,[9]=18.0,[10]=18.0,[0]=18.0}
|
||||||
L["debuffs"]['Deep Wound'] = {[0]=6.0}
|
L["debuffs"]['Deep Wound'] = {[0]=6.0}
|
||||||
|
|
||||||
-- add custom spell logic to libdebuff
|
|
||||||
HookScript(libdebuff, "OnEvent", function()
|
|
||||||
if event == "CHAT_MSG_SPELL_SELF_DAMAGE" then
|
|
||||||
-- refresh paladin judgements on holy strike
|
|
||||||
-- taken from: https://github.com/doorknob6/pfUI-turtle/blob/master/modules/debuffs.lua
|
|
||||||
local holystrike = string.find(string.sub(arg1,6,17), "Holy Strike")
|
|
||||||
--arg2 is spell dmg when it hits, nil when it misses
|
|
||||||
if holystrike and arg2 then
|
|
||||||
for seal in L["judgements"] do
|
|
||||||
local name = UnitName("target")
|
|
||||||
local level = UnitLevel("target")
|
|
||||||
if name and libdebuff.objects[name] then
|
|
||||||
if level and
|
|
||||||
libdebuff.objects[name][level] and
|
|
||||||
libdebuff.objects[name][level][seal] then
|
|
||||||
libdebuff:AddEffect(name, level, seal)
|
|
||||||
elseif libdebuff.objects[name][0] and
|
|
||||||
libdebuff.objects[name][0][seal] then
|
|
||||||
libdebuff:AddEffect(name, 0, seal)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- refresh rip and rake duration on ferocious bite (Turtle WoW feature)
|
|
||||||
-- Only refresh if Ferocious Bite actually hit (not missed/dodged/parried/etc.)
|
|
||||||
local match = string.find(arg1, "Ferocious Bite")
|
|
||||||
if match and arg2 and not libdebuff:DidSpellFail("Ferocious Bite") then
|
|
||||||
local name = UnitName("target")
|
|
||||||
local level = UnitLevel("target")
|
|
||||||
|
|
||||||
-- Refresh Rip mit existierender Duration
|
|
||||||
if libdebuff.objects[name] and libdebuff.objects[name][level] and libdebuff.objects[name][level]["Rip"] then
|
|
||||||
local existingDuration = libdebuff.objects[name][level]["Rip"].duration
|
|
||||||
libdebuff:AddEffect(name, level, "Rip", existingDuration)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Refresh Rake mit existierender Duration
|
|
||||||
if libdebuff.objects[name] and libdebuff.objects[name][level] and libdebuff.objects[name][level]["Rake"] then
|
|
||||||
local existingDuration = libdebuff.objects[name][level]["Rake"].duration
|
|
||||||
libdebuff:AddEffect(name, level, "Rake", existingDuration)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- refresh Immolate duration after cast Conflagrate
|
|
||||||
-- Only refresh if Conflagrate actually hit
|
|
||||||
local conflagrate = string.find(string.sub(arg1,6,17), "Conflagrate")
|
|
||||||
if conflagrate and arg2 and not libdebuff:DidSpellFail("Conflagrate") then
|
|
||||||
local name = UnitName("target")
|
|
||||||
local level = UnitLevel("target")
|
|
||||||
if libdebuff.objects[name] and libdebuff.objects[name][level] and libdebuff.objects[name][level]["Immolate"] then
|
|
||||||
local duration = libdebuff.objects[name][level]["Immolate"].duration
|
|
||||||
libdebuff:UpdateDuration(name, level, "Immolate", duration - 3)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- turtle wow totemic recall clear totem indicators
|
-- turtle wow totemic recall clear totem indicators
|
||||||
local _, class = UnitClass("player")
|
local _, class = UnitClass("player")
|
||||||
if libtotem and class == "SHAMAN" then
|
if libtotem and class == "SHAMAN" then
|
||||||
@@ -353,7 +295,7 @@ pfUI:RegisterModule("turtle-wow", function ()
|
|||||||
local initialized = false
|
local initialized = false
|
||||||
|
|
||||||
HookAddonOrVariable("Blizzard_InspectUI", function()
|
HookAddonOrVariable("Blizzard_InspectUI", function()
|
||||||
hooksecurefunc("InspectFrame_Show", function()
|
pfUI.hooksecurefunc("InspectFrame_Show", function()
|
||||||
-- break if theres nothing left to do
|
-- break if theres nothing left to do
|
||||||
if initialized then return end
|
if initialized then return end
|
||||||
|
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ pfUI:RegisterModule("unusable", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- update on regular pfUI button updates
|
-- update on regular pfUI button updates
|
||||||
hooksecurefunc(pfUI.bag, "UpdateSlot", function(self, bag, slot)
|
pfUI.hooksecurefunc(pfUI.bag, "UpdateSlot", function(self, bag, slot)
|
||||||
pfUI.unusable:UpdateSlot(bag, slot)
|
pfUI.unusable:UpdateSlot(bag, slot)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- update on bank frame itemlock updates
|
-- update on bank frame itemlock updates
|
||||||
hooksecurefunc("BankFrameItemButton_UpdateLock", function()
|
pfUI.hooksecurefunc("BankFrameItemButton_UpdateLock", function()
|
||||||
pfUI.unusable:UpdateSlot(-1, this:GetID())
|
pfUI.unusable:UpdateSlot(-1, this:GetID())
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ pfUI:RegisterModule("xpbar", function ()
|
|||||||
local REST_WINDOW = 300 -- seconds of sliding-window samples for rate calc
|
local REST_WINDOW = 300 -- seconds of sliding-window samples for rate calc
|
||||||
|
|
||||||
local REST_CAP_MUL = 1.5 -- target rested cap = UnitXPMax * 1.5
|
local REST_CAP_MUL = 1.5 -- target rested cap = UnitXPMax * 1.5
|
||||||
if IsTurtleWoW() then
|
if TURTLE_WOW_VERSION then
|
||||||
REST_CAP_MUL = 1.13
|
REST_CAP_MUL = 1.13
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ do
|
|||||||
-- ClassicAPI dependency check.
|
-- ClassicAPI dependency check.
|
||||||
-- pfUI relies pervasively on the modern C_* / SuperWoW / nameplate / focus
|
-- pfUI relies pervasively on the modern C_* / SuperWoW / nameplate / focus
|
||||||
-- API surface that ClassicAPI polyfills, so presence is required.
|
-- API surface that ClassicAPI polyfills, so presence is required.
|
||||||
local PFUI_CLASSIC_API_MIN = 10503 -- (X*10000 + Y*100 + Z)
|
local PFUI_CLASSIC_API_MIN = 10511 -- (X*10000 + Y*100 + Z)
|
||||||
local PFUI_CLASSIC_API_LATEST = PFUI_CLASSIC_API_MIN
|
local PFUI_CLASSIC_API_LATEST = PFUI_CLASSIC_API_MIN
|
||||||
local PFUI_CLASSIC_API_WEBSITE = "https://github.com/brues-code/ClassicAPI"
|
local PFUI_CLASSIC_API_WEBSITE = "https://github.com/brues-code/ClassicAPI"
|
||||||
local PFUI_CLASSIC_API_LATEST_URL = PFUI_CLASSIC_API_WEBSITE .. "/releases/latest"
|
local PFUI_CLASSIC_API_LATEST_URL = PFUI_CLASSIC_API_WEBSITE .. "/releases/latest"
|
||||||
@@ -99,9 +99,12 @@ pfUI.skins = {}
|
|||||||
pfUI.environment = {}
|
pfUI.environment = {}
|
||||||
pfUI.movables = {}
|
pfUI.movables = {}
|
||||||
pfUI.version = {}
|
pfUI.version = {}
|
||||||
pfUI.hooks = {}
|
|
||||||
pfUI.env = {}
|
pfUI.env = {}
|
||||||
|
|
||||||
|
pfUI.events = Mixin({}, CallbackRegistryMixin)
|
||||||
|
pfUI.events:OnLoad()
|
||||||
|
pfUI.events:SetUndefinedEventsAllowed(true)
|
||||||
|
|
||||||
-- check if macro addons are loaded (disables macrotweak/macroscan)
|
-- check if macro addons are loaded (disables macrotweak/macroscan)
|
||||||
function pfUI:MacroAddonsLoaded()
|
function pfUI:MacroAddonsLoaded()
|
||||||
return IsAddOnLoaded("Supermacro") or IsAddOnLoaded("SuperCleveRoidMacros") or IsAddOnLoaded("UltimaMacros")
|
return IsAddOnLoaded("Supermacro") or IsAddOnLoaded("SuperCleveRoidMacros") or IsAddOnLoaded("UltimaMacros")
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ pfUI:RegisterSkin("Auctionhouse", function ()
|
|||||||
SkinArrowButton(AuctionsNextPageButton, "right", 18)
|
SkinArrowButton(AuctionsNextPageButton, "right", 18)
|
||||||
end
|
end
|
||||||
|
|
||||||
hooksecurefunc("AuctionFrame_OnShow", function()
|
pfUI.hooksecurefunc("AuctionFrame_OnShow", function()
|
||||||
AuctionFrame:ClearAllPoints()
|
AuctionFrame:ClearAllPoints()
|
||||||
AuctionFrame:SetPoint("TOPLEFT", 10, -104)
|
AuctionFrame:SetPoint("TOPLEFT", 10, -104)
|
||||||
end)
|
end)
|
||||||
@@ -76,7 +76,7 @@ pfUI:RegisterSkin("Auctionhouse", function ()
|
|||||||
item:SetPoint("LEFT", 2, 0)
|
item:SetPoint("LEFT", 2, 0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
hooksecurefunc("AuctionFrameBrowse_Update", function()
|
pfUI.hooksecurefunc("AuctionFrameBrowse_Update", function()
|
||||||
for i = 1, NUM_BROWSE_TO_DISPLAY do
|
for i = 1, NUM_BROWSE_TO_DISPLAY do
|
||||||
HandleIcon(_G["BrowseButton"..i.."Item"], _G["BrowseButton"..i.."ItemIconTexture"])
|
HandleIcon(_G["BrowseButton"..i.."Item"], _G["BrowseButton"..i.."ItemIconTexture"])
|
||||||
end
|
end
|
||||||
@@ -145,7 +145,7 @@ pfUI:RegisterSkin("Auctionhouse", function ()
|
|||||||
item:ClearAllPoints()
|
item:ClearAllPoints()
|
||||||
item:SetPoint("LEFT", 2, 0)
|
item:SetPoint("LEFT", 2, 0)
|
||||||
end
|
end
|
||||||
hooksecurefunc("AuctionFrameBid_Update", function()
|
pfUI.hooksecurefunc("AuctionFrameBid_Update", function()
|
||||||
for i = 1, NUM_BIDS_TO_DISPLAY do
|
for i = 1, NUM_BIDS_TO_DISPLAY do
|
||||||
HandleIcon(_G["BidButton"..i.."Item"], _G["BidButton"..i.."ItemIconTexture"])
|
HandleIcon(_G["BidButton"..i.."Item"], _G["BidButton"..i.."ItemIconTexture"])
|
||||||
end
|
end
|
||||||
@@ -191,14 +191,14 @@ pfUI:RegisterSkin("Auctionhouse", function ()
|
|||||||
item:ClearAllPoints()
|
item:ClearAllPoints()
|
||||||
item:SetPoint("LEFT", 2, 0)
|
item:SetPoint("LEFT", 2, 0)
|
||||||
end
|
end
|
||||||
hooksecurefunc("AuctionFrameAuctions_Update", function()
|
pfUI.hooksecurefunc("AuctionFrameAuctions_Update", function()
|
||||||
for i = 1, NUM_AUCTIONS_TO_DISPLAY do
|
for i = 1, NUM_AUCTIONS_TO_DISPLAY do
|
||||||
HandleIcon(_G["AuctionsButton"..i.."Item"], _G["AuctionsButton"..i.."ItemIconTexture"])
|
HandleIcon(_G["AuctionsButton"..i.."Item"], _G["AuctionsButton"..i.."ItemIconTexture"])
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
SkinButton(AuctionsItemButton)
|
SkinButton(AuctionsItemButton)
|
||||||
hooksecurefunc("AuctionSellItemButton_OnEvent", function()
|
pfUI.hooksecurefunc("AuctionSellItemButton_OnEvent", function()
|
||||||
if event ~= "NEW_AUCTION_UPDATE" then return end
|
if event ~= "NEW_AUCTION_UPDATE" then return end
|
||||||
HandleIcon(AuctionsItemButton, AuctionsItemButton:GetNormalTexture())
|
HandleIcon(AuctionsItemButton, AuctionsItemButton:GetNormalTexture())
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ pfUI:RegisterSkin("Battlefield Minimap", function ()
|
|||||||
BattlefieldMinimapTab:Hide()
|
BattlefieldMinimapTab:Hide()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
hooksecurefunc("BattlefieldMinimap_ShowOpacity", function()
|
pfUI.hooksecurefunc("BattlefieldMinimap_ShowOpacity", function()
|
||||||
OpacityFrame:ClearAllPoints()
|
OpacityFrame:ClearAllPoints()
|
||||||
OpacityFrame:SetPoint("TOPRIGHT", "BattlefieldMinimap", "TOPLEFT", -2*border, 0)
|
OpacityFrame:SetPoint("TOPRIGHT", "BattlefieldMinimap", "TOPLEFT", -2*border, 0)
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -2,25 +2,13 @@ pfUI:RegisterSkin("Character", function ()
|
|||||||
local rawborder, border = GetBorderSize()
|
local rawborder, border = GetBorderSize()
|
||||||
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
|
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
|
||||||
|
|
||||||
-- Compatibility
|
-- Honor Tab
|
||||||
if PlayerTitleDropDown then -- tbc, wotlk
|
StripTextures(HonorFrame)
|
||||||
-- Character Tab
|
StripTextures(ArenaFrame)
|
||||||
SkinDropDown(PlayerTitleDropDown)
|
|
||||||
PlayerTitleDropDown:SetPoint("TOP", CharacterLevelText, "BOTTOM", 0, -2)
|
|
||||||
PlayerTitleDropDownText:SetPoint("LEFT", PlayerTitleDropDown.backdrop, "LEFT", 6, 2)
|
|
||||||
SkinDropDown(PlayerStatFrameLeftDropDown)
|
|
||||||
SkinDropDown(PlayerStatFrameRightDropDown)
|
|
||||||
|
|
||||||
-- Honor Tab
|
HonorFrameProgressBar:SetStatusBarTexture(pfUI.media["img:bar"])
|
||||||
StripTextures(PVPFrame)
|
CreateBackdrop(HonorFrameProgressBar)
|
||||||
else -- vanilla
|
HonorFrameProgressBar:SetHeight(24)
|
||||||
-- Honor Tab
|
|
||||||
StripTextures(HonorFrame)
|
|
||||||
|
|
||||||
HonorFrameProgressBar:SetStatusBarTexture(pfUI.media["img:bar"])
|
|
||||||
CreateBackdrop(HonorFrameProgressBar)
|
|
||||||
HonorFrameProgressBar:SetHeight(24)
|
|
||||||
end
|
|
||||||
|
|
||||||
local magicResTextureCords = {
|
local magicResTextureCords = {
|
||||||
{0.21875, 0.78125, 0.25, 0.3203125},
|
{0.21875, 0.78125, 0.25, 0.3203125},
|
||||||
@@ -148,22 +136,19 @@ pfUI:RegisterSkin("Character", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
HookScript(CharacterFrame, "OnShow", function()
|
pfUI.hooksecurefunc("CharacterFrame_OnShow", function()
|
||||||
RefreshCharacterSlots()
|
RefreshCharacterSlots()
|
||||||
RefreshPetPosition()
|
RefreshPetPosition()
|
||||||
|
end)
|
||||||
|
|
||||||
if not this.hooked then
|
pfUI.hooksecurefunc("PaperDollItemSlotButton_Update", function()
|
||||||
hooksecurefunc("PaperDollItemSlotButton_Update", function()
|
if this:GetParent() == PaperDollFrame then
|
||||||
-- update only character slots!
|
RefreshCharacterSlot(this)
|
||||||
if string.find(this:GetName(), "^Character.-Slot$") then
|
|
||||||
RefreshCharacterSlot(this)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
hooksecurefunc("PetTab_Update", RefreshPetPosition)
|
|
||||||
this.hooked = true
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
pfUI.hooksecurefunc("PetTab_Update", RefreshPetPosition)
|
||||||
|
|
||||||
StripTextures(PaperDollFrame)
|
StripTextures(PaperDollFrame)
|
||||||
StripTextures(CharacterAttributesFrame)
|
StripTextures(CharacterAttributesFrame)
|
||||||
StripTextures(CharacterResistanceFrame)
|
StripTextures(CharacterResistanceFrame)
|
||||||
@@ -285,7 +270,7 @@ pfUI:RegisterSkin("Character", function ()
|
|||||||
-- the FactionStanding text from `bar.standingText` on mouseout, so we
|
-- the FactionStanding text from `bar.standingText` on mouseout, so we
|
||||||
-- stash our augmented text there too — otherwise hovering a bar strips
|
-- stash our augmented text there too — otherwise hovering a bar strips
|
||||||
-- the "(N)" suffix off.
|
-- the "(N)" suffix off.
|
||||||
hooksecurefunc("ReputationFrame_Update", function()
|
pfUI.hooksecurefunc("ReputationFrame_Update", function()
|
||||||
if C.character.reputation.repRequired ~= "1" then return end
|
if C.character.reputation.repRequired ~= "1" then return end
|
||||||
local offset = FauxScrollFrame_GetOffset(ReputationListScrollFrame)
|
local offset = FauxScrollFrame_GetOffset(ReputationListScrollFrame)
|
||||||
for i = 1, NUM_FACTIONS_DISPLAYED do
|
for i = 1, NUM_FACTIONS_DISPLAYED do
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ pfUI:RegisterSkin("Friends", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- set positions
|
-- set positions
|
||||||
hooksecurefunc("WhoList_Update", function()
|
pfUI.hooksecurefunc("WhoList_Update", function()
|
||||||
for i = 1, WHOS_TO_DISPLAY do
|
for i = 1, WHOS_TO_DISPLAY do
|
||||||
local level = _G["WhoFrameButton"..i.."Level"]
|
local level = _G["WhoFrameButton"..i.."Level"]
|
||||||
level:ClearAllPoints()
|
level:ClearAllPoints()
|
||||||
@@ -231,7 +231,7 @@ pfUI:RegisterSkin("Friends", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- set positions
|
-- set positions
|
||||||
hooksecurefunc("GuildStatus_Update", function()
|
pfUI.hooksecurefunc("GuildStatus_Update", function()
|
||||||
for i = 1, GUILDMEMBERS_TO_DISPLAY do
|
for i = 1, GUILDMEMBERS_TO_DISPLAY do
|
||||||
local level = _G["GuildFrameButton"..i.."Level"]
|
local level = _G["GuildFrameButton"..i.."Level"]
|
||||||
level:ClearAllPoints()
|
level:ClearAllPoints()
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ pfUI:RegisterSkin("Gossip and Quest", function ()
|
|||||||
QuestRewardItemHighlightBG:SetTexture(1,1,1,.2)
|
QuestRewardItemHighlightBG:SetTexture(1,1,1,.2)
|
||||||
QuestRewardItemHighlightBG:SetAllPoints()
|
QuestRewardItemHighlightBG:SetAllPoints()
|
||||||
|
|
||||||
hooksecurefunc("QuestFrameItems_Update", function()
|
pfUI.hooksecurefunc("QuestFrameItems_Update", function()
|
||||||
QuestRewardItemHighlight:Hide()
|
QuestRewardItemHighlight:Hide()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
hooksecurefunc("QuestRewardItem_OnClick", function()
|
pfUI.hooksecurefunc("QuestRewardItem_OnClick", function()
|
||||||
if this.type == "choice" then
|
if this.type == "choice" then
|
||||||
QuestRewardItemHighlight:SetAllPoints(this.backdrop)
|
QuestRewardItemHighlight:SetAllPoints(this.backdrop)
|
||||||
QuestRewardItemHighlight:Show()
|
QuestRewardItemHighlight:Show()
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ pfUI:RegisterSkin("Mailbox", function ()
|
|||||||
StripTextures(SendMailPackageButton)
|
StripTextures(SendMailPackageButton)
|
||||||
SkinButton(SendMailPackageButton, nil, nil, nil, nil, true)
|
SkinButton(SendMailPackageButton, nil, nil, nil, nil, true)
|
||||||
|
|
||||||
hooksecurefunc("SendMailFrame_Update", function()
|
pfUI.hooksecurefunc("SendMailFrame_Update", function()
|
||||||
HandleIcon(SendMailPackageButton, SendMailPackageButton:GetNormalTexture())
|
HandleIcon(SendMailPackageButton, SendMailPackageButton:GetNormalTexture())
|
||||||
|
|
||||||
local _, itemID = GetSendMailItemLink()
|
local _, itemID = GetSendMailItemLink()
|
||||||
@@ -62,7 +62,7 @@ pfUI:RegisterSkin("Mailbox", function ()
|
|||||||
do -- OpenMailFrame
|
do -- OpenMailFrame
|
||||||
SkinButton(OpenMailPackageButton, nil, nil, nil, OpenMailPackageButtonIconTexture)
|
SkinButton(OpenMailPackageButton, nil, nil, nil, OpenMailPackageButtonIconTexture)
|
||||||
|
|
||||||
hooksecurefunc("InboxFrame_OnClick", function(index)
|
pfUI.hooksecurefunc("InboxFrame_OnClick", function(index)
|
||||||
local _, itemID = GetInboxItemLink(index)
|
local _, itemID = GetInboxItemLink(index)
|
||||||
if itemID then
|
if itemID then
|
||||||
local quality = C_Item.GetItemQualityByID(itemID)
|
local quality = C_Item.GetItemQualityByID(itemID)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ pfUI:RegisterSkin("Merchant", function ()
|
|||||||
if MerchantGuildBankRepairButton then -- tbc
|
if MerchantGuildBankRepairButton then -- tbc
|
||||||
SkinButton(MerchantGuildBankRepairButton, nil, nil, nil, MerchantGuildBankRepairButtonIcon)
|
SkinButton(MerchantGuildBankRepairButton, nil, nil, nil, MerchantGuildBankRepairButtonIcon)
|
||||||
MerchantGuildBankRepairButtonIcon:SetTexCoord(.59, .82, .06, .54)
|
MerchantGuildBankRepairButtonIcon:SetTexCoord(.59, .82, .06, .54)
|
||||||
hooksecurefunc("MerchantFrame_UpdateRepairButtons", function()
|
pfUI.hooksecurefunc("MerchantFrame_UpdateRepairButtons", function()
|
||||||
MerchantGuildBankRepairButton:ClearAllPoints()
|
MerchantGuildBankRepairButton:ClearAllPoints()
|
||||||
MerchantGuildBankRepairButton:SetPoint("RIGHT", MerchantBuyBackItemItemButton, "LEFT", -14, 0)
|
MerchantGuildBankRepairButton:SetPoint("RIGHT", MerchantBuyBackItemItemButton, "LEFT", -14, 0)
|
||||||
MerchantRepairAllButton:ClearAllPoints()
|
MerchantRepairAllButton:ClearAllPoints()
|
||||||
@@ -56,7 +56,7 @@ pfUI:RegisterSkin("Merchant", function ()
|
|||||||
moneyFrame:SetPoint("BOTTOMLEFT", itemButton, "BOTTOMRIGHT", 5, 1)
|
moneyFrame:SetPoint("BOTTOMLEFT", itemButton, "BOTTOMRIGHT", 5, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
hooksecurefunc("MerchantFrame_UpdateMerchantInfo", function()
|
pfUI.hooksecurefunc("MerchantFrame_UpdateMerchantInfo", function()
|
||||||
if MerchantFrame.selectedTab == 1 then
|
if MerchantFrame.selectedTab == 1 then
|
||||||
for i = 3, 11, 2 do
|
for i = 3, 11, 2 do
|
||||||
_G["MerchantItem"..i]:ClearAllPoints()
|
_G["MerchantItem"..i]:ClearAllPoints()
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ pfUI:RegisterSkin("Options - New", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- hook after category selection: UpdateOptions is local so we hook its caller
|
-- hook after category selection: UpdateOptions is local so we hook its caller
|
||||||
hooksecurefunc("OptionsListButton_OnClick", SkinControls)
|
pfUI.hooksecurefunc("OptionsListButton_OnClick", SkinControls)
|
||||||
-- also cover initial load
|
-- also cover initial load
|
||||||
HookScript(OptionsFrame, "OnShow", SkinControls)
|
HookScript(OptionsFrame, "OnShow", SkinControls)
|
||||||
end)
|
end)
|
||||||
@@ -19,7 +19,7 @@ pfUI:RegisterSkin("Options - Video", function ()
|
|||||||
slider:SetPoint(point, anchor, anchorPoint, x, y - shift)
|
slider:SetPoint(point, anchor, anchorPoint, x, y - shift)
|
||||||
end
|
end
|
||||||
|
|
||||||
hooksecurefunc("OptionsFrame_Load", function()
|
pfUI.hooksecurefunc("OptionsFrame_Load", function()
|
||||||
OptionsFramePixelShaders:SetWidth(230)
|
OptionsFramePixelShaders:SetWidth(230)
|
||||||
OptionsFrameMiscellaneous:ClearAllPoints()
|
OptionsFrameMiscellaneous:ClearAllPoints()
|
||||||
OptionsFrameMiscellaneous:SetPoint("LEFT", OptionsFramePixelShaders, "RIGHT", 6, 0)
|
OptionsFrameMiscellaneous:SetPoint("LEFT", OptionsFramePixelShaders, "RIGHT", 6, 0)
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ pfUI:RegisterSkin("Profession", function ()
|
|||||||
reagentlabel:SetTextColor(1,1,1,1)
|
reagentlabel:SetTextColor(1,1,1,1)
|
||||||
|
|
||||||
local scanner = libtipscan:GetScanner(name)
|
local scanner = libtipscan:GetScanner(name)
|
||||||
hooksecurefunc(SetSelection, function(id)
|
pfUI.hooksecurefunc(SetSelection, function(id)
|
||||||
if id and id ~= 0 then
|
if id and id ~= 0 then
|
||||||
detailscroll:Show()
|
detailscroll:Show()
|
||||||
HandleIcon(icon, icon:GetNormalTexture())
|
HandleIcon(icon, icon:GetNormalTexture())
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ pfUI:RegisterSkin("Quest Log", function ()
|
|||||||
|
|
||||||
StripTextures(QUEST_COUNT)
|
StripTextures(QUEST_COUNT)
|
||||||
QUEST_COUNT:ClearAllPoints()
|
QUEST_COUNT:ClearAllPoints()
|
||||||
hooksecurefunc("QuestLogUpdateQuestCount", function(numQuests)
|
pfUI.hooksecurefunc("QuestLogUpdateQuestCount", function(numQuests)
|
||||||
QUEST_COUNT:ClearAllPoints()
|
QUEST_COUNT:ClearAllPoints()
|
||||||
QUEST_COUNT:SetPoint("BOTTOMRIGHT", QuestLogFrame, "TOPRIGHT", 0, -50)
|
QUEST_COUNT:SetPoint("BOTTOMRIGHT", QuestLogFrame, "TOPRIGHT", 0, -50)
|
||||||
end)
|
end)
|
||||||
@@ -24,7 +24,7 @@ pfUI:RegisterSkin("Quest Log", function ()
|
|||||||
QUEST_COUNT:SetPoint("TOPRIGHT", -10, -30)
|
QUEST_COUNT:SetPoint("TOPRIGHT", -10, -30)
|
||||||
end
|
end
|
||||||
|
|
||||||
hooksecurefunc("QuestLog_OnShow", function()
|
pfUI.hooksecurefunc("QuestLog_OnShow", function()
|
||||||
QuestLogFrame:ClearAllPoints()
|
QuestLogFrame:ClearAllPoints()
|
||||||
QuestLogFrame:SetPoint("TOPLEFT", 10, -104)
|
QuestLogFrame:SetPoint("TOPLEFT", 10, -104)
|
||||||
end)
|
end)
|
||||||
@@ -163,7 +163,7 @@ pfUI:RegisterSkin("Quest Log", function ()
|
|||||||
QuestLogListScrollFrame:SetPoint("TOPLEFT", 10, -54)
|
QuestLogListScrollFrame:SetPoint("TOPLEFT", 10, -54)
|
||||||
QuestLogListScrollFrame:SetHeight(350)
|
QuestLogListScrollFrame:SetHeight(350)
|
||||||
|
|
||||||
hooksecurefunc("QuestLog_Update", function()
|
pfUI.hooksecurefunc("QuestLog_Update", function()
|
||||||
local numEntries = GetNumQuestLogEntries()
|
local numEntries = GetNumQuestLogEntries()
|
||||||
local questIndex, text, level, questTag, isHeader
|
local questIndex, text, level, questTag, isHeader
|
||||||
|
|
||||||
|
|||||||
@@ -38,12 +38,12 @@ pfUI:RegisterSkin("Readycheck", function ()
|
|||||||
frame.bar.text:SetPoint("CENTER", 0, 0)
|
frame.bar.text:SetPoint("CENTER", 0, 0)
|
||||||
|
|
||||||
local max
|
local max
|
||||||
hooksecurefunc("ShowReadyCheck", function()
|
pfUI.hooksecurefunc("ShowReadyCheck", function()
|
||||||
max = ReadyCheckFrame.timer
|
max = ReadyCheckFrame.timer
|
||||||
frame.bar:SetMinMaxValues(0, max)
|
frame.bar:SetMinMaxValues(0, max)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
hooksecurefunc(update_func, function()
|
pfUI.hooksecurefunc(update_func, function()
|
||||||
if not ReadyCheckFrame.timer then return end
|
if not ReadyCheckFrame.timer then return end
|
||||||
|
|
||||||
local perc = ReadyCheckFrame.timer/max
|
local perc = ReadyCheckFrame.timer/max
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ pfUI:RegisterSkin("GM Survey", function ()
|
|||||||
CreateBackdrop(GMSurveyCommentFrame, nil, true, .75)
|
CreateBackdrop(GMSurveyCommentFrame, nil, true, .75)
|
||||||
SkinScrollbar(GMSurveyCommentScrollFrameScrollBar)
|
SkinScrollbar(GMSurveyCommentScrollFrameScrollBar)
|
||||||
GMSurveyFrameComment:SetMaxLetters(2000)
|
GMSurveyFrameComment:SetMaxLetters(2000)
|
||||||
hooksecurefunc("GMSurveyFrame_Update", function()
|
pfUI.hooksecurefunc("GMSurveyFrame_Update", function()
|
||||||
GMSurveyFrameComment:SetWidth(505)
|
GMSurveyFrameComment:SetWidth(505)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ pfUI:RegisterSkin("Trade", function ()
|
|||||||
RecipientButtonBG:SetAllPoints()
|
RecipientButtonBG:SetAllPoints()
|
||||||
end
|
end
|
||||||
|
|
||||||
hooksecurefunc("TradeFrame_UpdateTargetItem", function(id)
|
pfUI.hooksecurefunc("TradeFrame_UpdateTargetItem", function(id)
|
||||||
HandleIcon(_G["TradeRecipientItem"..id.."ItemButton"], _G["TradeRecipientItem"..id..'IconTexture'])
|
HandleIcon(_G["TradeRecipientItem"..id.."ItemButton"], _G["TradeRecipientItem"..id..'IconTexture'])
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ pfUI:RegisterSkin("Trainer", function ()
|
|||||||
|
|
||||||
StripTextures(ClassTrainerSkillIcon)
|
StripTextures(ClassTrainerSkillIcon)
|
||||||
SkinButton(ClassTrainerSkillIcon, nil, nil, nil, nil, true)
|
SkinButton(ClassTrainerSkillIcon, nil, nil, nil, nil, true)
|
||||||
hooksecurefunc("ClassTrainer_SetSelection", function()
|
pfUI.hooksecurefunc("ClassTrainer_SetSelection", function()
|
||||||
HandleIcon(ClassTrainerSkillIcon, ClassTrainerSkillIcon:GetNormalTexture())
|
HandleIcon(ClassTrainerSkillIcon, ClassTrainerSkillIcon:GetNormalTexture())
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user