Module:Page/UnitList

local cargo = require('Module:CargoUtil') local model = require("Module:Data").model local memoize = require('Module:Memoize').memoize

local sf = string.format local function quote(s) return sf('%q', s) end

local p = {}

local render_unit = require('Module:Render/Unit') local render_job_icon = require('Module:Render/Job')._icon local enums = require('Module:Data/Enums') local unitExtra = mw.loadData("Module:Data/Extra/Unit") local gateList = mw.loadData("Module:Data/MasterParam/UnitEnlightenment/Lust")

local baseUnitQuery = '_pageNamespace=10000 AND ai="AI_PLAYER" AND (notsmn IS NULL OR hero = 1) AND piece IS NOT NULL AND server = "gl" AND iname NOT LIKE "%_APRILFOOLS"' local baseUnitFields = "_pageName,iname,rare,img,birth_id,elem,jobsets,skill"

local maxJobs = 3

local function pageNameByType(iname, pageType) if iname == nil then return nil end if pageType == nil then return nil end return 'Data:Game/MasterParam/'..pageType..'/' .. string.gsub(iname, '_', ' ') end

local string_rep = string.rep function p.rarityStar(rare) return string_rep('★', rare) .. string_rep('☆', 5 - rare) end p.rarityStar = memoize(p.rarityStar)

local originConvert = memoize(enums.originFromKey) local elemConvert = memoize(enums.elemFromKey)

local maxUnits = 500

local function getJobData(iname) if iname == nil then return nil end return cargo.query{ tables = "Job", fields = { "_pageName", "server", "ac2d", "mdl", "iname", },   	where = { '_pageNamespace = 10000', 'iname="'..iname..'"', 'server = "gl"', },   }[1] or {} end -- getJobData = memoize(getJobData)

local function getJobSetDatas(inames) if inames == nil or #inames == 0 then return nil end return cargo.query{ tables = {"JobSet"}, fields = {"iname", "job"}, where = { '_pageNamespace = 10000', 'server = "gl"', 'iname IN ('..table.concat(inames, ','):gsub('[^,]+', quote)..')', },   	orderBy = 'lplus', } end local function getJobSetData(iname) if iname == nil then return nil end return cargo.query{ tables = {"JobSet"}, fields = {"iname", "job"}, where = { '_pageNamespace = 10000', 'server = "gl"', 'iname = "'..iname..'"', },	}[1] or {} end

local function getJobSetUpgradeData(targetUnit, targetJobSet, targetJob) if targetUnit == nil or targetJobSet == nil or targetJob == nil then return nil end return cargo.query{ tables = {"JobSet"}, fields = { "_pageName", "cjob", "iname", "job", "ljob1", "llv1", "lplus", "lrare", "target_unit", "nil", },   	where = { '_pageNamespace = 10000', 'cjob = "'..targetJobSet..'"', 'ljob1 = "'..targetJob..'"', 'target_unit = "'..targetUnit..'"', 'server = "gl"', },   }[1] or {} end

local function getLeaderSkill(skill) local skillPageKey = pageNameByType(skill, 'Skill') if skillPageKey == nil then return nil end return model.getLoc(skillPageKey, 'expr') end

local function getEnlightenmentLeaderSkill(iname) if iname == nil then return nil end return (gateList[iname] and gateList[iname]['maxBonus'] and model.getLoc(pageNameByType(gateList[iname]['maxBonus'], 'Skill'), 'expr')) or '' end

function p.unitListItem(unit, mode) if mode == nil then mode = 'default' end

