最終更新日 2024-09-25

User.version.SDK ~武将~

武将の概念

武将と一言で言っても3つの概念で構成されます。

ここでは、よく利用するパターンをピックアップして解説します。

使用例①

最も単純な例は、やはり武将全員分をforループで回して順次処理をするというものです。
以下は武将が持つプロパティのほんの一部です。

武将のプロパティの利用
    public static void My_戦略_軍団ターン変更時(int 軍団番号)
    {
        foreach (var b in 武将.配列)
        {

            // 「Is_プレイヤ麾下武将」とはプレイヤの配下の武将のこと。
            // プレイヤ大名の第2軍団の武将達も含む概念。
            //
            // プレイヤが直接操作することが可能な武将には、
            // 別途「Is_プレイヤ担当武将」というのもある。
            if (b.Is_プレイヤ麾下武将)
            {
                b.兵士 = 100;
                b.騎馬鉄砲 = true;
                b.兵科 = 列挙.武将.兵科.鉄砲;
                b.職業 = 列挙.武将.職業.僧侶;
                b.技能暗殺 = true;
                b.水軍適性 = 列挙.武将.水軍適性.S;
            }
        }
    }

使用例②

次によくあるのが「特定の武将」を名指して何か処理を施すというものです。
天翔記の武将は、名前が途中で変わってしまう武将もいるため、
最も強力な武将指定手段は、「原則不動にして1300人分の通し番号」と言える「列伝番号」となります。

原始的な記述例
    public static void My_戦略_軍団ターン変更時(int 軍団番号)
    {
        // 自分で全部書く原始的な方法
        int iBushouID = 0xFFFF;

        // forを回して、武田晴信の武将列伝の人と合致すれば…
        // 武将番号を控える
        foreach (var b in 武将.配列)
        {
            if (b.列伝番号 == 列挙.武将.列伝番号.武田晴信)
            {
                iBushouID = b.番号;
            }
        }

        // その番号が配列の範囲に入っていれば…
        if (0 <= iBushouID && iBushouID < 武将.配列.Count)
        {
            武将.配列[iBushouID].士気 = 100;
        }
    }

このような記述が自力で出来ることは重要ですが、
より簡単に逆引きする手段が提供されています。

列伝番号での逆引きを使った記述例
    public static void My_戦略_軍団ターン変更時(int 軍団番号)
    {
        // 列伝から武将番号を逆引きする方法
        int iBushouID = 武将.Find_武将番号(列挙.武将.列伝番号.武田晴信);

        // 武田晴信が居るならば…
        if (0 <= iBushouID && iBushouID < 武将.配列.Count)
        {
            武将.配列[iBushouID].士気 = 100;
        }
    }

「列伝」を持たない自作武将の場合には、「姓名」による指定となるでしょう。
但し、姓名を使用した逆引きは慎重を要します。
その通りの姓名でなければ、逆引きが成立しないためです。
又、姓名は被る武将がいる可能性を否定できません。
それでも、新規武将などには列伝が存在しないため、
以下のような姓名に頼る形の逆引きとなりやすいでしょう。

姓名での逆引きを使った記述例
    public static void My_戦略_軍団ターン変更時(int 軍団番号)
    {
        // 姓名から武将番号を逆引きする方法
        // もし"武田信玄"という名前に改名していると逆引きが成立せず0xFFFFが返ってくる。
        int iBushouID = 武将.Find_武将番号("武田晴信");

        // "武田晴信"という姓名の人物が居るならば…
        if (0 <= iBushouID && iBushouID < 武将.配列.Count)
        {
            武将.配列[iBushouID].士気 = 100;
        }
    }

又、Exists関数を利用すれば、「0 <= 番号 && 番号 < ○○.配列.Count」のチェックが楽になります。

姓名での逆引きを使った記述例
    public static void My_戦略_軍団ターン変更時(int 軍団番号)
    {
        // 姓名から武将番号を逆引きする方法
        // もし"武田信玄"という名前に改名していると逆引きが成立せず0xFFFFが返ってくる。
        int iBushouID = 武将.Find_武将番号("武田晴信");

        // "武田晴信"という姓名の人物が居るならば…
        if (武将.配列.Exists(iBushouID))
        {
            武将.配列[iBushouID].士気 = 100;
        }
    }

使用例③

特定の武将1人ではなく、2人の間柄をどうこう、といった処理をすることも多いものです。

