annotate TeamOptimizer.lua @ 116:bccce18e12cb v54

Fixed a bug with transition from v52 crucible data to v53+.
author yellowfive
date Wed, 04 Oct 2017 11:18:19 -0700
parents ed7ffc8d9936
children
rev   line source
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@103 813 npcGuid = "container" .. time()
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