Module:Sandbox/Desynthesis results
Jump to navigation
Jump to search
Documentation for Module:Sandbox/Desynthesis results does not exist yet [create] (How does this work?)
function renderQty(min, max)
if min == max then
return tostring(min)
end
return ("%d–%d"):format(min, max)
end
local function itemDataFromID(id)
local results = mw.smw.ask({
("[[Has context::Item]][[Has internal ID::%d]]"):format(id),
"?=Pagename#",
"?Has context",
"?Has game icon#",
"?Has game icon frame type",
"?Has canonical name",
"?Has dye channels",
limit = 1,
link = "none",
})
return results and results[1] or nil
end
local icon = require("Module:Icon")
local function itemIconFromData(data)
if not data then
return ""
end
return tostring(icon.gameIconWithLabel({
icon = data["Has game icon"],
link = data["Pagename"],
type = data["Has context"],
dyeCount = tonumber(data["Has dye channels"]) or 0,
size = "small",
text = data["Has canonical name"],
}))
end
local p = {}
function p.renderTable(id)
id = tonumber(id)
-- Desynthesis data is huge, so it's split up into multiple JSON files
-- that we need to be able to handle. On the wiki these are under
-- Module:Desynthesis with subpages that group every 1000 item IDs where
-- IDs 1 through 1000 go in 001000.json, 1001-2000 go in 002000.json, etc.
--
-- Attempt to load the appropriate JSON file; if there is no such file, or
-- the file doesn't contain data for this item, return an error.
local name = ("Module:Desynthesis/%03d000.json"):format(math.floor((id - 1) / 1000) + 1)
local success, dataOrError = pcall(
mw.loadJsonData,
name
)
local sourceData
if success then
sourceData = dataOrError.Sources[id]
end -- otherwise, leave sourceData nil
if not sourceData then
return ("No data yet. (via [https://xivstats.com/desynth?source=%s xivstats.com])"):format(id)
end
local rewards = sourceData.Rewards
-- shallow copy into a new table so we can sort it
local mutableRewards = {}
for k, v in ipairs(rewards) do
mutableRewards[k] = v
end
mw.dumpObject(mutableRewards)
-- sort by chance of obtaining, descending
table.sort(mutableRewards, function(a, b) return a.Pct > b.Pct end)
local result = "{| class=\"desynthesis-results-table stdt__table_v2 crafting sortable\"\n! Item\n! Quantity\n! Chance\n"
for _, reward in ipairs(mutableRewards) do
local data = itemDataFromID(reward.Id)
if data and data["Pagename"] then
mw.smw.set({ ["Has desynthesis result"] = data["Pagename"] })
end
result = result .. ("|-\n| %s\n| %s\n| %.2f%%\n"):format(
itemIconFromData(data),
renderQty(reward.Min, reward.Max),
reward.Pct * 100
)
end
result = result .. ("|- class=sortbottom\n! align=center colspan=3 | Based on %d desynth attempts • Data provided by [https://xivstats.com/desynth?source=%s xivstats.com]\n|}"):format(sourceData.Records, id)
return result
end
function p.main(frame)
local id = frame.args.id or ""
local header = frame.args.header or ""
if id == "" then
return "<span class=error>Error: no item ID provided.</span>"
end
local table = p.renderTable(id)
if not table then
if header == "" then
return ("<span class=error>Error: No data for desynthesis source %d</span>"):format(id)
else
return ""
end
end
if header ~= "" then
header = frame:preprocess(header) .. "\n"
end
return header .. table
end
return p