最終更新日 2024-09-25

On_噴出メッセージ直前

On_噴出メッセージ直前

武将の吹き出しのメッセージ等、メッセージ的なものが表示される直前のタイミングで
呼ばれるイベントハンドラとなります。
文字列を返すことで、元のメッセージではなく、返したメッセージ内容に変更することが可能です。

使い処

主として特定の武将や特定の条件を満たした場合に、元のメッセージ内容を変更する際に使います。

使用例①

まずは使い方の基礎をしりましょう。
文字列がどういった内容なのかを判定するためには、
「文字列系に○○が含まれる」といった趣旨の判定が必然的に多くなります。

商人から米を買う際のメッセージの認識の仕方①
String^ 天翔記クラス::On_噴出メッセージ直前(String^ 元メッセージ, 噴出メッセージパラメタ型^ パラメタ) {

    if ( 元メッセージ->Contains("他でもない") &&
         元メッセージ->Contains("米を") &&
         元メッセージ->Contains("ほど\xA売") ) {
        return
        "米買い付け用\xA"
        "メッセージだと\xA"
        "認識しました\xA";
    }

    return "";
}

このように、ひたすらString->Containsを繰り返すことでもある程度は判定が出来ますが、
スマートではありません。

正規表現を使えば以下のようになります。

天翔記のメッセージの改行コードは通常とは異なり「\xA」となります。
注意してください。

商人から米を買う際のメッセージの認識の仕方②
String^ 天翔記クラス::On_噴出メッセージ直前(String^ 元メッセージ, 噴出メッセージパラメタ型^ パラメタ) {

    // Regexを短く
    using namespace System::Text::RegularExpressions;

    if ( Regex::Match(元メッセージ, "^他.+?\xA米を.+?ほど\xA売")->Success ) {
        return
            "米買い付け用\xA"
            "メッセージだと\xA"
            "認識しました\xA";
    }

    return "";
}

米だけではなく、馬や鉄砲にも対応するなら、以下のようになります。

商人から米・馬・鉄砲を買う際のメッセージの認識の仕方②
String^ 天翔記クラス::On_噴出メッセージ直前(String^ 元メッセージ, 噴出メッセージパラメタ型^ パラメタ) {

  // Regexを短く
  using namespace System::Text::RegularExpressions;

  if ( Regex::Match(元メッセージ, "^他.+?\xA[米馬鉄砲]+を[0-9]+ほど\xA売")->Success ) {
    return
      "買い付け用\xA"
      "メッセージだと\xA"
      "認識しました\xA";
  }

  return "";
}

使用例②

実際のメッセージをすりかえる際には、「誰が言ったメッセージなのか?」
が一番大きな手掛かりとなるでしょう。

第1人称を取得して、判定する
String^ 天翔記クラス::On_噴出メッセージ直前(String^ 元メッセージ, 噴出メッセージパラメタ型^ パラメタ) {

  using namespace System::Text::RegularExpressions;

  int 第1人称_武将番号 = パラメタ->第1人称_武将番号;

  if (0 <= 第1人称_武将番号 && 第1人称_武将番号 < 武将->配列->Count) {
    auto b = 武将->配列[第1人称_武将番号];

    if (b->列伝番号 == 列挙::武将::列伝番号::真田幸隆) {
      if (Regex::Match(元メッセージ, "^他.+?\xA米を.+?ほど\xA売")->Success) {
        return
          "米買い付け用\xA"
          "メッセージだと\xA"
          "認識しました\xA";
      }
      else if (Regex::Match(元メッセージ, "^他.+?\xA馬を.+?ほど\xA売")->Success) {
        return
          "馬買い付け用\xA"
          "メッセージだと\xA"
          "認識しました\xA";
      }
    }
  }

  return "";
}

使用例③

メッセージを取り扱う以上、その一部分を抽出する、
といったことは欠かせません。
.NET FrameWorkの汎用的な正規表現のメソッドとなるため、詳細は割愛しますが、
以下のように部分文字列を抽出する記述も多くなることでしょう。

第1人称・第2人称の両方を取得して、判定する
String^ 天翔記クラス::On_噴出メッセージ直前(String^ 元メッセージ, 噴出メッセージパラメタ型^ パラメタ) {

  using namespace Text::RegularExpressions;

  int 第1人称_武将番号 = パラメタ->第1人称_武将番号;

  if (0 <= 第1人称_武将番号 && 第1人称_武将番号 < 武将->配列->Count) {
    auto b = 武将->配列[第1人称_武将番号];

    if (b->列伝番号 == 列挙::武将::列伝番号::真田幸隆) {

      // 正規表現オブジェクト
      Regex^ reg1 = gcnew Regex("^他.+?\xA(?<何か>.+?)を.+?ほど\xA売");

      // 元メッセージとの正規表現結果。マッチ結果系の格納
      Match^ match1 = reg1->Match(元メッセージ);

      // マッチしているなら
      if (match1->Success) {

        // 「何か」のところの値を取得
        String^ nani = match1->Groups["何か"]->Value;
        return
          nani + "買い付け用\xA"
          "メッセージだと\xA"
          "認識しました\xA";
      }
    }
  }

  return "";
}

使用例④

噴出しメッセージでは2人の人間が会話をしていることが多いため、
誰が誰に話しているのか?
という第2人称も重要になることが多くなります。

第1人称・第2人称の両方を取得して、判定する
String^ 天翔記クラス::On_噴出メッセージ直前(String^ 元メッセージ, 噴出メッセージパラメタ型^ パラメタ) {

  using namespace System::Text::RegularExpressions;

  int 第1人称_武将番号 = パラメタ->第1人称_武将番号;
  int 第2人称_武将番号 = パラメタ->第2人称_武将番号;

  if (0 <= 第1人称_武将番号 && 第1人称_武将番号 < 武将->配列->Count &&
    0 <= 第2人称_武将番号 && 第2人称_武将番号 < 武将->配列->Count) {
      auto b1 = 武将->配列[第1人称_武将番号];
      auto b2 = 武将->配列[第2人称_武将番号];

    // 話してる人が第1人称。話相手が第2人称
    if (b1->列伝番号 == 列挙::武将::列伝番号::武田信繁 &&
      b2->列伝番号 == 列挙::武将::列伝番号::武田晴信) {

      // 会見のメッセージ
      if (Regex::Match(元メッセージ, "^何をするか")->Success) {
        return
          "信玄と信繁が\xA"
          "会見していると\xA"
          "認識しました\xA";
      }
    }
  }
  else {
    デバッグ出力 << "武将がそれ以外" << endl;
  }

  return "";
}

各シチュエーションのセリフ

各シチュエーションのセリフがどういった内容なのか?
については、「天翔記 wiki」によく纏まっています。

その他

「On_噴出メッセージ直前」イベントハンドラについて、主な解説は以上となります。