欢迎大家来到沙石镇时光中文维基!本站编辑权限开放,欢迎加入中文维基 QQ 群「沙海时光」:372816689
目前正在进行全站数据更新,期间可能会存在显示异常的问题。

全站通知:

模块:ItemHelper

来自沙石镇时光维基
跳到导航 跳到搜索

此模块的文档可以在模块:ItemHelper/doc创建

local Helper = require("Module:Helper")

local ItemPrototype = Helper.LazyLoad("Module:AssetItemPrototypeItem")
local Refine = Helper.LazyLoad("Module:AssetRefineConfigRefine")
local Text = Helper.LoadAsset("Module:AssetItemChinese")
local ItemId = Helper.LazyLoad("Module:ItemId")
local ItemName          = Helper.LazyLoad("Module:ItemName")
local ItemSourceNew     = Helper.LazyLoad("Module:AssetItemSource")
local ItemSource = Helper.LazyLoad("Module:ItemSource")
local ItemSource_2 = Helper.LazyLoad("Module:ItemSource_2")
local ItemUnimplemented = Helper.LazyLoad("Module:ItemUnimplemented")
local ImageUnifier = require("Module:ImageUnifier")
local cache = require "mw.ext.LuaCache"
local KEY_PREFIX = "Module:ItemHelper"
local EXP_TIME = 172800

local p = {}

local function getNameAndId(nameOrId, noError)
    if type(nameOrId) == "number" then
        local name = p.getText(ItemPrototype[nameOrId].nameId)

        if (name) then
            local id = ItemId[name:lower()]
            if id ~= nil and id ~= nameOrId then
                return name, nil
            else
                return name, nameOrId
            end
        else
        end
    else
        return nameOrId, p.getId(nameOrId, noError)
    end
end

p.getId = function(name, noError)
    if name == nil or name == "" then
        name = mw.getCurrentFrame():getParent():getTitle()
    end

    name, _ = name:gsub("&#(%d+);", function(n)
        return string.char(n)
    end)

    local cacheKey = KEY_PREFIX .. "getId" .. name
    cache.delete(cacheKey)

    --if (cache.get(cacheKey)) then
    --    local result = cache.get(cacheKey)
    --    return result
    --end

    local id = ItemId[name:lower()]
    
    -- 特殊物品名特判
    if not id then
    	-- Use gsub to lower `Ⅰ` and `Ⅱ`, then try again.
    	subName = (name:gsub("\226\133\160", "ⅰ"):gsub("\226\133\161", "ⅱ"))
		id = ItemId[subName:lower()]
	end

    if id == nil and not noError then
        error("Bad item name: " .. name)
    end

    --cache.set(cacheKey, id, EXP_TIME)
    return id
end

p.getInGameName = function(id)
    local name = p.getText(ItemPrototype[id].nameId)
    return name
end

-- 英维进行了修改
p.getName = function(id)
    --local cacheKey = KEY_PREFIX .. "getName" .. id

    --if (cache.get(cacheKey)) then
    --    local result = cache.get(cacheKey)
    --    return result
    --end

    local name
    
    if (name) then
    else
        name = p.getText(ItemPrototype[id].nameId)

        if (name) then
            if id > 80000000 then
                name = name .. "(制作书)"
            elseif id > 70000000 then
                name = name .. "(家具样式)"
            end
        else
        end
    end

    --cache.set(cacheKey, name, EXP_TIME)
    return name
end

-- 英维进行了修改
p.getName2 = function(id)
    --local cacheKey = KEY_PREFIX .. "getName" .. id

    --if (cache.get(cacheKey)) then
    --    local result = cache.get(cacheKey)
    --    return result
    --end

    local name

    if (name) then
    else
        name = p.getText(ItemPrototype[id].nameId)
    end

    --cache.set(cacheKey, name, EXP_TIME)
    return name
end

p.getSortKey = function(id)
    return ItemPrototype[id].orderIndex * 100000000 + id
end

p.getBaseQuality = function(id)
    local cacheKey = KEY_PREFIX .. "getBaseQuality" .. id

    if (cache.get(cacheKey)) then
        local result = cache.get(cacheKey)
        return result
    end

    local weights = ItemPrototype[id].gradeWeight
    for quality = 0, 3 do
        if weights[quality + 1] > 0 then
            local result = quality
            cache.set(cacheKey, result, EXP_TIME)
            return result
        end
    end
    error("gradeWeight of item " .. id .. " is empty")
end

