全站通知:

模块:Dyeing

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

当前模块用于读取、处理和输出染色齐先生的核桃房等页面的物品染色表格,本模块目前主要通过模板:DyeingTable使用。

计划后续补充更多功能,使之能够用于所有物品页面的“裁制”一小节。

[ 查看 | 编辑 | 历史 | 刷新 ]上述文档的内容来自模块:Dyeing/doc
local Helper = require("Module:Helper")
local ItemNames = require("Module:ItemNames")
local ObjectData = Helper.LazyLoad('Module:Object/data')

local cache = require "mw.ext.LuaCache"
local KEY_PREFIX = "Module:Dyeing"
local EXP_TIME = 172800

local p = {}

p.colors = {
    ['color_aquamarine'] = '127, 255, 212',
    ['color_black'] = '45, 45, 45',
    ['color_blue'] = '46, 85, 183',
    ['color_brown'] = '130, 73, 37',
    ['color_copper'] = '179, 85, 0',
    ['color_cyan'] = '0, 255, 255',
    ['color_dark_blue'] = '0, 0, 139',
    ['color_dark_brown'] = '139, 69, 19',
    ['color_dark_cyan'] = '0, 139, 139',
    ['color_dark_gray'] = '169, 169, 169',
    ['color_dark_green'] = '0, 100, 0',
    ['color_dark_orange'] = '255, 140, 0',
    ['color_dark_pink'] = '255, 20, 147',
    ['color_dark_purple'] = '148, 0, 211',
    ['color_dark_red'] = '139, 0, 0',
    ['color_dark_yellow'] = '184, 134, 11',
    ['color_gold'] = '255, 215, 0',
    ['color_gray'] = '128, 128, 128',
    ['color_green'] = '10, 143, 0',
    ['color_iridium'] = '105, 15, 255',
    ['color_iron'] = '197, 213, 224',
    ['color_jade'] = '130, 158, 93',
    ['color_light_cyan'] = '180, 255, 255',
    ['color_lime'] = '0, 255, 0',
    ['color_orange'] = '255, 128, 0',
    ['color_pale_violet_red'] = '219, 112, 147',
    ['color_pink'] = '255, 163, 186',
    ['color_poppyseed'] = '82, 47, 153',
    ['color_purple'] = '115, 41, 181',
    ['color_red'] = '220, 0, 0',
    ['color_salmon'] = '255, 85, 95',
    ['color_sand'] = '255, 222, 173',
    ['color_sea_green'] = '46, 139, 87',
    ['color_white'] = '255, 255, 255',
    ['color_yellow'] = '255, 230, 0',
    ['color_yellow_green'] = '173, 255, 47'
}

p.colorNames = {
    ['color_aquamarine'] = '蓝绿色',
    ['color_black'] = '黑色',
    ['color_blue'] = '蓝色',
    ['color_brown'] = '棕色',
    ['color_copper'] = '铜色',
    ['color_cyan'] = '青色',
    ['color_dark_blue'] = '深蓝色',
    ['color_dark_brown'] = '深棕色',
    ['color_dark_cyan'] = '深青色',
    ['color_dark_gray'] = '深灰色',
    ['color_dark_green'] = '深绿色',
    ['color_dark_orange'] = '深橙色',
    ['color_dark_pink'] = '亮粉色',
    ['color_dark_purple'] = '深紫色',
    ['color_dark_red'] = '深红色',
    ['color_dark_yellow'] = '褐色',
    ['color_gold'] = '金色',
    ['color_gray'] = '灰色',
    ['color_green'] = '绿色',
    ['color_iridium'] = '亮紫色',
    ['color_iron'] = '铁色',
    ['color_jade'] = '玉绿色',
    ['color_light_cyan'] = '淡青色',
    ['color_lime'] = '亮绿色',
    ['color_orange'] = '橙色',
    ['color_pale_violet_red'] = '苍紫罗兰色',
    ['color_pink'] = '粉色',
    ['color_poppyseed'] = '罂粟紫',
    ['color_prismatic'] = '自选',
    ['color_purple'] = '紫色',
    ['color_red'] = '红色',
    ['color_salmon'] = '橙红色',
    ['color_sand'] = '沙色',
    ['color_sea_green'] = '海绿色',
    ['color_white'] = '白色',
    ['color_yellow'] = '黄色',
    ['color_yellow_green'] = '黄绿色'
}

