维护提醒

BWIKI 全站将于 9 月 3 日(全天)进行维护,期间无法编辑任何页面或发布新的评论。

全站通知:

模块:Events/Preconditions

来自星露谷物语维基
跳到导航 跳到搜索
[ 创建 | 刷新 ]文档页面
当前模块文档缺失,需要扩充。
local Helper = require("Module:Helper")
local EventsData = Helper.LazyLoad("Module:Events/data")

local p = {}

-- 前置条件别名映射表
local aliasMap = {
    -- World/Context
    u = "DayOfMonth",
    N = "GoldenWalnuts",
    L = "InUpgradedHouse",
    v = "NPCVisible",
    p = "NpcVisibleHere",
    r = "Random",
    t = "Time",
    w = "Weather",
    ["*"] = "WorldState",
    y = "Year",
    G = "GameStateQuery",

    -- Current player
    q = "ChoseDialogueAnswers",
    D = "Dating",
    m = "EarnedMoney",
    c = "FreeInventorySlots",
    f = "Friendship",
    g = "Gender",
    i = "HasItem",
    M = "HasMoney",
    n = "LocalMail",
    h = "MissingPet",
    b = "ReachedMineBottom",
    R = "Roommate",
    e = "SawEvent",
    S = "SawSecretNote",
    s = "Shipped",
    O = "Spouse",
    B = "SpouseBed",
    a = "Tile",

    -- Host player
    C = "CommunityCenterOrWarehouseDone",
    j = "DaysPlayed",
    Hn = "HostMail",
    ["*n"] = "HostOrLocalMail",
    H = "IsHost",
    J = "JojaBundlesDone",

    -- Deprecated (for compatibility)
    x = "SendMail",
    A = "NotActiveDialogueEvent",
    X = "NotCommunityCenterOrWarehouseDone",
    d = "NotDayOfWeek",
    F = "NotFestivalDay",
    Hl = "NotHostMail",
    ["*l"] = "NotHostOrLocalMail",
    l = "NotLocalMail",
    Rf = "NotRoommate",
    k = "NotSawEvent",
    z = "NotSeason",
    o = "NotSpouse",
    U = "NotUpcomingFestival"
}

