annotate Export.lua @ 133:a0894ffebd15 v62

Bug fixes and tweaks for 8.0.
author yellowfive
date Wed, 25 Jul 2018 12:17:24 -0700
parents 65c285394049
children 3be9cc6f7d20
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@127 181
yellowfive@127 182 local bagList = {}
yellowfive@127 183 table.insert(bagList, BANK_CONTAINER)
yellowfive@127 184 table.insert(bagList, REAGENTBANK_CONTAINER)
yellowfive@127 185 for bagId = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do
yellowfive@127 186 table.insert(bagList, bagId)
yellowfive@127 187 end
yellowfive@57 188
yellowfive@127 189 for i,bagId in ipairs(bagList) do
yellowfive@124 190 local bagItems = {}
yellowfive@124 191 local bagItemsAndCounts = {}
yellowfive@124 192 scanBag(bagId, true, bagItems, bagItemsAndCounts)
yellowfive@124 193
yellowfive@124 194 bankItems[bagId] = bagItems
yellowfive@124 195 itemsAndCounts[bagId] = bagItemsAndCounts
yellowfive@57 196 end
yellowfive@57 197
yellowfive@57 198 -- see if the scan completed before the window closed, otherwise we don't overwrite with partial data
yellowfive@124 199 if _bankOpen and _lastBankBagId then
yellowfive@57 200 local itemLink = GetContainerItemLink(_lastBankBagId, _lastBankSlotId)
yellowfive@124 201 if itemLink then --still open
yellowfive@57 202 Amr.db.char.BankItems = bankItems
yellowfive@57 203 Amr.db.char.BankItemsAndCounts = itemsAndCounts
yellowfive@57 204 end
yellowfive@57 205 end
yellowfive@57 206 end
yellowfive@57 207
yellowfive@124 208 local function onBankOpened()
yellowfive@124 209 _bankOpen = true
yellowfive@124 210 scanBank()
yellowfive@124 211 end
yellowfive@124 212
yellowfive@124 213 local function onBankClosed()
yellowfive@124 214 _bankOpen = false
yellowfive@124 215 end
yellowfive@124 216
yellowfive@124 217 -- if a bank bag is updated while the bank is open, re-scan that bag
yellowfive@124 218 local function onBankUpdated(bagID)
yellowfive@124 219 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 220 local bagItems = {}
yellowfive@124 221 local bagItemsAndCounts = {}
yellowfive@124 222 scanBag(bagID, true, bagItems, bagItemsAndCounts)
yellowfive@124 223
yellowfive@124 224 -- see if the scan completed before the window closed, otherwise we don't overwrite with partial data
yellowfive@124 225 if _bankOpen and _lastBankBagId == bagID then
yellowfive@124 226 local itemLink = GetContainerItemLink(_lastBankBagId, _lastBankSlotId)
yellowfive@124 227 if itemLink then
yellowfive@124 228 Amr.db.char.BankItems[bagID] = bagItems
yellowfive@124 229 Amr.db.char.BankItemsAndCounts[bagID] = bagItemsAndCounts
yellowfive@124 230 end
yellowfive@124 231 end
yellowfive@124 232 end
yellowfive@124 233 end
yellowfive@124 234
yellowfive@124 235 --[[
yellowfive@57 236 -- scan the player's void storage and save the contents, must be at void storage
yellowfive@57 237 local function scanVoid()
yellowfive@57 238
yellowfive@57 239 if IsVoidStorageReady() then
yellowfive@57 240 local voidItems = {}
yellowfive@57 241 local VOID_STORAGE_MAX = 80
yellowfive@57 242 local VOID_STORAGE_PAGES = 2
yellowfive@57 243
yellowfive@57 244 for page = 1,VOID_STORAGE_PAGES do
yellowfive@57 245 for i = 1,VOID_STORAGE_MAX do
yellowfive@57 246 local itemId = GetVoidItemInfo(page, i)
yellowfive@57 247 if itemId then
yellowfive@57 248 local itemLink = GetVoidItemHyperlinkString(((page - 1) * VOID_STORAGE_MAX) + i);
yellowfive@57 249 if itemLink then
yellowfive@57 250 tinsert(voidItems, itemLink)
yellowfive@57 251 end
yellowfive@57 252 end
yellowfive@57 253 end
yellowfive@57 254 end
yellowfive@57 255
yellowfive@57 256 Amr.db.char.VoidItems = voidItems
yellowfive@57 257 end
yellowfive@57 258
yellowfive@57 259 end
yellowfive@124 260 ]]
yellowfive@57 261
yellowfive@81 262 local function scanTalents()
yellowfive@81 263 local specPos = GetSpecialization()
yellowfive@81 264 if not specPos or specPos < 1 or specPos > 4 then return end
yellowfive@81 265
yellowfive@81 266 local talentInfo = {}
yellowfive@81 267 local maxTiers = 7
yellowfive@81 268 for tier = 1, maxTiers do
yellowfive@81 269 for col = 1, 3 do
yellowfive@81 270 local id, name, _, _, _, spellId, _, t, c, selected = GetTalentInfoBySpecialization(specPos, tier, col)
yellowfive@81 271 if selected then
yellowfive@81 272 talentInfo[tier] = col
yellowfive@81 273 end
yellowfive@81 274 end
yellowfive@81 275 end
yellowfive@81 276
yellowfive@81 277 local str = ""
yellowfive@81 278 for i = 1, maxTiers do
yellowfive@81 279 if talentInfo[i] then
yellowfive@81 280 str = str .. talentInfo[i]
yellowfive@81 281 else
yellowfive@81 282 str = str .. '0'
yellowfive@81 283 end
yellowfive@81 284 end
yellowfive@81 285
yellowfive@81 286 Amr.db.char.Talents[specPos] = str
yellowfive@81 287 end
yellowfive@81 288
yellowfive@57 289 -- Returns a data object containing all information about the current player needed for an export:
yellowfive@57 290 -- gear, spec, reputations, bag, bank, and void storage items.
yellowfive@57 291 function Amr:ExportCharacter()
yellowfive@57 292
yellowfive@124 293 -- get all necessary player data
yellowfive@124 294 local data = Amr.Serializer:GetPlayerData()
yellowfive@124 295
yellowfive@124 296 -- cache latest-seen equipped gear for current spec
yellowfive@124 297 local spec = GetSpecialization()
yellowfive@124 298 Amr.db.char.Equipped[spec] = data.Equipped[spec]
yellowfive@124 299
yellowfive@124 300 -- scan current inventory just before export so that it is always fresh
yellowfive@57 301 scanBags()
yellowfive@57 302
yellowfive@81 303 -- scan current spec's talents just before exporting
yellowfive@81 304 scanTalents()
yellowfive@81 305
yellowfive@124 306 data.Talents = Amr.db.char.Talents
yellowfive@124 307 data.Equipped = Amr.db.char.Equipped
yellowfive@57 308 data.BagItems = Amr.db.char.BagItems
yellowfive@124 309
yellowfive@124 310 -- flatten bank data (which is stored by bag for more efficient updating)
yellowfive@124 311 data.BankItems = {}
yellowfive@124 312 for k,v in pairs(Amr.db.char.BankItems) do
yellowfive@124 313 for i,v2 in ipairs(v) do
yellowfive@124 314 table.insert(data.BankItems, v2)
yellowfive@124 315 end
yellowfive@124 316 end
yellowfive@124 317
yellowfive@124 318 --data.VoidItems = Amr.db.char.VoidItems
yellowfive@57 319
yellowfive@57 320 return data
yellowfive@57 321 end
yellowfive@57 322
yellowfive@57 323 function Amr:InitializeExport()
yellowfive@57 324 Amr:AddEventHandler("UNIT_INVENTORY_CHANGED", function(unitID)
yellowfive@57 325 if unitID and unitID ~= "player" then return end
yellowfive@124 326 cacheEquipped()
yellowfive@57 327 end)
yellowfive@57 328 end
yellowfive@57 329
yellowfive@124 330 Amr:AddEventHandler("BANKFRAME_OPENED", onBankOpened)
yellowfive@124 331 Amr:AddEventHandler("BANKFRAME_CLOSED", onBankClosed)
yellowfive@124 332 Amr:AddEventHandler("BAG_UPDATE", onBankUpdated)
yellowfive@57 333
yellowfive@124 334 --Amr:AddEventHandler("VOID_STORAGE_OPEN", scanVoid)
yellowfive@124 335 --Amr:AddEventHandler("VOID_STORAGE_CONTENTS_UPDATE", scanVoid)
yellowfive@124 336 --Amr:AddEventHandler("VOID_STORAGE_DEPOSIT_UPDATE", scanVoid)
yellowfive@124 337 --Amr:AddEventHandler("VOID_STORAGE_UPDATE", scanVoid)
yellowfive@81 338
yellowfive@81 339 Amr:AddEventHandler("PLAYER_TALENT_UPDATE", scanTalents)