abse4411 / projz_renpy_translation

RenPy翻译 rpy翻译 RenPy机翻工具 - A translator for RenPy, renpy translation, rpy translation, renpy translator
GNU General Public License v3.0
116 stars 12 forks source link

翻译完成后开启游戏报错 #24

Closed djgjb closed 5 months ago

djgjb commented 5 months ago

翻译游戏完成,开启后无法进入,弹出traceback.txt 无标题

abse4411 commented 5 months ago

使用 ij x -t I18n -u 来取消注入插件,来让游戏恢复正常运行。x是你的翻译索引号

djgjb commented 5 months ago

谢谢大佬,如果还原插件的话,怎么实现中文字体和汉化呢

abse4411 commented 5 months ago

稍等,需要注释一些代码。

djgjb commented 5 months ago

嗯嗯,好的大佬

abse4411 commented 5 months ago

IMG_3201 IMG_3200 请在resources/codes/projz_i18n_inject.rpy文件把上面图片所出现的代码给注释了,就是每行前面加个#号,然后重新注入插件看看。

djgjb commented 5 months ago

好的我试下

djgjb commented 5 months ago

按照大佬的方法已经可以进去游戏了,非常感谢!但是这个游戏设置UI和大多数renpy游戏不一样,设置界面只能改改全屏音量什么的,没有插件按钮,快捷键打开插件还会报错,这种目前是不是无解啊

abse4411 commented 5 months ago

按照大佬的方法已经可以进去游戏了,非常感谢! 但是这个游戏设置UI和大多数renpy游戏不一样,设置界面只能改改全屏音量什么的,没有插件按钮,快捷键打开插件还会报错,这种目前是不是无解啊

需要错误截图看看 今天中午在确认一下

djgjb commented 5 months ago

这是主界面按ctrl+i快捷键后弹出的报错 VP04DI}6(ITER28`VD~TUL9 OD6_Q 8YH 4 %2E)F16 $K

abse4411 commented 5 months ago

这是主界面按ctrl+i快捷键后弹出的报错 VP04DI}6(ITER28`VD~TUL9 OD6_Q 8YH 4 %2E)F16 $K

好的 这是代码注释后导致部分内容不完整而报错,后面我修改下再发一下

djgjb commented 5 months ago

OK,好的大佬

abse4411 commented 5 months ago
# coding=utf8
# projz_renpy_translation, a translator for RenPy games
# Copyright (C) 2023  github.com/abse4411
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

###########################################################
# ________  ________  ________        ___  ________       #
# |\   __  \|\   __  \|\   __  \      |\  \|\_____  \     #
# \ \  \|\  \ \  \|\  \ \  \|\  \     \ \  \\|___/  /|    #
#  \ \   ____\ \   _  _\ \  \\\  \  __ \ \  \   /  / /    #
#   \ \  \___|\ \  \\  \\ \  \\\  \|\  \\_\  \ /  /_/__   #
#    \ \__\    \ \__\\ _\\ \_______\ \________\\________\ #
#     \|__|     \|__|\|__|\|_______|\|________|\|_______| #
#                                                         #
#  This rpy file is generated by the project:             #
#  https://github.com/abse4411/projz_renpy_translation)   #
###########################################################
# Note: Run after define statements of font in gui.rpy
init offset = 999
# # Enable developer console
# init python:
#     if {projz_enable_console_content}:
#         renpy.config.developer = True

# location of fotns
define projz_font_dir = "{projz_fonts_dir}"
# Names of gui font var for saving default font
define projz_gui_vars = ["projz_gui_text_font","projz_gui_name_text_font","projz_gui_interface_text_font","projz_gui_button_text_font","projz_gui_choice_button_text_font","projz_gui_system_font","projz_gui_main_font"]
# Names of gui font var for saving selected font
define projz_sgui_vars = ["projz_sgui_text_font","projz_sgui_name_text_font","projz_sgui_interface_text_font","projz_sgui_button_text_font","projz_sgui_choice_button_text_font","projz_sgui_system_font","projz_sgui_main_font"]
define projz_gui_names = ["Text Font","Name Text Font","Interface Text Font","Button Text Font","Choice Button Text Font","System Font","Main Font"]
define projz_global_font = 'projz_global_font'
# Names for saving current selected font by our setting
# define projz_gui_selected_font = "projz_gui_selected_font"
init python:
    from store import persistent
    def projz_dget(name, dvalue=None):
        if hasattr(persistent, name) and getattr(persistent, name) is not None:
            return getattr(persistent, name)
        sname = name.replace('projz_s', 'projz_')
        if hasattr(persistent, sname) and getattr(persistent, sname) is not None:
            return getattr(persistent, sname)
        return dvalue

    def projz_get(name, dvalue=None):
        if hasattr(persistent, name) and getattr(persistent, name) is not None:
            return getattr(persistent, name)
        return dvalue

    def projz_set(name, value):
        setattr(persistent, name, value)
        return value

    def projz_dset(name, dobj, dname, dvalue=None):
        if hasattr(persistent, name) and getattr(persistent, name) is not None:
            return getattr(persistent, name)
        if hasattr(dobj, dname):
            return projz_set(name, getattr(dobj, dname))
        return projz_set(name, dvalue)

    def projz_config_get(name, dvalue=None):
        return projz_get("projz_config_"+name, dvalue)

    def projz_config_set(name, value):
        projz_set("projz_config_"+name, value)
        setattr(renpy.config, name, value)

    if projz_config_get("developer") is not None:
        renpy.config.developer = projz_config_get("developer")
    else:
        projz_config_set("developer", {projz_enable_developer_content})

    if projz_config_get("console", None) is not None:
        renpy.config.console = projz_config_get("console")
    else:
        projz_config_set("console", {projz_enable_console_content})

    if projz_get(projz_global_font) is None:
        projz_set(projz_global_font, None)

    # save default fonts
    projz_dset(projz_gui_vars[0], gui, 'text_font')
    projz_dset(projz_gui_vars[1], gui, 'name_text_font')
    projz_dset(projz_gui_vars[2], gui, 'interface_text_font')
    projz_dset(projz_gui_vars[3], gui, 'button_text_font')
    projz_dset(projz_gui_vars[4], gui, 'choice_button_text_font')
    projz_dset(projz_gui_vars[5], gui, 'system_font')
    projz_dset(projz_gui_vars[6], gui, 'main_font')

