Missions stores the Star Chart's node data.
On this Wiki, Missions is used in:
Usage
Direct Invocation
{{#invoke:Missions|function|input1|input2|...}}
Template
In template: {{#invoke:Missions|function|input1|input2|...}}
In articles: {{template|function|input1|input2|...}}
Module
local Mission = require('Module:Missions')
local function func(frame)
return Mission.getMissions(frame)
end
Product Backlog
- Add documentation 19:28, 3 July 2021 (UTC)
Documentation
Package items
missions.__listVars()(function)- Debug function to list out variables/keys used in
/data - Returns: String list of keys (string)
missions.getMissionTable(frame)(function)- Builds wikitable of missions based on their node names.
{{#invoke:Missions|getMissionTable|missionname1|missionname2|...}} - Parameter:
frameFrame object with names of mission nodes as arguments (table) - Returns: Resultant wikitext of wikitable (string)
missions.auto(frame)(function)- Display certain types of missions in a wikitable format based on argument passed
{{#invoke:Missions|auto|Val}}(e. g.{{#invoke:Missions|auto|Venus}}for list of Venus nodes or{{#invoke:Missions|auto|Survival}}for list of Survival nodes) - Parameter:
frameFrame object (table) - Returns: Resultant wikitext of wikitable (string)
missions.Select(frame)(function)- Returns a wikitable with mission nodes fitting multiple search criteria.
{{#invoke:Missions|Select|Var=Val|Var2=Val2|expanded=yes|partmatch=yes}}(e.g.{{#invoke:Missions|Select|Type=Survival|Planet=Venus}}returns wikitable of Survival mission nodes on Venus) - Parameter:
frameFrame object with named arguments representing key names of entries in/data(table) - Returns: Resultant wikitext of wikitable (string)
- Created with Docbunto
See Also
Code
--- '''Missions''' stores the [[Star Chart]]'s node data.<br />
--
-- On this Wiki, Missions is used in:
-- * [[Template:MissionTable]]
--
-- @module missions
-- @alias p
-- @author [[User:Falterfire|Falterfire]] (original)
-- @author [[User:Gigamicro|Gigamicro]] (rework/refactor)
-- @attribution [[User:Flaicher|Flaicher]]
-- @attribution [[User:Croquemorttime|Croquemorttime]]
-- @attribution [[User:Cephalon Scientia|Cephalon Scientia]]
-- @attribution [[User:FINNER|FINNER]]
-- @image StarChartU29afterHeartOfDeimosWithPath.jpg
-- @require [[Module:Missions/data]]
-- @require [[Module:Table]]
-- @require [[Module:Math]]
-- @release stable
-- <nowiki>
--By [[User:Giga Martin|Giga Martin]] ([[User talk:Giga Martin|talk]]) at 23:59, September 16, 2020 (UTC)
--Use:
-- {{#invoke:Missions|getMissions|missionname1|missionname2|...}} (e.g. {{#i:M|getMissions|Tessera|Oro}} )
-- {{#i:M|Var|Val}} (e.g. {{#i:M|Planet|Venus|expanded=yes}} )
-- {{#i:M||Val}} (e.g. {{#i:M||Venus|expanded=yes}} )
-- {{#i:M|Select|Var=Val|Var2=Val2|expanded=yes|partmatch=yes}} (e.g. {{#i:M|Select|Planet=Venus|Type=Capture|expanded=yes}} )
-- possible variables (case sensitive):
-- p.__listVars() or {{#invoke:Missions|listVars}}
local p = {}
local MissionData = mw.loadData( [[Module:Missions/data]] )
local Table = require( [[Module:Table]] )
local Math = require( [[Module:Math]] )
local function linkType(missionType)
assert(MissionData["MissionTypes"][missionType] ~= nil,
'linkType(missionType): missionType "'..missionType..'" is missing from [[Module:Missions/data]]')
return '[['..MissionData["MissionTypes"][missionType].Link..']]'
end
local function getMissions(compareFunction)
local data = {}
for i, m in ipairs(MissionData["MissionDetails"]) do
if(compareFunction(m)) then
table.insert(data, m)
end
end
return data
end
--- Debug function to list out variables/keys used in <code>/data</code>
-- @function p.__listVars
-- @return {string} String list of keys
function p.__listVars()
local result = {}
for i, v in ipairs(MissionData.vars) do table.insert(result, v) end
return table.concat(result, '\n')
end
--- Display missions in a wikitable format.
-- @function Missions
-- @param {table} data Table from <code>/data</code>
-- @param {table} Header Table with mixed table entries containing wikitable
-- column name and a cell function that formats the contents of column cells
-- @param {string} suffix Footnote to append below wikitable
-- @return {string} Resultant wikitext of wikitable
local function Missions(data, Header, suffix)
if not data then error ("bad argument #1 to 'Missions' (table expected, got "..type(data)..")", 2) end
local tHeader = '{| border="0" cellpadding="0" cellspacing="0" class="wikitable sortable" style="margin:auto;"\n|-'
Header = Header or {
{'Planet', cell = function(this, mission)
return '[['..mission.Planet..']]'
end},
{'Mission Name', cell = function(this, mission)
return "[["..mission.Link.."|"..mission.Name.."]]"
end},
{'Type', cell = function(this, mission)
return linkType(mission.Type)..(mission.IsDarkSector and " ([[Dark Sector]])" or '')
end},
{'Faction', cell = function(this, mission)
local enemyTemp = {}
for _, enemy in ipairs(type(mission.Enemy) == 'table' and mission.Enemy or {mission.Enemy}) do
table.insert(enemyTemp, '[['..enemy..']]')
end
return table.concat(enemyTemp, '/')
end},
{' data-sort-type="number"|Level', cell = function(this, mission)
return mission.MinLevel..' - '..mission.MaxLevel
end},
{' data-sort-type="number"|Mastery EXP', cell = function(this, mission)
return mission.MasteryExp
end},
}
for i, v in pairs(Header) do
tHeader = tHeader..'\n!'..v[1]
end
local tBody = ''
for i, mission in ipairs(data) do
tBody = tBody..'\n|-\n'
for ii, obj in ipairs(Header) do
tBody = tBody..'|'..obj:cell(mission)..(#Header > ii and '|' or '')
end
end
return tHeader..tBody..(suffix or '').."\n|}"
end
--- Display few missions in a wikitable format.
-- @function Missions
-- @param {table} data Table from <code>/data</code>
-- @param {table} Header Table with mixed table entries containing
-- {string} wikitable column width as a percentage, {string} column name,
-- and a {function} cell function that formats the contents of column cells
-- @param {string, table} properties Contains the names of wikitable properties mapped to a value
-- @return {string} Resultant wikitext of wikitable
local function FewMissions(data, Header, properties)
if type(data) ~= 'table' then error ("bad argument #1 to 'FewMissions()' (table expected, got "..type(data)..")", 2) end
if type(properties) ~= 'table' then properties = { properties } end
-- Get the value of the wikitable property as passed in by properties argument
-- or fallback to a default value when calling properties(prop, default)
setmetatable(properties, { __call = function(self, prop, default) return properties[prop] or default end })
local tHeader = {
'{| class="sortable" style="max-width: ',
properties('max-width', '700px'),
'; margin:auto; width: 100%; text-align: center; font-size: 11px;" cellpadding="',
properties('cellpadding', '3'),
'" cellspacing="',
properties('cellspacing', '2'),
'" |-'
}
local Header = Header or {
{'15', 'Target', cell = function(this, mission)
if(mission.FactionImage) then
return '\n| style="font-size:12px; border:1px solid black;"|['..'[File:'..(mission.FactionImage or mission.Pic)..'|link='..(mission.Boss or (type(mission.Enemy)=='table' and 'Crossfire' or mission.Enemy))..'|class=dark-invert|x64px]]'
else
return '\n| style="font-size:12px; border:1px solid black;"|['..'[File:Panel.png|64px]]'
end
end},
{'20', 'Planet', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|['..'['..mission.Planet..']]'
end},
{'15', 'Name', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|['..'['..mission.Link..'|'..mission.Name..']]'
end},
{'15', 'Type', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..linkType(mission.Type)..(mission.IsDarkSector and " ([[Dark Sector]])" or '')
end},
{'15', 'Level', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..mission.MinLevel..' - '..mission.MaxLevel
end},
{'20', 'Tile Set', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|['..'['..mission.Tileset..']]'
end},
}
for i, v in ipairs(Header) do
table.insert(tHeader,'\n! style="width:'..v[1]..'%; background-color:#585858; font-size:12px; color:#FFFFFF;" | '..v[2])
end
local tBody = ''
for i, mission in ipairs(data) do
tBody = tBody..'\n|-'
for ii, h in ipairs(Header) do tBody = tBody..h:cell(mission) end
end
return table.concat(tHeader)..tBody..'\n|}'
end
--- Builds wikitable of missions based on their node names.
-- `{{#invoke:Missions|getMissionTable|missionname1|missionname2|...}}`
-- @function p.getMissionTable
-- @param {table} frame Frame object with names of mission nodes as arguments
-- @return {string} Resultant wikitext of wikitable
function p.getMissionTable(frame)
local data = {}
frame = frame:getParent() or frame
for i, missionName in ipairs(frame.args or frame) do
if (missionName ~= '') then
table.insert(data, MissionData.by.Name[missionName][1])
end
end
return FewMissions(data, nil, { ['max-width'] = '400px', ['cellpadding'] = '1' })
end
--- Sorts out missions for general call.
-- @function MissionsBy
-- @param {string} B key name of table entries as seen in <code>/data</code>
-- @param {any} M value of key name
-- @return {string} Resultant wikitext of wikitable
local function MissionsBy(B, M)
M = M or (( { IsArchwing = true, IsDarkSector = true, IsCrossfire = true } )[B])--val
-- TODO: Refactor so code is more human-readable
return Missions(MissionData.by[B][M], ({
--put custom tables here
Type = {
{'Planet', cell = function(this, mission)
return '[['..mission.Planet..']]'
end},
{'Mission Name', cell = function(this, mission)
return "[["..mission.Link.."|"..mission.Name.."]]"..(mission.IsDarkSector and " ([[Dark Sector]])" or '')
end},
{'Faction', cell = function(this, mission)
local enemyTemp = {}
for _, enemy in ipairs(type(mission.Enemy) == 'table' and mission.Enemy or {mission.Enemy}) do
table.insert(enemyTemp, '[['..enemy..']]')
end
return table.concat(enemyTemp, '/')
end},
{'[[Credit Reward]]', cell = function(this, mission)
return mission.CreditReward and Math.formatnum(mission.CreditReward) or 0
end},
{'Addtional Credit Reward', cell = function(this, mission)
return mission.AdditionalCreditReward and Math.formatnum(mission.AdditionalCreditReward) or 0
end},
{'Wiki\'s [[Module:DropTables/data|DropTableAlias]]', cell = function(this, mission)
return '<code>'..(mission.DropTableAlias or '')..'</code>' or mission.Type
end},
{'data-sort-type="number"|Level', cell = function(this, mission)
return mission.MinLevel..' - '..mission.MaxLevel
end},
{'Tileset', cell = function(this, mission)
return '[['..mission.Tileset..']]'
end},
},
IsDarkSector = {
{'Planet', cell = function(this, mission)
return '[['..mission.Planet..']]'
end},
{'Mission Name', cell = function(this, mission)
return "[["..mission.Link.."|"..mission.Name.."]]"
end},
{'Type', cell = function(this, mission)
return linkType(mission.Type)
end},
{'data-sort-type="number"|[[Credit Reward]]', cell = function(this, mission)
return Math.formatnum(mission.CreditReward)
end},
{'data-sort-type="number"|Additional Credit Reward', cell = function(this, mission)
return Math.formatnum(mission.AdditionalCreditReward)
end},
{'data-sort-type="number"|Level', cell = function(this, mission)
return mission.MinLevel..' - '..mission.MaxLevel
end},
{'data-sort-type="number"|Resource Drop Chance Bonus', cell = function(this, mission)
return Math.percentage(mission.DSResourceBonus)
end},
{'data-sort-type="number"|Affinity Bonus', cell = function(this, mission)
return Math.percentage(mission.DSXPBonus)
end},
{'data-sort-type="number"|Weapon Affinity Bonus', cell = function(this, mission)
return Math.percentage(mission.DSWeaponBonus)..' on '..mission.DSWeapon
end},
}
})[B], "\n|+There are a total of "..Table.size(MissionData.by[B][M])..(({
--['Node'] = M.." Missions.",--name
--['Boss'] = M.." Missions.",
--['Pic'] = M.." Missions.",--single match
['IsArchwing'] = " [[Archwing]] Missions.",
['IsDarkSector'] = " [[Dark Sector]] Missions.",
['IsCrossfire'] = " [[Crossfire]] Missions.",--assume true
['FighterMaxLevel'] = (' max level %s Missions.'):format(tostring(M)),
['MaxLevel' ] = (' max level %s Missions.'):format(tostring(M)),
['FighterMinLevel'] = (' min level %s Missions.'):format(tostring(M)),
['MinLevel'] = (' min level %s Missions.'):format(tostring(M)),--unlikely but whatever
['Enemy'] = (' Missions against the %s'):format(tostring(M)),
['Tier'] = (' %s-tier Missions'):format(tostring(M)),
['Planet'] = (' Missions on %s'):format(tostring(M)),
['Tileset'] = (' Missions on the %s Tile Set'):format(tostring(M)),
['Type'] = (' %s Missions'):format(tostring(M)),
['Drops'] = (' Missions that drop %s'):format(tostring(M)),
['MasteryExp'] = (' Missions worth %s xp'):format(tostring(M))
--['DSWeapon'] = M.." Missions.",
--['DSResourceBonus'] = M.." Missions.",
--['DSXPBonus'] = M.." Missions.",
--['DSWeaponBonus'] = M.." Missions.",--unlikely to be used (numbers)
--['Other'] = M.." Missions.",--name of map variants (letters, letter/letter/letter)
})[B] or ' '..M..' '..B..' Missions')
)
end
--- Sorts out missions for general call.
-- @function MissionsBy
-- @param {string} B key name of table entries as seen in <code>/data</code>
-- @param {any} M value of key name
-- @return {string} Resultant wikitext of wikitable
local function FewMissionsBy(B, M)
M = M or (( { IsArchwing = true, IsDarkSector = true, IsCrossfire = true } )[B])--val
local Header = ({
--column { width%, title, cell constructor }
Planet = {
{'15', 'Target', cell = function(this, mission)
if (mission.FactionImage) then
return '\n| style="font-size:12px; border:1px solid black;"|['..'[File:'..(mission.FactionImage or mission.Pic)..'|link='..(mission.Boss or (type(mission.Enemy) == 'table' and 'Crossfire' or mission.Enemy))..'|class=dark-invert|x64px]'..']'
else
return '\n| style="font-size:12px; border:1px solid black;"|['..'[File:Panel.png|64px]'..']'
end
end},
{'20', 'Name', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|['..'['..mission.Link..'|'..mission.Name..']]'
end},
{'20', 'Type', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..linkType(mission.Type)..(mission.IsDarkSector and " ([[Dark Sector]])" or '')
end},
{'20', 'Level', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..mission.MinLevel..' - '..mission.MaxLevel
end},
{'15', '[[Credit Reward]]', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..(mission.CreditReward and Math.formatnum(mission.CreditReward) or 0)
end},
{'15', 'Additional Credit Reward', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..(mission.AdditionalCreditReward and Math.formatnum(mission.AdditionalCreditReward) or 0)
end},
{'25', '[[Tile Set]]', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|['..'['..mission.Tileset..']]'
end},
{'5', 'Mastery EXP', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..mission.MasteryExp
end},
{'20', 'Internal Name', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"| <code>'..mission.InternalName..'</code>'
end},
{'5', 'Hidden Node', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"| '..(mission.IsHidden and '✔️' or '❌')
end},
},
Tileset = {
{'15', 'Target', cell = function(this, mission)
if (mission.FactionImage) then
return '\n| style="font-size:12px; border:1px solid black;"|['..'[File:'..(mission.FactionImage or mission.Pic)..'|link='..(mission.Boss or (type(mission.Enemy)=='table' and 'Crossfire' or mission.Enemy))..'|class=dark-invert|x64px]'..']'
else
return '\n| style="font-size:12px; border:1px solid black;"|['..'[File:Panel.png|64px]'..']'
end
end},
{'20', 'Planet', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|['..'['..mission.Planet..']]'
end},
{'20', 'Name', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|['..'['..mission.Link..'|'..mission.Name..']]'
end},
{'25', 'Type', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..linkType(mission.Type)..(mission.IsDarkSector and " ([[Dark Sector]])" or '')
end},
{'20', 'Level', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..mission.MinLevel..' - '..mission.MaxLevel
end},
{'15', '[[Credit Reward]]', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..(mission.CreditReward and Math.formatnum(mission.CreditReward) or 0)
end},
{'15', 'Additional Credit Reward', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..(mission.AdditionalCreditReward and Math.formatnum(mission.AdditionalCreditReward) or 0)
end},
},
Type = {
{'15', 'Target', cell = function(this, mission)
if (mission.FactionImage) then
return '\n| style="font-size:12px; border:1px solid black;"|['..'[File:'..(mission.FactionImage or mission.Pic)..'|link='..(mission.Boss or (type(mission.Enemy)=='table' and 'Crossfire' or mission.Enemy))..'|class=dark-invert|x64px]'..']'
else
return '\n| style="font-size:12px; border:1px solid black;"|['..'[File:Panel.png|64px]'..']'
end
end},
{'20', 'Planet', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|['..'['..mission.Planet..']]'
end},
{'20', 'Name', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|['..'['..mission.Link..'|'..mission.Name..']]'
end},
{'20', 'Level', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..mission.MinLevel..' - '..mission.MaxLevel
end},
{'15', '[[Credit Reward]]', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..(mission.CreditReward and Math.formatnum(mission.CreditReward) or 0)
end},
{'15', 'Additional Credit Reward', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..(mission.AdditionalCreditReward and Math.formatnum(mission.AdditionalCreditReward) or 0)
end},
{'25', 'Tile Set', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|['..'['..mission.Tileset..']]'
end},
},
})[B] or
{
{'15', 'Target', cell = function(this, mission)
if (mission.FactionImage) then
return '\n| style="font-size:12px; border:1px solid black;"|['..'[File:'..(mission.FactionImage or mission.Pic)..'|link='..(mission.Boss or (type(mission.Enemy)=='table' and 'Crossfire' or mission.Enemy))..'|class=dark-invert|x64px]'..']'
else
return '\n| style="font-size:12px; border:1px solid black;"|['..'[File:Panel.png|64px]'..']'
end
end},
{'15', 'Planet', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|['..'['..mission.Planet..']]'
end},
{'15', 'Name', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|['..'['..mission.Link..'|'..mission.Name..']]'
end},
{'15', 'Type', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..linkType(mission.Type)..(mission.IsDarkSector and " ([[Dark Sector]])" or '')
end},
{'15', 'Level', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..mission.MinLevel..' - '..mission.MaxLevel
end},
{'15', '[[Credit Reward]]', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..(mission.CreditReward and Math.formatnum(mission.CreditReward) or 0)
end},
{'15', 'Additional Credit Reward', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..(mission.AdditionalCreditReward and Math.formatnum(mission.AdditionalCreditReward) or 0)
end},
{'25', 'Tile Set', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|['..'['..mission.Tileset..']]'
end},
}--default
-- Adding additional columns for Empyrean missions
-- TODO: Can be converted into a map and use table access via index to check for nil entries
local proximaTable = {
'Earth Proxima', 'Saturn Proxima', 'Venus Proxima', 'Neptune Proxima', 'Pluto Proxima', 'Veil Proxima', 'Skirmish'
}
if Table.contains(proximaTable, M) then
local b = 0
for i, v in ipairs(Header) do
if v[2] == 'Level' then
b = i
break
end
end
table.insert(Header, b, {
'10', 'Fighter Level', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..mission.FighterMinLevel..' - '..mission.FighterMaxLevel
end})
--edit other section widths?
--Header[b-1][1]=Header[b-1][1]-0 ..''
Header[b + 1][1] = '10'--Header[b+1][1]-10 ..''
table.insert(Header, {
'5', 'Max Fighters', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..mission.MaxFighters
end})
table.insert(Header, {
'5', 'Max Crewships', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..mission.MaxCrewships
end})
table.insert(Header, {
'5', 'Other Objective', cell = function(this, mission)
return '\n| style="font-size:12px; border:1px solid black;"|'..mission.Objectives..(mission.ObjectiveDetails and ' ('..mission.ObjectiveDetails..')' or '')
end})
end--railjack
if Table.contains({ 'Assassination' }, M) then
local b = 0;
for i, v in ipairs(Header) do
if v[2] == 'Level' then
b = i + 1
break
end
b = i
end
table.insert(Header, b, {
'15', 'Rewards', cell = function(this, mission)
local numDrops = Table.size(mission.Drops)
local r = ''
for i, v in ipairs(mission.Drops)do
r = r..(numDrops == i and numDrops > 1 and '& ' or '')..'['..'['..v..']'..']'..(numDrops ~= i and numDrops > 2 and ', ' or ' ')
end
return '\n| style="font-size:12px; border:1px solid black;"|'..r
end})
--edit other section widths?
Header[b - 1][1] = Header[b - 1][1] - 0 ..''
Header[b + 1][1] = Header[b + 1][1] - 0 ..''
end--rewards
return FewMissions(MissionData.by[B][M], Header)
end
-- Each key in M:Missions/data will automatically have its own invokable function that calls
-- either FewMissionsBy(key, frame.args[1]) or MissionsBy(key, frame.args[1])
-- e.g. {{#invoke:Missions|Var|Val}}
for k in pairs(MissionData.by) do
p[k] = function(frame)
return (((frame.args['expanded']) and FewMissionsBy or MissionsBy))(k, frame.args[1])
end
end
--- Display certain types of missions in a wikitable format based on argument passed
-- `{{#invoke:Missions|auto|Val}}`
-- (e.g. `{{#invoke:Missions|auto|Venus}}` for list of Venus nodes or
-- `{{#invoke:Missions|auto|Survival}}` for list of Survival nodes)
-- @function p.auto
-- @param {table} frame Frame object
-- @return {string} Resultant wikitext of wikitable
function p.auto(frame)
return p[MissionData.dictionary[frame.args[1]]](frame)
--return (((frame.args['expanded']) and FewMissionsBy or MissionsBy))(MissionData.dictionary[frame.args[1]], frame.args[1])
end
--- Returns a wikitable with mission nodes fitting multiple search criteria.
-- `{{#invoke:Missions|Select|Var=Val|Var2=Val2|expanded=yes|partmatch=yes}}`
-- (e.g. `{{#invoke:Missions|Select|Type=Survival|Planet=Venus}}` returns wikitable of Survival mission nodes on Venus)
-- @function p.Select
-- @param {table} frame Frame object with named arguments representing key names of entries in <code>/data</code>
-- @return {string} Resultant wikitext of wikitable
function p.Select(frame)
local args = frame.args or frame
local expanded = args.expanded and args.expanded ~= '' and 'true' or 'false'
local partMatch = args.partmatch and args.partmatch ~= '' --and 'true' or 'false'
local merge = {}
pcall(function() local tableNames = {} end) -- TODO: Why is this wrapped around a pcall()?
--local gargs = {}
for k,v in pairs(args) do
if Table.contains(MissionData.vars, k) then
pcall(function() v = v + 0 end)
table.insert(merge, MissionData.by[k][v])
pcall(function() table.insert(tableNames, k) end)
--gargs[k]=v
end
end
-- TODO: Remove mw.log()s
--max loops: largest by-table if partmatch; smallest otherwise
--merge = {{mission,mission},{mission,mission}}
-- [[
local data = {}
do
--merge down
local i = #merge
mw.log(i, 'tables')
while i > 1 do
pcall(function() tableNames[i - 1] = tableNames[i]..' & '..tableNames[i - 1]
mw.log(tableNames[i - 1] or '')end)
merge[i - 1] = (function(a, b)
--merge a and b
local ai, bi = 1, 1
local r = {}
while a[ai] and b[bi] do
--same mission? add it, increment both
if a[ai] == b[bi] then
mw.log(ai, bi, 'match')--,a[ai].Id,b[bi].Id)
table.insert(r, a[ai])
ai, bi = ai + 1, bi + 1
else
--catch up earlier one
if a[ai].Id > b[bi].Id then
mw.log(ai, bi, 'b', a[ai].Id, b[bi].Id)
if partMatch then table.insert(r, b[bi]) end
bi=bi+1
else
mw.log(ai, bi, 'a', a[ai].Id, b[bi].Id)
if partMatch then table.insert(r, a[ai]) end
ai = ai + 1
end
end
end
if partMatch then
while a[ai] do
mw.log(ai, bi, 'a')
table.insert(r, a[ai])
ai = ai + 1
end
while b[bi] do
mw.log(ai, bi, 'b')
table.insert(r, b[bi])
bi = bi + 1
end
end
return r
end)(merge[i], merge[i - 1])
merge[i] = nil
i = i - 1
end
data = merge[1]
end
return (({['false'] = Missions, ['true'] = FewMissions})[expanded])(data)
end
return p