维护提醒
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