Открыть меню
Переключить меню настроек
Открыть персональное меню
Вы не представились системе
Ваш IP-адрес будет виден всем, если вы внесёте какие-либо изменения.

Модуль:Gases: различия между версиями

Материал из Space Station 14 | Время приключений Вики
м Изменение пользователя на меня
мНет описания правки
 
(не показаны 3 промежуточные версии этого же участника)
Строка 1: Строка 1:
local p = {}
local p = {}
p.gases = mw.text.jsonDecode(mw.title.new('Участник:WikiHampter/gas_prototypes.json'):getContent())


local function trim(s)
local function tablelength(T)
    return s:match('^%s*(.-)%s*$') or s
local count = 0
for _ in pairs(T) do count = count + 1 end
return count
end
end


local function getJsonData()
local function attachAsNewLine(originalStr, joinStr)
    local title = mw.title.new('Участник:WikiHampter/gas_prototypes.json')
return originalStr .. "\n" .. joinStr
    if not title or not title.exists then
        return nil, 'Страница с JSON не найдена (Участник:WikiHampter/gas_prototypes.json)'
    end
    local jsonText = title:getContent()
    if not jsonText or jsonText == '' then
        return nil, 'Страница с JSON пуста'
    end
    local success, data = pcall(mw.text.jsonDecode, jsonText)
    if not success then
        return nil, 'Ошибка парсинга JSON: ' .. data
    end
    return data, nil
end
end


function p.table(frame)
local function contains(list, x)
    local args = frame.args
for _, v in ipairs(list) do
    local groupFilter = trim(args[1] or args['group'] or '')
if v == x then return true end
    local additional = trim(args['additional'] or '')
end
return false
end


    local data, err = getJsonData()
local function getEffects(gasPrototype)
    if err then
local effects = ""
        return '<div class="error">' .. mw.text.encode(err) .. '</div>'
if gasPrototype.metabolisms == nil then
    end
return effects
end
for metabolismGroupKey, metabolismGroup in pairs(gasPrototype.metabolisms) do
effects = attachAsNewLine(effects, "* " .. metabolismGroupKey .. " (" .. tostring(metabolismGroup.rate) .. " единиц в секунду)")
for _, effect in ipairs(metabolismGroup.effects) do
if effect.description ~= "" then
effects = attachAsNewLine(effects, "** " .. effect.description)
end
end
end
return effects
end


    local additionalSet = {}
function p.table(frame)
    if additional ~= '' then
local out = ""
        for item in mw.text.gsplit(additional, ',') do
local group = frame.args.group
            additionalSet[trim(item)] = true
local groups
        end
if group ~= nil and group ~= "" then
    end
groups = mw.text.split(group, ",")
end


    local gases = {}
out = out .. '{| class="wikitable sortable" style="width: 100%; text-align: center;"'
    for id, gas in pairs(data) do
out = out .. "\n! Газ !! Описание !! Цвет !! Удельная теплоёмкость (Дж/моль·K) !! Показатель адиабаты !! Молярная масса (г/моль) !! Цена за моль !! Эффекты"
        local matchGroup = false
        if groupFilter ~= '' then
            local groups = mw.text.split(gas.group or '', ',')
            for _, g in ipairs(groups) do
                if trim(g) == groupFilter then
                    matchGroup = true
                    break
                end
            end
        end
        if additionalSet[gas.name] or additionalSet[id] then
            matchGroup = true
        end
        if groupFilter == '' or matchGroup then
            table.insert(gases, gas)
        end
    end


    table.sort(gases, function(a, b)
local additional = frame.args.additional
        if a.group ~= b.group then
if additional ~= nil and additional ~= "" then
            return (a.group or '') < (b.group or '')
local additionalGasIds = mw.text.split(additional, ",")
        end
for _, gasId in ipairs(additionalGasIds) do
        return (a.name or '') < (b.name or '')
out = out .. fillGasRow(gasId)
    end)
end
end


    local root = mw.html.create('table')
for _, gasPrototype in pairs(p.gases) do
        :addClass('wikitable')
if group == nil or group == "" or contains(groups, gasPrototype.group) then
        :addClass('sortable')
out = out .. fillGasRow(gasPrototype.id)
        :css('width', '100%')
