全站通知:

模块:Category

来自星露谷物语维基
跳到导航 跳到搜索

本模块会根据具体物品输出游戏内对应的分类的色系和名称,用于模板:Category,具体使用说明见给定的模板。

[ 查看 | 编辑 | 历史 | 刷新 ]上述文档的内容来自模块:Category/doc
local utils = require("Module:Utils")
local ID = require("Module:ID")
local Furniture = require("Module:Furniture")
local ObjectData = utils.lazyload('Module:Object/data')
local WeaponsData = utils.lazyload('Module:Weapons/data')

local p = {}

-- ==================== 工具函数 ====================

local function startsWith(str, prefix)
    if not str or not prefix then return false end
    return string.sub(str, 1, string.len(prefix)) == prefix
end

local function stripPrefix(id)
    if not id then return "" end
    return string.gsub(id, "^%([^%)]*%)", "")
end

-- 检查ID是否匹配任意前缀
local function hasAnyPrefix(id, prefixes)
    for _, prefix in ipairs(prefixes) do
        if startsWith(id, prefix) then
            return true, prefix
        end
    end
    return false, nil
end

-- ==================== 数据配置 ====================

local categoryNames = {
    [-103] = "技能书", [-102] = "书", [-100] = "服装", [-99] = "工具",
    [-97] = "鞋类", [-96] = "戒指", [-81] = "采集品", [-80] = "花",
    [-79] = "水果", [-75] = "蔬菜", [-74] = "种子", [-28] = "怪物战利品",
    [-27] = "工匠物品", [-26] = "工匠物品", [-25] = "菜品", [-24] = "装饰",
    [-22] = "钓具", [-21] = "鱼饵", [-20] = "垃圾", [-19] = "化肥",
    [-18] = "动物制品", [-16] = "资源", [-15] = "资源", [-14] = "动物制品",
    [-12] = "矿物", [-8] = "制造品", [-7] = "菜品", [-6] = "动物制品",
    [-5] = "动物制品", [-4] = "鱼", [-2] = "矿物"
}

local categoryColors = {
    [-103] = "122,93,39", [-102] = "85,47,27", [-81] = "10,130,50",
    [-80] = "219,54,211", [-79] = "255,20,147", [-75] = "0,128,0",
    [-74] = "165,42,42", [-28] = "50,10,70", [-27] = "0,155,111",
    [-26] = "0,155,111", [-24] = "150,80,190", [-22] = "0,139,139",
    [-21] = "139,0,0", [-20] = "105,105,105", [-19] = "112,128,144",
    [-18] = "255,0,100", [-16] = "64,102,114", [-15] = "64,102,114",
    [-14] = "255,0,100", [-12] = "110,0,90", [-8] = "148,61,40",
    [-7] = "220,60,0", [-6] = "255,0,100", [-5] = "255,0,100",
    [-4] = "0,0,139", [-2] = "110,0,90"
}

local weaponBonuses = {
    ["(W)2"] = 20.0,
    ["(W)3"] = 15.0
}

local weaponTypeNames = {
    [0] = '剑', [1] = '匕首', [2] = '锤'
}

local furnitureRestrictions = {
    [1] = "户外家具",
    [2] = "装饰"
}

local clothingPrefixes = {"(H)", "(S)", "(P)"}

-- 特殊前缀映射 (颜色, 名称)
local specialPrefixes = {
    ["(F)"] = {"100,25,90", nil}, -- 家具 (名称由函数动态确定)
    ["(TR)"] = {"96,81,255", "饰品"},
    ["(T)"] = {"47,79,79", "工具"},
    ["(B)"] = {"47,79,79", "鞋类"},
    ["(BC)"] = {"0,0,0", ""},
    ["(W)"] = {"47,79,79", nil} -- 武器 (名称由函数动态确定)
}

-- ==================== 数据访问层 ====================

local FurnitureData

local function getFurnitures()
    if not FurnitureData then 
        FurnitureData = Furniture:parseData() 
    end
    return FurnitureData
end

local function getObjectProperty(id, property)
    local cleanId = stripPrefix(id)
    local item = ObjectData[cleanId]
    return item and item[property] or nil
end

local function getCategoryById(id)
    return getObjectProperty(id, "Category")
end

local function getTypeById(id)
    return getObjectProperty(id, "Type")
end

local function getFurniture(id)
    if not startsWith(id, "(F)") then return nil end
    local cleanId = stripPrefix(id)
    return getFurnitures()[cleanId]
end

-- ==================== 武器处理 ====================

