7. 選択肢・条件分岐・ウェイト

この節では、里々が「書き方」として用意していた3つ、選択肢(_)、条件分岐(>、when、iflist)、ウェイト(自動挿入)を扱います。

選択肢

里々の _ラベル は、湊にはありません。さくらスクリプトの \q[ラベル,ID] を直接書きます。 里々も内部でこの形に変換していたので、書く内容は同じです。

イベント名を ID にする

SSPの \q[ラベル,ID] は、ID が On で始まる場合、そのイベントを直接実行します。選ばれたときに動くトークを、OnXxx という名前で定義します。

OnBoot => {
    湊: どっちにしますか?
    \q[りんご,OnApple]
    \q[みかん,OnOrange]
}

OnApple => {
    湊: りんごですね。
}

OnOrange => {
    湊: みかんですね。
}
\0どっちにしますか?\n\q[りんご,OnApple]\n\q[みかん,OnOrange]\e
\0りんごですね。\e
\0みかんですね。\e

\q[…] の行は、直前のセリフに \n(改行)付きで連結されます。選択肢が縦に並ぶのは、この改行のおかげです。

\q[ラベル,OnID,値0,値1] のように、ID のあとに値を続けると、それが選ばれたイベントの reference["0"]、reference["1"] に入ります。

OnAnswer => {
    湊: ${reference["0"]}が選ばれました。
}
\0yesが選ばれました。\e

里々のように「ラベル=ジャンプ先のトーク名」にする

里々では、_はい と書くだけで *はい に飛びました。同じ動きにするには、ID を On で始めず、トーク名にします。すると SSPは、OnChoiceSelect イベントを reference["0"] に ID を入れて送ります。これを受けて call reference.0 で呼び出します。

OnBoot => {
    湊: どっち?
    \q[はい,はい]
    \q[いいえ,いいえ]
}

OnChoiceSelect => {
    call reference.0
}

はい => {
    湊: はいが選ばれました。
}

いいえ => {
    湊: いいえが選ばれました。
}
\0どっち?\n\q[はい,はい]\n\q[いいえ,いいえ]\e
\0はいが選ばれました。\e
(204)
  • call reference.0 は、reference["0"] の文字列をトーク名として呼びます。里々と同じく、同名のトークが複数あればランダムに1つ選ばれます。
  • 存在しない名前のときは、何も出力されず 204 になります。エラーにはなりません。
  • 選択肢が増えるたびに OnChoiceSelect の中身を書き換える必要はありません。

里々の選択肢関連の変数

里々の (選択ID) (選択ラベル) (選択番号) に当たる変数は、湊にはありません。SSPが送る Reference から取り出します。

里々湊
(選択ID)OnChoiceSelect の reference["0"](On で始まらない ID のとき)
(選択ラベル)OnChoiceSelectEx の reference["0"](SSPのみ)。ID は reference["1"]
(選択番号)なし

選択肢を条件で出す

里々では \q[(見たもの1フラグ),選択肢…] のように書きました。湊では、\q の行を if で囲みます。

OnBoot => {
    湊: どれにしますか?
    \q[りんご,OnApple]
    if (save.見た) {
        \n\q[みかん,OnOrange]
    }
}

OnSet => {
    global save.見た = true
}
\0どれにしますか?\n\q[りんご,OnApple]\e
(204)
\0どれにしますか?\n\q[りんご,OnApple]\n\q[みかん,OnOrange]\e

if の中の \q の行は、直前のセリフとは連結されないので、改行の \n を自分で書く必要があります。

条件分岐

里々湊
>ジャンプ先【タブ】条件式if (条件) { call … return }(4. ジャンプ)
(when,条件,真の値,偽の値)choose(条件, 真の値, 偽の値)
(iflist,左辺,右辺1,結果1,…,偽の結果)if … else if … else、または match
ssu.dll の if unlessif (条件)、if (!条件)、または choose()
ssu.dll の switch nswitchmatch
条件式の == >= &&(全角も可)== >= &&(半角のみ)

里々の iflist は、範囲で分岐するときによく使われました。湊では、if の連鎖を関数にまとめると読みやすくなります。