end
        :css('text-align', 'center')
end


    root:tag('caption')
out = out .. "\n|}"
        :wikitext('Газы')
return out
 
end
    root:tag('tr')
        :tag('th'):wikitext('Газ'):done()
        :tag('th'):wikitext('Описание'):done()
        :tag('th'):wikitext('Цвет'):done()
        :tag('th'):wikitext('Удельная теплоёмкость<br/>(Дж/моль·K)'):done()
        :tag('th'):wikitext('Показатель адиабаты'):done()
        :tag('th'):wikitext('Молярная масса<br/>(г/моль)'):done()
        :tag('th'):wikitext('Цена за моль'):done()
        :tag('th'):wikitext('Эффекты'):done()


    for _, gas in ipairs(gases) do
function fillGasRow(gasId)
        local color = gas.color or '#000000'
local gasPrototype = p.gases[gasId]
        local textColor = '#ffffff'
local out = ""
        local r, g, b = color:match('^#(..)(..)(..)$')
        if r then
            local luminance = (tonumber(r, 16) * 0.299 + tonumber(g, 16) * 0.587 + tonumber(b, 16) * 0.114) / 255
            if luminance > 0.5 then
                textColor = '#000000'
            end
        end


        local row = root:tag('tr')
local color = gasPrototype.color or "#000000"
local textColor = gasPrototype.textColor or "#FFFFFF"


        local nameCell = row:tag('td')
out = out .. '\n|- style="background: ' .. color .. '; color: ' .. textColor .. '"'
        nameCell
out = out .. '\n! scope="row" style="font-weight: bold;" | ' .. gasPrototype.name
            :css('background', color)
out = out .. '\n| style="text-align: left;" | ' .. gasPrototype.desc
            :css('color', textColor)
out = out .. '\n| ' .. color
            :css('font-weight', 'bold')
out = out .. '\n| ' .. tostring(gasPrototype.specificHeat or "")
            :wikitext(gas.name or gas.id)
out = out .. '\n| ' .. tostring(gasPrototype.heatCapacityRatio or "")
out = out .. '\n| ' .. tostring(gasPrototype.molarMass or "")
out = out .. '\n| ' .. tostring(gasPrototype.pricePerMole or "")
out = out .. '\n| style="text-align: left; font-size: 90%;" | ' .. getEffects(gasPrototype)


        row:tag('td')
return out
            :css('text-align', 'left')
            :wikitext(gas.desc or '')
 
        row:tag('td')
            :css('background', color)
            :css('width', '50px')
            :wikitext(mw.html.create('span')
                :css('color', textColor)
                :wikitext(color))
 
        row:tag('td'):wikitext(tostring(gas.specificHeat or ''))
        row:tag('td'):wikitext(tostring(gas.heatCapacityRatio or ''))
        row:tag('td'):wikitext(tostring(gas.molarMass or ''))
        row:tag('td'):wikitext(tostring(gas.pricePerMole or ''))
 
        local effectsCell = row:tag('td')
            :css('text-align', 'left')
            :css('font-size', '90%')
 
        if gas.metabolisms then
            for metabType, metabData in pairs(gas.metabolisms) do
                effectsCell:tag('div')
                    :css('font-weight', 'bold')
                    :css('margin-top', '4px')
                    :wikitext('Метаболизм: ' .. metabType .. ' (speed: ' .. tostring(metabData.rate or '?') .. ')')
 
                local list = effectsCell:tag('ul')
                    :css('margin', '2px 0')
                    :css('padding-left', '20px')
 
                if metabData.effects then
                    for _, eff in ipairs(metabData.effects) do
                        local desc = eff.description or ''
                        if desc ~= '' then
                            list:tag('li'):wikitext(desc)
                        end
                    end
                end
            end
        else
            effectsCell:wikitext('—')
        end
    end
 
    return tostring(root)
end
end


function p.single(frame)
function p.single(frame)
    local args = frame.args
local gasId = frame.args[1] or frame.args.id or ""
    local gasId = trim(args[1] or args['id'] or '')
if gasId == "" then
 
return '<div class="error">Не указан ID газа. Использование: {{#invoke:Gases|single|id=Oxygen}}</div>'
    if gasId == '' then