-- 中文描述映射表
local descriptionMap = {
    -- World/Context
    DayOfMonth = function(args)
        return "今天是" .. table.concat(args, "日或") .. "日"
    end,
    DayOfWeek = function(args)
        local dayMap = {
            Mon = "周一",
            Monday = "周一",
            Tue = "周二",
            Tuesday = "周二",
            Wed = "周三",
            Wednesday = "周三",
            Thu = "周四",
            Thursday = "周四",
            Fri = "周五",
            Friday = "周五",
            Sat = "周六",
            Saturday = "周六",
            Sun = "周日",
            Sunday = "周日"
        }
        local days = {}
        for _, day in ipairs(args) do
            table.insert(days, dayMap[day] or day)
        end
        return "今天是" .. table.concat(days, "或")
    end,
    FestivalDay = function()
        return "今天是节日"
    end,
    GoldenWalnuts = function(args)
        return "玩家总共已找到至少 " .. args[1] .. " 个金核桃(包括已花费的)"
    end,
    InUpgradedHouse = function(args)
        local level = args[1] or "2"
        return "当前位置是农舍或小屋,并且已升级至少 " .. level .. " 次"
    end,
    NPCVisible = function(args)
        return "NPC " .. args[1] .. " 在任何位置都可见"
    end,
    NpcVisibleHere = function(args)
        return "NPC " .. args[1] .. " 在当前位置可见"
    end,
    Random = function(args)
        local percent = math.floor(tonumber(args[1]) * 100)
        return "随机触发(" .. percent .. "% 概率)"
    end,
    Season = function(args)
        local seasonMap = {
            Spring = "春季",
            Summer = "夏季",
            Fall = "秋季",
            Winter = "冬季"
        }
        local seasons = {}
        for _, season in ipairs(args) do
            table.insert(seasons, seasonMap[season] or season)
        end
        return "当前季节是" .. table.concat(seasons, "或")
    end,
    Time = function(args)
        local function formatTime(time)
            local hour = math.floor(time / 100)
            local minute = time % 100
            if hour >= 24 then
                hour = hour - 24
            end
            return string.format("%02d:%02d", hour, minute)
        end
        return "当前时间在 " .. formatTime(tonumber(args[1])) .. " 到 " .. formatTime(tonumber(args[2])) ..
                   " 之间"
    end,
    UpcomingFestival = function(args)
        return args[1] .. " 天内将有节日"
    end,
    Weather = function(args)
        local weatherMap = {
            rainy = "雨天",
            sunny = "晴天"
        }
        return "当前天气是" .. (weatherMap[args[1]] or args[1])
    end,
    WorldState = function(args)
        return "世界状态 " .. args[1] .. " 处于激活状态"
    end,
    Year = function(args)
        if args[1] == "1" then
            return "必须在第一年"
        else
            return "年份至少为第 " .. args[1] .. " 年"
        end
    end,
    GameStateQuery = function(args)
        return "游戏状态查询:" .. table.concat(args, " ")
    end,
    ActiveDialogueEvent = function(args)
        return "特殊对话事件 " .. args[1] .. " 正在进行中"
    end,

    -- Current player
    ChoseDialogueAnswers = function(args)
        return "当前玩家已选择对话答案:" .. table.concat(args, "、")
    end,
    Dating = function(args)
        return "当前玩家正在与 " .. args[1] .. " 约会"
    end,
    EarnedMoney = function(args)
        return "当前玩家已赚取至少 " .. args[1] .. " 金币(包括已花费的)"
    end,
    FreeInventorySlots = function(args)
        return "当前玩家至少有 " .. args[1] .. " 个空闲背包槽位"
    end,
    Friendship = function(args)
        local result = {}
        for i = 1, #args, 2 do
            local name = args[i]
            local points = args[i + 1]
            local hearts = math.floor(tonumber(points) / 250)
            table.insert(result, "与 " .. name .. " 至少有 " .. hearts .. " 心好感度")
        end
        return table.concat(result, ",并且")
    end,
    Gender = function(args)
        if args[1]:lower() == "male" then
            return "当前玩家是男性"
        else
            return "当前玩家不是男性"
        end
    end,
    HasItem = function(args)
        return "当前玩家背包中有物品 " .. args[1]
    end,
    HasMoney = function(args)
        return "当前玩家至少有 " .. args[1] .. " 金币"
    end,
    LocalMail = function(args)
        return "当前玩家已收到邮件 " .. args[1]
    end,
    MissingPet = function(args)
        if args[1] then
            return "当前玩家尚未获得宠物,且偏好匹配 " .. args[1]
        else
            return "当前玩家尚未获得宠物"
        end
    end,
    ReachedMineBottom = function(args)
        local times = args[1] or "1"
        return "当前玩家已到达矿井底部至少 " .. times .. " 次"
    end,
    Roommate = function()
        return "当前玩家与任何NPC是室友关系"
    end,
    SawEvent = function(args)
        return "当前玩家已观看过事件:" .. table.concat(args, "或")
    end,
    SawSecretNote = function(args)
        return "当前玩家已看过秘密纸条 " .. args[1]
    end,
    Shipped = function(args)
        local result = {}
        for i = 1, #args, 2 do
            local item = args[i]
            local count = args[i + 1]
            table.insert(result, "已运输 " .. item .. " 至少 " .. count .. " 个")
        end
        return table.concat(result, ",并且")
    end,
    Skill = function(args)
        local skillMap = {
            Combat = "战斗",
            Farming = "农业",
            Fishing = "钓鱼",
            Foraging = "觅食",
            Luck = "幸运",
            Mining = "采矿"
        }
        local skill = skillMap[args[1]] or args[1]
        return "当前玩家的" .. skill .. "技能至少达到 " .. args[2] .. " 级"
    end,
    Spouse = function(args)
        return "当前玩家已与 " .. args[1] .. " 结婚或订婚"
    end,
    SpouseBed = function()
        return "当前玩家的房子里有双人床(或室友情况下有单人床,但室友不是Krobus)"
    end,
    Tile = function(args)
        local positions = {}
        for i = 1, #args, 2 do
            local x, y = args[i], args[i + 1]
            table.insert(positions, "(" .. x .. ", " .. y .. ")")
        end
        return "当前玩家站在位置:" .. table.concat(positions, "或")
    end,

    -- Host player
    CommunityCenterOrWarehouseDone = function()
        return "社区中心或Joja仓库已完成"
    end,
    DaysPlayed = function(args)
        return "玩家已游玩至少 " .. args[1] .. " 天"
    end,
    HostMail = function(args)
        return "主机玩家已收到邮件 " .. args[1]
    end,
    HostOrLocalMail = function(args)
        return "主机玩家或当前玩家已收到邮件 " .. args[1]
    end,
    IsHost = function()
        return "当前玩家是主机玩家(如果处于多人联机模式)"
    end,
    JojaBundlesDone = function()
        return "所有Joja包裹已完成"
    end,

    -- Deprecated conditions (for compatibility)
    SendMail = function(args)
        return "发送邮件 " .. args[1] .. "(已弃用的条件)"
    end,
    NotActiveDialogueEvent = function(args)
        return "特殊对话事件 " .. args[1] .. " 未在进行中"
    end,
    NotCommunityCenterOrWarehouseDone = function()
        return "社区中心和Joja仓库都未完成"
    end,
    NotDayOfWeek = function(args)
        local dayMap = {
            Mon = "周一",
            Monday = "周一",
            Tue = "周二",
            Tuesday = "周二",
            Wed = "周三",
            Wednesday = "周三",
            Thu = "周四",
            Thursday = "周四",
            Fri = "周五",
            Friday = "周五",
            Sat = "周六",
            Saturday = "周六",
            Sun = "周日",
            Sunday = "周日"
        }
        local days = {}
        for _, day in ipairs(args) do
            table.insert(days, dayMap[day] or day)
        end
        return "今天不是" .. table.concat(days, "或")
    end,
    NotFestivalDay = function()
        return "今天不是节日"
    end,
    NotHostMail = function(args)
        return "主机玩家未收到邮件 " .. args[1]
    end,
    NotHostOrLocalMail = function(args)
        return "主机玩家和当前玩家都未收到邮件 " .. args[1]
    end,
    NotLocalMail = function(args)
        return "当前玩家未收到邮件 " .. args[1]
    end,
    NotRoommate = function()
        return "当前玩家与任何NPC都不是室友关系"
    end,
    NotSawEvent = function(args)
        return "当前玩家未观看过事件:" .. table.concat(args, "或")
    end,
    NotSeason = function(args)
        local seasonMap = {
            Spring = "春季",
            Summer = "夏季",
            Fall = "秋季",
            Winter = "冬季"
        }
        local seasons = {}
        for _, season in ipairs(args) do
            table.insert(seasons, seasonMap[season] or season)
        end
        return "当前季节不是" .. table.concat(seasons, "或")
    end,
    NotSpouse = function(args)
        return "当前玩家未与 " .. args[1] .. " 结婚或订婚"
    end,
    NotUpcomingFestival = function(args)
        return args[1] .. " 天内没有节日"
    end
}

