Documentation for this module may be created at Module:FFXIV Data/doc
p = {}
local getArgs = require("Dev:Arguments").getArgs
local ffwiki = require("Module:HF")
local constants = mw.loadData("Module:FFXIV Data/Constants")
local html = mw.html
---BEGIN DEPRECATED CODE
--Tomestones database
function p.Tomestones(frame)
local args = getArgs(frame)
local data = mw.loadData("Module:FFXIV Data/Tomestones")
local typ = string.lower(args.type)
local ilv = tonumber(args.ilvl)
local tomes = {0, 0, 0}
if data[typ] and data[typ][ilv] then
tomes = data[typ][ilv]
else
tomes = {tonumber(args.tome1) or 0, tonumber(args.tome2) or 0, tonumber(args.tome3) or 0}
end
local rv = ""
if tomes == {0, 0, 0} then return rv end
for i, v in pairs(tomes) do
local tdata = data.tomes[i] or ffwiki.err("Missing data in [[Module:FFXIV Data/Tomestones]], contact an admin!")
if v > 0 then rv = rv .. "[[" .. tdata[2] .. "|25px|" .. tdata[1] .. "]] " .. v .. "<br/>" end
end
return rv
end
--Links database; used to generate templates
function p.Links(frame)
local arg = getArgs(frame)[1]
local links = mw.loadData("Module:FFXIV Data/Links")[arg]
local categories = mw.loadData("Module:FFXIV Data/Categories")[arg]
local linked = {}
local groups = {}
for i, v in ipairs(categories) do
table.insert(groups, {})
end
local stdstr = "List of Final Fantasy XIV " .. arg
local stdlen = string.len(stdstr .. "/")
local tbl = html.create("table"):addClass("FFXIV full-width article-table")
tbl:tag("th")
:addClass("a")
:attr("colspan", 2)
:wikitext("''[[Final Fantasy XIV]]'' [[List of Final Fantasy XIV " .. arg .. "|" .. getArgs(frame).title .. "]]")
for i, v in ipairs(links) do
if not linked[v[1]] and string.len(v[1]) > stdlen then
linked[v[1]] = 1
table.insert(groups[v[2] + 1], v[1])
end
end
for i, v in ipairs(groups) do
if #v > 0 then
local row = tbl:tag("tr")
row:tag("th")
:addClass("b")
:attr("style","width:30%")
:wikitext(categories[i])
dot = 0
local txt = ""
for j, w in ipairs(v) do
if dot == 1 then
txt = txt .. " - "
end
txt = txt .. "[" .. "[" .. w .. "|" .. w:sub(stdlen + 1) .. "]]"
dot = 1
end
row:tag("td"):wikitext(txt)
end
end
return tbl
end
---END DEPRECATED CODE
local function loadDb(db)
--Safely loads a db, returning an empty table if one doesn't exist.
local err, tbl = pcall(mw.loadData, "Module:FFXIV Data/" .. db)
if not err then return {} else return tbl end
end
local function subDb(db, id)
--Get the subdatabase corresponding to an id.
if not id then return {} end
local subdivision = loadDb(db).subdivision
local subdb = 1
for j, v in ipairs(subdivision or {}) do
if v <= id then subdb = j end
end
return loadDb(db .. "/" .. tostring(subdb))
end
local function getId(db, name)
return loadDb(db).index[name]
end
local function lookupById(db, id)
return subDb(db, id)[id] or nil
end
local function lookup(db, name)
return lookupById(db, getId(db, name))
end
local function lookupAll(db, startId, endId)
local content = {}
for id=startId,endId do
local unit = lookupById(db, id)
if unit then content[id] = unit end
end
return content
end
local function nameEntry(name, icon)
local entry = name or "—"
if icon then entry = entry .. "<br/>" .. iconById(icon) end
return entry
end
local function listToList(list)
-- Turns a Lua list (table indexed by naturals) to a <ul>
local ul = html.create("ul")
for j, v in ipairs(list) do
ul:tag("td")
:wikitext(tostring(v))
end
return ul
end
---------------FFXIV Editors: To make new tables, edit below this line.
--General lookup
function p.Lookup(frame)
local args = getArgs(frame)
--1: database name
--2: object name or id
--3: attr
--4: subattr
--5: subsubattr...
local data
if tonumber(args[2]) then
data = lookupById(args[1], tonumber(args[2]))
else
data = lookup(args[1], args[2])
end
if not data then return args[2] .. " doesn't exist" end
local j = 3
while args[j] and data[args[j]] do
data = data[args[j]]
j = j + 1
end
return tostring(data)
end
--Translations
function p.TranslationsTable(frame)
local args = getArgs(frame)
--1: database name
--2: start here
--3: end here
local db = args[1]
local startId = args[2] or 1
local endId = args[3] or loadDb(db).last
local content = lookupAll(db, startId, endId)
local romajiDb = loadDb("Romaji/" .. db)
local tbl = html.create("table")
:addClass("full-width sortable article-table translations FFXIV")
:tag("tr")
:addClass("a")
:tag("th")
:cssText("width: 25%")
:wikitext("Japanese")
:done()
:tag("th")
:cssText("width: 25%")
:wikitext("Romaji")
:done()
:tag("th")
:cssText("width: 25%")
:wikitext("Literal")
:done()
:tag("th")
:cssText("width: 25%")
:wikitext("English")
:allDone()
for id=startId,endId do
local official = content[id]
if official then
local romaji = romajiDb[official.name] or romajiDb[official.name_en] or {"—", "—"}
tbl:tag("tr")
:tag("td")
:addClass("b")
:wikitext(official.name_ja or "—")
:done()
:tag("td")
:wikitext(romaji[1])
:done()
:tag("td")
:wikitext(romaji[2])
:done()
:tag("td")
:wikitext(official.name_en or official.name or "—")
:done()
end
end
return tbl
end
--Icons
local function iconFile(id)
return "File:Icon " .. tostring(id) .. " from FFXIV.png"
end
local function iconById(id)
return '[[' .. iconFile(id) .. ']]'
end
function p.IconById(frame)
return iconById(getArgs(frame)[1])
end
function p.IconByMeaning(frame)
local args = getArgs(frame)
local meaning = lookup(args[1], args[2])
if not meaning or not meaning.icon then return '' end
return '[[' .. iconFile(meaning.icon) .. (meaning.name and ('|' .. meaning.name)) .. ']]'
end
--Achievements
local function makeAchievementHeader()
local tbl = html.create("table")
:addClass("full-width sortable article-table FFXIV")
:tag("tr")
:addClass("a")
:tag("th")
:cssText("width: 25%")
:wikitext("Name")
:done()
:tag("th")
:cssText("width: 15%")
:wikitext("Type")
:done()
:tag("th")
:cssText("width: 15%")
:wikitext("Title")
:done()
:tag("th")
:cssText("width: 40%")
:wikitext("Description")
:done()
:tag("th")
:cssText("width: 5%")
:wikitext("Patch")
:allDone()
return tbl
end
local function parseAchiData(achiData)
if achiData then
return html.create("tr")
:tag("th")
:addClass("b")
:wikitext(nameEntry(achiData.name, achiData.icon))
:done()
:tag("td")
:wikitext((achiData.kind_name or "—") .. ": " .. (achiData.category_name or "—")):done()
:tag("td")
:wikitext((achiData.title and (achiData.title.name or "—")) or "—"):done()
:tag("td")
:wikitext(achiData.help or "—")
:done()
:tag("td")
:wikitext(achiData.patch.number or "—")
:allDone()
end
end
function p.AchievementTable(frame)
local args = getArgs(frame)
local tbl = makeAchievementHeader()
for j, achi in ipairs(args) do
tbl:node(parseAchiData(lookup("achievement", achi)))
end
return tbl
end
function p.AllAchievementTable(frame)
local args = getArgs(frame)
local tbl = makeAchievementHeader()
for j=1,2500 do --Change for 5.x!
local achiData = lookupById("achievement", j)
if achiData and achiData.kind_name == args[1] and achiData.category_name == args[2] then
tbl:node(parseAchiData(achiData))
end
end
return tbl
end
--Enemies
function p.EnemyTable(frame)
return ""
end
--Instances
local function lookupDuty(truename, attr)
if truename and truename ~= '' then
local inst = lookup("instance", truename)
if inst and inst[attr] then return inst[attr] end
end
end
function p.InstanceType(frame)
local args = getArgs(frame)
local typ = lookupDuty(args[1], "content_name")
if typ then typ = typ:sub(1, -2)
else typ = args[2] end
return "[[File:FFXIV " .. typ .. " Icon.png|25px]] [[Duty#" .. typ .. "s|" .. typ .. "]]"
end
function p.InstanceLevel(frame)
local args = getArgs(frame)
local lv = lookupDuty(args[1], "level") or args[2]
local lvSync = lookupDuty(args[1], "level_sync") or args[3]
return lv .. " (Synced to " .. lvSync .. ")"
end
function p.InstanceILevel(frame)
local args = getArgs(frame)
local lv = lookupDuty(args[1], "item_level") or args[2]
local lvSync = lookupDuty(args[1], "level_sync") or args[3]
if lvSync then lvSync = " (Synced to " .. lvSync .. ")"
else lvSync = "" end
return lv .. lvSync
end
function p.InstanceTime(frame)
local args = getArgs(frame)
local tim = lookupDuty(args[1], "time_limit")
if tim then tim = tim .. " minutes"
else tim = args[2] end
return tim
end
--Items
local function makeItemHeader()
return html.create("table")
:addClass("full-width sortable article-table FFXIV")
:tag("tr")
:addClass("a")
:tag("th")
:attr("rowspan", 2)
:cssText("width: 20%")
:wikitext("Name")
:done()
:tag("th")
:cssText("width: 15%")
:wikitext("Type")
:done()
:tag("th")
:cssText("width: 5%")
:wikitext("iLv")
:done()
:tag("th")
:attr("rowspan", 2)
:cssText("width: 60%")
:wikitext("Description")
:allDone()
:tag("tr")
:addClass("a")
:tag("th")
:wikitext("Equip")
:done()
:tag("th")
:wikitext("Patch")
:allDone()
:tag("tr")
:tag("th")
:addClass("b")
:attr("colspan", 3)
:wikitext("Materials")
:done()
:tag("th")
:addClass("b")
:wikitext("Crafting")
:allDone()
end
local function parseItemData(itemData)
if not itemData then return end
local tr = {}
-- tr1
tr[1] = html.create("tr")
:tag("th")
:attr("rowspan", 2)
:addClass("b")
:wikitext(nameEntry(itemData.name, itemData.icon))
:done()
:tag("td")
:wikitext(itemData.category_name or "—")
:done()
:tag("td")
:wikitext(itemData.level_item or "—")
:done()
local descr = ""
for j, w in ipairs(constants.baseStats) do
local v = itemData.attributes_base[w[1]]
local vhq = itemData.attributes_base[w[1] .. "_hq"]
if (v and v > 0) or (vhq and vhq > 0) then
if descr ~= "" then descr = descr .. "<br/>" end
descr = descr .. "'''" .. w[2] .. "''': " .. (v or "0")
if vhq and (not v or vhq > v) then
descr = descr .. " ([[File:FFXIV HQ Icon.png]] " .. vhq .. ")"
end
end
end
for j, v in ipairs(itemData.attributes_params) do
if v.name ~= "" then
if descr ~= "" then descr = descr .. "<br/>" end
descr = descr .. "'''" .. v.name .. "''': " .. (v.value or "0")
if v.value_hq then descr = descr .. " ([[File:FFXIV HQ Icon.png]] " .. v.value_hq .. ")" end
end
end
if descr ~= "" then descr = "<p style=\"column-count:2\">" .. descr .. "</p>" end
tr[1]:tag("td")
:attr("rowspan", 2)
:wikitext(itemData.help_en .. descr)
:allDone()
--tr2
tr[2] = html.create("tr")
:tag("td")
:wikitext(((itemData.classjob_category and (itemData.classjob_category .. " ")) or "") .. (itemData.level_equip or "—"))
:done()
:tag("td")
:wikitext((itemData.patch and itemData.patch.number) or "—")
:allDone()
--gathering and crafting trs
local tableIndex = 3
--crafting tr
if itemData.craftable then
for _____, c in ipairs(itemData.craftable) do
conds = {}
local ind = 1
local possibleConds = mw.loadData("Module:FFXIV Data/Parameters").craftingConditions
for k, v in pairs(possibleConds) do
if c[k] and not c[k] == 0 then
conds[ind] = v
ind = ind + 1
end
end
if c.craft_quantity and c.craft_quantity > 1 then
conds[ind] = "Crafting quantity: " .. tostring(c.craft_quantity)
ind = ind + 1
end
if c.element_name and not c.element_name == "Aspect: None" then
conds[ind] = c.element_name
ind = ind + 1
end
if c.masterbook and c.masterbook.name then
conds[ind] = "Requires " .. itemLink(c.masterbook.name)
ind = ind + 1
end
mats = {}
ind = 1
if c.tree then
for _, v in ipairs(c.tree) do
if v.name then
local mat = itemLink(v.name)
if v.quantity and v.quantity > 1 then
mat = mat .. " x" .. tostring(v.quantity)
end
mats[ind] = mat
ind = ind + 1
end
end
end
cstats = '<p style="column-count:2">'
cstats = cstats .. "'''Crafter''': " .. c.classjob.abbr .. " " .. c.level_view
if c.stars_html then cstats = cstats .. c.stars_html end
cstats = cstats .. '<br/>'
cstats = cstats .. "'''Durability''': " .. c.durability .. "<br/>"
cstats = cstats .. "'''Craftsmanship''': " .. c.required_craftsmanship .. "<br/>"
cstats = cstats .. "'''Control''': " .. c.required_control .. "<br/>"
cstats = cstats .. "'''Difficulty''': " .. c.difficulty .. "<br/>"
cstats = cstats .. "'''Quality''': " .. c.quality .. "<br/>"
cstats = cstats .. '</p>'
tr[tableIndex] = html.create("tr")
:tag("td")
:attr("colspan","3")
:cssText("vertical-align:top")
:node(listToList(mats))
:done()
:tag("td")
:cssText("vertical-align:top")
:wikitext(cstats)
:node(listToList(conds))
:allDone()
tableIndex = tableIndex + 1
end
end
return tr
end
local function lookupItemData(item)
if tonumber(item) then return lookupById("item", item)
else return lookup("item", item) end
end
local function lookupItem(item)
return parseItemData(lookupItemData(item))
end
local function itemLink(item)
local i = lookupItemData(item)
if not i or not i.category_name then return item end
return "[[List of Final Fantasy XIV items/" .. i.category_name .. "#" .. item .. "|" .. item .. "]]"
end
function p.LootTable(frame)
local args = getArgs(frame)
local tbl = makeItemHeader()
for j, item in ipairs(args) do
local tr = lookupItem(item)
if tr then for j, v in ipairs(tr) do tbl:node(v) end end
end
return tbl
end
function p.AllLootTable(frame)
local args = getArgs(frame)
local category_name = args[1]
local header = "The following is a list of items classified as '''" .. category_name .. "''' from ''[[Final Fantasy XIV]]''."
local div = html.create("div")
:wikitext(header)
:done()
if args[2] then header = header .. "\n\n" .. args[2] end
local tbl = makeItemHeader()
for i=1,28000 do --This will need to be updated in 5.x!
local itemData = lookupById("item", i)
if itemData and itemData.category_name == category_name then
local tr = parseItemData(itemData)
if tr then for j, v in ipairs(tr) do tbl:node(v) end end
end
end
div:node(tbl)
return div
end
--Quests
local function lookupQuestData(quest)
local q
if tonumber(quest) then q = lookupById("quest", tonumber(quest))
else q = lookup("quest", quest) end
return q
end
local function questLink(quest)
local q = lookupQuestData(quest)
if not q or not q.genre_name then return quest end
return "[[List of Final Fantasy XIV quests/" .. q.genre_name .. "#" .. quest .. "|" .. quest .. "]]"
end
local function questTable(quest)
local tbl = html.create("table"):addClass("FFXIV article-table"):cssText("float:right;width:370px"):allDone()
if quest.icon then
tbl:tag("tr")
:tag("td")
:attr("colspan", 2)
:wikitext(iconById(quest.icon))
end
if quest.class_level_1 then
tbl:tag("tr")
:tag("th")
:addClass("b")
:wikitext("Level")
:done()
:tag("td")
:wikitext(quest.class_level_1)
end
if quest.category_name then
tbl:tag("tr")
:tag("th")
:addClass("b")
:wikitext("Type")
:done()
:tag("td")
:wikitext(quest.category_name)
end
if quest.pre_quests and quest.pre_quests ~= {} then
local prereqs = ""
for j, v in ipairs(quest.pre_quests) do
if prereqs ~= "" then prereqs = prereqs .. "<br/>" end
prereqs = prereqs .. questLink(v.name)
end
tbl:tag("tr")
:tag("th")
:addClass("b")
:wikitext("Requires")
:done()
:tag("td")
:wikitext(prereqs)
end
if quest.post_quests and quest.post_quests ~= {} then
local postreqs = ""
for j, v in ipairs(quest.post_quests) do
if postreqs ~= "" then postreqs = postreqs .. "<br/>" end
postreqs = postreqs .. questLink(v.name)
end
tbl:tag("tr")
:tag("th")
:addClass("b")
:wikitext("Unlocks")
:done()
:tag("td")
:wikitext(postreqs)
end
if quest.gil_reward or quest.exp_reward then
local rewards = ""
if quest.exp_reward then
rewards = "[[File:FFXIV EXP Icon.png]] " .. quest.exp_reward .. "<br/>"
end
if quest.gil_reward then
rewards = rewards .. "[[File:FFXIV Gil Icon.png]] " .. quest.gil_reward
end
tbl:tag("tr")
:tag("th")
:addClass("b")
:wikitext("Rewards")
:done()
:tag("td")
:wikitext(rewards)
end
if quest.npc_start then
tbl:tag("tr")
:tag("th")
:addClass("b")
:wikitext("Start NPC")
:done()
:tag("td")
:wikitext(quest.npc_start.name)
end
if quest.npc_end then
tbl:tag("tr")
:tag("th")
:addClass("b")
:wikitext("End NPC")
:done()
:tag("td")
:wikitext(quest.npc_end.name)
end
if quest.patch then
tbl:tag("tr")
:tag("th")
:addClass("b")
:wikitext("Patch")
:done()
:tag("td")
:wikitext(quest.patch.number)
end
return tbl
end
local function questBullets(list)
local ul = html.create("ul")
for j, v in ipairs(list) do
ul:tag("li"):wikitext(v.text)
end
return ul
end
local function questEntry(q)
if q then return html.create("div"):addClass("quest"):cssText("clear:right;")
:tag("h3")
:wikitext(q.name)
:done()
:node(questTable(q))
:done()
:tag("h4")
:wikitext("Journal")
:done()
:node(questBullets(q.text.journal))
:allDone()
:tag("h4")
:wikitext("Objectives")
:done()
:node(questBullets(q.text.todo))
:done() end
end
local function lookupQuest(quest)
return questEntry(lookupQuestData(quest))
end
function p.QuestLink(frame)
local quest = getArgs(frame)[1]
return questLink(quest)
end
function p.QuestList(frame)
local args = getArgs(frame)
local div = html.create("div"):addClass("quests")
for j, quest in ipairs(args) do
q = lookupQuest(quest)
if q then div:node(q) end
end
return div
end
function p.AllQuestsList(frame)
local args = getArgs(frame)
local genre_name = args[1]
local header = "The following is a list of quests classified as '''" .. genre_name .. "''' from ''[[Final Fantasy XIV]]''."
if args[2] then header = header .. "\n\n" .. args[2] end
local div = html.create("div")
:addClass("quests")
:wikitext(header)
:tag("h2")
:wikitext("Quests")
:done()
local j = 1
for i=65537,70000 do --This will need to be updated in 5.x!
q = lookupById("quest", i)
if q and q.genre_name == genre_name then div:node(questEntry(q)) end
end
return div
end
-----------Do not edit below this line!
return p
--[[Category:Final Fantasy XIV Database]]