forked from Ostoic/RaidBrowser
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstats.lua
316 lines (264 loc) · 8.64 KB
/
stats.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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
RaidBrowser.stats = {};
local raid_translations
if GetLocale() ~= "enUS" then
raid_translations = LibStub("LibBabble-Zone-3.0")
end
local raid_achievements = {
icc = {
4531, -- Storming the Citadel 10-man
4604, -- Storming the Citadel 25-man
4628, -- Storming the Citadel 10-man HC
4632, -- Storming the Citadel 25-man HC
4528, -- The Plagueworks 10-man
4605, -- The Plagueworks 25-man
4629, -- The Plagueworks 10-man HC
4633, -- The Plagueworks 25-man HC
4529, -- The Crimson Hall 10-man
4606, -- The Crimson Hall 25-man
4630, -- The Crimson Hall 10-man HC
4634, -- The Crimson Hall 25-man HC
4527, -- The Frostwing Halls 10-man
4607, -- The Frostwing Halls 25-man
4631, -- The Frostwing Halls 10-man HC
4635, -- The Frostwing Halls 25-man HC
4530, -- The Frozen Throne (LK10 NM)
4597, -- The Frozen Throne (LK25 NM)
4583, -- Bane of the Fallen King (LK10 HC)
4584, -- The Light of Dawn (LK25 HC)
},
toc = {
3917, -- Call of the Crusade 10-man
3916, -- Call of the Crusade 25-man
3918, -- Call of the Grand Crusade (10 HC)
3812, -- Call of the Grand Crusade (25 HC)
},
rs = {
4817, -- The Twilight Destroyer 10
4815, -- The Twilight Destroyer 25
4818, -- The Twilight Destroyer 10 HC
4816, -- The Twilight Destroyer 25 HC
},
};
local spec_names = {
full = {
-- Warrior
WarriorArms = "Arms Warrior",
WarriorFury = "Fury Warrior",
WarriorProtection = "Protection Warrior",
-- Paladin
PaladinHoly = "Holy Paladin",
PaladinProtection = "Protection Paladin",
PaladinCombat = "Retribution Paladin",
-- Hunter
HunterBeastMastery = "Beastmaster Hunter",
HunterMarksmanship = "Marksman Hunter",
HunterSurvival = "Survival Hunter",
-- Rogue
RogueAssassination = "Assassination Rogue",
RogueCombat = "Combat Rogue",
RogueSubtlety = "Subtlety Rogue",
-- Priest
PriestDiscipline = "Discipline Priest",
PriestHoly = "Holy Priest",
PriestShadow = "Shadow Priest",
-- DK
DeathKnightBlood = "Blood Death Knight",
DeathKnightFrost = "Frost Death Knight",
DeathKnightUnholy = "Unholy Death Knight",
-- Shaman
ShamanElementalCombat = "Elemental Shaman",
ShamanEnhancement = "Enhancement Shaman",
ShamanRestoration = "Restoration Shaman",
-- Mage
MageArcane = "Arcane Mage",
MageFire = "Fire Mage",
MageFrost = "Frost Mage",
-- Warlock
WarlockCurses = "Affliction Warlock",
WarlockSummoning = "Demolition Warlock",
WarlockDestruction = "Destruction Warlock",
-- Druid
DruidBalance = "Balance Druid",
DruidFeralCombat = "Feral Druid",
DruidRestoration = "Restoration Druid"
},
short = {
WarriorArms = "Arms Warri",
WarriorFury = "Fury Warri",
WarriorProtection = "Prot Warri",
PaladinHoly = "Holy Pala",
PaladinProtection = "Prot Pala",
PaladinCombat = "Retri Pala",
HunterBeastMastery = "BM Hunt",
HunterMarksmanship = "MM Hunt",
HunterSurvival = "Surv Hunt",
RogueAssassination = "Assa Rog",
RogueCombat = "Combat Rog",
RogueSubtlety = "Sub Rog",
PriestDiscipline = "Disco Heal",
PriestHoly = "Holy Priest",
PriestShadow = "Shadow",
DeathKnightBlood = "Blood DK",
DeathKnightFrost = "Frost DK",
DeathKnightUnholy = "Uh DK",
ShamanElementalCombat = "Ele Shamy",
ShamanEnhancement = "Enh Shamy",
ShamanRestoration = "Resto Shamy",
MageArcane = "Arcane Mage",
MageFire = "Fire Mage",
MageFrost = "Frost Mage",
WarlockCurses = "Affli Lock",
WarlockSummoning = "Demo Lock",
WarlockDestruction = "Destro Lock",
DruidBalance = "Boomy",
DruidFeralCombat = "Feral",
DruidRestoration = "Tree"
}
}
---@param raid string The name of the achievement ids table
---@nodiscard
local function find_best_achievement(raid)
local ids = raid_achievements[raid];
if not ids then
return nil;
end
local max_achievement = nil;
-- Find the highest ranking completed achievement
for i, id in ipairs(ids) do
local _, _, _, completed = GetAchievementInfo(id);
if completed and (not max_achievement or max_achievement[1] <= i) then
max_achievement = { i, id };
end
end
-- Find the highest ranking completed achievement criterion
for i, id in ipairs(ids) do
for j = 1, GetAchievementNumCriteria(id) do
local _, _, completed = GetAchievementCriteriaInfo(id, j)
if completed and (not max_achievement or max_achievement[1] <= i) then
max_achievement = { i, id };
end
end
end
if max_achievement then
return max_achievement[2];
else
return nil;
end
end
-- Function wrapper around GetTalentTabInfo
---@param i integer
---@return integer
---@nodiscard
local function GetTalentTabPoints(i)
local _, _, pts = GetTalentTabInfo(i)
return pts;
end
function RaidBrowser.stats.active_spec_index()
local indices = std.algorithm.transform({ 1, 2, 3 }, GetTalentTabPoints)
local i, _ = std.algorithm.max_of(indices);
return i;
end
---@return string
---@nodiscard
function RaidBrowser.stats.active_spec()
local active_tab = RaidBrowser.stats.active_spec_index()
local _, _, _, spec_name = GetTalentTabInfo(active_tab);
-- If we're a feral druid, then we need to distinguish between tank and cat feral.
if spec_name == 'DruidFeralCombat' then
local protector_of_pack_talent = 22;
local _, _, _, _, points = GetTalentInfo(active_tab, protector_of_pack_talent)
if points > 0 then
return 'Feral Druid (Bear)'
else
return 'Feral Druid (Cat)'
end
end
-- TODO: make config to toggle using full or short spec names
return spec_names["full"][spec_name] or spec_name;
end
---Return if the given raid is locked, and if so its reset time left (in seconds)
---@param raid_info any
---@return boolean, integer | nil
---@nodiscard
function RaidBrowser.stats.raid_lock_info(raid_info)
local instance_name = raid_info.instance_name
if raid_translations then
instance_name = raid_translations:GetUnstrictLookupTable()[raid_info.instance_name] or raid_info.instance_name
end
if instance_name == nil or raid_info.size == nil then return false, nil end
for i = 1, GetNumSavedInstances() do
local saved_name, _, reset, _, locked, _, _, _, saved_size = GetSavedInstanceInfo(i);
if saved_name ~= nil then
-- @napnapnap lockout fix (c8207076730d04f41b881dea3dd9f6ca32655372)
if string.lower(saved_name) == string.lower(instance_name) and saved_size == raid_info.size and locked then
return true, reset;
end
end
end
return false, nil;
end
---Returns for the currently active raidset, the spec name and its gearscore.
---@return string, integer
---@nodiscard
function RaidBrowser.stats.get_active_raidset()
local spec = nil;
local gs = nil;
-- Retrieve gearscore if GearScoreLite is installed
if GearScore_GetScore then
gs = GearScore_GetScore(UnitName('player'), 'player');
-- older GearScore version does not return gs on method call
if gs == nil and GS_Data then
if GS_Data[GetRealmName()] and GS_Data[GetRealmName()].Players[UnitName("player")] then
gs = GS_Data[GetRealmName()].Players[UnitName("player")]["GearScore"]
end
end
end
spec = RaidBrowser.stats.active_spec();
return spec, gs;
end
---@param set 'Primary'|'Secondary'
---@return string?, integer?
---@nodiscard
function RaidBrowser.stats.get_raidset(set)
local raidset = RaidBrowserCharacterRaidsets[set];
if not raidset then return end
return raidset.spec, raidset.gs;
end
---@return string?, integer?
function RaidBrowser.stats.current_raidset()
local x = 0
if RaidBrowserCharacterCurrentRaidset == 'Active' then
return RaidBrowser.stats.get_active_raidset();
end
---@diagnostic disable-next-line: param-type-mismatch
return RaidBrowser.stats.get_raidset(RaidBrowserCharacterCurrentRaidset);
end
---@param set 'Active' | 'Primary' | 'Secondary'
function RaidBrowser.stats.select_current_raidset(set)
RaidBrowserCharacterCurrentRaidset = set;
end
function RaidBrowser.stats.save_primary_raidset()
local spec, gs = RaidBrowser.stats.get_active_raidset();
RaidBrowserCharacterRaidsets['Primary'] = { spec = spec, gs = gs };
end
function RaidBrowser.stats.save_secondary_raidset()
local spec, gs = RaidBrowser.stats.get_active_raidset();
RaidBrowserCharacterRaidsets['Secondary'] = { spec = spec, gs = gs };
end
---Returns join message string
---@param raid_name string
---@return string
---@nodiscard
function RaidBrowser.stats.build_join_message(raid_name)
local spec, gs = RaidBrowser.stats.current_raidset();
-- local message = 'inv ' .. gs .. 'gs ' .. spec;
local message = 'inv for ' .. raid_name .. " - " .. gs .. 'gs ' .. spec;
-- Remove difficulty and raid_name size from the string
raid_name = RaidBrowser.get_short_raid_name(raid_name)
-- Find the best possible achievement for the given raid_name.
local achieve_id = find_best_achievement(raid_name);
if achieve_id then
message = message .. ' ' .. GetAchievementLink(achieve_id);
end
return message;
end