-- 否定条件的自然语言映射
local negationMap = {
    Weather = function(args)
        local weatherMap = {
            rainy = "雨天",
            sunny = "晴天"
        }
        return "当前天气不是" .. (weatherMap[args[1]] or args[1])
    end,
    Season = function(args)
        local seasonMap = {
            Spring = "春季",
            Summer = "夏季",
            Fall = "秋季",
            Winter = "冬季"
        }
        local seasons = {}
        for _, season in ipairs(args) do
            table.insert(seasons, seasonMap[season] or season)
        end
        return "当前季节不是" .. table.concat(seasons, "或")
    end,
    SawEvent = function(args)
        return "当前玩家未观看过事件:" .. table.concat(args, "或")
    end,
    FestivalDay = function()
        return "今天不是节日"
    end,
    DayOfWeek = function(args)
        local dayMap = {
            Mon = "周一",
            Monday = "周一",
            Tue = "周二",
            Tuesday = "周二",
            Wed = "周三",
            Wednesday = "周三",
            Thu = "周四",
            Thursday = "周四",
            Fri = "周五",
            Friday = "周五",
            Sat = "周六",
            Saturday = "周六",
            Sun = "周日",
            Sunday = "周日"
        }
        local days = {}
        for _, day in ipairs(args) do
            table.insert(days, dayMap[day] or day)
        end
        return "今天不是" .. table.concat(days, "或")
    end,
    LocalMail = function(args)
        return "当前玩家未收到邮件 " .. args[1]
    end,
    HostMail = function(args)
        return "主机玩家未收到邮件 " .. args[1]
    end,
    HostOrLocalMail = function(args)
        return "主机玩家和当前玩家都未收到邮件 " .. args[1]
    end,
    Spouse = function(args)
        return "当前玩家未与 " .. args[1] .. " 结婚或订婚"
    end,
    Roommate = function()
        return "当前玩家与任何NPC都不是室友关系"
    end,
    CommunityCenterOrWarehouseDone = function()
        return "社区中心和Joja仓库都未完成"
    end,
    UpcomingFestival = function(args)
        return args[1] .. " 天内没有节日"
    end,
    ActiveDialogueEvent = function(args)
        return "特殊对话事件 " .. args[1] .. " 未在进行中"
    end
}