-- This has been deprecated because it produces inaccurate results due to precision issues.
local function getWeaponLevel(weapon, qualifiedItemId)
    local weaponPoints = 0.0

    local avgDamage = (weapon.MaxDamage + weapon.MinDamage) / 2
    local speedBonus = math.max(0, weapon.Speed) + (weapon.Type == 1 and 15 or 0)
    weaponPoints = weaponPoints + math.floor(avgDamage * (1.0 + 0.03 * speedBonus))

    local precisionDefenseBonus = weapon.Precision / 2 + weapon.Defense
    local critBonus = (weapon.CritChance - 0.02) * 200.0 + (weapon.CritMultiplier - 3.0) * 6.0
    weaponPoints = weaponPoints + math.floor(precisionDefenseBonus + critBonus)

    local bonus = weaponBonuses[qualifiedItemId]
    if bonus then
        weaponPoints = weaponPoints + bonus
    end

    weaponPoints = weaponPoints + weapon.Defense * 2

    return math.floor(weaponPoints / 7.0 + 1.0)
end

local function getWeaponCategory(id)
    local cleanId = stripPrefix(id)
    local weapon = WeaponsData[cleanId]
    
    if not weapon then return nil end
    
    if string.find(weapon.Name, "Scythe") then
        return '镰刀'
    end
    
    if string.find(weapon.Name, "Slingshot") then
        return '弹弓'
    end
    
    return weaponTypeNames[weapon.Type] or weaponTypeNames[0]
end

-- ==================== 核心函数 ====================

-- 获取家具相关信息
local function getFurnitureInfo(id, getColor)
    local furniture = getFurniture(id)
    if not furniture then return nil end
    
    if getColor then
        return '100,25,90'
    else
        local restriction = furniture.placementRestriction
        return furnitureRestrictions[restriction] or "家具"
    end
end

-- 获取类别信息 (统一处理颜色和名称)
local function getCategoryInfo(id, getColor)
    -- 家具处理
    local furnitureInfo = getFurnitureInfo(id, getColor)
    if furnitureInfo then return furnitureInfo end
    
    -- 服装类别
    if hasAnyPrefix(id, clothingPrefixes) then
        return getColor and "0,0,0" or '服装'
    end
    
    -- 特殊前缀处理
    for prefix, info in pairs(specialPrefixes) do
        if startsWith(id, prefix) then
            local color, name = info[1], info[2]
            
            -- 武器特殊处理
            if prefix == "(W)" then
                local weaponCat = getWeaponCategory(id)
                if getColor then
                    return color
                else
                    return (weaponCat ~= '镰刀' and weaponCat ~= '弹弓' and weaponCat) or '工具'
                end
            end
            
            -- 家具已在前面处理
            if prefix ~= "(F)" then
                return getColor and color or name
            end
        end
    end
    
    -- 类型判断
    local itemType = getTypeById(id)
    if itemType == 'Arch' then
        return getColor and '110,0,90' or '古物'
    end
    if itemType == 'Ring' then
        return getColor and "0,0,0" or '戒指'
    end
    
    -- 根据类别ID返回
    local category = getCategoryById(id)
    if getColor then
        return categoryColors[category] or "0,0,0"
    else
        return categoryNames[category] or ""
    end
end

-- 统一的结果处理逻辑
local function processResult(result1, result2, getColor)
    if result1 == result2 then return result1 end
    
    if getColor then
        -- 颜色处理:优先返回非黑色
        return (result1 ~= '0,0,0') and result1 or result2
    else
        -- 名称处理:优先返回非空
        return (result1 ~= '' and result1 ~= nil) and result1 or result2
    end
end

-- ==================== 公共接口 ====================

-- 获取类别颜色
function getCategoryColor(id)
    return getCategoryInfo(id, true)
end

-- 获取类别名称
function getCategoryName(id)
    return getCategoryInfo(id, false)
end

-- 通用的框架处理函数
local function handleFrameCall(frame, processor)
    local name = frame.args[1]
    local id = frame.args[2]
    local id2 = ID.id {args = { name }}
    local result1 = processor(id)
    
    if id ~= id2 then
        local result2 = processor(id2)
        return processResult(result1, result2, processor == getCategoryColor)
    end
    
    return result1
end

function p.getCategoryColor(frame)
    return handleFrameCall(frame, getCategoryColor)
end

function p.getCategoryName(frame)
    return handleFrameCall(frame, getCategoryName)
end

-- ==================== 调试 ====================

function p.debug()
    local id = "(F)MoldyCouch"
    local furniture = getFurniture(id)
    
    if furniture then
        local restriction = furniture.placementRestriction
        return furnitureRestrictions[restriction] or "家具"
    end
    
    return nil
end

return p