The Binding of Isaac: Rebirth

The Binding of Isaac: Rebirth

Mod配置菜单(中文版)
frto027  [developer] 22 May, 2021 @ 6:14am
mod接口说明
这是在原版基础上新增的翻译API用法,写给mod作者的

中文版的MCM可以直接显示中文内容,直接使用原版MCM接口就可以了(如果有乱码,将lua文件保存为utf-8编码即可)。使用这两个方法来判断是否为中文版的MCM:

判断方法1
为避免一些不必要的麻烦,建议使用第一种方式来检测并使用ModConfigMenu。

如果你的mod后于此mod加载(加载顺序按照游戏mods菜单顺序,与mod名字有关)MCM会留下一个ModConfigMenu的全局变量,因此可以直接使用下面的逻辑去判断:
if ModConfigMenu then -- MCM已加载 if ModConfigMenu.i18n == "Chinese" then -- MCM中文版已加载 end end

判断方法2

如果你的mod先于MCM被加载(正常命名的mod比较少见),就可能需要手动加载MCM。
比如EID中,是这样加载MCM的:
local MCMLoaded, MCM = pcall(require, "scripts.modconfig") if MCMLoaded then -- MCM已加载 if MCM.i18n == "Chinese" then -- MCM中文版已加载 end end


非必要的话到这里就可以了,后续是翻译的接口

如果想要给现有的mod菜单做汉化(比如EID汉化包),使用后面这些接口就会方便一些。

在设计上,翻译接口不会改变原始mod的功能,比起直接修改原始mod,这可以避免大部分的兼容问题。这些接口是MCM中文版新增的,需要使用前面的方法判断是否为中文版后再使用。

后续新增的翻译API的典型用法可参考Max EID汉化中的mcm_cn.lua这个文件的写法。

使用下面的API设置菜单、子菜单的翻译名称
ModConfigMenu.SetCategoryNameTranslate("菜单名", "菜单翻译名") ModConfigMenu.SetSubcategoryNameTranslate("菜单名", "子菜单名","子菜单译名")

使用下面的API设置菜单、子菜单的描述信息翻译
ModConfigMenu.SetCategoryInfoTranslate("菜单名", "描述信息翻译") ModConfigMenu.SetSubcategoryInfoTranslate("菜单名","子菜单名", "描述信息翻译")

接下来是菜单项的翻译,MCM支持不同种类的文本表示方式(function、table、string),对于不同的表示方式,需要使用不同的api接口进行翻译。

各个菜单项的翻译包含Display、Info、Popup三个可翻译内容。如果没有翻译版本,就会使用原版的函数作为渲染显示,但如果有翻译,就会忽略原始的函数去使用翻译的函数。

区分不同类型的菜单项目

由于MCM支持多种菜单项的增加方式,在翻译之前需要能够区分清楚,要翻译的菜单项属于哪种方式添加的,来决定调用哪一个翻译接口。这一步需要阅读原始mod的相关位置,或者手动测试应当使用哪一个翻译接口。

对于每种内容,MCM支持function、table、string三种类型的菜单。