end
        return '<div class="error">Не указан ID газа. Использование: {{#invoke:Gases|single|id=Oxygen}}</div>'
    end
 
    local data, err = getJsonData()
    if err then
        return '<div class="error">' .. mw.text.encode(err) .. '</div>'
    end
 
    local gas = data[gasId]
    if not gas then
        return '<div class="error">Газ с ID "' .. mw.text.encode(gasId) .. '" не найден</div>'
    end
 
    local color = gas.color or '#000000'
    local textColor = '#ffffff'
    local r, gb = color:match('^#(..)(..)(..)$')
    if r then
        local luminance = (tonumber(r, 16) * 0.299 + tonumber(gb, 16) * 0.587 + tonumber(b, 16) * 0.114) / 255
        if luminance > 0.5 then
            textColor = '#000000'
        end
    end
 
    local root = mw.html.create('div')
        :addClass('gas-info-box')
        :css('border', '2px solid ' .. color)
        :css('border-radius', '8px')
        :css('padding', '10px')
        :css('margin', '10px 0')
        :css('background', '#f8f9fa')
 
    root:tag('div')
        :css('font-size', '1.5em')
        :css('font-weight', 'bold')
        :css('color', color)
        :wikitext(gas.name or gas.id)


    root:tag('div')
local gasPrototype = p.gases[gasId]
        :css('margin', '5px 0')
if not gasPrototype then
        :css('font-style', 'italic')
return '<div class="error">Газ с ID "' .. mw.text.encode(gasId) .. '" не найден</div>'
        :wikitext(gas.desc or '')
end


    local propsTable = root:tag('table')
local color = gasPrototype.color or "#000000"
        :css('width', '100%')
local textColor = gasPrototype.textColor or "#FFFFFF"
        :css('border-collapse', 'collapse')
        :css('margin', '10px 0')


    local function addProp(label, value)
local out = ""
        local tr = propsTable:tag('tr')
out = out .. '<div style="border: 2px solid ' .. color .. '; border-radius: 8px; padding: 10px; margin: 10px 0; background: #f8f9fa;">'
            :css('border-bottom', '1px solid #ddd')
out = out .. '<div style="font-size: 1.5em; font-weight: bold; color: ' .. color .. ';">' .. gasPrototype.name .. '</div>'
        tr:tag('td')
out = out .. '<div style="margin: 5px 0; font-style: italic;">' .. gasPrototype.desc .. '</div>'
            :css('font-weight', 'bold')
            :css('width', '200px')
            :css('padding', '4px 8px')
            :wikitext(label)
        tr:tag('td')
            :css('padding', '4px 8px')
            :wikitext(tostring(value or '—'))
    end


    addProp('Физическое описание', gas.physicalDesc or '')
out = out .. '<table style="width: 100%; border-collapse: collapse; margin: 10px 0;">'
    addProp('Цвет', mw.html.create('span')
out = out .. '<tr style="border-bottom: 1px solid #ddd;"><td style="font-weight: bold; width: 200px; padding: 4px 8px;">Физическое описание</td><td style="padding: 4px 8px;">' .. (gasPrototype.physicalDesc or "") .. '</td></tr>'
        :css('background', color)
out = out .. '<tr style="border-bottom: 1px solid #ddd;"><td style="font-weight: bold; width: 200px; padding: 4px 8px;">Цвет</td><td style="padding: 4px 8px;"><span style="background: ' .. color .. '; color: ' .. textColor .. '; padding: 2px 8px; border-radius: 3px;">' .. color .. '</span></td></tr>'
        :css('color', textColor)
out = out .. '<tr style="border-bottom: 1px solid #ddd;"><td style="font-weight: bold; width: 200px; padding: 4px 8px;">Удельная теплоёмкость</td><td style="padding: 4px 8px;">' .. (gasPrototype.specificHeat and (gasPrototype.specificHeat .. " Дж/моль·K") or "—") .. '</td></tr>'
        :css('padding', '2px 8px')
out = out .. '<tr style="border-bottom: 1px solid #ddd;"><td style="font-weight: bold; width: 200px; padding: 4px 8px;">Показатель адиабаты</td><td style="padding: 4px 8px;">' .. tostring(gasPrototype.heatCapacityRatio or "—") .. '</td></tr>'
        :css('border-radius', '3px')
out = out .. '<tr style="border-bottom: 1px solid #ddd;"><td style="font-weight: bold; width: 200px; padding: 4px 8px;">Молярная масса</td><td style="padding: 4px 8px;">' .. (gasPrototype.molarMass and (gasPrototype.molarMass .. " г/моль") or "—") .. '</td></tr>'
        :wikitext(color))