local gearExtra = mw.loadData("Module:Data/Extra/Gear") local render_gear_icon = require('Module:Render/Gear')._icon local tempOutput = {} table.insert(tempOutput, '|-') if mode == 'leader' then table.insert(tempOutput, '|'..render_unit._icon({unit.iname, data=unit, size='small'})) else table.insert(tempOutput, '|'..render_unit._icon({unit.iname, data=unit, name='none'})) table.insert(tempOutput, '|'..render_unit._pageName({unit.iname, data=unit})) end table.insert(tempOutput, '|') if mode ~= 'leader' then table.insert(tempOutput, '| '..(p.rarityStar(unit.rare+1))) -- Get job information local jobUpgradeList = {} if type(unit.jobsets) == 'string' then unit.jobsets = mw.text.split(unit.jobsets, '|') end local jobSetRows = getJobSetDatas(unit.jobsets) for i = 1, maxJobs do   		local jobSet = jobSetRows[i] or {} local tempJobOutput = {} if jobSet.job then local jobData = getJobData(jobSet.job) or {} if jobData.iname then tempJobOutput[#tempJobOutput+1] = render_job_icon({jobData.iname, data=jobData, size='small'}) local jobSetUpgradeData = getJobSetUpgradeData(unit.iname, jobSet.iname, jobData.iname) or {} if jobSetUpgradeData.job then local jobUpgradeData = getJobData(jobSetUpgradeData.job) or {} if jobUpgradeData.iname then tempJobOutput[#tempJobOutput+1] = ' ' tempJobOutput[#tempJobOutput+1] = render_job_icon({jobUpgradeData.iname, data=jobUpgradeData, size='small'}) -- 2nd level upgrade local jobSetUpgrade2Data = getJobSetUpgradeData(unit.iname, jobSetUpgradeData.iname, jobUpgradeData.iname) or {} if jobSetUpgrade2Data.job then local jobUpgrade2Data = getJobData(jobSetUpgrade2Data.job) or {} if jobUpgrade2Data.iname then tempJobOutput[#tempJobOutput+1] = ' ' tempJobOutput[#tempJobOutput+1] = render_job_icon({jobUpgrade2Data.iname, data=jobUpgrade2Data, size='small'}) end end end end end end table.insert(tempOutput, '| '..table.concat(tempJobOutput)) end -- for j=1,maxJobs do       --     local tempJobOutput = {} --    if unit.jobsets[j] then --        local jobSet = getJobSetData(unit.jobsets[j]) or {} --        if jobSet.job then --            local jobData = getJobData(jobSet.job) or {} --            if jobData.iname then --                tempJobOutput[#tempJobOutput+1] = render_job_icon({jobData.iname, data=jobData, size='small'}) --                local jobSetUpgradeData = getJobSetUpgradeData(unit.iname, jobSet.iname, jobData.iname) or {} --                if jobSetUpgradeData.job then --                    jobUpgradeData = getJobData(jobSetUpgradeData.job) or {} --                    if jobUpgradeData.iname then --                        tempJobOutput[#tempJobOutput+1] = ' ' --                        tempJobOutput[#tempJobOutput+1] = render_job_icon({jobUpgradeData.iname, data=jobUpgradeData, size='small'}) --                    end --                end --            end --        end --    end --    table.insert(tempOutput, '| '..table.concat(tempJobOutput)) -- end end local originConvert = memoize(enums.originFromKey) if mode ~= 'collab' then table.insert(tempOutput, '| '..(getLeaderSkill(unit.skill) or '')) table.insert(tempOutput, '| '..getEnlightenmentLeaderSkill(unit.iname)) table.insert(tempOutput, '|'..(originConvert(tonumber(unit.birth_id)) or 'Other')) end table.insert(tempOutput, '| '..(unitExtra[unit.iname]['source'] or 'Unknown')) return { name = model.getLoc(unit._pageName, 'name'), output = table.concat(tempOutput, "\n") } end

function p.unitListHeader(mode) if mode == nil then mode = 'default' end

if mode == 'leader' then return ' ! Name !! Element !! Leader Skill !! Enlightenment Leader Skill !! Origin !! Source' end if mode == 'collab' then return ' ! Portrait !! Name !! Element !! Rarity !! Job 1 !! Job 2 !! Job 3 !! Source' end return ' ! Portrait !! Name !! Element !! Rarity !! Job 1 !! Job 2 !! Job 3 !! Leader Skill !! Enlightenment Leader Skill !! Origin !! Source' end

function p.unitListOutput(unitList, mode) if mode == nil then mode = 'default' end local sb = {}

table.insert(sb, '{| class="wikitable sortable frozen-header"') table.insert(sb, ' |-') table.insert(sb, p.unitListHeader(mode)) local unitRows = {} for iname, unit in pairs(unitList) do       table.insert(unitRows, p.unitListItem(unit, mode)) end table.sort(unitRows, function(a, b) return a.name < b.name end)

for i, row in ipairs(unitRows) do       table.insert(sb, row.output) end table.insert(sb, "|}") return table.concat(sb, "\n") end

function p._unitListByElement(elemId) -- If the element is provided is not numeric we need to convert it   if tonumber(elemId) == nil then elemId = enums.elemFromName(elemId) or 0 end local unitList = cargo.query{ tables = "Unit", fields = baseUnitFields, where = { baseUnitQuery, 'elem = "'..elemId..'"', },   	limit = maxUnits, } or {}

return p.unitListOutput(unitList) end

function p._unitListByOrigin(birthId) -- If the element is provided is not numeric we need to convert it   if tonumber(birthId) == nil then birthId = enums.originKeyFromName(birthId) or 0 end local whereBirth if birthId and birthId > 0 then whereBirth = 'birth_id = ' .. birthId else whereBirth = 'birth_id IS NULL or birth_id < 1 or birth_id > 11' end

local unitList = cargo.query{ tables = "Unit", fields = baseUnitFields, where = { baseUnitQuery, whereBirth, },   	limit = maxUnits, } or {}

return p.unitListOutput(unitList) end

function p._unitListBySource(source) local unitKeys = {} source = source:lower for iname, unitData in pairs(unitExtra) do       if unitData['source'] and unitData['source']:lower:find(source) then unitKeys[#unitKeys+1] = iname end end

local unitList = cargo.query{ tables = "Unit", fields = baseUnitFields, where = { baseUnitQuery, 'iname IN ('..table.concat(unitKeys, ','):gsub('[^,]+', quote)..')', },   	limit = maxUnits, } or {} return p.unitListOutput(unitList) end

function p._unitListByGroup(groupKey) if groupKey then unitGroup = mw.ext.cargo.query('UnitGroup','units',{where='iname="'..groupKey..'"'})[1] or nil end if unitGroup == nil or unitGroup.units == nil then return '' end -- Exclude Lil'Ouro as these are generally memento groups local unitList = cargo.query{ tables = "Unit", fields = baseUnitFields, where = { baseUnitQuery, 'iname IN ('..unitGroup.units:gsub('[^,]+', quote)..') AND iname != "UN_V2_L_UROB"', },       limit = maxUnits, } or {} return p.unitListOutput(unitList) end

function p._unitListByIname(unitKeys, mode) local t = {} for i, v in ipairs(unitKeys) do   	v = mw.text.trim(v) if v ~= '' then t[#t+1] = quote(v) end end unitKeys = t   if #unitKeys == 0 then return '' end local unitList = cargo.query{ tables = "Unit", fields = baseUnitFields, where = { baseUnitQuery, 'iname IN ('..table.concat(unitKeys, ',')..')', },		limit = maxUnits, } or {} return p.unitListOutput(unitList, mode) end

function p.unitLeaderList local unitList = cargo.query{ tables = "Unit", fields = baseUnitFields, where = baseUnitQuery, limit = maxUnits, } or {}

return p.unitListOutput(unitList, 'leader') end

function p.unitList(frame) local args = require('Module:Arguments').getArgs(frame, {       parentFirst = true,    }) local methodTypes = { ['Element'] = '_unitListByElement', ['Origin'] = '_unitListByOrigin', ['Source'] = '_unitListBySource', ['Group'] = '_unitListByGroup', }   if args[1] and methodTypes[args[1]] then local methodType = methodTypes[args[1]] local method = p[methodType] return method(args[2] or nil) else return 'Invalid request' end end

function p.unitListByIname(frame) local args = require('Module:Arguments').getArgs(frame, {       parentFirst = true,    }) if args[1] and args[2] then local mode = args[1] local unitKeys = mw.text.split(args[2] or '', '%s*,%s*')

return p._unitListByIname(unitKeys, mode) else return 'Invalid request' end end

function p.test local keys = mw.text.split("UN_V2_VARGAS, UN_V2_SELENA, UN_V2_BF_LUNA", ',') -- mw.log(p._unitListByIname(keys, 'collab')) -- mw.log(p.unitList{'Element', 'Water'}) mw.log(p._unitListByGroup('UG_ALBELL_WILHELM')) end

return p