function
你可能在EID的源代码中看到这样的写法:
MCM.AddSetting("EID","General",{... Display = function() return "xxx" .. (x + y) end }
这里的Display就是一个函数,它被频繁调用,返回值显示在界面上,菜单项动态生成。

string
string类型是指下面的写法(菜单项固定不变):
MCM.AddText("EID","Display","xxxx")
或者
MCM.AddSetting("EID","General",{... Display = "xxxx" }
table
然后还有table的类型,也就是“数组”:
MCM.AddSetting("EID","General",{... Info= {"Info line 1","Info line 2"} }
翻译api

table/string

对于table和string的类型,由于是完整的字符串,我们可以使用下面的函数对每个独立的字符串进行严格匹配:
-- 直接写用法 ModConfigMenu.TranslateOptionsDisplayTextWithTable("菜单名","子菜单名",{ ["原始字符串1"] = "翻译字符串1", ["原始字符串2"] = "翻译字符串2", ["xxxx"] = "yyyy", ... }
子菜单名可以省略,表示没有子菜单
ModConfigMenu.TranslateOptionsDisplayTextWithTable("菜单名",{ ... })
function
对于function的写法,菜单项输出没有一个固定的值,但我们可以对原始Display函数的返回值进行查找和替换(使用lua的string.gsub,支持通配符),然后显示出来(每次函数返回值都会按照顺序去对所有pattern做查找替换,存在缓冲以提升性能)。
ModConfigMenu.TranslateOptionsDisplayWithTable("菜单名","子菜单名",{ {"pattern 1","result 1"}, {"pattern 2","result 2"}, ... }
pattern的写法看这里[www.lua.org]
一般,匹配“abcd”的pattern就是“abcd”本身,但如果pattern中有这些特殊符号:“( ) . % + - * ? [ ^ $”,就需要在它们前面加百分号。比如匹配"speed is 46%, costs $223(okay)"就需要写成"speed is 46%%, costs %$223%(okay%)"。

子菜单名可以省略,表示没有子菜单
ModConfigMenu.TranslateOptionsDisplayWithTable("菜单名",{{...},{...},...})
其他项目的翻译

Info
Info也就是MCM界面下面显示的描述信息。同样给出前面的两种翻译api。

提供针对菜单项的Info的函数(子菜单名可省略):
ModConfigMenu.TranslateOptionsInfoTextWithTable("菜单名","子菜单名",{ ["xxx"] = "yyy", } ModConfigMenu.TranslateOptionsInfoWithTable("菜单名","子菜单名",{ {"pattern 1","result 1"} })
对于table的用法,上面的xxx可以写table内的字符串,进行严格匹配。


Popup
Popup是弹出菜单(比如按键设置的弹窗),尽管比较少见,但也给出两种翻译方式:

提供针对菜单项的Popup的函数(子菜单名可省略):
ModConfigMenu.TranslateOptionsPopupTextWithTable("菜单名","子菜单名",{ ["xxx"] = "yyy", } ModConfigMenu.TranslateOptionsPopupWithTable("菜单名","子菜单名",{ {"pattern 1","result 1"} })
function的自定义处理
这些api可以使用自己的函数对function类型的菜单项进行处理,对于同一个子菜单,只能二选一地使用前面的pattern接口或者下面的function接口,不支持同时使用。
提供下面的函数,可以对function类型的值做任意处理(无缓存):
ModConfigMenu.TranslateOptionsDisplayWithFunc("菜单名","子菜单名",func) ModConfigMenu.TranslateOptionsInfoWithFunc("菜单名","子菜单名",func) ModConfigMenu.TranslateOptionsPopupWithFunc("菜单名","子菜单名",func)
这里的func是一个自己定义的函数,输入是原始内容(一个参数,是原来的Display函数返回的值),返回翻译内容(新的值)。
Last edited by frto027; 7 Dec, 2024 @ 8:43am
< >
Showing 1-2 of 2 comments
frto027  [developer] 7 Dec, 2024 @ 8:39am 
提示:皮肤/字体api尚未经过充分测试,可能存在bug
皮肤和字体接口
当前版本增加了皮肤和mod接口,这能够允许其它mod提供字体和皮肤供MCM中文版使用。玩家需要在Mod配置菜单的皮肤/字体选项中切换后才能使用。这些接口位于ModConfigMenu.Skin,您在使用前应该检查这个对象是否为nil。

新增字体
以MCM中文版本身增加的字体为例,您也可以使用类似以下方式向MCM中文版提供字体。其中LoadFontFile返回一个游戏内的Font对象,应当由您自行实现。此外,字体也可以通过SkinArg来覆盖绘图过程中的常量参数(例如行高等信息),具体请直接参考源码。

local function LoadFontFile(path) local r = Font() r:Load(path) return r end ModConfigMenu.Skin.AddFont({ Name = "Official", DisplayName = "官中", VersionPrintFont = LoadFontFile("resources-dlc3.zh/font/teammeatfontextended10.fnt"), Font10 = LoadFontFile("resources-dlc3.zh/font/teammeatfontextended10.fnt"), Font12 = LoadFontFile("resources-dlc3.zh/font/teammeatfontextended12.fnt"), Font16Bold = LoadFontFile("resources-dlc3.zh/font/teammeatfontextended16bold.fnt"), })

新增皮肤
使用ModConfigMenu.Skin.AddSkin({...})来增加一个皮肤,传入的参数将被追加到modconfig.lua中的skinConfigs数组,请参考该数组元素中的默认值编写皮肤。皮肤可以建议字体(UseFontName)、替换png文件、修改MCM绘图过程中用到的大部分绘制参数(SkinArg)。
Last edited by frto027; 7 Dec, 2024 @ 9:06am
坤你太美 20 Dec, 2024 @ 12:46am 
为什么按了L就闪退呢
< >
Showing 1-2 of 2 comments
Per page: 1530 50