out = out .. '<tr style="border-bottom: 1px solid #ddd;"><td style="font-weight: bold; width: 200px; padding: 4px 8px;">Цена за моль</td><td style="padding: 4px 8px;">' .. (gasPrototype.pricePerMole and (gasPrototype.pricePerMole .. " кредитов") or "—") .. '</td></tr>'
    addProp('Удельная теплоёмкость', (gas.specificHeat and (gas.specificHeat .. ' Дж/моль·K') or ''))
out = out .. '</table>'
    addProp('Показатель адиабаты', gas.heatCapacityRatio or '')
    addProp('Молярная масса', (gas.molarMass and (gas.molarMass .. ' г/моль') or ''))
    addProp('Цена за моль', (gas.pricePerMole and (gas.pricePerMole .. ' кредитов') or ''))


    if gas.metabolisms then
out = out .. getEffects(gasPrototype)
        root:tag('h3'):wikitext('Эффекты метаболизма')
        for metabType, metabData in pairs(gas.metabolisms) do
            root:tag('h4'):wikitext(metabType .. ' (speed: ' .. tostring(metabData.rate or '?') .. ')')
            local list = root:tag('ul')
            if metabData.effects then
                for _, eff in ipairs(metabData.effects) do
                    local desc = eff.description or ''
                    if desc ~= '' then
                        list:tag('li'):wikitext(desc)
                    end
                end
            end
        end
    end


    return tostring(root)
out = out .. "</div>"
return out
end
end


return p
return p

Текущая версия от 22:53, 4 июня 2026

Для документации этого модуля может быть создана страница Модуль:Gases/doc

local p = {}
p.gases = mw.text.jsonDecode(mw.title.new('Участник:WikiHampter/gas_prototypes.json'):getContent())

local function tablelength(T)
	local count = 0
	for _ in pairs(T) do count = count + 1 end
	return count
end

local function attachAsNewLine(originalStr, joinStr)
	return originalStr .. "\n" .. joinStr
end

local function contains(list, x)
	for _, v in ipairs(list) do
		if v == x then return true end
	end
	return false
end

local function getEffects(gasPrototype)
	local effects = ""
	if gasPrototype.metabolisms == nil then
		return effects
	end
	for metabolismGroupKey, metabolismGroup in pairs(gasPrototype.metabolisms) do
		effects = attachAsNewLine(effects, "* " .. metabolismGroupKey .. " (" .. tostring(metabolismGroup.rate) .. " единиц в секунду)")
		for _, effect in ipairs(metabolismGroup.effects) do
			if effect.description ~= "" then
				effects = attachAsNewLine(effects, "** " .. effect.description)
			end
		end
	end
	return effects
end

function p.table(frame)
	local out = ""
	local group = frame.args.group
	local groups
	if group ~= nil and group ~= "" then
		groups = mw.text.split(group, ",")
	end

	out = out .. '{| class="wikitable sortable" style="width: 100%; text-align: center;"'
	out = out .. "\n! Газ !! Описание !! Цвет !! Удельная теплоёмкость (Дж/моль·K) !! Показатель адиабаты !! Молярная масса (г/моль) !! Цена за моль !! Эффекты"

	local additional = frame.args.additional
	if additional ~= nil and additional ~= "" then
		local additionalGasIds = mw.text.split(additional, ",")
		for _, gasId in ipairs(additionalGasIds) do
			out = out .. fillGasRow(gasId)
		end
	end

	for _, gasPrototype in pairs(p.gases) do
		if group == nil or group == "" or contains(groups, gasPrototype.group) then
			out = out .. fillGasRow(gasPrototype.id)
		end
	end

	out = out .. "\n|}"
	return out
end