別の女性と結婚する(離婚伴う)
        public static void My_戦略_軍団ターン変更時(int 軍団番号)
    {
        // 列伝から武将番号を逆引きする方法
        int 一人目武将ID = 武将.Find_武将番号(列挙.武将.列伝番号.織田信長);
        int 二人目武将ID = 武将.Find_武将番号(列挙.武将.列伝番号.前田松);

        // 両方とも配列内に収まっている
        if (武将.配列.Exists(一人目武将ID) && 武将.配列.Exists(二人目武将ID) )
        {
            武将.配列[一人目武将ID].Do_結婚(二人目武将ID);
        }
    }

2人の相性なども重要かもしれません。

2人の相性差をデバッグ出力
void 天翔記クラス::My_戦略_軍団ターン変更時(int 軍団番号) {

    public static void My_戦略_軍団ターン変更時(int 軍団番号)
    {
        // 列伝から武将番号を逆引きする方法
        int 一人目武将ID = 武将.Find_武将番号(列挙.武将.列伝番号.織田信長);
        int 二人目武将ID = 武将.Find_武将番号(列挙.武将.列伝番号.長尾景虎);

        // 両方とも配列内に収まっている
        if (武将.配列.Exists(一人目武将ID) && 武将.配列.Exists(二人目武将ID) )
        {
            デバッグ出力 ("★相性差" + 武将.配列[一人目武将ID].Get_相性差(二人目武将ID) );
        }
    }

これら以外にも、数十個の2人の関係性を判定する関数等を提供しています。

使用例④

顔グラを自動で「取込み画像」のものへと差換えたい、といったことも
よくある要望のうちの一つでしょう。

顔グラの取込み自体は、HD版付属の顔グラツールで行えますので、
ここでは大量の顔グラを自動で差し替える場合の記述例となります。

「My_噴出メッセージ直前」のイベントハンドラに記述するのは、
このイベントハンドラが比較的頻繁に呼ばれるイベントハンドラであり、
このイベントハンドラが1度も呼ばれることなく、
武将の顔を見るといった機会はゲーム構成上、まずありえないからです。

全ての武将の顔グラ差し替えを自動化
    public static string My_噴出メッセージ直前(string 元メッセージ, 噴出メッセージパラメタ型 パラメタ)
    {
        // 全ての武将に対して…
        foreach (var b in 武将.配列)
        {

            // 天翔記に元々存在する武将であれば…
            if (0 <= b.列伝番号 && b.列伝番号 < 1300)
            {
                // 差換えの顔が反映されていなければ…
                if (b.差換顔番号 == 0)
                {
                    // 列伝番号に対応させて取込み画像を1300人分用意したので、それへと差換える、といった場合の記述
                    b.差換顔番号 = 列挙.武将.差換顔番号.取込1 + b.列伝番号 + 1;
                }
            }
        }

        return "";
    }

全員分を用意しているといったことはまずなく、
特定の人物分のみを用意していることが多いものです。
そういった場合には、下記のように列伝と値を対応させたキーと値の対応表を作るなどして
順次反映させる形となります。

特定の武将の顔グラ差し替えを自動化
using System.Collections.Generic;


    public static string My_噴出メッセージ直前(string 元メッセージ, 噴出メッセージパラメタ型 パラメタ)
    {
        Dictionary<int, int> dict = new Dictionary<int, int>();

        dict[列挙.武将.列伝番号.長尾景虎] = 3; // 長尾景虎には取込み画像の0003番を
        dict[列挙.武将.列伝番号.松平元康] = 2; // 徳川家康には取込み画像の0002番を

        foreach (var b in 武将.配列)
        {
            // 辞書に登録されている。
            if (dict.ContainsKey(b.列伝番号))
            {
                // まだ差換えたことがなければ
                if (b.差換顔番号 == 0)
                {
                    // 差換えの顔番号は、取込み画像のスタート基点+上の辞書の「キーに対応する値の部分」
                    b.差換顔番号 = 列挙.武将.差換顔番号.取込1 + dict[b.列伝番号];
                }
            }
        }

        return "";
    }

その他

武将について、主な解説は以上となります。
武将関連には他にも非常に多数のプロパティやメソッドがあります。
詳しくはHD.version.SDKソース内の「武将.h」や「武将列挙.h」を参照してみてください。