################### Make font vars dynamic since Ren’Py 6.99.14 ###################
# define gui.text_font = gui.preference(projz_gui_vars[0], gui.text_font)
# define gui.name_text_font = gui.preference(projz_gui_vars[1], gui.name_text_font)
# define gui.interface_text_font = gui.preference(projz_gui_vars[2], gui.interface_text_font)
# define gui.button_text_font = gui.preference(projz_gui_vars[3], gui.button_text_font)
# define gui.choice_button_text_font = gui.preference(projz_gui_vars[4], gui.choice_button_text_font)
###################################################################################

################### Make font vars dynamic by our implementation ###################
define gui.text_font = projz_dget(projz_sgui_vars[0])
define gui.name_text_font = projz_dget(projz_sgui_vars[1])
define gui.interface_text_font = projz_dget(projz_sgui_vars[2])
define gui.button_text_font = projz_dget(projz_sgui_vars[3])
define gui.choice_button_text_font = projz_dget(projz_sgui_vars[4])
define gui.system_font = projz_dget(projz_sgui_vars[5])
define gui.main_font = projz_dget(projz_sgui_vars[6])
####################################################################################

# define projz_languages = {"korean": ("한국어", "SourceHanSansLite.ttf"), "japanese": ("日本語","SourceHanSansLite.ttf"), "french":("Русский","DejaVuSans.ttf"), "chinese": ("简体中文","SourceHanSansLite.ttf")}
define projz_languages = {{projz_lang_content}}
# define projz_simple_languages = ["cn", "en"]
define projz_simple_languages = [{projz_slang_content}]
#define projz_fonts = ["DejaVuSans.ttf", "KMKDSP.ttf", "SourceHanSansLite.ttf"]
define projz_fonts = [{projz_font_content}]
# Note that: fonts should be placed in "game/projz_fonts"