p.getMaxQuality = function(id)
    if Refine[id] ~= nil then
        return 3
    end
    local weights = ItemPrototype[id].gradeWeight
    for quality = 3, 0, -1 do
        if weights[quality + 1] > 0 then
            return quality
        end
    end
    error("gradeWeight of item " .. id .. " is empty")
end

p.getRefineMaterial = function(id)
    if Refine[id] == nil then
        return nil
    end
    return Refine[id].matsGradeUp[1].id
end

p.hasTag = function(itemId, tag)
	local cacheKey = KEY_PREFIX .. "hasTag" .. itemId

    if (cache.get(cacheKey)) then
        local result = cache.get(cacheKey)
        return result
    end

    local item = ItemPrototype[itemId]
    if not item then
    	return false
    end
    tags = item["itemTag"]
    
    local result = false
    for _, itemTag in ipairs(tags) do
        if itemTag == tag then
            result = true
            break
        end
    end
    
    cache.set(cacheKey, result, EXP_TIME)
    return result
end

p.isImplemented = function(nameOrId)
    local cacheKey = KEY_PREFIX .. "isImplemented" .. nameOrId

    if (cache.get(cacheKey)) then
        cache.delete(cacheKey)
    --    local result = cache.get(cacheKey)
    --    return result
    end

    local name, id = getNameAndId(nameOrId, true)
    local result = true

    if id == nil then
        result = false
    end

    if (result) then
        local item = ItemPrototype[id]
        
        -- 存在报错物品
        if item == nil then
            result = false
        end
        -- 存在报错物品

        if ItemUnimplemented[name:lower()] then
            result = false
        end

        if (result) then
            if id >= 20000000 then
                result = false -- FIXME
            end

            if (result) then
                local desc = p.getText(item.infoId)

                if desc == nil or desc == "" then
                    result = false
                end

                if (result) then
                    if item.maleIconPath:lower() == "null" then
                        result = false
                    end
                else
                end
            else
            end
        else
        end
    else
    end

    --cache.set(cacheKey, result, EXP_TIME)
    return result
end