function fillGasRow(gasId)
	local gasPrototype = p.gases[gasId]
	local out = ""

	local color = gasPrototype.color or "#000000"
	local textColor = gasPrototype.textColor or "#FFFFFF"

	out = out .. '\n|- style="background: ' .. color .. '; color: ' .. textColor .. '"'
	out = out .. '\n! scope="row" style="font-weight: bold;" | ' .. gasPrototype.name
	out = out .. '\n| style="text-align: left;" | ' .. gasPrototype.desc
	out = out .. '\n| ' .. color
	out = out .. '\n| ' .. tostring(gasPrototype.specificHeat or "")
	out = out .. '\n| ' .. tostring(gasPrototype.heatCapacityRatio or "")
	out = out .. '\n| ' .. tostring(gasPrototype.molarMass or "")
	out = out .. '\n| ' .. tostring(gasPrototype.pricePerMole or "")
	out = out .. '\n| style="text-align: left; font-size: 90%;" | ' .. getEffects(gasPrototype)

	return out
end

function p.single(frame)
	local gasId = frame.args[1] or frame.args.id or ""
	if gasId == "" then
		return '<div class="error">Не указан ID газа. Использование: {{#invoke:Gases|single|id=Oxygen}}</div>'
	end

	local gasPrototype = p.gases[gasId]
	if not gasPrototype then
		return '<div class="error">Газ с ID "' .. mw.text.encode(gasId) .. '" не найден</div>'
	end

	local color = gasPrototype.color or "#000000"
	local textColor = gasPrototype.textColor or "#FFFFFF"

	local out = ""
	out = out .. '<div style="border: 2px solid ' .. color .. '; border-radius: 8px; padding: 10px; margin: 10px 0; background: #f8f9fa;">'
	out = out .. '<div style="font-size: 1.5em; font-weight: bold; color: ' .. color .. ';">' .. gasPrototype.name .. '</div>'
	out = out .. '<div style="margin: 5px 0; font-style: italic;">' .. gasPrototype.desc .. '</div>'

	out = out .. '<table style="width: 100%; border-collapse: collapse; margin: 10px 0;">'
	out = out .. '<tr style="border-bottom: 1px solid #ddd;"><td style="font-weight: bold; width: 200px; padding: 4px 8px;">Физическое описание</td><td style="padding: 4px 8px;">' .. (gasPrototype.physicalDesc or "—") .. '</td></tr>'
	out = out .. '<tr style="border-bottom: 1px solid #ddd;"><td style="font-weight: bold; width: 200px; padding: 4px 8px;">Цвет</td><td style="padding: 4px 8px;"><span style="background: ' .. color .. '; color: ' .. textColor .. '; padding: 2px 8px; border-radius: 3px;">' .. color .. '</span></td></tr>'
	out = out .. '<tr style="border-bottom: 1px solid #ddd;"><td style="font-weight: bold; width: 200px; padding: 4px 8px;">Удельная теплоёмкость</td><td style="padding: 4px 8px;">' .. (gasPrototype.specificHeat and (gasPrototype.specificHeat .. " Дж/моль·K") or "—") .. '</td></tr>'
	out = out .. '<tr style="border-bottom: 1px solid #ddd;"><td style="font-weight: bold; width: 200px; padding: 4px 8px;">Показатель адиабаты</td><td style="padding: 4px 8px;">' .. tostring(gasPrototype.heatCapacityRatio or "—") .. '</td></tr>'
	out = out .. '<tr style="border-bottom: 1px solid #ddd;"><td style="font-weight: bold; width: 200px; padding: 4px 8px;">Молярная масса</td><td style="padding: 4px 8px;">' .. (gasPrototype.molarMass and (gasPrototype.molarMass .. " г/моль") or "—") .. '</td></tr>'
	out = out .. '<tr style="border-bottom: 1px solid #ddd;"><td style="font-weight: bold; width: 200px; padding: 4px 8px;">Цена за моль</td><td style="padding: 4px 8px;">' .. (gasPrototype.pricePerMole and (gasPrototype.pricePerMole .. " кредитов") or "—") .. '</td></tr>'
	out = out .. '</table>'

	out = out .. getEffects(gasPrototype)

	out = out .. "</div>"
	return out
end

return p