缺氧 wiki 编辑团队提示:注册账号并登录后体验更佳,且可通过参数设置定制优化您的浏览体验!

该站点为镜像站点,如果你想帮助这个由玩家志愿编辑的 wiki 站点,请前往原站点参与编辑,
同时欢迎加入编辑讨论群 851803695 与其他编辑者一起参与建设!

全站通知:

模块:表格/小动物养殖

来自缺氧WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

程序包项

表格.小动物养殖.calculateDiet(diet_recipe, calories_per_cycle)函数
针对不同种类的食物,给出小动物的代谢反应方程。 此函数来自 Module:小动物信息框p._variant(...) 的局域函数 reprDiet(...)
参数
diet_recipe 来自 Module:Data/Critters 中任意小动物的 diet 键表下的任何一个条目。(
calories_per_cycle 小动物每周期消耗的卡路里总量。(float
返回:指定代谢配方对应的格式化代谢反应方程。(字符串
表格.小动物养殖.generateEntries()函数
生成小动物信息列表。
返回:由小动物养殖相关信息组成的表。此表单为 Lua 数据表,需要进一步格式化为可读形式。(
表格.小动物养殖.sortCompare(a, b)函数
用于表格默认排序的比较函数。
参数
a 参与比较的小动物数据。(
b 参与比较的小动物数据。(
返回:两种小动物的类别和变体字典序是否为顺序。(布尔
表格.小动物养殖.fetchEntry(critter_type)函数
获取一种小动物的信息。
参数critter_type 小动物种类。必须是 Module:Data/Critters 中的小动物键名。(字符串
返回:所查询小动物的信息。所含具体信息类别详见解析函数 p.formatRow(...) 的相关说明。(
表格.小动物养殖.getCritterName(critter_type)函数
查询给定小动物的标准译名。 本方法目前不使用,仅作为 utils.getEntry(id) 的备份选项。
参数critter_type 小动物种类。必须是 Module:Data/Critters 中的小动物键名。(字符串
返回:小动物的中文译名。(字符串
表格.小动物养殖.formatRow(row_data)函数
将传入的小动物数据转换为 wikitext 格式的表格中的一行数据。
参数
row_data 要处理的行内容。(
row_data.critter_type 小动物种类。该值是 Module:Data/Critters 中的小动物键名。(字符串
row_data.is_major_variant 是否为主变种。(布尔
row_data.critter_name 小动物中文译名。(字符串
row_data.required_dlc_ids DLC 依赖项列表。(
row_data.incubation_cycles 小动物基准孵化时间。(float
row_data.growth_cycles 小动物基准成年时间。(float
row_data.initial_temperature 小动物初始体温。(float
row_data.egg_mass 小动物蛋质量。(float
row_data.critter_mass 小动物质量。(float
row_data.diet 基准代谢量。(
row_data.calories_per_cycle 基准代谢速率。(float
row_data.space_required 小动物所需最小空间。(float
row_data.environment_temperatures 小动物生存环境的各种温度阈值。该表来自 Module:Data/Critters。(
row_data.base_fertile_cycles 野生产卵周期。温顺、快乐的驯化小动物产卵周期缩短为 10%。(float
row_data.initial_breeding_weights 各变种的初始产卵概率。(
row_data.age_max 小动物寿命。(float
row_data.death_drop 小动物死亡掉落物表。(
返回:格式化的表格行 wikitext 字符串。(字符串
表格.小动物养殖.main(frame)函数
入口函数,在页面中调用此函数以生成小动物养殖表格。 要进行控制台测试,请使用 =p.main({args={debug=true}})
参数frame 传入的页面信息。(
返回:生成的 wikitext 格式的表格。(字符串
用法<code>{{#invoke:表格/小动物养殖|main}}</code>


--- Module:表格/小动物养殖
-- 此模块文档使用 Docbunto 模块自动化
-- @author Tanyz13

-- ======== 依赖项 ========

local p = {}
local fstr = mw.ustring.format -- 用于格式化字符串
local getArgs = require('Module:Dev/Arguments').getArgs
local mod_table = require([[Module:表格]])
local mod_critter_infobox = require([[Module:小动物信息框]])
local po = require([[Module:Po]]).po
local utils = require([[Module:Utils]])
local data_critters = mw.loadData([[Module:Data/Critters]])
local data_items = mw.loadData([[Module:Data/Items]])
local data_plants = mw.loadData([[Module:Data/Plants]])

-- 单独处理的译名列表
-- 查询小动物的中文译名时,对于下表中所列的小动物,会直接查找其 ID 在此处给出的键值所对应的中文字符串
-- 此外,该表中所有的物种在处理时都将被视作主要变种
local name_exceptions = {
    ["WOODDEER"] = "WOODDEER",
    ["DIVERGENTBEETLE"] = "DIVERGENT.VARIANT_BEETLE",
    ["DIVERGENTWORM"] = "DIVERGENT.VARIANT_WORM",
    ["ICEBELLY"] = "ICEBELLY",
    ["BEE"] = "BEE"
}

-- 额外产品
local additional_product_data = {
	["BeeHive"] = "EnrichedUranium",
	["GoldBelly"] = "GoldBellyCrown",
	["IceBelly"] = "BasicFabric",
	["Crab"] = "CrabShell",
	["CrabWood"] = "Wood",
	["WoodDeer"] = "Wood",
	["Drecko"] = "BasicFabric",
	["DreckoPlastic"] = "Plastic",
	["Glom"] = "ContaminatedOxygen",
	["MoleDelicacy"] = "GingerConfig",
	["Moo"] = "Milk",
	["Raptor"] = "FeatherFabric",
}

-- 数据模块中没有的额外掉落物在此处列出
local additional_drop = {
    ["Bee"] = {
        {
            ["deathDropItem"] = "NuclearWaste",
            ["deathDropItemAmount"] = 1.0,
        }
    },
    ["Glom"] = {
        {
            ["deathDropItem"] = "ContaminatedOxygen",
            ["deathDropItemAmount"] = 3.0,
        }
    },
}

-- 表头内容
local table_header = "{| class=\"wikitable sortable mw-collapsible\" style=\"text-align:center;margin:auto;width:100%\"\n" ..
                     "|-\n" ..
                     "! 小动物 !! DLC !! 孵化用时/<br/>成长用时<br/>[周期] !! 初始体温<br/>[°C]\n" ..
                     "! 蛋质量<br/>[千克] !! 动物质量<br/>[千克] !! 每周期基准代谢量(温顺、快乐)!! 额外产品\n" ..
                     "! 需要空间<br/>[格] !! 舒适温度/<br/>存活温度<br/>[°C] !! 产卵周期<br/>(野生) !! 产卵概率<br/>(基准)\n" ..
                     "! 寿命<br/> [周期] !! 死亡掉落物<br/>[份数或千克]"

-- ======== 方法定义 ========

--- 针对不同种类的食物,给出小动物的代谢反应方程。此函数来自 [[:Module:小动物信息框]] 中 <code>p._variant(...)</code> 的局域函数 <code>reprDiet(...)</code>。
--
-- @function p.calculateDiet
-- @param  {table}  diet_recipe 来自 [[:Module:Data/Critters]] 中任意小动物的 diet 键表下的任何一个条目。
-- @param  {float}  calories_per_cycle 小动物每周期消耗的卡路里总量。
-- @return {string} 指定代谢配方对应的格式化代谢反应方程。
function p.calculateDiet(diet_recipe, calories_per_cycle)
    local intake_item, product_item = nil, nil
    local intake_plant_growth_duration = nil
    local conversion_ratio = tonumber(diet_recipe.conversionRatio) or 1
    local intake_name, intake_is_category, intake_code = utils.getEntry(diet_recipe.element)
    local calories_per_kg = diet_recipe.caloriesPerKg
    local intake_amount = ""
    -- 若摄入的不是植物,则计算食物质量;否则尝试查找植物生长周期,并计算食用百分比。糖心树例外:栓角海豹吸食花蜜按质量计算。
    if not data_plants[diet_recipe.element] or diet_recipe.element == "SpaceTree" then
        intake_amount = utils.kg2str(calories_per_cycle / calories_per_kg, 1)
    else
        if data_plants[diet_recipe.element].cropVal ~= nil then
            intake_plant_growth_duration = data_plants[diet_recipe.element].cropVal.cropDuration
        else
            return "表格模块错误:找不到植物数据。"
        end
        intake_amount = fstr("%.4g%%", 60000 * calories_per_cycle / calories_per_kg / intake_plant_growth_duration)
    end
    if diet_recipe.element ~= nil and diet_recipe.element ~= "" then
        if intake_name ~= nil then
            intake_item = intake_is_category and utils.wikiLink(intake_name, {isCate = intake_is_category}) or fstr("[[%s]]", intake_name)
        else
            intake_item = diet_recipe.element
        end
    end
    if diet_recipe.producedElement ~= nil and diet_recipe.producedElement ~= "" then
        local product_name, product_is_category = utils.getEntry(diet_recipe.producedElement)
        local product_mass = utils.kg2str(calories_per_cycle / calories_per_kg * conversion_ratio, 1)
        if product_name ~= nil then
            product_item = product_is_category and utils.wikiLink(product_name, {isCate = product_is_category}) or fstr("[[%s]]", product_name)
        else
            product_item = diet_recipe.producedElement
        end
        product_item = fstr("%s %s", product_item, product_mass)
    end
    intake_item = intake_item or '无'
    product_item = product_item or '无'
    return fstr("%s %s ⇒ %s", intake_item, intake_amount, product_item)
end

--- 生成小动物信息列表。
--
-- @function p.generateEntries
-- @return {table} 由小动物养殖相关信息组成的表。此表单为 Lua 数据表,需要进一步格式化为可读形式。
function p.generateEntries()
    local data_table = {}
    for critter_type, _ in pairs(data_critters) do
    	table.insert(data_table, p.fetchEntry(critter_type))
    end
	table.sort(data_table, p.sortCompare)
    return data_table
end

--- 用于表格默认排序的比较函数。
--
-- @function p.sortCompare
-- @param  {table} a 参与比较的小动物数据。
-- @param  {table} b 参与比较的小动物数据。
-- @return {bool}  两种小动物的类别和变体字典序是否为顺序。
function p.sortCompare(a, b)
    if a == nil or b == nil then
        return false
    end
    if a.family:lower() ~= b.family:lower() then
        if a.family:lower() < b.family:lower() then
            return true
        else
            return false
        end
    elseif a.is_major_variant then
        return true
    elseif b.is_major_variant then
        return false
    elseif a.critter_type:lower() < b.critter_type:lower() then
        return true
    else
        return false
    end
    return false
end

--- 获取一种小动物的信息。
--
-- @function p.fetchEntry
-- @param  {string} critter_type 小动物种类。必须是 [[:Module:Data/Critters]] 中的小动物键名。
-- @return {table}  所查询小动物的信息。所含具体信息类别详见解析函数 p.formatRow(...) 的相关说明。
function p.fetchEntry(critter_type)
    local entry = {}
    entry.critter_type = critter_type
    entry.family = data_critters[critter_type].family
    -- 判断是否为主变种
    local is_major_variant = false
    local caps_id = string.upper(data_critters[critter_type].id)
    local caps_family = string.gsub(string.upper(data_critters[critter_type].family), "SPECIES", "")
    if caps_id == caps_family or name_exceptions[caps_id] ~= nil then
        is_major_variant = true
    end
    entry.is_major_variant = is_major_variant
    -- 小动物译名
    local critter_name = utils.getEntry(critter_type)
    entry.critter_name = critter_name
    -- DLC 列表
    entry.required_dlc_ids = data_critters[critter_type].requiredDlcIds
    -- 基准孵化时间
    if data_critters[critter_type].babyMonitorDef ~= nil and data_critters[critter_type].babyMonitorDef.incubationCycles ~= nil then
        entry.incubation_cycles = data_critters[critter_type].babyMonitorDef.incubationCycles
    end
    -- 基准成年时间
    if data_critters[critter_type].babyMonitorDef ~= nil and data_critters[critter_type].babyMonitorDef.adultThreshold ~= nil then
        entry.growth_cycles = data_critters[critter_type].babyMonitorDef.adultThreshold
    end
    -- 初始体温
    if data_critters[critter_type].primaryElement.Temperature ~= nil then
        entry.initial_temperature = data_critters[critter_type].primaryElement.Temperature
    end
    -- 小动物蛋质量
    if data_critters[critter_type].fertilityMonitorDef ~= nil and data_critters[critter_type].fertilityMonitorDef.initialBreedingWeights ~= nil then
        entry.egg_mass = data_items[data_critters[critter_type].fertilityMonitorDef.initialBreedingWeights[1].name].primaryElement.Mass
    end
    -- 小动物质量
    if data_critters[critter_type].primaryElement.Mass ~= nil then
        entry.critter_mass = data_critters[critter_type].primaryElement.Mass
    end
    -- 基准代谢量
    local diet_recipe_count = 0
    if data_critters[critter_type].diet ~= nil then
        entry.diet = data_critters[critter_type].diet
        entry.calories_per_cycle = data_critters[critter_type].caloriesPerCycle
    end
    -- 需要空间
    if data_critters[critter_type].spaceRequired ~= nil then
        entry.space_required = data_critters[critter_type].spaceRequired
    end
    -- 温度阈值
    if data_critters[critter_type].critterTemperatureMonitorDef ~= nil then
        entry.environment_temperatures = data_critters[critter_type].critterTemperatureMonitorDef
    end
    -- 野生产卵周期、基准产卵概率
    if data_critters[critter_type].fertilityMonitorDef ~= nil then
        entry.base_fertile_cycles = data_critters[critter_type].fertilityMonitorDef.baseFertileCycles
        entry.initial_breeding_weights = data_critters[critter_type].fertilityMonitorDef.initialBreedingWeights
    end
    -- 小动物寿命
    if data_critters[critter_type].ageMax ~= nil then
        entry.age_max = data_critters[critter_type].ageMax
    end
    -- 死亡掉落物
    entry.death_drop = {}
    if data_critters[critter_type].deathDrop ~= nil then
        for _, drop_item in ipairs(data_critters[critter_type].deathDrop) do
            table.insert(entry.death_drop, drop_item)
        end
    end
    if additional_drop[critter_type] ~= nil then
        for _, drop_item in ipairs(additional_drop[critter_type]) do
            table.insert(entry.death_drop, drop_item)
        end
    end
    return entry
end

--- 查询给定小动物的标准译名。本方法目前不使用,仅作为 <code>utils.getEntry(id)</code> 的备份选项。
-- 
-- @function p.getCritterName
-- @param  {string} critter_type 小动物种类。必须是 [[:Module:Data/Critters]] 中的小动物键名。
-- @return {string} 小动物的中文译名。
function p.getCritterName(critter_type)
    local caps_id = string.upper(data_critters[critter_type].id)
    local caps_family = string.gsub(string.upper(data_critters[critter_type].family), "SPECIES", "")
    local critter_name = ""
    if name_exceptions[caps_id] ~= nil then
        critter_name = po("STRINGS.CREATURES.SPECIES." .. name_exceptions[caps_id] .. ".NAME")
    elseif caps_id == caps_family then -- if the critter is the major species of the family
        critter_name = po("STRINGS.CREATURES.SPECIES." .. caps_id .. ".NAME")
    else
        critter_name = po("STRINGS.CREATURES.SPECIES." .. caps_family .. ".VARIANT_" .. string.gsub(caps_id, caps_family, "") .. ".NAME")
    end
    return critter_name
end

--- 将传入的小动物数据转换为 wikitext 格式的表格中的一行数据。
--
-- @function p.formatRow
-- @param  {table}   row_data 要处理的行内容。
-- @param  {string}  row_data.critter_type 小动物种类。该值是 [[:Module:Data/Critters]] 中的小动物键名。
-- @param  {bool}    row_data.is_major_variant 是否为主变种。
-- @param  {string}  row_data.critter_name 小动物中文译名。
-- @param  {table}   row_data.required_dlc_ids DLC 依赖项列表。
-- @param  {float}   row_data.incubation_cycles 小动物基准孵化时间。
-- @param  {float}   row_data.growth_cycles 小动物基准成年时间。
-- @param  {float}   row_data.initial_temperature 小动物初始体温。
-- @param  {float}   row_data.egg_mass 小动物蛋质量。
-- @param  {float}   row_data.critter_mass 小动物质量。
-- @param  {table}   row_data.diet 基准代谢量。
-- @param  {float}   row_data.calories_per_cycle 基准代谢速率。
-- @param  {float}   row_data.space_required 小动物所需最小空间。
-- @param  {table}   row_data.environment_temperatures 小动物生存环境的各种温度阈值。该表来自 [[:Module:Data/Critters]]。
-- @param  {float}   row_data.base_fertile_cycles 野生产卵周期。温顺、快乐的驯化小动物产卵周期缩短为 10%。
-- @param  {table}   row_data.initial_breeding_weights 各变种的初始产卵概率。
-- @param  {float}   row_data.age_max 小动物寿命。
-- @param  {table}   row_data.death_drop 小动物死亡掉落物表。
-- @return {string} 格式化的表格行 wikitext 字符串。
function p.formatRow(row_data)
    local contents = {}
    -- 小动物头像
    local bf_modifier = ""
    if row_data.is_major_variant then
        bf_modifier = "'''"
    end
    local critter_avatar = fstr("| [[File:%s.png|link=%s|x30px]]<br/>%s%s%s", row_data.critter_name, row_data.critter_name, bf_modifier, row_data.critter_name, bf_modifier)
    -- DLC 列表
    local dlc_list = "| 无"
    local dlc_collection = {}
    if row_data.required_dlc_ids ~= nil then
        for _, dlc_id in ipairs(row_data.required_dlc_ids) do
            if type(dlc_id) == "string" then
                table.insert(dlc_collection, fstr("<small>".. utils.DLC_ICONS[dlc_id] .."</small>"))
            end
        end
        dlc_list = "| " .. table.concat(dlc_collection, "<br/>")
    end
    -- 基准孵化时间
    local incubation_cycles = "| N/A"
    if row_data.incubation_cycles ~= nil then
        incubation_cycles = fstr("| %g", row_data.incubation_cycles)
    end
    -- 基准成年时间
    local growth_cycles = "N/A"
    if row_data.growth_cycles ~= nil then
        growth_cycles = fstr("%g", row_data.growth_cycles)
    end
    -- 初始体温
    local initial_temperature = "| N/A"
    if row_data.initial_temperature ~= nil then
        initial_temperature = fstr("| %g", row_data.initial_temperature - 273.15)
    end
    -- 小动物蛋质量
    local egg_mass = "| N/A"
    if row_data.egg_mass ~= nil then
        egg_mass = fstr("| %g", row_data.egg_mass)
    end
    -- 小动物质量
    local critter_mass = "| N/A"
    if row_data.critter_mass ~= nil then
        critter_mass = fstr("| %g", row_data.critter_mass)
    end
    -- 基准代谢量
    local diet_list = "| N/A"
    local diet_table = {}
    if row_data.diet ~= nil then
        local diet_recipe_count = 0
        for _, diet_recipe in ipairs(row_data.diet) do
            table.insert(diet_table, p.calculateDiet(diet_recipe, -row_data.calories_per_cycle))
            diet_recipe_count = diet_recipe_count + 1
        end
        -- 若食物数量太多则进行折叠
        if diet_recipe_count > 6 then
            diet_list = "| <div class=\"mw-collapsible mw-collapsed\"><span style=\"text-align:center;font-weight:bold;\">共 " .. tostring(diet_recipe_count) .. " 种食物,点击“展开”以查看</span>" ..
                        "<div class=\"mw-collapsible-content\">" ..
                        table.concat(diet_table, " <br/> ")..
                        "</div></div>"
        else
            diet_list = "| " .. table.concat(diet_table, " <br/> ")
        end
    end
    -- 额外产品
    local additional_product = "| 无"
    if additional_product_data[row_data.critter_type] ~= nil then
        additional_product = "| [[" .. utils.getEntry(additional_product_data[row_data.critter_type]) .. "]]"
    end
    -- 需要空间
    local space_required = "| 0"
    if row_data.space_required ~= nil then
        space_required = fstr("| %d", row_data.space_required)
    end
    -- 温度阈值
    local comfortable_temperatures = "| N/A"
    local surviving_temperatures = "N/A"
    if row_data.environment_temperatures ~= nil then
        comfortable_temperatures = fstr("| %+g ~ %+g", row_data.environment_temperatures.temperatureColdUncomfortable - 273.15, row_data.environment_temperatures.temperatureHotUncomfortable - 273.15)
        surviving_temperatures = fstr("%+g ~ %+g", row_data.environment_temperatures.temperatureColdDeadly - 273.15, row_data.environment_temperatures.temperatureHotDeadly - 273.15)
    end
    -- 野生产卵周期
    local base_fertile_cycles = "| N/A"
    if row_data.base_fertile_cycles ~= nil then
        base_fertile_cycles = fstr("| %g", row_data.base_fertile_cycles)
    end
    -- 基准产卵概率
    local initial_breeding_weights = "| N/A"
    if row_data.initial_breeding_weights ~= nil then
        initial_breeding_weights = "| "
        local breeding_table = {}
        for _, egg_entry in ipairs(row_data.initial_breeding_weights) do
            local egg_name = utils.getEntry(egg_entry.name)
            table.insert(breeding_table, fstr("[[File:%s.png|x20px]] %g%%", egg_name, egg_entry.weight * 100))
        end
        initial_breeding_weights = initial_breeding_weights .. table.concat(breeding_table, "<br/>")
    end
    -- 小动物寿命
    local age_max = "| N/A"
    if row_data.age_max ~= nil then
        age_max = fstr("| %g", row_data.age_max)
    end
    -- 死亡掉落物
    local death_drop = "| 无"
    if next(row_data.death_drop) ~= nil then
        local death_drop_collection = {}
        for _, drop_item in ipairs(row_data.death_drop) do
            table.insert(death_drop_collection, fstr("{{物品|%s}} × %g", utils.getEntry(drop_item.deathDropItem), drop_item.deathDropItemAmount))
        end
        death_drop = "| ".. table.concat(death_drop_collection, "<br/>")
    end
    -- 拼接子串
    table.insert(contents, critter_avatar)
    table.insert(contents, dlc_list)
    table.insert(contents, incubation_cycles)
    table.insert(contents, growth_cycles)
    table.insert(contents, initial_temperature)
    table.insert(contents, egg_mass)
    table.insert(contents, critter_mass)
    table.insert(contents, diet_list)
    table.insert(contents, additional_product)
    table.insert(contents, space_required)
    table.insert(contents, comfortable_temperatures)
    table.insert(contents, surviving_temperatures)
    table.insert(contents, base_fertile_cycles)
    table.insert(contents, initial_breeding_weights)
    table.insert(contents, age_max)
    table.insert(contents, death_drop)
    return table.concat(contents, "\n")
end

--- 入口函数,在页面中调用此函数以生成小动物养殖表格。
-- 要进行控制台测试,请使用 <code>=p.main({args={debug=true}})</code>。
--
-- @function p.main
-- @usage  <code>{{#invoke:表格/小动物养殖|main}}</code>
-- @param  {table}  frame 传入的页面信息。
-- @return {string} 生成的 wikitext 格式的表格。
function p.main(frame)
    local args = getArgs(frame)
    local output_table = {}
    -- 生成表头
    table.insert(output_table, table_header)
    -- 获取信息
    local entries = p.generateEntries()
    -- 生成表格行
    for _, entry in pairs(entries) do
        local row = p.formatRow(entry)
        table.insert(output_table, row)
    end
    if args.debug ~= nil then
        return table.concat(output_table, "\n|-\n") .. "\n|}"
    else
        return mw.getCurrentFrame():preprocess(table.concat(output_table, "\n|-\n") .. "\n|}")
    end
end

return p