init python:
    old_set_text = None
    _old_prefix_suffix = None
    _old_do_display = None
    _DialogueTextTags_ref = None

    def global_set_text(self, text, scope=None, substitute=False, update=True):
        res = old_set_text(self, text, scope, substitute, update)
        if not (substitute is True or substitute is None):
            return res
        if len(text) != 1 or (not isinstance(text[0], basestring)) or isinstance(text[0], bytes):
            return res
        old_text = self.text[0]
        current_font = projz_get(projz_global_font)
        if current_font is not None and old_text is not None and old_text.strip()!='':
            new_text = u'{font='+str(current_font) + u'}' + old_text + u'{font}'
            self.text = [new_text]
        return res

    def global_prefix_suffix(self, thing, prefix, body, suffix):
        current_font = projz_get(projz_global_font)
        if current_font is not None:
            if (thing == 'what' or thing == 'who') and body is not None and body.strip()!='':
                body = u'{font='+str(current_font) + u'}' + body + u'{font}'
        return _old_prefix_suffix(self, thing, prefix, body, suffix)

    def global_do_display(self, who, what, **display_args):
        current_font = projz_get(projz_global_font)
        if current_font is None:
            return _old_do_display(self, who, what, **display_args)

        if what is not None and what.strip() != '':
            what = u'{font='+str(current_font) + u'}' + what + u'{font}'
        if who is not None and who.strip() != '':
            who = u'{font='+str(current_font) + u'}' + who + u'{font}'
        old_dtt = display_args.get('dtt', None)
        new_dtt = None
        if _DialogueTextTags_ref and isinstance(old_dtt, _DialogueTextTags_ref):
            new_dtt = _DialogueTextTags_ref(what)
            display_args['dtt'] = new_dtt
        _old_do_display(self, who, what, **display_args)
        if old_dtt is not None:
            for k, v in vars(new_dtt).items():
                setattr(old_dtt, k, v)

    try:
        _DialogueTextTags_ref = renpy.character.DialogueTextTags
    except Exception as projz_ex:
        print(projz_ex)
    try:
        old_set_text = renpy.text.text.Text.set_text
        renpy.text.text.Text.set_text = global_set_text
    except Exception as projz_ex:
        print(projz_ex)
    try:
        _old_prefix_suffix = renpy.character.ADVCharacter.prefix_suffix
        renpy.character.ADVCharacter.prefix_suffix = global_prefix_suffix
    except Exception as projz_ex:
        print(projz_ex)
        try:
            _old_do_display = renpy.character.ADVCharacter.do_display
            renpy.character.ADVCharacter.do_display = global_do_display
        except Exception as projz_ex:
            print(projz_ex)

    from store import persistent, Action, DictEquality
    class ProjzFontAction(Action, DictEquality):
        def __init__(self, name, value, rebuild=True):
            self.name = name
            self.value = value
            self.rebuild = rebuild

        def __call__(self):
            projz_set(self.name, self.value)

            if self.rebuild:
                gui.rebuild()

        def get_selected(self):
            return projz_get(self.name, None) == self.value

    class ProjzDefaultFontAction(Action, DictEquality):
        def __init__(self, name, rebuild=True):
            self.name = name
            self.rebuild = rebuild

        def __call__(self):
            projz_set(self.name, None)

            if self.rebuild:
                gui.rebuild()

        def get_selected(self):
            return projz_get(self.name, None) is None

    class ProjzAllFontAction(Action, DictEquality):
        def __init__(self, value, rebuild=True):
            self.value = value
            self.rebuild = rebuild

        def __call__(self):
            for name in projz_sgui_vars:
                projz_set(name, self.value)

            if self.rebuild:
                gui.rebuild()

        def get_selected(self):
            for i in range(len(projz_sgui_vars)):
                sfont = projz_get(projz_sgui_vars[i], None)
                if sfont is None or sfont != self.value:
                    return False
            return True

    class ProjzDefaultAllFontAction(Action, DictEquality):
        def __init__(self, rebuild=True):
            self.rebuild = rebuild

        def __call__(self):
            for name in projz_sgui_vars:
                projz_set(name, None)

            if self.rebuild:
                gui.rebuild()

        def get_selected(self):
            for name in projz_sgui_vars:
                if projz_get(name, None) is not None:
                    return False
            return True

    class ProjzConfigAction(Action, DictEquality):
        def __init__(self, name, value, rebuild=True):
            self.name = name
            self.value = value
            self.rebuild = rebuild

        def __call__(self):
            projz_config_set(self.name, self.value)

            if self.rebuild:
                gui.rebuild()

        def get_selected(self):
            if hasattr(renpy.config, self.name) and getattr(renpy.config, self.name) == self.value:
                return True
            return False

    class ProjzValueAction(Action, DictEquality):
        def __init__(self, name, value, rebuild=True):
            self.name = name
            self.value = value
            self.rebuild = rebuild

        def __call__(self):
            projz_set(self.name, self.value)

            if self.rebuild:
                gui.rebuild()

        def get_selected(self):
            return projz_get(self.name) == self.value

    def projz_set_font(font):
        for name in projz_sgui_vars:
            projz_set(name, font)
        gui.rebuild()

    def projz_show_i18n_settings():
        renpy.show_screen('projz_i18n_settings')

    def projz_reload_game():
        if old_set_text is not None:
            renpy.text.text.Text.set_text = old_set_text
        if _old_prefix_suffix is not None:
            renpy.character.ADVCharacter.prefix_suffix = _old_prefix_suffix
        if _old_do_display is not None:
            renpy.character.ADVCharacter.do_display = _old_do_display
        renpy.reload_script()

    config.underlay[0].keymap['projz_show_i18n_settings'] = projz_show_i18n_settings
    config.keymap['projz_show_i18n_settings'] = ['{projz_shortcut_key}']

