Модуль:Gases: различия между версиями
Материал из Space Station 14 | Время приключений Вики
Дополнительные действия
м исправление |
м Замена пользователя на себя |
||
| Строка 6: | Строка 6: | ||
local function getJsonData() | local function getJsonData() | ||
local title = mw.title.new('Участник: | local title = mw.title.new('Участник:WikiHampter/gas_prototypes.json') | ||
if not title or not title.exists then | if not title or not title.exists then | ||
return nil, 'Страница с JSON не найдена (Участник: | return nil, 'Страница с JSON не найдена (Участник:WikiHampter/gas_prototypes.json)' | ||
end | end | ||
local jsonText = title:getContent() | local jsonText = title:getContent() | ||
Версия от 22:50, 4 июня 2026
Для документации этого модуля может быть создана страница Модуль:Gases/doc
local p = {}
local function trim(s)
return s:match('^%s*(.-)%s*$') or s
end
local function getJsonData()
local title = mw.title.new('Участник:WikiHampter/gas_prototypes.json')
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
function p.table(frame)
local args = frame.args
local groupFilter = trim(args[1] or args['group'] or '')
local additional = trim(args['additional'] or '')
local data, err = getJsonData()
if err then
return '<div class="error">' .. mw.text.encode(err) .. '</div>'
end
local additionalSet = {}
if additional ~= '' then
for item in mw.text.gsplit(additional, ',') do
additionalSet[trim(item)] = true
end
end
local gases = {}
for id, gas in pairs(data) do
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)
if a.group ~= b.group then
return (a.group or '') < (b.group or '')
end
return (a.name or '') < (b.name or '')
end)
local root = mw.html.create('table')
:addClass('wikitable')
:addClass('sortable')
:css('width', '100%')
:css('text-align', 'center')
root:tag('caption')
:wikitext('Газы')
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
local color = gas.color or '#000000'
local textColor = '#ffffff'
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 nameCell = row:tag('td')
nameCell
:css('background', color)
:css('color', textColor)
:css('font-weight', 'bold')
:wikitext(gas.name or gas.id)
row:tag('td')
:css('text-align', 'left')
:wikitext(gas.desc or '')
row:tag('td')
:css('background', color)
:css('width', '50px')
:node(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
function p.single(frame)
local args = frame.args
local gasId = trim(args[1] or args['id'] or '')
if gasId == '' then
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, 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 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')
:css('margin', '5px 0')
:css('font-style', 'italic')
:wikitext(gas.desc or '')
local propsTable = root:tag('table')
:css('width', '100%')
:css('border-collapse', 'collapse')
:css('margin', '10px 0')
local function addProp(label, value)
local tr = propsTable:tag('tr')
:css('border-bottom', '1px solid #ddd')
tr:tag('td')
:css('font-weight', 'bold')
:css('width', '200px')
:css('padding', '4px 8px')
:wikitext(label)
local td = tr:tag('td')
:css('padding', '4px 8px')
if type(value) == 'table' then
td:node(value)
else
td:wikitext(tostring(value or '—'))
end
end
addProp('Физическое описание', gas.physicalDesc or '—')
addProp('Цвет', mw.html.create('span')
:css('background', color)
:css('color', textColor)
:css('padding', '2px 8px')
:css('border-radius', '3px')
:wikitext(color))
addProp('Удельная теплоёмкость', (gas.specificHeat and (gas.specificHeat .. ' Дж/моль·K') or '—'))
addProp('Показатель адиабаты', gas.heatCapacityRatio or '—')
addProp('Молярная масса', (gas.molarMass and (gas.molarMass .. ' г/моль') or '—'))
addProp('Цена за моль', (gas.pricePerMole and (gas.pricePerMole .. ' кредитов') or '—'))
if gas.metabolisms then
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)
end
return p