annotate Export.lua @ 125:4d175fb190f1 v58

Updated for 8.0 pre-patch and BfA.
author yellowfive
date Tue, 17 Jul 2018 09:58:51 -0700
parents e31b02b24488
children 65c285394049
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 _lastExport = nil
yellowfive@57 6 local _txt = nil
yellowfive@57 7
yellowfive@57 8 local function createLabel(container, text, width)
yellowfive@57 9 local lbl = AceGUI:Create("AmrUiLabel")
yellowfive@124 10 container:AddChild(lbl)
yellowfive@57 11 lbl:SetWidth(width or 800)
yellowfive@57 12 lbl:SetText(text)
yellowfive@57 13 lbl:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.Text))
yellowfive@57 14 return lbl
yellowfive@57 15 end
yellowfive@57 16
yellowfive@57 17 local function onSplashClose()
yellowfive@57 18 Amr:HideCover()
yellowfive@57 19 Amr.db.char.FirstUse = false
yellowfive@57 20 end
yellowfive@57 21
yellowfive@69 22 local function onTextChanged(widget)
yellowfive@69 23 local val = _txt:GetText()
yellowfive@69 24 if val == "overwolf-bib" then
yellowfive@69 25 -- go to the gear tab, open import window, and show a cover
yellowfive@69 26 Amr:ShowTab("Gear")
yellowfive@69 27 Amr:ShowImportWindow(true)
yellowfive@69 28 end
yellowfive@69 29 end
yellowfive@69 30
yellowfive@57 31 -- render a splash screen with first-time help
yellowfive@57 32 local function renderSplash(container)
yellowfive@57 33 local panel = Amr:RenderCoverChrome(container, 700, 450)
yellowfive@57 34
yellowfive@57 35 local lbl = createLabel(panel, L.ExportSplashTitle, 650)
yellowfive@57 36 lbl:SetJustifyH("CENTER")
yellowfive@57 37 lbl:SetFont(Amr.CreateFont("Bold", 24, Amr.Colors.TextHeaderActive))
yellowfive@57 38 lbl:SetPoint("TOP", panel.content, "TOP", 0, -10)
yellowfive@57 39
yellowfive@57 40 local lbl2 = createLabel(panel, L.ExportSplashSubtitle, 650)
yellowfive@57 41 lbl2:SetJustifyH("CENTER")
yellowfive@57 42 lbl2:SetFont(Amr.CreateFont("Bold", 18, Amr.Colors.TextTan))
yellowfive@57 43 lbl2:SetPoint("TOP", lbl.frame, "BOTTOM", 0, -20)
yellowfive@57 44
yellowfive@57 45 lbl = createLabel(panel, L.ExportSplash1, 650)
yellowfive@57 46 lbl:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.Text))
yellowfive@57 47 lbl:SetPoint("TOPLEFT", lbl2.frame, "BOTTOMLEFT", 0, -70)
yellowfive@57 48
yellowfive@57 49 lbl2 = createLabel(panel, L.ExportSplash2, 650)
yellowfive@57 50 lbl2:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.Text))
yellowfive@57 51 lbl2:SetPoint("TOPLEFT", lbl.frame, "BOTTOMLEFT", 0, -15)
yellowfive@57 52
yellowfive@57 53 local btn = AceGUI:Create("AmrUiButton")
yellowfive@57 54 btn:SetText(L.ExportSplashClose)
yellowfive@57 55 btn:SetBackgroundColor(Amr.Colors.Green)
yellowfive@57 56 btn:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White))
yellowfive@57 57 btn:SetWidth(120)
yellowfive@57 58 btn:SetHeight(28)
yellowfive@57 59 btn:SetCallback("OnClick", onSplashClose)
yellowfive@57 60 panel:AddChild(btn)
yellowfive@124 61 btn:SetPoint("BOTTOM", panel.content, "BOTTOM", 0, 20)
yellowfive@57 62 end
yellowfive@57 63
yellowfive@57 64 -- renders the main UI for the Export tab
yellowfive@57 65 function Amr:RenderTabExport(container)
yellowfive@57 66
yellowfive@57 67 local lbl = createLabel(container, L.ExportTitle)
yellowfive@57 68 lbl:SetFont(Amr.CreateFont("Bold", 24, Amr.Colors.TextHeaderActive))
yellowfive@57 69 lbl:SetPoint("TOPLEFT", container.content, "TOPLEFT", 0, -40)
yellowfive@57 70
yellowfive@57 71 local lbl2 = createLabel(container, L.ExportHelp1)
yellowfive@57 72 lbl2:SetPoint("TOPLEFT", lbl.frame, "BOTTOMLEFT", 0, -10)
yellowfive@57 73
yellowfive@57 74 lbl = createLabel(container, L.ExportHelp2)
yellowfive@57 75 lbl:SetPoint("TOPLEFT", lbl2.frame, "BOTTOMLEFT", 0, -10)
yellowfive@57 76
yellowfive@57 77 lbl2 = createLabel(container, L.ExportHelp3)
yellowfive@57 78 lbl2:SetPoint("TOPLEFT", lbl.frame, "BOTTOMLEFT", 0, -10)
yellowfive@57 79
yellowfive@57 80 _txt = AceGUI:Create("AmrUiTextarea")
yellowfive@57 81 _txt:SetWidth(800)
yellowfive@57 82 _txt:SetHeight(300)
yellowfive@57 83 _txt:SetFont(Amr.CreateFont("Regular", 12, Amr.Colors.Text))
yellowfive@69 84 _txt:SetCallback("OnTextChanged", onTextChanged)
yellowfive@57 85 container:AddChild(_txt)
yellowfive@124 86 _txt:SetPoint("TOP", lbl2.frame, "BOTTOM", 0, -20)
yellowfive@57 87
yellowfive@57 88 local data = self:ExportCharacter()
yellowfive@57 89 local txt = Amr.Serializer:SerializePlayerData(data, true)
yellowfive@57 90 _txt:SetText(txt)
yellowfive@57 91 _txt:SetFocus(true)
yellowfive@57 92
yellowfive@57 93 -- update shopping list data
yellowfive@57 94 Amr:UpdateShoppingData(data)
yellowfive@57 95
yellowfive@57 96 -- show help splash if first time a user is using this
yellowfive@57 97 if Amr.db.char.FirstUse then
yellowfive@57 98 Amr:ShowCover(renderSplash)
yellowfive@57 99 AceGUI:ClearFocus()
yellowfive@57 100 end
yellowfive@57 101 end
yellowfive@57 102
yellowfive@57 103 function Amr:ReleaseTabExport()
yellowfive@57 104 end
yellowfive@57 105
yellowfive@57 106 function Amr:GetExportText()
yellowfive@57 107 return _txt:GetText()
yellowfive@57 108 end
yellowfive@57 109
yellowfive@57 110
yellowfive@57 111 -- use some local variables to deal with the fact that a user can close the bank before a scan completes
yellowfive@57 112 local _lastBankBagId = nil
yellowfive@57 113 local _lastBankSlotId = nil
yellowfive@124 114 local _bankOpen = false
yellowfive@57 115
yellowfive@57 116 local function scanBag(bagId, isBank, bagTable, bagItemsWithCount)
yellowfive@57 117 local numSlots = GetContainerNumSlots(bagId)
yellowfive@124 118 local loc = ItemLocation.CreateEmpty()
yellowfive@57 119 for slotId = 1, numSlots do
yellowfive@57 120 local _, itemCount, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId)
yellowfive@57 121 if itemLink ~= nil then
yellowfive@57 122 local itemData = Amr.Serializer.ParseItemLink(itemLink)
yellowfive@57 123 if itemData ~= nil then
yellowfive@124 124
yellowfive@124 125 -- see if this is an azerite item and read azerite power ids
yellowfive@124 126 loc:SetBagAndSlot(bagId, slotId)
yellowfive@124 127 if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem(loc) then
yellowfive@124 128 local powers = Amr.ReadAzeritePowers(loc)
yellowfive@124 129 if powers then
yellowfive@124 130 itemData.azerite = powers
yellowfive@124 131 end
yellowfive@124 132 end
yellowfive@124 133
yellowfive@124 134 if isBank then
yellowfive@124 135 _lastBankBagId = bagId
yellowfive@124 136 _lastBankSlotId = slotId
yellowfive@124 137 end
yellowfive@57 138
yellowfive@124 139 table.insert(bagTable, itemData)
yellowfive@57 140
yellowfive@57 141 -- all items and counts, used for e.g. shopping list and reagents, etc.
yellowfive@57 142 if bagItemsWithCount then
yellowfive@57 143 if bagItemsWithCount[itemData.id] then
yellowfive@57 144 bagItemsWithCount[itemData.id] = bagItemsWithCount[itemData.id] + itemCount
yellowfive@57 145 else
yellowfive@57 146 bagItemsWithCount[itemData.id] = itemCount
yellowfive@57 147 end
yellowfive@57 148 end
yellowfive@57 149 end
yellowfive@57 150 end
yellowfive@57 151 end
yellowfive@57 152 end
yellowfive@57 153
yellowfive@124 154 -- cache the currently equipped gear for this spec
yellowfive@124 155 local function cacheEquipped()
yellowfive@124 156 local data = Amr.Serializer:GetEquipped()
yellowfive@57 157
yellowfive@124 158 local spec = GetSpecialization()
yellowfive@57 159 Amr.db.char.Equipped[spec] = data.Equipped[spec]
yellowfive@57 160 end
yellowfive@57 161
yellowfive@57 162 local function scanBags()
yellowfive@57 163
yellowfive@57 164 local bagItems = {}
yellowfive@57 165 local itemsAndCounts = {}
yellowfive@57 166
yellowfive@57 167 scanBag(BACKPACK_CONTAINER, false, bagItems, itemsAndCounts) -- backpack
yellowfive@57 168 for bagId = 1, NUM_BAG_SLOTS do
yellowfive@57 169 scanBag(bagId, false, bagItems, itemsAndCounts)
yellowfive@57 170 end
yellowfive@57 171
yellowfive@57 172 Amr.db.char.BagItems = bagItems
yellowfive@57 173 Amr.db.char.BagItemsAndCounts = itemsAndCounts
yellowfive@57 174 end
yellowfive@57 175
yellowfive@57 176 -- scan the player's bank and save the contents, must be at the bank
yellowfive@57 177 local function scanBank()
yellowfive@57 178
yellowfive@57 179 local bankItems = {}
yellowfive@57 180 local itemsAndCounts = {}
yellowfive@57 181
yellowfive@57 182 scanBag(BANK_CONTAINER, true, bankItems, itemsAndCounts)
yellowfive@57 183 scanBag(REAGENTBANK_CONTAINER, true, bankItems, itemsAndCounts)
yellowfive@57 184 for bagId = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do
yellowfive@124 185 local bagItems = {}
yellowfive@124 186 local bagItemsAndCounts = {}
yellowfive@124 187 scanBag(bagId, true, bagItems, bagItemsAndCounts)
yellowfive@124 188
yellowfive@124 189 bankItems[bagId] = bagItems
yellowfive@124 190 itemsAndCounts[bagId] = bagItemsAndCounts
yellowfive@57 191 end
yellowfive@57 192
yellowfive@57 193 -- see if the scan completed before the window closed, otherwise we don't overwrite with partial data
yellowfive@124 194 if _bankOpen and _lastBankBagId then
yellowfive@57 195 local itemLink = GetContainerItemLink(_lastBankBagId, _lastBankSlotId)
yellowfive@124 196 if itemLink then --still open
yellowfive@57 197 Amr.db.char.BankItems = bankItems
yellowfive@57 198 Amr.db.char.BankItemsAndCounts = itemsAndCounts
yellowfive@57 199 end
yellowfive@57 200 end
yellowfive@57 201 end
yellowfive@57 202
yellowfive@124 203 local function onBankOpened()
yellowfive@124 204 _bankOpen = true
yellowfive@124 205 scanBank()
yellowfive@124 206 end
yellowfive@124 207
yellowfive@124 208 local function onBankClosed()
yellowfive@124 209 _bankOpen = false
yellowfive@124 210 end
yellowfive@124 211
yellowfive@124 212 -- if a bank bag is updated while the bank is open, re-scan that bag
yellowfive@124 213 local function onBankUpdated(bagID)
yellowfive@124 214 if _bankOpen and (bagID == BANK_CONTAINER or bagID == REAGENTBANK_CONTAINER or (bagID >= NUM_BAG_SLOTS + 1 and bagID <= NUM_BAG_SLOTS + NUM_BANKBAGSLOTS)) then
yellowfive@124 215 local bagItems = {}
yellowfive@124 216 local bagItemsAndCounts = {}
yellowfive@124 217 scanBag(bagID, true, bagItems, bagItemsAndCounts)
yellowfive@124 218
yellowfive@124 219 -- see if the scan completed before the window closed, otherwise we don't overwrite with partial data
yellowfive@124 220 if _bankOpen and _lastBankBagId == bagID then
yellowfive@124 221 local itemLink = GetContainerItemLink(_lastBankBagId, _lastBankSlotId)
yellowfive@124 222 if itemLink then
yellowfive@124 223 Amr.db.char.BankItems[bagID] = bagItems
yellowfive@124 224 Amr.db.char.BankItemsAndCounts[bagID] = bagItemsAndCounts
yellowfive@124 225 end
yellowfive@124 226 end
yellowfive@124 227 end
yellowfive@124 228 end
yellowfive@124 229
yellowfive@124 230 --[[
yellowfive@57 231 -- scan the player's void storage and save the contents, must be at void storage
yellowfive@57 232 local function scanVoid()
yellowfive@57 233
yellowfive@57 234 if IsVoidStorageReady() then
yellowfive@57 235 local voidItems = {}
yellowfive@57 236 local VOID_STORAGE_MAX = 80
yellowfive@57 237 local VOID_STORAGE_PAGES = 2
yellowfive@57 238
yellowfive@57 239 for page = 1,VOID_STORAGE_PAGES do
yellowfive@57 240 for i = 1,VOID_STORAGE_MAX do
yellowfive@57 241 local itemId = GetVoidItemInfo(page, i)
yellowfive@57 242 if itemId then
yellowfive@57 243 local itemLink = GetVoidItemHyperlinkString(((page - 1) * VOID_STORAGE_MAX) + i);
yellowfive@57 244 if itemLink then
yellowfive@57 245 tinsert(voidItems, itemLink)
yellowfive@57 246 end
yellowfive@57 247 end
yellowfive@57 248 end
yellowfive@57 249 end
yellowfive@57 250
yellowfive@57 251 Amr.db.char.VoidItems = voidItems
yellowfive@57 252 end
yellowfive@57 253
yellowfive@57 254 end
yellowfive@124 255 ]]
yellowfive@57 256
yellowfive@81 257 local function scanTalents()
yellowfive@81 258 local specPos = GetSpecialization()
yellowfive@81 259 if not specPos or specPos < 1 or specPos > 4 then return end
yellowfive@81 260
yellowfive@81 261 local talentInfo = {}
yellowfive@81 262 local maxTiers = 7
yellowfive@81 263 for tier = 1, maxTiers do
yellowfive@81 264 for col = 1, 3 do
yellowfive@81 265 local id, name, _, _, _, spellId, _, t, c, selected = GetTalentInfoBySpecialization(specPos, tier, col)
yellowfive@81 266 if selected then
yellowfive@81 267 talentInfo[tier] = col
yellowfive@81 268 end
yellowfive@81 269 end
yellowfive@81 270 end
yellowfive@81 271
yellowfive@81 272 local str = ""
yellowfive@81 273 for i = 1, maxTiers do
yellowfive@81 274 if talentInfo[i] then
yellowfive@81 275 str = str .. talentInfo[i]
yellowfive@81 276 else
yellowfive@81 277 str = str .. '0'
yellowfive@81 278 end
yellowfive@81 279 end
yellowfive@81 280
yellowfive@81 281 Amr.db.char.Talents[specPos] = str
yellowfive@81 282 end
yellowfive@81 283
yellowfive@57 284 -- Returns a data object containing all information about the current player needed for an export:
yellowfive@57 285 -- gear, spec, reputations, bag, bank, and void storage items.
yellowfive@57 286 function Amr:ExportCharacter()
yellowfive@57 287
yellowfive@124 288 -- get all necessary player data
yellowfive@124 289 local data = Amr.Serializer:GetPlayerData()
yellowfive@124 290
yellowfive@124 291 -- cache latest-seen equipped gear for current spec
yellowfive@124 292 local spec = GetSpecialization()
yellowfive@124 293 Amr.db.char.Equipped[spec] = data.Equipped[spec]
yellowfive@124 294
yellowfive@124 295 -- scan current inventory just before export so that it is always fresh
yellowfive@57 296 scanBags()
yellowfive@57 297
yellowfive@81 298 -- scan current spec's talents just before exporting
yellowfive@81 299 scanTalents()
yellowfive@81 300
yellowfive@124 301 data.Talents = Amr.db.char.Talents
yellowfive@124 302 data.Equipped = Amr.db.char.Equipped
yellowfive@57 303 data.BagItems = Amr.db.char.BagItems
yellowfive@124 304
yellowfive@124 305 -- flatten bank data (which is stored by bag for more efficient updating)
yellowfive@124 306 data.BankItems = {}
yellowfive@124 307 for k,v in pairs(Amr.db.char.BankItems) do
yellowfive@124 308 for i,v2 in ipairs(v) do
yellowfive@124 309 table.insert(data.BankItems, v2)
yellowfive@124 310 end
yellowfive@124 311 end
yellowfive@124 312
yellowfive@124 313 --data.VoidItems = Amr.db.char.VoidItems
yellowfive@57 314
yellowfive@57 315 return data
yellowfive@57 316 end
yellowfive@57 317
yellowfive@57 318 function Amr:InitializeExport()
yellowfive@57 319 Amr:AddEventHandler("UNIT_INVENTORY_CHANGED", function(unitID)
yellowfive@57 320 if unitID and unitID ~= "player" then return end
yellowfive@124 321 cacheEquipped()
yellowfive@57 322 end)
yellowfive@57 323 end
yellowfive@57 324
yellowfive@124 325 Amr:AddEventHandler("BANKFRAME_OPENED", onBankOpened)
yellowfive@124 326 Amr:AddEventHandler("BANKFRAME_CLOSED", onBankClosed)
yellowfive@124 327 Amr:AddEventHandler("BAG_UPDATE", onBankUpdated)
yellowfive@57 328
yellowfive@124 329 --Amr:AddEventHandler("VOID_STORAGE_OPEN", scanVoid)
yellowfive@124 330 --Amr:AddEventHandler("VOID_STORAGE_CONTENTS_UPDATE", scanVoid)
yellowfive@124 331 --Amr:AddEventHandler("VOID_STORAGE_DEPOSIT_UPDATE", scanVoid)
yellowfive@124 332 --Amr:AddEventHandler("VOID_STORAGE_UPDATE", scanVoid)
yellowfive@81 333
yellowfive@81 334 Amr:AddEventHandler("PLAYER_TALENT_UPDATE", scanTalents)