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@57
|
797 local function scanMasterLoot()
|
yellowfive@57
|
798 -- only care if we are in a raid or group
|
yellowfive@57
|
799 if not IsInGroup() and not IsInRaid() then return end
|
yellowfive@57
|
800
|
yellowfive@57
|
801 -- we only care about the master looter
|
yellowfive@57
|
802 if not IsMasterLooter() then return end
|
yellowfive@57
|
803
|
yellowfive@57
|
804 -- guid of the unit being looted
|
yellowfive@57
|
805 local npcGuid = UnitGUID("target")
|
yellowfive@57
|
806 if not npcGuid then
|
yellowfive@57
|
807 -- this could wack shit out... but no raid bosses drop loot from containers right now, so should be fine
|
yellowfive@57
|
808 npcGuid = "container"
|
yellowfive@57
|
809 end
|
yellowfive@57
|
810
|
yellowfive@57
|
811 -- if we already have loot data for this unit, then we can ignore
|
yellowfive@57
|
812 if Amr.db.char.TeamOpt.LootGuid == npcGuid then return end
|
yellowfive@57
|
813
|
yellowfive@57
|
814 local loot = {}
|
yellowfive@57
|
815 for i = 1, GetNumLootItems() do
|
yellowfive@57
|
816 --local texture, item, quantity, quality, locked = GetLootSlotInfo(i)
|
yellowfive@57
|
817 local lootType = GetLootSlotType(i)
|
yellowfive@57
|
818 if lootType == 1 then
|
yellowfive@57
|
819 local link = GetLootSlotLink(i)
|
yellowfive@57
|
820 table.insert(loot, link)
|
yellowfive@57
|
821 end
|
yellowfive@57
|
822 end
|
yellowfive@57
|
823
|
yellowfive@57
|
824 Amr.db.char.TeamOpt.LootGuid = npcGuid
|
yellowfive@57
|
825 Amr.db.char.TeamOpt.Loot = loot
|
yellowfive@57
|
826
|
yellowfive@57
|
827 -- publish loot information to everyone else running the addon in case team optimizer user is not the master looter
|
yellowfive@57
|
828 local msg = _messagePrefixes.ItemExportLoot .. "\n" .. npcGuid .. "\n" .. table.concat(loot, "\n")
|
yellowfive@57
|
829 Amr:SendAmrCommMessage(msg)
|
yellowfive@57
|
830 end
|
yellowfive@57
|
831
|
yellowfive@57
|
832 local function onLootReceived(parts)
|
yellowfive@57
|
833
|
yellowfive@57
|
834 Amr.db.char.TeamOpt.LootGuid = parts[2]
|
yellowfive@57
|
835
|
yellowfive@57
|
836 local loot = {}
|
yellowfive@57
|
837 for i = 3, #parts do
|
yellowfive@57
|
838 table.insert(loot, parts[i])
|
yellowfive@57
|
839 end
|
yellowfive@57
|
840 Amr.db.char.TeamOpt.Loot = loot
|
yellowfive@57
|
841 end
|
yellowfive@57
|
842
|
yellowfive@57
|
843 local function onLeaveGroup()
|
yellowfive@57
|
844 -- if the current player is no longer in a group or raid, finish any looting in progress
|
yellowfive@57
|
845 Amr:FinishLoot(true)
|
yellowfive@57
|
846
|
yellowfive@57
|
847 -- clear loot when leave a group
|
yellowfive@57
|
848 Amr.db.char.TeamOpt.Loot = {}
|
yellowfive@57
|
849 Amr.db.char.TeamOpt.LootGuid = nil
|
yellowfive@57
|
850 Amr.db.global.TeamOpt.LootGear = {}
|
yellowfive@57
|
851 end
|
yellowfive@57
|
852
|
yellowfive@57
|
853 local function onGroupChanged()
|
yellowfive@57
|
854
|
yellowfive@57
|
855 if not IsInGroup() and not IsInRaid() then
|
yellowfive@57
|
856 onLeaveGroup()
|
yellowfive@57
|
857 end
|
yellowfive@57
|
858 end
|
yellowfive@57
|
859
|
yellowfive@57
|
860
|
yellowfive@57
|
861 local _lootExPlayersRemaining = 0
|
yellowfive@57
|
862 local _lootExRoster = nil
|
yellowfive@57
|
863 local _lootExCallback = nil
|
yellowfive@57
|
864
|
yellowfive@57
|
865 local function serializeLootExport()
|
yellowfive@57
|
866 if not IsInGroup() and not IsInRaid() then return "NOGROUP" end
|
yellowfive@57
|
867
|
yellowfive@57
|
868 local loot = Amr.db.char.TeamOpt.Loot
|
yellowfive@57
|
869 if not loot or #loot == 0 then return "NOLOOT" end
|
yellowfive@57
|
870
|
yellowfive@57
|
871 local itemObjects = {}
|
yellowfive@57
|
872 for i, link in ipairs(loot) do
|
yellowfive@57
|
873 local obj = Amr.ParseItemLink(link)
|
yellowfive@57
|
874 if obj then
|
yellowfive@57
|
875 table.insert(itemObjects, obj)
|
yellowfive@57
|
876 end
|
yellowfive@57
|
877 end
|
yellowfive@57
|
878
|
yellowfive@57
|
879 -- DEBUG: just grab all currently equipped items
|
yellowfive@57
|
880 --[[
|
yellowfive@57
|
881 itemObjects = {}
|
yellowfive@57
|
882 local blah = Amr:ExportCharacter()
|
yellowfive@57
|
883 for k, v in pairs(blah.Equipped[blah.ActiveSpec]) do
|
yellowfive@57
|
884 local obj = Amr.ParseItemLink(v)
|
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
|
yellowfive@57
|
891 local parts = {}
|
yellowfive@57
|
892
|
yellowfive@57
|
893 -- unique ids of items
|
yellowfive@57
|
894 local lootPart = {}
|
yellowfive@57
|
895 for i, obj in ipairs(itemObjects) do
|
yellowfive@57
|
896 table.insert(lootPart, Amr.GetItemUniqueId(obj))
|
yellowfive@57
|
897 end
|
yellowfive@57
|
898 table.insert(parts, table.concat(lootPart, ";"))
|
yellowfive@57
|
899
|
yellowfive@57
|
900 -- gear for players who have gained loot since the last item import or roster export
|
yellowfive@57
|
901 pruneGearForItemExport()
|
yellowfive@57
|
902 local lootGear = Amr.db.global.TeamOpt.LootGear
|
yellowfive@57
|
903 for k, v in pairs(lootGear) do
|
yellowfive@57
|
904 table.insert(parts, v)
|
yellowfive@57
|
905 end
|
yellowfive@57
|
906
|
yellowfive@57
|
907 return table.concat(parts, "\n")
|
yellowfive@57
|
908 end
|
yellowfive@57
|
909
|
yellowfive@57
|
910 local function onLootExportCompleted()
|
yellowfive@57
|
911
|
yellowfive@57
|
912 -- fill in LootGear with just those players who have changed
|
yellowfive@57
|
913 Amr.db.global.TeamOpt.LootGear = _lootExRoster
|
yellowfive@57
|
914
|
yellowfive@57
|
915 if _lootExCallback then
|
yellowfive@57
|
916 local txt = serializeLootExport()
|
yellowfive@57
|
917 _lootExCallback(txt)
|
yellowfive@57
|
918 end
|
yellowfive@57
|
919
|
yellowfive@57
|
920 -- reset state
|
yellowfive@57
|
921 _lootExPlayersRemaining = 0
|
yellowfive@57
|
922 _lootExRoster = nil
|
yellowfive@57
|
923 _lootExCallback = nil
|
yellowfive@57
|
924 end
|
yellowfive@57
|
925
|
yellowfive@57
|
926 -- called when this player's gear info has been requested by someone exporting loot
|
yellowfive@57
|
927 local function onGearForLootExportRequested()
|
yellowfive@57
|
928
|
yellowfive@57
|
929 local hasNewItem = false
|
yellowfive@57
|
930 local oldItems = Amr.db.char.TeamOpt.AllItems
|
yellowfive@57
|
931
|
yellowfive@57
|
932 if oldItems and #oldItems > 0 then
|
yellowfive@57
|
933 -- see if any new equippable items have been gained by comparing to the last snapshot
|
yellowfive@57
|
934 local data = Amr:ExportCharacter()
|
yellowfive@57
|
935 local allItems = snapshotAllItems(data)
|
yellowfive@57
|
936
|
yellowfive@57
|
937 if #oldItems ~= #allItems then
|
yellowfive@57
|
938 hasNewItem = true
|
yellowfive@57
|
939 else
|
yellowfive@57
|
940 -- go through items from front to back, if there are any that don't match then something has changed
|
yellowfive@57
|
941 for i = 1, #allItems do
|
yellowfive@57
|
942 local oldItem = oldItems[i]
|
yellowfive@57
|
943 local newItem = allItems[i]
|
yellowfive@57
|
944 if oldItem ~= newItem then
|
yellowfive@57
|
945 hasNewItem = true
|
yellowfive@57
|
946 break
|
yellowfive@57
|
947 end
|
yellowfive@57
|
948 end
|
yellowfive@57
|
949 end
|
yellowfive@57
|
950 end
|
yellowfive@57
|
951
|
yellowfive@57
|
952 -- whenever a new item is received, send out updated gear information that should be added to the next item export
|
yellowfive@57
|
953 sendGear(_messagePrefixes.ItemExportGear, not hasNewItem)
|
yellowfive@57
|
954 end
|
yellowfive@57
|
955
|
yellowfive@57
|
956 local function onGearForLootExportReceived(region, realm, name, data)
|
yellowfive@57
|
957 -- if I am not listening for incoming gear data for an item export, then ignore this message
|
yellowfive@57
|
958 if _lootExPlayersRemaining == 0 then return end
|
yellowfive@57
|
959
|
yellowfive@57
|
960 local key = toPlayerKey(realm, name)
|
yellowfive@57
|
961 if not data or data == "_" then
|
yellowfive@57
|
962 _lootExRoster[key] = nil
|
yellowfive@57
|
963 else
|
yellowfive@57
|
964 _lootExRoster[key] = data
|
yellowfive@57
|
965 end
|
yellowfive@57
|
966
|
yellowfive@57
|
967 _lootExPlayersRemaining = _lootExPlayersRemaining - 1
|
yellowfive@57
|
968 if _lootExPlayersRemaining <= 0 then
|
yellowfive@57
|
969 onLootExportCompleted()
|
yellowfive@57
|
970 end
|
yellowfive@57
|
971 end
|
yellowfive@57
|
972
|
yellowfive@57
|
973 -- 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
|
974 -- This is asynchronous because it needs to wait for gear data to arrive from each player.
|
yellowfive@57
|
975 function Amr:ExportLootAsync(callback)
|
yellowfive@57
|
976
|
yellowfive@57
|
977 if not IsInGroup() and not IsInRaid() then
|
yellowfive@57
|
978 callback("NOGROUP")
|
yellowfive@57
|
979 end
|
yellowfive@57
|
980
|
yellowfive@57
|
981 local loot = Amr.db.char.TeamOpt.Loot
|
yellowfive@57
|
982 if not loot or #loot == 0 then
|
yellowfive@57
|
983 callback("NOLOOT")
|
yellowfive@57
|
984 end
|
yellowfive@57
|
985
|
yellowfive@57
|
986 local playersNoGear = {}
|
yellowfive@57
|
987 _lootExPlayersRemaining = 0
|
yellowfive@57
|
988
|
yellowfive@57
|
989 local units = self:GetGroupUnitIdentifiers()
|
yellowfive@57
|
990 for i, unitId in ipairs(units) do
|
yellowfive@57
|
991 local realm, name = self:GetRealmAndName(unitId)
|
yellowfive@57
|
992 if realm then
|
yellowfive@57
|
993 local ver = self:GetAddonVersion(realm, name)
|
yellowfive@57
|
994 local key = toPlayerKey(realm, name)
|
yellowfive@57
|
995
|
yellowfive@57
|
996 if ver >= Amr.MIN_ADDON_VERSION then
|
yellowfive@57
|
997 _lootExPlayersRemaining = _lootExPlayersRemaining + 1
|
yellowfive@57
|
998 else
|
yellowfive@57
|
999 table.insert(playersNoGear, unitId)
|
yellowfive@57
|
1000 end
|
yellowfive@57
|
1001 end
|
yellowfive@57
|
1002 end
|
yellowfive@57
|
1003
|
yellowfive@57
|
1004 _lootExRoster = {}
|
yellowfive@57
|
1005 _lootExCallback = callback
|
yellowfive@57
|
1006
|
yellowfive@57
|
1007 if _lootExPlayersRemaining > 0 then
|
yellowfive@57
|
1008 -- send a message to receive player data, when the last player is received onLootExportCompleted will be called
|
yellowfive@57
|
1009 Amr:SendAmrCommMessage(_messagePrefixes.ItemExportRequestGear)
|
yellowfive@57
|
1010 else
|
yellowfive@57
|
1011 -- don't need to wait for anybody, just call immediately
|
yellowfive@57
|
1012 onLootExportCompleted()
|
yellowfive@57
|
1013 end
|
yellowfive@57
|
1014 end
|
yellowfive@57
|
1015
|
yellowfive@57
|
1016
|
yellowfive@57
|
1017 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1018 -- Roster Export
|
yellowfive@57
|
1019 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1020
|
yellowfive@57
|
1021 local _rosterPlayersRemaining = 0
|
yellowfive@57
|
1022 local _roster = nil
|
yellowfive@57
|
1023 local _rosterCallback = nil
|
yellowfive@57
|
1024
|
yellowfive@57
|
1025 local function onRosterCompleted()
|
yellowfive@57
|
1026
|
yellowfive@57
|
1027 if _rosterCallback then
|
yellowfive@57
|
1028 -- serialize the roster
|
yellowfive@57
|
1029 local parts = {}
|
yellowfive@57
|
1030 for key, data in pairs(_roster) do
|
yellowfive@57
|
1031 table.insert(parts, data)
|
yellowfive@57
|
1032 end
|
yellowfive@57
|
1033 local msg = table.concat(parts, "\n")
|
yellowfive@57
|
1034
|
yellowfive@57
|
1035 -- send to callback
|
yellowfive@57
|
1036 _rosterCallback(msg)
|
yellowfive@57
|
1037 end
|
yellowfive@57
|
1038
|
yellowfive@57
|
1039 -- reset state
|
yellowfive@57
|
1040 _rosterPlayersRemaining = 0
|
yellowfive@57
|
1041 _roster = nil
|
yellowfive@57
|
1042 _rosterCallback = nil
|
yellowfive@57
|
1043
|
yellowfive@57
|
1044 -- clear out loot gear needed, an export will refresh everyone at the time of export
|
yellowfive@57
|
1045 Amr.db.global.TeamOpt.LootGear = {}
|
yellowfive@57
|
1046 end
|
yellowfive@57
|
1047
|
yellowfive@57
|
1048 -- called when this player's gear info has been requested by someone exporting the raid roster
|
yellowfive@57
|
1049 local function onGearForRosterRequested()
|
yellowfive@57
|
1050
|
yellowfive@57
|
1051 sendGear(_messagePrefixes.RosterGear)
|
yellowfive@57
|
1052 end
|
yellowfive@57
|
1053
|
yellowfive@57
|
1054 local function onGearForRosterReceived(region, realm, name, data)
|
yellowfive@57
|
1055 -- if I am not listening for incoming gear data for the roster, then ignore this message
|
yellowfive@57
|
1056 if _rosterPlayersRemaining == 0 then return end
|
yellowfive@57
|
1057
|
yellowfive@57
|
1058 local key = toPlayerKey(realm, name)
|
yellowfive@57
|
1059 _roster[key] = data
|
yellowfive@57
|
1060
|
yellowfive@57
|
1061 _rosterPlayersRemaining = _rosterPlayersRemaining - 1
|
yellowfive@57
|
1062 if _rosterPlayersRemaining <= 0 then
|
yellowfive@57
|
1063 onRosterCompleted()
|
yellowfive@57
|
1064 end
|
yellowfive@57
|
1065 end
|
yellowfive@57
|
1066
|
yellowfive@57
|
1067 -- Export the current roster, including any known gear data for players with the in-game addon.
|
yellowfive@57
|
1068 -- This is asynchronous because it needs to wait for gear data to arrive from each player.
|
yellowfive@57
|
1069 function Amr:ExportRosterAsync(callback)
|
yellowfive@57
|
1070 if not IsInGroup() and not IsInRaid() then
|
yellowfive@57
|
1071 callback()
|
yellowfive@57
|
1072 return
|
yellowfive@57
|
1073 end
|
yellowfive@57
|
1074
|
yellowfive@57
|
1075 local playersNoGear = {}
|
yellowfive@57
|
1076 _rosterPlayersRemaining = 0
|
yellowfive@57
|
1077
|
yellowfive@57
|
1078 local units = self:GetGroupUnitIdentifiers()
|
yellowfive@57
|
1079 for i, unitId in ipairs(units) do
|
yellowfive@57
|
1080 local realm, name = self:GetRealmAndName(unitId)
|
yellowfive@57
|
1081 if realm then
|
yellowfive@57
|
1082 local ver = self:GetAddonVersion(realm, name)
|
yellowfive@57
|
1083 local key = toPlayerKey(realm, name)
|
yellowfive@57
|
1084
|
yellowfive@57
|
1085 if ver >= Amr.MIN_ADDON_VERSION then
|
yellowfive@57
|
1086 _rosterPlayersRemaining = _rosterPlayersRemaining + 1
|
yellowfive@57
|
1087 else
|
yellowfive@57
|
1088 table.insert(playersNoGear, unitId)
|
yellowfive@57
|
1089 end
|
yellowfive@57
|
1090 end
|
yellowfive@57
|
1091 end
|
yellowfive@57
|
1092
|
yellowfive@57
|
1093 -- fill the roster with any players who can't send us data
|
yellowfive@57
|
1094 _roster = {}
|
yellowfive@57
|
1095 for i, unitId in ipairs(playersNoGear) do
|
yellowfive@57
|
1096 local realm, name = self:GetRealmAndName(unitId)
|
yellowfive@57
|
1097 if realm then
|
yellowfive@57
|
1098 local key = toPlayerKey(realm, name)
|
yellowfive@57
|
1099 local obj = {
|
yellowfive@57
|
1100 Region = Amr.RegionNames[GetCurrentRegion()],
|
yellowfive@57
|
1101 Realm = realm,
|
yellowfive@57
|
1102 Name = name
|
yellowfive@57
|
1103 }
|
yellowfive@57
|
1104 _roster[key] = Amr.Serializer:SerializePlayerIdentity(obj)
|
yellowfive@57
|
1105 end
|
yellowfive@57
|
1106 end
|
yellowfive@57
|
1107
|
yellowfive@57
|
1108 _rosterCallback = callback
|
yellowfive@57
|
1109
|
yellowfive@57
|
1110 if _rosterPlayersRemaining > 0 then
|
yellowfive@57
|
1111 -- send a message to receive player data, when the last player is received onRosterCompleted will be called
|
yellowfive@57
|
1112 Amr:SendAmrCommMessage(_messagePrefixes.RosterRequestGear)
|
yellowfive@57
|
1113 else
|
yellowfive@57
|
1114 -- don't need to wait for anybody, just call immediately
|
yellowfive@57
|
1115 onRosterCompleted()
|
yellowfive@57
|
1116 end
|
yellowfive@57
|
1117 end
|
yellowfive@57
|
1118
|
yellowfive@57
|
1119
|
yellowfive@57
|
1120 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1121 -- Ranking Import
|
yellowfive@57
|
1122 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1123
|
yellowfive@57
|
1124 -- helper to parse import item identifier format into an item object
|
yellowfive@57
|
1125 local function parseItemIdentifier(ident)
|
yellowfive@57
|
1126
|
yellowfive@57
|
1127 local parts = { strsplit(":", ident) }
|
yellowfive@57
|
1128 local item = {}
|
yellowfive@57
|
1129 item.id = tonumber(parts[1])
|
yellowfive@57
|
1130 item.enchantId = 0
|
yellowfive@57
|
1131 item.gemIds = { 0, 0, 0, 0 }
|
yellowfive@57
|
1132 item.suffixId = math.abs(tonumber(parts[2]))
|
yellowfive@57
|
1133 item.upgradeId = tonumber(parts[3])
|
yellowfive@57
|
1134
|
yellowfive@57
|
1135 if #parts > 3 then
|
yellowfive@57
|
1136 item.bonusIds = {}
|
yellowfive@57
|
1137 for b = 4, #parts do
|
yellowfive@57
|
1138 table.insert(item.bonusIds, tonumber(parts[b]))
|
yellowfive@57
|
1139 end
|
yellowfive@57
|
1140 table.sort(item.bonusIds)
|
yellowfive@57
|
1141 end
|
yellowfive@57
|
1142
|
yellowfive@57
|
1143 return item
|
yellowfive@57
|
1144 end
|
yellowfive@57
|
1145
|
yellowfive@57
|
1146 function Amr:ParseRankingString(data)
|
yellowfive@57
|
1147 local rankings = {}
|
yellowfive@57
|
1148
|
yellowfive@57
|
1149 local player = Amr:ExportCharacter()
|
yellowfive@57
|
1150 local myUnitId = Amr:GetUnitId(player.Realm, player.Name)
|
yellowfive@57
|
1151 local ml = IsMasterLooter()
|
yellowfive@57
|
1152
|
yellowfive@57
|
1153 local itemList = { strsplit("\n", data) }
|
yellowfive@57
|
1154 for i = 1, #itemList do
|
yellowfive@57
|
1155 local ranking = {}
|
yellowfive@57
|
1156
|
yellowfive@57
|
1157 local itemParts = { strsplit("_", itemList[i]) }
|
yellowfive@57
|
1158
|
yellowfive@57
|
1159 -- first part has the item identifier
|
yellowfive@57
|
1160 ranking.item = parseItemIdentifier(itemParts[1])
|
yellowfive@57
|
1161
|
yellowfive@57
|
1162 -- second part has item info
|
yellowfive@57
|
1163 local infoParts = { strsplit(";", itemParts[2]) }
|
yellowfive@57
|
1164 ranking.itemInfo = {
|
yellowfive@57
|
1165 slot = infoParts[1],
|
yellowfive@57
|
1166 subclass = infoParts[2],
|
yellowfive@57
|
1167 weaponType = infoParts[3],
|
yellowfive@57
|
1168 armorType = infoParts[4]
|
yellowfive@57
|
1169 }
|
yellowfive@57
|
1170
|
yellowfive@57
|
1171 local meInList = false
|
yellowfive@57
|
1172
|
yellowfive@57
|
1173 -- parse each ranking
|
yellowfive@57
|
1174 ranking.ranks = {}
|
yellowfive@57
|
1175 for j = 3, #itemParts do
|
yellowfive@57
|
1176 local rankParts = { strsplit(";", itemParts[j]) }
|
yellowfive@57
|
1177
|
yellowfive@57
|
1178 local rank = {}
|
yellowfive@57
|
1179 rank.realm = rankParts[1]
|
yellowfive@57
|
1180 rank.name = rankParts[2]
|
yellowfive@57
|
1181 rank.specId = tonumber(rankParts[3])
|
yellowfive@57
|
1182 if rankParts[4] ~= "--" then
|
yellowfive@57
|
1183 rank.equipped = parseItemIdentifier(rankParts[4])
|
yellowfive@57
|
1184 end
|
yellowfive@57
|
1185 rank.score = tonumber(rankParts[5])
|
yellowfive@57
|
1186 rank.isEquipped = rankParts[6] == "t"
|
yellowfive@57
|
1187 rank.notRanked = rankParts[7] == "t"
|
yellowfive@57
|
1188 rank.offspec = rankParts[8] == "t"
|
yellowfive@57
|
1189 rank.enchantingSkill = tonumber(rankParts[9])
|
yellowfive@57
|
1190
|
yellowfive@57
|
1191 table.insert(ranking.ranks, rank)
|
yellowfive@57
|
1192
|
yellowfive@57
|
1193 if myUnitId == Amr:GetUnitId(rank.realm, rank.name) then
|
yellowfive@57
|
1194 meInList = true
|
yellowfive@57
|
1195 rank.isMasterLooter = ml
|
yellowfive@57
|
1196 end
|
yellowfive@57
|
1197 end
|
yellowfive@57
|
1198
|
yellowfive@57
|
1199 -- if the current player is the master looter and he is not in the list, then add him at the end
|
yellowfive@57
|
1200 if ml and not meInList then
|
yellowfive@57
|
1201 local rank = {
|
yellowfive@57
|
1202 realm = player.Realm,
|
yellowfive@57
|
1203 name = player.Name,
|
yellowfive@57
|
1204 specId = player.Specs[player.ActiveSpec],
|
yellowfive@57
|
1205 equipped = "--",
|
yellowfive@57
|
1206 score = 0,
|
yellowfive@57
|
1207 isEquipped = false,
|
yellowfive@57
|
1208 notRanked = true,
|
yellowfive@57
|
1209 offspec = false,
|
yellowfive@57
|
1210 enchantingSkill = 0,
|
yellowfive@57
|
1211 isMasterLooter = true
|
yellowfive@57
|
1212 }
|
yellowfive@57
|
1213 table.insert(ranking.ranks, rank)
|
yellowfive@57
|
1214 end
|
yellowfive@57
|
1215
|
yellowfive@57
|
1216 table.insert(rankings, ranking)
|
yellowfive@57
|
1217 end
|
yellowfive@57
|
1218
|
yellowfive@57
|
1219 return rankings
|
yellowfive@57
|
1220 end
|
yellowfive@57
|
1221
|
yellowfive@57
|
1222 -- import rankings from the website, save into the database, returns a string error if can't import for some reason
|
yellowfive@57
|
1223 function Amr:ImportRankings(data)
|
yellowfive@57
|
1224
|
yellowfive@57
|
1225 if not data or string.len(data) == 0 then
|
yellowfive@57
|
1226 return L.ImportErrorEmpty
|
yellowfive@57
|
1227 end
|
yellowfive@57
|
1228
|
yellowfive@57
|
1229 local success, rankings = pcall(Amr.ParseRankingString, self, data)
|
yellowfive@57
|
1230
|
yellowfive@57
|
1231 if not success then
|
yellowfive@57
|
1232 return L.ImportErrorFormat
|
yellowfive@57
|
1233 end
|
yellowfive@57
|
1234
|
yellowfive@57
|
1235 -- finish any looting in progress, effectively canceling it, user will have to press Start Loot again
|
yellowfive@57
|
1236 Amr:FinishLoot()
|
yellowfive@57
|
1237
|
yellowfive@57
|
1238 -- save the rankings
|
yellowfive@57
|
1239 Amr.db.global.TeamOpt.Rankings = rankings
|
yellowfive@57
|
1240 Amr.db.global.TeamOpt.RankingString = data
|
yellowfive@57
|
1241
|
yellowfive@57
|
1242 -- clear loot gear needed on successful ranking import
|
yellowfive@57
|
1243 Amr.db.global.TeamOpt.LootGear = {}
|
yellowfive@57
|
1244 end
|
yellowfive@57
|
1245
|
yellowfive@57
|
1246
|
yellowfive@57
|
1247 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1248 -- Loot Distribution
|
yellowfive@57
|
1249 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1250
|
yellowfive@57
|
1251 function Amr:StartLoot()
|
yellowfive@57
|
1252
|
yellowfive@57
|
1253 if not IsInGroup() and not IsInRaid() then
|
yellowfive@57
|
1254 Amr:ShowAlert(L.TeamAlertNoGroup, L.AlertOk)
|
yellowfive@57
|
1255 return
|
yellowfive@57
|
1256 end
|
yellowfive@57
|
1257
|
yellowfive@57
|
1258 -- broadcast the loot data to everyone, this triggers the loot window to show
|
yellowfive@57
|
1259 local msg = string.format("%s\n%s", Amr.LootMessagePrefixes.Start, Amr.db.global.TeamOpt.RankingString)
|
yellowfive@57
|
1260 Amr:SendAmrCommMessage(msg)
|
yellowfive@57
|
1261 end
|
yellowfive@57
|
1262
|
yellowfive@57
|
1263 function Amr:FinishLoot(clearHistory)
|
yellowfive@57
|
1264
|
yellowfive@57
|
1265 -- reset all state
|
yellowfive@57
|
1266 Amr.db.char.TeamOpt.LootInProgress = false
|
yellowfive@57
|
1267
|
yellowfive@57
|
1268 -- don't reset these for now... only reset these if someone leaves a group
|
yellowfive@57
|
1269 --Amr.db.char.TeamOpt.Loot = {}
|
yellowfive@57
|
1270 --Amr.db.char.TeamOpt.LootGuid = nil
|
yellowfive@57
|
1271 --Amr.db.global.TeamOpt.LootGear = {}
|
yellowfive@57
|
1272
|
yellowfive@57
|
1273 Amr.db.global.TeamOpt.Rankings = {}
|
yellowfive@57
|
1274 Amr.db.global.TeamOpt.RankingString = nil
|
yellowfive@57
|
1275
|
yellowfive@57
|
1276 Amr.db.char.TeamOpt.Rolls = {}
|
yellowfive@57
|
1277
|
yellowfive@57
|
1278 if clearHistory then
|
yellowfive@57
|
1279 Amr.db.char.TeamOpt.History = {}
|
yellowfive@57
|
1280 end
|
yellowfive@57
|
1281
|
yellowfive@57
|
1282 -- close the loot window
|
yellowfive@57
|
1283 Amr:HideLootWindow()
|
yellowfive@57
|
1284
|
yellowfive@57
|
1285 -- re-render the team optimizer UI
|
yellowfive@57
|
1286 Amr:RefreshTeamUi()
|
yellowfive@57
|
1287 end
|
yellowfive@57
|
1288
|
yellowfive@57
|
1289
|
yellowfive@57
|
1290 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1291 -- Synchronization
|
yellowfive@57
|
1292 ------------------------------------------------------------------------------------------------
|
yellowfive@57
|
1293 local _waitingForSync = false
|
yellowfive@57
|
1294
|
yellowfive@57
|
1295 -- check if we need to synchronize
|
yellowfive@57
|
1296 local function checkSync()
|
yellowfive@57
|
1297 -- 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
|
1298 if not IsMasterLooter() and Amr.db.char.TeamOpt.LootInProgress then
|
yellowfive@57
|
1299 _waitingForSync = true
|
yellowfive@57
|
1300 Amr:SendAmrCommMessage(_messagePrefixes.SyncRequest)
|
yellowfive@57
|
1301 end
|
yellowfive@57
|
1302 end
|
yellowfive@57
|
1303
|
yellowfive@57
|
1304 -- send data to anyone who needs to synchronize their loot data: history, rolls, rankings
|
yellowfive@57
|
1305 local function sendSyncData()
|
yellowfive@57
|
1306 -- only the master looter sends sync data to ensure that everyone gets the same stuff and we don't spam
|
yellowfive@57
|
1307 if not IsMasterLooter() then return end
|
yellowfive@57
|
1308
|
yellowfive@57
|
1309 local msgParts = {}
|
yellowfive@57
|
1310 table.insert(msgParts, _messagePrefixes.Sync)
|
yellowfive@57
|
1311 table.insert(msgParts, Amr:Serialize(Amr.db.char.TeamOpt.History))
|
yellowfive@57
|
1312 table.insert(msgParts, Amr:Serialize(Amr.db.char.TeamOpt.Rolls))
|
yellowfive@57
|
1313 table.insert(msgParts, Amr:Serialize(Amr.db.global.TeamOpt.Rankings))
|
yellowfive@57
|
1314
|
yellowfive@57
|
1315 Amr:SendAmrCommMessage(table.concat(msgParts, "\n"))
|
yellowfive@57
|
1316 end
|
yellowfive@57
|
1317
|
yellowfive@57
|
1318 local function receiveSyncData(parts)
|
yellowfive@57
|
1319 if not _waitingForSync then return end
|
yellowfive@57
|
1320 _waitingForSync = false
|
yellowfive@57
|
1321
|
yellowfive@57
|
1322 local success, obj = Amr:Deserialize(parts[2])
|
yellowfive@57
|
1323 if success then
|
yellowfive@57
|
1324 Amr.db.char.TeamOpt.History = obj
|
yellowfive@57
|
1325 end
|
yellowfive@57
|
1326
|
yellowfive@57
|
1327 success, obj = Amr:Deserialize(parts[3])
|
yellowfive@57
|
1328 if success then
|
yellowfive@57
|
1329 Amr.db.char.TeamOpt.Rolls = obj
|
yellowfive@57
|
1330 end
|
yellowfive@57
|
1331
|
yellowfive@57
|
1332 success, obj = Amr:Deserialize(parts[4])
|
yellowfive@57
|
1333 if success then
|
yellowfive@57
|
1334 Amr.db.global.TeamOpt.Rankings = obj
|
yellowfive@57
|
1335 end
|
yellowfive@57
|
1336
|
yellowfive@57
|
1337 -- refresh any windows that may be visible
|
yellowfive@57
|
1338 Amr:RefreshTeamUi()
|
yellowfive@57
|
1339 Amr:RefreshLootWindow()
|
yellowfive@57
|
1340 Amr:RefreshLootRolls()
|
yellowfive@57
|
1341 end
|
yellowfive@57
|
1342
|
yellowfive@57
|
1343
|
yellowfive@57
|
1344 function Amr:ProcessTeamMessage(message)
|
yellowfive@57
|
1345
|
yellowfive@57
|
1346 local parts = {}
|
yellowfive@57
|
1347 for part in string.gmatch(message, "([^\n]+)") do
|
yellowfive@57
|
1348 table.insert(parts, part)
|
yellowfive@57
|
1349 end
|
yellowfive@57
|
1350
|
yellowfive@57
|
1351 local prefix = parts[1]
|
yellowfive@57
|
1352
|
yellowfive@57
|
1353 if prefix == _messagePrefixes.RosterRequestGear then
|
yellowfive@57
|
1354 -- request for me to send my gear data
|
yellowfive@57
|
1355 onGearForRosterRequested()
|
yellowfive@57
|
1356 elseif prefix == _messagePrefixes.ItemExportRequestGear then
|
yellowfive@57
|
1357 -- request for me to send my gear data
|
yellowfive@57
|
1358 onGearForLootExportRequested()
|
yellowfive@57
|
1359 elseif prefix == _messagePrefixes.ItemExportLoot then
|
yellowfive@57
|
1360 -- the last loot that dropped
|
yellowfive@57
|
1361 onLootReceived(parts)
|
yellowfive@57
|
1362 elseif prefix == _messagePrefixes.SyncRequest then
|
yellowfive@57
|
1363 sendSyncData()
|
yellowfive@57
|
1364 elseif prefix == _messagePrefixes.Sync then
|
yellowfive@57
|
1365 receiveSyncData(parts)
|
yellowfive@57
|
1366 elseif prefix == Amr.LootMessagePrefixes.Start then
|
yellowfive@57
|
1367 Amr:OnStartLootReceived(parts)
|
yellowfive@57
|
1368 elseif prefix == Amr.LootMessagePrefixes.Roll then
|
yellowfive@57
|
1369 Amr:OnLootRollReceived(parts)
|
yellowfive@57
|
1370 elseif prefix == Amr.LootMessagePrefixes.Veto then
|
yellowfive@57
|
1371 Amr:OnLootVetoReceived(parts)
|
yellowfive@57
|
1372 elseif prefix == Amr.LootMessagePrefixes.Rand then
|
yellowfive@57
|
1373 Amr:OnLootRandReceived(parts)
|
yellowfive@57
|
1374 elseif prefix == Amr.LootMessagePrefixes.Give then
|
yellowfive@57
|
1375 Amr:OnLootGiveReceived(parts)
|
yellowfive@57
|
1376 elseif prefix == Amr.LootMessagePrefixes.Finish then
|
yellowfive@57
|
1377 Amr:FinishLoot()
|
yellowfive@57
|
1378 else
|
yellowfive@57
|
1379 -- message will be of format: prefix\nregion\nrealm\nname\n[stuff]
|
yellowfive@57
|
1380 local region = parts[2]
|
yellowfive@57
|
1381 local realm = parts[3]
|
yellowfive@57
|
1382 local name = parts[4]
|
yellowfive@57
|
1383 local data = parts[5]
|
yellowfive@57
|
1384
|
yellowfive@57
|
1385 if prefix == _messagePrefixes.RosterGear then
|
yellowfive@57
|
1386 -- receive gear data from someone
|
yellowfive@57
|
1387 onGearForRosterReceived(region, realm, name, data)
|
yellowfive@57
|
1388 elseif prefix == _messagePrefixes.ItemExportGear then
|
yellowfive@57
|
1389 -- receive gear data for item export
|
yellowfive@57
|
1390 onGearForLootExportReceived(region, realm, name, data)
|
yellowfive@57
|
1391 end
|
yellowfive@57
|
1392 end
|
yellowfive@57
|
1393 end
|
yellowfive@57
|
1394
|
yellowfive@57
|
1395 function Amr:InitializeTeamOpt()
|
yellowfive@57
|
1396
|
yellowfive@57
|
1397 if not IsInGroup() and not IsInRaid() then
|
yellowfive@57
|
1398 onLeaveGroup()
|
yellowfive@57
|
1399 end
|
yellowfive@57
|
1400
|
yellowfive@57
|
1401 Amr:AddEventHandler("LOOT_OPENED", scanMasterLoot)
|
yellowfive@57
|
1402 Amr:AddEventHandler("GROUP_ROSTER_UPDATE", onGroupChanged)
|
yellowfive@57
|
1403
|
yellowfive@57
|
1404 checkSync()
|
yellowfive@57
|
1405 end
|