置顶公告:【置顶】关于临时开启评论区所有功能的公告(2022.10.22) | 【置顶】关于本站Widget恢复使用的公告
  • 你好~!欢迎来到萌娘百科镜像站!如需查看或编辑,请联系本站管理员注册账号。
  • 本镜像站和其他萌娘百科的镜像站无关,请注意分别。

Module:MomoTalk

贴贴♀百科,万娘皆可贴的百科全书!转载请标注来源页面的网页链接,并声明引自贴贴百科。内容不可商用。
跳到导航 跳到搜索
Template-info.svg 模块文档  [查看] [编辑] [历史] [刷新]

用于{{MomoTalkPro}}的模块,详细用法请参见模板文档。

local p = {}

local getArgs = require('Module:Arguments').getArgs

local toggle_id = 0
local momo_id = 0
local switch_id = 0
local branch_id = -1
local talkers = {}
local talkers_avatar = {}
local arg_i = 1  -- 全局迭代索引,记录当前处理到的参数位置

local function increase_i(amount)  -- 增加索引值,数量为消息参数的数量
    arg_i = arg_i + amount
end

local function is_nil_or_empty(string)
    if string == nil then
        return true
    end
    if mw.text.trim(string) == "" then
        return true
    end
    return false
end

local function handle_talkers(args)
    local i = 1
    while args["talker_" .. i] ~= nil do
        talkers[i] = args["talker_" .. i]
        talkers_avatar[i] = args["talker_avatar_" .. i]
        i = i + 1
    end
end

local function handle_header(args)
    local output = ""
    local toggle_str = "mw-collapsible"
    local width = args["width"] or "min(600px, 95%)"
    local main_style = args["main_style"] or ""
    local inner_style = args["inner_style"] or ""
    if not is_nil_or_empty(args["no-header"]) then
        toggle_str = ""
    end
    output = output .. mw.ustring.format("<div id=\"mw-customcollapsible-%d\" class=\"momo-container %s\" style=\"width: %s;\">", toggle_id, toggle_str, width)  -- 最外层div
    output = output .. mw.ustring.format("<div class=\"momo-main\" style=\"box-shadow: 0 2px 3px #0002; %s\">", main_style)  -- 主框架div
    if not is_nil_or_empty(args["no-header"]) then  -- 优化no-header显示效果
        output = output .. "<div style=\"height:5px;\"></div>"
        return output
    end
    output = output .. mw.ustring.format("<div class=\"momo-header\"><div class=\"momo-header-img\">[[File:MomoTalkLogo.png|link=|150px]]</div><div class=\"momo-header-cross mw-customtoggle-%d\">×</div></div>", toggle_id)
    output = output .. mw.ustring.format("<div style=\"%s\">", inner_style) -- 内层自定义样式div
    return output
end

local function handle_activity(args) -- 参数格式:|a|到此已读
    increase_i(1)
    return mw.ustring.format("<div class=\"momo-banner\">%s</div>", args[arg_i])
end

local function check_continue(args, talker) -- 辅助函数,检查下一个消息类型是否为学生消息且说话人是否是同一个人
    if (args[arg_i + 1] == "s" or args[arg_i + 1] == "student") and tonumber(args[arg_i + 2]) == talker then
        return true
    end
    return false
end

local function handle_student_message(args) -- 参数格式:|s|1|在吗?
    local output = "<div class=\"momo-msg-student\">"
    local talker_id = tonumber(args[arg_i + 1])
    local talker_name = talkers[talker_id] or ""
    local talker_avatar = talkers_avatar[talker_id] or ""
    output = output .. mw.ustring.format("<div class=\"momo-avatar\">%s</div>", talker_avatar)  -- 头像
    output = output .. mw.ustring.format("<div class=\"momo-msg-main\"><div class=\"momo-name\">%s</div><div class=\"momo-msg-pack\">", talker_name)  -- 名字
    output = output .. mw.ustring.format("<div class=\"momo-msg\" style=\"width: fit-content;\">%s</div>", args[arg_i + 2])  -- 消息
    increase_i(2)
    while check_continue(args, talker_id) do
        increase_i(1)
        output = output .. mw.ustring.format("<div class=\"momo-msg\" style=\"width: fit-content;\">%s</div>", args[arg_i + 2]) -- 同一说话人的下一条消息
        increase_i(2)
    end
    output = output .. "</div></div></div>"
    return output
end

local function handle_student_image_message(args) -- 参数格式:|i|1|BA_Shiroko_Ridingsuit.png|300px
    local output = "<div class=\"momo-msg-student\">"
    local talker_id = tonumber(args[arg_i + 1])
    local talker_name = talkers[talker_id] or ""
    local talker_avatar = talkers_avatar[talker_id] or ""
    local width = args[arg_i + 3]
    if is_nil_or_empty(width) then
        width = "300px"
    end
    output = output .. mw.ustring.format("<div class=\"momo-avatar\">%s</div>", talker_avatar)  -- 头像
    output = output .. mw.ustring.format("<div class=\"momo-msg-main\"><div class=\"momo-name\">%s</div>", talker_name)  -- 名字
    output = output .. mw.ustring.format("<div class=\"momo-msg-img\">[[File:%s|%s]]</div>", args[arg_i + 2], width)  -- 消息
    output = output .. "</div></div>"
    increase_i(3)
    return output
end

local function check_continue_teacher(args)  -- 辅助函数,检查下一个消息类型是否仍为老师消息

end