-- 解析单个前置条件
function parsePrecondition(precondition)
    -- 处理否定前缀
    local isNegated = false
    if precondition:sub(1, 1) == "!" then
        isNegated = true
        precondition = precondition:sub(2)
    end

    -- 分割参数
    local parts = {}
    for part in precondition:gmatch("[^%s]+") do
        table.insert(parts, part)
    end

    if #parts == 0 then
        return ""
    end

    local condition = parts[1]
    local args = {}
    for i = 2, #parts do
        table.insert(args, parts[i])
    end

    -- 检查是否是别名
    if aliasMap[condition] then
        condition = aliasMap[condition]
    end

    -- 获取描述
    local description = ""
    if isNegated and negationMap[condition] then
        -- 使用自然的否定描述
        description = negationMap[condition](args)
    elseif descriptionMap[condition] then
        description = descriptionMap[condition](args)
        -- 如果是否定但没有专门的否定映射,使用通用否定前缀
        if isNegated then
            description = "不满足:" .. description
        end
    else
        -- 未知条件,返回原始文本
        description = "未知条件:" .. precondition
    end

    return description
end

-- 解析完整的事件key
function parseEventKey(eventKey)
    -- 分割事件ID和前置条件
    local parts = {}
    for part in eventKey:gmatch("[^/]+") do
        table.insert(parts, part)
    end

    if #parts == 0 then
        return "无效的事件key"
    end

    local eventId = parts[1]
    local result = "事件 " .. eventId

    if #parts == 1 then
        return result .. ":无前置条件"
    end

    -- 解析所有前置条件
    local conditions = {}
    for i = 2, #parts do
        if parts[i] ~= "" then -- 忽略空字符串
            local condition = parsePrecondition(parts[i])
            if condition ~= "" then
                table.insert(conditions, condition)
            end
        end
    end

    if #conditions == 0 then
        return result .. ":无前置条件"
    end

    return result .. ":" .. table.concat(conditions, ",并且")
end

p.condition = function(frame)
    local args = frame.args or frame
    local eventId = args[1]

    if not eventId or eventId == "" then
        return "<!-- 未提供事件编号 -->"
    end

    -- 在所有地点查找事件
    if not EventsData then
        return "<!-- EventsData 未加载 -->"
    end

    local foundEventKey = nil
    local foundLocation = nil

    -- 遍历所有地点寻找包含指定事件ID的事件key
    for locationName, locationData in pairs(EventsData) do
        if type(locationData) == "table" then
            for eventKey, eventScript in pairs(locationData) do
                -- 检查事件key是否以事件ID开头(后面跟着/或者完全匹配)
                if eventKey == eventId or eventKey:match("^" .. eventId .. "/") then
                    foundEventKey = eventKey
                    foundLocation = locationName
                    break
                end
            end
            if foundEventKey then
                break
            end
        end
    end

    -- 如果没找到事件,返回错误信息
    if not foundEventKey then
        return "<!-- 未找到事件编号 " .. eventId .. " -->"
    end

    -- 解析找到的完整事件key
    local description = parseEventKey(foundEventKey)
    
    -- 添加位置信息
    if foundLocation then
        description = description .. "(位置:" .. foundLocation .. ")"
    end
    
    return description
end

return p