public void Load(string fname, Stream stream) { using (var reader = new SrcDataReader(fname, stream)) { while (reader.HasMore) { string buf, buf2; string data_name = ""; string line_buf = ""; // 空行をスキップ while (reader.HasMore && string.IsNullOrEmpty(line_buf)) { line_buf = reader.GetLine(); } if (string.IsNullOrEmpty(line_buf)) { break; } // 名称 var ret = Strings.InStr(line_buf, ","); if (ret > 0) { data_name = Strings.Trim(Strings.Left(line_buf, ret - 1)); buf = Strings.Mid(line_buf, ret + 1); } else { data_name = line_buf; buf = ""; } if (Strings.InStr(data_name, " ") > 0) { throw reader.InvalidDataException("名称に半角スペースは使用出来ません。", line_buf); } if (Strings.InStr(data_name, "(") > 0 || Strings.InStr(data_name, ")") > 0) { throw reader.InvalidDataException("名称に全角括弧は使用出来ません。", line_buf); } if (Strings.InStr(data_name, "\"") > 0) { throw reader.InvalidDataException("名称に\"は使用出来ません。", line_buf); } if (IsDefined(data_name)) { Delete(data_name); } var sd = Add(data_name); // 読み仮名 ret = Strings.InStr(buf, ","); if (ret > 0) { throw reader.InvalidDataException("読み仮名の後に余分なデータが指定されています。", line_buf); } sd.KanaName = Strings.Trim(buf); if (string.IsNullOrEmpty(sd.KanaName)) { sd.KanaName = GeneralLib.StrToHiragana(data_name); } // 短縮形, 消費SP, 対象, 効果時間, 適用条件, 使用条件, アニメ line_buf = reader.GetLine(); // 短縮形 ret = Strings.InStr(line_buf, ","); if (ret == 0) { throw reader.InvalidDataException("消費SPが抜けています。", line_buf); } buf2 = Strings.Trim(Strings.Left(line_buf, ret - 1)); buf = Strings.Mid(line_buf, ret + 1); sd.ShortName = buf2; // 消費SP ret = Strings.InStr(buf, ","); if (ret == 0) { throw reader.InvalidDataException("対象が抜けています。", line_buf); } buf2 = Strings.Trim(Strings.Left(buf, ret - 1)); buf = Strings.Mid(buf, ret + 1); if (Information.IsNumeric(buf2)) { sd.SPConsumption = Conversions.ToInteger(buf2); } else { SRC.AddDataError(reader.InvalidData("消費SPの設定が間違っています。", data_name)); } // 対象 ret = Strings.InStr(buf, ","); if (ret == 0) { throw reader.InvalidDataException("効果時間が抜けています。", line_buf); } buf2 = Strings.Trim(Strings.Left(buf, ret - 1)); buf = Strings.Mid(buf, ret + 1); if (Information.IsNumeric(buf2)) { throw reader.InvalidDataException("対象が間違っています。", line_buf); } sd.TargetType = buf2; // 効果時間 ret = Strings.InStr(buf, ","); if (ret == 0) { throw reader.InvalidDataException("効果時間が抜けています。", line_buf); } buf2 = Strings.Trim(Strings.Left(buf, ret - 1)); buf = Strings.Mid(buf, ret + 1); if (Information.IsNumeric(buf2)) { throw reader.InvalidDataException("効果時間が間違っています。", line_buf); } sd.Duration = buf2; // 適用条件 ret = Strings.InStr(buf, ","); if (ret == 0) { throw reader.InvalidDataException("使用条件が抜けています。", line_buf); } buf2 = Strings.Trim(Strings.Left(buf, ret - 1)); buf = Strings.Mid(buf, ret + 1); if (Information.IsNumeric(buf2)) { throw reader.InvalidDataException("適用条件が間違っています。", line_buf); } sd.NecessaryCondition = buf2; // 使用条件, アニメ ret = Strings.InStr(buf, ","); if (ret > 0) { sd.Animation = Strings.Trim(Strings.Mid(buf, Strings.InStr(buf, ",") + 1)); } else { sd.Animation = sd.Name; } // 効果 line_buf = reader.GetLine(); if (Strings.Len(line_buf) == 0) { throw reader.InvalidDataException("効果が指定されていません。", line_buf); } sd.SetEffect(line_buf); // 解説 line_buf = reader.GetLine(); if (Strings.Len(line_buf) == 0) { throw reader.InvalidDataException("解説が指定されていません。", line_buf); } sd.Comment = line_buf; } } }
private ItemData LoadItem(SrcDataReader reader, ItemData lastId) { ItemData nd = null; try { string buf, buf2; string data_name = ""; string line_buf = ""; // 空行をスキップ while (reader.HasMore && string.IsNullOrEmpty(line_buf)) { line_buf = reader.GetLine(); } if (lastId != null) { lastId.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 (IsDefined(data_name)) { Delete(data_name); } nd = Add(data_name); // 愛称、読み仮名、アイテムクラス、装備個所 line_buf = reader.GetLine(); // 書式チェックのため、コンマの数を数えておく var comma_num = 0; var loopTo = Strings.Len(line_buf); for (var i = 1; i <= loopTo; i++) { if (Strings.Mid(line_buf, i, 1) == ",") { comma_num = (comma_num + 1); } } if (comma_num < 2) { throw reader.InvalidDataException("設定に抜けがあります。", data_name); } else if (comma_num > 3) { throw reader.InvalidDataException("余分な「,」があります。", data_name); } // 愛称 if (Strings.Len(line_buf) == 0) { throw reader.InvalidDataException("愛称の設定が抜けています。", data_name); } var ret = Strings.InStr(line_buf, ","); buf2 = Strings.Trim(Strings.Left(line_buf, ret - 1)); buf = Strings.Mid(line_buf, ret + 1); nd.Nickname = buf2; // 読み仮名 if (comma_num == 3) { ret = Strings.InStr(buf, ","); buf2 = Strings.Trim(Strings.Left(buf, ret - 1)); buf = Strings.Mid(buf, ret + 1); nd.KanaName = buf2; } else { nd.KanaName = GeneralLib.StrToHiragana(nd.Nickname); } // アイテムクラス ret = Strings.InStr(buf, ","); buf2 = Strings.Trim(Strings.Left(buf, ret - 1)); buf = Strings.Mid(buf, ret + 1); nd.Class = buf2; // 装備個所 buf2 = Strings.Trim(buf); if (Strings.Len(buf2) == 0) { throw reader.InvalidDataException("装備個所の設定が抜けています。", data_name); } nd.Part = buf2; // 特殊能力データ line_buf = UnitDataList.LoadFeatureOuter(data_name, nd, reader, SRC); // 最大HP修正値, 最大EN修正値, 装甲修正値, 運動性修正値, 移動力修正値 // 最大HP修正値 ret = Strings.InStr(line_buf, ","); if (ret == 0) { throw reader.InvalidDataException("最大EN修正値の設定が抜けています。", data_name); } buf2 = Strings.Trim(Strings.Left(line_buf, ret - 1)); buf = Strings.Mid(line_buf, ret + 1); if (Information.IsNumeric(buf2)) { nd.HP = Conversions.ToInteger(buf2); } else { SRC.AddDataError(reader.InvalidData("最大HP修正値の設定が間違っています。", data_name)); } // 最大EN修正値 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)) { nd.EN = Conversions.ToInteger(buf2); } else { SRC.AddDataError(reader.InvalidData("最大EN修正値の設定が間違っています。", 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)) { nd.Armor = Conversions.ToInteger(buf2); } 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)) { nd.Mobility = Conversions.ToInteger(buf2); } else { SRC.AddDataError(reader.InvalidData("運動性修正値の設定が間違っています。", data_name)); } // 移動力修正値 buf2 = Strings.Trim(buf); if (Strings.Len(buf2) == 0) { throw reader.InvalidDataException("移動力修正値の設定が抜けています。", data_name); } if (Information.IsNumeric(buf2)) { nd.Speed = Conversions.ToInteger(buf2); } else { SRC.AddDataError(reader.InvalidData("移動力修正値の設定が間違っています。", data_name)); } if (reader.EOT) { return(nd); } // 武器データ line_buf = UnitDataList.LoadWepon(data_name, nd, reader, SRC); if (line_buf == "===") { // アビリティデータ line_buf = UnitDataList.LoadAbility(data_name, nd, reader, SRC); } // 解説 while (Strings.Left(line_buf, 1) == "*") { if (Strings.Len(nd.Comment) > 0) { nd.Comment = nd.Comment + Environment.NewLine; } nd.Comment = nd.Comment + Strings.Mid(line_buf, 2); if (reader.EOT) { break; } line_buf = reader.GetLine(); } } finally { if (nd != null) { nd.Raw = reader.RawData; reader.ClearRawData(); } } return(nd); }
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); }
// reader から1つユニットを読み込む。 // 返却したUnitDataはリストに追加されている状態。 private UnitData LoadUnit(SrcDataReader reader, UnitData lastUd) { UnitData ud = null; try { int ret; string buf, buf2; var line_buf = ""; // 空行をスキップ while (reader.HasMore && string.IsNullOrEmpty(line_buf)) { line_buf = reader.GetLine(); } if (lastUd != null) { lastUd.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); } // 名称 string data_name; ret = Strings.InStr(line_buf, ","); if (ret > 0) { data_name = Strings.Trim(Strings.Left(line_buf, ret - 1)); buf = Strings.Mid(line_buf, ret + 1); } else { data_name = line_buf; 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 (IsDefined(data_name)) { ud = Item(data_name); ud.Clear(); } else { ud = Add(data_name); } // 読み仮名 ret = Strings.InStr(buf, ","); if (ret > 0) { throw reader.InvalidDataException(@"読み仮名の後に余分なデータが指定されています。", data_name); } ud.KanaName = buf; // 愛称, 読み仮名, ユニットクラス, パイロット数, アイテム数 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 > 4) { throw reader.InvalidDataException(@"余分な「,」があります。", data_name); } // 愛称 if (Strings.Len(line_buf) == 0) { throw reader.InvalidDataException(@"愛称の設定が抜けています。", data_name); } ret = Strings.InStr(line_buf, ","); buf2 = Strings.Trim(Strings.Left(line_buf, ret - 1)); buf = Strings.Mid(line_buf, ret + 1); ud.Nickname = buf2; // 読み仮名 if (comma_num == 4) { ret = Strings.InStr(buf, ","); buf2 = Strings.Trim(Strings.Left(buf, ret - 1)); buf = Strings.Mid(buf, ret + 1); ud.KanaName = buf2; } else { ud.KanaName = GeneralLib.StrToHiragana(ud.Nickname); } // ユニットクラス ret = Strings.InStr(buf, ","); buf2 = Strings.Trim(Strings.Left(buf, ret - 1)); buf = Strings.Mid(buf, ret + 1); if (!Information.IsNumeric(buf2)) { ud.Class = buf2; } else { SRC.AddDataError(reader.InvalidData(@"ユニットクラスの設定が間違っています。", data_name)); ud.Class = "汎用"; } // パイロット数 ret = Strings.InStr(buf, ","); buf2 = Strings.Trim(Strings.Left(buf, ret - 1)); buf = Strings.Mid(buf, ret + 1); if (Strings.Left(buf2, 1) != "(") { if (Information.IsNumeric(buf2)) { ud.PilotNum = GeneralLib.MinLng(Conversions.ToInteger(buf2), 99); } else { SRC.AddDataError(reader.InvalidData(@"パイロット数の設定が間違っています。", data_name)); ud.PilotNum = 1; } if (ud.PilotNum < 1) { SRC.AddDataError(reader.InvalidData(@"パイロット数の設定が間違っています。", data_name)); ud.PilotNum = 1; } } else { if (Strings.Right(buf2, 1) != ")") { throw reader.InvalidDataException(@"パイロット数の設定が間違っています。", data_name); } buf2 = Strings.Mid(buf2, 2, Strings.Len(buf2) - 2); if (Information.IsNumeric(buf2)) { ud.PilotNum = GeneralLib.MinLng(Conversions.ToInteger(buf2), 99); } else { SRC.AddDataError(reader.InvalidData(@"パイロット数の設定が間違っています。", data_name)); ud.PilotNum = 1; } if (ud.PilotNum < 1) { SRC.AddDataError(reader.InvalidData(@"パイロット数の設定が間違っています。", data_name)); ud.PilotNum = 1; } // XXX 何で負数にしてるの? ud.PilotNum = -ud.PilotNum; } // アイテム数 buf = Strings.Trim(buf); if (Strings.Len(buf) == 0) { throw reader.InvalidDataException(@"アイテム数の設定が抜けています。", data_name); } if (Information.IsNumeric(buf)) { ud.ItemNum = GeneralLib.MinLng(Conversions.ToInteger(buf), 99); } else { SRC.AddDataError(reader.InvalidData(@"アイテム数の設定が間違っています。", data_name)); ud.ItemNum = 4; } // 移動可能地形, 移動力, サイズ, 修理費, 経験値 line_buf = reader.GetLine(); // 移動可能地形 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)) { ud.Transportation = buf2; } else { SRC.AddDataError(reader.InvalidData(@"移動可能地形の設定が間違っています。", data_name)); ud.Transportation = "陸"; } // 移動力 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)) { ud.Speed = GeneralLib.MinLng(Conversions.ToInteger(buf2), 99); } 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); switch (buf2 ?? "") { case "XL": case "LL": case "L": case "M": case "S": case "SS": { ud.Size = buf2; break; } default: { SRC.AddDataError(reader.InvalidData(@"サイズの設定が間違っています。", data_name)); ud.Size = "M"; break; } } // 修理費 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)) { ud.Value = GeneralLib.MinLng(Conversions.ToInteger(buf2), 9999999); } else { SRC.AddDataError(reader.InvalidData(@"修理費の設定が間違っています。", data_name)); } // 経験値 buf = Strings.Trim(buf); if (Strings.Len(buf) == 0) { throw reader.InvalidDataException(@"経験値の設定が抜けています。", data_name); } if (Information.IsNumeric(buf)) { ud.ExpValue = GeneralLib.MinLng(Conversions.ToInteger(buf), 9999); } else { SRC.AddDataError(reader.InvalidData(@"経験値の設定が間違っています。", data_name)); } // 特殊能力データ line_buf = LoadFeatureOuter(data_name, ud, reader, SRC); // 最大HP ret = Strings.InStr(line_buf, ","); if (ret == 0) { throw reader.InvalidDataException(@"最大ENの設定が抜けています。", data_name); } buf2 = Strings.Trim(Strings.Left(line_buf, ret - 1)); buf = Strings.Mid(line_buf, ret + 1); if (Information.IsNumeric(buf2)) { ud.HP = GeneralLib.MinLng(Conversions.ToInteger(buf2), 9999999); } else { SRC.AddDataError(reader.InvalidData(@"最大HPの設定が間違っています。", data_name)); ud.HP = 1000; } // 最大EN 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)) { ud.EN = GeneralLib.MinLng(Conversions.ToInteger(buf2), 9999); } else { SRC.AddDataError(reader.InvalidData(@"最大ENの設定が間違っています。", data_name)); ud.EN = 100; } // 装甲 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)) { ud.Armor = GeneralLib.MinLng(Conversions.ToInteger(buf2), 99999); } else { SRC.AddDataError(reader.InvalidData(@"装甲の設定が間違っています。", data_name)); } // 運動性 buf2 = Strings.Trim(buf); if (Strings.Len(buf2) == 0) { throw reader.InvalidDataException(@"運動性の設定が抜けています。", data_name); } if (Information.IsNumeric(buf2)) { ud.Mobility = GeneralLib.MinLng(Conversions.ToInteger(buf2), 9999); } else { SRC.AddDataError(reader.InvalidData(@"運動性の設定が間違っています。", data_name)); } // 地形適応, ビットマップ line_buf = reader.GetLine(); // 地形適応 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 (Strings.Len(buf2) == 4) { ud.Adaption = buf2; } else { SRC.AddDataError(reader.InvalidData(@"地形適応の設定が間違っています。", data_name)); ud.Adaption = "AAAA"; } // ビットマップ buf = Strings.Trim(buf); if (Strings.Len(buf) == 0) { throw reader.InvalidDataException(@"ビットマップの設定が抜けています。", data_name); } if (Strings.LCase(Strings.Right(buf, 4)) == ".bmp") { ud.Bitmap = buf; } else { SRC.AddDataError(reader.InvalidData(@"ビットマップの設定が間違っています。", data_name)); ud.IsBitmapMissing = true; } if (reader.EOT) { return(ud); } // 武器データ line_buf = LoadWepon(data_name, ud, reader, SRC); if (line_buf != "===") { return(ud); } // アビリティデータ line_buf = LoadAbility(data_name, ud, reader, SRC); } finally { if (ud != null) { ud.Raw = reader.RawData; reader.ClearRawData(); } } return(ud); }