-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathForceLoadTradeSkillData.lua
187 lines (164 loc) · 7.19 KB
/
ForceLoadTradeSkillData.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
--[[----------------------------------------------------------------------------
Accessing tradeskill levels without the UI
By p3lim on 2023.04.25 17:11 UTC
https://github.com/Stanzilla/WoWUIBugs/issues/424
In the good old days we could simply request skill levels for the player's
profession(s) using GetNumSkillLines() and GetSkillLineInfo(index), and is
still the current method on classic realms.
The way to get this information now is by iterating over
C_TradeSkillUI.GetAllProfessionTradeSkillLines() and using
C_TradeSkillUI.GetProfessionInfoBySkillLineID(skillLineID) to get the skill
levels.
However this requires the tradeskill data to be valid, otherwise the skill
level values are all 0. To validate this data we need to call
C_TradeSkillUI.OpenTradeSkill(skillLineID), which requires a hardware event
and is disruptive as it force shows the tradeskill UI.
Once C_TradeSkillUI.OpenTradeSkill() has been called atleast once per
character session, the player can freely unlearn every profession and learn
something else, even /reload the game, and the data is still valid for all
current and future professions. This means there's a flag being set, per
character session.
My proposal is one of the following, in order of most preferable first:
1. let C_TradeSkillUI.GetProfessionInfoBySkillLineID(skillLineID) request
the data by itself
2. implement C_TradeSkillUI.RequestData(), which would validify this data
without requiring a hardware event, and without being disruptive (e.g.
it would trigger a different event than TRADE_SKILL_SHOW)
3. add an optional argument to the existing API, e.g.
C_TradeSkillUI.OpenTradeSkill(skillLineID[, dontOpen]), passing the new
arg as a parameter to the TRADE_SKILL_SHOW event, which the UIParent
event handler should respect (and addons would have to too, which is why
this is least preferable)
----------------------------------------------------------------------------
https://github.com/Stanzilla/WoWUIBugs/issues/424#issuecomment-1522140660
My current workaround, which anyone is free to copy:
----------------------------------------------------------------------------]]--
local isRetail = (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE)
if not isRetail then return end
-- in case other addons copies this, make sure it never loads multiple times unless there is a
-- newer version of it, in which case we disable it and load anyways
local version = 4
if _G['ForceLoadTradeSkillData'] then
if _G['ForceLoadTradeSkillData'].version < version then
_G['ForceLoadTradeSkillData']:UnregisterAllEvents()
else
return
end
end
local hack = CreateFrame('Frame', 'ForceLoadTradeSkillData')
hack.version = version
hack:SetPropagateKeyboardInput(true) -- make sure we don't own the keyboard
hack:RegisterEvent('PLAYER_LOGIN')
hack:SetScript('OnEvent', function(self, event)
if event == 'PLAYER_LOGIN' or event == 'SKILL_LINES_CHANGED' then
self:UnregisterEvent(event)
local professionID = self:GetAnyProfessionID()
if not professionID then
-- player has no professions, wait for them to learn one
self:RegisterEvent('SKILL_LINES_CHANGED')
elseif not self:HasProfessionData(professionID) then
-- player has profession but the session has no data, listen for key event
self.professionID = professionID
self:SetScript('OnKeyDown', self.OnKeyDown)
end
elseif event == 'TRADE_SKILL_SHOW' then
if not (C_TradeSkillUI.IsTradeSkillLinked() or C_TradeSkillUI.IsTradeSkillGuild()) then
-- we've triggered the tradeskill UI, close it again and bail out
C_TradeSkillUI.CloseTradeSkill()
self:UnregisterEvent(event)
UIParent:RegisterEvent(event)
-- unmute sounds
UnmuteSoundFile(SOUNDKIT.UI_PROFESSIONS_WINDOW_OPEN)
UnmuteSoundFile(SOUNDKIT.UI_PROFESSIONS_WINDOW_CLOSE)
end
end
end)
function hack:OnKeyDown()
-- unregister ourselves first to avoid duplicate queries
self:SetScript('OnKeyDown', nil)
-- be silent
MuteSoundFile(SOUNDKIT.UI_PROFESSIONS_WINDOW_OPEN)
MuteSoundFile(SOUNDKIT.UI_PROFESSIONS_WINDOW_CLOSE)
-- listen for tradeskill UI opening then query it
UIParent:UnregisterEvent('TRADE_SKILL_SHOW')
self:RegisterEvent('TRADE_SKILL_SHOW')
C_TradeSkillUI.OpenTradeSkill(self.professionID)
end
function hack:GetAnyProfessionID()
-- any profession except archaeology is valid for requesting data
for index, professionIndex in next, {GetProfessions()} do
if index ~= 3 and professionIndex then
local _, _, _, _, _, _, professionID = GetProfessionInfo(professionIndex)
if professionID then
return professionID
end
end
end
end
function hack:HasProfessionData(professionID)
local skillInfo = C_TradeSkillUI.GetProfessionInfoBySkillLineID(professionID)
return skillInfo and skillInfo.maxSkillLevel and skillInfo.maxSkillLevel > 0
end
--[[
-- in case other addons copies this, make sure it never loads multiple times unless there is a
-- newer version of it, in which case we disable it and load anyways
local version = 1
if _G['ForceLoadTradeSkillData'] then
if _G['ForceLoadTradeSkillData'].version < version then
_G['ForceLoadTradeSkillData']:UnregisterAllEvents()
else
return
end
end
local hack = CreateFrame('Frame', 'ForceLoadTradeSkillData')
hack.version = version
hack:SetPropagateKeyboardInput(true) -- make sure we don't own the keyboard
hack:RegisterEvent('PLAYER_LOGIN')
hack:SetScript('OnEvent', function(self, event)
if event == 'PLAYER_LOGIN' then
local professionID = self:GetAnyProfessionID()
if not professionID then
-- player has no professions, wait for them to learn one
self:RegisterEvent('SKILL_LINES_CHANGED')
elseif not self:HasProfessionData(professionID) then
-- player has profession but the session has no data, listen for key event
self.professionID = professionID
self:SetScript('OnKeyDown', self.OnKeyDown)
end
elseif event == 'TRADE_SKILL_SHOW' then
if not (C_TradeSkillUI.IsTradeSkillLinked() or C_TradeSkillUI.IsTradeSkillGuild()) then
-- we've triggered the tradeskill UI, close it again and bail out
C_TradeSkillUI.CloseTradeSkill()
self:UnregisterEvent(event)
end
elseif event == 'SKILL_LINES_CHANGED' then
if self:GetAnyProfessionID() then
-- player has learned a profession, listen for key event
self:SetScript('OnKeyDown', self.OnKeyDown)
self:UnregisterEvent(event)
end
end
end)
function hack:OnKeyDown()
-- unregister ourselves first to avoid duplicate queries
self:SetScript('OnKeyDown', nil)
-- listen for tradeskill UI opening then query it
self:RegisterEvent('TRADE_SKILL_SHOW')
C_TradeSkillUI.OpenTradeSkill(self.professionID)
end
function hack:GetAnyProfessionID()
-- any profession except archaeology is valid for requesting data
for index, professionIndex in next, {GetProfessions()} do
if index ~= 3 and professionIndex then
local _, _, _, _, _, _, professionID = GetProfessionInfo(professionIndex)
if professionID then
return professionID
end
end
end
end
function hack:HasProfessionData(professionID)
local skillInfo = C_TradeSkillUI.GetProfessionInfoBySkillLineID(professionID)
return skillInfo and skillInfo.maxSkillLevel and skillInfo.maxSkillLevel > 0
end
]]