diff --git a/spec/System/TestTradeQueryCurrency_spec.lua b/spec/System/TestTradeQueryCurrency_spec.lua index fe6de69d40..5e378b7f0d 100644 --- a/spec/System/TestTradeQueryCurrency_spec.lua +++ b/spec/System/TestTradeQueryCurrency_spec.lua @@ -9,7 +9,8 @@ describe("TradeQuery Currency Conversion", function() -- Pass: Calculates price in divs -- Fail: Wrong value or nil, indicating broken rounding/baseline logic it("handles chaos currency", function() - mock_tradeQuery.pbCurrencyConversion = { league = { chaos = 0.1 } } + mock_tradeQuery.pbCurrencyConversion = { realm = { league = { chaos = 0.1 } } } + mock_tradeQuery.pbRealm = "realm" mock_tradeQuery.pbLeague = "league" local result = mock_tradeQuery:ConvertCurrencyToDivs("chaos", 5) assert.are.equal(result, 0.5) @@ -23,40 +24,202 @@ describe("TradeQuery Currency Conversion", function() end) end) - describe("PriceBuilderProcessPoENinjaResponse", function() - -- Pass: Processes without error, restoring map while adding a notice - -- Fail: Corrupts map or crashes, indicating fragile API response handling, breaking future conversions - it("handles empty response", function() - local orig_conv = mock_tradeQuery.currencyConversionTradeMap - mock_tradeQuery.currencyConversionTradeMap = { div = "id" } - mock_tradeQuery.pbLeague = "league" - mock_tradeQuery.pbCurrencyConversion = { league = {} } - mock_tradeQuery.controls.pbNotice = { label = "" } - local resp = { lines = { }} - mock_tradeQuery:PriceBuilderProcessPoENinjaResponse(resp.lines) - -- No crash expected - assert.is_true(true) - assert.is_true(mock_tradeQuery.controls.pbNotice.label == "No currencies received from PoE Ninja") - mock_tradeQuery.currencyConversionTradeMap = orig_conv + it("applies the Stat Value fallback when currency rates are missing", function() + mock_tradeQuery.sortModes = { Price = "price", StatValue = "stat" } + mock_tradeQuery.itemSortSelectionList = { "price" } + mock_tradeQuery.pbItemSortSelectionIndex = 1 + mock_tradeQuery.resultTbl = { [1] = { { currency = "chaos", amount = 1 } } } + mock_tradeQuery.sortedResultTbl = {} + mock_tradeQuery.itemIndexTbl = {} + mock_tradeQuery.totalPrice = {} + mock_tradeQuery.controls.pbNotice = {} + mock_tradeQuery.controls.priceButton1 = {} + mock_tradeQuery.controls.fullPrice = {} + mock_tradeQuery.SortFetchResults = function(_, _, mode) + if mode == "price" then + return nil, "MissingConversionRates" + end + return { { index = 1 } } + end + mock_tradeQuery.UpdateDropdownList = function() end + + mock_tradeQuery:UpdateControlsWithItems(1) + + assert.are.equals(1, mock_tradeQuery.sortedResultTbl[1][1].index) + assert.are.equals(1, mock_tradeQuery.itemIndexTbl[1]) + end) + + + describe("PullCXData", function() + local dkjson = require("dkjson") + + -- base type ids the currency exchange uses + local DIVINE = "Metadata/Items/Currency/CurrencyModValues" + local CHAOS = "Metadata/Items/Currency/CurrencyRerollRare" + local EXALT = "Metadata/Items/Currency/CurrencyAddModToRare" + local ALCH = "Metadata/Items/Currency/CurrencyUpgradeToRare" + + -- static trade data: maps display name -> short trade id + local static = { + result = { { + entries = { + { id = "sep", text = "" }, -- separator, must be ignored + { id = "divine", text = "Divine Orb" }, + { id = "chaos", text = "Chaos Orb" }, + { id = "exalted", text = "Exalted Orb" }, + { id = "alch", text = "Orb of Alchemy" }, + } + } } + } + + local origDownloadPage, cxResponse + + before_each(function() + mock_tradeQuery.pbRealm = "poe2" + mock_tradeQuery.controls.pbNotice = {} + origDownloadPage = launch.DownloadPage + cxResponse = nil + launch.DownloadPage = function(_, url, callback) + if url == "https://www.pathofexile.com/api/trade2/data/static" then + callback({ body = dkjson.encode(static) }) + elseif cxResponse then + callback({ body = dkjson.encode(cxResponse) }) + end + end end) - -- Pass: Processes without error, restoring map while adding a notice - -- Fail: Corrupts map or crashes, indicating fragile API response handling, breaking future conversions - it("handles empty response", function() - local orig_conv = mock_tradeQuery.currencyConversionTradeMap - mock_tradeQuery.currencyConversionTradeMap = { div = "id" } - mock_tradeQuery.pbLeague = "league" - mock_tradeQuery.pbCurrencyConversion = { league = {} } - mock_tradeQuery.controls.pbNotice = { label = "" } - local resp = { lines = { { malformedLine = "lol"} }} - mock_tradeQuery:PriceBuilderProcessPoENinjaResponse(resp.lines) - -- No crash expected - assert.is_true(true) - assert.is_true(mock_tradeQuery.controls.pbNotice.label == "Currencies not updated: malformed PoE Ninja response") - mock_tradeQuery.currencyConversionTradeMap = orig_conv + after_each(function() + launch.DownloadPage = origDownloadPage end) - end) + it("fetches currency exchange data without authentication", function() + local requestedUrl + local requestedParams + launch.DownloadPage = function(_, url, callback, params) + if url == "https://www.pathofexile.com/api/trade2/data/static" then + callback({ body = dkjson.encode(static) }) + else + requestedUrl = url + requestedParams = params + callback({ body = dkjson.encode({ markets = {} }) }) + end + end + + mock_tradeQuery.pbRealm = "poe2" + mock_tradeQuery:PullCXData() + + assert.is_truthy(requestedUrl:match("^https://web%.poecdn%.com/api/currency%-exchange/poe2/%d+$")) + assert.is_nil(requestedParams) + end) + + it("waits until a realm is selected", function() + local fetched = false + mock_tradeQuery.pbRealm = "" + launch.DownloadPage = function() + fetched = true + end + + mock_tradeQuery:PullCXData() + + assert.is_false(fetched) + end) + + -- Provide the currency exchange response returned by the download mock. + local function mockCX(markets) + cxResponse = { markets = markets } + end + + it("converts a chained market to divine values", function() + mockCX({ + -- exalt -> divine directly (1 exalt = 0.1 div) + { + league = "Standard", + market_pair = { EXALT, DIVINE }, + lowest_ratio = { [EXALT] = 10, [DIVINE] = 1 }, + highest_stock = { [EXALT] = 100, [DIVINE] = 100 }, + }, + -- chaos -> divine directly (1 chaos = 0.005 div) + { + league = "Standard", + market_pair = { CHAOS, DIVINE }, + lowest_ratio = { [CHAOS] = 200, [DIVINE] = 1 }, + highest_stock = { [CHAOS] = 500, [DIVINE] = 500 }, + }, + -- alch -> chaos (1 alch = 0.2 chaos), needs a second hop to divine + { + league = "Standard", + market_pair = { ALCH, CHAOS }, + lowest_ratio = { [ALCH] = 5, [CHAOS] = 1 }, + highest_stock = { [ALCH] = 1000, [CHAOS] = 1000 }, + }, + }) + + mock_tradeQuery:PullCXData() + + local rates = mock_tradeQuery.pbCurrencyConversion.poe2.Standard + assert.is_not_nil(rates) + assert.are.equal(1, rates.divine) + assert.are.equal(0.1, rates.exalted) + assert.are.equal(0.005, rates.chaos) + -- 0.2 chaos * 0.005 div/chaos = 0.001 div + assert.are.equal(0.001, rates.alch) + end) + + it("keeps the highest-stock listing for a currency", function() + mockCX({ + { + league = "Standard", + market_pair = { EXALT, DIVINE }, + lowest_ratio = { [EXALT] = 10, [DIVINE] = 1 }, -- 0.1 div + highest_stock = { [EXALT] = 50, [DIVINE] = 5 }, + }, + { + league = "Standard", + market_pair = { EXALT, DIVINE }, + lowest_ratio = { [EXALT] = 5, [DIVINE] = 1 }, -- 0.2 div + highest_stock = { [EXALT] = 200, [DIVINE] = 40 }, -- more stock, wins + }, + }) + + mock_tradeQuery:PullCXData() + + assert.are.equal(0.2, mock_tradeQuery.pbCurrencyConversion.poe2.Standard.exalted) + end) + + it("skips listings with a zero ratio", function() + mockCX({ + { + league = "Standard", + market_pair = { EXALT, DIVINE }, + lowest_ratio = { [EXALT] = 0, [DIVINE] = 1 }, + highest_stock = { [EXALT] = 100, [DIVINE] = 100 }, + }, + }) + + mock_tradeQuery:PullCXData() + + -- league had no usable listings, so it should not appear + assert.is_nil(mock_tradeQuery.pbCurrencyConversion.poe2.Standard) + end) + it("shows a notice on an API error response", function() + cxResponse = { error = { message = "kaput" } } + + mock_tradeQuery:PullCXData() + + assert.are.equal("CX error: kaput", mock_tradeQuery.controls.pbNotice.label) + assert.is_nil(mock_tradeQuery.pbCurrencyConversion.poe2) + end) + + it("does not refetch within the rate-limit window", function() + mock_tradeQuery.pbCurrencyConversion.poe2 = { timestamp = os.time() } + local fetched = false + launch.DownloadPage = function() fetched = true end + + mock_tradeQuery:PullCXData() + + assert.is_false(fetched) + end) + end) describe("GetTotalPriceString", function() -- Pass: Sums and formats correctly (e.g., "5 chaos, 10 div", should be most valuable currency first) -- Fail: Wrong string (e.g., unsorted/missing sums), indicating aggregation bug, misleading users on totals @@ -67,14 +230,14 @@ describe("TradeQuery Currency Conversion", function() assert.are.equal(result, "1 exalted, 10 div, 5 chaos") -- check if they're sorted according to currency value + mock_tradeQuery.pbRealm = "realm" mock_tradeQuery.pbLeague = "league" - mock_tradeQuery.pbCurrencyConversion = { league = { chaos = 0.1, exalted = 0.05, div = 1, mirror = 700} } + mock_tradeQuery.pbCurrencyConversion = { realm = { league = { chaos = 0.1, exalted = 0.05, div = 1, mirror = 700 } } } local result = mock_tradeQuery:GetTotalPriceString() assert.are.equal(result, "10 div, 5 chaos, 1 exalted") -- check that missing currency values don't crash - mock_tradeQuery.pbLeague = "league" - mock_tradeQuery.pbCurrencyConversion = { league = { chaos = 0.1, exalted = 0.05, mirror = 700 } } + mock_tradeQuery.pbCurrencyConversion = { realm = { league = { chaos = 0.1, exalted = 0.05, mirror = 700 } } } local result = mock_tradeQuery:GetTotalPriceString() assert.True(true) end) diff --git a/src/Classes/TradeQuery.lua b/src/Classes/TradeQuery.lua index 89a722e675..0a568b5eff 100644 --- a/src/Classes/TradeQuery.lua +++ b/src/Classes/TradeQuery.lua @@ -38,12 +38,9 @@ function TradeQueryClass:TradeQuery(itemsTab) -- default set of trade item sort selection self.slotTables = { } self.pbItemSortSelectionIndex = 1 - -- for each league, a table of values of each currency in div - --- @type table> - self.pbCurrencyConversion = { } - self.lastCurrencyConversionRequest = 0 - self.lastCurrencyFileTime = { } - self.pbFileTimestampDiff = { } + -- for each realm and league, a table of values of each currency in div + --- @type table>> + self.pbCurrencyConversion = {} self.pbRealm = "" self.pbRealmIndex = 1 self.pbLeagueIndex = 1 @@ -98,7 +95,6 @@ function TradeQueryClass:PullLeagueList() self.controls.league:SetList(self.itemsTab.leagueDropList) self.controls.league.selIndex = 1 self.pbLeague = self.itemsTab.leagueDropList[self.controls.league.selIndex] - self:SetCurrencyConversionButton() end end) end @@ -107,77 +103,148 @@ end --- @param amount integer --- @return number? function TradeQueryClass:ConvertCurrencyToDivs(currencyId, amount) - local map = self.pbCurrencyConversion[self.pbLeague] + local map = self.pbCurrencyConversion[self.pbRealm] and self.pbCurrencyConversion[self.pbRealm][self.pbLeague] if map and map[currencyId] then return amount * map[currencyId] end end --- Method to pull down and interpret the PoE.Ninja JSON endpoint data ---- @param league string -function TradeQueryClass:PullPoENinjaCurrencyConversion(league) +local generalCurrencies = { + ["Metadata/Items/Currency/CurrencyModValues"] = true, + ["Metadata/Items/Currency/CurrencyRerollRare"] = true +} + +-- Method to pull down and interpret the Currency Exchange JSON endpoint data +function TradeQueryClass:PullCXData() + local realm = self.pbRealm + if realm == "" then + return + end local now = get_time() - -- Limit PoE Ninja Currency Conversion request to 1 per hour - if (now - self.lastCurrencyConversionRequest) < 3600 then - self:SetNotice(self.controls.pbNotice, "PoE Ninja Rate Limit Exceeded: " .. tostring(3600 - (now - self.lastCurrencyConversionRequest))) + -- Limit Currency Conversion request to 1 per hour + if self.pbCurrencyConversion[realm] and ((now - self.pbCurrencyConversion[realm].timestamp) < 61 * 60) then return end - self.pbCurrencyConversion[league] = { } - self.lastCurrencyConversionRequest = now - launch:DownloadPage( - "https://poe.ninja/poe2/api/economy/exchange/current/overview?type=Currency&league=" .. urlEncode(league), - function(response, errMsg) + -- download json containing short names for each item id + launch:DownloadPage("https://www.pathofexile.com/api/trade2/data/static", function(response, errMsg) + if errMsg then + self:SetNotice(self.controls.pbNotice, "Error: " .. tostring(errMsg)) + return + end + + local static = dkjson.decode(response.body) + if not static then + self:SetNotice(self.controls.pbNotice, "Could not decode static trade data") + return + end + local url = "https://web.poecdn.com/api/currency-exchange" + if realm ~= "pc" then + url = url .. "/" .. realm + end + local hourSeconds = 60 * 60 + url = url .. "/" .. ((math.floor(now / hourSeconds) - 1) * hourSeconds) + launch:DownloadPage(url, function(response, errMsg) if errMsg then self:SetNotice(self.controls.pbNotice, "Error: " .. tostring(errMsg)) return end - local json_data = dkjson.decode(response.body) - if not json_data or not json_data.lines then - self:SetNotice(self.controls.pbNotice, "Failed to Get PoE Ninja response") + local json = dkjson.decode(response.body) + if not json then + self:SetNotice(self.controls.pbNotice, "Malformed CX API response") return end - if not self:PriceBuilderProcessPoENinjaResponse(json_data.lines) then - -- don't edit json on failure + if json.error then + self:SetNotice(self.controls.pbNotice, "CX error: " .. json.error.message) return end - local print_str = "" - for key, value in pairs(self.pbCurrencyConversion[self.pbLeague]) do - print_str = print_str .. '"'..key..'": '..tostring(value)..',' - end - local foo = io.open("../"..self.pbLeague.."_currency_values.json", "w") - foo:write("{" .. print_str .. '"updateTime": ' .. tostring(get_time()) .. "}") - foo:close() - self:SetCurrencyConversionButton() - end) + local success, result = pcall(function() + -- short currency names for each base item type id + local currencyNames = {} + local currencyIdMap = {} + for id, name in pairs(require("Data.CurrencyNames")) do + currencyIdMap[name] = id + end + for _, entry in ipairs(static.result[1].entries) do + if entry.id ~= "sep" then + local itemID = currencyIdMap[entry.text] + -- Not every bulk trade item is exported as currency. + if itemID then + currencyNames[itemID] = entry.id + end + end + end -end + local out = {} + for _, entry in ipairs(json.markets) do + local league = entry.league + if not out[league] then + out[league] = {} + end + local leagueOut = out[league] --- Method to process the PoE.Ninja response ---- @param responseLines table[] ---- @return bool -function TradeQueryClass:PriceBuilderProcessPoENinjaResponse(responseLines) - -- Populate the divine-converted values for each tradeId - for _, currencyDetails in ipairs(responseLines) do - -- these use the same ids as the trade site, which are also short - -- readable names, like "transmute" or "aug", which means there's no - -- need for conversion. - local id = currencyDetails.id - -- poe.ninja uses divs as the primary currency, and as far as I know, - -- this figure is equivalent to the best ratio in equivalent divs - local divs = currencyDetails.primaryValue - if not id or not divs then - self:SetNotice(self.controls.pbNotice, "Currencies not updated: malformed PoE Ninja response") - return false - end - self.pbCurrencyConversion[self.pbLeague][id] = divs - end - -- if nothing was actually found, we should add a notice - if next(self.pbCurrencyConversion[self.pbLeague]) == nil then - self:SetNotice(self.controls.pbNotice, "No currencies received from PoE Ninja") - return false - end - return true + -- Base type IDs are in the form Metadata/Items/.../CurrencyModValues. + local fromID = entry.market_pair[1] + local toID = entry.market_pair[2] + + -- Normalize entries to price each currency in chaos or divines. + if generalCurrencies[fromID] and toID ~= "Metadata/Items/Currency/CurrencyModValues" then + fromID, toID = toID, fromID + end + + local fromShort = currencyNames[fromID] + local toShort = currencyNames[toID] + if not fromShort or not generalCurrencies[toID] or entry.lowest_ratio[fromID] == 0 then + goto CXContinue + end + + local newEntry = { + currency = toShort, + price = entry.lowest_ratio[toID] / entry.lowest_ratio[fromID], + stock = entry.highest_stock[fromID] + } + -- Only keep the most popular option. + if not leagueOut[fromShort] or leagueOut[fromShort].stock < newEntry.stock then + leagueOut[fromShort] = newEntry + end + ::CXContinue:: + end + + -- Convert any chaos prices to divine equivalent prices. + for leagueName, leagueEntries in pairs(out) do + for from, to in pairs(leagueEntries) do + if to.currency ~= "divine" then + local divEntry = leagueEntries[to.currency] + if not divEntry then + leagueEntries[from] = nil + else + leagueEntries[from] = divEntry.price * to.price + end + end + end + for from, to in pairs(leagueEntries) do + if type(to) == "table" then + leagueEntries[from] = to.price + end + end + if not next(leagueEntries) then + out[leagueName] = nil + else + leagueEntries.divine = 1 + end + end + + return out + end) + if not success then + self:SetNotice(self.controls.pbNotice, "Failed to process CX response") + ConPrintf("CX error: %s", result) + return + end + result.timestamp = now + self.pbCurrencyConversion[realm] = result + end) + end) end local function initStatSortSelectionList(list) @@ -386,14 +453,16 @@ Highest Weight - Displays the order retrieved from trade]] self.controls.realmLabel = new("LabelControl"):LabelControl({ "LEFT", self.controls.setSelect, "RIGHT" }, { 18, 0, 20, row_height - 4 }, "^7Realm:") self.controls.realm = new("DropDownControl"):DropDownControl({ "LEFT", self.controls.realmLabel, "RIGHT" }, { 6, 0, 150, row_height }, self.realmDropList, function(index, value) self.pbRealmIndex = index - self.pbRealm = self.realmIds[value] + if self.pbRealm ~= self.realmIds[value] then + self.pbRealm = self.realmIds[value] + self:PullCXData() + end local function setLeagueDropList() self.itemsTab.leagueDropList = copyTable(self.allLeagues[self.pbRealm]) self.controls.league:SetList(self.itemsTab.leagueDropList) -- invalidate selIndex to trigger select function call in the SetSel self.controls.league.selIndex = nil self.controls.league:SetSel(self.pbLeagueIndex) - self:SetCurrencyConversionButton() end if self.allLeagues[self.pbRealm] then setLeagueDropList() @@ -426,7 +495,6 @@ Highest Weight - Displays the order retrieved from trade]] self.controls.league = new("DropDownControl"):DropDownControl({ "LEFT", self.controls.leagueLabel, "RIGHT" }, { 6, 0, 150, row_height }, self.itemsTab.leagueDropList, function(index, value) self.pbLeagueIndex = index self.pbLeague = value - self:SetCurrencyConversionButton() end) self.controls.league:SetSel(self.pbLeagueIndex) self.controls.league.enabled = function() @@ -581,11 +649,7 @@ Highest Weight - Displays the order retrieved from trade]] main:ClosePopup() end) - self.controls.updateCurrencyConversion = new("ButtonControl"):ButtonControl({ "BOTTOMLEFT", nil, "BOTTOMLEFT" }, { pane_margins_horizontal, -pane_margins_vertical, 240, row_height }, "Get Currency Conversion Rates", function() - self:PullPoENinjaCurrencyConversion(self.pbLeague) - end) self.controls.pbNotice = new("LabelControl"):LabelControl({ "BOTTOMRIGHT", nil, "BOTTOMRIGHT" }, { -row_height - pane_margins_vertical - row_vertical_padding, -pane_margins_vertical, 300, row_height }, "") - self:SetCurrencyConversionButton() -- used in PopupDialog:Draw() local function scrollBarFunc() @@ -619,6 +683,7 @@ Highest Weight - Displays the order retrieved from trade]] end end end + self:PullCXData() main:OpenPopup(pane_width, self.pane_height, "Trader", self.controls, nil, nil, "close", (scrollBarShown and scrollBarFunc or nil)) end @@ -728,48 +793,6 @@ function TradeQueryClass:SetStatWeights(previousSelectionList) main:OpenPopup(420, popupHeight, "Stat Weight Multipliers", controls) end --- Method to update the Currency Conversion button label -function TradeQueryClass:SetCurrencyConversionButton() - local currencyLabel = "Update Currency Conversion Rates" - self.pbFileTimestampDiff[self.controls.league.selIndex] = nil - if self.pbLeague == nil then - return - end - local values_file = io.open("../"..self.pbLeague.."_currency_values.json", "r") - if values_file then - local lines = values_file:read "*a" - values_file:close() - self.pbCurrencyConversion[self.pbLeague] = dkjson.decode(lines) - self.lastCurrencyFileTime[self.controls.league.selIndex] = self.pbCurrencyConversion[self.pbLeague]["updateTime"] - self.pbFileTimestampDiff[self.controls.league.selIndex] = get_time() - self.lastCurrencyFileTime[self.controls.league.selIndex] - if self.pbFileTimestampDiff[self.controls.league.selIndex] < 3600 then - -- Less than 1 hour (60 * 60 = 3600) - currencyLabel = "Currency Rates are very recent" - elseif self.pbFileTimestampDiff[self.controls.league.selIndex] < (24 * 3600) then - -- Less than 1 day - currencyLabel = "Currency Rates are recent" - end - else - currencyLabel = "Get Currency Conversion Rates" - end - self.controls.updateCurrencyConversion.label = currencyLabel - self.controls.updateCurrencyConversion.enabled = function() - return self.pbFileTimestampDiff[self.controls.league.selIndex] == nil or self.pbFileTimestampDiff[self.controls.league.selIndex] >= 3600 - end - self.controls.updateCurrencyConversion.tooltipFunc = function(tooltip) - tooltip:Clear() - if self.lastCurrencyFileTime[self.controls.league.selIndex] ~= nil then - self.pbFileTimestampDiff[self.controls.league.selIndex] = get_time() - self.lastCurrencyFileTime[self.controls.league.selIndex] - end - if self.pbFileTimestampDiff[self.controls.league.selIndex] == nil or self.pbFileTimestampDiff[self.controls.league.selIndex] >= 3600 then - tooltip:AddLine(16, "Currency Conversion rates are pulled from PoE Ninja") - tooltip:AddLine(16, "Updates are limited to once per hour and not necessary more than once per day") - elseif self.pbFileTimestampDiff[self.controls.league.selIndex] ~= nil and self.pbFileTimestampDiff[self.controls.league.selIndex] < 3600 then - tooltip:AddLine(16, "Conversion Rates are less than an hour old (" .. tostring(self.pbFileTimestampDiff[self.controls.league.selIndex]) .. " seconds old)") - end - end -end - -- Method to set the notice message in upper right of PoB Trader pane function TradeQueryClass:SetNotice(notice_control, msg) if msg:find("No Matching Results") then @@ -868,9 +891,8 @@ function TradeQueryClass:UpdateControlsWithItems(row_idx) local sortMode = self.itemSortSelectionList[self.pbItemSortSelectionIndex] local sortedItems, errMsg = self:SortFetchResults(row_idx, sortMode) if errMsg == "MissingConversionRates" then - self:SetNotice(self.controls.pbNotice, "^4Please update currency rates to sort by price. Falling back to Stat Value sort.") + self:SetNotice(self.controls.pbNotice, "^4Currency rates unavailable. Falling back to Stat Value sort.") sortedItems, errMsg = self:SortFetchResults(row_idx, self.sortModes.StatValue) - return elseif errMsg then self:SetNotice(self.controls.pbNotice, "Error: " .. errMsg) return @@ -1301,8 +1323,10 @@ function TradeQueryClass:GetTotalPriceString() for currency, _ in pairs(prices) do table.insert(currencies, currency) end - local currencyMap = self.pbCurrencyConversion[self.pbLeague] or {} - table.sort(currencies, function (a, b) + local currencyMap = self.pbCurrencyConversion[self.pbRealm] and + self.pbCurrencyConversion[self.pbRealm][self.pbLeague] + or {} + table.sort(currencies, function(a, b) if currencyMap[a] and currencyMap[b] then return currencyMap[a] > currencyMap[b] else diff --git a/src/Classes/TradeQueryRequests.lua b/src/Classes/TradeQueryRequests.lua index 2290bfcf26..56e3720b71 100644 --- a/src/Classes/TradeQueryRequests.lua +++ b/src/Classes/TradeQueryRequests.lua @@ -408,7 +408,7 @@ function TradeQueryRequestsClass:FetchResultBlock(url, callback) s = s .. string.format("{%s}", flagName) end end - return escapeGGGString(modLine.description) + return s .. escapeGGGString(modLine.description) end t_insert(rawLines, "Implicits: " .. (#item.enchantMods + #item.runeMods + #item.implicitMods)) for _, modLine in ipairs(item.enchantMods or {}) do diff --git a/src/Data/CurrencyNames.lua b/src/Data/CurrencyNames.lua new file mode 100644 index 0000000000..9ef00b81f0 --- /dev/null +++ b/src/Data/CurrencyNames.lua @@ -0,0 +1,457 @@ +-- This file is automatically generated, do not edit! +-- Game data (c) Grinding Gear Games + +-- This file contains mapping item names for every currency base item type ID. +-- Used for working with the currency exchange which uses item type IDs. + +-- spell-checker: disable +return { + ["Metadata/Items/AtlasExiles/AddModToRareCrusader"] = "Crusader's Exalted Orb", + ["Metadata/Items/AtlasExiles/AddModToRareHunter"] = "Hunter's Exalted Orb", + ["Metadata/Items/AtlasExiles/AddModToRareRedeemer"] = "Redeemer's Exalted Orb", + ["Metadata/Items/AtlasExiles/AddModToRareWarlord"] = "Warlord's Exalted Orb", + ["Metadata/Items/AtlasExiles/ApplyInfluence"] = "Awakener's Orb", + ["Metadata/Items/Currency/AbyssalBenchTicketArmour"] = "Preserved Rib", + ["Metadata/Items/Currency/AbyssalBenchTicketArmourHigh"] = "Ancient Rib", + ["Metadata/Items/Currency/AbyssalBenchTicketArmourLow"] = "Gnawed Rib", + ["Metadata/Items/Currency/AbyssalBenchTicketBreach"] = "Altered Collarbone", + ["Metadata/Items/Currency/AbyssalBenchTicketJewel"] = "Preserved Cranium", + ["Metadata/Items/Currency/AbyssalBenchTicketJewellery"] = "Preserved Collarbone", + ["Metadata/Items/Currency/AbyssalBenchTicketJewelleryHigh"] = "Ancient Collarbone", + ["Metadata/Items/Currency/AbyssalBenchTicketJewelleryLow"] = "Gnawed Collarbone", + ["Metadata/Items/Currency/AbyssalBenchTicketWaystone"] = "Preserved Vertebrae", + ["Metadata/Items/Currency/AbyssalBenchTicketWeapon"] = "Preserved Jawbone", + ["Metadata/Items/Currency/AbyssalBenchTicketWeaponHigh"] = "Ancient Jawbone", + ["Metadata/Items/Currency/AbyssalBenchTicketWeaponLow"] = "Gnawed Jawbone", + ["Metadata/Items/Currency/Bestiary/BestiaryNet1"] = "Simple Rope Net", + ["Metadata/Items/Currency/Bestiary/BestiaryNet10"] = "Thaumaturgical Net", + ["Metadata/Items/Currency/Bestiary/BestiaryNet11"] = "Necromancy Net", + ["Metadata/Items/Currency/Bestiary/BestiaryNet2"] = "Reinforced Rope Net", + ["Metadata/Items/Currency/Bestiary/BestiaryNet3"] = "Strong Rope Net", + ["Metadata/Items/Currency/Bestiary/BestiaryNet4"] = "Simple Iron Net", + ["Metadata/Items/Currency/Bestiary/BestiaryNet5"] = "Reinforced Iron Net", + ["Metadata/Items/Currency/Bestiary/BestiaryNet6"] = "Strong Iron Net", + ["Metadata/Items/Currency/Bestiary/BestiaryNet7"] = "Simple Steel Net", + ["Metadata/Items/Currency/Bestiary/BestiaryNet8"] = "Reinforced Steel Net", + ["Metadata/Items/Currency/Bestiary/BestiaryNet9"] = "Strong Steel Net", + ["Metadata/Items/Currency/CurrencyAddAtlasMod"] = "Simple Sextant", + ["Metadata/Items/Currency/CurrencyAddAtlasModHigh"] = "Awakened Sextant", + ["Metadata/Items/Currency/CurrencyAddAtlasModMaven"] = "Elevated Sextant", + ["Metadata/Items/Currency/CurrencyAddAtlasModMid"] = "Prime Sextant", + ["Metadata/Items/Currency/CurrencyAddEquipmentSocket"] = "Artificer's Orb", + ["Metadata/Items/Currency/CurrencyAddEquipmentSocketShard"] = "Artificer's Shard", + ["Metadata/Items/Currency/CurrencyAddGemExperience"] = "Facetor's Lens", + ["Metadata/Items/Currency/CurrencyAddModToMagic"] = "Orb of Augmentation", + ["Metadata/Items/Currency/CurrencyAddModToMagic2"] = "Greater Orb of Augmentation", + ["Metadata/Items/Currency/CurrencyAddModToMagic3"] = "Perfect Orb of Augmentation", + ["Metadata/Items/Currency/CurrencyAddModToRare"] = "Exalted Orb", + ["Metadata/Items/Currency/CurrencyAddModToRare2"] = "Greater Exalted Orb", + ["Metadata/Items/Currency/CurrencyAddModToRare3"] = "Perfect Exalted Orb", + ["Metadata/Items/Currency/CurrencyAddModToRareShard"] = "Exalted Shard", + ["Metadata/Items/Currency/CurrencyAddSkillGemSocket3"] = "Lesser Jeweller's Orb", + ["Metadata/Items/Currency/CurrencyAddSkillGemSocket4"] = "Greater Jeweller's Orb", + ["Metadata/Items/Currency/CurrencyAddSkillGemSocket5"] = "Perfect Jeweller's Orb", + ["Metadata/Items/Currency/CurrencyAfflictionShard"] = "Simulacrum Splinter", + ["Metadata/Items/Currency/CurrencyArcaneFluxChaos"] = "Void Flux", + ["Metadata/Items/Currency/CurrencyArcaneFluxCold"] = "Chilling Flux", + ["Metadata/Items/Currency/CurrencyArcaneFluxFire"] = "Blazing Flux", + ["Metadata/Items/Currency/CurrencyArcaneFluxLightning"] = "Crackling Flux", + ["Metadata/Items/Currency/CurrencyArmourQuality"] = "Armourer's Scrap", + ["Metadata/Items/Currency/CurrencyAtlasPassiveRefund"] = "Orb of Unmaking", + ["Metadata/Items/Currency/CurrencyBreachChaosShard"] = "Splinter of Chayula", + ["Metadata/Items/Currency/CurrencyBreachColdShard"] = "Splinter of Tul", + ["Metadata/Items/Currency/CurrencyBreachFireShard"] = "Splinter of Xoph", + ["Metadata/Items/Currency/CurrencyBreachLightningShard"] = "Splinter of Esh", + ["Metadata/Items/Currency/CurrencyBreachPhysicalShard"] = "Splinter of Uul-Netol", + ["Metadata/Items/Currency/CurrencyBreachShard"] = "Breach Splinter", + ["Metadata/Items/Currency/CurrencyBreachUpgradeUniqueChaos"] = "Blessing of Chayula", + ["Metadata/Items/Currency/CurrencyBreachUpgradeUniqueCold"] = "Blessing of Tul", + ["Metadata/Items/Currency/CurrencyBreachUpgradeUniqueFire"] = "Blessing of Xoph", + ["Metadata/Items/Currency/CurrencyBreachUpgradeUniqueLightning"] = "Blessing of Esh", + ["Metadata/Items/Currency/CurrencyBreachUpgradeUniquePhysical"] = "Blessing of Uul-Netol", + ["Metadata/Items/Currency/CurrencyConflictOrb"] = "Orb of Conflict", + ["Metadata/Items/Currency/CurrencyConvertStrongboxToNormal"] = "[DNT] Box Scour", + ["Metadata/Items/Currency/CurrencyConvertToNormal"] = "Orb of Scouring", + ["Metadata/Items/Currency/CurrencyCorrupt"] = "Vaal Orb", + ["Metadata/Items/Currency/CurrencyCorruptedEssenceAbyss"] = "Essence of the Abyss", + ["Metadata/Items/Currency/CurrencyCorruptedEssenceBreach"] = "Essence of the Breach", + ["Metadata/Items/Currency/CurrencyCorruptedEssenceDelirium"] = "Essence of Delirium", + ["Metadata/Items/Currency/CurrencyCorruptedEssenceHorror"] = "Essence of Horror", + ["Metadata/Items/Currency/CurrencyCorruptedEssenceHysteria"] = "Essence of Hysteria", + ["Metadata/Items/Currency/CurrencyCorruptedEssenceInsanity"] = "Essence of Insanity", + ["Metadata/Items/Currency/CurrencyDelveCraftingAbyss"] = "Hollow Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingAttackMods"] = "Serrated Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingBleedPoison"] = "Corroded Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingCasterMods"] = "Aetheric Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingChaos"] = "Aberrant Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingCold"] = "Frigid Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingCorruptEssence"] = "Glyphic Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingDefences"] = "Dense Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingElemental"] = "Prismatic Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingEnchant"] = "Deft Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingFire"] = "Scorched Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingGemLevel"] = "Faceted Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingLife"] = "Pristine Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingLightning"] = "Metallic Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingLuckyModRolls"] = "Sanctified Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingMana"] = "Lucent Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingMinionsAuras"] = "Bound Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingMirror"] = "Fractured Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingPhysical"] = "Jagged Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingQuality"] = "Perfect Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingRandom"] = "Tangled Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingSellPrice"] = "Gilded Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingSockets"] = "Fundamental Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingSpeed"] = "Shuddering Fossil", + ["Metadata/Items/Currency/CurrencyDelveCraftingVaal"] = "Bloodstained Fossil", + ["Metadata/Items/Currency/CurrencyDuplicate"] = "Mirror of Kalandra", + ["Metadata/Items/Currency/CurrencyDuplicateShard"] = "Mirror Shard", + ["Metadata/Items/Currency/CurrencyEldritchAddModToRare"] = "Eldritch Exalted Orb", + ["Metadata/Items/Currency/CurrencyEldritchEmber1"] = "Lesser Eldritch Ember", + ["Metadata/Items/Currency/CurrencyEldritchEmber2"] = "Greater Eldritch Ember", + ["Metadata/Items/Currency/CurrencyEldritchEmber3"] = "Grand Eldritch Ember", + ["Metadata/Items/Currency/CurrencyEldritchEmber4"] = "Exceptional Eldritch Ember", + ["Metadata/Items/Currency/CurrencyEldritchIchor1"] = "Lesser Eldritch Ichor", + ["Metadata/Items/Currency/CurrencyEldritchIchor2"] = "Greater Eldritch Ichor", + ["Metadata/Items/Currency/CurrencyEldritchIchor3"] = "Grand Eldritch Ichor", + ["Metadata/Items/Currency/CurrencyEldritchIchor4"] = "Exceptional Eldritch Ichor", + ["Metadata/Items/Currency/CurrencyEldritchRemoveMod"] = "Eldritch Orb of Annulment", + ["Metadata/Items/Currency/CurrencyEldritchRerollRare"] = "Eldritch Chaos Orb", + ["Metadata/Items/Currency/CurrencyEnkindlingOrb"] = "Enkindling Orb", + ["Metadata/Items/Currency/CurrencyEssenceAlly"] = "Essence of Command", + ["Metadata/Items/Currency/CurrencyEssenceAttack"] = "Essence of Battle", + ["Metadata/Items/Currency/CurrencyEssenceAttribute"] = "Essence of the Infinite", + ["Metadata/Items/Currency/CurrencyEssenceCaster"] = "Essence of Sorcery", + ["Metadata/Items/Currency/CurrencyEssenceChaos"] = "Essence of Ruin", + ["Metadata/Items/Currency/CurrencyEssenceCold"] = "Essence of Ice", + ["Metadata/Items/Currency/CurrencyEssenceColdResist"] = "Essence of Thawing", + ["Metadata/Items/Currency/CurrencyEssenceCritical"] = "Essence of Seeking", + ["Metadata/Items/Currency/CurrencyEssenceDefences"] = "Essence of Enhancement", + ["Metadata/Items/Currency/CurrencyEssenceFire"] = "Essence of Flames", + ["Metadata/Items/Currency/CurrencyEssenceFireResist"] = "Essence of Insulation", + ["Metadata/Items/Currency/CurrencyEssenceLife"] = "Essence of the Body", + ["Metadata/Items/Currency/CurrencyEssenceLightning"] = "Essence of Electricity", + ["Metadata/Items/Currency/CurrencyEssenceLightningResist"] = "Essence of Grounding", + ["Metadata/Items/Currency/CurrencyEssenceMana"] = "Essence of the Mind", + ["Metadata/Items/Currency/CurrencyEssencePhysical"] = "Essence of Abrasion", + ["Metadata/Items/Currency/CurrencyEssenceRarity"] = "Essence of Opulence", + ["Metadata/Items/Currency/CurrencyEssenceSpeed"] = "Essence of Haste", + ["Metadata/Items/Currency/CurrencyEssenceSpeedCaster"] = "Essence of Alacrity", + ["Metadata/Items/Currency/CurrencyExpeditionShard"] = "Runic Splinter", + ["Metadata/Items/Currency/CurrencyExtractOil"] = "Oil Extractor", + ["Metadata/Items/Currency/CurrencyFlaskQuality"] = "Glassblower's Bauble", + ["Metadata/Items/Currency/CurrencyFractureRare"] = "Fracturing Orb", + ["Metadata/Items/Currency/CurrencyFractureRareShard"] = "Fracturing Shard", + ["Metadata/Items/Currency/CurrencyGemQuality"] = "Gemcutter's Prism", + ["Metadata/Items/Currency/CurrencyGreaterEssenceAlly"] = "Greater Essence of Command", + ["Metadata/Items/Currency/CurrencyGreaterEssenceAttack"] = "Greater Essence of Battle", + ["Metadata/Items/Currency/CurrencyGreaterEssenceAttribute"] = "Greater Essence of the Infinite", + ["Metadata/Items/Currency/CurrencyGreaterEssenceCaster"] = "Greater Essence of Sorcery", + ["Metadata/Items/Currency/CurrencyGreaterEssenceChaos"] = "Greater Essence of Ruin", + ["Metadata/Items/Currency/CurrencyGreaterEssenceCold"] = "Greater Essence of Ice", + ["Metadata/Items/Currency/CurrencyGreaterEssenceColdResist"] = "Greater Essence of Thawing", + ["Metadata/Items/Currency/CurrencyGreaterEssenceCritical"] = "Greater Essence of Seeking", + ["Metadata/Items/Currency/CurrencyGreaterEssenceDefences"] = "Greater Essence of Enhancement", + ["Metadata/Items/Currency/CurrencyGreaterEssenceFire"] = "Greater Essence of Flames", + ["Metadata/Items/Currency/CurrencyGreaterEssenceFireResist"] = "Greater Essence of Insulation", + ["Metadata/Items/Currency/CurrencyGreaterEssenceLife"] = "Greater Essence of the Body", + ["Metadata/Items/Currency/CurrencyGreaterEssenceLightning"] = "Greater Essence of Electricity", + ["Metadata/Items/Currency/CurrencyGreaterEssenceLightningResist"] = "Greater Essence of Grounding", + ["Metadata/Items/Currency/CurrencyGreaterEssenceMana"] = "Greater Essence of the Mind", + ["Metadata/Items/Currency/CurrencyGreaterEssencePhysical"] = "Greater Essence of Abrasion", + ["Metadata/Items/Currency/CurrencyGreaterEssenceRarity"] = "Greater Essence of Opulence", + ["Metadata/Items/Currency/CurrencyGreaterEssenceSpeed"] = "Greater Essence of Haste", + ["Metadata/Items/Currency/CurrencyGreaterEssenceSpeedCaster"] = "Greater Essence of Alacrity", + ["Metadata/Items/Currency/CurrencyHarbingerBlessingBelt"] = "Time-light Scroll", + ["Metadata/Items/Currency/CurrencyHarbingerBlessingHelmet"] = "Deregulation Scroll", + ["Metadata/Items/Currency/CurrencyHarbingerBlessingQuiver"] = "Fragmentation Scroll", + ["Metadata/Items/Currency/CurrencyHarbingerBlessingShield"] = "Specularity Scroll", + ["Metadata/Items/Currency/CurrencyHarbingerBlessingStaff"] = "Haemocombustion Scroll", + ["Metadata/Items/Currency/CurrencyHarbingerBlessingSword"] = "Electroshock Scroll", + ["Metadata/Items/Currency/CurrencyHeistArmourEnchant"] = "Tailoring Orb", + ["Metadata/Items/Currency/CurrencyHeistWeaponEnchant"] = "Tempering Orb", + ["Metadata/Items/Currency/CurrencyHellscapeAddModToRare"] = "Tainted Exalted Orb", + ["Metadata/Items/Currency/CurrencyHellscapeArmourQuality"] = "Tainted Armourer's Scrap", + ["Metadata/Items/Currency/CurrencyHellscapeRerollRare"] = "Tainted Chaos Orb", + ["Metadata/Items/Currency/CurrencyHellscapeRerollSocketColours"] = "Tainted Chromatic Orb", + ["Metadata/Items/Currency/CurrencyHellscapeRerollSocketLinks"] = "Tainted Orb of Fusing", + ["Metadata/Items/Currency/CurrencyHellscapeRerollSocketNumbers"] = "Tainted Jeweller's Orb", + ["Metadata/Items/Currency/CurrencyHellscapeUpgradeModTier"] = "Tainted Divine Teardrop", + ["Metadata/Items/Currency/CurrencyHellscapeUpgradeToUnique"] = "Tainted Mythic Orb", + ["Metadata/Items/Currency/CurrencyHellscapeWeaponQuality"] = "Tainted Blacksmith's Whetstone", + ["Metadata/Items/Currency/CurrencyHinekorasLock"] = "Hinekora's Lock", + ["Metadata/Items/Currency/CurrencyIdentification"] = "Scroll of Wisdom", + ["Metadata/Items/Currency/CurrencyIdentificationShard"] = "Scroll Fragment", + ["Metadata/Items/Currency/CurrencyImprint"] = "Imprint", + ["Metadata/Items/Currency/CurrencyImprintOrb"] = "Eternal Orb", + ["Metadata/Items/Currency/CurrencyIncursionAddModToRareEquipment"] = "[DNT] Not Shown To Players", + ["Metadata/Items/Currency/CurrencyIncursionBetterGemQuality"] = "[DNT] Incursion Gemcutter's Prism (not visible to players)", + ["Metadata/Items/Currency/CurrencyIncursionCasterWeaponQuality"] = "Vaal Arcanist's Infuser", + ["Metadata/Items/Currency/CurrencyIncursionCorrupt1"] = "Corrupt", + ["Metadata/Items/Currency/CurrencyIncursionCorruptTablet"] = "Ancient Infuser", + ["Metadata/Items/Currency/CurrencyIncursionDoubleCorrupt"] = "Architect's Orb", + ["Metadata/Items/Currency/CurrencyIncursionDoubleCorruptGem"] = "Crystallised Corruption", + ["Metadata/Items/Currency/CurrencyIncursionExtractAllSocketablesBench"] = "Orb of Extraction", + ["Metadata/Items/Currency/CurrencyIncursionExtractAllSocketablesCurrency"] = "Orb of Extraction", + ["Metadata/Items/Currency/CurrencyIncursionJewelleryQuality"] = "Vaal Catalysing Infuser", + ["Metadata/Items/Currency/CurrencyIncursionMartialWeaponQuality"] = "Vaal Blacksmith's Infuser", + ["Metadata/Items/Currency/CurrencyIncursionModifySoulCore"] = "Core Destabiliser", + ["Metadata/Items/Currency/CurrencyIncursionMutateCorruptionEnchantArmour"] = "Kopec's Orb of Sacrifice", + ["Metadata/Items/Currency/CurrencyIncursionMutateCorruptionEnchantJewel"] = "Yugul's Orb of Sacrifice", + ["Metadata/Items/Currency/CurrencyIncursionMutateCorruptionEnchantJewellery"] = "Kamasa's Orb of Sacrifice", + ["Metadata/Items/Currency/CurrencyIncursionMutateCorruptionEnchantWeapon"] = "Yaomac's Orb of Sacrifice", + ["Metadata/Items/Currency/CurrencyIncursionMutateUnique"] = "Vaal Cultivation Orb", + ["Metadata/Items/Currency/CurrencyIncursionUpgradeMagicToRareEquipment"] = "[DNT] Not Shown To Players", + ["Metadata/Items/Currency/CurrencyIncursionUpgradeToRareEquipment"] = "[DNT] Not Shown To Players", + ["Metadata/Items/Currency/CurrencyIncursionVialBossAmulet"] = "Vial of Sacrifice", + ["Metadata/Items/Currency/CurrencyIncursionVialBossFlask"] = "Vial of the Ghost", + ["Metadata/Items/Currency/CurrencyIncursionVialBossJewel"] = "Vial of Transcendence", + ["Metadata/Items/Currency/CurrencyIncursionVialFire"] = "Vial of Fate", + ["Metadata/Items/Currency/CurrencyIncursionVialHealing"] = "Vial of Summoning", + ["Metadata/Items/Currency/CurrencyIncursionVialLightning"] = "Vial of the Ritual", + ["Metadata/Items/Currency/CurrencyIncursionVialMinion"] = "Vial of Consequence", + ["Metadata/Items/Currency/CurrencyIncursionVialPoison"] = "Vial of Awakening", + ["Metadata/Items/Currency/CurrencyIncursionVialTrap"] = "Vial of Dominance", + ["Metadata/Items/Currency/CurrencyIncursionWeaponOrArmourQualityHigh"] = "Vaal Armourer's Infuser", + ["Metadata/Items/Currency/CurrencyIncursionWeaponOrArmourQualityLow"] = "[DNT] Not Shown To Players", + ["Metadata/Items/Currency/CurrencyIncursionWeaponOrArmourQualityMid"] = "[DNT] Not Shown To Players", + ["Metadata/Items/Currency/CurrencyInstillingOrb"] = "Instilling Orb", + ["Metadata/Items/Currency/CurrencyItemiseCapturedMonster"] = "Bestiary Orb", + ["Metadata/Items/Currency/CurrencyItemiseSextantModifier"] = "Surveyor's Compass", + ["Metadata/Items/Currency/CurrencyItemisedCapturedMonster"] = "Imprinted Bestiary Orb", + ["Metadata/Items/Currency/CurrencyItemisedProphecy"] = "Prophecy", + ["Metadata/Items/Currency/CurrencyItemisedSextantModifier"] = "Charged Compass", + ["Metadata/Items/Currency/CurrencyJewelQualityAttack"] = "Refined Reaver Catalyst", + ["Metadata/Items/Currency/CurrencyJewelQualityAttribute"] = "Refined Adaptive Catalyst", + ["Metadata/Items/Currency/CurrencyJewelQualityCaster"] = "Refined Sibilant Catalyst", + ["Metadata/Items/Currency/CurrencyJewelQualityChaos"] = "Refined Chayula's Catalyst", + ["Metadata/Items/Currency/CurrencyJewelQualityCold"] = "Refined Tul's Catalyst", + ["Metadata/Items/Currency/CurrencyJewelQualityDefences"] = "Refined Carapace Catalyst", + ["Metadata/Items/Currency/CurrencyJewelQualityFire"] = "Refined Xoph's Catalyst", + ["Metadata/Items/Currency/CurrencyJewelQualityLife"] = "Refined Flesh Catalyst", + ["Metadata/Items/Currency/CurrencyJewelQualityLightning"] = "Refined Esh's Catalyst", + ["Metadata/Items/Currency/CurrencyJewelQualityMana"] = "Refined Neural Catalyst", + ["Metadata/Items/Currency/CurrencyJewelQualityMinion"] = "Refined Necrotic Catalyst", + ["Metadata/Items/Currency/CurrencyJewelQualityPhysical"] = "Refined Uul-Netol's Catalyst", + ["Metadata/Items/Currency/CurrencyJewelQualitySpeed"] = "Refined Skittering Catalyst", + ["Metadata/Items/Currency/CurrencyJewelleryQualityAttack"] = "Reaver Catalyst", + ["Metadata/Items/Currency/CurrencyJewelleryQualityAttribute"] = "Adaptive Catalyst", + ["Metadata/Items/Currency/CurrencyJewelleryQualityCaster"] = "Sibilant Catalyst", + ["Metadata/Items/Currency/CurrencyJewelleryQualityChaos"] = "Chayula's Catalyst", + ["Metadata/Items/Currency/CurrencyJewelleryQualityCold"] = "Tul's Catalyst", + ["Metadata/Items/Currency/CurrencyJewelleryQualityDefences"] = "Carapace Catalyst", + ["Metadata/Items/Currency/CurrencyJewelleryQualityFire"] = "Xoph's Catalyst", + ["Metadata/Items/Currency/CurrencyJewelleryQualityLife"] = "Flesh Catalyst", + ["Metadata/Items/Currency/CurrencyJewelleryQualityLightning"] = "Esh's Catalyst", + ["Metadata/Items/Currency/CurrencyJewelleryQualityMana"] = "Neural Catalyst", + ["Metadata/Items/Currency/CurrencyJewelleryQualityMinion"] = "Necrotic Catalyst", + ["Metadata/Items/Currency/CurrencyJewelleryQualityPhysical"] = "Uul-Netol's Catalyst", + ["Metadata/Items/Currency/CurrencyJewelleryQualitySpeed"] = "Skittering Catalyst", + ["Metadata/Items/Currency/CurrencyKiwiFeather"] = "Jade Kiwi Feather", + ["Metadata/Items/Currency/CurrencyLegionEternalEmpireShard"] = "Timeless Eternal Empire Splinter", + ["Metadata/Items/Currency/CurrencyLegionKaruiShard"] = "Timeless Karui Splinter", + ["Metadata/Items/Currency/CurrencyLegionMarakethShard"] = "Timeless Maraketh Splinter", + ["Metadata/Items/Currency/CurrencyLegionTemplarShard"] = "Timeless Templar Splinter", + ["Metadata/Items/Currency/CurrencyLegionVaalShard"] = "Timeless Vaal Splinter", + ["Metadata/Items/Currency/CurrencyLesserEssenceAlly"] = "Lesser Essence of Command", + ["Metadata/Items/Currency/CurrencyLesserEssenceAttack"] = "Lesser Essence of Battle", + ["Metadata/Items/Currency/CurrencyLesserEssenceAttribute"] = "Lesser Essence of the Infinite", + ["Metadata/Items/Currency/CurrencyLesserEssenceCaster"] = "Lesser Essence of Sorcery", + ["Metadata/Items/Currency/CurrencyLesserEssenceChaos"] = "Lesser Essence of Ruin", + ["Metadata/Items/Currency/CurrencyLesserEssenceCold"] = "Lesser Essence of Ice", + ["Metadata/Items/Currency/CurrencyLesserEssenceColdResist"] = "Lesser Essence of Thawing", + ["Metadata/Items/Currency/CurrencyLesserEssenceCritical"] = "Lesser Essence of Seeking", + ["Metadata/Items/Currency/CurrencyLesserEssenceDefences"] = "Lesser Essence of Enhancement", + ["Metadata/Items/Currency/CurrencyLesserEssenceFire"] = "Lesser Essence of Flames", + ["Metadata/Items/Currency/CurrencyLesserEssenceFireResist"] = "Lesser Essence of Insulation", + ["Metadata/Items/Currency/CurrencyLesserEssenceLife"] = "Lesser Essence of the Body", + ["Metadata/Items/Currency/CurrencyLesserEssenceLightning"] = "Lesser Essence of Electricity", + ["Metadata/Items/Currency/CurrencyLesserEssenceLightningResist"] = "Lesser Essence of Grounding", + ["Metadata/Items/Currency/CurrencyLesserEssenceMana"] = "Lesser Essence of the Mind", + ["Metadata/Items/Currency/CurrencyLesserEssencePhysical"] = "Lesser Essence of Abrasion", + ["Metadata/Items/Currency/CurrencyLesserEssenceRarity"] = "Lesser Essence of Opulence", + ["Metadata/Items/Currency/CurrencyLesserEssenceSpeed"] = "Lesser Essence of Haste", + ["Metadata/Items/Currency/CurrencyLesserEssenceSpeedCaster"] = "Lesser Essence of Alacrity", + ["Metadata/Items/Currency/CurrencyMagicQuality"] = "Arcanist's Etcher", + ["Metadata/Items/Currency/CurrencyMapQuality"] = "Cartographer's Chisel", + ["Metadata/Items/Currency/CurrencyModValues"] = "Divine Orb", + ["Metadata/Items/Currency/CurrencyPassiveRefund"] = "Orb of Regret", + ["Metadata/Items/Currency/CurrencyPeacockFeather"] = "Stygian Peacock Feather", + ["Metadata/Items/Currency/CurrencyPerandusCoin"] = "Perandus Coin", + ["Metadata/Items/Currency/CurrencyPerfectEssenceAlly"] = "Perfect Essence of Command", + ["Metadata/Items/Currency/CurrencyPerfectEssenceAttack"] = "Perfect Essence of Battle", + ["Metadata/Items/Currency/CurrencyPerfectEssenceAttribute"] = "Perfect Essence of the Infinite", + ["Metadata/Items/Currency/CurrencyPerfectEssenceCaster"] = "Perfect Essence of Sorcery", + ["Metadata/Items/Currency/CurrencyPerfectEssenceChaos"] = "Perfect Essence of Ruin", + ["Metadata/Items/Currency/CurrencyPerfectEssenceCold"] = "Perfect Essence of Ice", + ["Metadata/Items/Currency/CurrencyPerfectEssenceColdResist"] = "Perfect Essence of Thawing", + ["Metadata/Items/Currency/CurrencyPerfectEssenceCritical"] = "Perfect Essence of Seeking", + ["Metadata/Items/Currency/CurrencyPerfectEssenceDefences"] = "Perfect Essence of Enhancement", + ["Metadata/Items/Currency/CurrencyPerfectEssenceFire"] = "Perfect Essence of Flames", + ["Metadata/Items/Currency/CurrencyPerfectEssenceFireResist"] = "Perfect Essence of Insulation", + ["Metadata/Items/Currency/CurrencyPerfectEssenceLife"] = "Perfect Essence of the Body", + ["Metadata/Items/Currency/CurrencyPerfectEssenceLightning"] = "Perfect Essence of Electricity", + ["Metadata/Items/Currency/CurrencyPerfectEssenceLightningResist"] = "Perfect Essence of Grounding", + ["Metadata/Items/Currency/CurrencyPerfectEssenceMana"] = "Perfect Essence of the Mind", + ["Metadata/Items/Currency/CurrencyPerfectEssencePhysical"] = "Perfect Essence of Abrasion", + ["Metadata/Items/Currency/CurrencyPerfectEssenceRarity"] = "Perfect Essence of Opulence", + ["Metadata/Items/Currency/CurrencyPerfectEssenceSpeed"] = "Perfect Essence of Haste", + ["Metadata/Items/Currency/CurrencyPerfectEssenceSpeedCaster"] = "Perfect Essence of Alacrity", + ["Metadata/Items/Currency/CurrencyPortal"] = "Portal Scroll", + ["Metadata/Items/Currency/CurrencyRefreshExpedition"] = "Exotic Coinage", + ["Metadata/Items/Currency/CurrencyRemoveMod"] = "Orb of Annulment", + ["Metadata/Items/Currency/CurrencyRemoveModShard"] = "Annulment Shard", + ["Metadata/Items/Currency/CurrencyRerollDefences"] = "Sacred Orb", + ["Metadata/Items/Currency/CurrencyRerollImplicit"] = "Blessed Orb", + ["Metadata/Items/Currency/CurrencyRerollMagic"] = "Orb of Alteration", + ["Metadata/Items/Currency/CurrencyRerollMagicShard"] = "Alteration Shard", + ["Metadata/Items/Currency/CurrencyRerollMapType"] = "Orb of Horizons", + ["Metadata/Items/Currency/CurrencyRerollMapTypeShard"] = "Horizon Shard", + ["Metadata/Items/Currency/CurrencyRerollRare"] = "Chaos Orb", + ["Metadata/Items/Currency/CurrencyRerollRare2"] = "Greater Chaos Orb", + ["Metadata/Items/Currency/CurrencyRerollRare3"] = "Perfect Chaos Orb", + ["Metadata/Items/Currency/CurrencyRerollRareShard"] = "Chaos Shard", + ["Metadata/Items/Currency/CurrencyRerollRemnant"] = "Liquid Verisium", + ["Metadata/Items/Currency/CurrencyRerollSkillQualityType"] = "Prime Regrading Lens", + ["Metadata/Items/Currency/CurrencyRerollSocketColours"] = "Chromatic Orb", + ["Metadata/Items/Currency/CurrencyRerollSocketLinks"] = "Orb of Fusing", + ["Metadata/Items/Currency/CurrencyRerollSupportQualityType"] = "Secondary Regrading Lens", + ["Metadata/Items/Currency/CurrencyRerollUnique"] = "Ancient Orb", + ["Metadata/Items/Currency/CurrencyRerollUniqueShard"] = "Ancient Shard", + ["Metadata/Items/Currency/CurrencyRespecShapersOrb"] = "Unshaping Orb", + ["Metadata/Items/Currency/CurrencyRhoaFeather"] = "Albino Rhoa Feather", + ["Metadata/Items/Currency/CurrencyRitualShard"] = "Petition Splinter", + ["Metadata/Items/Currency/CurrencyRitualSplinter"] = "Ritual Splinter", + ["Metadata/Items/Currency/CurrencyRitualStone"] = "Ritual Vessel", + ["Metadata/Items/Currency/CurrencySealMapHigh"] = "Master Cartographer's Seal", + ["Metadata/Items/Currency/CurrencySealMapLow"] = "Apprentice Cartographer's Seal", + ["Metadata/Items/Currency/CurrencySealMapMid"] = "Journeyman Cartographer's Seal", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel1"] = "Thaumaturgic Flux (Level 1)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel10"] = "Thaumaturgic Flux (Level 10)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel11"] = "Thaumaturgic Flux (Level 11)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel12"] = "Thaumaturgic Flux (Level 12)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel13"] = "Thaumaturgic Flux (Level 13)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel14"] = "Thaumaturgic Flux (Level 14)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel15"] = "Thaumaturgic Flux (Level 15)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel16"] = "Thaumaturgic Flux (Level 16)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel17"] = "Thaumaturgic Flux (Level 17)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel18"] = "Thaumaturgic Flux (Level 18)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel19"] = "Thaumaturgic Flux (Level 19)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel2"] = "Thaumaturgic Flux (Level 2)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel20"] = "Thaumaturgic Flux (Level 20)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel3"] = "Thaumaturgic Flux (Level 3)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel4"] = "Thaumaturgic Flux (Level 4)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel5"] = "Thaumaturgic Flux (Level 5)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel6"] = "Thaumaturgic Flux (Level 6)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel7"] = "Thaumaturgic Flux (Level 7)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel8"] = "Thaumaturgic Flux (Level 8)", + ["Metadata/Items/Currency/CurrencySetKalguuranSkillGemLevel9"] = "Thaumaturgic Flux (Level 9)", + ["Metadata/Items/Currency/CurrencySilverCoin"] = "Silver Coin", + ["Metadata/Items/Currency/CurrencySkillGemToken"] = "Uncarved Gemstone", + ["Metadata/Items/Currency/CurrencyStrongboxQuality"] = "Engineer's Orb", + ["Metadata/Items/Currency/CurrencyStrongboxQualityInfused"] = "Infused Engineer's Orb", + ["Metadata/Items/Currency/CurrencyStrongboxQualityShard"] = "Engineer's Shard", + ["Metadata/Items/Currency/CurrencyToucanFeather"] = "Rainbow Toucan Feather", + ["Metadata/Items/Currency/CurrencyUpgradeInfluenceMod"] = "Orb of Dominance", + ["Metadata/Items/Currency/CurrencyUpgradeInherentTo20"] = "Perfect Flux", + ["Metadata/Items/Currency/CurrencyUpgradeMagicToRare"] = "Regal Orb", + ["Metadata/Items/Currency/CurrencyUpgradeMagicToRare2"] = "Greater Regal Orb", + ["Metadata/Items/Currency/CurrencyUpgradeMagicToRare3"] = "Perfect Regal Orb", + ["Metadata/Items/Currency/CurrencyUpgradeMagicToRareShard"] = "Regal Shard", + ["Metadata/Items/Currency/CurrencyUpgradeMapTier"] = "Harbinger's Orb", + ["Metadata/Items/Currency/CurrencyUpgradeMapTierShard"] = "Harbinger's Shard", + ["Metadata/Items/Currency/CurrencyUpgradeRandomly"] = "Orb of Chance", + ["Metadata/Items/Currency/CurrencyUpgradeRandomlyShard"] = "Chance Shard", + ["Metadata/Items/Currency/CurrencyUpgradeToMagic"] = "Orb of Transmutation", + ["Metadata/Items/Currency/CurrencyUpgradeToMagic2"] = "Greater Orb of Transmutation", + ["Metadata/Items/Currency/CurrencyUpgradeToMagic3"] = "Perfect Orb of Transmutation", + ["Metadata/Items/Currency/CurrencyUpgradeToMagicShard"] = "Transmutation Shard", + ["Metadata/Items/Currency/CurrencyUpgradeToRare"] = "Orb of Alchemy", + ["Metadata/Items/Currency/CurrencyUpgradeToRareAndSetSockets"] = "Orb of Binding", + ["Metadata/Items/Currency/CurrencyUpgradeToRareAndSetSocketsShard"] = "Binding Shard", + ["Metadata/Items/Currency/CurrencyUpgradeToRareShard"] = "Alchemy Shard", + ["Metadata/Items/Currency/CurrencyVerisiumAlloy1"] = "Runic Alloy", + ["Metadata/Items/Currency/CurrencyVerisiumAlloy10"] = "Celestial Alloy", + ["Metadata/Items/Currency/CurrencyVerisiumAlloy11"] = "Transcendent Alloy", + ["Metadata/Items/Currency/CurrencyVerisiumAlloy12"] = "The Runebinder's Alloy", + ["Metadata/Items/Currency/CurrencyVerisiumAlloy13"] = "The Runefather's Alloy", + ["Metadata/Items/Currency/CurrencyVerisiumAlloy2"] = "Adaptive Alloy", + ["Metadata/Items/Currency/CurrencyVerisiumAlloy3"] = "Protective Alloy", + ["Metadata/Items/Currency/CurrencyVerisiumAlloy4"] = "Expansive Alloy", + ["Metadata/Items/Currency/CurrencyVerisiumAlloy5"] = "Swift Alloy", + ["Metadata/Items/Currency/CurrencyVerisiumAlloy6"] = "Cyclonic Alloy", + ["Metadata/Items/Currency/CurrencyVerisiumAlloy7"] = "Prismatic Alloy", + ["Metadata/Items/Currency/CurrencyVerisiumAlloy8"] = "Mystic Alloy", + ["Metadata/Items/Currency/CurrencyVerisiumAlloy9"] = "Sovereign Alloy", + ["Metadata/Items/Currency/CurrencyVerisiumMetal1"] = "Verisium", + ["Metadata/Items/Currency/CurrencyVerisiumMetal2"] = "Exceptional Verisium", + ["Metadata/Items/Currency/CurrencyVerisiumMetalBreach1"] = "Mutated Verisium", + ["Metadata/Items/Currency/CurrencyVerisiumMetalKalguur1"] = "Founders Verisium", + ["Metadata/Items/Currency/CurrencyVerisiumMetalUnique1"] = "Medved's Crest of the Circle", + ["Metadata/Items/Currency/CurrencyVerisiumMetalUnique2"] = "Vorana's Crest of the Scythe", + ["Metadata/Items/Currency/CurrencyVerisiumMetalUnique3"] = "Uhtred's Crest of the Chalice", + ["Metadata/Items/Currency/CurrencyVerisiumMetalUnique4"] = "Olroth's Crest of the Sun", + ["Metadata/Items/Currency/CurrencyVerisiumMetalVaal1"] = "Corrupted Verisium", + ["Metadata/Items/Currency/CurrencyVerisiumOreUniqueEventidePetals"] = "Veridical Starlit Ore", + ["Metadata/Items/Currency/CurrencyVerisiumOreUniqueEyesOfTheRunefather"] = "Venerable Starlit Ore", + ["Metadata/Items/Currency/CurrencyVerisiumOreUniqueSerlesGrit"] = "Starlit Ore", + ["Metadata/Items/Currency/CurrencyVerisiumOreUniqueStolvarheim"] = "Warding Starlit Ore", + ["Metadata/Items/Currency/CurrencyVerisiumOreUniqueTheUnleashed"] = "Revered Starlit Ore", + ["Metadata/Items/Currency/CurrencyVultureFeather"] = "Golden Vulture Feather", + ["Metadata/Items/Currency/CurrencyWeaponQuality"] = "Blacksmith's Whetstone", + ["Metadata/Items/Currency/DistilledEmotion1"] = "Diluted Liquid Ire", + ["Metadata/Items/Currency/DistilledEmotion10"] = "Concentrated Liquid Isolation", + ["Metadata/Items/Currency/DistilledEmotion2"] = "Diluted Liquid Guilt", + ["Metadata/Items/Currency/DistilledEmotion3"] = "Diluted Liquid Greed", + ["Metadata/Items/Currency/DistilledEmotion4"] = "Liquid Paranoia", + ["Metadata/Items/Currency/DistilledEmotion5"] = "Liquid Envy", + ["Metadata/Items/Currency/DistilledEmotion6"] = "Liquid Disgust", + ["Metadata/Items/Currency/DistilledEmotion7"] = "Liquid Despair", + ["Metadata/Items/Currency/DistilledEmotion8"] = "Concentrated Liquid Fear", + ["Metadata/Items/Currency/DistilledEmotion9"] = "Concentrated Liquid Suffering", + ["Metadata/Items/Currency/DistilledEmotionTimeLost1"] = "Ancient Diluted Liquid Ire", + ["Metadata/Items/Currency/DistilledEmotionTimeLost10"] = "Ancient Concentrated Liquid Isolation", + ["Metadata/Items/Currency/DistilledEmotionTimeLost2"] = "Ancient Diluted Liquid Guilt", + ["Metadata/Items/Currency/DistilledEmotionTimeLost3"] = "Ancient Diluted Liquid Greed", + ["Metadata/Items/Currency/DistilledEmotionTimeLost4"] = "Ancient Liquid Paranoia", + ["Metadata/Items/Currency/DistilledEmotionTimeLost5"] = "Ancient Liquid Envy", + ["Metadata/Items/Currency/DistilledEmotionTimeLost6"] = "Ancient Liquid Disgust", + ["Metadata/Items/Currency/DistilledEmotionTimeLost7"] = "Ancient Liquid Despair", + ["Metadata/Items/Currency/DistilledEmotionTimeLost8"] = "Ancient Concentrated Liquid Fear", + ["Metadata/Items/Currency/DistilledEmotionTimeLost9"] = "Ancient Concentrated Liquid Suffering", + ["Metadata/Items/Currency/EndgameDistilledEmotion1"] = "Potent Liquid Melancholy", + ["Metadata/Items/Currency/EndgameDistilledEmotion2"] = "Potent Liquid Ferocity", + ["Metadata/Items/Currency/EndgameDistilledEmotion3"] = "Potent Liquid Contempt", + ["Metadata/Items/Currency/EndgameDistilledEmotionTimeLost1"] = "Ancient Potent Liquid Melancholy", + ["Metadata/Items/Currency/EndgameDistilledEmotionTimeLost2"] = "Ancient Potent Liquid Ferocity", + ["Metadata/Items/Currency/EndgameDistilledEmotionTimeLost3"] = "Ancient Potent Liquid Contempt", + ["Metadata/Items/Currency/Expedition/ExpeditionPinnacleKeyShard"] = "Shattered Triskelion", + ["Metadata/Items/Currency/GoldCoin"] = "Gold", + ["Metadata/Items/Currency/HarvestSeedBlue"] = "Primal Crystallised Lifeforce", + ["Metadata/Items/Currency/HarvestSeedBoss"] = "Sacred Crystallised Lifeforce", + ["Metadata/Items/Currency/HarvestSeedGreen"] = "Vivid Crystallised Lifeforce", + ["Metadata/Items/Currency/HarvestSeedRed"] = "Wild Crystallised Lifeforce", + ["Metadata/Items/Currency/ScoutingReports/AtlasScoutingReportBlighted"] = "Blighted Scouting Report", + ["Metadata/Items/Currency/ScoutingReports/AtlasScoutingReportBreachstone"] = "Otherworldly Scouting Report", + ["Metadata/Items/Currency/ScoutingReports/AtlasScoutingReportCorrupted"] = "Vaal Scouting Report", + ["Metadata/Items/Currency/ScoutingReports/AtlasScoutingReportDelirium"] = "Delirious Scouting Report", + ["Metadata/Items/Currency/ScoutingReports/AtlasScoutingReportExplorers"] = "Explorer's Scouting Report", + ["Metadata/Items/Currency/ScoutingReports/AtlasScoutingReportGuardian"] = "Influenced Scouting Report", + ["Metadata/Items/Currency/ScoutingReports/AtlasScoutingReportJuiced"] = "Operative's Scouting Report", + ["Metadata/Items/Currency/ScoutingReports/AtlasScoutingReportMoreHidden"] = "Comprehensive Scouting Report", + ["Metadata/Items/Currency/ScoutingReports/AtlasScoutingReportUnique"] = "Singular Scouting Report", + ["Metadata/Items/Currency/StrongboxKey"] = "Cryptic Key", + ["Metadata/Items/Expedition/ExpeditionVendorCurrencyFaction1"] = "Broken Circle Artifact", + ["Metadata/Items/Expedition/ExpeditionVendorCurrencyFaction2"] = "Black Scythe Artifact", + ["Metadata/Items/Expedition/ExpeditionVendorCurrencyFaction3"] = "Order Artifact", + ["Metadata/Items/Expedition/ExpeditionVendorCurrencyFaction4"] = "Sun Artifact", + ["Metadata/Items/Heist/HeistCoin"] = "Rogue's Marker", + ["Metadata/Items/MapFragments/CurrencyMavenKeyFragment"] = "Crescent Splinter", + ["Metadata/Items/MicrotransactionCurrency/MicrotransactionTencentEventCoin4"] = "Red Packet", + ["Metadata/Items/Sanctum/SanctumBronzeKey"] = "Bronze Key", + ["Metadata/Items/Sanctum/SanctumBronzeKeyDrop"] = "Bronze Key", + ["Metadata/Items/Sanctum/SanctumGoldKey"] = "Gold Key", + ["Metadata/Items/Sanctum/SanctumGoldKeyDrop"] = "Gold Key", + ["Metadata/Items/Sanctum/SanctumSilverKey"] = "Silver Key", + ["Metadata/Items/Sanctum/SanctumSilverKeyDrop"] = "Silver Key", +} diff --git a/src/Export/Scripts/miscdata.lua b/src/Export/Scripts/miscdata.lua index 5c95c538d7..d096a5a7b7 100644 --- a/src/Export/Scripts/miscdata.lua +++ b/src/Export/Scripts/miscdata.lua @@ -1,3 +1,5 @@ +---@module "Modules.Utils" +local utils = LoadModule("../Modules/Utils") local out = io.open("../Data/Misc.lua", "w") out:write("-- This file is automatically generated, do not edit!\n\n") out:write('---@class MiscDataExport\n') @@ -170,4 +172,11 @@ out:write('}\n') out:write('return data\n') out:close() +local currencies = {} +for row in dat("BaseItemTypes"):Rows() do + if row.ItemClass.Id == "StackableCurrency" and row.Name ~= "" then + currencies[row.Id] = row.Name + end +end +utils.saveTableToFile("../Data/CurrencyNames.lua", currencies, "This file contains mapping item names for every currency base item type ID.\nUsed for working with the currency exchange which uses item type IDs.") print("Misc data exported.")