public void ToListTest() { // TODO カッコの扱いちゃんと見る var cases = new ToListTestCase[] { new ToListTestCase { input = "いちご ニンジン サンダル", expected = new List <string> { "いちご", "ニンジン", "サンダル" } }, new ToListTestCase { input = "This is a pen.", expected = new List <string> { "This", "is", "a", "pen." } }, //new ToListTestCase{ input= "a (b c) (d (e f))", expected= new List<string>{ "a", "b c", "d (e f)" } }, new ToListTestCase { input = "こぶた たぬき きつね ねこ", expected = new List <string> { "こぶた", "たぬき", "きつね", "ねこ" } }, //new ToListTestCase{ input= "a (b c)) (d (e f))", expected= new List<string>{ "a", "b c", ") (d (e f))" } }, }; foreach (var c in cases) { var actual = GeneralLib.ToList(c.input); Console.WriteLine(c.input + ": " + JsonConvert.SerializeObject(actual)); Assert.IsTrue(c.expected.SequenceEqual(actual), $"case: {c.input}"); } }
// ラベルを探す public int FindLabel(string lname) { int FindLabelRet; string lname2; // 通常ラベルから検索 FindLabelRet = FindNormalLabel(lname); if (FindLabelRet >= 0) { return(FindLabelRet); } // イベントラベルから検索 FindLabelRet = FindEventLabel(lname); if (FindLabelRet >= 0) { return(FindLabelRet); } // パラメータ間の文字列の違いで一致しなかった可能性があるので // 文字列を半角スペース一文字のみにして検索してみる lname2 = string.Join(" ", GeneralLib.ToList(lname)); // イベントラベルから検索 FindLabelRet = FindEventLabel(lname2); return(FindLabelRet); }
protected override int ExecInternal() { string fname = GeneralLib.ToList(EventData.Data).Skip(1).FirstOrDefault(); if (GeneralLib.ListLength(fname) == 1) { fname = Expression.GetValueAsString(fname); } Sound.PlayWave(fname); return(EventData.NextID); }
// ラベルを追加 public void AddLabel(string lname, int eventDataId) { var new_label = new LabelData(SRC); string lname2; new_label.Data = lname; new_label.EventDataId = eventDataId; new_label.Enable = true; if (new_label.Name == LabelType.NormalLabel) { // 登録済なら無視 if (colNormalLabelList.Values.Any(x => x.EventDataId == eventDataId)) { return; } // 通常ラベルを追加 if (FindNormalLabel0(lname) < 0) { colNormalLabelList.Add(new_label, lname); } // 通常ラベルが重複定義されている場合は無視 } else { // 登録済なら無視 if (colEventLabelList.Values.Any(x => x.EventDataId == eventDataId)) { return; } // イベントラベルを追加 // パラメータ間の文字列の違いによる不一致をなくすため、 // 文字列を半角スペース一文字に直しておく lname2 = string.Join(" ", GeneralLib.ToList(lname)); if (!IsLabelDefined(lname2)) { colEventLabelList.Add(new_label, lname2); } else { var lname3 = lname2 + "(" + SrcFormatter.Format(eventDataId) + ")"; if (!IsLabelDefined(lname3)) { colEventLabelList.Add(new_label, lname3); } } } }
protected override int ExecInternal() { string fname = ""; int play_bgm_end; // PlayMIDIコマンドが連続してる場合、最後のPlayMIDIコマンドの位置を検索 var playCmds = Event.EventCmd .Skip(EventData.ID) .TakeWhile(x => x.Name == Name) .ToList(); play_bgm_end = playCmds.Max(x => x.EventData.ID); // 最後のSPlayMIDIから順にMIDIファイルを検索 foreach (var cmd in playCmds.Reverse <CmdData>()) { var fnameList = GeneralLib.ToList(cmd.EventData.Data).Skip(1).ToList(); fname = string.Join(" ", fnameList); if (fnameList.Count == 1) { if (Strings.Left(fname, 2) == "$(") { fname = "\"" + fname + "\""; } fname = Expression.GetValueAsString(fname, true); } else { fname = "(" + fname + ")"; } fname = Sound.SearchMidiFile(fname); if (!string.IsNullOrEmpty(fname)) { // MIDIファイルが存在したので選択 break; } } // MIDIファイルを再生 Sound.KeepBGM = false; Sound.BossBGM = false; Sound.StartBGM(fname, Repeat); // 次のコマンド実行位置は最後のPlayMIDIコマンドの後 return(play_bgm_end + 1); }
// アビリティに効果を追加 public void SetEffect(string elist) { elist = (elist ?? "").Trim(); foreach (var eelm in GeneralLib.ToList(elist)) { var dat = new AbilityEffect(); var buf = eelm; var j = Strings.InStr(buf, "Lv"); var k = Strings.InStr(buf, "="); string etype; string elevel; string edata; if (j > 0 && (k == 0 || j < k)) { // レベル指定のある効果(データ指定があるものを含む) dat.Name = Strings.Left(buf, j - 1); if (k > 0) { // データ指定があるもの dat.Level = Conversions.ToDouble(Strings.Mid(buf, j + 2, k - (j + 2))); buf = Strings.Mid(buf, k + 1); if (Strings.Left(buf, 1) == "\"") { buf = Strings.Mid(buf, 2, Strings.Len(buf) - 2); } j = Strings.InStr(buf, "Lv"); k = Strings.InStr(buf, "="); if (j > 0 && (k == 0 || j < k)) { // データ指定内にレベル指定がある etype = Strings.Left(buf, j - 1); if (k > 0) { elevel = Strings.Mid(buf, j + 2, k - (j + 2)); edata = Strings.Mid(buf, k + 1); } else { elevel = Strings.Mid(buf, j + 2); edata = ""; } } else if (k > 0) { // データ指定内にデータ指定がある etype = Strings.Left(buf, k - 1); elevel = ""; edata = Strings.Mid(buf, k + 1); } else { // 単純なデータ指定 etype = buf; elevel = ""; edata = ""; } if (dat.Name == "付加" && string.IsNullOrEmpty(elevel)) { elevel = SrcFormatter.Format(Constants.DEFAULT_LEVEL); } dat.Data = Strings.Trim(etype + " " + elevel + " " + edata); } else { // データ指定がないもの dat.Level = Conversions.ToDouble(Strings.Mid(buf, j + 2)); } } else if (k > 0) { // データ指定を含む効果 dat.Name = Strings.Left(buf, k - 1); buf = Strings.Mid(buf, k + 1); if (Strings.Asc(buf) == 34) // " { buf = Strings.Mid(buf, 2, Strings.Len(buf) - 2); } j = Strings.InStr(buf, "Lv"); k = Strings.InStr(buf, "="); if (dat.Name == "解説") { // 解説の指定 etype = buf; elevel = ""; edata = ""; } else if (j > 0) { // データ指定内にレベル指定がある etype = Strings.Left(buf, j - 1); if (k > 0) { elevel = Strings.Mid(buf, j + 2, k - (j + 2)); edata = Strings.Mid(buf, k + 1); } else { elevel = Strings.Mid(buf, j + 2); edata = ""; } } else if (k > 0) { // データ指定内にデータ指定がある etype = Strings.Left(buf, k - 1); elevel = ""; edata = Strings.Mid(buf, k + 1); } else { // 単純なデータ指定 etype = buf; elevel = ""; edata = ""; } if (dat.Name == "付加" && string.IsNullOrEmpty(elevel)) { elevel = SrcFormatter.Format(Constants.DEFAULT_LEVEL); } dat.Data = Strings.Trim(etype + " " + elevel + " " + edata); } else { // 効果名のみ dat.Name = buf; } j = 1; foreach (AbilityEffect dat2 in colEffects) { if ((dat.Name ?? "") == (dat2.Name ?? "")) { j = (j + 1); } } if (j == 1) { colEffects.Add(dat, dat.Name); } else { colEffects.Add(dat, dat.Name + SrcFormatter.Format(j)); } } }
// 各Midiフォルダから指定されたMIDIファイルを検索する public string SearchMidiFile(string midi_name) { // TODO FileSystemに逃がす var baseDirs = new string[] { SRC.ScenarioPath, SRC.ExtDataPath, SRC.ExtDataPath2, SRC.AppPath, } // TODO Directory.Exists //.Where(x => Directory.Exists(x)) .Select(x => SRC.FileSystem.PathCombine(x, "Midi")) //.Where(x => Directory.Exists(x)) .ToList(); var midiNames = GeneralLib.ToList(midi_name, true); var existFile = midiNames .SelectMany(x => baseDirs.Select(y => SRC.FileSystem.PathCombine(y, x))) .FirstOrDefault(x => File.Exists(x)); return(existFile); // TODO Impl 検索の整理 //string SearchMidiFileRet = default; //string fname, fname_mp3 = default; //; ///* Cannot convert LocalDeclarationStatementSyntax, System.NotSupportedException: Keyword not supported! // scenario_midi_dir_exists As Boolean // extdata_midi_dir_exists As Boolean // extdata2_midi_dir_exists As Boolean // */ //; //// fpath_history As New Collection DEL MARGE //int j, i, num; //string buf, buf2; //var sub_folder = default(string); //// 初めて実行する際に、各フォルダにMidiフォルダがあるかチェック //if (!IsMidiSearchPathInitialized) //{ // if (Strings.Len(SRC.ScenarioPath) > 0) // { // // UPGRADE_WARNING: Dir に新しい動作が指定されています。 詳細については、'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"' をクリックしてください。 // if (Strings.Len(FileSystem.Dir(SRC.ScenarioPath + "Midi", FileAttribute.Directory)) > 0) // { // scenario_midi_dir_exists = true; // } // } // if (Strings.Len(SRC.ExtDataPath) > 0) // { // // UPGRADE_WARNING: Dir に新しい動作が指定されています。 詳細については、'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"' をクリックしてください。 // if (Strings.Len(FileSystem.Dir(SRC.ExtDataPath + "Midi", FileAttribute.Directory)) > 0) // { // extdata_midi_dir_exists = true; // } // } // if (Strings.Len(SRC.ExtDataPath2) > 0) // { // // UPGRADE_WARNING: Dir に新しい動作が指定されています。 詳細については、'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"' をクリックしてください。 // if (Strings.Len(FileSystem.Dir(SRC.ExtDataPath2 + "Midi", FileAttribute.Directory)) > 0) // { // extdata2_midi_dir_exists = true; // } // } // // MP3が演奏可能かどうかも調べておく // if (SRC.FileSystem.FileExists(SRC.AppPath + "VBMP3.dll")) // { // is_mp3_available = true; // } // IsMidiSearchPathInitialized = true; //} //// ダミーのファイル名? //if (Strings.Len(midi_name) < 5) //{ // return SearchMidiFileRet; //} //// 引数1として渡された文字列をリストとして扱い、左から順にMIDIを検索 //num = GeneralLib.ListLength(midi_name); //i = 1; //while (i <= num) //{ // // スペースを含むファイル名への対応 // buf = ""; // var loopTo = num; // for (j = i; j <= loopTo; j++) // { // buf2 = Strings.LCase(GeneralLib.ListIndex(midi_name, j)); // // 全体が()で囲まれている場合は()を外す // if (Strings.Left(buf2, 1) == "(" && Strings.Right(buf2, 1) == ")") // { // buf2 = Strings.Mid(buf2, 2, Strings.Len(buf2) - 2); // } // buf = buf + " " + buf2; // if (Strings.Right(buf, 4) == ".mid") // { // break; // } // } // buf = Strings.Trim(buf); // // 同名のMP3ファイルがある場合はMIDIファイルの代わりにMP3ファイルを使う // if (is_mp3_available) // { // fname_mp3 = Strings.Left(buf, Strings.Len(buf) - 4) + ".mp3"; // } // // フルパスでの指定? // if (Strings.InStr(buf, ":") == 2) // { // if (is_mp3_available) // { // if (SRC.FileSystem.FileExists(fname_mp3)) // { // SearchMidiFileRet = fname_mp3; // return SearchMidiFileRet; // } // } // if (SRC.FileSystem.FileExists(buf)) // { // SearchMidiFileRet = buf; // } // return SearchMidiFileRet; // } // // DEL START MARGE // // '履歴を検索してみる // // On Error GoTo NotFound // // fname = fpath_history.Item(buf) // // // // '履歴上にファイルを発見 // // SearchMidiFile = fname // // Exit Function // // NotFound: // // '履歴になかった // // On Error GoTo 0 // // DEL END MARGE // // サブフォルダ指定あり? // if (Strings.InStr(buf, "_") > 0) // { // sub_folder = Strings.Left(buf, Strings.InStr(buf, "_") - 1) + @"\"; // } // // シナリオ側のMidiフォルダ // if (scenario_midi_dir_exists) // { // if (is_mp3_available) // { // if (!string.IsNullOrEmpty(sub_folder)) // { // fname = SRC.ScenarioPath + @"Midi\" + sub_folder + fname_mp3; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // fname = SRC.ScenarioPath + @"Midi\" + fname_mp3; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // if (!string.IsNullOrEmpty(sub_folder)) // { // fname = SRC.ScenarioPath + @"Midi\" + sub_folder + buf; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // fname = SRC.ScenarioPath + @"Midi\" + buf; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // // ExtDataPath側のMidiフォルダ // if (extdata_midi_dir_exists) // { // if (is_mp3_available) // { // if (!string.IsNullOrEmpty(sub_folder)) // { // fname = SRC.ExtDataPath + @"Midi\" + sub_folder + fname_mp3; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // fname = SRC.ExtDataPath + @"Midi\" + fname_mp3; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // if (!string.IsNullOrEmpty(sub_folder)) // { // fname = SRC.ExtDataPath + @"Midi\" + sub_folder + buf; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // fname = SRC.ExtDataPath + @"Midi\" + buf; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // // ExtDataPath2側のMidiフォルダ // if (extdata2_midi_dir_exists) // { // if (is_mp3_available) // { // if (!string.IsNullOrEmpty(sub_folder)) // { // fname = SRC.ExtDataPath2 + @"Midi\" + sub_folder + fname_mp3; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // fname = SRC.ExtDataPath2 + @"Midi\" + fname_mp3; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // if (!string.IsNullOrEmpty(sub_folder)) // { // fname = SRC.ExtDataPath2 + @"Midi\" + sub_folder + buf; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // fname = SRC.ExtDataPath2 + @"Midi\" + buf; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // // 本体側のMidiフォルダ // if (is_mp3_available) // { // if (!string.IsNullOrEmpty(sub_folder)) // { // fname = SRC.AppPath + @"Midi\" + sub_folder + fname_mp3; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // fname = SRC.AppPath + @"Midi\" + fname_mp3; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // if (!string.IsNullOrEmpty(sub_folder)) // { // fname = SRC.AppPath + @"Midi\" + sub_folder + buf; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // } // fname = SRC.AppPath + @"Midi\" + buf; // if (SRC.FileSystem.FileExists(fname)) // { // SearchMidiFileRet = fname; // // fpath_history.Add fname, buf DEL MARGE // return SearchMidiFileRet; // } // i = (j + 1); //} //return SearchMidiFileRet; }
protected override ValueType InvokeInternal(SRC SRC, ValueType etype, string[] @params, int pcount, bool[] is_term, out string str_result, out double num_result) { str_result = ""; num_result = 0d; // XXX 元は expr 切り出してたけれどなんでだろ var list = GeneralLib.ToList(@params[1]); var num = list.Count; var flag = false; // XXX このSwitch何を意図したものなのか分からん。。。 switch (num) { case 1: { if (SRC.PList.IsDefined(list[0])) { { var withBlock17 = SRC.PList.Item(list[0]); if (withBlock17.Unit is null) { flag = false; } else { { var withBlock18 = withBlock17.Unit; if (withBlock18.Status == "出撃" || withBlock18.Status == "格納") { flag = true; } else { flag = false; } } } } } else if (SRC.Expression.GetValueAsLong(@params[1]) != 0) { flag = true; } else { flag = false; } break; } case 2: { if (SRC.PList.IsDefined(list[1])) { var withBlock19 = SRC.PList.Item(list[1]); if (withBlock19.Unit is null) { flag = true; } else { { var withBlock20 = withBlock19.Unit; if (withBlock20.Status == "出撃" || withBlock20.Status == "格納") { flag = false; } else { flag = true; } } } } else if (SRC.Expression.GetValueAsLong(@params[1], true) == 0) { flag = true; } else { flag = false; } break; } default: { if (SRC.Expression.GetValueAsLong(@params[1]) != 0) { flag = true; } else { flag = false; } break; } } if (flag) { str_result = SRC.Expression.GetValueAsString(@params[2], is_term[2]); } else { str_result = SRC.Expression.GetValueAsString(@params[3], is_term[3]); } if (etype == ValueType.NumericType) { num_result = GeneralLib.StrToDbl(str_result); return(ValueType.NumericType); } else { return(ValueType.StringType); } }
protected override int ExecInternal() { string ustatus; string vname; Event.ForEachSet = new List <string>(); switch (ArgNum) { // ユニットに対するForEach case 2: case 3: { if (ArgNum == 2) { ustatus = "出撃 格納"; } else { ustatus = GetArgAsString(3); if (ustatus == "全て") { ustatus = "全"; } } switch (GetArgAsString(2) ?? "") { case "全": if (ustatus == "全") { foreach (Unit u in SRC.UList.Items) { if (u.Status != "他形態" && u.Status != "旧主形態" && u.Status != "旧形態" && u.Status != "破棄") { Event.ForEachSet.Add(u.ID); } } } else { foreach (Unit u in SRC.UList.Items) { if (Strings.InStr(ustatus, u.Status) > 0) { Event.ForEachSet.Add(u.ID); } } } break; case "味方": case "NPC": case "敵": case "中立": { var uparty = GetArgAsString(2); if (ustatus == "全") { foreach (Unit u in SRC.UList.Items) { if ((u.Party0 ?? "") == (uparty ?? "")) { if (u.Status != "他形態" && u.Status != "旧主形態" && u.Status != "旧形態" && u.Status != "破棄") { Event.ForEachSet.Add(u.ID); } } } } else { foreach (Unit u in SRC.UList.Items) { if ((u.Party0 ?? "") == (uparty ?? "")) { if (Strings.InStr(ustatus, u.Status) > 0) { Event.ForEachSet.Add(u.ID); } } } } break; } default: var ugroup = GetArgAsString(2); if (ustatus == "全て") { ustatus = "全"; } foreach (Unit u in SRC.UList.Items) { if (u.CountPilot() > 0) { if ((u.MainPilot().ID ?? "") == (ugroup ?? "") || Strings.InStr(u.MainPilot().ID, ugroup + ":") == 1) { if (ustatus == "全") { if (u.Status != "他形態" && u.Status != "旧主形態" && u.Status != "旧形態" && u.Status != "破棄") { Event.ForEachSet.Add(u.ID); } } else if (Strings.InStr(ustatus, u.Status) > 0) { Event.ForEachSet.Add(u.ID); } } } } break; } break; } // 配列の要素に対するForEach case 4: { // インデックス用変数名 vname = GetArg(2); if (Strings.Left(vname, 1) == "$") { vname = Strings.Mid(vname, 2); } // 配列の変数名 var aname = GetArg(4); if (Strings.Left(aname, 1) == "$") { aname = Strings.Mid(aname, 2); } // Eval関数 if (Strings.LCase(Strings.Left(aname, 5)) == "eval(") { if (Strings.Right(aname, 1) == ")") { aname = Strings.Mid(aname, 6, Strings.Len(aname) - 6); aname = Expression.GetValueAsString(aname); } } // 配列を検索し、配列要素を見つける if (GeneralLib.InStrNotNest(aname, "パイロット一覧(") == 1) { // 配列作成 var pilots = SRC.PList.Items.Where(p => p.Alive && !p.Away) // XXX メインパイロットが差し変わっていたら除外? .Where(p => !(p.Unit != null && p.Unit.CountPilot() > 0 && p == p.Unit.MainPilot() && p != p.Unit.Pilots.First())); // ソート var key_type = Expression.GetValueAsString(aname.InsideKakko()); if (key_type == "名称") { pilots = pilots.OrderBy(x => x.KanaName); } else { pilots = pilots.OrderByDescending(p => { switch (key_type ?? "") { case "レベル": return(500 * p.Level + p.Exp); case "SP": return(p.MaxSP); case "格闘": return(p.Infight); case "射撃": return(p.Shooting); case "命中": return(p.Hit); case "回避": return(p.Dodge); case "技量": return(p.Technique); case "反応": return(p.Intuition); default: return(0); } }); } pilots.ToList().ForEach(p => Event.ForEachSet.Add(p.ID)); } else if (GeneralLib.InStrNotNest(aname, "ユニット一覧(") == 1) { // 配列作成 var units = SRC.UList.Items.Where(u => u.Status == "出撃" || u.Status == "格納" || u.Status == "待機"); var key_type = Expression.GetValueAsString(aname.InsideKakko()); if (key_type == "名称") { units = units.OrderBy(x => x.KanaName); } else { units = units.OrderByDescending(u => { switch (key_type ?? "") { case "ランク": return(u.Rank); case "HP": return(u.HP); case "EN": return(u.EN); case "装甲": return(u.get_Armor("")); case "運動性": return(u.get_Mobility("")); case "移動力": return(u.Speed); case "最大攻撃力": return(u.Weapons .Where(x => x.IsEnable()) .Where(x => !x.IsWeaponClassifiedAs("合")) .Select(x => x.WeaponPower("")) .Append(0) .Max()); case "最長射程": return(u.Weapons .Where(x => x.IsEnable()) .Where(x => !x.IsWeaponClassifiedAs("合")) .Select(x => x.WeaponMaxRange()) .Append(0) .Max()); default: return(0); } }); } units.ToList().ForEach(u => Event.ForEachSet.Add(u.ID)); } else { if (Expression.IsSubLocalVariableDefined(aname)) { // サブルーチンローカルな配列に対するForEach Event.SubLocalVars().ArrayIndexesByName(aname).ToList().ForEach(x => Event.ForEachSet.Add(x)); } else if (Expression.IsLocalVariableDefined(aname)) { // ローカルな配列に対するForEach Event.LocalVariableList.Values.ArrayIndexesByName(aname).ToList().ForEach(x => Event.ForEachSet.Add(x)); } else if (Expression.IsGlobalVariableDefined(aname)) { // グローバルな配列に対するForEach Event.GlobalVariableList.Values.ArrayIndexesByName(aname).ToList().ForEach(x => Event.ForEachSet.Add(x)); } // リストに対するForEach if (Event.ForEachSet.Count == 0) { var buf = Expression.GetValueAsString(aname); Event.ForEachSet = GeneralLib.ToList(buf); } } break; } default: throw new EventErrorException(this, "ForEachコマンドの引数の数が違います"); } if (Event.ForEachSet.Count > 0) { // ForEachの実行要素がある場合 Event.ForEachIndex = 1; Event.ForIndex = (Event.ForIndex + 1); if (ArgNum < 4) { Event.SelectedUnitForEvent = SRC.UList.Item(Event.ForEachSet[0]); } else { Expression.SetVariableAsString(GetArg(2), Event.ForEachSet[0]); } return(EventData.NextID); } else { // ForEachの実行要素がない場合 // 対応するNextを探す var depth = 1; foreach (var i in AfterEventIdRange()) { var cmd = Event.EventCmd[i]; switch (cmd.Name) { case CmdType.ForCmd: case CmdType.ForEachCmd: depth = (depth + 1); break; case CmdType.NextCmd: depth = (depth - 1); if (depth == 0) { return(cmd.EventData.NextID); } break; } } throw new EventErrorException(this, "ForまたはForEachとNextが対応していません"); } }
// 戦闘アニメを再生 public void PlayAnimation(string main_situation, string sub_situation = "", bool keep_message_form = false) { var in_bulk = false; // 戦闘アニメデータを検索 var anime = AnimationData(main_situation, sub_situation); // 見つからなかった場合は一括指定を試してみる if (string.IsNullOrEmpty(anime)) { switch (Strings.Right(main_situation, 4) ?? "") { case "(準備)": case "(攻撃)": case "(命中)": { anime = AnimationData(Strings.Left(main_situation, Strings.Len(main_situation) - 4), sub_situation); in_bulk = true; break; } case "(発動)": { anime = AnimationData(Strings.Left(main_situation, Strings.Len(main_situation) - 4), sub_situation); break; } } } anime = anime.Trim(); // 表示キャンセル if (string.IsNullOrEmpty(anime) || anime == "-") { return; } // マウスの右ボタンでキャンセル if (GUI.IsRButtonPressed()) { // アニメの終了処理はキャンセルしない if (main_situation != "終了" && Strings.Right(main_situation, 4) != "(終了)") { // 式評価のみ行う Expression.FormatMessage(ref anime); return; } } // メッセージウィンドウは表示されている? var is_message_form_opened = GUI.MessageFormVisible; // TODO Impl オブジェクト色等 //// オブジェクト色等を記録しておく //prev_obj_color = Event.ObjColor; //prev_obj_fill_color = Event.ObjFillColor; //prev_obj_fill_style = Event.ObjFillStyle; //prev_obj_draw_width = Event.ObjDrawWidth; //prev_obj_draw_option = Event.ObjDrawOption; //// オブジェクト色等をデフォルトに戻す //Event.ObjColor = ColorTranslator.ToOle(Color.White); //Event.ObjFillColor = ColorTranslator.ToOle(Color.White); //Event.ObjFillStyle = vbFSTransparent; //Event.ObjDrawWidth = 1; //Event.ObjDrawOption = ""; // 検索するシチュエーションが武器名かどうか調べる var is_weapon = Weapons.Any(w => main_situation == w.Name + "(攻撃)"); // 検索するシチュエーションがアビリティかどうか調べる var is_ability = Abilities.Any(a => main_situation == a.Data.Name + "(発動)"); // イベント用ターゲットを記録しておく var prev_selected_target = Event.SelectedTargetForEvent; // 攻撃でもアビリティでもない場合、ターゲットが設定されていなければ // 自分自身をターゲットに設定する // (発動アニメではアニメ表示にSelectedTargetForEventが使われるため) if (!is_weapon && !is_ability) { if (Event.SelectedTargetForEvent is null) { Event.SelectedTargetForEvent = this; } } // アニメ指定を分割 var animes = anime.Split(";").ToList(); try { var need_refresh = false; var wait_time = 0; var sname = ""; var buf = ""; foreach (var a in animes) { var animepart = a; // 最後に実行されたのがサブルーチン呼び出しかどうかを判定するため // サブルーチン名をあらかじめクリアしておく sname = ""; // 式評価 Expression.FormatMessage(ref animepart); // 画面クリア? if (Strings.LCase(animepart) == "clear") { GUI.ClearPicture(); need_refresh = true; goto NextAnime; } // 戦闘アニメ以外の特殊効果 switch (Strings.LCase(Strings.Right(GeneralLib.LIndex(animepart, 1), 4)) ?? "") { case ".wav": case ".mp3": { // 効果音 Sound.PlayWave(animepart); if (wait_time > 0) { if (need_refresh) { GUI.UpdateScreen(); need_refresh = false; } GUI.Sleep(wait_time); wait_time = 0; } goto NextAnime; } case ".bmp": case ".jpg": case ".gif": case ".png": { // カットインの表示 if (wait_time > 0) { animepart = (wait_time / 100d) + ";" + animepart; wait_time = 0; need_refresh = false; } else if (Strings.Left(animepart, 1) == "@") { need_refresh = false; } else { need_refresh = true; } GUI.DisplayBattleMessage("-", animepart, msg_mode: ""); goto NextAnime; } } switch (Strings.LCase(GeneralLib.LIndex(animepart, 1)) ?? "") { case "line": case "circle": case "arc": case "oval": case "color": case "fillcolor": case "fillstyle": case "drawwidth": { // 画面処理コマンド if (wait_time > 0) { animepart = (wait_time / 100d) + ";" + animepart; wait_time = 0; need_refresh = false; } else { need_refresh = true; } GUI.DisplayBattleMessage("-", animepart, msg_mode: ""); goto NextAnime; } case "center": { // 指定したユニットを中央表示 buf = Expression.GetValueAsString(GeneralLib.ListIndex(animepart, 2)); if (SRC.UList.IsDefined(buf)) { { var withBlock = SRC.UList.Item(buf); GUI.Center(withBlock.x, withBlock.y); GUI.RedrawScreen(); need_refresh = false; } } goto NextAnime; } case "keep": { // そのまま終了 break; } } // ウェイト? if (Information.IsNumeric(animepart)) { wait_time = (int)(100d * Conversions.ToDouble(animepart)); goto NextAnime; } // サブルーチンの呼び出しが確定 // 戦闘アニメ再生用のサブルーチン名を作成 sname = GeneralLib.LIndex(animepart, 1); if (Strings.Left(sname, 1) == "@") { sname = Strings.Mid(sname, 2); } else if (is_weapon) { // 武器名の場合 sname = "戦闘アニメ_" + sname + "攻撃"; } else { // その他の場合 // 括弧を含んだ武器名に対応するため、"("は後ろから検索 var idx = GeneralLib.InStr2(main_situation, "("); // 変形系のシチュエーションではサフィックスを無視 if (idx > 0) { switch (Strings.Left(main_situation, idx - 1) ?? "") { case "変形": case "ハイパーモード": case "ノーマルモード": case "パーツ分離": case "合体": case "分離": { idx = 0; break; } } } // 武器名(攻撃無効化)の場合もサフィックスを無視 if (idx > 0) { if (Strings.Mid(main_situation, idx) == "(攻撃無効化)") { idx = 0; } } if (idx > 0) { // サフィックスあり sname = "戦闘アニメ_" + sname + Strings.Mid(main_situation, idx + 1, Strings.Len(main_situation) - idx - 1); } else { sname = "戦闘アニメ_" + sname + "発動"; } } // サブルーチンが見つからなかった if (Event.FindNormalLabel(sname) == 0) { if (in_bulk) { // 一括指定を利用している場合 switch (Strings.Right(main_situation, 4) ?? "") { case "(準備)": { // 表示をキャンセル goto NextAnime; } case "(攻撃)": { // 複数のアニメ指定がある場合は諦めて他のものを使う if (animes.Count > 1) { goto NextAnime; } // そうでなければ「デフォルト」を使用 sname = "戦闘アニメ_デフォルト攻撃"; break; } case "(命中)": { // 複数のアニメ指定がある場合は諦めて他のものを使う if (animes.Count > 1) { goto NextAnime; } // そうでなければ「ダメージ」を使用 sname = "戦闘アニメ_ダメージ命中"; break; } } } else { if (wait_time > 0) { animepart = (wait_time / 100d) + ";" + animepart; wait_time = 0; } if (!GUI.MessageFormVisible) { if (ReferenceEquals(Commands.SelectedTarget, this)) { GUI.OpenMessageForm(this, u2: null); } else { GUI.OpenMessageForm(Commands.SelectedTarget, this); } } GUI.DisplayBattleMessage("-", animepart, msg_mode: ""); goto NextAnime; } } sname = "`" + sname + "`"; // 引数の構築 sname = sname + "," + string.Join(",", GeneralLib.ToList(animepart).Skip(1)); if (in_bulk) { sname = sname + ",`一括指定`"; } // 戦闘アニメ再生前にウェイトを入れる if (need_refresh) { GUI.UpdateScreen(); need_refresh = false; } if (wait_time > 0) { GUI.Sleep(wait_time); wait_time = 0; } // 画像描画が行われたかどうかの判定のためにフラグを初期化 GUI.IsPictureDrawn = false; // 戦闘アニメ再生 Event.SaveBasePoint(); Expression.CallFunction("Call(" + sname + ")", Expressions.ValueType.StringType, out buf, out _); Event.RestoreBasePoint(); // 画像を消去しておく if (GUI.IsPictureDrawn && Strings.LCase(buf) != "keep") { GUI.ClearPicture(); GUI.UpdateScreen(); } NextAnime: ; } // 戦闘アニメ再生後にウェイトを入れる? if (need_refresh) { GUI.UpdateScreen(); need_refresh = false; } if (wait_time > 0) { GUI.Sleep(wait_time); wait_time = 0; } // 画像を消去しておく if (GUI.IsPictureDrawn && string.IsNullOrEmpty(sname) && Strings.InStr(main_situation, "(準備)") == 0 && Strings.LCase(anime) != "keep") { GUI.ClearPicture(); GUI.UpdateScreen(); } // 最初から表示されていたのでなければメッセージウィンドウを閉じる if (!is_message_form_opened && !keep_message_form) { GUI.CloseMessageForm(); } //// オブジェクト色等を元に戻す //Event.ObjColor = prev_obj_color; //Event.ObjFillColor = prev_obj_fill_color; //Event.ObjFillStyle = prev_obj_fill_style; //Event.ObjDrawWidth = prev_obj_draw_width; //Event.ObjDrawOption = prev_obj_draw_option; // イベント用ターゲットを元に戻す Event.SelectedTargetForEvent = prev_selected_target; } catch (Exception ex) { // TODO Handle error //if (Strings.Len(Event.EventErrorMessage) > 0) //{ // Event.DisplayEventErrorMessage(Event.CurrentLineNum, Event.EventErrorMessage); // Event.EventErrorMessage = ""; //} //else //{ // Event.DisplayEventErrorMessage(Event.CurrentLineNum, ""); //} Event.DisplayEventErrorMessage(Event.CurrentLineNum, ex.Message); } }