FANDOM


local getArgs = require("Dev:Arguments").getArgs
local html = mw.html
 
local p = {}
local BLADE = require "Module:BladeEngine".new(p, "Module:FFXV Data")
 
function japanese(args)
    return require "Module:Japanese".initJ(args)
end
 
function foot(args)
    return require "Module:Foot".render(args)
end
 
function createslip(title, text)
    --creating a div and setting it inline? makes me feel dirty
    --but mobile ignores custom styling, so the margin-right will be
    ----ignored
    --this way, mobile will put the div elements each on its own line
    ----while desktop can separate them with margin
    --the alternative is to add a bunch of trailing non-break spaces
    ----instead of margin for a global (still dirty-feeling) solution
    return html.create("div")
        :css({
            ["display"] = "inline",
            ["margin-right"] = "25px",
            ["float"] = "left"
        })
        :tag("b")
            :addClass(a)
            :wikitext(title .. ": ")
            :done()
        :tag("span")
            :wikitext(text)
            :done()
end
 
 
function p.Weapons(frame)
    local datapage = "Module:FFXV Data/Weapons"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local displaycategory = (not args.displaycategory) or args.displaycategory ~= "false"
 
    local displaynpcweapons = args.displaynpcweapons and args.displaynpcweapons == "true"
 
    if not displaynpcweapons then
        args.unequippable = "false"
    end
 
    local querydata = BLADE.select(data, args)
 
    local colspan = 5
    if displaycategory then
        colspan = colspan + 1
    end
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext("Name")
    if displaycategory then
        thead:tag("th"):wikitext("Category")
    end
    thead:tag("th"):wikitext("Attack")
    thead:tag("th"):wikitext("Critical")
    thead:tag("th"):wikitext("Modifiers/Notes")
    thead:tag("th"):wikitext("Value")
    thead:tag("th"):wikitext("Obtain")
    for i=1, #querydata do
        local itm = querydata[i]
 
        local rowspan = 1
        if itm.desc then
            rowspan = rowspan + 1
        end
        if itm.patchnotes then
            rowspan = rowspan + 1
        end
 
 
        local name = BLADE.formatlink(data, itm, "link", "name")
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        if itm.image then
            name = name .. '<br/>' .. BLADE.formatfield(data, itm, "image"):setWidth(30)
        end
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b"):wikitext(name)
            :attr("rowspan", rowspan)
        if displaycategory then
            tr:tag("td"):wikitext(itm.category):css("text-align", "center")
        end
        tr:tag("td"):wikitext(itm.atk):css("text-align", "center")
        tr:tag("td"):wikitext(itm.crt):css("text-align", "center")
        local modifiers = {}
        if itm.mhp~=0 then
            table.insert(modifiers, "Max HP: "
                .. BLADE.formatfield(data, itm, "mhp"))
        end
        if itm.mmp~=0 then
            table.insert(modifiers, "Max MP: "
                .. BLADE.formatfield(data, itm, "mmp"))
        end
        if itm.str~=0 then
            table.insert(modifiers, "Strength: "
                .. BLADE.formatfield(data, itm, "str"))
        end
        if itm.vit~=0 then
            table.insert(modifiers, "Vitality: "
                .. BLADE.formatfield(data, itm, "vit"))
        end
        if itm.mag~=0 then
            table.insert(modifiers, "Magic: "
                .. BLADE.formatfield(data, itm, "mag"))
        end
        if itm.spr~=0 then
            table.insert(modifiers, "Spirit: "
                .. BLADE.formatfield(data, itm, "spr"))
        end
        if itm.sht~=0 then
            table.insert(modifiers, "Shot Resistance: "
                .. BLADE.formatfield(data, itm, "sht"))
        end
        if itm.fir~=0 then
            table.insert(modifiers, "Fire Resistance: "
                .. BLADE.formatfield(data, itm, "fir"))
        end
        if itm.ice~=0 then
            table.insert(modifiers, "Ice Resistance: "
                .. BLADE.formatfield(data, itm, "ice"))
        end
        if itm.ltn~=0 then
            table.insert(modifiers, "Lightning Resistance: "
                .. BLADE.formatfield(data, itm, "ltn"))
        end
        if itm.drk~=0 then
            table.insert(modifiers, "Dark Resistance: "
                .. BLADE.formatfield(data, itm, "drk"))
        end
        if itm.info then table.insert(modifiers, itm.info) end
        tr:tag("td"):wikitext(table.concat(modifiers, "<br/>"))
        local canbuy = itm.shop
        local cansell = not itm.unsellable
        local buyprice = itm.cost
        local sellprice = itm.cost==0 and 0 or (itm.cost/2)
        if not canbuy then
            buyprice = "&mdash;"
        end
        if not cansell then
            sellprice = "&mdash;"
        end
        tr:tag("td"):wikitext("Buy: " .. buyprice .. "<br/>Sell: " .. sellprice):css("text-align", "center")
        local obtain = {}
        if itm.default then table.insert(obtain, "'''Default:''' " .. itm.default) end
        if itm.find then table.insert(obtain, "'''Find:''' " .. itm.find) end
        if itm.reward then table.insert(obtain, "'''Reward:''' " .. itm.reward) end
        if itm.shop then table.insert(obtain, "'''Shop:''' " .. itm.shop) end
        if itm.upgrade then table.insert(obtain, "'''Upgrade:''' " .. itm.upgrade) end
        if itm.trade then table.insert(obtain, "'''Trade:''' " .. itm.trade) end
        if itm.drop then table.insert(obtain, "'''Enemy drop:''' " .. itm.drop) end
        if itm.download then table.insert(obtain, "'''Download:''' " .. itm.download) end
        tr:tag("td"):wikitext(table.concat(obtain, "<br/>"))
 
        if itm.desc then
            tr = tbl:tag("tr")
            tr:tag("td"):attr("colspan", colspan):wikitext(BLADE.formatfield(data, itm, "desc"))
        end
        if itm.patchnotes then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(
                    "'''Patch notes:''' " ..
                    BLADE.formatfield(data, itm, "patchnotes")
                )
        end
    end
 
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
function p.Accessories(frame)
    local datapage = "Module:FFXV Data/Accessories"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local querydata = BLADE.select(data, args)
 
    local displaycharacter = (not args.displaycharacter) or args.displaycharacter ~= "false"
 
    local colspan = 4
    if displaycharacter then
        colspan = colspan + 1
    end
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext("Name")
    thead:tag("th"):wikitext("Effects")
    thead:tag("th"):wikitext("Value")
    thead:tag("th"):wikitext("Obtain")
    if displaycharacter then
        thead:tag("th"):wikitext("Equippable by")
    end
    for i=1, #querydata do
        local itm = querydata[i]
        local name = BLADE.formatlink(data, itm, "link", "name")
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        if itm.image then
            name = name .. '<br/>' .. BLADE.formatfield(data, itm, "image"):setWidth(180)
        end
 
        local effects = {}
        if itm.crt ~= 0 then
            table.insert(effects, "Critical Rate " .. BLADE.formatfield(data, itm, "crt"))
        end
        if itm.mhp ~= 0 then
            table.insert(effects, "Max HP " .. BLADE.formatfield(data, itm, "mhp"))
        end
        if itm.mmp ~= 0 then
            table.insert(effects, "Max MP " .. BLADE.formatfield(data, itm, "mmp"))
        end
        if itm.hpr ~= 0 then
            table.insert(effects, "HP Recovery Rate " .. BLADE.formatfield(data, itm, "hpr"))
        end
        if itm.mpr ~= 0 then
            table.insert(effects, "MP Recovery Rate " .. BLADE.formatfield(data, itm, "mpr"))
        end
        if itm.str ~= 0 then
            table.insert(effects, "Strength " .. BLADE.formatfield(data, itm, "str"))
        end
        if itm.vit ~= 0 then
            table.insert(effects, "Vitality " .. BLADE.formatfield(data, itm, "vit"))
        end
        if itm.mag ~= 0 then
            table.insert(effects, "Magic " .. BLADE.formatfield(data, itm, "mag"))
        end
        if itm.spr ~= 0 then
            table.insert(effects, "Spirit " .. BLADE.formatfield(data, itm, "spr"))
        end
        if itm.sht ~= 0 then
            table.insert(effects, "Shot Res. " .. BLADE.formatfield(data, itm, "sht"))
        end
        if itm.fir ~= 0 then
            table.insert(effects, "Fire Res. " .. BLADE.formatfield(data, itm, "fir"))
        end
        if itm.ice ~= 0 then
            table.insert(effects, "Ice Res. " .. BLADE.formatfield(data, itm, "ice"))
        end
        if itm.ltn ~= 0 then
            table.insert(effects, "Lightning Res. " .. BLADE.formatfield(data, itm, "ltn"))
        end
        if itm.drk ~= 0 then
            table.insert(effects, "Dark Res. " .. BLADE.formatfield(data, itm, "drk"))
        end
        if itm.exp ~= 0 then
            table.insert(effects, "EXP " .. BLADE.formatfield(data, itm, "exp"))
        end
        if itm.dirt ~= 0 then
            table.insert(effects, "Dirt accumulation " .. BLADE.formatfield(data, itm, "dirt"))
        end
        if itm.phasemp ~= 0 then
            table.insert(effects, "Phase MP cost " .. BLADE.formatfield(data, itm, "phasemp"))
        end
        if itm.halfhpitem then
            table.insert(effects, "When Noctis's HP is less than 50%, uses " .. BLADE.formatfield(data, itm, "halfhpitem"))
        end
        if itm.effect then
            table.insert(effects, BLADE.formatfield(data, itm, "effect"))
        end
        effects = table.concat(effects, "; ")
 
        local canbuy = itm.shop
        local cansell = not itm.unsellable
        local buyprice = itm.cost
        local sellprice = itm.cost==0 and 0 or (itm.cost/2)
        if not canbuy then
            buyprice = "&mdash;"
        end
        if not cansell then
            sellprice = "&mdash;"
        end
        local cost = "Buy: " .. buyprice .. "<br/>Sell: " .. sellprice
 
        local obtain = {}
        if itm.default then table.insert(obtain, "'''Default:''' " .. itm.default) end
        if itm.find then table.insert(obtain, "'''Find:''' " .. itm.find) end
        if itm.reward then table.insert(obtain, "'''Reward:''' " .. itm.reward) end
        if itm.shop then table.insert(obtain, "'''Shop:''' " .. itm.shop) end
        if itm.upgrade then table.insert(obtain, "'''Upgrade:''' " .. itm.upgrade) end
        if itm.trade then table.insert(obtain, "'''Trade:''' " .. itm.trade) end
        if itm.drop then table.insert(obtain, "'''Enemy drop:''' " .. itm.drop) end
        if itm.download then table.insert(obtain, "'''Download:''' " .. itm.download) end
        obtain = table.concat(obtain, "<br/>")
 
        local user = {}
        if displaycharacter then
            if itm.noctis then
                table.insert(user, "Noctis")
            end
            if itm.gladiolus then
                table.insert(user, "Gladiolus")
            end
            if itm.ignis then
                table.insert(user, "Ignis")
            end
            if itm.prompto then
                table.insert(user, "Prompto")
            end
            if #user == 4 then--with the appearance of guests this might get confusing
                user = { "All" }
            end
            if itm.iris then
                table.insert(user, "Iris")
            end
            if itm.cor then
                table.insert(user, "Cor")
            end
            if itm.aranea then
                table.insert(user, "Aranea")
            end
        end
        user = table.concat(user, ", ")
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b"):wikitext(name)
            :attr("rowspan", 1 +
                (itm.desc and 1 or 0)
                +
                (itm.patchnotes and 1 or 0)
            )
        tr:tag("td"):wikitext(effects)
        tr:tag("td"):wikitext(cost)
        tr:tag("td"):wikitext(obtain)
        if displaycharacter then 
            tr:tag("td"):wikitext(user)
        end
 
        if itm.desc then
            tr = tbl:tag("tr")
            tr:tag("td"):attr("colspan", colspan):wikitext(BLADE.formatfield(data, itm, "desc"))
        end
        if itm.patchnotes then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(
                    "'''Patch notes:''' " ..
                    BLADE.formatfield(data, itm, "patchnotes")
                )
        end
    end
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
function p.Items(frame)
    local datapage = "Module:FFXV Data/Items"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local querydata = BLADE.select(data, args)
 
    local colspan = 5
 
    local statuspage = "Final Fantasy XV statuses"
 
    ---name/jpn/rom/lit/image
    ---item
    ----cost
    ----obtain
    ---ability
    ----target
    ----effect
    ----user(Noctis or All)
    ---elemancy
    ----addedeffect
    ----powervalue
    ----effectlevel
    ----duplicationunits
    ---desc
    ---patchnotes
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext("Name")
    thead:tag("th"):wikitext("Target")
    thead:tag("th"):wikitext("Effect")
    thead:tag("th"):wikitext("User")
    thead:tag("th"):wikitext("Value")
    thead:tag("th"):wikitext("Obtain")
    for i=1, #querydata do
        local itm = querydata[i]
 
        --ITEM
        local name = BLADE.formatlink(data, itm, "link", "name")
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        if itm.image then
            name = name .. '<br/>' .. BLADE.formatfield(data, itm, "image"):setWidth(180)
        end
 
        local canbuy = itm.shop
        local cansell = not itm.unsellable
        local buyprice = itm.cost
        local sellprice = itm.cost==0 and 0 or (itm.cost/2)
        if not canbuy then
            buyprice = "&mdash;"
        end
        if not cansell then
            sellprice = "&mdash;"
        end
        local cost = "Buy: " .. buyprice .. "<br/>Sell: " .. sellprice
 
        local obtain = {}
        if itm.default then table.insert(obtain, "'''Default:''' " .. itm.default) end
        if itm.find then table.insert(obtain, "'''Find:''' " .. itm.find) end
        if itm.survival then table.insert(obtain, "'''Survival:''' Level " .. itm.survival) end
        if itm.reward then table.insert(obtain, "'''Reward:''' " .. itm.reward) end
        if itm.shop then table.insert(obtain, "'''Shop:''' " .. itm.shop) end
        if itm.upgrade then table.insert(obtain, "'''Upgrade:''' " .. itm.upgrade) end
        if itm.trade then table.insert(obtain, "'''Trade:''' " .. itm.trade) end
        if itm.drop then table.insert(obtain, "'''Enemy drop:''' " .. itm.drop) end
        if itm.download then table.insert(obtain, "'''Download:''' " .. itm.download) end
        obtain = table.concat(obtain, "<br/>")
 
        --ABILITY (when item is used)
        local target
        if itm.target then
            target = BLADE.formatfield(data, itm, "target")
        else
            target = "&mdash;"
        end
 
        local effects = {}
        local restores = {}
        if itm.hprestore then
            table.insert(restores, BLADE.formatfield(data, itm, "hprestore") .. " of current HP")
        end
        if itm.maxhprestore then
            table.insert(restores, BLADE.formatfield(data, itm, "maxhprestore") .. " of lowered maximum HP")
        end
        if itm.mprestore then
            table.insert(restores, BLADE.formatfield(data, itm, "mprestore") .. " of current MP")
        end
        if #restores>0 then
            restores = table.concat(restores, ", ")
            restores = (itm.revivestarget and "Revives and r" or "R") .. "estores " .. restores
            table.insert(effects, restores)
        end
 
        local removes = {}
        if itm.removestasis then
            table.insert(removes, "Stasis")
        end
        if itm.removedanger then
            table.insert(removes, "Danger")
        end
        if itm.removepoison then
            table.insert(removes, "Poison")
        end
        if itm.removestone then
            table.insert(removes, "Stone")
        end
        if itm.removeconfusion then
            table.insert(removes, "Confusion")
        end
        if itm.removetoad then
            table.insert(removes, "Toad")
        end
        if #removes > 0 then
            for i=1, #removes do
                local x = removes[i]
                removes[i] = "[[" .. statuspage .. "#" .. x .. "|" .. x .. "]]"
            end
            table.insert(effects, "Removes " .. table.concat(removes, ", "))
        end
 
        local inflicts = {}
        local statuslist = {
            { fld = "revitalized", nme = "Revitalized", stt = "HP Recovery Rate" },
            { fld = "tenacious", nme = "Tenacious", stt = "Strength" },
            { fld = "stalwart", nme = "Stalwart", stt = "Vitality" },
            { fld = "enchanted", nme = "Enchanted", stt = "Magic" },
            { fld = "spiritual", nme = "Spiritual", stt= "Spirit" },
            { fld = "nimble", nme = "Nimble" },
            { fld = "inspired", nme = "Inspired" },
            { fld = "phoenixsfavor", nme = "Phoenix's Favor" },
        }
        for i=1, #statuslist do
            local thisstatus = statuslist[i]
            local fieldname = thisstatus.fld
            if itm[fieldname] then
                local statusname = thisstatus.nme
                local statustext = ("[[%s#%s|%s]]"):format(statuspage, statusname, statusname)
                local statusstat = thisstatus.stt
                if thisstatus.stt then
                    local statincr = BLADE.formatfield(data, itm, fieldname)
                    statustext = statustext .. " (" .. statusstat .. " +" .. statincr .. ")"
                end
                table.insert(inflicts, statustext)
            end
        end
        if #inflicts > 0 then
            local infl = "Inflicts " .. table.concat(inflicts, ", ")
            local duration = itm.duration
            if duration then
                duration = duration .. " seconds"
            else
                duration = "''unknown duration''"
            end
            table.insert(effects, infl .. " for " .. duration)
        end
 
        if itm.effect then
            table.insert(effects, itm.effect)
        end
 
        if #effects > 0 then
            effects = table.concat(effects, ". ") .. "."
        else
            effects = "&mdash;"
        end
 
        local user = itm.allies and "All" or "Noctis"
 
        --ELEMANCY
        local elemancy
        if itm.powervalue then
            local addedeffect = BLADE.formatfield(data, itm, "addedeffect")
            local powervalue = BLADE.formatfield(data, itm, "powervalue")
            local effectlevel = BLADE.formatfield(data, itm, "effectlevel")
            local duplicationunits = BLADE.formatfield(data, itm, "duplicationunits")
            elemancy = html.create("div")
                :node(createslip(
                    "Added effect",
                    itm.addedeffect and addedeffect or "&mdash;"
                    )
                )
                :node(createslip(
                    "Power value",
                    itm.powervalue and powervalue or "&mdash;"
                    )
                )
                :node(createslip(
                    "Effect level",
                    itm.effectlevel and effectlevel or "&mdash;"
                    )
                )
                :node(createslip(
                    "Duplication units",
                    itm.duplicationunits and duplicationunits or "&mdash;"
                    )
                )
        end
 
        local rowspan = 1
        if elemancy then rowspan = rowspan +1 end
        if itm.desc then rowspan = rowspan +1 end
        if itm.patchnotes then rowspan = rowspan +1 end
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b"):wikitext(name)
            :attr("rowspan", rowspan)
        tr:tag("td"):wikitext(target)
        tr:tag("td"):wikitext(effects)
        tr:tag("td"):wikitext(user)
        tr:tag("td"):wikitext(cost)
        tr:tag("td"):wikitext(obtain)
 
        if elemancy then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(tostring(elemancy))
        end
        if itm.desc then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(BLADE.formatfield(data, itm, "desc"))
        end
        if itm.patchnotes then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(
                    "'''Patch notes:''' " ..
                    BLADE.formatfield(data, itm, "patchnotes")
                )
        end
    end
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
function p.Attires(frame)
    local datapage = "Module:FFXV Data/Attires"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local character = args.character and args.character:lower()
 
    if character then
        args[character] = "true"
    end
 
    local querydata = BLADE.select(data, args)
 
    local colspan = 3
    if not character then
        colspan = colspan + 1
    end
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext("Name")
    thead:tag("th"):wikitext("Image")
    thead:tag("th"):wikitext("Effect")
    thead:tag("th"):wikitext("Obtain")
    if not character then
        thead:tag("th"):wikitext("Character")
    end
    for i=1, #querydata do
        local itm = querydata[i]
 
        local rowspan = 1
 
        if itm.desc then
            rowspan = rowspan + 1
        end
        if itm.patchnotes then
            rowspan = rowspan + 1
        end
 
        local name = BLADE.formatlink(data, itm, "link", "name")
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        local image = {}
        if character then
            local charimagefield = character .. "image"
            if itm[charimagefield] then
                table.insert(image, BLADE.formatfield(data, itm, charimagefield))
            end
        else
            if itm.noctisimage then
                local charimage = BLADE.formatfield(data, itm, "noctisimage")
                charimage:setCaption("Noctis")
                table.insert(image, charimage)
            end
            if itm.gladiolusimage then
                local charimage = BLADE.formatfield(data, itm, "gladiolusimage")
                charimage:setCaption("Gladiolus")
                table.insert(image, charimage)
            end
            if itm.ignisimage then
                local charimage = BLADE.formatfield(data, itm, "ignisimage")
                charimage:setCaption("Ignis")
                table.insert(image, charimage)
            end
            if itm.promptoimage then
                local charimage = BLADE.formatfield(data, itm, "promptoimage")
                charimage:setCaption("Prompto")
                table.insert(image, charimage)
            end
            if itm.irisimage then
                local charimage = BLADE.formatfield(data, itm, "irisimage")
                charimage:setCaption("Iris")
                table.insert(image, charimage)
            end
            if itm.corimage then
                local charimage = BLADE.formatfield(data, itm, "corimage")
                charimage:setCaption("Cor")
                table.insert(image, charimage)
            end
            if itm.araneaimage then
                local charimage = BLADE.formatfield(data, itm, "araneaimage")
                charimage:setCaption("Aranea")
                table.insert(image, charimage)
            end
        end
 
        local imagewidth = math.floor(150 / #image)
 
        for i=1, #image do
            image[i]:setHeight(250):setWidth(imagewidth)
            image[i] = tostring(image[i])
        end
 
        image = table.concat(image, "")
 
        local effects = {}
        if itm.crt ~= 0 then
            table.insert(effects, "Critical Rate " .. BLADE.formatfield(data, itm, "crt"))
        elseif itm.crtint ~= 0 then
            table.insert(effects, "Critical Rate " .. BLADE.formatfield(data, itm, "crtint"))
        end
        if itm.mhp ~= 0 then
            table.insert(effects, "Max HP " .. BLADE.formatfield(data, itm, "mhp"))
        elseif itm.mhpint ~= 0 then
            table.insert(effects, "Max HP " .. BLADE.formatfield(data, itm, "mhpint"))
        end
        if itm.mmp ~= 0 then
            table.insert(effects, "Max MP " .. BLADE.formatfield(data, itm, "mmp"))
        elseif itm.mmpint ~= 0 then
            table.insert(effects, "Max MP " .. BLADE.formatfield(data, itm, "mmpint"))
        end
        if itm.hpr ~= 0 then
            table.insert(effects, "HP Recovery Rate " .. BLADE.formatfield(data, itm, "hpr"))
        elseif itm.hprint ~= 0 then
            table.insert(effects, "HP Recovery Rate " .. BLADE.formatfield(data, itm, "hprint"))
        end
        if itm.mpr ~= 0 then
            table.insert(effects, "MP Recovery Rate " .. BLADE.formatfield(data, itm, "mpr"))
        elseif itm.mprint ~= 0 then
            table.insert(effects, "MP Recovery Rate " .. BLADE.formatfield(data, itm, "mprint"))
        end
        if itm.str ~= 0 then
            table.insert(effects, "Strength " .. BLADE.formatfield(data, itm, "str"))
        elseif itm.strint ~= 0 then
            table.insert(effects, "Strength " .. BLADE.formatfield(data, itm, "strint"))
        end
        if itm.vit ~= 0 then
            table.insert(effects, "Vitality " .. BLADE.formatfield(data, itm, "vit"))
        elseif itm.vitint ~= 0 then
            table.insert(effects, "Vitality " .. BLADE.formatfield(data, itm, "vitint"))
        end
        if itm.mag ~= 0 then
            table.insert(effects, "Magic " .. BLADE.formatfield(data, itm, "mag"))
        elseif itm.magint ~= 0 then
            table.insert(effects, "Magic " .. BLADE.formatfield(data, itm, "magint"))
        end
        if itm.spr ~= 0 then
            table.insert(effects, "Spirit " .. BLADE.formatfield(data, itm, "spr"))
        elseif itm.sprint ~= 0 then
            table.insert(effects, "Spirit " .. BLADE.formatfield(data, itm, "sprint"))
        end
        if itm.sht ~= 0 then
            table.insert(effects, "Shot Res. " .. BLADE.formatfield(data, itm, "sht"))
        elseif itm.shtint ~= 0 then
            table.insert(effects, "Shot Res. " .. BLADE.formatfield(data, itm, "shtint"))
        end
        if itm.fir ~= 0 then
            table.insert(effects, "Fire Res. " .. BLADE.formatfield(data, itm, "fir"))
        elseif itm.firint ~= 0 then
            table.insert(effects, "Fire Res. " .. BLADE.formatfield(data, itm, "firint"))
        end
        if itm.ice ~= 0 then
            table.insert(effects, "Ice Res. " .. BLADE.formatfield(data, itm, "ice"))
        elseif itm.iceint ~= 0 then
            table.insert(effects, "Ice Res. " .. BLADE.formatfield(data, itm, "iceint"))
        end
        if itm.ltn ~= 0 then
            table.insert(effects, "Lightning Res. " .. BLADE.formatfield(data, itm, "ltn"))
        elseif itm.ltnint ~= 0 then
            table.insert(effects, "Lightning Res. " .. BLADE.formatfield(data, itm, "ltnint"))
        end
        if itm.drk ~= 0 then
            table.insert(effects, "Dark Res. " .. BLADE.formatfield(data, itm, "drk"))
        elseif itm.drkint ~= 0 then
            table.insert(effects, "Dark Res. " .. BLADE.formatfield(data, itm, "drkint"))
        end
        local status = {}
        if itm.mollified then
            table.insert(status, "[[Final Fantasy XV statuses#Enfeebled|Enfeebled]]")
        end
        if itm.disenchanted then
            table.insert(status, "[[Final Fantasy XV statuses#Disenchanted|Disenchanted]]")
        end
        if itm.burnt then
            table.insert(status, "[[Final Fantasy XV statuses#Burnt|Burnt]]")
        end
        if itm.frozen then
            table.insert(status, "[[Final Fantasy XV statuses#Frozen|Frozen]]")
        end
        if itm.shocked then
            table.insert(status, "[[Final Fantasy XV statuses#Shocked|Shocked]]")
        end
        if #status > 0 then
            table.insert(effects, "Immune to " .. table.concat(status, ", "))
        end
        if itm.flameproof then
            table.insert(effects, "Immune to Fire elemental damage")
        end
        if itm.endurance then
            table.insert(effects, "Grants infinite stamina")
        end
        if itm.effect then
            table.insert(effects, BLADE.formatfield(data, itm, "effect"))
        end
        effects = table.concat(effects, "; ")
 
        local user = {}
        if not character then
            if itm.noctis then
                table.insert(user, "Noctis")
            end
            if itm.gladiolus then
                table.insert(user, "Gladiolus")
            end
            if itm.ignis then
                table.insert(user, "Ignis")
            end
            if itm.prompto then
                table.insert(user, "Prompto")
            end
            if itm.iris then
                table.insert(user, "Iris")
            end
            if itm.cor then
                table.insert(user, "Cor")
            end
            if itm.aranea then
                table.insert(user, "Aranea")
            end
        end
        user = table.concat(user, ", ")
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th")
            :addClass("b")
            :wikitext(name)
            :attr("rowspan", rowspan)
        tr:tag("td")
            :attr(BLADE.cellformat("image"))
            :wikitext(image)
        tr:tag("td")
            :attr(BLADE.cellformat("string", "longtext"))
            :wikitext(effects)
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "unlock"))
            :wikitext(BLADE.formatfield(data, itm, "unlock"))
        if not character then 
            tr:tag("td")
                :attr(BLADE.cellformat("string", "longtext"))
                :wikitext(user)
        end
 
        if itm.desc then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr(BLADE.cellformatfield(data, "desc"))
                :attr("colspan", colspan)
                :wikitext(BLADE.formatfield(data, itm, "desc"))
        end
        if itm.patchnotes then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr(BLADE.cellformatfield(data, "patchnotes"))
                :attr("colspan", colspan)
                :wikitext(
                    "'''Patch notes:''' " ..
                    BLADE.formatfield(data, itm, "patchnotes")
                )
        end
    end
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
function p.Ingredients(frame)
    local datapage = "Module:FFXV Data/Ingredients"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local querydata = BLADE.select(data, args)
 
    local recipedatapage = "Module:FFXV Data/Recipes"
    local recipedata = mw.loadData(recipedatapage)
 
    local colspan = 3
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext("Name")
    thead:tag("th"):wikitext("Value")
    thead:tag("th"):wikitext("Recipes")
    thead:tag("th"):wikitext("Obtain")
    for i=1, #querydata do
        local itm = querydata[i]
 
        local name = BLADE.formatlink(data, itm, "link", "name")
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        if itm.image then
            name = name .. '<br/>' .. BLADE.formatfield(data, itm, "image"):setWidth(180)
        end
 
        local canbuy = itm.shop
        local cansell = not itm.unsellable
        local buyprice = itm.cost
        local sellprice = itm.cost==0 and 0 or (itm.cost/2)
        if not canbuy then
            buyprice = "&mdash;"
        end
        if not cansell then
            sellprice = "&mdash;"
        end
        local cost = "Buy: " .. buyprice .. "<br/>Sell: " .. sellprice
 
        local recipes = {}
        local recipequery = BLADE.select(recipedata, {ingredients=itm.name}, { "name", "disambig", "ingredients" })
        for i=1, #recipequery do
            local rec = recipequery[i]
            recipes[i] = ("[[%s#%s|%s]]"):format(recipedata.mainpage, rec.name, rec.name .. ((rec.disambig~="") and (" (" .. rec.disambig .. ")") or ""))
        end
 
        local obtain = {}
        if itm.default then table.insert(obtain, "'''Default:''' " .. itm.default) end
        if itm.find then table.insert(obtain, "'''Find:''' " .. itm.find) end
        if itm.reward then table.insert(obtain, "'''Reward:''' " .. itm.reward) end
        if itm.shop then table.insert(obtain, "'''Shop:''' " .. itm.shop) end
        if itm.upgrade then table.insert(obtain, "'''Upgrade:''' " .. itm.upgrade) end
        if itm.trade then table.insert(obtain, "'''Trade:''' " .. itm.trade) end
        if itm.drop then table.insert(obtain, "'''Enemy drop:''' " .. itm.drop) end
        if itm.download then table.insert(obtain, "'''Download:''' " .. itm.download) end
        obtain = table.concat(obtain, "<br/>")
 
         --ELEMANCY
        local elemancy
        if itm.powervalue then
            local addedeffect = BLADE.formatfield(data, itm, "addedeffect")
            local powervalue = BLADE.formatfield(data, itm, "powervalue")
            local effectlevel = BLADE.formatfield(data, itm, "effectlevel")
            local duplicationunits = BLADE.formatfield(data, itm, "duplicationunits")
            elemancy = html.create("div")
                :node(createslip(
                    "Added effect",
                    itm.addedeffect and addedeffect or "None"
                    )
                )
                :node(createslip(
                    "Power value",
                    itm.powervalue and powervalue or "&mdash;"
                    )
                )
                :node(createslip(
                    "Effect level",
                    itm.effectlevel and effectlevel or "&mdash;"
                    )
                )
                :node(createslip(
                    "Duplication units",
                    itm.duplicationunits and duplicationunits or "&mdash;"
                    )
                )
        end
 
        local rowspan = 1
        if itm.desc then
            rowspan = rowspan + 1
        end
        if itm.patchnotes then
            rowspan = rowspan + 1
        end
        if elemancy then
            rowspan = rowspan + 1
        end
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b"):wikitext(name)
            :attr("rowspan", rowspan)
        tr:tag("td"):wikitext(cost)
        tr:tag("td")
            :attr(BLADE.cellformat("string", "longtext"))
            :wikitext(table.concat(recipes, ", "))
        tr:tag("td"):wikitext(obtain)
 
        if elemancy then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(tostring(elemancy))
        end
        if itm.desc then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr(BLADE.cellformatfield(data, "desc"))
                :attr("colspan", colspan)
                :wikitext(BLADE.formatfield(data, itm, "desc"))
        end
        if itm.patchnotes then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(
                    "'''Patch notes:''' " ..
                    BLADE.formatfield(data, itm, "patchnotes")
                )
        end
    end
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
function p.RestaurantMeals(frame)
    local datapage = "Module:FFXV Data/RestaurantMeals"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local querydata = BLADE.select(data, args)
 
    local statusdata = mw.loadData("Module:FFXV Data/FoodStatuses")
    local statusquerydata = BLADE.select(statusdata, {}, {"name", "icon", "leveleffect", "effect", "multiplier"})
 
    local statusattr = {}
    local statusattrorder = {}
    for i=1, #statusquerydata do
        local itm = statusquerydata[i]
        local name = itm.name
        local key = name:lower():gsub("[- ]", "")
        statusattr[key] = itm
        statusattrorder[i] = key
    end
 
    local displayrestaurant = (not args.displayrestaurant) or args.displayrestaurant ~= "false"
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext("Name")
    thead:tag("th"):wikitext("Effects")
    thead:tag("th"):wikitext("Price")
    thead:tag("th"):wikitext("Recipe obtained")
    thead:tag("th"):wikitext(displayrestaurant and "Restaurants" or "Unlock")
    for i=1, #querydata do
        local itm = querydata[i]
        local name = BLADE.formatlink(data, itm, "link", "name")
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        if itm.image then
            name = name .. '<br/>' .. BLADE.formatfield(data, itm, "image"):setWidth(180)
        end
 
        local effects = {}
        for i, k in ipairs(statusattrorder) do
            local found = itm[k]
            if found then
                local v = statusattr[k]
                local name = v.name
                local icon
                if v.icon then
                    icon = BLADE.formatfield(statusquerydata, v, "icon"):setWidth(12)
                end
                local desc = v.leveleffect or v.effect
                if type(itm[k])=="number" then
                    name = name .. " (Level " .. itm[k] .. ")"
                    desc = desc:format(itm[k]*v.multiplier)
                end
                name = (icon or "") .. " [[Final Fantasy XV statuses#" .. v.name .. "|" .. name .. "]]"
                table.insert(effects, "<b>" .. name .. ":</b> " .. desc)
            end
        end
        effects = table.concat(effects, "<br/>")
 
        local howtobuy
        if displayrestaurant then
            howtobuy = itm.restaurant
            if itm.unlock then
                howtobuy = howtobuy .. "; " .. itm.unlock
            end
        else
            howtobuy = itm.unlock or "Default"
        end
 
        local recipename = "&mdash;"
        if itm.recipe then
            recipename = BLADE.formatfield(data, itm, "recipe")
            recipename = "[[Recipe (Final Fantasy XV)#" .. recipename .. "|" .. recipename .. "]]"
        end
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b"):wikitext(name)
            :attr("rowspan", 1 +
                (itm.desc~="" and 1 or 0)
                +
                (itm.patchnotes and 1 or 0)
            )
        tr:tag("td"):wikitext(effects)
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "cost"))
            :wikitext(BLADE.formatfield(data, itm, "cost"))
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "recipe"))
            :wikitext(recipename)
        tr:tag("td")
            :wikitext(howtobuy)
 
        if itm.desc~="" then
            tr = tbl:tag("tr")
            tr:tag("td"):attr("colspan", 5):wikitext(BLADE.formatfield(data, itm, "desc"))
        end
        if itm.patchnotes then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", 4 + (displayrestaurant and 1 or 0))
                :wikitext(
                    "'''Patch notes:''' " ..
                    BLADE.formatfield(data, itm, "patchnotes")
                )
        end
    end
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
function p.Recipes(frame)
    local datapage = "Module:FFXV Data/Recipes"
    local data = mw.loadData(datapage)
 
    args = getArgs(frame)
 
    local querydata = BLADE.select(data, args)
 
    local statusdata = mw.loadData("Module:FFXV Data/FoodStatuses")
    local statusquerydata = BLADE.select(statusdata, {}, {"name", "icon", "leveleffect", "effect", "multiplier"})
 
    local statusattr = {}
    local statusattrorder = {}
    for i=1, #statusquerydata do
        local itm = statusquerydata[i]
        local name = itm.name
        local key = name:lower():gsub("[- ]", "")
        statusattr[key] = itm
        statusattrorder[i] = key
    end
 
    local displaycharacter = (not args.displaycharacter) or args.displaycharacter ~= "false"
 
    local colspan = 5
    if displaycharacter then
        colspan = 6
    end
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
        :addClass("sortable")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th")
        :wikitext("Name")
    thead:tag("th")
        :wikitext("Ingredients")
        :addClass("unsortable")
    thead:tag("th")
        :wikitext("Effects")
        :addClass("unsortable")
    thead:tag("th")
        :wikitext("SP")
    if displaycharacter then
        thead:tag("th"):wikitext("Favorite of")
    end
    thead:tag("th")
        :wikitext("Unlock")
        :addClass("unsortable")
    for i=1, #querydata do
        local itm = querydata[i]
        local name = BLADE.formatlink(data, itm, "link", "name")
 
        if itm.disambig ~= "" then
            name = name .. "<br/><small><i>(" .. itm.disambig .. ")</i></small>"
        end
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        if itm.image then
            name = name .. '<br/>' .. BLADE.formatfield(data, itm, "image"):setWidth(180)
        end
 
        local ingredients = {}
        if itm.ingredients then
            for _, v in ipairs (itm.ingredients) do
                table.insert(ingredients, "[[Ingredients#" .. v .. "|" .. v .. "]]")
            end
        end
        if #ingredients == 0 then table.insert(ingredients, "None") end
        ingredients = table.concat(ingredients, "<br/>")
 
        local effects = {}
        for i, k in ipairs(statusattrorder) do
            local found = itm[k]
            if found then
                local v = statusattr[k]
                local name = v.name
                local icon
                if v.icon then
                    icon = BLADE.formatfield(statusquerydata, v, "icon"):setWidth(12)
                end
                local desc = v.leveleffect or v.effect
                if type(itm[k])=="number" then
                    name = name .. " (Level " .. itm[k] .. ")"
                    desc = desc:format(itm[k]*v.multiplier)
                end
                name = (icon or "") .. " [[Final Fantasy XV statuses#" .. v.name .. "|" .. name .. "]]"
                table.insert(effects, "<b>" .. name .. ":</b> " .. desc)
            end
        end
 
        local favorite--there can only be one!
        if itm.noctis then
            favorite = "Noctis"
        elseif itm.gladio then
            favorite = "Gladio"
        elseif itm.ignis then
            favorite = "Ignis"
        elseif itm.prompto then
            favorite = "Prompto"
        else
            favorite = "&mdash;"
        end
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b"):wikitext(name)
            :attr("rowspan", 1 +
                (itm.desc~="" and 1 or 0)
                +
                (itm.patchnotes and 1 or 0)
            )
        tr:tag("td"):wikitext(ingredients)
        tr:tag("td"):wikitext(table.concat(effects, "<br/>"))
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "sp"))
            :wikitext(itm.sp==0 and "?" or BLADE.formatfield(data, itm, "sp"))
        if displaycharacter then
            tr:tag("td")
                :attr(BLADE.cellformat("string"))
                :wikitext(favorite)
        end
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "unlock"))
            :wikitext(BLADE.formatfield(data, itm, "unlock"))
 
        if itm.desc~="" then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(BLADE.formatfield(data, itm, "desc"))
        end
        if itm.patchnotes then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(
                    "'''Patch notes:''' " ..
                    BLADE.formatfield(data, itm, "patchnotes")
                )
        end
    end
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
function p.Fish(frame)
    local datapage = "Module:FFXV Data/Fish"
    local data = mw.loadData(datapage)
    local luredatapage = "Module:FFXV Data/Lures"
    local luredata = mw.loadData(luredatapage)
    args = getArgs(frame)
 
    local parameters = { "name", "jpn", "rom", "lit", "link", "image", "sp", "exp", "ap", "item", "stm", "pwr", "info", "spots" }
 
    local querydata = BLADE.select(data, args, parameters)
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext(BLADE.fieldtitle(data, "name"))
    thead:tag("th"):wikitext(BLADE.fieldtitle(data, "stm"))
    thead:tag("th"):wikitext(BLADE.fieldtitle(data, "pwr"))
    thead:tag("th"):wikitext(BLADE.fieldtitle(data, "sp"))
    thead:tag("th"):wikitext(BLADE.fieldtitle(data, "exp"))
    thead:tag("th"):wikitext(BLADE.fieldtitle(data, "ap"))
    thead:tag("th"):wikitext(BLADE.fieldtitle(data, "item"))
    thead:tag("th"):wikitext("Optimal lures&nbsp;" .. tostring(BLADE.dnav(luredata, luredatapage, false, {purge=false})))
    thead:tag("th"):wikitext(BLADE.fieldtitle(data, "spots"))
    for i=1, #querydata do
        local itm = querydata[i]
        local name = BLADE.formatlink(data, itm, "link", "name")
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        if itm.image then
            name = name .. '<br/>' .. BLADE.formatfield(data, itm, "image"):setWidth(180)
        end
 
        local optimallures = {}
        local lurequery = BLADE.select(luredata, {suits=itm.name}, { "name", "suits" })
        for i=1, #lurequery do
            local lur = lurequery[i]
            optimallures[i] = ("[[%s#%s|%s]]"):format(luredata.mainpage, lur.name, lur.name)
        end
 
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b")
            :attr("rowspan", itm.info and 2 or 1)
            :wikitext(name)
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "stm"))
            :wikitext(BLADE.formatfield(data, itm, "stm"))
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "pwr"))
            :wikitext(BLADE.formatfield(data, itm, "pwr"))
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "sp"))
            :wikitext(BLADE.formatfield(data, itm, "sp"))
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "exp"))
            :wikitext(BLADE.formatfield(data, itm, "exp"))
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "ap"))
            :wikitext(BLADE.formatfield(data, itm, "ap"))
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "item"))
            :wikitext(BLADE.formatfield(data, itm, "item"))
        tr:tag("td")
            :attr(BLADE.cellformat("string", "longtext"))
            :wikitext(table.concat(optimallures, ", "))
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "spots"))
            :wikitext(BLADE.formatfield(data, itm, "spots"))
        if itm.info then
            tbl:tag("tr"):tag("td")
                :attr(BLADE.cellformatfield(data, "info"))
                :attr("colspan", 8)
                :wikitext(BLADE.formatfield(data, itm, "info"))
        end
    end
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
function p.Lures(frame)
    local datapage = "Module:FFXV Data/Lures"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local parameters = { "name", "jpn", "rom", "lit", "link", "image", "morning", "day", "evening", "night", "sunny", "cloudy", "rainy", "suits", "info", "find", "shop", "reward", "download" }
 
    local querydata = BLADE.select(data, args, parameters)
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = {
        tbl:tag("tr"):addClass("a"),
        tbl:tag("tr"):addClass("a")
    }
    thead[1]:tag("th")
        :wikitext(BLADE.fieldtitle(data, "name"))
        :attr("rowspan", 2)
    thead[1]:tag("th")
        :wikitext("Effectiveness (time)")
        :attr("colspan", 4)
    thead[1]:tag("th")
        :wikitext("Effectiveness (weather)")
        :attr("colspan", 3)
    thead[1]:tag("th")
        :wikitext(BLADE.fieldtitle(data, "suits"))
        :attr("rowspan", 2)
    thead[1]:tag("th")
        :wikitext("Obtains")
        :attr("rowspan", 2)
    thead[2]:tag("th")
        :wikitext(BLADE.fieldtitle(data, "morning"))
    thead[2]:tag("th")
        :wikitext(BLADE.fieldtitle(data, "day"))
    thead[2]:tag("th")
        :wikitext(BLADE.fieldtitle(data, "evening"))
    thead[2]:tag("th")
        :wikitext(BLADE.fieldtitle(data, "night"))
    thead[2]:tag("th")
        :wikitext(BLADE.fieldtitle(data, "sunny"))
    thead[2]:tag("th")
        :wikitext(BLADE.fieldtitle(data, "cloudy"))
    thead[2]:tag("th")
        :wikitext(BLADE.fieldtitle(data, "rainy"))
    for i=1, #querydata do
        local itm = querydata[i]
        local name = BLADE.formatlink(data, itm, "link", "name")
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        if itm.image then
            name = name .. '<br/>' .. BLADE.formatfield(data, itm, "image"):setWidth(180)
        end
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b")
            :attr("rowspan", itm.info and 2 or 1)
            :wikitext(name)
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "morning"))
            :wikitext(BLADE.formatfield(data, itm, "morning"))
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "day"))
            :wikitext(BLADE.formatfield(data, itm, "day"))
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "evening"))
            :wikitext(BLADE.formatfield(data, itm, "evening"))
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "night"))
            :wikitext(BLADE.formatfield(data, itm, "night"))
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "sunny"))
            :wikitext(BLADE.formatfield(data, itm, "sunny"))
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "cloudy"))
            :wikitext(BLADE.formatfield(data, itm, "cloudy"))
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "rainy"))
            :wikitext(BLADE.formatfield(data, itm, "rainy"))
 
        local fish = {}
        local fishpage = require "Module:FFXV Data/Fish".mainpage
        for _, v in ipairs(itm.suits) do
            local thisfish= v
            table.insert(fish, "[[" .. fishpage .."#" .. thisfish .. "|" .. thisfish .. "]]")
        end
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "suits"))
            :wikitext(table.concat(fish, ", "))
 
        local obtain = {}
        if itm.find then table.insert(obtain, "'''Find:''' " .. itm.find) end
        if itm.reward then table.insert(obtain, "'''Reward:''' " .. itm.reward) end
        if itm.shop then table.insert(obtain, "'''Shop:''' " .. itm.shop) end
        if itm.download then table.insert(obtain, "'''Download:''' " .. itm.download) end
        tr:tag("td"):wikitext(table.concat(obtain, "<br/>"))
 
 
        if itm.info then
            tbl:tag("tr"):tag("td")
                :attr(BLADE.cellformatfield(data, "info"))
                :attr("colspan", 8)
                :wikitext(BLADE.formatfield(data, itm, "info"))
        end
    end
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
function p.FoodStatuses(frame)
    local datapage = "Module:FFXV Data/FoodStatuses"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local querydata = BLADE.select(data, args)
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext("Name")
    thead:tag("th"):wikitext("Effect")
 
    for i=1, #querydata do
        local itm = querydata[i]
        local name = BLADE.formatlink(data, itm, "link", "name")
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        if itm.icon then
            name = name .. '<br/>' .. BLADE.formatfield(data, itm, "icon")
        end
 
        local description = itm.icondesc or itm.desc
 
        if description ~= "" and itm.multiplier then
            description = description:format(itm.multiplier .. "n")
        end
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b"):wikitext(name)
            :attr("rowspan", 1 +
                (itm.desc~="" and 1 or 0)
                +
                (itm.patchnotes and 1 or 0)
            )
        tr:tag("td"):wikitext(BLADE.formatfield(data, itm, "effect"))
 
        if description~="" then
            tr = tbl:tag("tr")
            tr:tag("td"):attr("colspan", 1):wikitext(BLADE.format(description, "string", "quote"))
        end
        if itm.patchnotes then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", 1)
                :wikitext(
                    "'''Patch notes:''' " ..
                    BLADE.formatfield(data, itm, "patchnotes")
                )
        end
    end
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
function p.Sidequests(frame)
    local datapage = "Module:FFXV Data/Sidequests"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local displaycategory = (not args.displaycategory) or args.displaycategory ~= "false"
    local displaylocation = (not args.displaylocation) or args.displaylocation ~= "false"
 
    local querydata = BLADE.select(data, args)
 
    local colspan = 3
    if displaycategory then
        colspan = colspan + 1
    end
    if displaylocation then
        colspan = colspan + 1
    end
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext("Name")
    if displaycategory then
        thead:tag("th"):wikitext("Category")
    end
    if displaylocation then
        thead:tag("th"):wikitext("Location")
    end
    thead:tag("th"):wikitext("Unlock")
    thead:tag("th"):wikitext("Reward")
 
 
    for i=1, #querydata do
        local itm = querydata[i]
        local name = BLADE.listlink(data, itm, "name")
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b"):wikitext(name)
            :attr("rowspan", 1)
        if displaycategory then
            tr:tag("td"):wikitext(itm.category):css("text-align", "center")
        end
        if displaylocation then
            tr:tag("td"):wikitext(itm.location):css("text-align", "center")
        end
        tr:tag("td"):wikitext(itm.unlock)
        tr:tag("td"):wikitext(itm.reward)
 
        if itm.patchnotes then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", 1)
                :wikitext(
                    "'''Patch notes:''' " ..
                    BLADE.formatfield(data, itm, "patchnotes")
                )
        end
    end
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
 