p.potColorCategories = {
    [1] = { name = '红色', rgb = '220, 0, 0' },
    [2] = { name = '橙色', rgb = '255, 128, 0' },
    [3] = { name = '黄色', rgb = '255, 230, 0' },
    [4] = { name = '绿色', rgb = '10, 143, 0' },
    [5] = { name = '蓝色', rgb = '46, 105, 203' },
    [6] = { name = '紫色', rgb = '115, 41, 181' }
}

p.tagToPotCategoryIndex = {}
do
    local potColorGroups = {
        { "color_red", "color_salmon", "color_dark_red", "color_pink" },
        { "color_orange", "color_dark_orange", "color_dark_brown", "color_brown", "color_copper" },
        { "color_yellow", "color_dark_yellow", "color_gold", "color_sand" },
        { "color_green", "color_dark_green", "color_lime", "color_yellow_green", "color_jade" },
        { "color_blue", "color_dark_blue", "color_dark_cyan", "color_light_cyan", "color_cyan", "color_aquamarine" },
        { "color_purple", "color_dark_purple", "color_dark_pink", "color_pale_violet_red", "color_poppyseed", "color_iridium" }
    }
    
    for categoryIndex, tags in ipairs(potColorGroups) do
        for _, tag in ipairs(tags) do
            p.tagToPotCategoryIndex[tag] = categoryIndex
        end
    end
end

local excludedItems = { ['30'] = true, ['94'] = true, ['803'] = true, ['180'] = true, ['182'] = true, ['748'] = true }

local function sanitizeColorTag(colorTag)
    return colorTag and mw.text.trim(colorTag):lower() or nil
end

local function getPotCategoryInfo(colorTag)
    local tag = sanitizeColorTag(colorTag)
    if not tag then return nil end
    
    local categoryIndex = p.tagToPotCategoryIndex[tag]
    return categoryIndex and p.potColorCategories[categoryIndex] or nil
end

local function extractColorTag(contextTags)
    if not contextTags then return nil end
    
    for _, tag in ipairs(contextTags) do
        if type(tag) == "string" and tag:match("^color_") then
            return tag
        end
    end
    return nil
end

local function extractDyeIntensity(contextTags)
    if not contextTags then return nil end
    
    local intensityMap = { weak = "普通", medium = "中等", strong = "强烈" }
    
    for _, tag in ipairs(contextTags) do
        if type(tag) == "string" and tag:match("^dye_") then
            local intensity = tag:match("^dye_(.+)")
            if intensity then
                return intensityMap[intensity] or intensity
            end
        end
    end
    return nil
end

local function getTextColorFromRgb(rgbString)
    if not rgbString then return "black" end
    
    local r, g, b = rgbString:match("(%d+),%s*(%d+),%s*(%d+)")
    if not (r and g and b) then return "black" end
    
    local brightness = 0.299 * r + 0.587 * g + 0.114 * b
    return brightness < 128 and "white" or "black"
end

local function getItemDisplayName(itemId)
    local englishName = ItemNames.getEnglishName("(O)" .. itemId) or ''
    local chineseName = ItemNames.getChineseName("(O)" .. itemId) or ''
    local expandName = englishName:gsub(": ", " ")
    
    local specialNames = {
        ['126'] = '诡异玩偶(绿)',
        ['127'] = '诡异玩偶(黄)'
    }
    expandName = specialNames[itemId] or expandName
    
    local specialAffixes = {
        ['腌鱼籽'] = '任意', ['蛋'] = '白、棕', ['果酱'] = '任意', ['果汁'] = '任意',
        ['大鸡蛋'] = '白、棕', ['腌菜'] = '任意', ['鱼籽'] = '任意', ['果酒'] = '任意'
    }
    local affix = specialAffixes[chineseName]
    
    local args = affix and {expandName, affix, class = "inline"} or {expandName, class = "inline"}
    return Helper.ExpandTemplate("模板:Name", args), chineseName
