yellowfive@57
|
1 local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot")
|
yellowfive@57
|
2 local L = LibStub("AceLocale-3.0"):GetLocale("AskMrRobot", true)
|
yellowfive@57
|
3 local AceGUI = LibStub("AceGUI-3.0")
|
yellowfive@57
|
4
|
yellowfive@57
|
5 local _panelSplash
|
yellowfive@57
|
6 local _panelStartLoot
|
yellowfive@57
|
7 local _lblStartLoot
|
yellowfive@57
|
8 local _btnStartLoot
|
yellowfive@57
|
9 local _scrollHistory
|
yellowfive@57
|
10 local _tabs
|
yellowfive@57
|
11
|
yellowfive@57
|
12 local _messagePrefixes = {
|
yellowfive@57
|
13 RosterRequestGear = "_TRR",
|
yellowfive@57
|
14 RosterGear = "_TRG",
|
yellowfive@57
|
15 ItemExportRequestGear = "_TLR",
|
yellowfive@57
|
16 ItemExportGear = "_TLG",
|
yellowfive@57
|
17 ItemExportLoot = "_TLL",
|
yellowfive@57
|
18 SyncRequest = "_TSR",
|
yellowfive@57
|
19 Sync = "_TSS"
|
yellowfive@57
|
20 }
|
yellowfive@57
|
21
|
yellowfive@57
|
22 Amr.LootMessagePrefixes = {
|
yellowfive@57
|
23 Start = "_TCS",
|
yellowfive@57
|
24 Roll = "_TCR",
|
yellowfive@57
|
25 Veto = "_TCV",
|
yellowfive@57
|
26 Rand = "_TCD",
|
yellowfive@57
|
27 Give = "_TCG",
|
yellowfive@57
|
28 Finish = "_TCF"
|
yellowfive@57
|
29 }
|
yellowfive@57
|
30
|
yellowfive@57
|
31 local function renderExportWindow(container, instructions, text)
|
yellowfive@57
|
32
|
yellowfive@57
|
33 local bg = Amr:RenderCoverChrome(container, 800, 450)
|
yellowfive@57
|
34
|
yellowfive@57
|
35 local lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
36 lbl:SetWidth(750)
|
yellowfive@57
|
37 lbl:SetText(L.TeamExportHelp)
|
yellowfive@57
|
38 lbl:SetPoint("TOP", bg.content, "TOP", 0, -10)
|
yellowfive@57
|
39 bg:AddChild(lbl)
|
yellowfive@57
|
40
|
yellowfive@57
|
41 local lbl2 = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
42 lbl2:SetWidth(750)
|
yellowfive@57
|
43 lbl2:SetText(instructions)
|
yellowfive@57
|
44 lbl2:SetPoint("TOP", lbl.frame, "BOTTOM", 0, -10)
|
yellowfive@57
|
45 bg:AddChild(lbl2)
|
yellowfive@57
|
46
|
yellowfive@57
|
47 local txt = AceGUI:Create("AmrUiTextarea")
|
yellowfive@57
|
48 txt:SetWidth(750)
|
yellowfive@57
|
49 txt:SetHeight(300)
|
yellowfive@57
|
50 txt:SetPoint("TOP", lbl2.frame, "BOTTOM", 0, -10)
|
yellowfive@57
|
51 txt:SetFont(Amr.CreateFont("Regular", 12, Amr.Colors.Text))
|
yellowfive@57
|
52 txt:SetText(text)
|
yellowfive@57
|
53 bg:AddChild(txt)
|
yellowfive@57
|
54
|
yellowfive@57
|
55 local btn = AceGUI:Create("AmrUiButton")
|
yellowfive@57
|
56 btn:SetText(L.TeamButtonExportClose)
|
yellowfive@57
|
57 btn:SetBackgroundColor(Amr.Colors.Green)
|
yellowfive@57
|
58 btn:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
|
yellowfive@57
|
59 btn:SetWidth(120)
|
yellowfive@57
|
60 btn:SetHeight(28)
|
yellowfive@57
|
61 btn:SetPoint("TOPLEFT", txt.frame, "BOTTOMLEFT", 0, -10)
|
yellowfive@57
|
62 btn:SetCallback("OnClick", function(widget) Amr:HideCover() end)
|
yellowfive@57
|
63 bg:AddChild(btn)
|
yellowfive@57
|
64
|
yellowfive@57
|
65 return txt
|
yellowfive@57
|
66 end
|
yellowfive@57
|
67
|
yellowfive@57
|
68 local function renderImportWindow(container)
|
yellowfive@57
|
69
|
yellowfive@57
|
70 local bg = Amr:RenderCoverChrome(container, 700, 450)
|
yellowfive@57
|
71
|
yellowfive@57
|
72 local lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
73 lbl:SetWidth(600)
|
yellowfive@57
|
74 lbl:SetText(L.TeamImportRankingsHeader)
|
yellowfive@57
|
75 lbl:SetPoint("TOP", bg.content, "TOP", 0, -10)
|
yellowfive@57
|
76 bg:AddChild(lbl)
|
yellowfive@57
|
77
|
yellowfive@57
|
78 local txt = AceGUI:Create("AmrUiTextarea")
|
yellowfive@57
|
79 txt:SetWidth(600)
|
yellowfive@57
|
80 txt:SetHeight(300)
|
yellowfive@57
|
81 txt:SetPoint("TOP", lbl.frame, "BOTTOM", 0, -10)
|
yellowfive@57
|
82 txt:SetFont(Amr.CreateFont("Regular", 12, Amr.Colors.Text))
|
yellowfive@57
|
83 bg:AddChild(txt)
|
yellowfive@57
|
84
|
yellowfive@57
|
85 local btnImportOk = AceGUI:Create("AmrUiButton")
|
yellowfive@57
|
86 btnImportOk:SetText(L.ImportButtonOk)
|
yellowfive@57
|
87 btnImportOk:SetBackgroundColor(Amr.Colors.Green)
|
yellowfive@57
|
88 btnImportOk:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
|
yellowfive@57
|
89 btnImportOk:SetWidth(120)
|
yellowfive@57
|
90 btnImportOk:SetHeight(28)
|
yellowfive@57
|
91 btnImportOk:SetPoint("TOPLEFT", txt.frame, "BOTTOMLEFT", 0, -10)
|
yellowfive@57
|
92 bg:AddChild(btnImportOk)
|
yellowfive@57
|
93
|
yellowfive@57
|
94 local btnImportCancel = AceGUI:Create("AmrUiButton")
|
yellowfive@57
|
95 btnImportCancel:SetText(L.ImportButtonCancel)
|
yellowfive@57
|
96 btnImportCancel:SetBackgroundColor(Amr.Colors.Green)
|
yellowfive@57
|
97 btnImportCancel:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
|
yellowfive@57
|
98 btnImportCancel:SetWidth(120)
|
yellowfive@57
|
99 btnImportCancel:SetHeight(28)
|
yellowfive@57
|
100 btnImportCancel:SetPoint("LEFT", btnImportOk.frame, "RIGHT", 20, 0)
|
yellowfive@57
|
101 btnImportCancel:SetCallback("OnClick", function(widget) Amr:HideCover() end)
|
yellowfive@57
|
102 bg:AddChild(btnImportCancel)
|
yellowfive@57
|
103
|
yellowfive@57
|
104 local lblErr = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
105 lblErr:SetWidth(600)
|
yellowfive@57
|
106 lblErr:SetFont(Amr.CreateFont("Bold", 14, Amr.Colors.Red))
|
yellowfive@57
|
107 lblErr:SetText("")
|
yellowfive@57
|
108 lblErr:SetPoint("TOPLEFT", btnImportOk.frame, "BOTTOMLEFT", 0, -20)
|
yellowfive@57
|
109 bg:AddChild(lblErr)
|
yellowfive@57
|
110
|
yellowfive@57
|
111 btnImportOk:SetCallback("OnClick", function(widget)
|
yellowfive@57
|
112 local msg = txt:GetText()
|
yellowfive@57
|
113 local err = Amr:ImportRankings(msg)
|
yellowfive@57
|
114 if err then
|
yellowfive@57
|
115 lblErr:SetText(err)
|
yellowfive@57
|
116 txt:SetFocus(true)
|
yellowfive@57
|
117 else
|
yellowfive@57
|
118 Amr:HideCover()
|
yellowfive@57
|
119 Amr:RefreshTeamUi()
|
yellowfive@57
|
120 end
|
yellowfive@57
|
121 end)
|
yellowfive@57
|
122
|
yellowfive@57
|
123 return txt
|
yellowfive@57
|
124 end
|
yellowfive@57
|
125
|
yellowfive@57
|
126 local function renderVersionWindow(container)
|
yellowfive@57
|
127
|
yellowfive@57
|
128 local windowWidth = 500
|
yellowfive@57
|
129 local lbl, lbl2
|
yellowfive@57
|
130 local bg, border = Amr:RenderCoverChrome(container, windowWidth, 600)
|
yellowfive@57
|
131
|
yellowfive@57
|
132 lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
133 lbl:SetWidth(windowWidth - 60)
|
yellowfive@57
|
134 lbl:SetJustifyH("CENTER")
|
yellowfive@57
|
135 lbl:SetFont(Amr.CreateFont("Bold", 24, Amr.Colors.TextHeaderActive))
|
yellowfive@57
|
136 lbl:SetText(L.TeamVersionTitle)
|
yellowfive@57
|
137 lbl:SetPoint("TOP", bg.content, "TOP", 0, -10)
|
yellowfive@57
|
138 bg:AddChild(lbl)
|
yellowfive@57
|
139
|
yellowfive@57
|
140 if not IsInGroup() and not IsInRaid() then
|
yellowfive@57
|
141 lbl2 = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
142 lbl2:SetWidth(windowWidth - 20)
|
yellowfive@57
|
143 lbl2:SetJustifyH("CENTER")
|
yellowfive@57
|
144 lbl2:SetFont(Amr.CreateFont("Italic", 16, Amr.Colors.TextTan))
|
yellowfive@57
|
145 lbl2:SetText(L.TeamVersionNoGroup)
|
yellowfive@57
|
146 lbl2:SetPoint("TOP", lbl.frame, "BOTTOM", 0, -25)
|
yellowfive@57
|
147 bg:AddChild(lbl2)
|
yellowfive@57
|
148 border:SetHeight(150)
|
yellowfive@57
|
149 else
|
yellowfive@57
|
150 local units = Amr:GetGroupUnitIdentifiers()
|
yellowfive@57
|
151
|
yellowfive@57
|
152 local missing = {}
|
yellowfive@57
|
153 local tooLow = {}
|
yellowfive@57
|
154
|
yellowfive@57
|
155 for i, unitId in ipairs(units) do
|
yellowfive@57
|
156 local realm, name = Amr:GetRealmAndName(unitId)
|
yellowfive@57
|
157 if realm then
|
yellowfive@57
|
158 local ver = Amr:GetAddonVersion(realm, name)
|
yellowfive@57
|
159 if ver == 0 then
|
yellowfive@57
|
160 table.insert(missing, { unitId, realm, name })
|
yellowfive@57
|
161 elseif ver < Amr.MIN_ADDON_VERSION then
|
yellowfive@57
|
162 table.insert(tooLow, { unitId, realm, name, ver })
|
yellowfive@57
|
163 end
|
yellowfive@57
|
164 end
|
yellowfive@57
|
165 end
|
yellowfive@57
|
166
|
yellowfive@57
|
167 if #missing == 0 and #tooLow == 0 then
|
yellowfive@57
|
168 lbl2 = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
169 lbl2:SetWidth(windowWidth - 20)
|
yellowfive@57
|
170 lbl2:SetJustifyH("CENTER")
|
yellowfive@57
|
171 lbl2:SetFont(Amr.CreateFont("Italic", 16, Amr.Colors.TextTan))
|
yellowfive@57
|
172 lbl2:SetText(L.TeamVersionGood)
|
yellowfive@57
|
173 lbl2:SetPoint("TOP", lbl.frame, "BOTTOM", 0, -25)
|
yellowfive@57
|
174 bg:AddChild(lbl2)
|
yellowfive@57
|
175 border:SetHeight(150)
|
yellowfive@57
|
176 else
|
yellowfive@57
|
177 local prev = lbl
|
yellowfive@57
|
178 local h = 0
|
yellowfive@57
|
179
|
yellowfive@57
|
180 -- helper to render a player name
|
yellowfive@57
|
181 local function renderItem(obj, showVer)
|
yellowfive@57
|
182 lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
183 lbl:SetWidth(120)
|
yellowfive@57
|
184
|
yellowfive@57
|
185 local cls, clsEn = UnitClass(obj[1])
|
yellowfive@57
|
186 local color = clsEn and Amr.Colors.Classes[clsEn] or Amr.Colors.TextHeaderDisabled
|
yellowfive@57
|
187 lbl:SetFont(Amr.CreateFont("Regular", 14, color))
|
yellowfive@57
|
188
|
yellowfive@57
|
189 lbl:SetText(obj[3])
|
yellowfive@57
|
190 lbl:SetPoint("TOPLEFT", prev.frame, "BOTTOMLEFT", 0, -5)
|
yellowfive@57
|
191 bg:AddChild(lbl)
|
yellowfive@57
|
192 prev = lbl
|
yellowfive@57
|
193 h = h + lbl:GetHeight() + 5
|
yellowfive@57
|
194
|
yellowfive@57
|
195 if showVer then
|
yellowfive@57
|
196 lbl2 = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
197 lbl2:SetWidth(60)
|
yellowfive@57
|
198 lbl2:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.White))
|
yellowfive@57
|
199 lbl2:SetText("v" .. obj[4])
|
yellowfive@57
|
200 lbl2:SetPoint("LEFT", lbl.frame, "RIGHT", 5, 0)
|
yellowfive@57
|
201 bg:AddChild(lbl2)
|
yellowfive@57
|
202 end
|
yellowfive@57
|
203 end
|
yellowfive@57
|
204
|
yellowfive@57
|
205 if #missing > 0 then
|
yellowfive@57
|
206 lbl2 = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
207 lbl2:SetWidth(180)
|
yellowfive@57
|
208 lbl2:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.Red))
|
yellowfive@57
|
209 lbl2:SetText(L.TeamVersionMissing)
|
yellowfive@57
|
210 lbl2:SetJustifyH("CENTER")
|
yellowfive@57
|
211 lbl2:SetPoint("TOP", prev.frame, "BOTTOM", 0, -20)
|
yellowfive@57
|
212 bg:AddChild(lbl2)
|
yellowfive@57
|
213 h = h + lbl2:GetHeight() + 20
|
yellowfive@57
|
214
|
yellowfive@57
|
215 prev = lbl2
|
yellowfive@57
|
216 for i, obj in ipairs(missing) do
|
yellowfive@57
|
217 renderItem(obj)
|
yellowfive@57
|
218 end
|
yellowfive@57
|
219 end
|
yellowfive@57
|
220
|
yellowfive@57
|
221 if #tooLow > 0 then
|
yellowfive@57
|
222 lbl2 = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
223 lbl2:SetWidth(180)
|
yellowfive@57
|
224 lbl2:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.Gold))
|
yellowfive@57
|
225 lbl2:SetText(L.TeamVersionOld)
|
yellowfive@57
|
226 lbl2:SetJustifyH("CENTER")
|
yellowfive@57
|
227 lbl2:SetPoint("TOP", prev.frame, "BOTTOM", 0, -20)
|
yellowfive@57
|
228 bg:AddChild(lbl2)
|
yellowfive@57
|
229 h = h + lbl2:GetHeight() + 20
|
yellowfive@57
|
230
|
yellowfive@57
|
231 prev = lbl2
|
yellowfive@57
|
232 for i, obj in ipairs(tooLow) do
|
yellowfive@57
|
233 renderItem(obj, true)
|
yellowfive@57
|
234 end
|
yellowfive@57
|
235 end
|
yellowfive@57
|
236
|
yellowfive@57
|
237 border:SetHeight(h + 100)
|
yellowfive@57
|
238 end
|
yellowfive@57
|
239 end
|
yellowfive@57
|
240
|
yellowfive@57
|
241 local btn = AceGUI:Create("AmrUiButton")
|
yellowfive@57
|
242 btn:SetText(L.TeamButtonExportClose)
|
yellowfive@57
|
243 btn:SetBackgroundColor(Amr.Colors.Green)
|
yellowfive@57
|
244 btn:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
|
yellowfive@57
|
245 btn:SetWidth(120)
|
yellowfive@57
|
246 btn:SetHeight(28)
|
yellowfive@57
|
247 btn:SetPoint("BOTTOM", bg.content, "BOTTOM", 0, 10)
|
yellowfive@57
|
248 btn:SetCallback("OnClick", function(widget) Amr:HideCover() end)
|
yellowfive@57
|
249 bg:AddChild(btn)
|
yellowfive@57
|
250 end
|
yellowfive@57
|
251
|
yellowfive@57
|
252 local function onVersionClick()
|
yellowfive@57
|
253 -- show a window with players who do not have the addon or too low a version
|
yellowfive@57
|
254 Amr:ShowCover(renderVersionWindow)
|
yellowfive@57
|
255 end
|
yellowfive@57
|
256
|
yellowfive@57
|
257 local function onExportRosterClick()
|
yellowfive@57
|
258
|
yellowfive@57
|
259 Amr:ShowCover(L.TeamExportRosterLoading)
|
yellowfive@57
|
260
|
yellowfive@57
|
261 Amr:ExportRosterAsync(function(txt)
|
yellowfive@57
|
262 Amr:HideCover()
|
yellowfive@57
|
263
|
yellowfive@57
|
264 if not txt then
|
yellowfive@57
|
265 Amr:ShowAlert(L.TeamAlertNoGroup, L.AlertOk)
|
yellowfive@57
|
266 return
|
yellowfive@57
|
267 end
|
yellowfive@57
|
268
|
yellowfive@57
|
269 Amr:ShowCover(function(container)
|
yellowfive@57
|
270 local textbox = renderExportWindow(container, L.TeamExportRosterText, txt)
|
yellowfive@57
|
271 textbox:SetFocus(true)
|
yellowfive@57
|
272 end)
|
yellowfive@57
|
273 end)
|
yellowfive@57
|
274
|
yellowfive@57
|
275 end
|
yellowfive@57
|
276
|
yellowfive@57
|
277 local function onExportLootClick()
|
yellowfive@57
|
278
|
yellowfive@57
|
279 Amr:ShowCover(L.TeamExportRosterLoading)
|
yellowfive@57
|
280
|
yellowfive@57
|
281 Amr:ExportLootAsync(function(txt)
|
yellowfive@57
|
282 Amr:HideCover()
|
yellowfive@57
|
283
|
yellowfive@57
|
284 if txt == "NOGROUP" then
|
yellowfive@57
|
285 Amr:ShowAlert(L.TeamAlertNoGroup, L.AlertOk)
|
yellowfive@57
|
286 return
|
yellowfive@57
|
287 elseif txt == "NOLOOT" then
|
yellowfive@57
|
288 Amr:ShowAlert(L.TeamAlertNoLoot, L.AlertOk)
|
yellowfive@57
|
289 return
|
yellowfive@57
|
290 else
|
yellowfive@57
|
291 Amr:ShowCover(function(container)
|
yellowfive@57
|
292 local textbox = renderExportWindow(container, L.TeamExportLootText, txt)
|
yellowfive@57
|
293 textbox:SetFocus(true)
|
yellowfive@57
|
294 end)
|
yellowfive@57
|
295 end
|
yellowfive@57
|
296 end)
|
yellowfive@57
|
297 end
|
yellowfive@57
|
298
|
yellowfive@57
|
299 local function onImportRankingsClick()
|
yellowfive@57
|
300 Amr:ShowCover(function(container)
|
yellowfive@57
|
301 local textbox = renderImportWindow(container)
|
yellowfive@57
|
302 textbox:SetFocus(true)
|
yellowfive@57
|
303 end)
|
yellowfive@57
|
304 end
|
yellowfive@57
|
305
|
yellowfive@57
|
306 local function renderTab(tab, container)
|
yellowfive@57
|
307
|
yellowfive@57
|
308 local lbl, lbl2
|
yellowfive@57
|
309
|
yellowfive@57
|
310 if tab == "Member" then
|
yellowfive@57
|
311 local lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
312 lbl:SetWidth(500)
|
yellowfive@57
|
313 lbl:SetFont(Amr.CreateFont("Regular", 24, Amr.Colors.TextTan))
|
yellowfive@57
|
314 lbl:SetText(L.TeamMemberText)
|
yellowfive@57
|
315 lbl:SetPoint("TOPLEFT", container.content, "TOPLEFT", 0, -40)
|
yellowfive@57
|
316 container:AddChild(lbl)
|
yellowfive@57
|
317
|
yellowfive@57
|
318 -- if loot is still going on, show a button to re-show the loot window
|
yellowfive@57
|
319 if Amr.db.char.TeamOpt.LootInProgress then
|
yellowfive@57
|
320 lbl2 = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
321 lbl2:SetWidth(500)
|
yellowfive@57
|
322 lbl2:SetFont(Amr.CreateFont("Italic", 18, Amr.Colors.TextTan))
|
yellowfive@57
|
323 lbl2:SetText(L.TeamMemberShowLootLabel)
|
yellowfive@57
|
324 lbl2:SetPoint("TOPLEFT", lbl.frame, "BOTTOMLEFT", 0, -60)
|
yellowfive@57
|
325 container:AddChild(lbl2)
|
yellowfive@57
|
326
|
yellowfive@57
|
327 local btn = AceGUI:Create("AmrUiButton")
|
yellowfive@57
|
328 btn:SetWidth(180)
|
yellowfive@57
|
329 btn:SetHeight(26)
|
yellowfive@57
|
330 btn:SetBackgroundColor(Amr.Colors.Blue)
|
yellowfive@57
|
331 btn:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
|
yellowfive@57
|
332 btn:SetText(L.TeamMemberShowLoot)
|
yellowfive@57
|
333 btn:SetPoint("TOPLEFT", lbl2.frame, "BOTTOMLEFT", 0, -10)
|
yellowfive@57
|
334 btn:SetCallback("OnClick", function(widget)
|
yellowfive@57
|
335 Amr:ShowLootWindow()
|
yellowfive@57
|
336 Amr:RefreshLootWindow()
|
yellowfive@57
|
337 Amr:RefreshLootRolls()
|
yellowfive@57
|
338 end)
|
yellowfive@57
|
339 container:AddChild(btn)
|
yellowfive@57
|
340 end
|
yellowfive@57
|
341
|
yellowfive@57
|
342 elseif tab == "Leader" then
|
yellowfive@57
|
343
|
yellowfive@57
|
344 local lblNum = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
345 lblNum:SetFont(Amr.CreateFont("Bold", 26, Amr.Colors.White))
|
yellowfive@57
|
346 lblNum:SetText("0.")
|
yellowfive@57
|
347 lblNum:SetWidth(40)
|
yellowfive@57
|
348 lblNum:SetPoint("TOPLEFT", container.content, "TOPLEFT", 6, -40)
|
yellowfive@57
|
349 container:AddChild(lblNum)
|
yellowfive@57
|
350
|
yellowfive@57
|
351 local btnVersion = AceGUI:Create("AmrUiButton")
|
yellowfive@57
|
352 btnVersion:SetText(L.TeamButtonVersionText)
|
yellowfive@57
|
353 btnVersion:SetBackgroundColor(Amr.Colors.Orange)
|
yellowfive@57
|
354 btnVersion:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
|
yellowfive@57
|
355 btnVersion:SetWidth(180)
|
yellowfive@57
|
356 btnVersion:SetHeight(26)
|
yellowfive@57
|
357 btnVersion:SetPoint("LEFT", lblNum.frame, "RIGHT", 0, -1)
|
yellowfive@57
|
358 btnVersion:SetCallback("OnClick", onVersionClick)
|
yellowfive@57
|
359 container:AddChild(btnVersion)
|
yellowfive@57
|
360
|
yellowfive@57
|
361 lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
362 lbl:SetFont(Amr.CreateFont("Italic", 14, Amr.Colors.TextTan))
|
yellowfive@57
|
363 lbl:SetText(L.TeamExportVersionLabel)
|
yellowfive@57
|
364 lbl:SetWidth(400)
|
yellowfive@57
|
365 lbl:SetPoint("TOPLEFT", btnVersion.frame, "TOPRIGHT", 20, 0)
|
yellowfive@57
|
366 container:AddChild(lbl)
|
yellowfive@57
|
367
|
yellowfive@57
|
368 lblNum = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
369 lblNum:SetFont(Amr.CreateFont("Bold", 26, Amr.Colors.White))
|
yellowfive@57
|
370 lblNum:SetText("1.")
|
yellowfive@57
|
371 lblNum:SetWidth(40)
|
yellowfive@57
|
372 lblNum:SetPoint("TOPRIGHT", btnVersion.frame, "BOTTOMLEFT", 0, -39)
|
yellowfive@57
|
373 container:AddChild(lblNum)
|
yellowfive@57
|
374
|
yellowfive@57
|
375 local btnRoster = AceGUI:Create("AmrUiButton")
|
yellowfive@57
|
376 btnRoster:SetText(L.TeamButtonExportRosterText)
|
yellowfive@57
|
377 btnRoster:SetBackgroundColor(Amr.Colors.Orange)
|
yellowfive@57
|
378 btnRoster:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
|
yellowfive@57
|
379 btnRoster:SetWidth(180)
|
yellowfive@57
|
380 btnRoster:SetHeight(26)
|
yellowfive@57
|
381 btnRoster:SetPoint("LEFT", lblNum.frame, "RIGHT", 0, -1)
|
yellowfive@57
|
382 btnRoster:SetCallback("OnClick", onExportRosterClick)
|
yellowfive@57
|
383 container:AddChild(btnRoster)
|
yellowfive@57
|
384
|
yellowfive@57
|
385 lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
386 lbl:SetFont(Amr.CreateFont("Italic", 14, Amr.Colors.TextTan))
|
yellowfive@57
|
387 lbl:SetText(L.TeamExportRosterLabel)
|
yellowfive@57
|
388 lbl:SetWidth(400)
|
yellowfive@57
|
389 lbl:SetPoint("TOPLEFT", btnRoster.frame, "TOPRIGHT", 20, 0)
|
yellowfive@57
|
390 container:AddChild(lbl)
|
yellowfive@57
|
391
|
yellowfive@57
|
392 lblNum = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
393 lblNum:SetFont(Amr.CreateFont("Bold", 26, Amr.Colors.White))
|
yellowfive@57
|
394 lblNum:SetText("2.")
|
yellowfive@57
|
395 lblNum:SetWidth(40)
|
yellowfive@57
|
396 lblNum:SetPoint("TOPRIGHT", btnRoster.frame, "BOTTOMLEFT", 0, -89)
|
yellowfive@57
|
397 container:AddChild(lblNum)
|
yellowfive@57
|
398
|
yellowfive@57
|
399 local btnLoot = AceGUI:Create("AmrUiButton")
|
yellowfive@57
|
400 btnLoot:SetText(L.TeamButtonExportLootText)
|
yellowfive@57
|
401 btnLoot:SetBackgroundColor(Amr.Colors.Orange)
|
yellowfive@57
|
402 btnLoot:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
|
yellowfive@57
|
403 btnLoot:SetWidth(180)
|
yellowfive@57
|
404 btnLoot:SetHeight(26)
|
yellowfive@57
|
405 btnLoot:SetPoint("LEFT", lblNum.frame, "RIGHT", 0, -1)
|
yellowfive@57
|
406 btnLoot:SetCallback("OnClick", onExportLootClick)
|
yellowfive@57
|
407 container:AddChild(btnLoot)
|
yellowfive@57
|
408
|
yellowfive@57
|
409 lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
410 lbl:SetFont(Amr.CreateFont("Italic", 14, Amr.Colors.TextTan))
|
yellowfive@57
|
411 lbl:SetText(L.TeamExportLootLabel)
|
yellowfive@57
|
412 lbl:SetWidth(400)
|
yellowfive@57
|
413 lbl:SetPoint("TOPLEFT", btnLoot.frame, "TOPRIGHT", 20, 0)
|
yellowfive@57
|
414 container:AddChild(lbl)
|
yellowfive@57
|
415
|
yellowfive@57
|
416 lbl2 = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
417 lbl2:SetFont(Amr.CreateFont("Bold", 14, Amr.Colors.Blue))
|
yellowfive@57
|
418 lbl2:SetText(L.TeamExportLootLabel2)
|
yellowfive@57
|
419 lbl2:SetWidth(400)
|
yellowfive@57
|
420 lbl2:SetPoint("TOPLEFT", lbl.frame, "BOTTOMLEFT", 0, -5)
|
yellowfive@57
|
421 container:AddChild(lbl2)
|
yellowfive@57
|
422
|
yellowfive@57
|
423 lblNum = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
424 lblNum:SetFont(Amr.CreateFont("Bold", 26, Amr.Colors.White))
|
yellowfive@57
|
425 lblNum:SetText("3.")
|
yellowfive@57
|
426 lblNum:SetWidth(40)
|
yellowfive@57
|
427 lblNum:SetPoint("TOPRIGHT", btnLoot.frame, "BOTTOMLEFT", 0, -89)
|
yellowfive@57
|
428 container:AddChild(lblNum)
|
yellowfive@57
|
429
|
yellowfive@57
|
430 local btnRank = AceGUI:Create("AmrUiButton")
|
yellowfive@57
|
431 btnRank:SetText(L.TeamButtonImportRankingsText)
|
yellowfive@57
|
432 btnRank:SetBackgroundColor(Amr.Colors.Green)
|
yellowfive@57
|
433 btnRank:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
|
yellowfive@57
|
434 btnRank:SetWidth(180)
|
yellowfive@57
|
435 btnRank:SetHeight(26)
|
yellowfive@57
|
436 btnRank:SetPoint("LEFT", lblNum.frame, "RIGHT", 0, -1)
|
yellowfive@57
|
437 btnRank:SetCallback("OnClick", onImportRankingsClick)
|
yellowfive@57
|
438 container:AddChild(btnRank)
|
yellowfive@57
|
439
|
yellowfive@57
|
440 lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
441 lbl:SetFont(Amr.CreateFont("Italic", 14, Amr.Colors.TextTan))
|
yellowfive@57
|
442 lbl:SetText(L.TeamImportRankingsLabel)
|
yellowfive@57
|
443 lbl:SetWidth(400)
|
yellowfive@57
|
444 lbl:SetPoint("TOPLEFT", btnRank.frame, "TOPRIGHT", 20, 0)
|
yellowfive@57
|
445 container:AddChild(lbl)
|
yellowfive@57
|
446
|
yellowfive@57
|
447 _panelStartLoot = AceGUI:Create("AmrUiPanel")
|
yellowfive@57
|
448 _panelStartLoot:SetLayout("None")
|
yellowfive@57
|
449 _panelStartLoot:SetBackgroundColor(Amr.Colors.Black, 0)
|
yellowfive@57
|
450 _panelStartLoot:SetPoint("TOPLEFT", lblNum.frame, "BOTTOMLEFT", 0, -90)
|
yellowfive@57
|
451 container:AddChild(_panelStartLoot)
|
yellowfive@57
|
452 _panelStartLoot:SetVisible(false)
|
yellowfive@57
|
453
|
yellowfive@57
|
454 lblNum = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
455 lblNum:SetFont(Amr.CreateFont("Bold", 26, Amr.Colors.White))
|
yellowfive@57
|
456 lblNum:SetText("4.")
|
yellowfive@57
|
457 lblNum:SetWidth(40)
|
yellowfive@57
|
458 lblNum:SetPoint("TOPLEFT", _panelStartLoot.content, "TOPLEFT")
|
yellowfive@57
|
459 _panelStartLoot:AddChild(lblNum)
|
yellowfive@57
|
460
|
yellowfive@57
|
461 _btnStartLoot = AceGUI:Create("AmrUiButton")
|
yellowfive@57
|
462 _btnStartLoot:SetText(L.TeamButtonStartLootText)
|
yellowfive@57
|
463 _btnStartLoot:SetBackgroundColor(Amr.Colors.Blue)
|
yellowfive@57
|
464 _btnStartLoot:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
|
yellowfive@57
|
465 _btnStartLoot:SetWidth(180)
|
yellowfive@57
|
466 _btnStartLoot:SetHeight(26)
|
yellowfive@57
|
467 _btnStartLoot:SetPoint("LEFT", lblNum.frame, "RIGHT", 0, -1)
|
yellowfive@57
|
468 _btnStartLoot:SetCallback("OnClick", function(widget)
|
yellowfive@57
|
469 if Amr.db.char.TeamOpt.LootInProgress then
|
yellowfive@57
|
470 Amr:ShowLootWindow()
|
yellowfive@57
|
471 Amr:RefreshLootWindow()
|
yellowfive@57
|
472 Amr:RefreshLootRolls()
|
yellowfive@57
|
473 else
|
yellowfive@57
|
474 Amr:StartLoot()
|
yellowfive@57
|
475 end
|
yellowfive@57
|
476 end)
|
yellowfive@57
|
477 _panelStartLoot:AddChild(_btnStartLoot)
|
yellowfive@57
|
478
|
yellowfive@57
|
479 _lblStartLoot = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
480 _lblStartLoot:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.Text))
|
yellowfive@57
|
481 _lblStartLoot:SetWidth(400)
|
yellowfive@57
|
482 _lblStartLoot:SetPoint("LEFT", _btnStartLoot.frame, "RIGHT", 20, 0)
|
yellowfive@57
|
483 _panelStartLoot:AddChild(_lblStartLoot)
|
yellowfive@57
|
484 end
|
yellowfive@57
|
485
|
yellowfive@57
|
486 -- loot history shows on either tab
|
yellowfive@57
|
487 lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
488 lbl:SetFont(Amr.CreateFont("Regular", 16, Amr.Colors.TextTan))
|
yellowfive@57
|
489 lbl:SetText(L.TeamHistoryTitle)
|
yellowfive@57
|
490 lbl:SetWidth(280)
|
yellowfive@57
|
491 lbl:SetPoint("TOPRIGHT", container.content, "TOPRIGHT", 0, -12)
|
yellowfive@57
|
492 container:AddChild(lbl)
|
yellowfive@57
|
493
|
yellowfive@57
|
494 local panelHistory = AceGUI:Create("AmrUiPanel")
|
yellowfive@57
|
495 panelHistory:SetLayout("Fill")
|
yellowfive@57
|
496 panelHistory:SetBackgroundColor(Amr.Colors.Black, 0.3)
|
yellowfive@57
|
497 panelHistory:SetPoint("TOPRIGHT", lbl.frame, "BOTTOMRIGHT", 0, -5)
|
yellowfive@57
|
498 panelHistory:SetPoint("BOTTOMLEFT", container.content, "BOTTOMRIGHT", -280, 0)
|
yellowfive@57
|
499 container:AddChild(panelHistory)
|
yellowfive@57
|
500
|
yellowfive@57
|
501 _scrollHistory = AceGUI:Create("AmrUiScrollFrame")
|
yellowfive@57
|
502 _scrollHistory:SetLayout("List")
|
yellowfive@57
|
503 panelHistory:AddChild(_scrollHistory)
|
yellowfive@57
|
504 end
|
yellowfive@57
|
505
|
yellowfive@57
|
506 local function renderHistory()
|
yellowfive@57
|
507 if not _scrollHistory then return end
|
yellowfive@57
|
508 _scrollHistory:ReleaseChildren()
|
yellowfive@57
|
509
|
yellowfive@57
|
510 -- history is list of objects with:
|
yellowfive@57
|
511 -- link, result, class, name
|
yellowfive@57
|
512
|
yellowfive@57
|
513 local history = Amr.db.char.TeamOpt.History
|
yellowfive@57
|
514 local historyWidth = 260
|
yellowfive@57
|
515
|
yellowfive@57
|
516 local emptyMsg = nil
|
yellowfive@57
|
517 if not IsInGroup() and not IsInRaid() then
|
yellowfive@57
|
518 emptyMsg = L.TeamHistoryNoGroup
|
yellowfive@57
|
519 elseif not history or #history == 0 then
|
yellowfive@57
|
520 emptyMsg = L.TeamHistoryEmpty
|
yellowfive@57
|
521 end
|
yellowfive@57
|
522
|
yellowfive@57
|
523 if emptyMsg then
|
yellowfive@57
|
524 local panel = AceGUI:Create("AmrUiPanel")
|
yellowfive@57
|
525 panel:SetLayout("None")
|
yellowfive@57
|
526 panel:SetBackgroundColor(Amr.Colors.Black, 0)
|
yellowfive@57
|
527 panel:SetWidth(historyWidth)
|
yellowfive@57
|
528 panel:SetHeight(30)
|
yellowfive@57
|
529 _scrollHistory:AddChild(panel)
|
yellowfive@57
|
530
|
yellowfive@57
|
531 local lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
532 lbl:SetWidth(historyWidth)
|
yellowfive@57
|
533 lbl:SetJustifyH("CENTER")
|
yellowfive@57
|
534 lbl:SetFont(Amr.CreateFont("Italic", 14, Amr.Colors.TextTan))
|
yellowfive@57
|
535 lbl:SetText(emptyMsg)
|
yellowfive@57
|
536 lbl:SetPoint("LEFT", panel.content, "LEFT", 8, 0)
|
yellowfive@57
|
537 panel:AddChild(lbl)
|
yellowfive@57
|
538 else
|
yellowfive@57
|
539 for i = #history, 1, -1 do
|
yellowfive@57
|
540 local obj = history[i]
|
yellowfive@57
|
541 local itemLink = obj.link
|
yellowfive@57
|
542
|
yellowfive@57
|
543 local panel = AceGUI:Create("AmrUiPanel")
|
yellowfive@57
|
544 panel:SetLayout("None")
|
yellowfive@57
|
545 panel:SetBackgroundColor(Amr.Colors.Black, 0)
|
yellowfive@57
|
546 panel:SetWidth(historyWidth)
|
yellowfive@57
|
547 panel:SetHeight(45)
|
yellowfive@57
|
548 _scrollHistory:AddChild(panel)
|
yellowfive@57
|
549
|
yellowfive@57
|
550 local lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
551 lbl:SetWidth(historyWidth - 5)
|
yellowfive@57
|
552 lbl:SetWordWrap(false)
|
yellowfive@57
|
553 lbl:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.Text))
|
yellowfive@57
|
554 lbl:SetPoint("TOPLEFT", panel.content, "TOPLEFT", 5, -5)
|
yellowfive@57
|
555 panel:AddChild(lbl)
|
yellowfive@57
|
556
|
yellowfive@57
|
557 Amr.GetItemInfo(itemLink, function(obj, name, link)
|
yellowfive@57
|
558 -- set item name, tooltip
|
yellowfive@57
|
559 obj:SetText(link:gsub("%[", ""):gsub("%]", ""))
|
yellowfive@57
|
560 Amr:SetItemTooltip(obj, link, "ANCHOR_BOTTOMRIGHT", 0, obj.frame:GetHeight())
|
yellowfive@57
|
561 end, lbl)
|
yellowfive@57
|
562
|
yellowfive@57
|
563 lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
564 lbl:SetWidth(historyWidth - 5)
|
yellowfive@57
|
565 lbl:SetWordWrap(false)
|
yellowfive@57
|
566 lbl:SetFont(Amr.CreateFont("Italic", 12, Amr.Colors.White))
|
yellowfive@57
|
567
|
yellowfive@57
|
568 if obj.result == "Disenchant" then
|
yellowfive@57
|
569 lbl:SetFont(Amr.CreateFont("Italic", 12, Amr.Colors.TextHeaderDisabled))
|
yellowfive@57
|
570 lbl:SetText(L.TeamLootOptionDisenchant)
|
yellowfive@57
|
571 else
|
yellowfive@57
|
572 local color = obj.class and Amr.Colors.Classes[obj.class] or Amr.Colors.TextHeaderDisabled
|
yellowfive@57
|
573 lbl:SetText((obj.result == "??" and "" or L["TeamLootOption" .. obj.result] .. ": ") .."|c" .. Amr.ColorToHex(color, 1) .. obj.name .. "|r")
|
yellowfive@57
|
574 end
|
yellowfive@57
|
575
|
yellowfive@57
|
576 lbl:SetPoint("BOTTOMLEFT", panel.content, "BOTTOMLEFT", 5, 8)
|
yellowfive@57
|
577 panel:AddChild(lbl)
|
yellowfive@57
|
578
|
yellowfive@57
|
579 local line = AceGUI:Create("AmrUiPanel")
|
yellowfive@57
|
580 line:SetBackgroundColor(Amr.Colors.Black, 1)
|
yellowfive@57
|
581 line:SetWidth(historyWidth)
|
yellowfive@57
|
582 line:SetHeight(1)
|
yellowfive@57
|
583 line:SetPoint("BOTTOM", panel.content, "BOTTOM")
|
yellowfive@57
|
584 panel:AddChild(line)
|
yellowfive@57
|
585 end
|
yellowfive@57
|
586 end
|
yellowfive@57
|
587 end
|
yellowfive@57
|
588
|
yellowfive@57
|
589 local function onTabSelected(container, event, group)
|
yellowfive@57
|
590 container:ReleaseChildren()
|
yellowfive@57
|
591
|
yellowfive@57
|
592 -- clear references to tab elements
|
yellowfive@57
|
593 _panelStartLoot = nil
|
yellowfive@57
|
594 _lblStartLoot = nil
|
yellowfive@57
|
595 _btnStartLoot = nil
|
yellowfive@57
|
596 _scrollHistory = nil
|
yellowfive@57
|
597
|
yellowfive@57
|
598 Amr.db.char.TeamOpt.Role = group
|
yellowfive@57
|
599 renderTab(group, container)
|
yellowfive@57
|
600 Amr:RefreshTeamUi()
|
yellowfive@57
|
601 end
|
yellowfive@57
|
602
|
yellowfive@57
|
603 -- renders the main UI for the Team Optimizer tab
|
yellowfive@57
|
604 function Amr:RenderTabTeam(container)
|
yellowfive@57
|
605
|
yellowfive@57
|
606 -- splash screen to customize team optimizer ui for the user
|
yellowfive@57
|
607 if not Amr.db.char.TeamOpt.Role then
|
yellowfive@57
|
608 _panelSplash = AceGUI:Create("AmrUiPanel")
|
yellowfive@57
|
609 _panelSplash:SetLayout("None")
|
yellowfive@57
|
610 _panelSplash:SetBackgroundColor(Amr.Colors.Black, 0)
|
yellowfive@57
|
611 _panelSplash:SetPoint("TOPLEFT", container.content, "TOPLEFT")
|
yellowfive@57
|
612 _panelSplash:SetPoint("BOTTOMRIGHT", container.content, "BOTTOMRIGHT")
|
yellowfive@57
|
613 container:AddChild(_panelSplash)
|
yellowfive@57
|
614
|
yellowfive@57
|
615 local lblSplash = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
616 lblSplash:SetWidth(800)
|
yellowfive@57
|
617 lblSplash:SetJustifyH("CENTER")
|
yellowfive@57
|
618 lblSplash:SetFont(Amr.CreateFont("Regular", 24, Amr.Colors.Text))
|
yellowfive@57
|
619 lblSplash:SetText(L.TeamSplashHeader)
|
yellowfive@57
|
620 lblSplash:SetPoint("TOP", _panelSplash.content, "TOP", 0, -40)
|
yellowfive@57
|
621 _panelSplash:AddChild(lblSplash)
|
yellowfive@57
|
622
|
yellowfive@57
|
623 local btn = AceGUI:Create("AmrUiButton")
|
yellowfive@57
|
624 btn:SetText(L.TeamTabLeaderText)
|
yellowfive@57
|
625 btn:SetBackgroundColor(Amr.Colors.Orange)
|
yellowfive@57
|
626 btn:SetFont(Amr.CreateFont("Bold", 24, Amr.Colors.White))
|
yellowfive@57
|
627 btn:SetWidth(280)
|
yellowfive@57
|
628 btn:SetHeight(60)
|
yellowfive@57
|
629 btn:SetPoint("TOPRIGHT", lblSplash.frame, "BOTTOM", -50, -50)
|
yellowfive@57
|
630 btn:SetCallback("OnClick", function(widget)
|
yellowfive@57
|
631 Amr.db.char.TeamOpt.Role = "Leader"
|
yellowfive@57
|
632 _panelSplash:SetVisible(false)
|
yellowfive@57
|
633 _tabs:SetVisible(true)
|
yellowfive@57
|
634 _tabs:SelectTab("Leader")
|
yellowfive@57
|
635 end)
|
yellowfive@57
|
636 _panelSplash:AddChild(btn)
|
yellowfive@57
|
637
|
yellowfive@57
|
638 local lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
639 lbl:SetWidth(280)
|
yellowfive@57
|
640 lbl:SetJustifyH("CENTER")
|
yellowfive@57
|
641 lbl:SetFont(Amr.CreateFont("Italic", 16, Amr.Colors.TextTan))
|
yellowfive@57
|
642 lbl:SetText(L.TeamSplashLeaderLabel)
|
yellowfive@57
|
643 lbl:SetPoint("TOP", btn.frame, "BOTTOM", 0, -20)
|
yellowfive@57
|
644 _panelSplash:AddChild(lbl)
|
yellowfive@57
|
645
|
yellowfive@57
|
646 btn = AceGUI:Create("AmrUiButton")
|
yellowfive@57
|
647 btn:SetText(L.TeamTabMemberText)
|
yellowfive@57
|
648 btn:SetBackgroundColor(Amr.Colors.Orange)
|
yellowfive@57
|
649 btn:SetFont(Amr.CreateFont("Bold", 24, Amr.Colors.White))
|
yellowfive@57
|
650 btn:SetWidth(280)
|
yellowfive@57
|
651 btn:SetHeight(60)
|
yellowfive@57
|
652 btn:SetPoint("TOPLEFT", lblSplash.frame, "BOTTOM", 50, -50)
|
yellowfive@57
|
653 btn:SetCallback("OnClick", function(widget)
|
yellowfive@57
|
654 Amr.db.char.TeamOpt.Role = "Member"
|
yellowfive@57
|
655 _panelSplash:SetVisible(false)
|
yellowfive@57
|
656 _tabs:SetVisible(true)
|
yellowfive@57
|
657 _tabs:SelectTab("Member")
|
yellowfive@57
|
658 end)
|
yellowfive@57
|
659 _panelSplash:AddChild(btn)
|
yellowfive@57
|
660
|
yellowfive@57
|
661 lbl = AceGUI:Create("AmrUiLabel")
|
yellowfive@57
|
662 lbl:SetWidth(280)
|
yellowfive@57
|
663 lbl:SetJustifyH("CENTER")
|
yellowfive@57
|
664 lbl:SetFont(Amr.CreateFont("Italic", 16, Amr.Colors.TextTan))
|
yellowfive@57
|
665 lbl:SetText(L.TeamSplashMemberLabel)
|
yellowfive@57
|
666 lbl:SetPoint("TOP", btn.frame, "BOTTOM", 0, -20)
|
yellowfive@57
|
667 _panelSplash:AddChild(lbl)
|
yellowfive@57
|
668 end
|
yellowfive@57
|
669
|
yellowfive@57
|
670 -- tabstrip
|
yellowfive@57
|
671 _tabs = AceGUI:Create("AmrUiTabGroup")
|
yellowfive@57
|
672 _tabs:SetLayout("None")
|
yellowfive@57
|
673 _tabs:SetTabs({
|
yellowfive@57
|
674 {text=L.TeamTabLeaderText, value="Leader", style="bold"},
|
yellowfive@57
|
675 {text=L.TeamTabMemberText, value="Member", style="bold"}
|
yellowfive@57
|
676 })
|
yellowfive@57
|
677 _tabs:SetPoint("TOPLEFT", container.content, "TOPLEFT", 6, -30)
|
yellowfive@57
|
678 _tabs:SetPoint("BOTTOMRIGHT", container.content, "BOTTOMRIGHT")
|
yellowfive@57
|
679 _tabs:SetCallback("OnGroupSelected", onTabSelected)
|
yellowfive@57
|
680 container:AddChild(_tabs)
|
yellowfive@57
|
681
|
yellowfive@57
|
682 local role = Amr.db.char.TeamOpt.Role
|
yellowfive@57
|
683
|
yellowfive@57
|
684 _tabs:SetVisible(not not role)
|
yellowfive@57
|
685 if role then
|
yellowfive@57
|
686 -- if a role has been chosen, select the proper tab (which will also refresh the UI)
|
yellowfive@57
|
687 _tabs:SelectTab(role)
|
yellowfive@57
|
688 else
|
yellowfive@57
|
689 -- no role, refresh the UI manually
|
yellowfive@57
|
690 self:RefreshTeamUi()
|
yellowfive@57
|
691 end
|
yellowfive@57
|
692
|
yellowfive@57
|
693 end
|
yellowfive@57
|
694
|
yellowfive@57
|
695 function Amr:ReleaseTabTeam()
|
yellowfive@57
|
696 _panelSplash = nil
|
yellowfive@57
|
697 _panelStartLoot = nil
|
yellowfive@57
|
698 _lblStartLoot = nil
|
yellowfive@57
|
699 _btnStartLoot = nil
|
yellowfive@57
|
700 _scrollHistory = nil
|
yellowfive@57
|
701 _tabs = nil
|
yellowfive@57
|
702 end
|
yellowfive@57
|
703
|
yellowfive@57
|
704 function Amr:RefreshTeamUi()
|
yellowfive@57
|
705
|
yellowfive@57
|
706 -- if rankings have been loaded, render the 'start loot' panel
|
yellowfive@57
|
707 if _panelStartLoot then
|
yellowfive@57
|
708 local rankString = Amr.db.global.TeamOpt.RankingString
|
yellowfive@57
|
709 if rankString then
|
yellowfive@57
|
710 _panelStartLoot:SetVisible(true)
|
yellowfive@57
|
711 _lblStartLoot:SetText(L.TeamStartLootLabel(#Amr.db.global.TeamOpt.Rankings))
|
yellowfive@57
|
712 _btnStartLoot:SetText(Amr.db.char.TeamOpt.LootInProgress and L.TeamButtonResumeLootText or L.TeamButtonStartLootText)
|
yellowfive@57
|
713 else
|
yellowfive@57
|
714 _panelStartLoot:SetVisible(false)
|
yellowfive@57
|
715 end
|
yellowfive@57
|
716 end
|
yellowfive@57
|
717
|
yellowfive@57
|
718 -- render loot history
|
yellowfive@57
|
719 renderHistory()
|
yellowfive@57
|
720 end
|
yellowfive@57
|
721
|
yellowfive@57
|
722 local function getItemIdsFromLinks(all, list)
|
yellowfive@57
|
723 for i, v in ipairs(list) do
|
yellowfive@57
|
724 local obj = Amr.ParseItemLink(v)
|
yellowfive@57
|
725 local id = Amr.GetItemUniqueId(obj)
|
yellowfive@57
|
726 if id then
|
yellowfive@57
|
727 table.insert(all, id)
|
yellowfive@57
|
728 end
|
yellowfive@57
|
729 end
|
yellowfive@57
|
730 end
|
yellowfive@57
|
731
|
yellowfive@57
|
732 -- update AllItems, used to determine when a new item is actually a new equippable item
|
yellowfive@57
|
733 local function snapshotAllItems(data)
|
yellowfive@57
|
734
|
yellowfive@57
|
735 local all = {}
|
yellowfive@57
|
736 for k, v in pairs(data.Equipped[data.ActiveSpec]) do
|
yellowfive@57
|
737 local obj = Amr.ParseItemLink(v)
|
yellowfive@57
|
738 local id = Amr.GetItemUniqueId(obj)
|
yellowfive@57
|
739 if id then
|
yellowfive@57
|
740 table.insert(all, id)
|
yellowfive@57
|
741 end
|
yellowfive@57
|
742 end
|
yellowfive@57
|
743 getItemIdsFromLinks(all, data.BagItems)
|
yellowfive@57
|
744 getItemIdsFromLinks(all, data.BankItems)
|
yellowfive@57
|
745 getItemIdsFromLinks(all, data.VoidItems)
|
yellowfive@57
|
746
|
yellowfive@57
|
747 table.sort(all)
|
yellowfive@57
|
748 return all
|
yellowfive@57
|
749 end
|
yellowfive@57
|
750
|
yellowfive@57
|
751 local function sendGear(prefix, empty)
|
yellowfive@57
|
752
|
yellowfive@57
|
753 local region = Amr.RegionNames[GetCurrentRegion()]
|
yellowfive@57
|
754 local realm = GetRealmName()
|
yellowfive@57
|
755 local name = UnitName("player")
|
yellowfive@57
|
756
|
yellowfive@57
|
757 -- get all data, including inventory
|
yellowfive@57
|
758 local txt = "_"
|
yellowfive@57
|
759 if not empty then
|
yellowfive@57
|
760 local data = Amr:ExportCharacter()
|
yellowfive@57
|
761 txt = Amr.Serializer:SerializePlayerData(data, true)
|
yellowfive@57
|
762
|
yellowfive@57
|
763 -- snapshot items when gear is sent
|
yellowfive@57
|
764 Amr.db.char.TeamOpt.AllItems = snapshotAllItems(data)
|
yellowfive@57
|
765 end
|
yellowfive@57
|
766
|
yellowfive@57
|
767 local msg = string.format("%s\n%s\n%s\n%s\n%s", prefix, region, realm, name, txt)
|
yellowfive@57
|
768 Amr:SendAmrCommMessage(msg)
|
yellowfive@57
|
769 end
|
yellowfive@57
|
770
|
yellowfive@57
|
771 local function toPlayerKey(realm, name)
|
yellowfive@57
|
772 return name .. "-" .. realm
|
yellowfive@57
|
773 end
|
yellowfive@57
|
774
|
yellowfive@57
|
775
|
yellowfive@57
|
776 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
777 -- Loot Export
|
yellowfive@57
|
778 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
779
|
yellowfive@57
|
780 -- prune out any characters no longer in the player's group
|
yellowfive@57
|
781 local function pruneGearForItemExport()
|
yellowfive@57
|
782
|
yellowfive@57
|
783 local newInfo = {}
|
yellowfive@57
|
784 local units = Amr:GetGroupUnitIdentifiers()
|
yellowfive@57
|
785
|
yellowfive@57
|
786 for i, unitId in ipairs(units) do
|
yellowfive@57
|
787 local realm, name = Amr:GetRealmAndName(unitId)
|
yellowfive@57
|
788 if realm then
|
yellowfive@57
|
789 local key = toPlayerKey(realm, name)
|
yellowfive@57
|
790 newInfo[key] = Amr.db.global.TeamOpt.LootGear[key]
|
yellowfive@57
|
791 end
|
yellowfive@57
|
792 end
|
yellowfive@57
|
793
|
yellowfive@57
|
794 Amr.db.global.TeamOpt.LootGear = newInfo
|
yellowfive@57
|
795 end
|
yellowfive@57
|
796
|
yellowfive@96
|
797 local _ignoreLoot = {
|
yellowfive@96
|
798 [139562] = true,
|
yellowfive@96
|
799 [136903] = true
|
yellowfive@96
|
800 }
|
yellowfive@96
|
801
|
yellowfive@57
|
802 local function scanMasterLoot()
|
yellowfive@57
|
803 -- only care if we are in a raid or group
|
yellowfive@57
|
804 if not IsInGroup() and not IsInRaid() then return end
|
yellowfive@57
|
805
|
yellowfive@57
|
806 -- we only care about the master looter
|
yellowfive@57
|
807 if not IsMasterLooter() then return end
|
yellowfive@57
|
808
|
yellowfive@57
|
809 -- guid of the unit being looted
|
yellowfive@57
|
810 local npcGuid = UnitGUID("target")
|
yellowfive@57
|
811 if not npcGuid then
|
yellowfive@57
|
812 -- this could wack shit out... but no raid bosses drop loot from containers right now, so should be fine
|
yellowfive@57
|
813 npcGuid = "container"
|
yellowfive@57
|
814 end
|
yellowfive@57
|
815
|
yellowfive@57
|
816 -- if we already have loot data for this unit, then we can ignore
|
yellowfive@57
|
817 if Amr.db.char.TeamOpt.LootGuid == npcGuid then return end
|
yellowfive@57
|
818
|
yellowfive@57
|
819 local loot = {}
|
yellowfive@57
|
820 for i = 1, GetNumLootItems() do
|
yellowfive@57
|
821 --local texture, item, quantity, quality, locked = GetLootSlotInfo(i)
|
yellowfive@57
|
822 local lootType = GetLootSlotType(i)
|
yellowfive@57
|
823 if lootType == 1 then
|
yellowfive@57
|
824 local link = GetLootSlotLink(i)
|
yellowfive@96
|
825 local success, itemObj = pcall(Amr.ParseItemLink, link)
|
yellowfive@96
|
826
|
yellowfive@96
|
827 if not success or not itemObj or _ignoreLoot[itemObj.id] then
|
yellowfive@96
|
828 -- ignore items that can't be read or that we explicitly don't care about
|
yellowfive@96
|
829 else
|
yellowfive@96
|
830 table.insert(loot, link)
|
yellowfive@96
|
831 end
|
yellowfive@57
|
832 end
|
yellowfive@57
|
833 end
|
yellowfive@57
|
834
|
yellowfive@57
|
835 Amr.db.char.TeamOpt.LootGuid = npcGuid
|
yellowfive@57
|
836 Amr.db.char.TeamOpt.Loot = loot
|
yellowfive@57
|
837
|
yellowfive@57
|
838 -- publish loot information to everyone else running the addon in case team optimizer user is not the master looter
|
yellowfive@57
|
839 local msg = _messagePrefixes.ItemExportLoot .. "\n" .. npcGuid .. "\n" .. table.concat(loot, "\n")
|
yellowfive@57
|
840 Amr:SendAmrCommMessage(msg)
|
yellowfive@57
|
841 end
|
yellowfive@57
|
842
|
yellowfive@57
|
843 local function onLootReceived(parts)
|
yellowfive@57
|
844
|
yellowfive@57
|
845 Amr.db.char.TeamOpt.LootGuid = parts[2]
|
yellowfive@57
|
846
|
yellowfive@57
|
847 local loot = {}
|
yellowfive@57
|
848 for i = 3, #parts do
|
yellowfive@57
|
849 table.insert(loot, parts[i])
|
yellowfive@57
|
850 end
|
yellowfive@57
|
851 Amr.db.char.TeamOpt.Loot = loot
|
yellowfive@57
|
852 end
|
yellowfive@57
|
853
|
yellowfive@57
|
854 local function onLeaveGroup()
|
yellowfive@57
|
855 -- if the current player is no longer in a group or raid, finish any looting in progress
|
yellowfive@57
|
856 Amr:FinishLoot(true)
|
yellowfive@57
|
857
|
yellowfive@57
|
858 -- clear loot when leave a group
|
yellowfive@57
|
859 Amr.db.char.TeamOpt.Loot = {}
|
yellowfive@57
|
860 Amr.db.char.TeamOpt.LootGuid = nil
|
yellowfive@57
|
861 Amr.db.global.TeamOpt.LootGear = {}
|
yellowfive@57
|
862 end
|
yellowfive@57
|
863
|
yellowfive@57
|
864 local function onGroupChanged()
|
yellowfive@57
|
865
|
yellowfive@57
|
866 if not IsInGroup() and not IsInRaid() then
|
yellowfive@57
|
867 onLeaveGroup()
|
yellowfive@57
|
868 end
|
yellowfive@57
|
869 end
|
yellowfive@57
|
870
|
yellowfive@57
|
871
|
yellowfive@57
|
872 local _lootExPlayersRemaining = 0
|
yellowfive@57
|
873 local _lootExRoster = nil
|
yellowfive@57
|
874 local _lootExCallback = nil
|
yellowfive@57
|
875
|
yellowfive@57
|
876 local function serializeLootExport()
|
yellowfive@57
|
877 if not IsInGroup() and not IsInRaid() then return "NOGROUP" end
|
yellowfive@57
|
878
|
yellowfive@57
|
879 local loot = Amr.db.char.TeamOpt.Loot
|
yellowfive@57
|
880 if not loot or #loot == 0 then return "NOLOOT" end
|
yellowfive@57
|
881
|
yellowfive@57
|
882 local itemObjects = {}
|
yellowfive@57
|
883 for i, link in ipairs(loot) do
|
yellowfive@57
|
884 local obj = Amr.ParseItemLink(link)
|
yellowfive@57
|
885 if obj then
|
yellowfive@57
|
886 table.insert(itemObjects, obj)
|
yellowfive@57
|
887 end
|
yellowfive@57
|
888 end
|
yellowfive@57
|
889
|
yellowfive@57
|
890 -- DEBUG: just grab all currently equipped items
|
yellowfive@57
|
891 --[[
|
yellowfive@57
|
892 itemObjects = {}
|
yellowfive@57
|
893 local blah = Amr:ExportCharacter()
|
yellowfive@57
|
894 for k, v in pairs(blah.Equipped[blah.ActiveSpec]) do
|
yellowfive@57
|
895 local obj = Amr.ParseItemLink(v)
|
yellowfive@57
|
896 if obj then
|
yellowfive@57
|
897 table.insert(itemObjects, obj)
|
yellowfive@57
|
898 end
|
yellowfive@57
|
899 end
|
yellowfive@57
|
900 ]]
|
yellowfive@57
|
901
|
yellowfive@57
|
902 local parts = {}
|
yellowfive@57
|
903
|
yellowfive@57
|
904 -- unique ids of items
|
yellowfive@57
|
905 local lootPart = {}
|
yellowfive@57
|
906 for i, obj in ipairs(itemObjects) do
|
yellowfive@57
|
907 table.insert(lootPart, Amr.GetItemUniqueId(obj))
|
yellowfive@57
|
908 end
|
yellowfive@57
|
909 table.insert(parts, table.concat(lootPart, ";"))
|
yellowfive@57
|
910
|
yellowfive@57
|
911 -- gear for players who have gained loot since the last item import or roster export
|
yellowfive@57
|
912 pruneGearForItemExport()
|
yellowfive@57
|
913 local lootGear = Amr.db.global.TeamOpt.LootGear
|
yellowfive@57
|
914 for k, v in pairs(lootGear) do
|
yellowfive@57
|
915 table.insert(parts, v)
|
yellowfive@57
|
916 end
|
yellowfive@57
|
917
|
yellowfive@57
|
918 return table.concat(parts, "\n")
|
yellowfive@57
|
919 end
|
yellowfive@57
|
920
|
yellowfive@57
|
921 local function onLootExportCompleted()
|
yellowfive@57
|
922
|
yellowfive@57
|
923 -- fill in LootGear with just those players who have changed
|
yellowfive@57
|
924 Amr.db.global.TeamOpt.LootGear = _lootExRoster
|
yellowfive@57
|
925
|
yellowfive@57
|
926 if _lootExCallback then
|
yellowfive@57
|
927 local txt = serializeLootExport()
|
yellowfive@57
|
928 _lootExCallback(txt)
|
yellowfive@57
|
929 end
|
yellowfive@57
|
930
|
yellowfive@57
|
931 -- reset state
|
yellowfive@57
|
932 _lootExPlayersRemaining = 0
|
yellowfive@57
|
933 _lootExRoster = nil
|
yellowfive@57
|
934 _lootExCallback = nil
|
yellowfive@57
|
935 end
|
yellowfive@57
|
936
|
yellowfive@57
|
937 -- called when this player's gear info has been requested by someone exporting loot
|
yellowfive@57
|
938 local function onGearForLootExportRequested()
|
yellowfive@57
|
939
|
yellowfive@57
|
940 local hasNewItem = false
|
yellowfive@57
|
941 local oldItems = Amr.db.char.TeamOpt.AllItems
|
yellowfive@57
|
942
|
yellowfive@57
|
943 if oldItems and #oldItems > 0 then
|
yellowfive@57
|
944 -- see if any new equippable items have been gained by comparing to the last snapshot
|
yellowfive@57
|
945 local data = Amr:ExportCharacter()
|
yellowfive@57
|
946 local allItems = snapshotAllItems(data)
|
yellowfive@57
|
947
|
yellowfive@57
|
948 if #oldItems ~= #allItems then
|
yellowfive@57
|
949 hasNewItem = true
|
yellowfive@57
|
950 else
|
yellowfive@57
|
951 -- go through items from front to back, if there are any that don't match then something has changed
|
yellowfive@57
|
952 for i = 1, #allItems do
|
yellowfive@57
|
953 local oldItem = oldItems[i]
|
yellowfive@57
|
954 local newItem = allItems[i]
|
yellowfive@57
|
955 if oldItem ~= newItem then
|
yellowfive@57
|
956 hasNewItem = true
|
yellowfive@57
|
957 break
|
yellowfive@57
|
958 end
|
yellowfive@57
|
959 end
|
yellowfive@57
|
960 end
|
yellowfive@57
|
961 end
|
yellowfive@57
|
962
|
yellowfive@57
|
963 -- whenever a new item is received, send out updated gear information that should be added to the next item export
|
yellowfive@57
|
964 sendGear(_messagePrefixes.ItemExportGear, not hasNewItem)
|
yellowfive@57
|
965 end
|
yellowfive@57
|
966
|
yellowfive@57
|
967 local function onGearForLootExportReceived(region, realm, name, data)
|
yellowfive@57
|
968 -- if I am not listening for incoming gear data for an item export, then ignore this message
|
yellowfive@57
|
969 if _lootExPlayersRemaining == 0 then return end
|
yellowfive@57
|
970
|
yellowfive@57
|
971 local key = toPlayerKey(realm, name)
|
yellowfive@57
|
972 if not data or data == "_" then
|
yellowfive@57
|
973 _lootExRoster[key] = nil
|
yellowfive@57
|
974 else
|
yellowfive@57
|
975 _lootExRoster[key] = data
|
yellowfive@57
|
976 end
|
yellowfive@57
|
977
|
yellowfive@57
|
978 _lootExPlayersRemaining = _lootExPlayersRemaining - 1
|
yellowfive@57
|
979 if _lootExPlayersRemaining <= 0 then
|
yellowfive@57
|
980 onLootExportCompleted()
|
yellowfive@57
|
981 end
|
yellowfive@57
|
982 end
|
yellowfive@57
|
983
|
yellowfive@57
|
984 -- Export the current loot, including any known gear data for players with the in-game addon, but only if it has changed since the last snapshot.
|
yellowfive@57
|
985 -- This is asynchronous because it needs to wait for gear data to arrive from each player.
|
yellowfive@57
|
986 function Amr:ExportLootAsync(callback)
|
yellowfive@57
|
987
|
yellowfive@57
|
988 if not IsInGroup() and not IsInRaid() then
|
yellowfive@57
|
989 callback("NOGROUP")
|
yellowfive@57
|
990 end
|
yellowfive@57
|
991
|
yellowfive@57
|
992 local loot = Amr.db.char.TeamOpt.Loot
|
yellowfive@57
|
993 if not loot or #loot == 0 then
|
yellowfive@57
|
994 callback("NOLOOT")
|
yellowfive@57
|
995 end
|
yellowfive@57
|
996
|
yellowfive@57
|
997 local playersNoGear = {}
|
yellowfive@57
|
998 _lootExPlayersRemaining = 0
|
yellowfive@57
|
999
|
yellowfive@57
|
1000 local units = self:GetGroupUnitIdentifiers()
|
yellowfive@57
|
1001 for i, unitId in ipairs(units) do
|
yellowfive@57
|
1002 local realm, name = self:GetRealmAndName(unitId)
|
yellowfive@57
|
1003 if realm then
|
yellowfive@57
|
1004 local ver = self:GetAddonVersion(realm, name)
|
yellowfive@57
|
1005 local key = toPlayerKey(realm, name)
|
yellowfive@57
|
1006
|
yellowfive@57
|
1007 if ver >= Amr.MIN_ADDON_VERSION then
|
yellowfive@57
|
1008 _lootExPlayersRemaining = _lootExPlayersRemaining + 1
|
yellowfive@57
|
1009 else
|
yellowfive@57
|
1010 table.insert(playersNoGear, unitId)
|
yellowfive@57
|
1011 end
|
yellowfive@57
|
1012 end
|
yellowfive@57
|
1013 end
|
yellowfive@57
|
1014
|
yellowfive@57
|
1015 _lootExRoster = {}
|
yellowfive@57
|
1016 _lootExCallback = callback
|
yellowfive@57
|
1017
|
yellowfive@57
|
1018 if _lootExPlayersRemaining > 0 then
|
yellowfive@57
|
1019 -- send a message to receive player data, when the last player is received onLootExportCompleted will be called
|
yellowfive@57
|
1020 Amr:SendAmrCommMessage(_messagePrefixes.ItemExportRequestGear)
|
yellowfive@57
|
1021 else
|
yellowfive@57
|
1022 -- don't need to wait for anybody, just call immediately
|
yellowfive@57
|
1023 onLootExportCompleted()
|
yellowfive@57
|
1024 end
|
yellowfive@57
|
1025 end
|
yellowfive@57
|
1026
|
yellowfive@57
|
1027
|
yellowfive@57
|
1028 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1029 -- Roster Export
|
yellowfive@57
|
1030 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1031
|
yellowfive@57
|
1032 local _rosterPlayersRemaining = 0
|
yellowfive@57
|
1033 local _roster = nil
|
yellowfive@57
|
1034 local _rosterCallback = nil
|
yellowfive@57
|
1035
|
yellowfive@57
|
1036 local function onRosterCompleted()
|
yellowfive@57
|
1037
|
yellowfive@57
|
1038 if _rosterCallback then
|
yellowfive@57
|
1039 -- serialize the roster
|
yellowfive@57
|
1040 local parts = {}
|
yellowfive@57
|
1041 for key, data in pairs(_roster) do
|
yellowfive@57
|
1042 table.insert(parts, data)
|
yellowfive@57
|
1043 end
|
yellowfive@57
|
1044 local msg = table.concat(parts, "\n")
|
yellowfive@57
|
1045
|
yellowfive@57
|
1046 -- send to callback
|
yellowfive@57
|
1047 _rosterCallback(msg)
|
yellowfive@57
|
1048 end
|
yellowfive@57
|
1049
|
yellowfive@57
|
1050 -- reset state
|
yellowfive@57
|
1051 _rosterPlayersRemaining = 0
|
yellowfive@57
|
1052 _roster = nil
|
yellowfive@57
|
1053 _rosterCallback = nil
|
yellowfive@57
|
1054
|
yellowfive@57
|
1055 -- clear out loot gear needed, an export will refresh everyone at the time of export
|
yellowfive@57
|
1056 Amr.db.global.TeamOpt.LootGear = {}
|
yellowfive@57
|
1057 end
|
yellowfive@57
|
1058
|
yellowfive@57
|
1059 -- called when this player's gear info has been requested by someone exporting the raid roster
|
yellowfive@57
|
1060 local function onGearForRosterRequested()
|
yellowfive@57
|
1061
|
yellowfive@57
|
1062 sendGear(_messagePrefixes.RosterGear)
|
yellowfive@57
|
1063 end
|
yellowfive@57
|
1064
|
yellowfive@57
|
1065 local function onGearForRosterReceived(region, realm, name, data)
|
yellowfive@57
|
1066 -- if I am not listening for incoming gear data for the roster, then ignore this message
|
yellowfive@57
|
1067 if _rosterPlayersRemaining == 0 then return end
|
yellowfive@57
|
1068
|
yellowfive@57
|
1069 local key = toPlayerKey(realm, name)
|
yellowfive@57
|
1070 _roster[key] = data
|
yellowfive@57
|
1071
|
yellowfive@57
|
1072 _rosterPlayersRemaining = _rosterPlayersRemaining - 1
|
yellowfive@57
|
1073 if _rosterPlayersRemaining <= 0 then
|
yellowfive@57
|
1074 onRosterCompleted()
|
yellowfive@57
|
1075 end
|
yellowfive@57
|
1076 end
|
yellowfive@57
|
1077
|
yellowfive@57
|
1078 -- Export the current roster, including any known gear data for players with the in-game addon.
|
yellowfive@57
|
1079 -- This is asynchronous because it needs to wait for gear data to arrive from each player.
|
yellowfive@57
|
1080 function Amr:ExportRosterAsync(callback)
|
yellowfive@57
|
1081 if not IsInGroup() and not IsInRaid() then
|
yellowfive@57
|
1082 callback()
|
yellowfive@57
|
1083 return
|
yellowfive@57
|
1084 end
|
yellowfive@57
|
1085
|
yellowfive@57
|
1086 local playersNoGear = {}
|
yellowfive@57
|
1087 _rosterPlayersRemaining = 0
|
yellowfive@57
|
1088
|
yellowfive@57
|
1089 local units = self:GetGroupUnitIdentifiers()
|
yellowfive@57
|
1090 for i, unitId in ipairs(units) do
|
yellowfive@57
|
1091 local realm, name = self:GetRealmAndName(unitId)
|
yellowfive@57
|
1092 if realm then
|
yellowfive@57
|
1093 local ver = self:GetAddonVersion(realm, name)
|
yellowfive@57
|
1094 local key = toPlayerKey(realm, name)
|
yellowfive@57
|
1095
|
yellowfive@57
|
1096 if ver >= Amr.MIN_ADDON_VERSION then
|
yellowfive@57
|
1097 _rosterPlayersRemaining = _rosterPlayersRemaining + 1
|
yellowfive@57
|
1098 else
|
yellowfive@57
|
1099 table.insert(playersNoGear, unitId)
|
yellowfive@57
|
1100 end
|
yellowfive@57
|
1101 end
|
yellowfive@57
|
1102 end
|
yellowfive@57
|
1103
|
yellowfive@57
|
1104 -- fill the roster with any players who can't send us data
|
yellowfive@57
|
1105 _roster = {}
|
yellowfive@57
|
1106 for i, unitId in ipairs(playersNoGear) do
|
yellowfive@57
|
1107 local realm, name = self:GetRealmAndName(unitId)
|
yellowfive@57
|
1108 if realm then
|
yellowfive@57
|
1109 local key = toPlayerKey(realm, name)
|
yellowfive@57
|
1110 local obj = {
|
yellowfive@57
|
1111 Region = Amr.RegionNames[GetCurrentRegion()],
|
yellowfive@57
|
1112 Realm = realm,
|
yellowfive@57
|
1113 Name = name
|
yellowfive@57
|
1114 }
|
yellowfive@57
|
1115 _roster[key] = Amr.Serializer:SerializePlayerIdentity(obj)
|
yellowfive@57
|
1116 end
|
yellowfive@57
|
1117 end
|
yellowfive@57
|
1118
|
yellowfive@57
|
1119 _rosterCallback = callback
|
yellowfive@57
|
1120
|
yellowfive@57
|
1121 if _rosterPlayersRemaining > 0 then
|
yellowfive@57
|
1122 -- send a message to receive player data, when the last player is received onRosterCompleted will be called
|
yellowfive@57
|
1123 Amr:SendAmrCommMessage(_messagePrefixes.RosterRequestGear)
|
yellowfive@57
|
1124 else
|
yellowfive@57
|
1125 -- don't need to wait for anybody, just call immediately
|
yellowfive@57
|
1126 onRosterCompleted()
|
yellowfive@57
|
1127 end
|
yellowfive@57
|
1128 end
|
yellowfive@57
|
1129
|
yellowfive@57
|
1130
|
yellowfive@57
|
1131 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1132 -- Ranking Import
|
yellowfive@57
|
1133 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1134
|
yellowfive@57
|
1135 -- helper to parse import item identifier format into an item object
|
yellowfive@57
|
1136 local function parseItemIdentifier(ident)
|
yellowfive@57
|
1137
|
yellowfive@57
|
1138 local parts = { strsplit(":", ident) }
|
yellowfive@57
|
1139 local item = {}
|
yellowfive@57
|
1140 item.id = tonumber(parts[1])
|
yellowfive@57
|
1141 item.enchantId = 0
|
yellowfive@57
|
1142 item.gemIds = { 0, 0, 0, 0 }
|
yellowfive@57
|
1143 item.suffixId = math.abs(tonumber(parts[2]))
|
yellowfive@57
|
1144 item.upgradeId = tonumber(parts[3])
|
yellowfive@94
|
1145 item.level = tonumber(parts[4])
|
yellowfive@57
|
1146
|
yellowfive@94
|
1147 if #parts > 4 then
|
yellowfive@57
|
1148 item.bonusIds = {}
|
yellowfive@94
|
1149 for b = 5, #parts do
|
yellowfive@57
|
1150 table.insert(item.bonusIds, tonumber(parts[b]))
|
yellowfive@57
|
1151 end
|
yellowfive@57
|
1152 table.sort(item.bonusIds)
|
yellowfive@57
|
1153 end
|
yellowfive@57
|
1154
|
yellowfive@57
|
1155 return item
|
yellowfive@57
|
1156 end
|
yellowfive@57
|
1157
|
yellowfive@57
|
1158 function Amr:ParseRankingString(data)
|
yellowfive@57
|
1159 local rankings = {}
|
yellowfive@57
|
1160
|
yellowfive@57
|
1161 local player = Amr:ExportCharacter()
|
yellowfive@57
|
1162 local myUnitId = Amr:GetUnitId(player.Realm, player.Name)
|
yellowfive@57
|
1163 local ml = IsMasterLooter()
|
yellowfive@57
|
1164
|
yellowfive@57
|
1165 local itemList = { strsplit("\n", data) }
|
yellowfive@57
|
1166 for i = 1, #itemList do
|
yellowfive@57
|
1167 local ranking = {}
|
yellowfive@57
|
1168
|
yellowfive@57
|
1169 local itemParts = { strsplit("_", itemList[i]) }
|
yellowfive@57
|
1170
|
yellowfive@57
|
1171 -- first part has the item identifier
|
yellowfive@57
|
1172 ranking.item = parseItemIdentifier(itemParts[1])
|
yellowfive@57
|
1173
|
yellowfive@57
|
1174 -- second part has item info
|
yellowfive@57
|
1175 local infoParts = { strsplit(";", itemParts[2]) }
|
yellowfive@57
|
1176 ranking.itemInfo = {
|
yellowfive@57
|
1177 slot = infoParts[1],
|
yellowfive@57
|
1178 subclass = infoParts[2],
|
yellowfive@57
|
1179 weaponType = infoParts[3],
|
yellowfive@57
|
1180 armorType = infoParts[4]
|
yellowfive@57
|
1181 }
|
yellowfive@57
|
1182
|
yellowfive@57
|
1183 local meInList = false
|
yellowfive@57
|
1184
|
yellowfive@57
|
1185 -- parse each ranking
|
yellowfive@57
|
1186 ranking.ranks = {}
|
yellowfive@57
|
1187 for j = 3, #itemParts do
|
yellowfive@57
|
1188 local rankParts = { strsplit(";", itemParts[j]) }
|
yellowfive@57
|
1189
|
yellowfive@57
|
1190 local rank = {}
|
yellowfive@57
|
1191 rank.realm = rankParts[1]
|
yellowfive@57
|
1192 rank.name = rankParts[2]
|
yellowfive@57
|
1193 rank.specId = tonumber(rankParts[3])
|
yellowfive@57
|
1194 if rankParts[4] ~= "--" then
|
yellowfive@57
|
1195 rank.equipped = parseItemIdentifier(rankParts[4])
|
yellowfive@57
|
1196 end
|
yellowfive@57
|
1197 rank.score = tonumber(rankParts[5])
|
yellowfive@57
|
1198 rank.isEquipped = rankParts[6] == "t"
|
yellowfive@57
|
1199 rank.notRanked = rankParts[7] == "t"
|
yellowfive@57
|
1200 rank.offspec = rankParts[8] == "t"
|
yellowfive@57
|
1201 rank.enchantingSkill = tonumber(rankParts[9])
|
yellowfive@57
|
1202
|
yellowfive@57
|
1203 table.insert(ranking.ranks, rank)
|
yellowfive@57
|
1204
|
yellowfive@57
|
1205 if myUnitId == Amr:GetUnitId(rank.realm, rank.name) then
|
yellowfive@57
|
1206 meInList = true
|
yellowfive@57
|
1207 rank.isMasterLooter = ml
|
yellowfive@57
|
1208 end
|
yellowfive@57
|
1209 end
|
yellowfive@57
|
1210
|
yellowfive@57
|
1211 -- if the current player is the master looter and he is not in the list, then add him at the end
|
yellowfive@57
|
1212 if ml and not meInList then
|
yellowfive@57
|
1213 local rank = {
|
yellowfive@57
|
1214 realm = player.Realm,
|
yellowfive@57
|
1215 name = player.Name,
|
yellowfive@57
|
1216 specId = player.Specs[player.ActiveSpec],
|
yellowfive@57
|
1217 equipped = "--",
|
yellowfive@57
|
1218 score = 0,
|
yellowfive@57
|
1219 isEquipped = false,
|
yellowfive@57
|
1220 notRanked = true,
|
yellowfive@57
|
1221 offspec = false,
|
yellowfive@57
|
1222 enchantingSkill = 0,
|
yellowfive@57
|
1223 isMasterLooter = true
|
yellowfive@57
|
1224 }
|
yellowfive@57
|
1225 table.insert(ranking.ranks, rank)
|
yellowfive@57
|
1226 end
|
yellowfive@57
|
1227
|
yellowfive@57
|
1228 table.insert(rankings, ranking)
|
yellowfive@57
|
1229 end
|
yellowfive@57
|
1230
|
yellowfive@57
|
1231 return rankings
|
yellowfive@57
|
1232 end
|
yellowfive@57
|
1233
|
yellowfive@57
|
1234 -- import rankings from the website, save into the database, returns a string error if can't import for some reason
|
yellowfive@57
|
1235 function Amr:ImportRankings(data)
|
yellowfive@57
|
1236
|
yellowfive@57
|
1237 if not data or string.len(data) == 0 then
|
yellowfive@57
|
1238 return L.ImportErrorEmpty
|
yellowfive@57
|
1239 end
|
yellowfive@57
|
1240
|
yellowfive@57
|
1241 local success, rankings = pcall(Amr.ParseRankingString, self, data)
|
yellowfive@57
|
1242
|
yellowfive@57
|
1243 if not success then
|
yellowfive@57
|
1244 return L.ImportErrorFormat
|
yellowfive@57
|
1245 end
|
yellowfive@57
|
1246
|
yellowfive@57
|
1247 -- finish any looting in progress, effectively canceling it, user will have to press Start Loot again
|
yellowfive@57
|
1248 Amr:FinishLoot()
|
yellowfive@57
|
1249
|
yellowfive@57
|
1250 -- save the rankings
|
yellowfive@57
|
1251 Amr.db.global.TeamOpt.Rankings = rankings
|
yellowfive@57
|
1252 Amr.db.global.TeamOpt.RankingString = data
|
yellowfive@57
|
1253
|
yellowfive@57
|
1254 -- clear loot gear needed on successful ranking import
|
yellowfive@57
|
1255 Amr.db.global.TeamOpt.LootGear = {}
|
yellowfive@57
|
1256 end
|
yellowfive@57
|
1257
|
yellowfive@57
|
1258
|
yellowfive@57
|
1259 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1260 -- Loot Distribution
|
yellowfive@57
|
1261 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1262
|
yellowfive@57
|
1263 function Amr:StartLoot()
|
yellowfive@57
|
1264
|
yellowfive@57
|
1265 if not IsInGroup() and not IsInRaid() then
|
yellowfive@57
|
1266 Amr:ShowAlert(L.TeamAlertNoGroup, L.AlertOk)
|
yellowfive@57
|
1267 return
|
yellowfive@57
|
1268 end
|
yellowfive@57
|
1269
|
yellowfive@57
|
1270 -- broadcast the loot data to everyone, this triggers the loot window to show
|
yellowfive@57
|
1271 local msg = string.format("%s\n%s", Amr.LootMessagePrefixes.Start, Amr.db.global.TeamOpt.RankingString)
|
yellowfive@57
|
1272 Amr:SendAmrCommMessage(msg)
|
yellowfive@57
|
1273 end
|
yellowfive@57
|
1274
|
yellowfive@57
|
1275 function Amr:FinishLoot(clearHistory)
|
yellowfive@57
|
1276
|
yellowfive@57
|
1277 -- reset all state
|
yellowfive@57
|
1278 Amr.db.char.TeamOpt.LootInProgress = false
|
yellowfive@57
|
1279
|
yellowfive@57
|
1280 -- don't reset these for now... only reset these if someone leaves a group
|
yellowfive@57
|
1281 --Amr.db.char.TeamOpt.Loot = {}
|
yellowfive@57
|
1282 --Amr.db.char.TeamOpt.LootGuid = nil
|
yellowfive@57
|
1283 --Amr.db.global.TeamOpt.LootGear = {}
|
yellowfive@57
|
1284
|
yellowfive@57
|
1285 Amr.db.global.TeamOpt.Rankings = {}
|
yellowfive@57
|
1286 Amr.db.global.TeamOpt.RankingString = nil
|
yellowfive@57
|
1287
|
yellowfive@57
|
1288 Amr.db.char.TeamOpt.Rolls = {}
|
yellowfive@57
|
1289
|
yellowfive@57
|
1290 if clearHistory then
|
yellowfive@57
|
1291 Amr.db.char.TeamOpt.History = {}
|
yellowfive@57
|
1292 end
|
yellowfive@57
|
1293
|
yellowfive@57
|
1294 -- close the loot window
|
yellowfive@57
|
1295 Amr:HideLootWindow()
|
yellowfive@57
|
1296
|
yellowfive@57
|
1297 -- re-render the team optimizer UI
|
yellowfive@57
|
1298 Amr:RefreshTeamUi()
|
yellowfive@57
|
1299 end
|
yellowfive@57
|
1300
|
yellowfive@57
|
1301
|
yellowfive@57
|
1302 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1303 -- Synchronization
|
yellowfive@57
|
1304 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1305 local _waitingForSync = false
|
yellowfive@57
|
1306
|
yellowfive@57
|
1307 -- check if we need to synchronize
|
yellowfive@57
|
1308 local function checkSync()
|
yellowfive@57
|
1309 -- if loot is in progress and this person is not the ML, send a request to synchronize on startup, this player may have missed some data
|
yellowfive@57
|
1310 if not IsMasterLooter() and Amr.db.char.TeamOpt.LootInProgress then
|
yellowfive@57
|
1311 _waitingForSync = true
|
yellowfive@57
|
1312 Amr:SendAmrCommMessage(_messagePrefixes.SyncRequest)
|
yellowfive@57
|
1313 end
|
yellowfive@57
|
1314 end
|
yellowfive@57
|
1315
|
yellowfive@57
|
1316 -- send data to anyone who needs to synchronize their loot data: history, rolls, rankings
|
yellowfive@57
|
1317 local function sendSyncData()
|
yellowfive@57
|
1318 -- only the master looter sends sync data to ensure that everyone gets the same stuff and we don't spam
|
yellowfive@57
|
1319 if not IsMasterLooter() then return end
|
yellowfive@57
|
1320
|
yellowfive@57
|
1321 local msgParts = {}
|
yellowfive@57
|
1322 table.insert(msgParts, _messagePrefixes.Sync)
|
yellowfive@57
|
1323 table.insert(msgParts, Amr:Serialize(Amr.db.char.TeamOpt.History))
|
yellowfive@57
|
1324 table.insert(msgParts, Amr:Serialize(Amr.db.char.TeamOpt.Rolls))
|
yellowfive@57
|
1325 table.insert(msgParts, Amr:Serialize(Amr.db.global.TeamOpt.Rankings))
|
yellowfive@57
|
1326
|
yellowfive@57
|
1327 Amr:SendAmrCommMessage(table.concat(msgParts, "\n"))
|
yellowfive@57
|
1328 end
|
yellowfive@57
|
1329
|
yellowfive@57
|
1330 local function receiveSyncData(parts)
|
yellowfive@57
|
1331 if not _waitingForSync then return end
|
yellowfive@57
|
1332 _waitingForSync = false
|
yellowfive@57
|
1333
|
yellowfive@57
|
1334 local success, obj = Amr:Deserialize(parts[2])
|
yellowfive@57
|
1335 if success then
|
yellowfive@57
|
1336 Amr.db.char.TeamOpt.History = obj
|
yellowfive@57
|
1337 end
|
yellowfive@57
|
1338
|
yellowfive@57
|
1339 success, obj = Amr:Deserialize(parts[3])
|
yellowfive@57
|
1340 if success then
|
yellowfive@57
|
1341 Amr.db.char.TeamOpt.Rolls = obj
|
yellowfive@57
|
1342 end
|
yellowfive@57
|
1343
|
yellowfive@57
|
1344 success, obj = Amr:Deserialize(parts[4])
|
yellowfive@57
|
1345 if success then
|
yellowfive@57
|
1346 Amr.db.global.TeamOpt.Rankings = obj
|
yellowfive@57
|
1347 end
|
yellowfive@57
|
1348
|
yellowfive@57
|
1349 -- refresh any windows that may be visible
|
yellowfive@57
|
1350 Amr:RefreshTeamUi()
|
yellowfive@57
|
1351 Amr:RefreshLootWindow()
|
yellowfive@57
|
1352 Amr:RefreshLootRolls()
|
yellowfive@57
|
1353 end
|
yellowfive@57
|
1354
|
yellowfive@57
|
1355
|
yellowfive@57
|
1356 function Amr:ProcessTeamMessage(message)
|
yellowfive@57
|
1357
|
yellowfive@57
|
1358 local parts = {}
|
yellowfive@57
|
1359 for part in string.gmatch(message, "([^\n]+)") do
|
yellowfive@57
|
1360 table.insert(parts, part)
|
yellowfive@57
|
1361 end
|
yellowfive@57
|
1362
|
yellowfive@57
|
1363 local prefix = parts[1]
|
yellowfive@57
|
1364
|
yellowfive@57
|
1365 if prefix == _messagePrefixes.RosterRequestGear then
|
yellowfive@57
|
1366 -- request for me to send my gear data
|
yellowfive@57
|
1367 onGearForRosterRequested()
|
yellowfive@57
|
1368 elseif prefix == _messagePrefixes.ItemExportRequestGear then
|
yellowfive@57
|
1369 -- request for me to send my gear data
|
yellowfive@57
|
1370 onGearForLootExportRequested()
|
yellowfive@57
|
1371 elseif prefix == _messagePrefixes.ItemExportLoot then
|
yellowfive@57
|
1372 -- the last loot that dropped
|
yellowfive@57
|
1373 onLootReceived(parts)
|
yellowfive@57
|
1374 elseif prefix == _messagePrefixes.SyncRequest then
|
yellowfive@57
|
1375 sendSyncData()
|
yellowfive@57
|
1376 elseif prefix == _messagePrefixes.Sync then
|
yellowfive@57
|
1377 receiveSyncData(parts)
|
yellowfive@57
|
1378 elseif prefix == Amr.LootMessagePrefixes.Start then
|
yellowfive@57
|
1379 Amr:OnStartLootReceived(parts)
|
yellowfive@57
|
1380 elseif prefix == Amr.LootMessagePrefixes.Roll then
|
yellowfive@57
|
1381 Amr:OnLootRollReceived(parts)
|
yellowfive@57
|
1382 elseif prefix == Amr.LootMessagePrefixes.Veto then
|
yellowfive@57
|
1383 Amr:OnLootVetoReceived(parts)
|
yellowfive@57
|
1384 elseif prefix == Amr.LootMessagePrefixes.Rand then
|
yellowfive@57
|
1385 Amr:OnLootRandReceived(parts)
|
yellowfive@57
|
1386 elseif prefix == Amr.LootMessagePrefixes.Give then
|
yellowfive@57
|
1387 Amr:OnLootGiveReceived(parts)
|
yellowfive@57
|
1388 elseif prefix == Amr.LootMessagePrefixes.Finish then
|
yellowfive@57
|
1389 Amr:FinishLoot()
|
yellowfive@57
|
1390 else
|
yellowfive@57
|
1391 -- message will be of format: prefix\nregion\nrealm\nname\n[stuff]
|
yellowfive@57
|
1392 local region = parts[2]
|
yellowfive@57
|
1393 local realm = parts[3]
|
yellowfive@57
|
1394 local name = parts[4]
|
yellowfive@57
|
1395 local data = parts[5]
|
yellowfive@57
|
1396
|
yellowfive@57
|
1397 if prefix == _messagePrefixes.RosterGear then
|
yellowfive@57
|
1398 -- receive gear data from someone
|
yellowfive@57
|
1399 onGearForRosterReceived(region, realm, name, data)
|
yellowfive@57
|
1400 elseif prefix == _messagePrefixes.ItemExportGear then
|
yellowfive@57
|
1401 -- receive gear data for item export
|
yellowfive@57
|
1402 onGearForLootExportReceived(region, realm, name, data)
|
yellowfive@57
|
1403 end
|
yellowfive@57
|
1404 end
|
yellowfive@57
|
1405 end
|
yellowfive@57
|
1406
|
yellowfive@57
|
1407 function Amr:InitializeTeamOpt()
|
yellowfive@57
|
1408
|
yellowfive@57
|
1409 if not IsInGroup() and not IsInRaid() then
|
yellowfive@57
|
1410 onLeaveGroup()
|
yellowfive@57
|
1411 end
|
yellowfive@57
|
1412
|
yellowfive@57
|
1413 Amr:AddEventHandler("LOOT_OPENED", scanMasterLoot)
|
yellowfive@57
|
1414 Amr:AddEventHandler("GROUP_ROSTER_UPDATE", onGroupChanged)
|
yellowfive@57
|
1415
|
yellowfive@57
|
1416 checkSync()
|
yellowfive@57
|
1417 end
|