end
 
function p.Hunts(frame)
    local datapage = "Module:FFXV Data/Hunts"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local displaylocation = (not args.displaylocation) or args.displaylocation ~= "false"
 
    local querydata = BLADE.select(data, args)
 
    local colspan = 8
    if displaylocation then
        colspan = colspan + 1
    end
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
        :addClass("sortable")
        :css("text-align", "center")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext("Name")
    if displaylocation then
        thead:tag("th"):wikitext("Location")
    end
    thead:tag("th"):wikitext("Rank")
    thead:tag("th"):wikitext("Type")
    thead:tag("th"):wikitext("Mark")
    thead:tag("th"):wikitext("Habitat")
    thead:tag("th"):wikitext("Level")
    thead:tag("th"):wikitext("Reward")
    thead:tag("th"):wikitext("Stars")
 
 
    for i=1, #querydata do
        local itm = querydata[i]
        local name = BLADE.formatlink(data, itm, "link", "name")--needs reformatted to link to Quest (Final Fantasy XV)/Sidequests#"name" instead, not sure how
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b"):wikitext(name)
            :attr("rowspan", 1)
        if displaycategory then
            tr:tag("td"):wikitext(itm.category):css("text-align", "center")
        end
        if displaylocation then
            tr:tag("td"):wikitext(itm.location):css("text-align", "center")
        end
        tr:tag("td"):wikitext(itm.rank)
        tr:tag("td"):wikitext(itm.type)
        tr:tag("td"):wikitext(itm.mark)
        tr:tag("td"):wikitext(itm.habitat)
        tr:tag("td"):wikitext(itm.level)
        tr:tag("td"):wikitext(itm.reward)
        tr:tag("td"):wikitext(itm.stars)
 
        if itm.patchnotes then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", 1)
                :wikitext(
                    "'''Patch notes:''' " ..
                    BLADE.formatfield(data, itm, "patchnotes")
                )
        end
    end
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
 
