Module:ResearchCost
Jump to navigation
Jump to search
This module uses Extension:Cargo, an integral part of the wiki's back-end.
- This module queries the table "Research". View table.
This module allows for easy and quick lookup of one or all type(s) of Research costs. It looks up the costs based on the provided research tier number, and returns them in one of several formats.
The main function that it exposes is getCode
. It is invoked by Template:ResearchCost, which also describes its usage in greater detail. Alternatively, the comments in the module code describe its functionality.
It is generally recommended to use Template:ResearchCost instead of invoking this module directly.
local p = {}
local mergeArgs = require("Module:ProcessArgs").merge
-- List of costs by tier then by type, as the game defines them
local TECH_TIERS_BASE = {
{},
{ basic=15 },
{ basic=20 },
{ basic=30, advanced=20 },
{ basic=35, advanced=30 },
{ basic=40, advanced=50 },
{ basic=50, advanced=70 },
{ basic=70, advanced=100 },
{ basic=70, advanced=100, space=200 },
{ basic=70, advanced=100, space=400 },
{ basic=70, advanced=100, space=800 },
{ basic=70, advanced=100, space=1600 },
keys={'basic', 'advanced', 'space'}
}
local TECH_TIERS_SO = {
{},
{ basic=15 },
{ basic=20 },
{ basic=30, advanced=20 },
{ basic=35, advanced=30 },
{ basic=40, advanced=50, orbital=0, nuclear=20 },
{ basic=50, advanced=70, orbital=30, nuclear=40 },
{ basic=70, advanced=100, orbital=250, nuclear=370 },
{ basic=100, advanced=130, orbital=400, nuclear=435 },
{ basic=100, advanced=130, orbital=600 },
{ basic=100, advanced=130, orbital=800 },
{ basic=100, advanced=130, orbital=1600 },
keys={'basic', 'advanced', 'nuclear', 'orbital'}
}
-- Mapping of research type keys to display names
local ResearchTypes = {
basic = {
key='basic',
name='Novice Research',
shorthand='Novice',
barClass='research-novice',
image='File:Novice-Research.png'
},
advanced = {
key='advanced',
name='Advanced Research',
shorthand='Advanced',
barClass='research-intermediate',
image='File:Advanced Research.png'
},
space = {
key='space',
name='Interstellar Research',
shorthand='Interstellar',
barClass='research-interstellar',
image='File:Interstellar Research.png'
},
nuclear = {
key='nuclear',
name='Applied Sciences Research',
shorthand='Applied Sciences',
barClass='research-matscience',
image='File:Materials Science Research.png'
},
orbital = {
key='orbital',
name='Data Analysis Research',
shorthand='Data Analysis',
barClass='research-interstellar',
image='File:Orbital Research.png'
},
}
-- Helper function for determining if a given flag is set
-- in a function's arguments
local isFlagSet = function(flag)
if flag then
local word = tostring(flag)
return #word > 0 and tostring(flag) ~= 'false' and tostring(flag):sub(1, 1):lower() ~= 'n'
else
return false
end
end
local getTypeKey = function(arg)
for k,v in pairs(ResearchTypes) do
if string.lower(k) == string.lower(arg) or string.lower(v.shorthand) == string.lower(arg) then
return v.key
end
end
return nil
end
local getOneCost = function(frame, args, tier, type, format)
local size = nil
if args and args.size then
size = tonumber(args.size)
if not size or size <= 8 then size = nil end
end
size = size or 18
if not tier or not tier[type] or not ResearchTypes[type] then
return '0'
end
if format == 'value' then
return tier[type]
elseif format == 'map' then
return ResearchTypes[type].name .. '=' .. tier[type]
elseif format == 'bar' then
if tier[type] <= 0 then return '' end
local curName = ResearchTypes[type].name
return string.format('|-\n| class="research-bar %s" | %d || [[%s|%dx%dpx|%s|link=%s]]',
ResearchTypes[type].barClass,
tier[type],
ResearchTypes[type].image,
size,
size,
curName,
curName)
end
return ResearchTypes[type].name .. ': ' .. tier[type]
end
local getTotalCost = function(frame, args, isSO)
local firstArg = (args[2] and #args[2] > 0 and 2) or 1
local myType = getTypeKey(args[firstArg])
if not myType then return '' end
local fieldOne = (isSO and 'IF(tierSO IS NULL, tier, tierSO)=myTier') or 'tier=myTier'
local whereOne = (isSO and "contentSO='1'") or "contentBase='1'"
local queryResult = mw.ext.cargo.query('Research',
fieldOne..",count(*)=count",
{
where = whereOne,
groupBy = "myTier",
orderBy = "myTier asc"
}
)
if #queryResult < 1 then return 0 end
local total = 0
local myTiers = {TECH_TIERS_BASE, TECH_TIERS_SO}
myTiers = myTiers[(isSO and 2) or 1]
for i,v in ipairs(queryResult) do
local t = tonumber(v.myTier)+1
if myTiers[t] and myTiers[t][myType] then
total = total + v.count * myTiers[t][myType]
end
end
return total
end
-- Arguments:
-- [1] - the research tier #
-- [2] - (optional) the research type to look up, by shorthand (e.g. "applied
-- sciences") or by key (e.g. "nuclear"), case-insensitive
-- ['SO' or 'so'] - set to falsy (0, false, 'no', 'N') for base game, else Spaced Out!
-- ['format'] - format to return the results in (inly if args[2] is not specified).
--
-- See the documentation for Template:ResearchCost for more details.
function p.getCost(frame)
local args = frame
if frame == mw.getCurrentFrame() then
args = mergeArgs(true)
else
frame = mw.getCurrentFrame()
end
local isSO = isFlagSet(args.so or args.SO or false)
local dlc = (isSO and 2) or 1
local format = string.lower(args.format or 'default')
local result = ''
local delim = '\n'
local subfmt = format
local skipMissing = true
if format == 'list' then
delim = ','
subfmt = 'value'
skipMissing = false
dlc = 'both'
elseif format == 'map' then
delim = ','
elseif format == 'total' then
return getTotalCost(frame, args, isSO)
elseif format == 'value' then
return ''
end
local allTiers = {TECH_TIERS_BASE, TECH_TIERS_SO}
for i,tiers in ipairs(allTiers) do
if dlc == 'both' or dlc == i then
local tierNum = (args[1] and tonumber(args[1])) or -1
if not tierNum or tierNum < 0 or tierNum >= #tiers then
return ''
end
local myTier = tiers[tierNum+1]
if args[2] then
local myType = getTypeKey(args[2])
if not myType then return '' end
return getOneCost(frame, args, myTier, myType, 'value')
end
local typeKeys = tiers.keys
for _,type in ipairs(typeKeys) do
if (myTier[type] and myTier[type] > 0) or not skipMissing then
if #result > 0 then
result = result .. delim
end
result = result .. getOneCost(frame, args, myTier, type, subfmt)
end
end
end
end
return result
end
return p