screen projz_i18n_settings():
    default show_more = False
    tag menu
    use game_menu(_("I18n settings"), scroll="viewport"):
        vbox:
            textbutton _("Return") action Return()
            hbox:
                box_wrap True
                vbox:
                    style_prefix "radio"
                    label _("Language")
                    textbutton _("Default") action [Function(projz_set_font, None), Language(None)]
                    for k,v in projz_languages.items():
                        textbutton v[0] text_font projz_font_dir+v[1] action [Function(projz_set_font, projz_font_dir+v[1]), Language(k)]
                    for k in projz_simple_languages:
                        textbutton k action Language(k)
                ################### Make font vars dynamic by our implementation ###################
                vbox:
                    style_prefix "radio"
                    label _("Global Font")
                    textbutton _("Default") action ProjzValueAction(projz_global_font, None)
                    for f in projz_fonts:
                        textbutton f:
                            text_font projz_font_dir+f
                            action ProjzValueAction(projz_global_font, projz_font_dir+f)
                vbox:
                    style_prefix "radio"
                    label _("Font")
                    textbutton _("Default") action ProjzDefaultAllFontAction()
                    for f in projz_fonts:
                        textbutton f:
                            text_font projz_font_dir+f
                            action ProjzAllFontAction(projz_font_dir+f)
                vbox:
                    style_prefix "radio"
                    label _("Other Font Settings")
                    textbutton _("Expand") action SetScreenVariable("show_more", True)
                    textbutton _("Collapse") action SetScreenVariable("show_more", False)
                showif show_more == True:
                    for sf,n in zip(projz_sgui_vars, projz_gui_names):
                        vbox:
                            style_prefix "radio"
                            label _(n)
                            textbutton _("Default") action ProjzDefaultFontAction(sf)
                            for f in projz_fonts:
                                textbutton f:
                                    text_font projz_font_dir+f
                                    action ProjzFontAction(sf, projz_font_dir+f)
                ####################################################################################

                ################### Make font vars dynamic since Ren’Py 6.99.14 ###################
                # vbox:
                #     style_prefix "radio"
                #     label _("Font")
                #     textbutton "Default" action [gui.SetPreference(projz_gui_vars[0], persistent.projz_gui_text_font, rebuild=False), gui.SetPreference(projz_gui_vars[1], persistent.projz_gui_name_text_font, rebuild=False), gui.SetPreference(projz_gui_vars[2], persistent.projz_gui_interface_text_font, rebuild=False), gui.SetPreference(projz_gui_vars[3], persistent.projz_gui_button_text_font, rebuild=False), gui.SetPreference(projz_gui_vars[4], persistent.projz_gui_choice_button_text_font, rebuild=True)]
                #     for f in projz_fonts:
                #         textbutton f:
                #             text_font f
                #             action [gui.SetPreference(projz_gui_vars[0], "projz_fonts/"+f, rebuild=False), gui.SetPreference(projz_gui_vars[1], "projz_fonts/"+f, rebuild=False), gui.SetPreference(projz_gui_vars[2], "projz_fonts/"+f, rebuild=False), gui.SetPreference(projz_gui_vars[3], "projz_fonts/"+f, rebuild=False), gui.SetPreference(projz_gui_vars[4], "projz_fonts/"+f, rebuild=True)]
                ###################################################################################
#                 null height 10
#                 hbox:
#                     style_prefix "slider"
#                     box_wrap True
#                     vbox:
#                         label _("Text Size Scaling")
#                         bar value Preference("font size")
#                         textbutton _("Reset") action Preference("font size", 1.0)
#                     vbox:
#                         label _("Line Spacing Scaling")
#                         bar value Preference("font line spacing")
#                         textbutton _("Reset") action Preference("font line spacing", 1.0)
                null height 10
                hbox:
                    vbox:
                        style_prefix "radio"
                        label _("Developer Mode")
                        textbutton "auto" action [ProjzConfigAction("developer", "auto")]
                        textbutton "True" action [ProjzConfigAction("developer", True)]
                        textbutton "False" action [ProjzConfigAction("developer", False)]
                        text _("Reload Required")
                    vbox:
                        style_prefix "radio"
                        label _("Console (Shift+O)")
                        textbutton "True" action [ProjzConfigAction("console", True)]
                        textbutton "False" action [ProjzConfigAction("console", False)]
                        text _("Reload Required")
                    vbox:
                        style_prefix "check"
                        label _("Reload Game (Shift+R)")
                        textbutton _("Reload") action[Function(projz_reload_game)]
            null height 10
            label _("Watch")
#             grid 2 12:
            grid 2 10:
                text _("Language")
                text "[_preferences.language]"
                text _("Developer Mode")
                text "[config.developer]"
                text _("Debug Console")
                text "[config.console]"
                text _("Text Font")
                text "[gui.text_font]"
                text _("Name Text Font")
                text "[gui.name_text_font]"
                text _("Interface Text Font")
                text "[gui.interface_text_font]"
                text _("Button Text Font")
                text "[gui.button_text_font]"
                text _("Choice Button Text Font")
                text "[gui.choice_button_text_font]"
                text _("System Font")
                text "[gui.system_font]"
                text _("Main Font")
                text "[gui.main_font]"

            null height 10
            label _("Note that")
            text _("If there exists the font configuration in game/tl/language/style.rpy, it will disable our font setting because of its higher priority. For more information, please see {a=https://www.renpy.org/doc/html/translation.html#style-translations}this{/a}.")
            null height 10
            text _("Thanks to my sponsors:\n- 799190761\n- ansan\nTo become a sponsor, see {a=https://github.com/abse4411/projz_renpy_translation?tab=readme-ov-file#sponsor}this{a}.")
            null height 10
            text _("This plugin is injected by the {a=https://github.com/abse4411/projz_renpy_translation}projz_renpy_translation{/a} project under the {a=https://github.com/abse4411/projz_renpy_translation?tab=GPL-3.0-1-ov-file}GPL-3.0 license{/a}.") xalign 1.0
            null height 60