end
 
function p.AutoParts(frame)
    local datapage = "Module:FFXV Data/AutoParts"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local displaycategory = (not args.displaycategory) or args.displaycategory ~= "false"
 
    local querydata = BLADE.select(data, args)
 
    local colspan = 2
    if displaycategory then
        colspan = colspan + 1
    end
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext("Name")
    if displaycategory then
        thead:tag("th"):wikitext("Category")
    end
    thead:tag("th"):wikitext("Value")
    thead:tag("th"):wikitext("Obtain")
    for i=1, #querydata do
        local itm = querydata[i]
 
        local rowspan = 1
        if itm.desc then
            rowspan = rowspan + 1
        end
        if itm.eff then
            rowspan = rowspan + 1
        end
        if itm.patchnotes then
            rowspan = rowspan + 1
        end
 
 
        local name = BLADE.formatlink(data, itm, "link", "name")
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        if itm.image then
            name = name .. '<br/>' .. BLADE.formatfield(data, itm, "image"):setWidth(180)
        end
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b"):wikitext(name)
            :attr("rowspan", rowspan)
        if displaycategory then
            tr:tag("td"):wikitext(itm.category):css("text-align", "center")
        end
 
        local canbuy = itm.shop
        local cansell = not itm.unsellable
        local buyprice = itm.cost
        local sellprice = itm.cost==0 and 0 or (itm.cost)
        if not canbuy then
            buyprice = "&mdash;"
        end
        if not cansell then
            sellprice = "&mdash;"
        end
        tr:tag("td"):wikitext("Buy: " .. buyprice .. "<br/>Sell: " .. sellprice):css("text-align", "center")
        local obtain = {}
        if itm.default then table.insert(obtain, "'''Default:''' " .. itm.default) end
        if itm.find then table.insert(obtain, "'''Find:''' " .. itm.find) end
        if itm.reward then table.insert(obtain, "'''Reward:''' " .. itm.reward) end
        if itm.shop then table.insert(obtain, "'''Shop:''' " .. itm.shop) end
        if itm.upgrade then table.insert(obtain, "'''Upgrade:''' " .. itm.upgrade) end
        if itm.trade then table.insert(obtain, "'''Trade:''' " .. itm.trade) end
        if itm.drop then table.insert(obtain, "'''Enemy drop:''' " .. itm.drop) end
        if itm.download then table.insert(obtain, "'''Download:''' " .. itm.download) end
        tr:tag("td"):wikitext(table.concat(obtain, "<br/>"))
 
        if itm.desc then
            tr = tbl:tag("tr")
            tr:tag("td"):attr("colspan", colspan):wikitext(BLADE.formatfield(data, itm, "desc"))
        end
        if itm.eff then
            tr = tbl:tag("tr")
            tr:tag("td"):attr("colspan", colspan):wikitext(BLADE.formatfield(data, itm, "eff"))
        end
        if itm.patchnotes then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(
                    "'''Patch notes:''' " ..
                    BLADE.formatfield(data, itm, "patchnotes")
                )
        end
    end
 
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
function p.AutoParts2(frame)
    local datapage = "Module:FFXV Data/AutoParts2"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local displaycategory = (not args.displaycategory) or args.displaycategory ~= "false"
 
    local querydata = BLADE.select(data, args)
 
    local colspan = 3
    if displaycategory then
        colspan = colspan + 1
    end
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext("Name")
    if displaycategory then
        thead:tag("th"):wikitext("Category")
    end
    thead:tag("th"):wikitext("Value")
    thead:tag("th"):wikitext("Obtain")
    thead:tag("th"):wikitext("Used")
    for i=1, #querydata do
        local itm = querydata[i]
 
        local rowspan = 1
        if itm.desc then
            rowspan = rowspan + 1
        end
        if itm.eff then
            rowspan = rowspan + 1
        end
        if itm.patchnotes then
            rowspan = rowspan + 1
        end
 
 
        local name = BLADE.formatlink(data, itm, "link", "name")
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        if itm.image then
            name = name .. '<br/>' .. BLADE.formatfield(data, itm, "image"):setWidth(180)
        end
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b"):wikitext(name)
            :attr("rowspan", rowspan)
        if displaycategory then
            tr:tag("td"):wikitext(itm.category):css("text-align", "center")
        end
 
        local canbuy = itm.shop
        local cansell = not itm.unsellable
        local buyprice = itm.cost
        local sellprice = itm.cost==0 and 0 or (itm.cost)
        if not canbuy then
            buyprice = "&mdash;"
        end
        if not cansell then
            sellprice = "&mdash;"
        end
        tr:tag("td"):wikitext("Buy: " .. buyprice .. "<br/>Sell: " .. sellprice):css("text-align", "center")
        local obtain = {}
        if itm.default then table.insert(obtain, "'''Default:''' " .. itm.default) end
        if itm.find then table.insert(obtain, "'''Find:''' " .. itm.find) end
        if itm.reward then table.insert(obtain, "'''Reward:''' " .. itm.reward) end
        if itm.shop then table.insert(obtain, "'''Shop:''' " .. itm.shop) end
        if itm.upgrade then table.insert(obtain, "'''Upgrade:''' " .. itm.upgrade) end
        if itm.trade then table.insert(obtain, "'''Trade:''' " .. itm.trade) end
        if itm.drop then table.insert(obtain, "'''Enemy drop:''' " .. itm.drop) end
        if itm.download then table.insert(obtain, "'''Download:''' " .. itm.download) end
        tr:tag("td"):wikitext(table.concat(obtain, "<br/>"))
 
        local used = {}
        if itm.used then
            for _, v in ipairs (itm.used) do
             table.insert(used, "[[Regalia/Color#" .. v .. "|" .. v .. "]]")
            end
    end
        if #used == 0 then table.insert(used, "None") end
        used = table.concat(used, ", ")
 
        tr:tag("td"):wikitext(used)
 
        if itm.desc then
            tr = tbl:tag("tr")
            tr:tag("td"):attr("colspan", colspan):wikitext(BLADE.formatfield(data, itm, "desc"))
        end
        if itm.eff then
            tr = tbl:tag("tr")
            tr:tag("td"):attr("colspan", colspan):wikitext(BLADE.formatfield(data, itm, "eff"))
        end
        if itm.patchnotes then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(
                    "'''Patch notes:''' " ..
                    BLADE.formatfield(data, itm, "patchnotes")
                )
        end
    end
 
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
function p.RegaliaColors(frame)
    local datapage = "Module:FFXV Data/RegaliaColors"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local displaycategory = (not args.displaycategory) or args.displaycategory ~= "false"
 
    local querydata = BLADE.select(data, args)
 
    local colspan = 3
    if displaycategory then
        colspan = colspan + 1
    end
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext("Name")
    thead:tag("th"):wikitext("Items")
    thead:tag("th"):wikitext("Price")
    thead:tag("th"):wikitext("Image")
    for i=1, #querydata do
        local itm = querydata[i]
 
        local rowspan = 1
        if itm.desc then
            rowspan = rowspan + 1
        end
        if itm.patchnotes then
            rowspan = rowspan + 1
        end
 
        local name = BLADE.formatlink(data, itm, "link", "name")
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b"):wikitext(name)
 
        local items = {}
        if itm.whiss then table.insert(items, "'''[[Auto Parts#Whitestone Shard|Whitestone Shard]]:''' " .. BLADE.formatlink(data, itm, "link", "whiss")) end
        if itm.blass then table.insert(items, "'''[[Auto Parts#Blackstone Shard|Blackstone Shard]]:''' " .. BLADE.formatfield(data, itm, "blass")) end
        if itm.redss then table.insert(items, "'''[[Auto Parts#Redstone Shard|Redstone Shard]]:''' " .. BLADE.formatfield(data, itm, "redss")) end
        if itm.bluss then table.insert(items, "'''[[Auto Parts#Bluestone Shard|Bluestone Shard]]:''' " .. BLADE.formatfield(data, itm, "bluss")) end
        if itm.gress then table.insert(items, "'''[[Auto Parts#Greenstone Shard|Greenstone Shard]]:''' " .. BLADE.formatfield(data, itm, "gress")) end
        if itm.yelss then table.insert(items, "'''[[Auto Parts#Yellowstone Shard|Yellowstone Shard]]:''' " .. BLADE.formatfield(data, itm, "yelss")) end
        if itm.whiso then table.insert(items, "'''[[Auto Parts#Whitestone Ore|Whitestone Ore]]:''' " .. BLADE.formatfield(data, itm, "whiso")) end
        if itm.blaso then table.insert(items, "'''[[Auto Parts#Blackstone Ore|Blackstone Ore]]:''' " .. BLADE.formatfield(data, itm, "blaso")) end
        if itm.redso then table.insert(items, "'''[[Auto Parts#Redstone Ore|Redstone Ore]]:''' " .. BLADE.formatfield(data, itm, "redso")) end
        if itm.bluso then table.insert(items, "'''[[Auto Parts#Bluestone Ore|Bluestone Ore]]:''' " .. BLADE.formatfield(data, itm, "bluso")) end
        if itm.greso then table.insert(items, "'''[[Auto Parts#Greenstone Ore|Greenstone Ore]]:''' " .. BLADE.formatfield(data, itm, "greso")) end
        if itm.yelso then table.insert(items, "'''[[Auto Parts#Yellowstone Ore|Yellowstone Ore]]:''' " .. BLADE.formatfield(data, itm, "yelso")) end
        if itm.whisc then table.insert(items, "'''[[Auto Parts#Whitestone Crystal|Whitestone Crystal]]:''' " .. BLADE.formatfield(data, itm, "whisc")) end
        if itm.blasc then table.insert(items, "'''[[Auto Parts#Blackstone Crystal|Blackstone Crystal]]:''' " .. BLADE.formatfield(data, itm, "blasc")) end
        if itm.redsc then table.insert(items, "'''[[Auto Parts#Redstone Crystal|Redstone Crystal]]:''' " .. BLADE.formatfield(data, itm, "redsc")) end
        if itm.blusc then table.insert(items, "'''[[Auto Parts#Bluestone Crystal|Bluestone Crystal]]:''' " .. BLADE.formatfield(data, itm, "blusc")) end
        if itm.gresc then table.insert(items, "'''[[Auto Parts#Greenstone Crystal|Greenstone Crystal]]:''' " .. BLADE.formatfield(data, itm, "gresc")) end
        if itm.yelsc then table.insert(items, "'''[[Auto Parts#Yellowstone Crystal|Yellowstone Crystal]]:''' " .. BLADE.formatfield(data, itm, "yelsc")) end
        if itm.sildu then table.insert(items, "'''[[Auto Parts#Silver Dust|Silver Dust]]:''' " .. BLADE.formatfield(data, itm, "sildu")) end
        if itm.goldu then table.insert(items, "'''[[Auto Parts#Gold Dust|Gold Dust]]:''' " .. BLADE.formatfield(data, itm, "goldu")) end
        if itm.pridu then table.insert(items, "'''[[Auto Parts#Prismatic Dust|Prismatic Dust]]:''' " .. BLADE.formatfield(data, itm, "pridu")) end
        if itm.silsh then table.insert(items, "'''[[Auto Parts#Silver Shard|Silver Shard]]:''' " .. BLADE.formatfield(data, itm, "silsh")) end
        if itm.golsh then table.insert(items, "'''[[Auto Parts#Gold Shard|Gold Shard]]:''' " .. BLADE.formatfield(data, itm, "golsh")) end
        if itm.prish then table.insert(items, "'''[[Auto Parts#Prismatic Shard|Prismatic Shard]]:''' " .. BLADE.formatfield(data, itm, "prish")) end
        if itm.silor then table.insert(items, "'''[[Auto Parts#Silver Ore|Silver Ore]]:''' " .. BLADE.formatfield(data, itm, "silor")) end
        if itm.golor then table.insert(items, "'''[[Auto Parts#Gold Ore|Gold Ore]]:''' " .. BLADE.formatfield(data, itm, "golor")) end
        if itm.prior then table.insert(items, "'''[[Auto Parts#Prismatic Ore|Prismatic Ore]]:''' " .. BLADE.formatfield(data, itm, "prior")) end
        tr:tag("td"):wikitext(table.concat(items, "<br/>"))
 
        tr:tag("td")
            :attr(BLADE.cellformatfield(data, "cost"))
            :wikitext(BLADE.formatfield(data, itm, "cost"))
 
        local image = ""
        if itm.image then
            image = tostring(BLADE.formatfield(data, itm, "image"):setWidth(180))
        end
 
 
        tr:tag("td")
            :attr(BLADE.cellformat("image"))
            :wikitext(image)
 
        if itm.desc then
            tr = tbl:tag("tr")
            tr:tag("td"):attr("colspan", colspan):wikitext(BLADE.formatfield(data, itm, "desc"))
        end
        if itm.patchnotes then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(
                    "'''Patch notes:''' " ..
                    BLADE.formatfield(data, itm, "patchnotes")
                )
        end
