Module:Chem box
From Space Station 14 Wiki
Module documentation
|
---|
View or edit this documentation • (about module documentation) |
Uses JSON data
This module uses JSON data pages:
Implements {{chem box}}.
local p = {} --p stands for package
local getArgs = require("Module:Arguments").getArgs
local yesNo = require("Module:Yesno")
local chem_data = mw.loadJsonData("Module:Chem box/chem data.json")
local current_frame = mw.getCurrentFrame()
-- ====================
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
-- Makes the first letter uppercase.
-- Source: https://stackoverflow.com/a/2421746
local function capitalize(str)
return (str:gsub("^%l", string.upper))
end
local function passthrough_assert_true(value, valueToReturnIfTrue, errorMessageOnFalse)
if value then
return valueToReturnIfTrue
else
error(errorMessageOnFalse)
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
-- table concat function because ofcourse fucking table.concat doesn't work
local function concat_numberic_table(tbl, sep)
local temp_table = {}
for i = 1, numeric_table_length(tbl) do
table.insert(temp_table, tbl[i])
end
return table.concat(temp_table, sep)
end
local function ternary_strict(valueToCheck, valueIfTrue, valueIfFalse)
if valueToCheck == true then
return valueIfTrue
else
return valueIfFalse
end
end
-- ====================
-- Lookups reagent by ID or name.
--
-- Raises an error if no reagent was found.
-- Set `no_error` to `true` to return `nil` instead.
function p.lookup_reagent(query, no_error)
local query_lower = string.lower(query)
for _, reagent in ipairs(chem_data) do
assert_value_not_nil(reagent.id)
assert_value_not_nil(reagent.name)
if reagent.id == query then
return reagent
end
if string.lower(reagent.name) == query_lower then
return reagent
end
end
return passthrough_assert_true(no_error, nil, "failed to lookup reagent: no match was found")
end
-- ====================
function p.generate_chem_box(frame)
local args = getArgs(frame)
local query = args[1]
assert_value_not_nil(query, "failed to generate chem box: query was not provided")
-- ===================
local reagent = p.lookup_reagent(query)
assert_value_not_nil(reagent.color)
assert_value_not_nil(reagent.name)
assert_value_not_nil(reagent.recipes)
assert_value_not_nil(reagent.effects)
assert_value_not_nil(reagent.desc)
assert_value_not_nil(reagent.physicalDesc)
assert_value_not_nil(reagent.textColorTheme)
local recipes_container_el = mw.html.create("div")
if numeric_table_length(reagent.recipes) == 0 then
local no_recipes_text_el = mw.html.create("span"):css("color", "gray"):node("No recipes")
recipes_container_el:node(no_recipes_text_el)
else
for _, recipe in ipairs(reagent.recipes) do
assert_value_not_nil(recipe.id)
assert_value_not_nil(recipe.reactants)
assert_value_not_nil(recipe.products)
local recipe_box_template_args = {}
recipe_box_template_args.name = recipe.id
-- a list of catalist reactants.
-- contains "id" and "amount"
local catalyst_reactants = {}
for reactant_i, reactant in ipairs(recipe.reactants) do
local reactant_id = reactant[1]
local reactant_amount = reactant[2]
local reactant_is_catalyst = reactant[3] or false
local label = reactant_id
if reactant_is_catalyst then
table.insert(catalyst_reactants, {
id = reactant_id,
amount = reactant_amount,
})
end
local component_el = current_frame:expandTemplate({
title = "Recipe Component",
args = {
item = label,
amount = reactant_amount,
-- TODO
-- image = ""
},
})
recipe_box_template_args["component-" .. reactant_i] = component_el
end
local temperature_args = {}
if recipe.minTemp ~= nil or recipe.maxTemp ~= nil then
local temperature_string = ""
if recipe.minTemp ~= nil then
temperature_string = tostring(recipe.minTemp) .. "k "
end
temperature_string = temperature_string .. "<"
if recipe.maxTemp ~= nil then
temperature_string = temperature_string .. " " .. tostring(recipe.maxTemp) .. "k"
end
temperature_args = {temperature = temperature_string}
end
local required_mixer = "Beaker"
if recipe.requiredMixerCategories ~= nil then
required_mixer = recipe.requiredMixerCategories[1]
end
recipe_box_template_args.transformer = current_frame:expandTemplate({
title = required_mixer,
args = temperature_args
})
for product_i, product in ipairs(recipe.products) do
local component_el = current_frame:expandTemplate({
title = "Recipe Component",
args = {
item = product[1],
amount = product[2],
-- TODO
-- image = ""
},
})
recipe_box_template_args["result-" .. product_i] = component_el
end
-- add catalysts as products, if any
for catalyst_product_i, catalyst_product_entry in ipairs(catalyst_reactants) do
local product_id = catalyst_product_entry.id
local product_amount = catalyst_product_entry.amount
local label = current_frame:expandTemplate({
title = "Tooltip",
args = {
'<sup class="quickbox-catalyst-note">+</sup>',
'<span class="quickbox-catalyst-note-tooltip">This product is a catalyst reactant, remaining after the reaction.</span>',
},
}) .. product_id
local component_el = current_frame:expandTemplate({
title = "Recipe Component",
args = {
item = label,
amount = product_amount,
-- TODO
-- image = ""
},
})
local index = numeric_table_length(recipe.products) + catalyst_product_i
recipe_box_template_args["result-" .. index] = component_el
end
local recipes_el = current_frame:expandTemplate({
title = "Recipe Box",
args = recipe_box_template_args,
})
recipes_container_el:node(recipes_el)
end
end
local effects = concat_numberic_table(reagent.effects, "")
local text_color = ternary_strict(
reagent.textColorTheme == "light",
"var(--quickbox-header-text-theme-light)",
"var(--quickbox-header-text-theme-dark)"
)
return current_frame:expandTemplate({
title = "Manual Chem Box",
args = {
id = reagent.id,
color = reagent.color,
textcolor = text_color,
name = capitalize(reagent.name),
recipes = tostring(recipes_container_el:allDone()),
metabolisms = effects,
desc = reagent.desc,
physicalDesc = reagent.physicalDesc,
},
})
end
function p.generate_chem_boxes_for_all_reagents()
local container_el = mw.html.create("div"):addClass("reagents-list")
for _, reagent in ipairs(chem_data) do
assert_value_not_nil(reagent.id)
container_el:node(p.generate_chem_box({
reagent.id,
}))
end
return container_el:allDone()
end
function p.generate_chem_boxes_for_group(frame)
local args = getArgs(frame)
local query = args[1]
assert_value_not_nil(query)
query = string.lower(query)
local container_el = mw.html.create("div"):addClass("reagents-list")
for _, reagent in ipairs(chem_data) do
assert_value_not_nil(reagent.id)
assert_value_not_nil(reagent.group)
if string.lower(reagent.group) == query then
container_el:node(p.generate_chem_box({
reagent.id,
}))
end
end
return container_el:allDone()
end
return p