abse4411 commented 5 months ago

OK,好的大佬

把上面内容替换到resources/codes/projz_i18n_inject.rpy文件中,应该没问题,上面有个返回按钮。

djgjb commented 5 months ago

嗯嗯,替换重新注入插件之后没有报错,但是ctrl+i进去只有一些常规按钮和左下角的返回

abse4411 commented 5 months ago

嗯嗯,替换重新注入插件之后没有报错,但是ctrl+i进去只有一些常规按钮和左下角的返回

只去除了更改字体大小和行间距的功能,其他就是所有功能了,包括语言更改,设置字体等

djgjb commented 5 months ago

找不到语言更改的按钮 无标题

abse4411 commented 5 months ago

这个游戏可能代码不太一样,后面我重发下

djgjb commented 5 months ago

嗯嗯麻烦大佬了,单个游戏还好,有没有办法能比较通用的处理这种大量改动ui的游戏情况呢

abse4411 commented 5 months ago
# coding=utf8
# projz_renpy_translation, a translator for RenPy games
# Copyright (C) 2023  github.com/abse4411
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

###########################################################
# ________  ________  ________        ___  ________       #
# |\   __  \|\   __  \|\   __  \      |\  \|\_____  \     #
# \ \  \|\  \ \  \|\  \ \  \|\  \     \ \  \\|___/  /|    #
#  \ \   ____\ \   _  _\ \  \\\  \  __ \ \  \   /  / /    #
#   \ \  \___|\ \  \\  \\ \  \\\  \|\  \\_\  \ /  /_/__   #
#    \ \__\    \ \__\\ _\\ \_______\ \________\\________\ #
#     \|__|     \|__|\|__|\|_______|\|________|\|_______| #
#                                                         #
#  This rpy file is generated by the project:             #
#  https://github.com/abse4411/projz_renpy_translation)   #
###########################################################
# Note: Run after define statements of font in gui.rpy
init offset = 999
# # Enable developer console
# init python:
#     if {projz_enable_console_content}:
#         renpy.config.developer = True

# location of fotns
define projz_font_dir = "{projz_fonts_dir}"
# Names of gui font var for saving default font
define projz_gui_vars = ["projz_gui_text_font","projz_gui_name_text_font","projz_gui_interface_text_font","projz_gui_button_text_font","projz_gui_choice_button_text_font","projz_gui_system_font","projz_gui_main_font"]
# Names of gui font var for saving selected font
define projz_sgui_vars = ["projz_sgui_text_font","projz_sgui_name_text_font","projz_sgui_interface_text_font","projz_sgui_button_text_font","projz_sgui_choice_button_text_font","projz_sgui_system_font","projz_sgui_main_font"]
define projz_gui_names = ["Text Font","Name Text Font","Interface Text Font","Button Text Font","Choice Button Text Font","System Font","Main Font"]
define projz_global_font = 'projz_global_font'
# Names for saving current selected font by our setting
# define projz_gui_selected_font = "projz_gui_selected_font"
init python:
    from store import persistent
    def projz_dget(name, dvalue=None):
        if hasattr(persistent, name) and getattr(persistent, name) is not None:
            return getattr(persistent, name)
        sname = name.replace('projz_s', 'projz_')
        if hasattr(persistent, sname) and getattr(persistent, sname) is not None:
            return getattr(persistent, sname)
        return dvalue

    def projz_get(name, dvalue=None):
        if hasattr(persistent, name) and getattr(persistent, name) is not None:
            return getattr(persistent, name)
        return dvalue

    def projz_set(name, value):
        setattr(persistent, name, value)
        return value

    def projz_dset(name, dobj, dname, dvalue=None):
        if hasattr(persistent, name) and getattr(persistent, name) is not None:
            return getattr(persistent, name)
        if hasattr(dobj, dname):
            return projz_set(name, getattr(dobj, dname))
        return projz_set(name, dvalue)

    def projz_config_get(name, dvalue=None):
        return projz_get("projz_config_"+name, dvalue)

    def projz_config_set(name, value):
        projz_set("projz_config_"+name, value)
        setattr(renpy.config, name, value)

    if projz_config_get("developer") is not None:
        renpy.config.developer = projz_config_get("developer")
    else:
        projz_config_set("developer", {projz_enable_developer_content})

    if projz_config_get("console", None) is not None:
        renpy.config.console = projz_config_get("console")
    else:
        projz_config_set("console", {projz_enable_console_content})

    if projz_get(projz_global_font) is None:
        projz_set(projz_global_font, None)

    # save default fonts
    projz_dset(projz_gui_vars[0], gui, 'text_font')
    projz_dset(projz_gui_vars[1], gui, 'name_text_font')
    projz_dset(projz_gui_vars[2], gui, 'interface_text_font')
    projz_dset(projz_gui_vars[3], gui, 'button_text_font')
    projz_dset(projz_gui_vars[4], gui, 'choice_button_text_font')
    projz_dset(projz_gui_vars[5], gui, 'system_font')
    projz_dset(projz_gui_vars[6], gui, 'main_font')

