の3点を追加
元来は、「大名役職」と「軍団役職」は別管理であり、大名家が役職を1つだけ持っている際は、
大名情報にだけ役職が付き、第1軍団の軍団情報には役職が付かないのであるが、
これは取り扱いに戸惑いを覚えるであろうから、Get_軍団役職(...)やSet_軍団役職(...)において、
引数にしてした軍団が第1軍団であれば、大名の役職を対象とするようにした。
すでにWebサービスが機能していないため、削除した。
いくつかの関数のミスリードに繋がる不適切なコメントの修正
選択大名ダイアログ表示(...) の関数にて利用する
の3つが提供されていなかった不具合を修正。
/D "_HAS_STD_BYTE=0"を付け加えただけの変更。
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_待機武将戸籍情報リスト()と使い方は同じであり、得られる型が、「武将情報型」と同じものとなる。
これにより、「該当の待機武将」の詳しい能力を知ることが出来る。
但し、ラッパー関数などは一切無いので注意すること。(間違ってp武将情報用のラッパー関数を、この待機武将情報に当てはめないこと);
void カスタム::On_プレイヤ担当ターン《メイン画面》() { int num = Get_待機武将データ数(); auto p待機武将情報リスト = Get_待機武将情報リスト(); if (p待機武将情報リスト) { for (int t = 0; t < num; t++) { デバッグ出力 << (int)p待機武将情報リスト[t].兵数 << endl; } } }
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ビットに相当する。
よって、不明なデータは無い。
待機武将が登場した直後に実行されるイベントハンドラ。
詳細はこちら
仮想武将が登場した直後に実行されるイベントハンドラ。
詳細はこちら
待機武将が登場した直前に実行されるイベントハンドラ。
詳細はこちら
待機武将のうち、すでに登場済みの武将の人数を得る。
この数値は、「次に登場する待機武将」を割り出すのに使える。
該当のシナリオにおいて、「待機武将のデータ数」を取得する。
実行するシナリオや、改変シナリオによって、「待機武将」の数が異なるので、
「待機武将一覧」を総なめしたい場合などに利用する。
該当のシナリオにおいて、「待機武将の武将戸籍情報」に類するデータをを取得する。
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; } } }
詳細はこちら
大名内に軍団を新設するのは良いが、
何もないところから、「軍団作成可能な情報」を正確に集めるのは大変である。
この関数は、
などの面倒な計算を全て肩代わりして、一気に返り値として返してくれます。
この関数で得られた結果値の情報を元に、
Set_軍団新設(...)関数を利用する
と、大名内に新たな軍団を作ることが可能となります。
Get_軍団新設候補情報(...)は返り値として、「軍団新設候補情報型」の値を返し、その値は、
をフィールドとして持ちます。
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; } } } } }
このような、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; } } } } } }
軍団をまるまる大名へと独立させます。
状況が明確であれば、以下のように対象を指定するだけで良いでしょう。
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; } } } } } }
同じ大名配下、という前提で、軍団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); } } } } }
上記で「大名としての独立」に関する関数は、
実行するイベントハンドラによっては、
画面上の描画が反映されません。
そのような場合は、フェイドアウト()、フェイドイン()関数を利用しましょう。
武将に年齢を設定する際のラップ関数
とある軍団下に属する全ての城の番号リストを得るためのラップ関数
とある大名下に属する全ての城の番号リストを得るためのラップ関数
Set_鉄砲適性で、範囲チェックに不具合があり、値を設定出来ないバグ修正
武将を選択せずに、ダイアログを終了した際に、返り値が不正であるバグ修正