Module:Chemistry
From Space Station 14 Wiki
Module documentation
|
---|
View or edit this documentation • (about module documentation) |
local p = {} --p stands for package
local getArgs = require("Module:Arguments").getArgs
local yesNo = require("Module:Yesno")
-- local reagents_table = mw.loadJsonData("Module:Chemistry/data/auto/reagents.json");
-- local reactions_table = mw.loadJsonData("Module:Chemistry/data/auto/reactions.json");
-- ==============================
local function assert_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
local function starts_with(str, substr)
return string.sub(str, 1, string.len(substr)) == substr
end
local function ends_with(str, substr)
local substr_length = string.len(substr)
return string.sub(str, string.len(str) - substr_length + 1, string.len(str)) == substr
end
local function starts_with_insensitive(str, substr)
return starts_with(string.lower(str), string.lower(substr))
end
local function ends_with_insensitive(str, substr)
return ends_with(string.lower(str), string.lower(substr))
end
local function table_filter(tbl, filterFn)
local out = {}
for k, v in pairs(tbl) do
if filterFn(v, k, tbl) then out[k] = v end
end
return out
end
local function num_table_reduce(tbl, reduceFn, initial_value)
local out = initial_value
for i, v in ipairs(tbl) do
out = reduceFn(out, v, i, tbl)
end
return out
end
local function table_find(tbl, findFn)
for k, v in pairs(tbl) do
if findFn(v, k, tbl) then return v end
end
end
local function table_contains(tbl, findFn)
return table_find(tbl, findFn) ~= nil
end
local function table_contains_value(tbl, value)
return table_find(tbl, function(iter_value)
return iter_value == value
end) ~= nil
end
local function table_find_key(tbl, findFn)
for k, v in pairs(tbl) do
if findFn(v, k, tbl) then return k end
end
end
local function table_find_index(tbl, findFn)
for i, v in ipairs(tbl) do
if findFn(v, i, tbl) then return i end
end
end
local function table_map(tbl, mapFn)
local res = {}
for k, v in pairs(tbl) do
table.insert(res, mapFn(v, k, tbl))
end
return res
end
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
-- Returns keys of a table.
local function table_keys(tbl)
local arr = {}
for key, _ in pairs(tbl) do
table.insert(arr, key)
end
return arr
end
-- Sorts a table into a new table.
-- An alternative to cases such as when table.sort is not working,
-- like when trying to sort JSON tables (thanks fuckass lua).
local function table_to_sorted(tbl, sortfn)
local keys = {}
for key, _ in pairs(tbl) do
table.insert(keys, key)
end
table.sort(keys, function(keyA, keyB) return sortfn(tbl[keyA], tbl[keyB]) end)
local t2 = {}
for _, key in ipairs(keys) do
table.insert(t2, tbl[key])
end
return t2
end
-- Given a table and a property key, attempts to retrieve said property.
-- If property does not exists, creates it with by assigning a value from `create_value_fn`.
-- The created value is then returned.
function get_table_prop_or_create(tbl, prop_key, create_value_fn)
local value = tbl[prop_key]
if value == nil then
value = create_value_fn()
tbl[prop_key] = value
end
return value;
end
-- ==============================
-- Converts a hex color value to rgb, returning 3 components as separate values.
-- source: https://gist.github.com/fernandohenriques/12661bf250c8c2d8047188222cab7e28
function hex2rgb(hex)
local hex = hex:gsub("#","")
if hex:len() == 3 then
return (tonumber("0x"..hex:sub(1,1))*17)/255, (tonumber("0x"..hex:sub(2,2))*17)/255, (tonumber("0x"..hex:sub(3,3))*17)/255
else
return tonumber("0x"..hex:sub(1,2))/255, tonumber("0x"..hex:sub(3,4))/255, tonumber("0x"..hex:sub(5,6))/255
end
end
-- ==============================
-- Calculates text color of a reagent header based on its background color.
-- Returns either `black` or `white`.
-- Uses the same algorithm the game uses.
function calculate_reagent_header_text_color(hex)
local r, g, b = hex2rgb(hex)
return 0.2126 * r + 0.7152 * g + 0.0722 * b > 0.5
and "black"
or "white"
end
local function auto_reagent_card(frame, args)
error("not impl")
end
local function manual_reagent_card(frame, args)
local product_name = args.name
assert_not_nil(product_name, "failed to generate manual reagent card: product name not provided")
local product_id = args.id
local color = args.color
local recipes = args.recipes
local description = args.desc
local physical_description = args.physicalDesc
local effects = args.effects or args.metabolisms
-- ===============
local card_container_el = mw.html.create("div")
:addClass("reagent-card")
if product_id then
card_container_el:attr("id", "reagent-" .. product_id)
end
local header_el = card_container_el:tag("div")
:addClass("reagent-card-header")
local header_label_el = header_el:tag("span")
:wikitext(product_name)
if color then
header_el:css("background-color", color);
header_label_el:css("color", calculate_reagent_header_text_color(color))
end
if recipes and #recipes > 0 then
local recipes_el = card_container_el:tag("div")
:addClass("reagent-card-section mw-collapsible mw-collapsed")
end
if effects and #effects > 0 then
local effects_el = card_container_el:tag("div")
:addClass("reagent-card-section mw-collapsible mw-collapsed")
end
if description then
local description_el = card_container_el:tag("p")
:addClass("reagent-card-section")
:wikitext(description)
end
if physical_description then
local phys_description_el = card_container_el:tag("p")
:addClass("reagent-card-section")
:wikitext(physical_description)
end
return card_container_el
end
local function auto_reaction_card(frame, args)
error("not impl")
end
local function manual_reaction_card(frame, args)
error("not impl")
end
-- ==============================
-- Generates a reagent card element, containing
-- info about a reagent such as description, recipes, effects, etc.
--
-- Has 2 modes depending on what is passed:
-- - Automatic - when first argument is a reagent ID. This triggers automatic data lookup.
-- - Manual - when there are only named arguments. This allows to fill every parameter manually.
function p.reagent_card(frame)
local args = getArgs(frame)
if args[1] == nil then
return manual_reagent_card(frame, args)
else
return auto_reagent_card(frame, args)
end
end
-- Generates a reaction card element, containing
-- info about a chemical reaction.
--
-- Has 2 modes depending on what is passed:
-- - Automatic - when first argument is a reagent ID. This triggers automatic data lookup.
-- - Manual - when there are only named arguments. This allows to fill every parameter manually.
function p.reaction_card(frame)
local args = getArgs(frame)
if args[1] == nil then
return manual_reaction_card(frame, args)
else
return auto_reaction_card(frame, args)
end
end
return p