################### Make font vars dynamic since Ren’Py 6.99.14 ###################
# define gui.text_font = gui.preference(projz_gui_vars[0], gui.text_font)
# define gui.name_text_font = gui.preference(projz_gui_vars[1], gui.name_text_font)
# define gui.interface_text_font = gui.preference(projz_gui_vars[2], gui.interface_text_font)
# define gui.button_text_font = gui.preference(projz_gui_vars[3], gui.button_text_font)
# define gui.choice_button_text_font = gui.preference(projz_gui_vars[4], gui.choice_button_text_font)
###################################################################################

################### Make font vars dynamic by our implementation ###################
define gui.text_font = projz_dget(projz_sgui_vars[0])
define gui.name_text_font = projz_dget(projz_sgui_vars[1])
define gui.interface_text_font = projz_dget(projz_sgui_vars[2])
define gui.button_text_font = projz_dget(projz_sgui_vars[3])
define gui.choice_button_text_font = projz_dget(projz_sgui_vars[4])
define gui.system_font = projz_dget(projz_sgui_vars[5])
define gui.main_font = projz_dget(projz_sgui_vars[6])
####################################################################################

# define projz_languages = {"korean": ("한국어", "SourceHanSansLite.ttf"), "japanese": ("日本語","SourceHanSansLite.ttf"), "french":("Русский","DejaVuSans.ttf"), "chinese": ("简体中文","SourceHanSansLite.ttf")}
define projz_languages = {{projz_lang_content}}
# define projz_simple_languages = ["cn", "en"]
define projz_simple_languages = [{projz_slang_content}]
#define projz_fonts = ["DejaVuSans.ttf", "KMKDSP.ttf", "SourceHanSansLite.ttf"]
define projz_fonts = [{projz_font_content}]
# Note that: fonts should be placed in "game/projz_fonts"