end

local function sortItemsByCategory(itemsData)
    table.sort(itemsData, function(a, b)
        local aIsAsdf = (a.type == 'asdf')
        local bIsAsdf = (b.type == 'asdf')
        
        if aIsAsdf and not bIsAsdf then
            return false
        end
        if not aIsAsdf and bIsAsdf then
            return true
        end
        
        if a.category ~= b.category then
            return a.category < b.category
        end
        if a.type ~= b.type then
            return a.type < b.type
        end
        return a.price < b.price
    end)
end

local function processItemData(itemId, itemData)
    if not (itemData and itemData.Name and itemData.ContextTags) then
        return nil
    end
    
    local colorTag = extractColorTag(itemData.ContextTags)
    if not colorTag then return nil end
    
    local displayName, chineseName = getItemDisplayName(itemId)
    if not (displayName and displayName ~= '') then return nil end
    
    return {
        display = displayName,
        chineseName = chineseName,
        category = itemData.Category or 0,
        type = itemData.Type or '',
        price = itemData.Price or 0,
        colorTag = colorTag
    }
end

function p.getColor(frame)
    local colorTag = sanitizeColorTag(frame.args[1])
    return colorTag and p.colors[colorTag] or nil
end

function p.getColorName(frame)
    local colorTag = sanitizeColorTag(frame.args[1])
    return colorTag and p.colorNames[colorTag] or nil
end

function p.getPotColorName(frame)
    local categoryInfo = getPotCategoryInfo(frame.args[1])
    return categoryInfo and categoryInfo.name or nil
end

function p.getPotColorRgb(frame)
    local categoryInfo = getPotCategoryInfo(frame.args[1])
    return categoryInfo and categoryInfo.rgb or nil
end

function p.generateColorTable(frame)
    local cacheKey = 'DyeingTable'
    if cache.get(cacheKey) then
        local result = cache.get(cacheKey)
        return result
    end

    if not ObjectData then
        return "<!-- 无法加载 ObjectData -->"
    end
    
    local items = {}
    
    for itemId, itemData in pairs(ObjectData) do
        if not excludedItems[itemId] then
            local itemInfo = processItemData(itemId, itemData)
            if itemInfo then
                local colorName = p.colorNames[itemInfo.colorTag]
                local colorRgb = p.colors[itemInfo.colorTag]
                if colorName and colorRgb then
                    local dyeIntensity = extractDyeIntensity(itemData.ContextTags) or ""
                    local textColor = getTextColorFromRgb(colorRgb)
                    
                    itemInfo.html = string.format(
                        '<tr><td data-sort-value="%s">%s</td><td>%s</td><td style="background-color: rgb(%s); color: %s;">%s</td><td>%s</td></tr>',
                        itemInfo.chineseName, itemInfo.display, colorName, colorRgb, textColor, colorRgb, dyeIntensity
                    )
                    table.insert(items, itemInfo)
                end
            end
        end
    end
    
    sortItemsByCategory(items)
    
    local tableRows = {}
    for _, item in ipairs(items) do
        table.insert(tableRows, item.html)
    end
    
    local result = table.concat(tableRows, "\n")
    cache.set(cacheKey, result, EXP_TIME)
    return result
end

