Module:Research
From Space Station 14 Wiki
Documentation for this module may be created at Module:Research/doc
local p = {} --p stands for package
local getArgs = require('Module:Arguments').getArgs
local itemModule = require('Module:Item')
local yesNo = require('Module:Yesno')
local techs_by_tech_ids_by_discipline_ids = mw.loadJsonData("Module:Research/techs by tech IDs by discipline IDs.json")
local disciplines_by_discipline_ids = mw.loadJsonData("Module:Research/disciplines by discipline IDs.json")
local current_frame = mw:getCurrentFrame()
local was_template_styles_tag_el_added = false
-- ====================
local function numeric_table_length(t)
local count = 0
for _ in ipairs(t) do count = count + 1 end
return count
end
local function table_length(t)
local count = 0
for _ in pairs(t) do count = count + 1 end
return count
end
local function table_has_value(tab, val)
for _, value in ipairs(tab) do
if value == val then
return true
end
end
return false
end
local function assert_value_not_nil(value, error_message)
if value == nil then
if error_message == nil then
error("value is nil")
else
error(error_message)
end
end
end
-- Given a value, checks if it's "nil".
-- * If it's not - returns the `value`.
-- * IF it is - returns the `value_if_nil`.
local function nil_or(value, value_if_nil)
if value == nil then
return value_if_nil
else
return value
end
end
local function find_first_numeric_table_item_matching_condition(table, condition)
for i, item in ipairs(table) do
if condition(item, i, table) then
return item
end
end
end
local function find_first_table_item_matching_condition(table, condition)
for key, value in pairs(table) do
if condition(key, value, table) then
return value
end
end
end
local function find_first_table_item_key_matching_condition(table, condition)
for key, value in pairs(table) do
if condition(key, value, table) then
return key
end
end
end
-- ====================
-- Checks whether there's a research by name or ID.
-- Name can be in any casing, but if using ID - the casing must match exactly.
function p.research_exists_by_name_or_id(research_name_or_id)
return p.try_lookup_research(research_name_or_id) ~= nil
end
-- Lookups research by name or ID.
-- Name can be in any casing, but if using ID - the casing must match exactly.
--
-- Returns a table containg `discipline_id`, `research_id` and `research`.
-- If no reserach was found, returns `nil`.
function p.try_lookup_research(research_name_or_id)
local lowercase_research_name_or_id = string.lower(research_name_or_id)
for discipline_id, researches_by_id in pairs(techs_by_tech_ids_by_discipline_ids) do
for research_id, research in pairs(researches_by_id) do
assert_value_not_nil(research.name, "failed to lookup a research: research by ID '" .. research_id .."' doesn't have a 'name' defined")
if(research_id == research_name_or_id or string.lower(research.name) == lowercase_research_name_or_id) then
return {
discipline_id = discipline_id,
research_id = research_id,
research = research
}
end
end
end
end
-- Lookups research by name or ID.
-- Name can be in any casing, but if using ID - the casing must match exactly.
--
-- Returns a table containg `discipline_id`, `research_id` and `research`.
-- If no reserach was found, raises an error.
function p.lookup_research(research_name_or_id)
local result = p.try_lookup_research(research_name_or_id)
if result == nil then
error("failed to lookup a research: research with name/ID '" .. research_name_or_id .. "' was not found");
else
return result
end
end
-- ====================
function p.generate_card(frame)
local args = getArgs(frame)
local research_query = args[1]
assert_value_not_nil(research_query, "failed to generate a research card: research name was not provided")
-- =======================
local research_lookup_result = p.try_lookup_research(research_query)
if research_lookup_result == nil then
error("failed to generate a research card: no research was found found by name/ID: " + research_query)
end
-- todo move asserts out?
assert_value_not_nil(research_lookup_result.research.name)
assert_value_not_nil(research_lookup_result.research.tier)
assert_value_not_nil(research_lookup_result.research.cost)
assert_value_not_nil(research_lookup_result.research.recipeUnlocks)
-- ======================
local research_card_el = mw.html.create("div")
:addClass("research-card")
if not was_template_styles_tag_el_added then
research_card_el:node(current_frame:extensionTag("templatestyles", "", { src = 'Template:Research/styles.css' }))
was_template_styles_tag_el_added = true
end
-- todo
local icon_el = itemModule.generate_item{ "PlushieLizard", label = "", size = "84px", link = '' }
:addClass("research-card-icon")
research_card_el:node(icon_el)
local header_el = mw.html.create("div")
:addClass("research-card-header")
research_card_el:node(header_el)
local header_text_el = mw.html.create("span")
:addClass("research-card-header-text")
:node(research_lookup_result.research.name)
header_el:node(header_text_el)
-- discipline icon el
-- todo replace with icon
header_el:node(
itemModule.generate_item{ "PlushieLizard", label = "", size = "24px", link = '' }
:addClass("research-card-header-discipline-icon")
)
-- todo color
-- todo replace discipline ID with name
local tier_and_discipline_text_el = mw.html.create("span")
:addClass("research-card-header-tier-and-discipline")
:node("Tier " .. research_lookup_result.research.tier .. ", ")
:node(
mw.html.create("span")
:css("color", "white")
:node(research_lookup_result.discipline_id)
)
header_el:node(tier_and_discipline_text_el)
local body_el = mw.html.create("div")
:addClass("research-card-body")
research_card_el:node(body_el)
-- todo cost color
local cost_el = mw.html.create("span")
:addClass("research-card-body-cost")
:node("Cost: " .. research_lookup_result.research.cost)
body_el:node(cost_el)
-- unlocks label el
body_el:node("Unlocks:")
local unlocks_el = mw.html.create("ul")
:addClass("research-card-body-unlocks")
-- todo recipe names
-- todo expanding recipe names to recipes. maybe a tooltip?
for _, recipe_id in ipairs(research_lookup_result.research.recipeUnlocks) do
unlocks_el:node(
mw.html.create("li")
:addClass("research-card-body-unlocks-unlock")
:node(recipe_id)
)
end
body_el:node(unlocks_el)
return research_card_el
:allDone()
end
return p