init python:
    old_set_text = None
    _old_prefix_suffix = None
    _old_do_display = None
    _DialogueTextTags_ref = None

    def global_set_text(self, text, scope=None, substitute=False, update=True):
        res = old_set_text(self, text, scope, substitute, update)
        if not (substitute is True or substitute is None):
            return res
        if len(text) != 1 or (not isinstance(text[0], basestring)) or isinstance(text[0], bytes):
            return res
        old_text = self.text[0]
        current_font = projz_get(projz_global_font)
        if current_font is not None and old_text is not None and old_text.strip()!='':
            new_text = u'{font='+str(current_font) + u'}' + old_text + u'{font}'
            self.text = [new_text]
        return res

    def global_prefix_suffix(self, thing, prefix, body, suffix):
        current_font = projz_get(projz_global_font)
        if current_font is not None:
            if (thing == 'what' or thing == 'who') and body is not None and body.strip()!='':
                body = u'{font='+str(current_font) + u'}' + body + u'{font}'
        return _old_prefix_suffix(self, thing, prefix, body, suffix)

    def global_do_display(self, who, what, **display_args):
        current_font = projz_get(projz_global_font)
        if current_font is None:
            return _old_do_display(self, who, what, **display_args)

        if what is not None and what.strip() != '':
            what = u'{font='+str(current_font) + u'}' + what + u'{font}'
        if who is not None and who.strip() != '':
            who = u'{font='+str(current_font) + u'}' + who + u'{font}'
        old_dtt = display_args.get('dtt', None)
        new_dtt = None
        if _DialogueTextTags_ref and isinstance(old_dtt, _DialogueTextTags_ref):
            new_dtt = _DialogueTextTags_ref(what)
            display_args['dtt'] = new_dtt
        _old_do_display(self, who, what, **display_args)
        if old_dtt is not None:
            for k, v in vars(new_dtt).items():
                setattr(old_dtt, k, v)

    try:
        _DialogueTextTags_ref = renpy.character.DialogueTextTags
    except Exception as projz_ex:
        print(projz_ex)
    try:
        old_set_text = renpy.text.text.Text.set_text
        renpy.text.text.Text.set_text = global_set_text
    except Exception as projz_ex:
        print(projz_ex)
    try:
        _old_prefix_suffix = renpy.character.ADVCharacter.prefix_suffix
        renpy.character.ADVCharacter.prefix_suffix = global_prefix_suffix
    except Exception as projz_ex:
        print(projz_ex)
        try:
            _old_do_display = renpy.character.ADVCharacter.do_display
            renpy.character.ADVCharacter.do_display = global_do_display
        except Exception as projz_ex:
            print(projz_ex)

    from store import persistent, Action, DictEquality
    class ProjzFontAction(Action, DictEquality):
        def __init__(self, name, value, rebuild=True):
            self.name = name
            self.value = value
            self.rebuild = rebuild

        def __call__(self):
            projz_set(self.name, self.value)

            if self.rebuild:
                gui.rebuild()

        def get_selected(self):
            return projz_get(self.name, None) == self.value

    class ProjzDefaultFontAction(Action, DictEquality):
        def __init__(self, name, rebuild=True):
            self.name = name
            self.rebuild = rebuild

        def __call__(self):
            projz_set(self.name, None)

            if self.rebuild:
                gui.rebuild()

        def get_selected(self):
            return projz_get(self.name, None) is None

    class ProjzAllFontAction(Action, DictEquality):
        def __init__(self, value, rebuild=True):
            self.value = value
            self.rebuild = rebuild

        def __call__(self):
            for name in projz_sgui_vars:
                projz_set(name, self.value)

            if self.rebuild:
                gui.rebuild()

        def get_selected(self):
            for i in range(len(projz_sgui_vars)):
                sfont = projz_get(projz_sgui_vars[i], None)
                if sfont is None or sfont != self.value:
                    return False
            return True

    class ProjzDefaultAllFontAction(Action, DictEquality):
        def __init__(self, rebuild=True):
            self.rebuild = rebuild

        def __call__(self):
            for name in projz_sgui_vars:
                projz_set(name, None)

            if self.rebuild:
                gui.rebuild()

        def get_selected(self):
            for name in projz_sgui_vars:
                if projz_get(name, None) is not None:
                    return False
            return True

    class ProjzConfigAction(Action, DictEquality):
        def __init__(self, name, value, rebuild=True):
            self.name = name
            self.value = value
            self.rebuild = rebuild

        def __call__(self):
            projz_config_set(self.name, self.value)

            if self.rebuild:
                gui.rebuild()

        def get_selected(self):
            if hasattr(renpy.config, self.name) and getattr(renpy.config, self.name) == self.value:
                return True
            return False

    class ProjzValueAction(Action, DictEquality):
        def __init__(self, name, value, rebuild=True):
            self.name = name
            self.value = value
            self.rebuild = rebuild

        def __call__(self):
            projz_set(self.name, self.value)

            if self.rebuild:
                gui.rebuild()

        def get_selected(self):
            return projz_get(self.name) == self.value

    def projz_set_font(font):
        for name in projz_sgui_vars:
            projz_set(name, font)
        gui.rebuild()

    def projz_show_i18n_settings():
        renpy.show_screen('projz_i18n_settings')

    def projz_reload_game():
        if old_set_text is not None:
            renpy.text.text.Text.set_text = old_set_text
        if _old_prefix_suffix is not None:
            renpy.character.ADVCharacter.prefix_suffix = _old_prefix_suffix
        if _old_do_display is not None:
            renpy.character.ADVCharacter.do_display = _old_do_display
        renpy.reload_script()

    config.underlay[0].keymap['projz_show_i18n_settings'] = projz_show_i18n_settings
    config.keymap['projz_show_i18n_settings'] = ['{projz_shortcut_key}']