function p.getPotColorItems(frame)
    local targetColor = frame.args[1]
    if not targetColor then return "" end
    
    local cacheKey = 'PotColor_' .. targetColor
    if cache.get(cacheKey) then
        local result = cache.get(cacheKey)
        return result
    end
    
    local colorMap = {
        ["红色"] = 1, ["red"] = 1,
        ["橙色"] = 2, ["orange"] = 2,
        ["黄色"] = 3, ["yellow"] = 3,
        ["绿色"] = 4, ["green"] = 4,
        ["蓝色"] = 5, ["blue"] = 5,
        ["紫色"] = 6, ["purple"] = 6
    }
    
    local targetIndex = colorMap[targetColor]
    if not targetIndex then return "" end
    
    local itemsData = {}
    
    for itemId, itemData in pairs(ObjectData) do
        if not excludedItems[itemId] and itemData and itemData.ContextTags then
            local colorTag = extractColorTag(itemData.ContextTags)
            if colorTag then
                local categoryIndex = p.tagToPotCategoryIndex[colorTag]
                if categoryIndex == targetIndex then
                    local itemInfo = processItemData(itemId, itemData)
                    if itemInfo then
                        table.insert(itemsData, itemInfo)
                    end
                end
            end
        end
    end
    
    sortItemsByCategory(itemsData)
    
    local displayItems = {}
    for _, item in ipairs(itemsData) do
        table.insert(displayItems, item.display)
    end
    
    local result = table.concat(displayItems, " • ")
    cache.set(cacheKey, result, EXP_TIME)
    return result
end

function p.getQiColorItems(frame)
    local targetColor = frame.args[1]
    if not targetColor then return "" end
    
    local cacheKey = 'QiColor_' .. targetColor
    if cache.get(cacheKey) then
        local result = cache.get(cacheKey)
        return result
    end
    
    local qiColorGroups = {
        ["红色"] = {"color_red", "color_dark_red"},
        ["red"] = {"color_red", "color_dark_red"},
        ["橙色"] = {"color_orange", "color_copper", "color_dark_orange"},
        ["orange"] = {"color_orange", "color_copper", "color_dark_orange"},
        ["黄色"] = {"color_yellow", "color_dark_yellow", "color_gold"},
        ["yellow"] = {"color_yellow", "color_dark_yellow", "color_gold"},
        ["绿色"] = {"color_green", "color_dark_green", "color_lime", "color_yellow_green", "color_jade"},
        ["green"] = {"color_green", "color_dark_green", "color_lime", "color_yellow_green", "color_jade"},
        ["蓝色"] = {"color_blue", "color_dark_blue", "color_dark_cyan", "color_light_cyan", "color_cyan", "color_aquamarine"},
        ["blue"] = {"color_blue", "color_dark_blue", "color_dark_cyan", "color_light_cyan", "color_cyan", "color_aquamarine"},
        ["紫色"] = {"color_purple", "color_dark_purple", "color_dark_pink", "color_pale_violet_red", "color_poppyseed", "color_iridium"},
        ["purple"] = {"color_purple", "color_dark_purple", "color_dark_pink", "color_pale_violet_red", "color_poppyseed", "color_iridium"}
    }
    
    local targetTags = qiColorGroups[targetColor]
    if not targetTags then return "" end
    
    local tagSet = {}
    for _, tag in ipairs(targetTags) do
        tagSet[tag] = true
    end
    
    local itemsData = {}
    
    for itemId, itemData in pairs(ObjectData) do
        if not excludedItems[itemId] and itemData and itemData.ContextTags then
            local colorTag = extractColorTag(itemData.ContextTags)
            if colorTag and tagSet[colorTag] then
                local itemInfo = processItemData(itemId, itemData)
                if itemInfo then
                    table.insert(itemsData, itemInfo)
                end
            end
        end
    end
    
    sortItemsByCategory(itemsData)
    
    local displayItems = {}
    for _, item in ipairs(itemsData) do
        table.insert(displayItems, item.display)
    end
    
    local result = table.concat(displayItems, " • ")
    cache.set(cacheKey, result, EXP_TIME)
    return result
end

return p