p.restoreCase = function(name)
    if not name then
    	return ""
    -- TODO: 特殊物品特判
    -- elseif (name == "gordana diary Ⅰ" or name == "gordana diary ⅰ") then
    --     return "Gordana Diary Ⅰ"
    -- elseif (name == "gordana diary Ⅱ" or name == "gordana diary ⅱ") then
    --     return "Gordana Diary Ⅱ"
    else
        local lname = name:lower()
        local id = ItemId[lname]

        if id == nil then
            return name
        end

        local origName = p.getText(ItemPrototype[id].nameId)

        if lname:sub(1, #origName) ~= origName:lower() then
            error(lname .. " is not a lowercase disambiguation name of " .. origName)
        end

        return origName .. lname:sub(#origName + 1)
    end
end

p.addIconAndLink = function(name)
    if (name) then
        local cacheKey = KEY_PREFIX .. "addIconAndLink" .. name

        if (cache.get(cacheKey)) then
            local result = cache.get(cacheKey)
            return result
        end

        if type(name) == "number" then
            name = p.getName(name)
        end

        -- local title = p.restoreCase(name)
        local title = name
        
        if (title) then
            local iconFile = title:gsub(":", "-")
            local icon = ImageUnifier.GetImagesMain({
                iconFile
            }, {
                caption = title,
                link = title
            }, "text", true)

            local result = icon .. "[[" .. title .. "]]"
            cache.set(cacheKey, result, EXP_TIME)
            return result
        else
            return ""
        end
    else
    end
end

p.getSource = function(id, separator)
    local sources = nil
    for _, data in ipairs({ItemSource, ItemSource_2}) do
        if data[id] ~= nil then
            sources = sources or {}
            for k, v in pairs(data[id]) do
                sources[k] = v
            end
        end
    end

    local lines = {}
    local locations = {}

    if sources == nil then
        return ""
    end

    -- FIXME
    if id == 12400061 then
        return Helper.ExpandTemplate("m", {
            "The Childhood Friend"
        })
    end

    if sources["_unknown/mission"] and sources["_unknown/mission"][1] == "1700218" then
        return Helper.ExpandTemplate("m", {
            "Civil Business"
        })
    end

    local noValueSourceTypes = {
        developer = "Letter from the Developers",
        farming = "[[Farming]]",
        fishing = "[[Sandfishing]]",
        gathering = "[[Gathering]]",
        kicking = "[[Kicking]]",
        logging = "[[Logging]]",
        quarrying = "[[Quarrying]]",
        recycle = "[[Recycling]]",
        skiing = "[[Sandrunning]]",
        museum = "[[Catori's_Museum#Donation rewards|Donation reward]]",
        pet = "[[Pets#Pet_care_and_dispatch|Pet]]",
        ranking = "[[Workshop Rank]]",
        salvaging = "[[Salvaging]]",
        constructionJunction = "[[Construction_Junction#Construction_Junction_Catalog|Construction Junction Catalog]]",
        dlc = "[[Downloadable_content|DLC]]",
        kickstarter = "[[Kickstarter]]"
    }

    for source_type, line in pairs(noValueSourceTypes) do
        if sources[source_type] then
            table.insert(lines, line)
        end
    end

    -- these locations are not well understood yet
    -- only show them when there is no other sources
    local badLocations = {
        -- ["Cave"] = 0,
        -- ["Gecko Station"] = 0,
    }

    local mapSourceTypes = {
        -- gathering = "[[Gathering]]",
        -- salvaging = "[[Salvaging]]",
        ruin_abandoned = true,
        ruin_hazard = true,
        treasure = "[[Treasure chest]]"
    }

    for source_type, line in pairs(mapSourceTypes) do
        if sources[source_type] then
            for _, location in ipairs(sources[source_type]) do
                if location == "_main_" then
                    table.insert(lines, line)
                elseif badLocations[location] == 0 then
                    badLocations[location] = 1
                    -- elseif location == "Gecko Station" then
                    -- locations["Gecko Station Ruins"] = true
                else
                    locations[location] = true
                end
            end
        end
    end

    if sources.monster then
        local line = "[[" .. sources.monster[1] .. "]]"
        -- `#sources.monster` is always 0
        for i, _ in ipairs(sources.monster) do
            if i > 1 then
                line = "[[Monsters]]"
                break
            end
        end
        table.insert(lines, line)
    end

    local lv1Machines = {
        ["Tailoring Machine lv1"] = "[[Tailoring Machine lv1|Tailoring Machine]]",
        ["Blender lv1"] = "[[Blender lv1|Blender]]",
        ["Forging Machine lv1"] = "[[Forging Machine lv1|Forging Machine]]",
        ["Primary Jewelry Processing Machine"] = "[[Primary Jewelry Processing Machine|Jewelry Machine]]",
        ["Relic Restoration Machine"] = "[[Relics#Restoring|Relic Restoration]]",
        ["Intermediate Jewelry Processing Machine"] = "[[Intermediate Jewelry Processing Machine|Jewelry Machine]]",
        ["Intermediate Tailoring Machine"] = "[[Intermediate Tailoring Machine|Tailoring Machine]]"
    }

    local valueOnlySourceTypes = {
        store = true,
        assembly = true,
        crafting = true,
        cooking = true,
        container = true,
        delivery = true,
        location = true,
        npc = true, -- marry gift
        mail = true,
        miniGame = true
    }

    for source_type, _ in pairs(valueOnlySourceTypes) do
        if sources[source_type] then
            for _, value in ipairs(sources[source_type]) do
                if lv1Machines[value] ~= nil then
                    table.insert(lines, lv1Machines[value])
                elseif (source_type == "npc") then
                    table.insert(lines, Helper.ExpandTemplate("NPC2", {
                        [1] = value
                    }))
                elseif (source_type == "mail") then
                    table.insert(lines, ImageUnifier.GetImagesMain({
                        "Mail_normal_opened.png"
                    }, {
                        caption = nil,
                        link = nil
                    }, "text", true) .. value)
                elseif value ~= "Vending Machine" then
                    table.insert(lines, "[[" .. value .. "]]")
                end
            end
        end
    end

    local badMissions = {
        ["Flaming Saddles"] = true
    }

    if sources.mission then
        for _, mission in ipairs(sources.mission) do
            if not badMissions[mission] then
                table.insert(lines, Helper.ExpandTemplate("m", {
                    mission
                }))
            end
        end
    end

    if (sources.civilCorpsCommission) then
        table.insert(lines, "[[Civil_Corps#Commisions|Civil Corps Commisions]]")
    end

    local sortLocations = {}
    for location, _ in pairs(locations) do
        table.insert(sortLocations, location)
    end
    table.sort(sortLocations)
    for _, location in ipairs(sortLocations) do
        table.insert(lines, "[[" .. location .. "]]")
    end

    if #lines == 0 then
        for location, flag in pairs(badLocations) do
            if flag == 1 then
                table.insert(lines, "[[" .. location .. "]]")
            end
        end
    end

    if separator == nil then
        return table.concat(lines, "<br>")
    else
        return table.concat(lines, separator)
    end
end

p.learnedFrom = function(id)
    local sources = ItemSourceNew[id]
    if sources == nil then
        return ""
    end
    local lines = p.formatRecipeSources(sources["recipeSources"])
    return table.concat(lines, "<br>")
end

p.mainSources = function(id, separator)
    local sources = ItemSourceNew[id]
    if sources == nil then
        return "未知"
    end
    local lines = p.formatSources(sources["mainSources"])
    if separator == nil then
        return table.concat(lines, "<br>")
    else
        return table.concat(lines, separator)
    end
end

p.otherSources = function(id, separator)
    local sources = ItemSourceNew[id]
    if sources == nil then
        return ""
    end
    local lines = p.formatSources(sources["secondarySources"])
    if separator == nil then
        return table.concat(lines, "<br>")
    else
        return table.concat(lines, separator)
    end
end

p.insertConvertedLines = function(lines, sources, sourceTypes)
    for _, entry in ipairs(sourceTypes) do
        local sourceType, line = entry[1], entry[2]
        if sources[sourceType] then table.insert(lines, line) end
    end
end

p.insertLinkedLines = function(lines, sources, sourceType)
    if sources[sourceType] then
        for _, value in ipairs(sources[sourceType]) do
            table.insert(lines, "[[" .. value .. "]]")
        end
    end
end

p.formatRecipeSources = function(sources)
    local lines = {}
    local simple = {
        { "cooking_experimentation", "[[Cooking|Cooking Experimentation]]" }
    }

    p.insertConvertedLines(lines, sources, simple)

    if sources["machine_acquired"] then
        p.insertLinkedLines(lines, sources, "machine_acquired")
    end

    if sources["share_recipe"] then
        local line = "[[Cooking|Talk Recipes]]"
        for _, value in ipairs(sources["share_recipe"]) do
            line = line .. " ([[" .. value .. "]])"
        end
        table.insert(lines, line)
    end

    local otherSources = p.formatSources(sources)
    for _, line in ipairs(otherSources) do
        table.insert(lines, line)
    end

    return lines
end

p.formatSources = function(sources)
    local lines = {}

    -- Missions and Events
    local unknownMission = false
    if sources.mission then
        for _, mission in ipairs(sources.mission) do
            if string.match(mission, "^Mission %d+$") then
                unknownMission = true
            else
                table.insert(lines, "任务:" .. Helper.ExpandTemplate("m", { mission }))
            end
        end
    end
    
    if sources.event then
        for _, event in ipairs(sources.event) do
            table.insert(lines, "剧情:" .. Helper.ExpandTemplate("e", { event }))
        end
    end

    -- Keep unknown missions at the bottom of the mission list.
    if unknownMission then
        table.insert(lines, "未知任务")
    end

    -- Stores
    p.insertLinkedLines(lines, sources, "store")

    -- Crafting
    local craftingTypes = { 'assembly', 'crafting', 'cooking' }
    for _, craftingType in ipairs(craftingTypes) do
        p.insertLinkedLines(lines, sources, craftingType)
    end

    -- Other Workshop-Related Sources
    local workshopSourceTypes = {
        { "recycling", "[[回收]]" },
        { "ore_refining", "[[原石筛选机]]" },
        { "commissions", "[[订单]]" },
        { "desires", "[[Desires]]" },
        { "guild_ranking", "[[Workshop Rank#Commerce_Guild_Awards|Commerce Guild Awards]]" },
        { "default", "Starting equipment" },
        { "machine_upgrade", "[[Machine Upgrade Kit|Machine Upgrade]]" },
    }
    p.insertConvertedLines(lines, sources, workshopSourceTypes)

    -- Raw Resource Acquisition
    local resourceFarmingSourceTypes = {
        { "farming", "[[种植]]" },
        { "fishing", "[[沙捕]]" },
        { "kicking", "[[踢树]]" },
        { "logging", "[[伐木]]" },
        { "quarrying", "[[挖矿]]" },
        { "salvaging", "[[回收废品]]" }
    }
    p.insertConvertedLines(lines, sources, resourceFarmingSourceTypes)

    -- Gathering (anything you pick up by interacting with it)
    if sources.gathering then
        for _, location in ipairs(sources.gathering) do
            if string.lower(location) == "sandrock" then
                table.insert(lines, "[[Gathering]]")
            else
                table.insert(lines, "[[" .. location .. "]]")
            end
        end
    end

    -- Ruins
    local ruinSourceTypes = { 'ruin_abandoned', 'ruin_hazard' }
    for _, ruinType in ipairs(ruinSourceTypes) do
        p.insertLinkedLines(lines, sources, ruinType)
    end

    -- Treasure Chests
    if sources.treasure then
        for _, location in ipairs(sources.treasure) do
            table.insert(lines, "[[Treasure chest]] ([[" .. location .. "]])")
        end
    end

    -- Monsters
    p.insertLinkedLines(lines, sources, "monster")
    
    local monsterSourceTypes = {
    	{ "enraged_monsters", "[[Enraged monsters]]" }
    }
    p.insertConvertedLines(lines, sources, monsterSourceTypes)
    
	-- Entertainment
    local entertainmentSourceTypes = {
        { "game_center", "[[Game Center]]" },
        { "sand_sledding", "[[Sandrunning]]" },
        { "sand_racing", "[[Sand Buggy Circuit]]" },
        { "museum", "[[Museum#Donation rewards|Donation reward]]" },
        { "festivals", "[[Festivals]]" },
        { "day_of_bright_sun", "[[Day of the Bright Sun]]" },
        { "showdown_at_high_noon", "[[Showdown at High Noon]]" },
        { "party", "[[Party]]" }
    }
    p.insertConvertedLines(lines, sources, entertainmentSourceTypes)

    -- Subscription Delivery Services, Commissions, and Pet Dispatch
    p.insertLinkedLines(lines, sources, "delivery")

    local deliverySourceTypes = {
        { "civil_corps_commission", "[[Civil_Corps#Commisions|Civil Corps commisions]]" },
        { "pet_dispatch", "[[Pets#Pet_care_and_dispatch|Pet dispatch]]" }
    }
    p.insertConvertedLines(lines, sources, deliverySourceTypes)

    -- Container Items
    p.insertLinkedLines(lines, sources, "container")

    -- NPCs
    local npcSourceToLink = {
        { "birthday", "[[Birthday]]" },
        { "marriage", "[[Marriage]]" },
        { "wedding", "[[Marriage#Wedding_gifts|Wedding gift]]" },
        { "new_child", "[[Parenthood#Having_children|New baby gift]]" },
        { "spouse_cooking", "[[Marriage#Cooking|Spouse's cooking]]" },
        { "spouse_gift", Helper.ExpandTemplate("m", { "Gift from your Spouse" }) },
        { "spouse_gift_expecting", Helper.ExpandTemplate("m", { "Speak to your partner" }) }
    }

    if sources.npc then
        for _, entry in ipairs(npcSourceToLink) do
            local sourceType, line = entry[1], entry[2]
            if sources.npc[sourceType] then
                for _, npc in ipairs(sources.npc[sourceType]) do
                	local npc_line
                    if npc == "all spouses" or npc == "female spouses" or npc == "male spouses" then
                        npc_line = line .. " (" .. npc .. ")"
                    else
                        npc_line = line .. " ([[" .. npc .. "]])"
                    end
                    table.insert(lines, npc_line)
                end
            end
        end

        if sources.npc["conversation"] then
            for _, npc in ipairs(sources.npc["conversation"]) do
                table.insert(lines, "[[" .. npc .. "]]")
            end
        end
    end

    -- Mail
    if sources.mail then
        for _, value in ipairs(sources.mail) do
            local text, id = value[1], value[2]
            table.insert(lines, ImageUnifier.GetImagesMain({ "Mail_normal_opened.png" }, { caption = id, link = nil }, "text", true) .. text)
        end
    end

    -- DLC and Kickstarter
    local extrasSourceTypes = {
        { "dlc", "[[Downloadable_content|DLC]]" },
        { "kickstarter", "[[Kickstarter]]" }
    }
    p.insertConvertedLines(lines, sources, extrasSourceTypes)

    return lines
end

p.isFood = function(itemId)
    for i, t in ipairs(ItemPrototype[itemId].tags) do
        if (ItemPrototype[itemId].tags[i] == 2 or ItemPrototype[itemId].tags[i] == "Food") then
            return true
        end
    end

    return false
end

p.is_equipment = function(itemId)
    local itemPrototype = ItemPrototype[itemId]

    if (itemPrototype) then
        for tagIndex, tag in pairs(itemPrototype.tags) do
            if (tag == "Equipment") then
                return true
            else
            end
        end
    else
    end

    return false
end

p.getText = function(id)
	return Text[id]
end

p.debugId = function(itemName)
	mw.log(p.getId(itemName))
end

p.debug = function()
	-- Camo Rescue Team Boots
    mw.logObject(p.mainSources(12310015))
    -- Token
    mw.logObject(p.mainSources(19999997))
    -- Water
    mw.logObject(p.otherSources(19999998, ","))
    -- Vintage shotgun
    mw.logObject(p.learnedFrom(11000021))
end

return p