Ren’Py改造メモ(12)

次の選択肢、または未読までファストスキップできるようにする

選択肢のあるノベルゲームの場合、スキップの速さはかなり重要です。
早送りより文字どうりスキップして欲しい。
そこでRen’Pyにもともとあるファストスキップを利用して
未読で止まるようにした上で、ボタンから実行できるようにしてみました。
ただしこの方法はまだ実験中です。

方法としては config.fast_skipping を True に設定した後
Action Skipを参考に以下のコードを任意の場所に記述します。


label _return_fast_skipping:
    $ config.skipping = "fast"
    jump _return

init python:
    config.fast_skipping = True

    class FastSkip(Action):

        def __call__(self):
            if not self.get_sensitive():
                return

            if renpy.context()._menu:
                renpy.jump("_return_fast_skipping")
            else:
                config.skipping = "fast"
                renpy.restart_interaction()

        def get_sensitive(self):
            return ( config.allow_skipping and (not renpy.context()._main_menu) ) and ( renpy.game.preferences.skip_unseen or renpy.game.context().seen_current(True) )

そして未読で止まるようにするためにrenpy/execution.pyのContextクラスの240行目、run関数の最後に以下のコードを加えます。


            if ( not renpy.game.preferences.skip_unseen ) and ( not self.seen_current(True) ):
                renpy.config.skipping = None

それよりdisplay_say関数を上書きしたほうが良いです。

    # 未読なら停止する
    def check_fast_skip():
        if ( not renpy.game.preferences.skip_unseen ) and ( not renpy.game.context().seen_current(True) ) and renpy.config.skipping == "fast":
            renpy.config.skipping = None
            # ファストスキップ後はロールバック出来ないようにする(トラブル防止?)
            renpy.block_rollback()
    # display_sayを上書きする
    # 古いバージョンは引数の数が違う
    display_say_org = renpy.character.display_say
    def display_say2(
        who,
        what,
        show_function,
        interact,
        slow,
        afm,
        ctc,
        ctc_pause,
        ctc_position,
        all_at_once,
        cb_args,
        with_none,
        callback,
        type, #@ReservedAssignment
        checkpoint=True,
        ctc_timedpause=None,
        ctc_force=False):

        check_fast_skip()
        return display_say_org(
            who,
            what,
            show_function,
            interact,
            slow,
            afm,
            ctc,
            ctc_pause,
            ctc_position,
            all_at_once,
            cb_args,
            with_none,
            callback,
            type,
            checkpoint,
            ctc_timedpause,
            ctc_force)

    renpy.character.display_say = display_say2

これで後はクイックメニューにでもAction FastSkipを実行するボタンを追加すれば次の選択肢、または未読までファストスキップ出来るようになります。任意の場所で止まった欲しいときはその直前で renpy.config.skipping = Noneを実行すればいいです。
ここまでの内容をfastskip.rpyとして配布場所に置いておきます。

しかしこの方法にはいくつか欠点があります。

まず上記2つの条件にあてはまらなくてもスキップが止まる場合があります。
普通に使っている分には多分大丈夫ですが、どういう条件で止まるのかはよくわかりません。
ui.pyのinteract関数あたりが怪しいのですが、回避策不明です。
そもそもファストスキップはマニュアル曰くsay,pause,transition以外のinteractがおこなわれると止まり、それが普通は選択肢だそうです。
現在判明しているかぎりは次の部分で停止します。input, menu, imagemap, movie, screenの呼び出し。
このinteractがなんなのかがいまいち不明なのですが、多分ユーザーからの入力を受け付けられる状態のことだと思います。

次に本体に改造を加えなくてはいけないことです。

さらにあまり実験に使えるサンプルがないので本当に大丈夫なのかいまいち不安です。
Ren’Py製ゲームを幾つか落してきて fastskip.rpy を追加して実験してみたところ大抵のゲームで期待通りに動作しました。
しかしそうでない場合もあり、ひどいものだとエラーが連発する作品が一作ありました。
もし利用する場合はテストをしっかりしてください。

話は変わりますが、Ren’Pyではファイルをgameフォルダに追加するだけでスクリプトを追加できます。
ハックし放題です。
マウスホイールに対応させられたりとユーザー側にも便利なものがありますが、セキュリティ的にはちょっとどうよとも思います。
追加ファイルの禁止を設定出来るようになるといいのですが。


コメントを残す

メールアドレスが公開されることはありません。