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

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

全站通知:

模块:小动物信息框

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

用于模板:Template:小动物信息框。 视图模块:Module:信息框/小动物。 数据模块:Module:Data/Critters



-- 小动物信息框
local p = {}
local fstr = mw.ustring.format -- shortcut for formattig a string

local utils = require("Module:Utils")
local po = require([[Module:Po]]).po
local i18ncr = require([[Module:I18n]]).loadMessages([[Module:I18n/Creatures]])
local infobox = require([[Module:信息框/小动物]])
local getArgs = require("Module:Dev/Arguments").getArgs
local crDataPath = [[Module:Data/Critters]]
local crData = mw.loadData(crDataPath)
local k0 = utils.K0
local arrow = '➤'
local variant_exempt = {
    FreshWater = "FRESH_WATER"
}
local exception = {
    Bee = "STRINGS.CREATURES.SPECIES.BEE",
    BeeHive = "STRINGS.BUILDINGS.PREFABS.BEEHIVE",
    ScoutRover = "STRINGS.ROBOTS.MODELS.SCOUT",
    SweepBot = "STRINGS.ROBOTS.MODELS.SWEEPBOT"
}

local function familyCode(id)
    return fstr("STRINGS.CREATURES.FAMILY_PLURAL.%s", string.upper(id))
end