screen projz_i18n_settings():
    modal True
    default show_more = False
    side "c b r":
        viewport id "vp":
            mousewheel True
            draggable True
            vbox:
                textbutton _("Hide") action Hide("projz_i18n_settings")
                hbox:
                    box_wrap True
                    vbox:
                        style_prefix "radio"
                        label _("Language")
                        textbutton _("Default") action [Function(projz_set_font, None), Language(None)]
                        for k,v in projz_languages.items():
                            textbutton v[0] text_font projz_font_dir+v[1] action [Function(projz_set_font, projz_font_dir+v[1]), Language(k)]
                        for k in projz_simple_languages:
                            textbutton k action Language(k)
                    ################### Make font vars dynamic by our implementation ###################
                    vbox:
                        style_prefix "radio"
                        label _("Global Font")
                        textbutton _("Default") action ProjzValueAction(projz_global_font, None)
                        for f in projz_fonts:
                            textbutton f:
                                text_font projz_font_dir+f
                                action ProjzValueAction(projz_global_font, projz_font_dir+f)
                    vbox:
                        style_prefix "radio"
                        label _("Font")
                        textbutton _("Default") action ProjzDefaultAllFontAction()
                        for f in projz_fonts:
                            textbutton f:
                                text_font projz_font_dir+f
                                action ProjzAllFontAction(projz_font_dir+f)
                    vbox:
                        style_prefix "radio"
                        label _("Other Font Settings")
                        textbutton _("Expand") action SetScreenVariable("show_more", True)
                        textbutton _("Collapse") action SetScreenVariable("show_more", False)
                    showif show_more == True:
                        for sf,n in zip(projz_sgui_vars, projz_gui_names):
                            vbox:
                                style_prefix "radio"
                                label _(n)
                                textbutton _("Default") action ProjzDefaultFontAction(sf)
                                for f in projz_fonts:
                                    textbutton f:
                                        text_font projz_font_dir+f
                                        action ProjzFontAction(sf, projz_font_dir+f)
                    null height 10
                    hbox:
                        vbox:
                            style_prefix "radio"
                            label _("Developer Mode")
                            textbutton "auto" action [ProjzConfigAction("developer", "auto")]
                            textbutton "True" action [ProjzConfigAction("developer", True)]
                            textbutton "False" action [ProjzConfigAction("developer", False)]
                            text _("Reload Required")
                        vbox:
                            style_prefix "radio"
                            label _("Console (Shift+O)")
                            textbutton "True" action [ProjzConfigAction("console", True)]
                            textbutton "False" action [ProjzConfigAction("console", False)]
                            text _("Reload Required")
                        vbox:
                            style_prefix "check"
                            label _("Reload Game (Shift+R)")
                            textbutton _("Reload") action[Function(projz_reload_game)]
                null height 10
                label _("Watch")
    #             grid 2 12:
                grid 2 10:
                    text _("Language")
                    text "[_preferences.language]"
                    text _("Developer Mode")
                    text "[config.developer]"
                    text _("Debug Console")
                    text "[config.console]"
                    text _("Text Font")
                    text "[gui.text_font]"
                    text _("Name Text Font")
                    text "[gui.name_text_font]"
                    text _("Interface Text Font")
                    text "[gui.interface_text_font]"
                    text _("Button Text Font")
                    text "[gui.button_text_font]"
                    text _("Choice Button Text Font")
                    text "[gui.choice_button_text_font]"
                    text _("System Font")
                    text "[gui.system_font]"
                    text _("Main Font")
                    text "[gui.main_font]"

                null height 10
                label _("Note that")
                text _("If there exists the font configuration in game/tl/language/style.rpy, it will disable our font setting because of its higher priority. For more information, please see {a=https://www.renpy.org/doc/html/translation.html#style-translations}this{/a}.")
                null height 10
                text _("Thanks to my sponsors:\n- 799190761\n- ansan\nTo become a sponsor, see {a=https://github.com/abse4411/projz_renpy_translation?tab=readme-ov-file#sponsor}this{a}.")
                null height 10
                text _("This plugin is injected by the {a=https://github.com/abse4411/projz_renpy_translation}projz_renpy_translation{/a} project under the {a=https://github.com/abse4411/projz_renpy_translation?tab=GPL-3.0-1-ov-file}GPL-3.0 license{/a}.") xalign 1.0
                null height 60

        bar value XScrollValue("vp")
        vbar value YScrollValue("vp")
abse4411 commented 5 months ago

嗯嗯麻烦大佬了,单个游戏还好,有没有办法能比较通用的处理这种大量改动ui的游戏情况呢

新发的应该能处理大部分情况

djgjb commented 5 months ago

现在已经可以实现插件内容的完全显示和改变游戏语言了,谢谢大佬,我还想问下如果是这种游戏,安卓设备无法使用快捷键打开插件,那有没有解决方案呢

abse4411 commented 5 months ago

现在已经可以实现插件内容的完全显示和改变游戏语言了,谢谢大佬,我还想问下如果是这种游戏,安卓设备无法使用快捷键打开插件,那有没有解决方案呢

在game/screens.rpy添加该插件的按钮即可:

screen preferences():

    tag menu

    use game_menu(_("Options"), scroll="viewport"):

        vbox:

            textbutton _("I18n settings") action Show("projz_i18n_settings")
            hbox:
                box_wrap True

                if renpy.variant("pc") or renpy.variant("web"):

其中textbutton _("I18n settings") action Show("projz_i18n_settings")为添加插件的代码

djgjb commented 5 months ago

添加后开启游戏会报错,提示 [code] I'm sorry, but errors were detected in your script. Please correct the errors listed below, and try again.

File "game/screens.rpy", line 467: hbox expects a non-empty block. if renpy.variant("pc") or renpy.variant("web"): ^

Ren'Py Version: Ren'Py 7.0.0.196 Fri May 31 01:24:25 2024 [/code]

abse4411 commented 5 months ago

添加后开启游戏会报错,提示 [code] I'm sorry, but errors were detected in your script. Please correct the errors listed below, and try again.

File "game/screens.rpy", line 467: hbox expects a non-empty block. if renpy.variant("pc") or renpy.variant("web"): ^

Ren'Py Version: Ren'Py 7.0.0.196 Fri May 31 01:24:25 2024 [/code]

缩进注意一下,只需要textbutton _("I18n settings") action Show("projz_i18n_settings")到对应的位置,在vbox或者hbox下面,然后缩进一下,和下面的代码前面空格保持一样即可。

djgjb commented 5 months ago

谢谢大佬的帮助,问题已经基本解决