end
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
function p.RegaliaInterior(frame)
    local datapage = "Module:FFXV Data/RegaliaInterior"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local displaycategory = (not args.displaycategory) or args.displaycategory ~= "false"
 
    local querydata = BLADE.select(data, args)
 
    local colspan = 3
    if displaycategory then
        colspan = colspan + 1
    end
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext("Name")
    if displaycategory then
        thead:tag("th"):wikitext("Category")
    end
    thead:tag("th"):wikitext("Image")
    for i=1, #querydata do
        local itm = querydata[i]
 
        local rowspan = 1
        if itm.desc then
            rowspan = rowspan + 1
        end
        if itm.patchnotes then
            rowspan = rowspan + 1
        end
 
        local name = BLADE.formatlink(data, itm, "link", "name")
 
        if itm.lit and itm.lit ~= itm.name then
            name = name .. "<br/>(" .. BLADE.formataltjpnname(data, itm, "jpn", "rom", "lit") .. ")"
        end
 
        local tr = tbl:tag("tr"):attr("id", itm.name)
        tr:tag("th"):addClass("b"):wikitext(name)
            :attr("rowspan", rowspan)
        if displaycategory then
            tr:tag("td"):wikitext(itm.category):css("text-align", "center")
        end
 
        local image = ""
        if itm.image then
            image = tostring(BLADE.formatfield(data, itm, "image"):setWidth(180))
        end
 
        tr:tag("td")
            :attr(BLADE.cellformat("image"))
            :wikitext(image)
 
        if itm.desc then
            tr = tbl:tag("tr")
            tr:tag("td"):attr("colspan", colspan):wikitext(BLADE.formatfield(data, itm, "desc"))
        end
        if itm.patchnotes then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(
                    "'''Patch notes:''' " ..
                    BLADE.formatfield(data, itm, "patchnotes")
                )
        end
    end
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
function p.MenaceDungeon(frame)
    local datapage = "Module:FFXV Data/MenaceDungeon"
    local data = mw.loadData(datapage)
    args = getArgs(frame)
 
    local displaycategory = (not args.displaycategory) or args.displaycategory ~= "false"
 
    local querydata = BLADE.select(data, args)
 
    local colspan = 3
    if displaycategory then
        colspan = colspan + 1
    end
 
    local tbl = html.create("table")
        :addClass("FFXV")
        :addClass("article-table")
        :addClass("full-width")
    local thead = tbl:tag("tr"):addClass("a")
    thead:tag("th"):wikitext("Level")
    if displaycategory then
        thead:tag("th"):wikitext("Category")
    end
    thead:tag("th"):wikitext("Enemy")
    thead:tag("th"):wikitext("Item")
    for i=1, #querydata do
        local itm = querydata[i]
 
        local rowspan = 1
        if itm.left then
            rowspan = rowspan + 1
            end
        if itm.middle then
            rowspan = rowspan + 1
            end
        if itm.right then
            rowspan = rowspan + 1
        end
 
        local level = BLADE.formatfield(data, itm, "level")
 
        local enemy = BLADE.formatlink(data, itm, "enemylink", "enemy")
 
        local item = BLADE.formatlink(data, itm, "itemlink", "item")
 
        local tr = tbl:tag("tr"):attr("id", itm.level)
        tr:tag("th"):addClass("b"):wikitext(level)
            :attr("rowspan", rowspan)
        tr:tag("td"):wikitext(enemy):css("text-align", "center")
        tr:tag("td"):wikitext(item):css("text-align", "center")
        if displaycategory then
            tr:tag("td"):wikitext(itm.category):css("text-align", "center")    
 
 
        end
        if itm.left then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(
                    "'''Left:''' " ..
                    BLADE.formatfield(data, itm, "left")
                )
        end
        if itm.middle then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(
                    "'''Middle:''' " ..
                    BLADE.formatfield(data, itm, "middle")
                )
        end
        if itm.right then
            tr = tbl:tag("tr")
            tr:tag("td")
                :attr("colspan", colspan)
                :wikitext(
                    "'''Right:''' " ..
                    BLADE.formatfield(data, itm, "right")
                )
        end
    end
 
    return html.create("div"):node(BLADE.dnav(data, datapage)):node(tbl)
end
 
return p
Community content is available under CC-BY-SA unless otherwise noted.