ScenarioModVer2 更新履歴 v2.6.5.0~

  • v2.7.9.1 ⇒ v2.7.9.5

    • TSMod非互換更新。

      TSMod.dll v2.7.9.5 と ScenarioMod v2.7.9.1 の組み合わせではGet_待機武将戸籍情報リスト()関数が機能しなくなった。

      TSMod.dll v2.7.9.5以上で、Get_待機武将戸籍情報リスト() を利用する場合は、ScenarioMod も v2.7.9.5以上を要する。

    • Get_待機武将情報リスト()

      Get_待機武将戸籍情報リスト()と使い方は同じであり、得られる型が、「武将情報型」と同じものとなる。
      これにより、「該当の待機武将」の詳しい能力を知ることが出来る。
      但し、ラッパー関数などは一切無いので注意すること。(間違ってp武将情報用のラッパー関数を、この待機武将情報に当てはめないこと);

      void カスタム::On_プレイヤ担当ターン《メイン画面》() {
      
          int num = Get_待機武将データ数();
      
          auto p待機武将情報リスト = Get_待機武将情報リスト();
      
          if (p待機武将情報リスト) {
              for (int t = 0; t < num; t++) {
                  デバッグ出力 << (int)p待機武将情報リスト[t].兵数 << endl;
              }
          }
      }
      
    • Get_待機武将登場情報リスト()

      Get_待機武将戸籍情報リスト()と使い方は同じであり、得られる型が、登場年・登場時に仕える大名・登場時に居場所となる城などの情報となる。
      これにより、「最速で何年に登場するのか、どの大名か、どの城か」などを知ることが出来る。

       void カスタム::On_プレイヤ担当ターン《メイン画面》() {
      	int num = Get_待機武将データ数();
      
      	auto p待機武将登場情報リスト = Get_待機武将登場情報リスト();
      	auto p待機武将戸籍情報リスト = Get_待機武将戸籍情報リスト();
      
      	デバッグ出力 << Get_天翔記基準年() << endl;
      
      	int base = Get_天翔記基準年();
      	if (p待機武将登場情報リスト) {
      		for (int t = 0; t < 10; t++) {
      			デバッグ出力 << p待機武将戸籍情報リスト[t]._名字 << p待機武将戸籍情報リスト[t]._名前 << endl;
      			デバッグ出力 << (int)p待機武将登場情報リスト[t].登場年 + base << endl;
      		}
      	}
      
      }
      
    • これらの「待機武将」に関する並びやパラメータは、シナリオエディタで「該当シナリオ」の「未登場武将」タブで確認すると理解が早い。


      なお、シナリオエディタには間違いがあり、 「独立」が2bit(値0-3) となっているが、これは3bit(値0-7)の間違い であり、
      「?」となっているものが、この「独立」の残り1ビットに相当する。
      よって、不明なデータは無い。

    • その他、数点の関数バグの修正

  • v2.7.8.3 ⇒ v2.7.9.1

    • 新たなるイベントハンドラ、「On_待機武将登場直後」

      待機武将が登場した直後に実行されるイベントハンドラ。

      詳細はこちら

    • 新たなるイベントハンドラ、「On_仮想武将登場直後」

      仮想武将が登場した直後に実行されるイベントハンドラ。

      詳細はこちら

    • 新たなるイベントハンドラ、「On_待機武将登場直前」

      待機武将が登場した直前に実行されるイベントハンドラ。

      詳細はこちら

    • Get_待機武将登場済人数()

      待機武将のうち、すでに登場済みの武将の人数を得る。
      この数値は、「次に登場する待機武将」を割り出すのに使える。

    • Get_待機武将データ数()

      該当のシナリオにおいて、「待機武将のデータ数」を取得する。
      実行するシナリオや、改変シナリオによって、「待機武将」の数が異なるので、
      「待機武将一覧」を総なめしたい場合などに利用する。

    • Get_待機武将戸籍情報リスト()

      該当のシナリオにおいて、「待機武将の武将戸籍情報」に類するデータをを取得する。

      void カスタム::On_プレイヤ担当ターン《メイン画面》() {
      
          int num = Get_待機武将データ数();
      
          auto p待機武将戸籍情報リスト = Get_待機武将戸籍情報リスト();
      
          if (p待機武将戸籍情報リスト) {
              for (int t = 0; t < num; t++) {
                  デバッグ出力 << p待機武将戸籍情報リスト[t]._名字 << p待機武将戸籍情報リスト[t]._名前 << endl;
              }
          }
      }
      

      登場済みの人数もわかっているため、次に登場する武将の顔番号を取得することも出来る。

      void カスタム::On_プレイヤ担当ターン《メイン画面》() {
      
          int 登場済の数 = Get_待機武将登場済人数();
      
          auto p待機武将戸籍情報リスト = Get_待機武将戸籍情報リスト();
      
          if (p待機武将戸籍情報リスト) {
      
              auto next武将 = p待機武将戸籍情報リスト[登場済の数];
      
              if (next武将.顔番号 == 顔番号::明智光秀) {
                  デバッグ出力 << next武将._名字 << next武将._名前 << endl;
              }
          }
      
      }
      
  • v2.7.8.3 ⇒ v2.7.8.3

    • 新たなるイベントハンドラ、「On_シナリオデータ反映直後」

      詳細はこちら

    • Get_軍団新設候補情報(int 大名番号【配列用】)という関数の追加

      大名内に軍団を新設するのは良いが、
      何もないところから、「軍団作成可能な情報」を正確に集めるのは大変である。

      この関数は、

      • 今、指定の大名に新たに軍団を新設することは、様々な条件を考えて可能なのか?
      • どの武将を軍団長にするのか、候補リスト全て
      • どこの城を軍団長の拠点城として選択できるのか、そのリスト全て
      • 軍団の割当番号(1~8の番号)で、余っている番号は何か、そのリスト全て

      などの面倒な計算を全て肩代わりして、一気に返り値として返してくれます。

      この関数で得られた結果値の情報を元に、
      Set_軍団新設(...)関数を利用する
      と、大名内に新たな軍団を作ることが可能となります。

      Get_軍団新設候補情報(...)は返り値として、「軍団新設候補情報型」の値を返し、その値は、

      • Is新設可能(結局、いろいろ計算した結果、軍団は新設可能なのか?)
      • 候補軍団割当番号リスト(余っている軍団割当番号(1~8)は何なのか?
      • 候補城番号【配列用】リスト(どこの城で軍団を新設できるのか、その候補の城番号「配列用」のリスト)
      • 候補武将番号【配列用】リスト(どの武将を軍団長として任命できるのか、その候補の城番号「配列用」のリスト)

      をフィールドとして持ちます。

      void カスタム::On_シナリオデータ反映直後(int シナリオ番号) {
       
          if (3 <= シナリオ番号 && シナリオ番号 <= 5) {
       
              int iBushouID = Get_武将番号【配列用】(顔番号::織田信長);
       
              if (0 <= iBushouID && iBushouID < 最大数::武将情報::配列数) {
      
                  if (p武将戸籍情報[iBushouID].状態 == 状態::大名) {
      
                      // 信長の大名としての番号
                      int pDaimyoID = p武将情報[iBushouID].所属大名【大名番号】 - 1;
       
                      // 信長家で、軍団を新設したいが、可能なのか?
                      // どのような「武将」が新たな軍団長となれるのか、どのような「城」を軍団長の本拠と出来るのか
                      // そのような便利な情報を返してもらう。
                      auto ret = Get_軍団新設候補情報(pDaimyoID);
       
                      デバッグ出力 << "この大名が軍団を新設することは?" << (ret.Is新設可能 ? "可能" : "不可能") << endl;
       
                      if (ret.Is新設可能) {
       
                          デバッグ出力 << "2~8で余っている軍団割当番号は? ";
                          for each(auto wn in ret.候補軍団割当番号リスト) {
                              デバッグ出力 << wn << " ";
                          }
                          デバッグ出力 << endl;
       
                          デバッグ出力 << "どの城に軍団を新設できますか?";
                          for each(auto cn in ret.候補城番号【配列用】リスト) {
                              デバッグ出力 << Get_城名(cn) + Get_城称(cn) << " ";
                          }
                          デバッグ出力 << endl;
       
                          デバッグ出力 << "誰を軍団に任命できますか?";
                          for each(auto bn in ret.候補武将番号【配列用】リスト) {
                              デバッグ出力 << Get_名字(bn) + Get_名前(bn) << " ";
                          }
                          デバッグ出力 << endl;
                      }
                  }
              }
          }
      }
      


    • int Set_軍団新設(int 武将番号【配列用】, int 城番号【配列用】, 軍団新設候補情報型 チェック情報)

      このような、Get_軍団新設候補情報(...)関数で得られた情報があることで、
      その結果の値の中から、自分で選択し、Set_軍団新設(...)を安全に実行することが出来ます。

      軍団新設に成功した場合は、返り値として「軍団番号【配列用】」が返ってきます。

      void カスタム::On_プレイヤ担当ターン《メイン画面》() {
          int iBushouID = Get_武将番号【配列用】(顔番号::織田信長);
      
          if (0 <= iBushouID && iBushouID < 最大数::武将情報::配列数) {
      
              if (p武将戸籍情報[iBushouID].状態 == 状態::大名) {
      
                  int pDaimyoID = p武将情報[iBushouID].所属大名【大名番号】 - 1;
      
                  auto ret = Get_軍団新設候補情報(pDaimyoID);
      
                  if (ret.Is新設可能) {
                      
                      srand((unsigned)time(NULL));
      
                      // シャカシャカ
                      std::random_shuffle(ret.候補武将番号【配列用】リスト.begin(), ret.候補武将番号【配列用】リスト.end());
                      int iRndBushouID = ret.候補武将番号【配列用】リスト[0];
      
                      // シャカシャカ
                      std::random_shuffle(ret.候補城番号【配列用】リスト.begin(), ret.候補城番号【配列用】リスト.end());
                      int iRndCastleID = ret.候補城番号【配列用】リスト[0];
      
                      // 候補のうち、ランダムで、軍団を新設する
                      int iGundanID = Set_軍団新設(iRndBushouID, iRndCastleID, ret);
                      if (iGundanID != 0xFFFF) {
                          デバッグ出力 << "軍団番号【配列用】" << iGundanID << "として、軍団が新設された" << endl;
                      }
                      else {
                          デバッグ出力 << "軍団の新設には失敗した" << endl;
                      }
                  }
              }
          }
      }
      

      武将候補リストや、城候補リストが存在することで、「安全に」「誰か特定の人物」を、
      軍団長にすることが出来るようになります。

       void カスタム::On_プレイヤ担当ターン《メイン画面》() {
          int iBushouID = Get_武将番号【配列用】(顔番号::織田信長);
      
          if (0 <= iBushouID && iBushouID < 最大数::武将情報::配列数) {
      
              if (p武将戸籍情報[iBushouID].状態 == 状態::大名) {
      
                  int pDaimyoID = p武将情報[iBushouID].所属大名【大名番号】 - 1;
      
                  auto ret = Get_軍団新設候補情報(pDaimyoID);
      
                  if (ret.Is新設可能) {
                      
                      srand((unsigned)time(NULL));
                      // 城はシャカシャカ
                      std::random_shuffle(ret.候補城番号【配列用】リスト.begin(), ret.候補城番号【配列用】リスト.end());
                      int iRndCastleID = ret.候補城番号【配列用】リスト[0];
      
                      int iShibataBushouID = Get_武将番号【配列用】(顔番号::柴田勝家);
                      // (本来はiShibataBushouIDは範囲チェックをした方がよいが、「リストの中にあること」が
                      // 範囲チェック替わりとなるので、省略
      
                      // 今、この瞬間、軍団長になれる武将候補リストの中に、勝家は含まれてる?
                      auto iter = std::find(ret.候補武将番号【配列用】リスト.begin(), ret.候補武将番号【配列用】リスト.end(), iShibataBushouID);
      
                      // 候補内に柴田勝家が居た
                      if (iter != ret.候補武将番号【配列用】リスト.end()) {
      
                          // 候補のうち、勝家で、ランダム城で、軍団を新設する
                          int iGundanID = Set_軍団新設(iShibataBushouID, iRndCastleID, ret);
                          if (iGundanID != 0xFFFF) {
                              デバッグ出力 << "軍団番号【配列用】" << iGundanID << "として、軍団が新設された" << endl;
                          }
                          else {
                              デバッグ出力 << "軍団の新設には失敗した" << endl;
                          }
                      }
                  }
              }
          }
      }
      


    • int Set_軍団独立(int 軍団番号【配列用】)

      軍団をまるまる大名へと独立させます。

      状況が明確であれば、以下のように対象を指定するだけで良いでしょう。

      void カスタム::On_シナリオデータ反映直後(int シナリオ番号) {
      
          if (シナリオ番号 == 5) {
              // 明智光秀を探す
              int iBushouID = Get_武将番号【配列用】(顔番号::明智光秀);
              // 登場している
              if (0 <= iBushouID && iBushouID < 最大数::武将情報::配列数) {
                  // 光秀は軍団長だ
                  if (p武将戸籍情報[iBushouID].状態 == 状態::軍団長) {
      
                      // 所属軍団
                      int iGundanID = p武将情報[iBushouID].所属軍団【軍団番号】 - 1;
      
                      // 該当の軍団長は、大名として独立する
                      int iDaimyoID = Set_軍団独立(iGundanID);
      
                      // 成否をチェック
                      if (iDaimyoID != 0xFFFF) {
                          デバッグ出力 << "明智光秀は独立に成功した" << endl;
                      }
                  }
      
              }
          }
      }
      


      「独立させた軍団」をそのまま、「独立した大名」とするのも、
      Set_軍団新設(...)関数の返り値をそのまま使えるので、楽です。

      void カスタム::On_メインゲーム開始() {
          int iBushouID = Get_武将番号【配列用】(顔番号::織田信長);
      
          if (0 <= iBushouID && iBushouID < 最大数::武将情報::配列数) {
      
              if (p武将戸籍情報[iBushouID].状態 == 状態::大名) {
      
                  int pDaimyoID = p武将情報[iBushouID].所属大名【大名番号】 - 1;
      
                  auto ret = Get_軍団新設候補情報(pDaimyoID);
      
                  if (ret.Is新設可能) {
      
                      srand((unsigned)time(NULL));
      
                      std::random_shuffle(ret.候補城番号【配列用】リスト.begin(), ret.候補城番号【配列用】リスト.end());
                      int iRndCastleID = ret.候補城番号【配列用】リスト[0];
      
                      int iShibataBushouID = Get_武将番号【配列用】(顔番号::柴田勝家);
                      // (本来はiShibataBushouIDは範囲チェックをした方がよいが、「リストの中にあること」が
                      // 範囲チェック替わりとなるので、省略
      
                      // シャカシャカ
                      auto iter = std::find(ret.候補武将番号【配列用】リスト.begin(), ret.候補武将番号【配列用】リスト.end(), iShibataBushouID);
      
                      // 候補内に柴田勝家が居た
                      if (iter != ret.候補武将番号【配列用】リスト.end()) {
      
                          // 候補のうち、勝家で、ランダム城で、軍団を新設する
                          int iGundanID = Set_軍団新設(iShibataBushouID, iRndCastleID, ret);
                          if (iGundanID != 0xFFFF) {
                              デバッグ出力 << "軍団番号【配列用】" << iGundanID << "として、軍団が新設された" << endl;
      
                              // 該当の軍団長は、大名として独立する
                              int iDaimyoID = Set_軍団独立(iGundanID);
      
                              // 成否をチェック
                              if (iDaimyoID != 0xFFFF) {
                                  デバッグ出力 << Get_名前(iShibataBushouID) << "は大名化に成功した" << endl;
                              }
                              else {
                                  デバッグ出力 << Get_名前(iShibataBushouID) << "は大名化に失敗した" << endl;
                              }
      
                          }
                          else {
                              デバッグ出力 << "軍団の新設には失敗した" << endl;
                          }
                      }
                  }
              }
          }
      }
      
    • bool Set_非本拠城所属軍団(int 城番号【配列用】, int 新軍団番号【配列用】)

      同じ大名配下、という前提で、軍団A配下の城を、軍団B配下へと切り替えます。
      対象の城は「非本拠の城」である必要があります。
      非本拠とは、「大名がいない城」「軍団長がいない城」を指します。

      一番簡単な例は、「状況が決め打ちできる」時でしょう。
      使い方を理解するという点で、有効です。

      void カスタム::On_シナリオデータ反映直後(int シナリオ番号) {
      
          if (シナリオ番号 == 5) {
              int i二条城CastleID = 城::城配列番号::二条城;
      
              int i光秀BushouID = Get_武将番号【配列用】(顔番号::明智光秀);
      
              // 光秀は居る&軍団長
              if (0 <= i光秀BushouID && i光秀BushouID < 最大数::武将情報::配列数) {
                  if (p武将戸籍情報[i光秀BushouID].状態 == 状態::軍団長) {
      
                      int 光秀GundanID = p武将情報[i光秀BushouID].所属軍団【軍団番号】 - 1;
      
                      Set_非本拠城所属軍団(i二条城CastleID, 光秀GundanID);
      
                  }
              }
          }
      }
      


      大抵の場合は、上記のように「城が特定を名指しで」とはいかないことでしょう。
      こういった場合は、軍団配下の城から割り出していきましょう。
      (もちろん色々な考え方があります)

      勝家が持っている城を、可能な限り秀吉に渡してみましょう。

      void カスタム::On_シナリオデータ反映直後(int シナリオ番号) {
      
          if (シナリオ番号 == 5) {
      
              int i勝家BushouID = Get_武将番号【配列用】(顔番号::柴田勝家);
              int i秀吉BushouID = Get_武将番号【配列用】(顔番号::羽柴秀吉);
      
              // 両方居る
              if (0 <= i勝家BushouID && i勝家BushouID < 最大数::武将情報::配列数 &&
                  0 <= i秀吉BushouID && i秀吉BushouID < 最大数::武将情報::配列数) {
      
                  // 両方軍団長
                  if (p武将戸籍情報[i勝家BushouID].状態 == 状態::軍団長 &&
                      p武将戸籍情報[i秀吉BushouID].状態 == 状態::軍団長) {
      
                      int 勝家GundanID = p武将情報[i勝家BushouID].所属軍団【軍団番号】 - 1;
      
                      // ----------------------勝家が持っている城のリスト(但し、勝家自身がいる城を除く -----------------------
                      auto 勝家城リスト = Get_軍団所持城番号リスト【配列用】(勝家GundanID);
      
                      番号リスト型 本拠以外の勝家城リスト;
      
                      for each (auto iCastleID in 勝家城リスト) {
                          // 大名や軍団長が居ない
                          if (p城情報[iCastleID].本城 == 本城::非本拠) {
                              本拠以外の勝家城リスト.push_back(iCastleID);
                          }
                      }
      
                      // ----------------------秀吉は勝家が持っている城をどんどん奪う -----------------------
                      int 秀吉GundanID = p武将情報[i秀吉BushouID].所属軍団【軍団番号】 - 1;
      
                      for each(int iCastleID in 本拠以外の勝家城リスト) {
                          Set_非本拠城所属軍団(iCastleID, 秀吉GundanID);
                      }
                  }
      
              }
          }
      
      }
      
      


    • 軍団や大名情報と、マップ上の描画が食い違った場合

      上記で「大名としての独立」に関する関数は、
      実行するイベントハンドラによっては、
      画面上の描画が反映されません。

      そのような場合は、フェイドアウト()、フェイドイン()関数を利用しましょう。

  • v2.7.1.1 ⇒ v2.7.8.3

    • Set_年齢(...) 関数の追加

      武将に年齢を設定する際のラップ関数

    • Get_軍団所持城番号リスト【配列用】(...)

      とある軍団下に属する全ての城の番号リストを得るためのラップ関数

    • Get_大名所持城番号リスト【配列用】(...)

      とある大名下に属する全ての城の番号リストを得るためのラップ関数

  • v2.6.9.0 ⇒ v2.7.1.1

    • Set_鉄砲適性 のバグ

      Set_鉄砲適性で、範囲チェックに不具合があり、値を設定出来ないバグ修正

    • 選択武将ダイアログ表示のバグ

      武将を選択せずに、ダイアログを終了した際に、返り値が不正であるバグ修正

  • v2.6.8.0 ⇒ v2.6.9.0

    • 「家名」を表示しよとする直前に呼び出されるイベントハンドラを追加。

      詳細は、「On_家名表示直前

  • v2.6.7.7 ⇒ v2.6.8.0

    バグ修正のみ。

    • 城情報列挙.h

      「列挙::城::城絵背景::平野」の値が、「2」という間違った値となっていた。
      正しくは「3」

    • 言葉遣い情報型.h(.cpp)

      言葉遣い情報型.hの「%願います%」において、一部条件を満たすと、「ござった」という無関係なメッセージが出る不具合。
      本来は「お願いいたす」が正しい。

  • v2.6.7.6 ⇒ v2.6.7.7

    • バグ修正のみ。

      「列挙::家宝::家宝画像::***」について、一部番号が間違っていたのを修正。

  • v2.6.7.5 ⇒ v2.6.7.6

    • バグ修正のみ。

      「季節::春」など、季節に関する列挙に関して名前空間を省略した記述が出来なくなっていた問題を修正。

  • v2.6.7.4 ⇒ v2.6.7.5

    • 状況に応じて、武将の最大兵数を変化させるためのイベントハンドラを追加

      詳細は、「On_武将最大兵数要求時

    • 型名が1つ変更

      型名に統一性が無かったため、「攻撃方法決定時型パラメタ」という型名が「攻撃方法決定時パラメタ型」と変更された。

  • v2.6.7.3 ⇒ v2.6.7.4

    • 戦争中の武将ユニットの移動残量を適切に変更することが可能となった。

      詳細は、「On_移動力残量変更時《戦争画面》

    • 戦争画面が終了した後、かつ、捕虜処理が始まる前のタイミングで実行されるイベントハンドラが追加された。

      詳細は、「On_戦争画面終了()

  • v2.6.7.2 ⇒ v2.6.7.3

    • 武将詳細画面の「〇〇隊」の「隊」が変更可能となった

      詳細は、「On_部隊名表示直前

  • v2.6.7.0 ⇒ v2.6.7.2

    • 列挙名前空間

      今回の修正は主として、値比較の対象を全て「列挙」という名前空間に入れるものです。

      void カスタム::On_シナリオ大名選択直前(int シナリオ番号) {
          int iBushouIDA = Get_武将番号【配列用】(列挙::武将::顔番号::織田信長);
      
          int iBushouIDB = Get_武将番号【配列用】(顔番号::織田信長); // 衝突しにいくいであろうところまでは、名前空間がすでにusing済み
      
          p家宝情報[列挙::家宝::家宝配列番号::ルソン壺].家宝画像 = 列挙::家宝::家宝画像::花入;
      
          p家宝情報[家宝配列番号::ルソン壺].家宝画像 = 家宝画像::花入; // 衝突しにいくいであろうところまでは、名前空間がすでにusing済み
      
          p城情報[列挙::城::城配列番号::二条城].兵質 = 列挙::城::兵質::悪;
      
          p城情報[城配列番号::二条城].兵質 = 兵質::悪;  // 衝突しにいくいであろうところまでは、名前空間がすでにusing済み
      }
      
    • Set_コマンド行動力設定関数の名称変更

      Set_コマンド行動力設定という関数の名称、及び、使用方法が変化しました。

      Set_コマンド行動力(メイン画面::行動力コマンド名::手切, 10);
      

      のような形となりました。

  • v2.6.6.9 ⇒ v2.6.7.0

    • 適正→適性へ

      今回の修正は主として、不適正なフィールド名の変更となります。

      長らく放置されていた「戦闘適正」といった「適性」を「適正」と
      間違って表記されていた全ての箇所が「適性」と修正された。

      この変更により多くのコンパイルエラーを引き起こす可能性があるので、
      手持ちのソースの「適正」→「適性」と 一喝で置き換えるなどして対処してください。

    • 混乱状態::挑発→混乱状態::挑発混乱へ

      混乱状態::挑発は名称が紛らわしいため、混乱状態::挑発混乱と命名が変更となった。

  • v2.6.6.8 ⇒ v2.6.6.9

    • 官位所有者や家宝所有者を変更する際、能力変更も一緒に行うための関数

      • Set_官位所有者変更
      • Set_家宝所有者変更

      といった関数が追加された。

      これら所有者の変更には、常に武将の能力の変更が伴うため、
      これまではメンドクサイ処理を自身で記述する必要があったが、関数として提供されたこととなる。

    • 家宝や官位による上昇値を除いた値取得のための関数

      • Get_元最大政才
      • Get_元最大戦才
      • Get_元最大智才
      • Get_元野望
      • Get_元魅力

      といった、武将の能力のうち、家宝や官位による上昇幅を覗いた値を得るための専用の関数が追加された。

    • その他

      • Get_家宝番号【配列用】

      という、家宝名から家宝番号【配列用】を逆引きするための関数が追加された。

  • v2.6.6.7 ⇒ v2.6.6.8

    • 戦国名城物語型& カスタム::On_戦国名城物語要求時(int 城番号)

      というイベントハンドラが追加された。

      詳細は、「こちら

  • v2.6.5.7 ⇒ v2.6.6.7

    • 戦国武将列伝型& カスタム::On_戦国武将列伝要求時(int 武将番号, int 顔番号)

      というイベントハンドラが追加された。

      詳細は、「こちら

    • 戦国名物事典型& カスタム::On_戦国名物事典要求時(int 家宝番号)

      というイベントハンドラが追加された。

      詳細は、「こちら

  • v2.6.5.5 ⇒ v2.6.5.7

    • エンディング情報型& カスタム::On_エンディング判定時(int 大名番号)

      というイベントハンドラが追加された。

      詳細は、「こちら

    • カスタム条件として、OR条件::戦争::鉄砲不可

      が追加された。

      詳細は、「こちら

  • v2.6.5.3 ⇒ v2.6.5.5

    • 使用対象の全ての「構造体」「関数」などに対して、「入力補完用のコメント」を付記

      使用されそうな関数や型に関しては、原則全て「Summaryタイプ」のコメントを付記した。
      (C#などで使われるVisualStudio専用スタイルのコメント)

      便利に機能するはずである。

  • v2.6.5.2 ⇒ v2.6.5.3

    • mrubyの除去

      ScenarioModからmruby部分に関するすべての機能がカットされた。
      mrubyのモジュールが、「Visual Studio の異なるバージョン間」で互換性が保てないため。

      ScenarioModでは、外部テキストスクリプトとしてはLuaを中心に据えているのでそちらを利用してください。
      又、IronPythonModも提供しています。

  • v2.6.5.2 ⇒ v2.6.5.2

  • v2.6.5.1 ⇒ v2.6.5.2

    • Set_武将誕生の仕様変更

      Set_武将誕生の関数が、「失敗」した際の返り値が、意図せず0xFFFFになっていたのを修正た。
      正しくは該当関数に付記しているコメント通り-1である。

    • LUA::例外型の型を変更

      「LUA::例外型」や「MRUBY::例外型」はこれまで「int型」であったが、「std::exception」の「派生型」となった。
      よって標準のC++例外型として扱うことが可能となった。

  • v2.6.5.0 ⇒ v2.6.5.1

    • 独自ファイルへの拡張セーブデータ簡易機能

      「独自のファイル」に拡張データをセーブするための簡易機能が追加された。

      今回提供の簡易機能は、別ファイル名(自分で名前を付ける)に別途拡張データをセーブするものとなります。

      特に名前を変更しなかった場合は、「SAVEDAT.N6PEX」というファイルに、拡張部分のデータが格納されるようになります。

    • TSModのセーブデータの拡張との違い

      TSModでは、セーブデータファイル(SAVEDATA.N6P)そのものに「拡張データ」を持っています。
      この一部分を利用して、ScenarioModには「Get_フラグ()」や「Set_フラグ()」といった関数が提供されています。

      しかし、セーブやロードと同時に、ある程度まとまった量の「独自のデータ」の保存や復元を行いたいという場合、
      ScenarioModへと提供されている「フラグの機能」では、まかないないため 「各自が全て自前」でその機構を記述する必要があります。

      今回はそれをある程度自動化し、短いソース記述で目的を達成する、という機能となります。

    • カスタム駆動関数.cpp

      // 最終的にセーブしたいデータの「構造体(あるいはクラス)」を定義する。名前は自由。
      // 構造体内のメンバフィールドの「型」として使えるのは「プリミティブ型」及び「ポインタ」である。
      // あくまで「メモリブロック」として保存される、
      // 何ビット目が0か1か、それだけが考慮対象である。
      // よって一度保存した後に、「構造体のサイズ」や「フィールドの並び」を変更すると、読み込みデータが瓦解する。
      // これを防止するため、下の例のように「予備領域」を事前に持っておき、「予備領域」を切り崩しながら、新たなフィールドを追加する。
      //------------保--存--対--象------------------------------------------------------------------
      struct my拡張構造体 {
          int a;
          char sz[12]; // string型を使うのは許されない。string型はプリミティブ型ではないので、コンパイラのバージョンが変わるだけで「メモリブロック上でのサイズ」が変化してしまうため。
                       // 「C++ プリミティブ型」などでググって使える「型」を検索すること。
          byte 予備[40]; // 予備データ。
      };
      //--------------------------------------------------------------------------------------------
      
      // 緑の所は構造体の名前を指定する。青の所は自由な名前をつければ良い。
      拡張セーブデータ情報型<my拡張構造体> my拡張セーブデータ;
      
      // この行を記述しておくと、後々変数に短い名前でアクセスできる。
      // 下記の例では、「my拡張セーブデータ.拡張パラメタ」に「pex」という別名で参照できるようにしている。
      auto &pex = my拡張セーブデータ.拡張パラメタ;
      
      
      // 以下は「ScenaroModの既存のイベントハンドラ」に記述を足す。
      
      void カスタム::On_トップメニュー表示時() {
          my拡張セーブデータ.Do_メモリクリア();
      }
      
      void カスタム::On_セーブデータ読込時(int スロット番号, string セーブファイル名) {
          my拡張セーブデータ.On_セーブデータ読込時(スロット番号, セーブファイル名); // 拡張データを独自のファイルからロード
      }
      
      void カスタム::On_セーブデータ保存時(int スロット番号, string セーブファイル名) {
          my拡張セーブデータ.On_セーブデータ保存時(スロット番号, セーブファイル名); // 拡張データを独自のファイルにセーブ
      }
      

      以上で準備が完了。

      あとは、

      void カスタム::On_軍団ターン変更《メイン画面》(int 軍団番号) {
          pex.a = 30;
          string s = "あああ";
          strcpy( pex.sz, s.c_str() ); // string型ではなく、char配列なので、strcpyを使う必要がある。
      }
      

      などと自由に使える。

      これはセーブのタイミングで、セーブされ、ロードのタイミングで、読み込まれる。

    • 拡張用のセーブデータを別途作成する例

      多くのデータ項目に拡張データを持つような場合、
      例えば 「拡張セーブデータ.h」(ファイル名自由)
      といったファイル名で自分で好きなように下のように定義して、

      namespace ユーザー {
      
          // 武将1人分の拡張パラメタ
          struct 武将情報EX型 {
              int a;                    // 4バイトの数値
              int b;                    // 4バイトの数値
              int c;                    // 4バイトの数値
              char 渾名[15];            // 14バイト+NULLの文字列(もしくは15バイトのデータ)
      
              byte 予備[40];            // 40バイトを保持。将来データを増やした時に、ここから削って増やす。合計のバイト数をかならずぴったり合わせる。
          };
      
          // 大名家1つ分の拡張パラメタ
          struct 大名情報EX型 {
              int a;                    // 4バイトの数値
              int b;                    // 4バイトの数値
              byte 予備[20];            // 予備として20バイトを保持。将来データを増やした時に、ここから削って増やす。合計のバイト数をかならずぴったり合わせる。
          };
      
          // 軍団1つ分の拡張パラメタ
          struct 軍団情報EX型 {
              int a;                    // 4バイトの数値
              int b;                    // 4バイトの数値
              byte 予備[20];            // 予備として20バイトを保持。将来データを増やした時に、ここから削って増やす。合計のバイト数をかならずぴったり合わせる。
          };
      
          // 城1つ分の拡張パラメタ
          struct 城情報EX型 {
              int a;                    // 4バイトの数値
              int b;                    // 4バイトの数値
              byte 予備[20];            // 予備として20バイトを保持。将来データを増やした時に、ここから削って増やす。合計のバイト数をかならずぴったり合わせる。
          };
      
          // 家宝1つ分の拡張パラメタ
          struct 家宝情報EX型 {
              int a;                    // 4バイトの数値
              int b;                    // 4バイトの数値
              byte 予備[20];            // 予備として20バイトを保持。将来データを増やした時に、ここから削って増やす。合計のバイト数をかならずぴったり合わせる。
          };
      
          // 官位1つ分の拡張パラメタ
          struct 官位情報EX型 {
              int a;                    // 4バイトの数値
              int b;                    // 4バイトの数値
              byte 予備[20];            // 予備として20バイトを保持。将来データを増やした時に、ここから削って増やす。合計のバイト数をかならずぴったり合わせる。
          };
      
          struct 予備情報EX型 {
              int 予備[100];            // 予備として100バイトを保持。将来データを増やした時に、ここから削って増やす。合計のバイト数をかならずぴったり合わせる。
          };
      
          // 1つのセーブスロットに対応する拡張データ
          struct 自分の拡張セーブデータ型 {
              武将情報EX型 p武将情報[最大数::武将情報::配列数];   // 武将の拡張データ。p武将情報の配列と同じ番号で良い。
              大名情報EX型 p大名情報[最大数::大名情報::配列数];   // 大名の拡張データ。p大名情報の配列と同じ番号で良い。
              軍団情報EX型 p軍団情報[最大数::軍団情報::配列数];   // 軍団の拡張データ。p軍団情報の配列と同じ番号で良い。
              城情報EX型   p城情報[最大数::城情報::配列数];       // 城の拡張データ。p城情報の配列と同じ番号で良い。
              家宝情報EX型 p家宝情報[最大数::家宝情報::配列数];   // 家宝の拡張データ。p家宝情報の配列と同じ番号で良い。
              官位情報EX型 p官位情報[最大数::官位情報::配列数];   // 官位の拡張データ。p官位情報の配列と同じ番号で良い。
              予備情報EX型 p汎用情報;                             // これら以外の何か汎用のデータ。
          };
      }
      
      

      といったファイル名で保存し、 カスタム駆動関数.cpp

      #include "拡張セーブデータ.h"
      
      拡張セーブデータ情報型<ユーザー::自分の拡張セーブデータ型> my拡張セーブデータ;
      
      auto &pex = my拡張セーブデータ.拡張パラメタ;
      
      // 後は、同じ
      
      

      といった感じにすれば良いだろう。

      あとは、短い名前として用意した「pex」で値に自由にアクセス出来る。

      void カスタム::On_相場変更直前() {
          int iBushouID = Get_武将番号【配列用】(顔番号::武田晴信); // 武田信玄
          if ( 0<=iBushouID && iBushouID < 最大数::武将情報::配列数) {
              デバッグ出力 << pex.p武将情報[iBushouID].渾名 << endl;
          }
      }
      
  • v2.6.2.9 ⇒ v2.6.5.0

    • Visual Studio 2013以上を必須環境へ

      天翔記.jpのほぼ全てのプロジェクトがVisual Studio 2013へと更新されました。

      これに伴い、ScenaroModも Visual Studio 2013 Community 以上のバージョンを必須バージョンとします。
      (今回の変更により、事実上、ScenarioModの開発には、Windows7以上のOSが必須となります。)