模組:滿意RenderInfobox
可在模組:滿意RenderInfobox/doc建立此模組的說明文件
require("Module:滿意DocsUtils")
local p = {}
-- Hover tooltips for select labels
loc.tooltips = {
maxSpeed = "Applies on flat terrain, can be exceeded if going downhill",
time0_50 = "Time to reach 50 km/h on flat terrain",
damagePerSecond = "Damage per second",
}
-- Group names
loc.groups = {
item = "Item",
liquid = "Liquid",
gas = "Gas",
unknown = "Unknown",
building = "Building",
vehicle = "Vehicle",
fuel = "Fuel",
equipment = "Equipment",
ingredients = "Ingre­dients",
dimensions = "Dimensions",
}
-- Row labels (may be wiki links)
loc.labels = {
unlockedBy = "Unlocked by",
className = "Class name",
stackSize = "Stack size",
radioactive = "[[Radioactivity|Radioactive]]",
sinkPoints = "[[AWESOME Sink|Sink points]]",
energy = "Energy",
stackEnergy = "Stack energy",
abbreviation = "Abbrev­iation",
fluidColor = "Fluid color",
equipmentSlot = "Equipment slot",
ammo = "Ammo",
damage = "[[Health|Damage]]",
magSize = "Magazine size",
rateOfFire = "Rate of fire",
reloadTime = "Reload time",
damagePerSecond = "DPS",
range = "Range",
powerUsage = "[[Power|Power<br/>usage]]",
powerGenerated = "[[Power|Power<br/>generated]]",
fuelBurnRate = "Fuel burn rate",
supplementPerMinute = "Supplement<br/>input rate",
overclockable = "[[Clock speed|Overclock­able]]",
somersloopSlots = "[[Production amplifier|Somersloop<br/>slots]]",
inventorySize = "Inventory size",
inputBufferSize = "Input<br/>buffer size",
beltInputs = "Conveyor<br/>inputs",
beltOutputs = "Conveyor<br/>outputs",
pipeInputs = "Pipeline<br/>inputs",
pipeOutputs = "Pipeline<br/>outputs",
maxSpeed = "Max speed",
time0_50 = "0-50 km/h",
size_width = "Width",
size_length = "Length",
size_height = "Height",
size_area = "Area",
yes = "Yes",
no = "No",
}
loc.categories = {
items = "[[Category:Items]]",
fluids = "[[Category:Fluids]]",
liquids = "[[Category:Liquids]]",
gases = "[[Category:Gases]]",
buildings = "[[Category:Buildings]]",
vehicles = "[[Category:Vehicles]]",
fuels = "[[Category:Fuels]]",
radioactive = "[[Category:Radioactive]]",
}
loc.fuelSort = function(a, b)
if a.isVehicle ~= b.isVehicle then
return not a.isVehicle
elseif not a.isVehicle then
return a.buildingName < b.buildingName
else
return a.buildingName > b.buildingName
end
end
-- Generate a single <data> row. Automatically get label from loc.labels and format the value.
-- - parameter - string - parameter name from the data JSON
-- - branchValues - table
-- - unit - string - unit to show after the values
-- - nowiki - boolean - whether to escape the values
local function infoboxRow(parameter, branchValues, unit, nowiki)
local output = formatBranchDiff(getBranchValues(parameter, branchValues.stable, branchValues.experimental), nil, nowiki)
if output ~= "" and unit ~= nil then
output = output .. unit
end
return "<data><label>" .. loc.labels[parameter] .. "</label><default>" .. output .. "</default></data>"
end
function p.generateItemInfobox(frame)
local targetClassName = frame:getParent().args.className
local target = getObjectFromClassName(targetClassName, itemsJSON)
if target.stable == nil and target.experimental == nil then
return tostring(mw.html.create("strong"):addClass("error"):wikitext("Item infobox error: invalid target"):allDone())
end
-- image name
local itemLink, _ = getLinkAndName(targetClassName, target.stable, target.experimental)
-- form
local forms = getBranchValues("form", target.stable, target.experimental)
forms.stable = forms.stable ~= nil and (forms.stable == "solid" and loc.groups.item or (forms.stable == "liquid" and loc.groups.liquid or (forms.stable == "gas" and loc.groups.gas or loc.groups.item))) or nil
forms.experimental = forms.experimental ~= nil and (forms.experimental == "solid" and loc.groups.item or (forms.experimental == "liquid" and loc.groups.liquid or (forms.experimental == "gas" and loc.groups.gas or loc.groups.item))) or nil
forms.text = formatBranchDiff(forms)
forms.eitherIsSolid = forms.stable == loc.groups.item or forms.experimental == loc.groups.item
forms.eitherIsFluid = forms.stable == loc.groups.liquid or forms.experimental == loc.groups.liquid or forms.stable == loc.groups.gas or forms.experimental == loc.groups.gas
-- fuel
local fuelValues = getBranchValues("energy", target.stable, target.experimental)
local fuelSection = ""
if fuelValues.stable ~= 0 or fuelValues.experimental ~= 0 then
local fuelConsumers = {}
local fuelConsumersOrder = {}
-- list the item's energy
fuelSection = "<data><label>" .. loc.labels.energy .. "</label><default>" .. formatBranchDiff(fuelValues) .. loc.units.mj .. "</default></data>"
-- if the item is a solid fuel, list the energy per stack
if (target.stable ~= nil and target.stable.form == "solid") or (target.experimental ~= nil and target.experimental.form == "solid") then
fuelSection = fuelSection .. "<data><label>" .. loc.labels.stackEnergy .. "</label><default>" .. formatBranchDiff(
{stable = fuelValues.stable ~= nil and target.stable.form == "solid" and fuelValues.stable * target.stable.stackSize or nil,
experimental = fuelValues.experimental ~= nil and target.experimental.form == "solid" and fuelValues.experimental * target.experimental.stackSize or nil},
target.stable ~= nil and target.experimental ~= nil and target.stable.form ~= target.experimental.form) .. loc.units.mj .. "</default></data>"
end
-- list the buildings that consume the item as fuel
for _,branchBuildings in pairs(buildingsJSON) do
for _,building in pairs(branchBuildings) do
for _,fuelProcess in pairs(building.burnsFuel) do
if fuelProcess.fuel == targetClassName then
if fuelConsumers[building.className] == nil then
fuelConsumers[building.className] = {}
end
if building.stable then
fuelConsumers[building.className].stable = building
end
if building.experimental then
fuelConsumers[building.className].experimental = building
end
end
end
end
end
-- determine the order of the fuel consumers by retrieving names from their classNames, then sorting alphabetically
for className,_ in pairs(fuelConsumers) do
local buildingLink, buildingName = getLinkAndName(className, fuelConsumers[className].stable, fuelConsumers[className].experimental)
table.insert(fuelConsumersOrder, {className = className, buildingName = buildingName, buildingLink = buildingLink, isVehicle = fuelConsumers[className].stable ~= nil and fuelConsumers[className].stable.isVehicle or fuelConsumers[className].experimental ~= nil and fuelConsumers[className].experimental.isVehicle})
end
table.sort(fuelConsumersOrder, loc.fuelSort)
-- list the fuel consumption of each building in both branches, in both per minute and per cycle
for _,namedBuilding in pairs(fuelConsumersOrder) do
local branchBuilding = fuelConsumers[namedBuilding.className]
local buildingPowerGeneration = getBranchValues("powerGenerated", branchBuilding.stable, branchBuilding.experimental)
if buildingPowerGeneration.stable == 0 then
buildingPowerGeneration.stable = nil
end
if buildingPowerGeneration.experimental == 0 then
buildingPowerGeneration.experimental = nil
end
-- calculate the fuel consumption per minute and per cycle
if buildingPowerGeneration.stable ~= nil and buildingPowerGeneration.stable ~= 0 and fuelValues.stable ~= nil then
buildingPowerGeneration.stable = fuelValues.stable/buildingPowerGeneration.stable
buildingPowerGeneration.stablePerMin = formatNumber(60/buildingPowerGeneration.stable)
buildingPowerGeneration.stable = formatNumber(buildingPowerGeneration.stable)
end
if buildingPowerGeneration.experimental ~= nil and fuelValues.experimental ~= nil then
buildingPowerGeneration.experimental = fuelValues.experimental/buildingPowerGeneration.experimental
buildingPowerGeneration.experimentalPerMin = formatNumber(60/buildingPowerGeneration.experimental)
buildingPowerGeneration.experimental = formatNumber(buildingPowerGeneration.experimental)
end
-- manually do EA/EX formatting
local fuelConsumption = ""
-- if it's the same for both branches, list it only once
if buildingPowerGeneration.stable ~= nil and buildingPowerGeneration.stable == buildingPowerGeneration.experimental then
fuelConsumption = "<li>'''" .. buildingPowerGeneration.stable .. loc.units.sec .. " (" .. buildingPowerGeneration.stablePerMin .. loc.units.pmin .. ")'''</li>"
else
-- if it's different for each branch, list it twice, formatted for each branch
if buildingPowerGeneration.stable ~= nil then
fuelConsumption = fuelConsumption .. "<li>{{EA|'''" .. buildingPowerGeneration.stable .. loc.units.sec .. "''' (" .. buildingPowerGeneration.stablePerMin .. loc.units.pmin .. ")}}</li>"
end
if buildingPowerGeneration.experimental ~= nil then
fuelConsumption = fuelConsumption .. "<li>{{EX|'''" .. buildingPowerGeneration.experimental .. loc.units.sec .. "''' (" .. buildingPowerGeneration.experimentalPerMin .. loc.units.pmin .. ")}}</li>"
end
end
fuelSection = fuelSection .. "<data><default><ul><li>{{ItemLink|" .. namedBuilding.buildingLink .. "|" .. namedBuilding.buildingName .. "}}<ul>" .. fuelConsumption .. "</ul><li/></ul></default></data>"
end
-- wrap in a group, end the fuel consumers list and data row
fuelSection = [=[<group collapse="open"><header>]=] .. loc.groups.fuel .. [=[</header>]=] .. fuelSection .. [=[</group>]=]
end
-- infobox
local xml = [=[<infobox>
<title><default>]=] .. formatBranchDiff(getBranchValues("name", target.stable, target.experimental), true) .. [=[</default></title>
<image><default>]=] .. frame:callParserFunction("#setmainimage", itemLink .. ".png") .. [=[</default></image>
<data><default><i>]=] .. formatBranchDiff(getBranchValues("description", target.stable, target.experimental)) .. [=[</i></default></data>
]=] .. infoboxRow("unlockedBy", target) .. [=[
]=] .. infoboxRow("className", target) .. [=[
<group collapse="open"><header>]=] .. forms.text .. [=[</header>
]=] .. (forms.eitherIsSolid and infoboxRow("stackSize", target) or "") .. [=[
]=] .. infoboxRow("radioactive", target) .. [=[
]=] .. (forms.eitherIsSolid and infoboxRow("sinkPoints", target) or "") .. [=[
]=] .. infoboxRow("abbreviation", target) .. [=[
]=] .. (forms.eitherIsFluid and infoboxRow("fluidColor", target, nil, true) or "") .. [=[
</group>]=] .. fuelSection .. [=[
<group collapse="open"><header>]=] .. loc.groups.equipment .. [=[</header>
<data><label>]=] .. loc.labels.equipmentSlot .. [=[</label><default>]=] .. (frame:getParent().args.equipmentSlot or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.ammo .. [=[</label><default>]=] .. (frame:getParent().args.ammo or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.damage .. [=[</label><default>]=] .. (frame:getParent().args.damage or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.magSize .. [=[</label><default>]=] .. (frame:getParent().args.magSize or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.rateOfFire .. [=[</label><default>]=] .. (not (frame:getParent().args.rateOfFire == nil or frame:getParent().args.rateOfFire == "") and (frame:getParent().args.rateOfFire .. "/s") or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.reloadTime .. [=[</label><default>]=] .. (not (frame:getParent().args.reloadTime == nil or frame:getParent().args.reloadTime == "") and (frame:getParent().args.reloadTime .. loc.units.sec) or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.damagePerSecond .. [=[</label><default>]=] .. (frame:getParent().args.damagePerSecond or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.range .. [=[</label><default>]=] .. (frame:getParent().args.range or "") .. [=[</default></data>
</group>
</infobox>]=]
-- categories
local categories = ""
if not (frame:getParent().args.nocat ~= nil and frame:getParent().args.nocat == "1") then
-- individual ifs to cover branch differences
if forms.stable == loc.groups.item or forms.experimental == loc.groups.item then
categories = categories .. loc.categories.items
end
if forms.stable == loc.groups.liquid or forms.experimental == loc.groups.liquid then
categories = categories .. loc.categories.liquids .. loc.categories.fluids
end
if forms.stable == loc.groups.gas or forms.experimental == loc.groups.gas then
categories = categories .. loc.categories.gases .. loc.categories.fluids
end
if fuelValues.stable ~= 0 or fuelValues.experimental ~= 0 then
categories = categories .. loc.categories.fuels
end
local radioactiveValues = getBranchValues("radioactive", target.stable, target.experimental)
if radioactiveValues.stable ~= 0 or radioactiveValues.experimental ~= 0 then
categories = categories .. loc.categories.radioactive
end
end
return mw.getCurrentFrame():preprocess(xml) .. categories
end
function p.generateBuildingInfobox(frame)
local targetClassName = frame:getParent().args.className
local target = getObjectFromClassName(targetClassName, buildingsJSON)
if target.stable == nil and target.experimental == nil then
return tostring(mw.html.create("strong"):addClass("error"):wikitext("Building infobox error: invalid target"):allDone())
end
-- image name
local buildingLink, _ = getLinkAndName(targetClassName, target.stable, target.experimental)
-- somersloop slots
local somersloopValues = getBranchValues("somersloopSlots", target.stable, target.experimental)
-- fuel
local fuelSection = ""
local fuelValues = getBranchValues("burnsFuel", target.stable, target.experimental)
if (fuelValues.stable ~= nil and fuelValues.stable[1] ~= nil) or (fuelValues.experimental ~= nil and fuelValues.experimental[1] ~= nil) then
local fuels = {}
local fuelsOrder = {}
-- if a fuel is burnable in a branch, set its name and energy
for branchName,branch in pairs(getBranchValues("burnsFuel", target.stable, target.experimental)) do
for _,fuel in pairs(branch) do
if fuels[fuel.fuel] == nil then
fuels[fuel.fuel] = {fuel = {}, energy = {}, supplement = {}, byproduct = {}, byproductAmount = {}}
end
local fuelItem = getObjectFromClassName(fuel.fuel, itemsJSON)
fuels[fuel.fuel].fuel[branchName] = fuel.fuel
fuels[fuel.fuel].energy[branchName] = fuelItem[branchName].energy
fuels[fuel.fuel].supplement[branchName] = fuel.supplement
fuels[fuel.fuel].byproduct[branchName] = fuel.byproduct
fuels[fuel.fuel].byproductAmount[branchName] = fuel.byproductAmount
end
end
-- order fuels by their energy
for fuelClassName,_ in pairs(fuels) do
table.insert(fuelsOrder, fuelClassName)
end
table.sort(fuelsOrder, function(a,b) return (fuels[a].energy.stable or fuels[a].energy.experimental or 0) < (fuels[b].energy.stable or fuels[b].energy.experimental or 0) end)
-- generate infobox fuel section
for _,fuelClassName in pairs(fuelsOrder) do
local supplement = fuels[fuelClassName].supplement.stable or fuels[fuelClassName].supplement.experimental
local byproduct = fuels[fuelClassName].byproduct.stable or fuels[fuelClassName].byproduct.experimental
fuelSection = fuelSection .. "<li>'''" .. generateItemLink(fuelClassName, fuels[fuelClassName].fuel.stable, fuels[fuelClassName].fuel.experimental, false) .. "'''"
fuelSection = fuelSection .. (supplement and (" + " .. generateItemLink(supplement, fuels[fuelClassName].supplement.stable, fuels[fuelClassName].supplement.experimental, false)) or "") .. "</li>"
fuelSection = fuelSection .. (byproduct and ("<ul><li>→ " .. formatBranchDiff(fuels[fuelClassName].byproductAmount) .. "× " .. generateItemLink(byproduct, fuels[fuelClassName].byproduct.stable, fuels[fuelClassName].byproduct.experimental, false) .. "</li></ul>") or "")
end
fuelSection = [=[<group collapse="open"><header>]=] .. loc.groups.fuel .. [=[</header>]=] .. infoboxRow("supplementPerMinute", target, loc.units.pmin) .. [=[<data><default><ul>]=] .. fuelSection .. [=[</ul></default></data></group>]=]
end
-- ingredients
local ingredientSection = ""
local recipes = {}
-- get all recipes that produce the target building (should be only one, or two if EA/EX)
for _,branchRecipes in pairs(recipesJSON) do
for _,recipe in pairs(branchRecipes) do
for _,product in pairs(recipe.products) do
if targetClassName == product.item then
if recipe.stable then
recipes.stable = recipe
end
if recipe.experimental then
recipes.experimental = recipe
end
end
end
end
end
-- if there is only one recipe, show ingredients in a group
if (recipes.stable == recipes.experimental) or (recipes.stable == nil and recipes.experimental ~= nil) or (recipes.stable ~= nil and recipes.experimental == nil) then
recipes.stable = recipes.stable or recipes.experimental
for _,ingredient in pairs(recipes.stable.ingredients) do
local itemLink, itemName = getLinkAndName(ingredient.item, true, true)
ingredientSection = ingredientSection .. "<data><default>'''" .. formatNumber(ingredient.amount) .. " × {{ItemLink|" .. itemLink .. "|" .. itemName .. "}}'''</default></data>"
end
ingredientSection = [=[<group collapse="open"><header>]=] .. loc.groups.ingredients .. [=[</header>]=] .. ingredientSection .. [=[</group>]=]
-- else use a tabber section to show branch recipes completely separately
elseif recipes.stable ~= nil and recipes.stable ~= recipes.experimental then
ingredientSection = "<panel>"
-- ensure stable is always first
for _,branchName in ipairs({"stable", "experimental"}) do
local recipe = recipes[branchName]
if recipe ~= nil then
ingredientSection = ingredientSection .. [=[<section><label>]=] .. loc.branches[branchName] .. [=[</label><group collapse="open"><header>]=] .. loc.groups.ingredients .. [=[</header>]=]
-- list ingredients in individual data rows
for _,ingredient in pairs(recipe.ingredients) do
local itemLink, itemName = getLinkAndName(ingredient.item, true, true)
ingredientSection = ingredientSection .. "<data><default>'''" .. formatNumber(ingredient.amount) .. " × {{ItemLink|" .. itemLink .. "|" .. itemName .. "}}'''</default></data>"
end
end
ingredientSection = ingredientSection .. "</group></section>"
end
ingredientSection = ingredientSection .. "</panel>"
end
-- whether is a vehicle or a building
local isVehicle = getBranchValues("isVehicle", target.stable, target.experimental)
isVehicle = {(isVehicle.stable or isVehicle.experimental) and loc.groups.vehicle or loc.groups.building}
local powerGenerated = formatBranchDiff(getBranchValues("powerGenerated", target.stable, target.experimental))
if powerGenerated ~= "" then
powerGenerated = powerGenerated .. loc.units.mw
end
-- infobox
local xml = [=[<infobox>
<title><default>]=] .. formatBranchDiff(getBranchValues("name", target.stable, target.experimental), true) .. [=[</default></title>
<image><default>]=] .. frame:callParserFunction("#setmainimage", buildingLink .. ".png") .. [=[</default></image>
<data><default><i>]=] .. formatBranchDiff(getBranchValues("description", target.stable, target.experimental)) .. [=[</i></default></data>
]=] .. infoboxRow("unlockedBy", target) .. [=[
]=] .. infoboxRow("className", target) .. [=[
<group collapse="open"><header>]=] .. isVehicle[1] .. [=[</header>
]=] .. (isVehicle[1] == loc.groups.building and infoboxRow("powerUsage", target, loc.units.mw) or "") .. [=[
<data><label>]=] .. (isVehicle[1] == loc.groups.vehicle and loc.labels.fuelBurnRate or loc.labels.powerGenerated) .. [=[</label><default>]=] .. powerGenerated .. [=[</default></data>
<data><label>]=] .. loc.labels.overclockable .. [=[</label><default>]=] .. (not (frame:getParent().args.overclockable == nil or frame:getParent().args.overclockable == "") and (frame:getParent().args.overclockable == "1" and loc.labels.yes or loc.labels.no) or "") .. [=[</default></data>
]=] .. ((somersloopValues.stable ~= 0 or somersloopValues.experimental ~= 0) and infoboxRow("somersloopSlots", target) or "") .. [=[
<data><label>]=] .. loc.labels.inventorySize .. [=[</label><default>]=] .. (frame:getParent().args.inventorySize or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.inputBufferSize .. [=[</label><default>]=] .. (frame:getParent().args.inputBufferSize or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.beltInputs .. [=[</label><default>]=] .. (frame:getParent().args.beltInputs or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.beltOutputs .. [=[</label><default>]=] .. (frame:getParent().args.beltOutputs or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.pipeInputs .. [=[</label><default>]=] .. (frame:getParent().args.pipeInputs or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.pipeOutputs .. [=[</label><default>]=] .. (frame:getParent().args.pipeOutputs or "") .. [=[</default></data>
<data><label><span title="]=] .. loc.tooltips.maxSpeed .. [=[">]=] .. loc.labels.maxSpeed .. [=[</span></label><default>]=] .. (not (frame:getParent().args.maxSpeed == nil or frame:getParent().args.maxSpeed == "") and (frame:getParent().args.maxSpeed .. loc.units.kmh) or "") .. [=[</default></data>
<data><label><span title="]=] .. loc.tooltips.time0_50 .. [=[">]=] .. loc.labels.time0_50 .. [=[</span></label><default>]=] .. (not (frame:getParent().args.time0_50 == nil or frame:getParent().args.time0_50 == "") and (frame:getParent().args.time0_50 .. loc.units.sec) or "") .. [=[</default></data>
</group>
<group collapse="open"><header>]=] .. loc.groups.dimensions .. [=[</header>
<data><label>]=] .. loc.labels.size_width .. [=[</label><default>]=] .. (not (frame:getParent().args.size_width == nil or frame:getParent().args.size_width == "") and (frame:getParent().args.size_width .. loc.units.m) or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.size_length .. [=[</label><default>]=] .. (not (frame:getParent().args.size_length == nil or frame:getParent().args.size_length == "") and (frame:getParent().args.size_length .. loc.units.m) or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.size_height .. [=[</label><default>]=] .. (not (frame:getParent().args.size_height == nil or frame:getParent().args.size_height == "") and (frame:getParent().args.size_height .. loc.units.m) or "") .. [=[</default></data>
<data><label>]=] .. loc.labels.size_area .. [=[</label><default>]=] .. ((tonumber(frame:getParent().args.size_width) and tonumber(frame:getParent().args.size_length)) and (tonumber(frame:getParent().args.size_width)*tonumber(frame:getParent().args.size_length) .. loc.units.m2) or "") .. [=[</default></data>
<data><default>]=] .. (frame:getParent().args.size_note or "") .. [=[</default></data>
</group>]=] .. fuelSection .. ingredientSection .. [=[
</infobox>]=]
-- categories
local categories = ""
if not (frame:getParent().args.nocat ~= nil and frame:getParent().args.nocat == "1") then
if isVehicle[1] == loc.groups.vehicle then
categories = loc.categories.vehicles
else
categories = loc.categories.buildings
end
end
return mw.getCurrentFrame():preprocess(xml) .. categories
end
return p