local function crBaseCode(crData)
    local id = crData.id
    if exception[id] ~= nil then return exception[id] end
    mw.log(utils.getEntry(id))
    local _, _, code, tag = utils.getEntry(id)
    if code then
        if tag:upper() == "CREATURE" or tag:upper() == "CREATURES" then
            return code:sub(1, -6)
        end
    end
    local speciesName = string.gsub(crData.family, "Species$", "")
    local prefix = "STRINGS.CREATURES.SPECIES."
    if id:upper() == speciesName:upper() then return prefix .. id:upper() end
    local variName = id:sub(#speciesName + 1)
    variName = variant_exempt[variName] or variName
    return prefix .. fstr("%s.VARIANT_%s", speciesName:upper(), variName:upper())
end

function p.getCode(pagename)
    local msgctxt = i18ncr:msgRev({
        key = pagename,
        args = {prefix = "STRINGS.CREATURES.SPECIES."}
    } or "")
    local critterId = ""
    if msgctxt == nil or utils.isDefaultT(pagename, msgctxt) then
        msgctxt = i18ncr:msgRev({
            key = pagename,
            args = {prefix = "STRINGS.CREATURES.FAMILY_PLURAL."}
        } or "")
        if msgctxt == nil or utils.isDefaultT(pagename, msgctxt) then
            msgctxt = i18ncr:msgRev({
                key = pagename,
                args = {prefix = "STRINGS.CREATURES.FAMILY."}
            } or "")
            if msgctxt ~= nil or utils.isDefaultT(pagename, msgctxt) then
                critterId = msgctxt:gsub("^STRINGS%.CREATURES%.FAMILY%.", "")
            end
        else
            critterId = msgctxt:gsub("^STRINGS%.CREATURES%.FAMILY_PLURAL%.", "")
        end
    else
        critterId = msgctxt:gsub("^STRINGS%.CREATURES%.SPECIES%.", "")
    end
    if msgctxt == nil then
        error(fstr("找不到小动物科 '%s',请使用参数1或检查 [[%s]]。", critterId, crDataPath))
    end
    local matchId = string.match(critterId, "(.-)%.")
    if matchId ~= nil then
        critterId = matchId
    end
    critterId = critterId:gsub("Species$", "")
    critterId = critterId:gsub("SPECIES$", "")
    return msgctxt, critterId
end

function p._variant(variId) -- variId is somthing like DreckoPlastic
    local variData = crData[variId]
    local baseCode = crBaseCode(variData)
    local out = {}
    out["ID"] = fstr("<code>%s</code>",variId)
    out["名称"] = po(baseCode .. ".NAME")
    out["图片"] = fstr("%s.png", out["名称"])
    out["图片说明"] = po(baseCode .. ".DESC")
    out["寿命"] = variData.ageMax
    out["血量"] = variData.hitPoints

    if variData.decorProvider ~= nil then
        out["装饰值"] = variData.decorProvider.baseDecor
        out["装饰半径"] = variData.decorProvider.baseRadius
    end
    if variData.kBoxCollider2D ~= nil then
        out["宽度"] = variData.kBoxCollider2D.x
        out["高度"] = variData.kBoxCollider2D.y
    end
    if variData.deathDrop ~= nil then
        out["死亡掉落"] = {}
        for _, deathDrop in ipairs(variData.deathDrop) do
            local ddiName = fstr("{{物品|%s}}", utils.getEntry(deathDrop.deathDropItem))
            local deathDropEntry = fstr("%s × %s", ddiName, utils.float2str(deathDrop.deathDropItemAmount))
            table.insert(out["死亡掉落"], deathDropEntry)
        end
        out["死亡掉落"] = #out["死亡掉落"] ~= 0 and table.concat(out["死亡掉落"], "<br/>") or nil
    end
    if variData.critterTemperatureMonitorDef ~= nil then
    	local temps = variData.critterTemperatureMonitorDef
        out["舒适温度下限"] = utils.float2str(temps.temperatureColdUncomfortable + k0)
        out["舒适温度上限"] = utils.float2str(temps.temperatureHotUncomfortable + k0)
        out["存活温度下限"] = utils.float2str(temps.temperatureColdDeadly + k0)
        out["存活温度上限"] = utils.float2str(temps.temperatureHotDeadly + k0)
    end
    out["需求空间"] = variData.spaceRequired
    out["掩埋致死"] = variData.entombVulnerable ~= nil and variData.entombVulnerable == true or nil
    out["淹没致死"] = variData.drownVulnerable ~= nil and variData.drownVulnerable == true or nil
    out["水下生存"] = variData.livesUnderWater ~= nil and variData.livesUnderWater == true or nil
    if variData.babyMonitorDef ~= nil then
        out["成熟期"] = variData.babyMonitorDef.adultThreshold and fstr("%s [[周期]]", utils.float2str(variData.babyMonitorDef.adultThreshold))
        out["孵化期"] = variData.babyMonitorDef.incubationCycles and fstr("%s [[周期]]", utils.float2str(variData.babyMonitorDef.incubationCycles))
    end
    out["可驯化"] = variData.isRanchable == true or variData.family == "PacuSpecies"

    -- out["产卵概率"]
    if variData.fertilityMonitorDef ~= nil then
        local fertilityData = variData.fertilityMonitorDef
        if fertilityData.initialBreedingWeights then
            local totalWeight = 0
            for _, egg in ipairs(fertilityData.initialBreedingWeights) do
                totalWeight = totalWeight + egg.weight
            end

            out["产卵概率"] = {}
            for _, egg in ipairs(fertilityData.initialBreedingWeights) do
                local offspringEntry = fstr("{{物品|%s}}: %.1f%%", utils.getEntry(egg.name), egg.weight / totalWeight * 100)
                table.insert(out["产卵概率"], offspringEntry)
            end
            out["产卵概率"] = #out["产卵概率"] ~= 0 and table.concat(out["产卵概率"], "<br/>") or nil
        end
        if fertilityData.baseFertileCycles ~= nil then 
            out["产卵周期"] = fstr("%.1f [[周期]]", fertilityData.baseFertileCycles)
        end
    end 
    

    -- out["代谢"]
    if variData.diet then
        local kCalPerCycle = math.abs(variData.caloriesPerCycle or 0)
        local plantData = mw.loadData([[Module:Data/Plants]])
        local function reprDiet(di)
            local intake, produce = nil, nil
            local intakePlantPeriod = nil
            local ratio = tonumber(di.conversionRatio) or 1
            local intakeName, intakeIsCate, intakeCode = utils.getEntry(di.element)
            local kCalPerKg = di.caloriesPerKg
            local intakeMass = ""
            if not plantData[di.element] or di.element == "SpaceTree" then
                -- if intakeCode and not utils.startswith(intakeCode, 'STRINGS.ELEMENTS.') and not utils.startswith(intakeCode, 'STRINGS.ITEMS.FOOD.') then
                --     intakeMass = fstr("%.2f% 单位", kCalPerCycle / kCalPerKg)
                -- else
                    intakeMass = utils.kg2str(kCalPerCycle / kCalPerKg, 1)
                -- end
           else
           		if plantData[di.element].cropVal then
                	intakePlantPeriod = plantData[di.element].cropVal.cropDuration
                else
                    return "出错:找不到植物数据"
                end
                intakeMass = fstr("%.1f%% 生长进度", 60000 * kCalPerCycle / kCalPerKg /
                                      intakePlantPeriod)
            end

            if di.element ~= nil and di.element ~= "" then
                if intakeName then
                    intake = intakeIsCate and utils.wikiLink(intakeName, {isCate = intakeIsCate})
                        or fstr("{{物品|%s}}", intakeName)
                else
                    intake = di.element
                end
            end
            if di.producedElement ~= nil and di.element ~= "" then
                local prodName, prodIsCate = utils.getEntry(di.producedElement)
                local produceMass = utils.kg2str(kCalPerCycle / kCalPerKg * ratio, 1)
                if prodName then
                    produce = prodIsCate and utils.wikiLink(prodName, {isCate = prodIsCate})
                        or fstr("{{物品|%s}}", prodName)
                else
                    produce = di.producedElement
                end
                produce = fstr("%s %s", produce, produceMass)
            end
            intake = intake or '无'
            produce = produce or '无'
            return fstr('<div>%s</div>' ..
                            '<div style="text-align: right">%s</div>' ..
                            '<div>%s</div>' .. '<div>%s</div>', intake,
                        intakeMass, arrow, produce)
        end
        out["代谢"] = table.concat(utils.map(variData.diet, reprDiet), "\n")
    end
    if variData.caloriesPerCycle ~= nil then
        out['卡路里变化'] = fstr("%s 千卡/[[周期]]", utils.float2str(variData.caloriesPerCycle/1000))
    end
    if variData.caloriesStomachSize ~= nil then
        out['胃容量'] = fstr("%s 千卡", utils.float2str(variData.caloriesStomachSize/1000))
    end
    if variData.deathTimer ~= nil then
        out['饥饿倒计时'] = fstr("%s [[周期]]", utils.float2str(variData.deathTimer/600))
    end
    if variData.primaryElement ~= nil then
        out["元素"] = fstr("{{物品|%s}}", utils.getEntry(variData.primaryElement.Name))
        out["质量"] = utils.kg2str(variData.primaryElement.Mass)
        out["初始温度"] = utils.float2str(variData.primaryElement.InternalTemperature + k0) .. " °C"
    end
    if variData.dlcIds ~= nil then
        local icons = utils.dlcIcons(variData.dlcIds)
        out['可用DLC'] = icons ~= nil and #icons > 0 and table.concat(icons, " ") or nil
    end
    -- test by: mw.logObject(p._variant("Hatch"))
    -- test by: mw.logObject(p._variant("Squirrel"))
    return out
end

function p.variant(frame)
    local args = getArgs(frame)
    return p._variant(args[1] or args.variId)
end

-- test by: = p.main(require("Module:debug").frame({},{debug=1, "Hatch"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, pagename="好吃哈奇"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, pagename="发光虫"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, pagename="辐射蜂"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, pagename="树鼠"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, pagename="毛鳞壁虎"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, pagename="释气海牛"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, pagename="抛壳蟹"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, "ScoutRover"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, "SweepBot"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, "Bee"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, "DivergentBeetle"}))

function p.main(frame)
    local args = getArgs(frame)
    local infos = {}
    local critters = {}

    if args[1] ~= nil then
        for _, critterId in ipairs(args) do
            local _, _, critterCode = utils.getEntry(critterId)
            if critterCode == nil then
                error(fstr("找不到小动物科 '%s',请使用参数1或检查 [[%s]]。", critterId, crDataPath))
            end
            table.insert(critters, {
                id = critterId,
                code = critterCode
            })
        end
    else
        local msgctxt, critterId = p.getCode(args.pagename)
        table.insert(critters, {
            id = critterId,
            code = msgctxt
        })
    end

    -- 找到同个species下的所有小动物id
    local families = {}
    for _, critter in ipairs(critters) do
        for k, v in pairs(crData) do
            if k:upper() == critter.id:upper() or string.gsub(v.family, "Species$", ""):upper() == critter.id:upper() then
                table.insert(families, v.family)
                break
            end
        end
    end

    -- 装配所有小动物数据
    local varisData = {}
    for _, family in ipairs(families) do
        for k, v in pairs(crData) do
            if v.family:upper() == family:upper() then
                local curr = p._variant(v.id)
                table.insert(varisData, {label = curr['名称'], data = curr, family = v.family})
            end
        end
    end

    if args.debug then
        mw.logObject(varisData, "varisData")
    end
    local infoboxTitle = #varisData > 1 and po(familyCode(varisData[1].family)) or args.pagename
    return infobox.main(infoboxTitle, varisData)
end

return p