コード例 #1
0
ファイル: PilotDataList.cs プロジェクト: 7474/SRC
        // パイロットデータリストにデータを追加
        public PilotData Add(string pname)
        {
            var new_pilot_data = new PilotData(SRC);

            new_pilot_data.Name = pname;
            colPilotDataList.Add(new_pilot_data, pname);
            return(new_pilot_data);
        }
コード例 #2
0
ファイル: PilotDataList.cs プロジェクト: 7474/SRC
        private void AddDummyData()
        {
            var pd = new PilotData(SRC);

            // ユニットステータスコマンドの無人ユニット用
            pd.Name     = "ステータス表示用ダミーパイロット(ザコ)";
            pd.Nickname = "パイロット不在";
            pd.Adaption = "AAAA";
            pd.Bitmap   = ".bmp";
            colPilotDataList.Add(pd, pd.Name);
        }
コード例 #3
0
ファイル: PilotDataList.cs プロジェクト: 7474/SRC
 public void Load(string fname, Stream stream)
 {
     using (var reader = new SrcDataReader(fname, stream))
     {
         PilotData lastPd = null;
         while (reader.HasMore)
         {
             lastPd = LoadPilot(reader, lastPd);
         }
         Raw = reader.Raw;
     }
 }
コード例 #4
0
ファイル: PilotDataList.cs プロジェクト: 7474/SRC
        public PilotData LoadPilot(SrcDataReader reader, PilotData lastPd)
        {
            PilotData pd = null;

            try
            {
                string buf, buf2;

                string data_name = "";
                string line_buf  = "";
                // 空行をスキップ
                while (reader.HasMore && string.IsNullOrEmpty(line_buf))
                {
                    line_buf = reader.GetLine();
                }
                if (lastPd != null)
                {
                    lastPd.DataComment = reader.RawComment.Trim();
                }
                else
                {
                    DataComment = string.Join(Environment.NewLine + Environment.NewLine,
                                              new string[] {
                        DataComment,
                        reader.RawComment.Trim(),
                    }.Where(x => !string.IsNullOrEmpty(x)));
                }
                reader.ClearRawComment();
                if (reader.EOT)
                {
                    return(null);
                }

                if (Strings.InStr(line_buf, ",") > 0)
                {
                    throw reader.InvalidDataException(@"名称の設定が抜けています。", data_name);
                }

                // 名称
                data_name = line_buf;
                if (Strings.InStr(data_name, " ") > 0)
                {
                    throw reader.InvalidDataException(@"名称に半角スペースは使用出来ません。", data_name);
                }

                if (Strings.InStr(data_name, "(") > 0 || Strings.InStr(data_name, ")") > 0)
                {
                    throw reader.InvalidDataException(@"名称に全角括弧は使用出来ません", data_name);
                }

                if (Strings.InStr(data_name, "\"") > 0)
                {
                    throw reader.InvalidDataException("名称に\"は使用出来ません。", data_name);
                }

                if (IsDefined2(data_name))
                {
                    // すでに定義済みのパイロットの場合はデータを置き換え
                    pd = Item(data_name);
                    pd.Clear();
                }
                else
                {
                    pd = Add(data_name);
                }

                // 愛称, 読み仮名, 性別, クラス, 地形適応, 経験値
                line_buf = reader.GetLine();

                // 書式チェックのため、コンマの数を数えておく
                int comma_num = 0;
                var loopTo    = Strings.Len(line_buf);
                for (int i = 1; i <= loopTo; i++)
                {
                    if (Strings.Mid(line_buf, i, 1) == ",")
                    {
                        comma_num = (comma_num + 1);
                    }
                }

                if (comma_num < 3)
                {
                    throw reader.InvalidDataException(@"設定に抜けがあります。", data_name);
                }
                else if (comma_num > 5)
                {
                    throw reader.InvalidDataException(@"余分な「,」があります。", data_name);
                }

                // 愛称
                int ret = Strings.InStr(line_buf, ",");
                buf2 = Strings.Trim(Strings.Left(line_buf, ret - 1));
                buf  = Strings.Mid(line_buf, ret + 1);
                if (Strings.Len(buf2) == 0)
                {
                    throw reader.InvalidDataException(@"愛称の設定が抜けています。", data_name);
                }

                pd.Nickname = buf2;
                switch (comma_num)
                {
                case 4:
                {
                    // 読み仮名 or 性別
                    ret  = Strings.InStr(buf, ",");
                    buf2 = Strings.Trim(Strings.Left(buf, ret - 1));
                    buf  = Strings.Mid(buf, ret + 1);
                    switch (buf2 ?? "")
                    {
                    case "男性":
                    case "女性":
                    case "-":
                    {
                        pd.KanaName = GeneralLib.StrToHiragana(pd.Nickname);
                        pd.Sex      = buf2;
                        break;
                    }

                    default:
                    {
                        pd.KanaName = buf2;
                        break;
                    }
                    }

                    break;
                }

                case 5:
                {
                    // 読み仮名
                    ret  = Strings.InStr(buf, ",");
                    buf2 = Strings.Trim(Strings.Left(buf, ret - 1));
                    buf  = Strings.Mid(buf, ret + 1);
                    switch (buf2 ?? "")
                    {
                    case "男性":
                    case "女性":
                    case "-":
                    {
                        SRC.AddDataError(reader.InvalidData(@"読み仮名の設定が抜けています。", data_name));
                        pd.KanaName = GeneralLib.StrToHiragana(pd.Nickname);
                        break;
                    }

                    default:
                    {
                        pd.KanaName = buf2;
                        break;
                    }
                    }

                    // 性別
                    ret  = Strings.InStr(buf, ",");
                    buf2 = Strings.Trim(Strings.Left(buf, ret - 1));
                    buf  = Strings.Mid(buf, ret + 1);
                    switch (buf2 ?? "")
                    {
                    case "男性":
                    case "女性":
                    case "-":
                    {
                        pd.Sex = buf2;
                        break;
                    }

                    default:
                    {
                        SRC.AddDataError(reader.InvalidData(@"性別の設定が間違っています。", data_name));
                        break;
                    }
                    }

                    break;
                }

                default:
                {
                    pd.KanaName = GeneralLib.StrToHiragana(pd.Nickname);
                    break;
                }
                }

                // クラス
                ret  = Strings.InStr(buf, ",");
                buf2 = Strings.Trim(Strings.Left(buf, ret - 1));
                buf  = Strings.Mid(buf, ret + 1);
                if (!Information.IsNumeric(buf2))
                {
                    pd.Class = buf2;
                }
                else
                {
                    SRC.AddDataError(reader.InvalidData(@"クラスの設定が間違っています。", data_name));
                }

                // 地形適応
                ret  = Strings.InStr(buf, ",");
                buf2 = Strings.Trim(Strings.Left(buf, ret - 1));
                buf  = Strings.Mid(buf, ret + 1);
                if (Strings.Len(buf2) == 4)
                {
                    pd.Adaption = buf2;
                }
                else
                {
                    SRC.AddDataError(reader.InvalidData(@"地形適応の設定が間違っています。", data_name));
                    pd.Adaption = "AAAA";
                }

                // 経験値
                buf2 = Strings.Trim(buf);
                if (Information.IsNumeric(buf2))
                {
                    pd.ExpValue = GeneralLib.MinLng(Conversions.ToInteger(buf2), 9999);
                }
                else
                {
                    SRC.AddDataError(reader.InvalidData(@"経験値の設定が間違っています。", data_name));
                }

                // 特殊能力データ
                line_buf = reader.GetLine();
                if (line_buf == "特殊能力なし")
                {
                    line_buf = reader.GetLine();
                }
                else if (line_buf == "特殊能力")
                {
                    // 新形式による特殊能力表記
                    line_buf = reader.GetLine();
                    buf      = line_buf;
                    int    i      = 0;
                    string aname  = "";
                    string adata  = "";
                    double alevel = Constants.DEFAULT_LEVEL;
                    while (true)
                    {
                        i = (i + 1);

                        // コンマの位置を検索
                        ret = Strings.InStr(buf, ",");
                        // 「"」が使われているか検索
                        int ret2 = Strings.InStr(buf, "\"");
                        if (ret2 < ret && ret2 > 0)
                        {
                            // 「"」が見つかった場合、次の「"」後のコンマを検索
                            bool in_quote = true;
                            int  j        = (ret2 + 1);
                            while (j <= Strings.Len(buf))
                            {
                                switch (Strings.Mid(buf, j, 1) ?? "")
                                {
                                case "\"":
                                {
                                    in_quote = !in_quote;
                                    break;
                                }

                                case ",":
                                {
                                    if (!in_quote)
                                    {
                                        buf2 = Strings.Left(buf, j - 1);
                                        buf  = Strings.Mid(buf, j + 1);
                                    }

                                    break;
                                }
                                }

                                j = (j + 1);
                            }

                            if (j == Strings.Len(buf))
                            {
                                buf2 = buf;
                                buf  = "";
                            }

                            in_quote = false;
                        }
                        else if (ret > 0)
                        {
                            // コンマが見つかったらコンマまでの文字列を切り出す
                            buf2 = Strings.Trim(Strings.Left(buf, ret - 1));
                            buf  = Strings.Trim(Strings.Mid(buf, ret + 1));

                            // コンマの後ろの文字列が空白の場合
                            if (string.IsNullOrEmpty(buf))
                            {
                                if (i % 2 == 1)
                                {
                                    throw reader.InvalidDataException(@"行末の「,」の後に特殊能力指定が抜けています。", data_name);
                                }
                                else
                                {
                                    throw reader.InvalidDataException(@"行末の「,」の後に特殊能力レベル指定が抜けています。", data_name);
                                };
                            }
                        }
                        else
                        {
                            // 行末の文字列
                            buf2 = buf;
                            buf  = "";
                        }

                        if (i % 2 == 1)
                        {
                            // 特殊能力名&レベル

                            if (Information.IsNumeric(buf2))
                            {
                                if (i == 1)
                                {
                                    // 特殊能力の指定は終り。能力値の指定へ
                                    buf = buf2 + ", " + buf;
                                    break;
                                }
                                else
                                {
                                    SRC.AddDataError(reader.InvalidData(@"行頭から" + SrcFormatter.Format((object)((i + 1) / 2)) + "番目の特殊能力名の設定が間違っています。", data_name));
                                }
                            }

                            if (Strings.InStr(buf2, " ") > 0)
                            {
                                if (Strings.Left(buf2, 4) != "先手必勝" && Strings.Left(buf2, 6) != "SP消費減少" && Strings.Left(buf2, 12) != "スペシャルパワー自動発動" && Strings.Left(buf2, 4) != "ハンター" && Strings.InStr(buf2, "=解説 ") == 0)
                                {
                                    if (string.IsNullOrEmpty(aname))
                                    {
                                        throw reader.InvalidDataException(@"行頭から" + SrcFormatter.Format((object)((i + 1) / 2)) + "番目の特殊能力「" + Strings.Trim(Strings.Left(buf2, Strings.InStr(buf2, " "))) + "」の指定の後に「,」が抜けています。", data_name);
                                    }
                                    else
                                    {
                                        throw reader.InvalidDataException(@"特殊能力「" + aname + "」のレベル指定の後に「,」が抜けています。", data_name);
                                    };
                                }
                            }

                            // 特殊能力の別名指定がある?
                            int j = Strings.InStr(buf2, "=");
                            if (j > 0)
                            {
                                adata = Strings.Mid(buf2, j + 1);
                                buf2  = Strings.Left(buf2, j - 1);
                            }
                            else
                            {
                                adata = "";
                            }

                            // 特殊能力のレベル指定を切り出す
                            j = Strings.InStr(buf2, "Lv");
                            switch (j)
                            {
                            case 0:
                            {
                                // 指定なし
                                aname  = buf2;
                                alevel = Constants.DEFAULT_LEVEL;
                                break;
                            }

                            case 1:
                            {
                                // レベル指定のみあり
                                if (!Information.IsNumeric(Strings.Mid(buf2, j + 2)))
                                {
                                    SRC.AddDataError(reader.InvalidData(@"特殊能力「" + aname + "」のレベル指定が不正です。", data_name));
                                }

                                alevel = Conversions.ToDouble(Strings.Mid(buf2, j + 2));
                                if (string.IsNullOrEmpty(aname))
                                {
                                    SRC.AddDataError(reader.InvalidData(@"行頭から" + SrcFormatter.Format((object)((i + 1) / 2)) + "番目の特殊能力名の設定が間違っています。", data_name));
                                }

                                break;
                            }

                            default:
                            {
                                // 特殊能力名とレベルの両方が指定されている
                                aname  = Strings.Left(buf2, j - 1);
                                alevel = Conversions.ToDouble(Strings.Mid(buf2, j + 2));
                                break;
                            }
                            }
                        }
                        // 特殊能力修得レベル
                        else if (Information.IsNumeric(buf2))
                        {
                            pd.AddSkill(aname, alevel, adata, Conversions.ToInteger(buf2));
                        }
                        else
                        {
                            if (alevel > 0d)
                            {
                                SRC.AddDataError(reader.InvalidData(@"特殊能力「" + aname + "Lv" + SrcFormatter.Format((object)alevel) + "」の修得レベルが間違っています。", data_name));
                            }
                            else
                            {
                                SRC.AddDataError(reader.InvalidData(@"特殊能力「" + aname + "」の修得レベルが間違っています。", data_name));
                            }

                            pd.AddSkill(aname, alevel, adata, 1);
                        }

                        if (string.IsNullOrEmpty(buf))
                        {
                            // ここでこの行は終り

                            // iが奇数の場合は修得レベルが抜けている
                            if (i % 2 == 1)
                            {
                                if (alevel > 0d)
                                {
                                    SRC.AddDataError(reader.InvalidData(@"特殊能力「" + aname + "Lv" + SrcFormatter.Format((object)alevel) + "」の修得レベルが間違っています。", data_name));
                                }
                                else
                                {
                                    SRC.AddDataError(reader.InvalidData(@"特殊能力「" + aname + "」の修得レベルが間違っています。", data_name));
                                }
                            }

                            line_buf = reader.GetLine();
                            buf      = line_buf;
                            i        = 0;
                            aname    = "";
                        }
                    }
                }
                else if (Strings.InStr(line_buf, "特殊能力,") == 1)
                {
                    // 旧形式による特殊能力表記
                    buf = Strings.Mid(line_buf, 6);
                    int    i      = 0;
                    string aname  = "";
                    string adata  = "";
                    double alevel = Constants.DEFAULT_LEVEL;
                    do
                    {
                        i = (i + 1);

                        // コンマの位置を検索
                        ret = Strings.InStr(buf, ",");
                        // 「"」が使われているか検索
                        int ret2 = Strings.InStr(buf, "\"");
                        if (ret2 < ret && ret2 > 0)
                        {
                            // 「"」が見つかった場合、次の「"」後のコンマを検索
                            bool in_quote = true;
                            int  j        = (ret2 + 1);
                            while (j <= Strings.Len(buf))
                            {
                                switch (Strings.Mid(buf, j, 1) ?? "")
                                {
                                case "\"":
                                {
                                    in_quote = !in_quote;
                                    break;
                                }

                                case ",":
                                {
                                    if (!in_quote)
                                    {
                                        buf2 = Strings.Left(buf, j - 1);
                                        buf  = Strings.Mid(buf, j + 1);
                                    }

                                    break;
                                }
                                }

                                j = (j + 1);
                            }

                            if (j == Strings.Len(buf))
                            {
                                buf2 = buf;
                                buf  = "";
                            }

                            in_quote = false;
                        }
                        else if (ret > 0)
                        {
                            // コンマが見つかったらコンマまでの文字列を切り出す
                            buf2 = Strings.Trim(Strings.Left(buf, ret - 1));
                            buf  = Strings.Mid(buf, ret + 1);

                            // コンマの後ろの文字列が空白の場合
                            if (string.IsNullOrEmpty(buf))
                            {
                                if (i % 2 == 1)
                                {
                                    throw reader.InvalidDataException(@"行末の「,」の後に特殊能力指定が抜けています。", data_name);
                                }
                                else
                                {
                                    throw reader.InvalidDataException(@"行末の「,」の後に特殊能力レベル指定が抜けています。", data_name);
                                };
                            }
                        }
                        else
                        {
                            // 行末の文字列
                            buf2 = buf;
                            buf  = "";
                        }

                        if (i % 2 == 1)
                        {
                            // 特殊能力名&レベル

                            if (Strings.InStr(buf2, " ") > 0)
                            {
                                if (string.IsNullOrEmpty(aname))
                                {
                                    throw reader.InvalidDataException(@"行頭から" + SrcFormatter.Format((object)((i + 1) / 2)) + "番目の特殊能力の指定の後に「,」が抜けています。", data_name);
                                }
                                else
                                {
                                    throw reader.InvalidDataException(@"特殊能力「" + aname + "」のレベル指定の後に「,」が抜けています。", data_name);
                                };
                            }

                            // 特殊能力の別名指定がある?
                            int j = Strings.InStr(buf2, "=");
                            if (j > 0)
                            {
                                adata = Strings.Mid(buf2, j + 1);
                                buf2  = Strings.Left(buf2, j - 1);
                            }
                            else
                            {
                                adata = "";
                            }

                            // 特殊能力のレベル指定を切り出す
                            j = Strings.InStr(buf2, "Lv");
                            switch (j)
                            {
                            case 0:
                            {
                                // 指定なし
                                aname  = buf2;
                                alevel = Constants.DEFAULT_LEVEL;
                                break;
                            }

                            case 1:
                            {
                                // レベル指定のみあり
                                if (!Information.IsNumeric(Strings.Mid(buf2, j + 2)))
                                {
                                    throw reader.InvalidDataException(@"特殊能力「" + aname + "」のレベル指定が不正です", data_name);
                                }

                                alevel = Conversions.ToDouble(Strings.Mid(buf2, j + 2));
                                if (string.IsNullOrEmpty(aname))
                                {
                                    throw reader.InvalidDataException(@"行頭から" + SrcFormatter.Format((object)((i + 1) / 2)) + "番目の特殊能力の名前「" + buf2 + "」が不正です", data_name);
                                }

                                break;
                            }

                            default:
                            {
                                // 特殊能力名とレベルの両方が指定されている
                                aname  = Strings.Left(buf2, j - 1);
                                alevel = Conversions.ToDouble(Strings.Mid(buf2, j + 2));
                                break;
                            }
                            }
                        }
                        // 特殊能力修得レベル
                        else if (Information.IsNumeric(buf2))
                        {
                            pd.AddSkill(aname, alevel, adata, Conversions.ToInteger(buf2));
                        }
                        else
                        {
                            if (alevel > 0d)
                            {
                                SRC.AddDataError(reader.InvalidData(@"特殊能力「" + aname + "Lv" + SrcFormatter.Format((object)alevel) + "」の修得レベルが間違っています。", data_name));
                            }
                            else
                            {
                                SRC.AddDataError(reader.InvalidData(@"特殊能力「" + aname + "」の修得レベルが間違っています。", data_name));
                            }

                            pd.AddSkill(aname, alevel, adata, 1);
                        }
                    }while (ret > 0);

                    // iが奇数の場合は修得レベルが抜けている
                    if (i % 2 == 1)
                    {
                        if (alevel > 0d)
                        {
                            SRC.AddDataError(reader.InvalidData(@"特殊能力「" + aname + "Lv" + SrcFormatter.Format((object)alevel) + "」の修得レベルが間違っています。", data_name));
                        }
                        else
                        {
                            SRC.AddDataError(reader.InvalidData(@"特殊能力「" + aname + "」の修得レベルが間違っています。", data_name));
                        }
                    }

                    line_buf = reader.GetLine();
                }
                else
                {
                    throw reader.InvalidDataException(@"特殊能力の設定が抜けています。", data_name);
                }

                // 格闘
                if (Strings.Len(line_buf) == 0)
                {
                    throw reader.InvalidDataException(@"格闘攻撃力の設定が抜けています。", data_name);
                }

                ret = Strings.InStr(line_buf, ",");
                if (ret == 0)
                {
                    throw reader.InvalidDataException(@"射撃攻撃力の設定が抜けています。", data_name);
                }

                buf2 = Strings.Trim(Strings.Left(line_buf, ret - 1));
                buf  = Strings.Mid(line_buf, ret + 1);
                if (Information.IsNumeric(buf2))
                {
                    pd.Infight = GeneralLib.MinLng(Conversions.ToInteger(buf2), 9999);
                }
                else
                {
                    SRC.AddDataError(reader.InvalidData(@"格闘攻撃力の設定が間違っています。", data_name));
                }

                // 射撃
                ret = Strings.InStr(buf, ",");
                if (ret == 0)
                {
                    throw reader.InvalidDataException(@"命中の設定が抜けています。", data_name);
                }

                buf2 = Strings.Trim(Strings.Left(buf, ret - 1));
                buf  = Strings.Mid(buf, ret + 1);
                if (Information.IsNumeric(buf2))
                {
                    pd.Shooting = GeneralLib.MinLng(Conversions.ToInteger(buf2), 9999);
                }
                else
                {
                    SRC.AddDataError(reader.InvalidData(@"射撃攻撃力の設定が間違っています。", data_name));
                }

                // 命中
                ret = Strings.InStr(buf, ",");
                if (ret == 0)
                {
                    throw reader.InvalidDataException(@"回避の設定が抜けています。", data_name);
                }

                buf2 = Strings.Trim(Strings.Left(buf, ret - 1));
                buf  = Strings.Mid(buf, ret + 1);
                if (Information.IsNumeric(buf2))
                {
                    pd.Hit = GeneralLib.MinLng(Conversions.ToInteger(buf2), 9999);
                }
                else
                {
                    SRC.AddDataError(reader.InvalidData(@"命中の設定が間違っています。", data_name));
                }

                // 回避
                ret = Strings.InStr(buf, ",");
                if (ret == 0)
                {
                    throw reader.InvalidDataException(@"技量の設定が抜けています。", data_name);
                }

                buf2 = Strings.Trim(Strings.Left(buf, ret - 1));
                buf  = Strings.Mid(buf, ret + 1);
                if (Information.IsNumeric(buf2))
                {
                    pd.Dodge = GeneralLib.MinLng(Conversions.ToInteger(buf2), 9999);
                }
                else
                {
                    SRC.AddDataError(reader.InvalidData(@"回避の設定が間違っています。", data_name));
                }

                // 技量
                ret = Strings.InStr(buf, ",");
                if (ret == 0)
                {
                    throw reader.InvalidDataException(@"反応の設定が抜けています。", data_name);
                }

                buf2 = Strings.Trim(Strings.Left(buf, ret - 1));
                buf  = Strings.Mid(buf, ret + 1);
                if (Information.IsNumeric(buf2))
                {
                    pd.Technique = GeneralLib.MinLng(Conversions.ToInteger(buf2), 9999);
                }
                else
                {
                    SRC.AddDataError(reader.InvalidData(@"技量の設定が間違っています。", data_name));
                }

                // 反応
                ret = Strings.InStr(buf, ",");
                if (ret == 0)
                {
                    throw reader.InvalidDataException(@"性格の設定が抜けています。", data_name);
                }

                buf2 = Strings.Trim(Strings.Left(buf, ret - 1));
                buf  = Strings.Mid(buf, ret + 1);
                if (Information.IsNumeric(buf2))
                {
                    pd.Intuition = GeneralLib.MinLng(Conversions.ToInteger(buf2), 9999);
                }
                else
                {
                    SRC.AddDataError(reader.InvalidData(@"反応の設定が間違っています。", data_name));
                }

                // 性格
                buf2 = Strings.Trim(buf);
                if (Strings.Len(buf2) == 0)
                {
                    throw reader.InvalidDataException(@"性格の設定が抜けています。", data_name);
                }

                if (Strings.InStr(buf2, ",") > 0)
                {
                    SRC.AddDataError(reader.InvalidData(@"行末に余分なコンマが付けられています。", data_name));
                    buf2 = Strings.Trim(Strings.Left(buf2, Strings.InStr(buf2, ",") - 1));
                }

                if (!Information.IsNumeric(buf2))
                {
                    pd.Personality = buf2;
                }
                else
                {
                    SRC.AddDataError(reader.InvalidData(@"性格の設定が間違っています。", data_name));
                }

                // スペシャルパワー
                line_buf = reader.GetLine();
                switch (line_buf ?? "")
                {
                // スペシャルパワーを持っていない
                case "SPなし":
                case "精神なし":
                {
                    break;
                }

                case var @case when @case == "":
                {
                    throw reader.InvalidDataException(@"スペシャルパワーの設定が抜けています。", data_name);
                }

                default:
                {
                    ret = Strings.InStr(line_buf, ",");
                    if (ret == 0)
                    {
                        throw reader.InvalidDataException(@"SP値の設定が抜けています。", data_name);
                    }

                    buf2 = Strings.Trim(Strings.Left(line_buf, ret - 1));
                    buf  = Strings.Mid(line_buf, ret + 1);
                    if (buf2 != "SP" && buf2 != "精神")
                    {
                        throw reader.InvalidDataException(@"スペシャルパワーの設定が抜けています。", data_name);
                    }

                    // SP値
                    ret = Strings.InStr(buf, ",");
                    if (ret > 0)
                    {
                        buf2 = Strings.Trim(Strings.Left(buf, ret - 1));
                        buf  = Strings.Mid(buf, ret + 1);
                    }
                    else
                    {
                        buf2 = Strings.Trim(buf);
                        buf  = "";
                    }

                    if (Information.IsNumeric(buf2))
                    {
                        pd.SP = GeneralLib.MinLng(Conversions.ToInteger(buf2), 9999);
                    }
                    else
                    {
                        SRC.AddDataError(reader.InvalidData(@"SPの設定が間違っています。", data_name));
                        pd.SP = 1;
                    }

                    // スペシャルパワーと獲得レベル
                    ret = Strings.InStr(buf, ",");
                    string sname = "";
                    while (ret > 0)
                    {
                        sname = Strings.Trim(Strings.Left(buf, ret - 1));
                        int sp_cost = 0;
                        buf = Strings.Mid(buf, ret + 1);

                        // SP消費量
                        if (Strings.InStr(sname, "=") > 0)
                        {
                            sp_cost = GeneralLib.StrToLng(Strings.Mid(sname, Strings.InStr(sname, "=") + 1));
                            sname   = Strings.Left(sname, Strings.InStr(sname, "=") - 1);
                        }
                        else
                        {
                            sp_cost = 0;
                        }

                        ret = Strings.InStr(buf, ",");
                        if (ret == 0)
                        {
                            buf2 = Strings.Trim(buf);
                            buf  = "";
                        }
                        else
                        {
                            buf2 = Strings.Trim(Strings.Left(buf, ret - 1));
                            buf  = Strings.Mid(buf, ret + 1);
                        }

                        if (string.IsNullOrEmpty(sname))
                        {
                            SRC.AddDataError(reader.InvalidData(@"スペシャルパワーの指定が抜けています。", data_name));
                        }
                        // TODO ビューワでSP設定しとく
                        //else if (!SRC.SPDList.IsDefined(sname))
                        //{
                        //    SRC.AddDataError(reader.InvalidData(@sname + "というスペシャルパワーは存在しません。", data_name));
                        //}
                        else if (!Information.IsNumeric(buf2))
                        {
                            SRC.AddDataError(reader.InvalidData(@"スペシャルパワー「" + sname + "」の獲得レベルが間違っています。", data_name));
                            pd.AddSpecialPower(sname, 1, sp_cost);
                        }
                        else
                        {
                            pd.AddSpecialPower(sname, Conversions.ToInteger(buf2), sp_cost);
                        }

                        ret = Strings.InStr(buf, ",");
                    }

                    if (!string.IsNullOrEmpty(buf))
                    {
                        SRC.AddDataError(reader.InvalidData(@"スペシャルパワー「" + Strings.Trim(sname) + "」の獲得レベル指定が抜けています。", data_name));
                    }

                    break;
                }
                }

                // ビットマップ, MIDI
                line_buf = reader.GetLine();

                // ビットマップ
                if (Strings.Len(line_buf) == 0)
                {
                    throw reader.InvalidDataException(@"ビットマップの設定が抜けています。", data_name);
                }

                ret = Strings.InStr(line_buf, ",");
                if (ret == 0)
                {
                    throw reader.InvalidDataException(@"MIDIの設定が抜けています。", data_name);
                }

                buf2 = Strings.Trim(Strings.Left(line_buf, ret - 1));
                buf  = Strings.Mid(line_buf, ret + 1);
                if (Strings.LCase(Strings.Right(buf2, 4)) == ".bmp")
                {
                    pd.Bitmap = buf2;
                }
                else
                {
                    SRC.AddDataError(reader.InvalidData(@"ビットマップの設定が間違っています。", data_name));
                    pd.IsBitmapMissing = true;
                }

                // MIDI
                buf  = Strings.Trim(buf);
                buf2 = buf;
                while (Strings.Right(buf2, 1) == ")")
                {
                    buf2 = Strings.Left(buf2, Strings.Len(buf2) - 1);
                }
                switch (Strings.LCase(Strings.Right(buf2, 4)) ?? "")
                {
                case ".mid":
                case ".mp3":
                case ".wav":
                case "-":
                {
                    pd.BGM = buf;
                    break;
                }

                case var case1 when case1 == "":
                {
                    SRC.AddDataError(reader.InvalidData(@"MIDIの設定が抜けています。", data_name));
                    pd.Bitmap = "-.mid";
                    break;
                }

                default:
                {
                    SRC.AddDataError(reader.InvalidData(@"MIDIの設定が間違っています。", data_name));
                    pd.Bitmap = "-.mid";
                    break;
                }
                }

                if (reader.EOT)
                {
                    return(pd);
                }

                line_buf = reader.GetLine();
                if (line_buf != "===")
                {
                    return(pd);
                }

                // 特殊能力データ
                line_buf = UnitDataList.LoadFeature(data_name, pd, reader, SRC);


                if (line_buf != "===")
                {
                    return(pd);
                }

                // 武器データ
                line_buf = UnitDataList.LoadWepon(data_name, pd, reader, SRC);

                if (line_buf != "===")
                {
                    return(pd);
                }

                // アビリティデータ
                line_buf = UnitDataList.LoadAbility(data_name, pd, reader, SRC);
            }
            finally
            {
                if (pd != null)
                {
                    pd.Raw = reader.RawData;
                    reader.ClearRawData();
                }
            }
            return(pd);
        }