func 時間帯(h) {
    if (h < 6) {
        return "深夜"
    } else if (h < 12) {
        return "朝"
    } else if (h < 18) {
        return "昼"
    }
    return "夜"
}

OnBoot => {
    湊: ${時間帯(5)} ${時間帯(11)} ${時間帯(12)} ${時間帯(23)}
    湊: ${choose(true, "はい", "いいえ")}
}
\0深夜 朝 昼 夜\nはい\e

if の条件は、真偽値ではなく どんな値でも書けます。その場合の真偽の判定は、5. 型と暗黙の型変換の規則に従います。

match

値による分岐は match です。数値と文字列は、内容が同じなら一致とみなされます("3" は 3 に一致します)。

OnBoot => {
    let x = "3"
    match x {
        3 => {
            湊: 数値3にマッチ
        }
        _ => {
            湊: その他
        }
    }
}
\0数値3にマッチ\e

_ はどれにも一致しなかったときの分岐です。1 | 2 => のように | で複数の値をまとめられます。

ウェイト

里々が自動で入れていたウェイトは、湊にはありません。 句読点で間を空ける処理(replace.txt や $自動挿入ウェイトタイプ)も、スコープ切り替え時の自動ウェイトもありません。何も書かないと、間のない速い喋りになります。

手で書く

さくらスクリプトの \w5(50ミリ秒)や \_w[500] をそのまま書きます。

文字列リテラルの中の \ は1つだけ

セリフの中でも、文字列の中でも、\w5 は1つのバックスラッシュで書きます。\\w5 と2つ書くと、ウェイトになりません。文字列の中の \\ は2文字のまま残るため、さくらスクリプトとしては「バックスラッシュという文字を表示する」の意味になるからです。

OnBoot => {
    let ok = "あ\w5い"
    let ng = "あ\\w5い"
    湊: ${ok}|${ng}
}
\0あ\w5い|あ\\w5い\e

句読点に自動でウェイトを付ける

里々の replace.txt(句読点の置き換え)に当たる処理は、replace() を使った関数で作れます。

func wait(s) {
    return replace(replace(s, "、", "、\w3"), "。", "。\w9")
}

OnBoot => {
    湊: ${wait("今日は、いい天気ですね。")}
}
\0今日は、\w3いい天気ですね。\w9\e

セリフごとに ${wait("…")} と書く必要があります。全体に一括で適用する仕組みはありません。

すべての出力に一括で適用したい場合は、SSPの OnTranslate イベントを使う方法があります(3. イベント)。ただし、この方法は、選択肢のラベルや \![…] の引数の中の句読点にもウェイトを入れてしまうので、慎重に使ってください。

スコープの切り替えと改行

里々では、: で始まる行ごとに話者が交互に切り替わり、切り替え時に $スコープ切り替え時(\n[half] など)が自動で挿入されました。

湊では、話者を毎回書き、切り替え時の挿入もありません。

OnBoot => {
    湊: 一行目\n[half]
    助手: 二行目
    湊: 三行目
    助手: 四行目
}
\0一行目\n[half]\1二行目\0\n三行目\1\n四行目\e
  • 話者が変わるときは、\0 \1 のタグが入るだけです。\n[half] のような間隔は、自分で書きます。
  • 一度話した話者に戻るときだけ、直後に \n が自動で入ります。 上の例の \0\n三行目 と \1\n四行目 がそうです(config.toml の auto_newline = false で止められます)。

サーフェス

[数字] を話者の前に付けると、その話者の発話の直前に \s[数字] が入ります。セリフの途中に入れたいときは、\s[数字] を直接書きます。

OnBoot => {
    [5]湊: 5番
    湊: \s[3]3番
    助手: 助手
}
\0\s[5]5番\n\s[3]3番\1助手\e

里々の (5) のような括弧でのサーフェス切り替えは使えません。$デフォルトサーフェス や $会話時サーフェス戻し、$サーフェス加算値 のような自動処理もありません。トークの先頭で、必要なサーフェスを毎回書いてください。

次は8. SAORI呼び出しに進んでください。