local function handle_teacher_message(args)  -- 参数格式:|t|在哦
    local output = "<div class=\"momo-msg-sensei\">"
    output = output .. "<div class=\"momo-msg-pack\">"
    output = output .. mw.ustring.format("<div class=\"momo-msg\" style=\"width: fit-content;\">%s</div>", args[arg_i + 1])  -- 消息
    increase_i(1)
    while check_continue_teacher(args) do
        output = output .. mw.ustring.format("<div class=\"momo-msg\" style=\"width: fit-content;\">%s</div>", args[arg_i + 1])  -- 消息
        increase_i(1)
    end
    output = output .. "</div></div>"
    return output
end

local function handle_teacher_image_message(args)  -- todo
    return ""
end

local function handle_choose(args)  -- 参数格式:|c|回复|回复1|回复2|end
    local output = "<div class=\"momo-msg-sensei\">"
    local branch = 0
    local title = args[arg_i + 1]
    if is_nil_or_empty(title) then
        title = "回复"
    end
    output = output .. "<div class=\"momo-box momo-box-reply\" style=\"width: min(480px, 90%);\">"
    output = output .. mw.ustring.format("<div class=\"momo-title\">%s</div><hr />", title)
    output = output .. mw.ustring.format("<div class=\"textToggleDisplayButtons\" data-key-0=\"@radio\" data-value-0=\"1\" data-key-1=\"@default\" data-value-1=\"momotalk-%d-%d-%d\">", momo_id, switch_id, branch)
    branch_id = -1
    local increase = 2
    while true do
        local message = args[arg_i + increase]
        output = output .. mw.ustring.format("<span data-order=\"%d\" data-key=\"momotalk-%d-%d-%d\"><span class=\"textToggleDisplayButtonLabelText on\"><span class=\"momo-choose-item\" style=\"box-shadow: 0 2px 3px #0002;\">%s</span></span><span class=\"textToggleDisplayButtonLabelText off\"><span class=\"momo-choose-item\" style=\"box-shadow: 0 2px 3px #0002;\">%s</span></span></span>", branch, momo_id, switch_id, branch, message, message)
        branch = branch + 1
        increase = increase + 1
        if args[arg_i + increase] == "end" then
            break
        end
    end
    switch_id = switch_id + 1
    increase_i(increase)
    output = output .. "</div></div></div>"
    return output
end

local function handle_branch(args)  -- 参数格式:|b
    branch_id = branch_id + 1
    return mw.ustring.format("<div class=\"textToggleDisplay hidden\" data-id=\"momotalk-%d-%d-%d\">", momo_id, switch_id - 1, branch_id)
end

local function handle_branch_end(args)  -- 参数格式:|e
    return "</div>"
end

local function handle_kizuna(args)  -- 参数格式:|k|羁绊剧情|前往羁绊剧情
    local output = "<div class=\"momo-msg-sensei\">"
    local title = args[arg_i + 1]
    if is_nil_or_empty(title) then
        title = "羁绊剧情"
    end
    output = output .. "<div class=\"momo-box momo-box-love\" style=\"width: min(480px, 90%);\">"
    output = output .. mw.ustring.format("<div class=\"momo-title\">%s</div><hr />", title)
    output = output .. mw.ustring.format("<div class=\"momo-choose-item\" style=\"box-shadow: 0 2px 3px #0002;\">%s</div>", args[arg_i + 2])
    output = output .. "</div></div>"
    increase_i(2)
    return output
end

local function handle_message(args)
    local output = ""
    while args[arg_i] ~= nil do
        local type = args[arg_i]
        if type == "a" or type == "activity" then  -- 处理横栏提示
            output = output .. handle_activity(args)
        elseif type == "s" or type == "student" or type == "n" or type == "new" then -- 处理学生信息
            output = output .. handle_student_message(args)
        elseif type == "i" or type == "image" then  -- 处理学生图片信息
            output = output .. handle_student_image_message(args)
        elseif type == "t" or type == "teacher" or type == "nt" or type == "new_teacher" then  -- 处理老师信息
            output = output .. handle_teacher_message(args)
        elseif type == "ti" or type == "teacher_image" then  -- 处理老师图片信息
            output = output .. handle_teacher_image_message(args)
        elseif type == "c" or type == "choose" then  -- 处理对话选项
            output = output .. handle_choose(args)
        elseif type == "b" or type == "branch" then  -- 处理对话分支
            output = output .. handle_branch(args)
        elseif type == "e" or type == "end" then  -- 处理分支结束
            output = output .. handle_branch_end(args)
        elseif type == "k" or type == "kizuna" then  -- 处理羁绊剧情
            output = output .. handle_kizuna(args)
        else
            mw.log(mw.ustring.format("[Warning] 位于%d处的匿名参数【%s】无法被解析!", arg_i, type))
        end
        -- 如果参数种类无法被识别,则跳过此参数
        increase_i(1)
    end
    return output
end

function p.main(_frame)
    local args = getArgs(_frame, { removeBlanks = false, parentOnly = true })
    toggle_id = tonumber(_frame:callParserFunction("#var", "toggle_id", 0)) or 0
    _frame:callParserFunction("#vardefine", "toggle_id", toggle_id + 1)
    momo_id = tonumber(_frame:callParserFunction("#var", "momotalk_id", 0)) or 0
    _frame:callParserFunction("#vardefine", "momotalk_id", momo_id + 1)
    return p._main(args)
end

function p._main(args)
    handle_talkers(args)
    local output = handle_header(args)
    output = output .. handle_message(args)
    output = output .. "</div></div></div>" -- 关闭handle_header中的三个div
    return output
end

return p