ローレベルな通信コマンドからの脱却(2)

伺かはSSTP通信を使ってメッセージを表示することができます。
特にローカルPC内でのメッセージ送信で使うのですが、文法的には次のようになります。

    msg =  "\\0\\f[height,14]\\s[0]明日の予測ですが・・・\\1\\f[height,14]\\s[10]えーと、明日も特に波乱はなさそうです。\\n"
    send_one_msg(msg)

めんどくせーー、というのが前回の話でした。

簡単に使えるよう、まずは定義ファイルを作ろう

キャラクターID,表情名,サーフェスID
0,びっくり,964
0,びっくり,965
0,びっくり1,966
0,びっくり2,967
1,びっくり,1965
1,びっくり1,1966
0,怒り,7,コメント
1,落ち込み,304
1,落ち込み1,306
0,落ち込み,4
0,落ち込み1,202
1,驚き,11
1,驚き1,307
1,驚き2,310
1,驚き3,313

現在のサーフェスの実装状況を元に定義ファイルを作りましたが、次の問題があることがわかります。

  • キャラクター0の「びっくり」が2つ定義されている

  • キャラクター0に「びっくり2」があるが、キャラクター1には無い。

この定義ファイルを使うためには次のような要件になります。

  • 複数定義されている表情名が指定されたら、その中からランダムにサーフェスIDを戻す。

  • キャラクターに存在しない末尾数値の表情名が指定されたら、末尾数値を無視してサーフェスIDを戻す。

  • 見当違いな表情名がしていされたら、標準サーフェスIDを戻す。

Pythonで実装しよう

Pythonの辞書型は重複定義ができないので、拡張したクラスにします。

    ############################################################################################################
    # 重複を許した特定のキーで辞書を追加する関数
    ############################################################################################################
    def add_value_to_key(self, dictionary, key, value):
        if key in dictionary:
            dictionary[key].append(value)  # キーが存在する場合、値をリストに追加
        else:
            dictionary[key] = [value]  # キーが存在しない場合、新しいリストとして追加                

    ############################################################################################################
    # 重複を許した特定のキーで辞書からサーフェスIDを取得する関数
    ############################################################################################################
    def get_random_value(self, dictionary, key):
        if key in dictionary:
            return int(random.choice(dictionary[key]))  # ランダムに1つの値を選択
        else:
            return -1  # キーが存在しない場合      
    ############################################################################################################
    # 一致度の高い順位にサーフェスIDを取得する関数
    ############################################################################################################
    def get_best_surface_id(self, charcter_id, face_name):
        key = self.get_just_surface_key(charcter_id, face_name) #ぴったり一致したサーフェスID検索用のキー
        tmp_surfece_id = self.get_random_value(self.dict_just_surface_id, key)    #ぴったり一致したサーフェスID検索
        if tmp_surfece_id >= 0: #サーフェスIDとして正しかったら関数終了
            return tmp_surfece_id

        key = self.get_sketchy_surface_key(charcter_id, face_name) #大体一致したサーフェスID検索用のキー
        tmp_surfece_id = self.get_random_value(self.dict_sketchy_surface_id, key)    #大体一致したサーフェスID検索用
        if tmp_surfece_id >= 0: #サーフェスIDとして正しかったら関数終了
            return tmp_surfece_id

        #どうしようもないのでデフォルトID返却
        if charcter_id == 0:
            return 0
        else:
            return 10     

送信メッセージも自動化しよう

キャラクターID、フォントサイズ、サーフェスID、メッセージ本文がSSTP通信の基本的な電文となります。
ページトップのような書き方して、表示タイミングを合わせるのも面倒です。
テンプレでいいじゃん。

    ############################################################################################################
    # SSTPメッセージを制御文字列などと結合して作成する
    ############################################################################################################
    def create_sstp_msg(self, charcter_id, face_name,font_size, msg):
        if self.surface_dict is None:
            #未定義の場合は読み込み
            self.surface_dict = _sketchy_surface_dict()
        #サーフェスIDに変換
        surface_id = self.surface_dict.get_best_surface_id(charcter_id, face_name)

        #charcter_id, surface_id, font_size, msgを結合してSSTP用文字列生成
        sstp_msg = f"\\{charcter_id}\\f[height,{font_size}]\\s[{surface_id}]{msg}"

        #生成した文字列を戻す
        return sstp_msg

インスタンスを意識するのも面倒ですよね

綺麗とは言い辛いが、グローバル変数(ファイル内で使用)と関数で対応しよう。

############################################################################################################
# このファイルの中だけのグローバル変数
############################################################################################################
_send_sstp_cotroller =_send_sstp_control()
############################################################################################################
# 外部から呼び出し用のFunction
############################################################################################################
############################################################################################################
# メッセージキューにためる
############################################################################################################
def stock_talk(charcter_id, face_name, font_size, msg):
    _send_sstp_cotroller.stock_talk(charcter_id, face_name, font_size, msg)

############################################################################################################
# 会話の一区切りを入れる
############################################################################################################
def break_talk():
    _send_sstp_cotroller.break_talk()

############################################################################################################
# 蓄積したメッセージをSSTP送信する
############################################################################################################
def send_talk():
    _send_sstp_cotroller.send_talk()

実装結果と実行結果

    stock_talk(0,'落ち込み',16,'ちょうびっくりー')
    stock_talk(1,'落ち込み',24,'ちょうびっくり!!!!')
    stock_talk(1,'落ち込み1',16,'ほんとに??????')
    stock_talk(0,'落ち込み1',24,'ほんと!')
    stock_talk(1,'落ち込み2',12,'えーーーーーー!')
    break_talk()
    stock_talk(0,'落ち込み2',16,'えーーー')
    stock_talk(0,'落ち込み3',24,'ほんと!')
    stock_talk(0,'落ち込み3',24,'まじで!!')
    stock_talk(0,'落ち込み4',36,'まじで!!!')
    send_talk()

この呼び出しで、キャラクター割り振りと会話同期ができるようになりました。

台詞の表示順序の実際

これでメインの作業に戻れる。。。

いいなと思ったら応援しよう!