// 「アビリティ」コマンドを開始 // is_item=True の場合は「アイテム」コマンドによる使い捨てアイテムのアビリティ private void StartAbilityCommand(bool is_item = false) { string cap; GUI.LockGUI(); // 使用するアビリティを選択 if (is_item) { cap = "アイテム選択"; } else { cap = Expression.Term("アビリティ", SelectedUnit) + "選択"; } UnitAbility unitAbility; if (CommandState == "コマンド選択") { unitAbility = GUI.AbilityListBox(SelectedUnit, new UnitAbilityList(AbilityListMode.BeforeMove, SelectedUnit), cap, "移動前", is_item); } else { unitAbility = GUI.AbilityListBox(SelectedUnit, new UnitAbilityList(AbilityListMode.AfterMove, SelectedUnit), cap, "移動後", is_item); } // キャンセル if (unitAbility == null) { SelectedAbility = 0; if (SRC.AutoMoveCursor) { GUI.RestoreCursorPos(); } CancelCommand(); GUI.UnlockGUI(); return; } SelectedAbility = unitAbility.AbilityNo(); var currentUnit = SelectedUnit; // アビリティ専用BGMがあればそれを演奏 if (currentUnit.IsFeatureAvailable("アビリティBGM")) { var BGM = currentUnit.Features.Where(x => x.Name == "アビリティBGM") .Where(x => GeneralLib.LIndex(x.Data, 1) == unitAbility.Data.Name) .Select(x => Sound.SearchMidiFile(Strings.Mid(x.Data, Strings.InStr(x.Data, " ") + 1))) .FirstOrDefault(); if (!string.IsNullOrEmpty(BGM)) { Sound.ChangeBGM(BGM); } } // 射程0のアビリティはその場で実行 if (unitAbility.Data.MaxRange == 0) { SelectedTarget = SelectedUnit; // 変身アビリティであるか判定 var is_transformation = unitAbility.Data.Effects.Any(x => x.EffectType == "変身"); SelectedAbilityName = unitAbility.Data.Name; // 使用イベント Event.HandleEvent("使用", SelectedUnit.MainPilot().ID, SelectedAbilityName); if (SRC.IsScenarioFinished) { SRC.IsScenarioFinished = false; GUI.UnlockGUI(); return; } if (SRC.IsCanceled) { SRC.IsCanceled = false; WaitCommand(); return; } // アビリティを実行 SelectedUnit.ExecuteAbility(unitAbility, SelectedUnit); SelectedUnit = SelectedUnit.CurrentForm(); GUI.CloseMessageForm(); // 破壊イベント { var withBlock1 = SelectedUnit; if (withBlock1.Status == "破壊") { if (withBlock1.CountPilot() > 0) { Event.HandleEvent("破壊", withBlock1.MainPilot().ID); if (SRC.IsScenarioFinished) { SRC.IsScenarioFinished = false; GUI.UnlockGUI(); return; } if (SRC.IsCanceled) { SRC.IsCanceled = false; GUI.UnlockGUI(); return; } } WaitCommand(); return; } } // 使用後イベント { var withBlock2 = SelectedUnit; if (withBlock2.CountPilot() > 0) { Event.HandleEvent("使用後", withBlock2.MainPilot().ID, SelectedAbilityName); if (SRC.IsScenarioFinished) { SRC.IsScenarioFinished = false; GUI.UnlockGUI(); return; } if (SRC.IsCanceled) { SRC.IsCanceled = false; GUI.UnlockGUI(); return; } } } // 変身アビリティの場合は行動終了しない if (!is_transformation || CommandState == "移動後コマンド選択") { WaitCommand(); } else { if (SelectedUnit.Status == "出撃") { // カーソル自動移動 if (SRC.AutoMoveCursor) { GUI.MoveCursorPos("ユニット選択", SelectedUnit); } Status.DisplayUnitStatus(SelectedUnit); } else { Status.ClearUnitStatus(); } CommandState = "ユニット選択"; GUI.UnlockGUI(); } return; } // アビリティの射程を求めておく var min_range = unitAbility.AbilityMinRange(); var max_range = unitAbility.AbilityMaxRange(); { // マップ型アビリティかどうかで今後のコマンド処理の進行の仕方が異なる if (is_item) { if (unitAbility.IsAbilityClassifiedAs("M")) { SelectedCommand = "マップアイテム"; } else { SelectedCommand = "アイテム"; } } else { if (unitAbility.IsAbilityClassifiedAs("M")) { SelectedCommand = "マップアビリティ"; } else { SelectedCommand = "アビリティ"; } } // アビリティの効果範囲を設定 if (unitAbility.IsAbilityClassifiedAs("M直")) { Map.AreaInCross(currentUnit.x, currentUnit.y, min_range, max_range); } else if (unitAbility.IsAbilityClassifiedAs("M拡")) { Map.AreaInWideCross(currentUnit.x, currentUnit.y, min_range, max_range); } else if (unitAbility.IsAbilityClassifiedAs("M扇")) { Map.AreaInSectorCross(currentUnit.x, currentUnit.y, min_range, max_range, (int)unitAbility.AbilityLevel("M扇")); } else if (unitAbility.IsAbilityClassifiedAs("M移")) { Map.AreaInMoveAction(SelectedUnit, max_range); } else { Map.AreaInRange(currentUnit.x, currentUnit.y, max_range, min_range, "すべて"); } // 射程1の合体技はパートナーで相手を取り囲んでいないと使用できない if (unitAbility.IsAbilityClassifiedAs("合") && !unitAbility.IsAbilityClassifiedAs("M") && unitAbility.Data.MaxRange == 1) { foreach (var t in Map.AdjacentUnit(currentUnit)) { if (currentUnit.IsAlly(t)) { var partners = unitAbility.CombinationPartner(t.x, t.y); if (partners.Count == 0) { Map.MaskData[t.x, t.y] = true; } } } } } // ユニットがいるマスの処理 if (!unitAbility.IsAbilityClassifiedAs("M投") && !unitAbility.IsAbilityClassifiedAs("M線") && !unitAbility.IsAbilityClassifiedAs("M移")) { var loopTo2 = GeneralLib.MinLng(currentUnit.x + max_range, Map.MapWidth); for (var i = GeneralLib.MaxLng(currentUnit.x - max_range, 1); i <= loopTo2; i++) { var loopTo3 = GeneralLib.MinLng(currentUnit.y + max_range, Map.MapHeight); for (var j = GeneralLib.MaxLng(currentUnit.y - max_range, 1); j <= loopTo3; j++) { if (!Map.MaskData[i, j]) { var t = Map.MapDataForUnit[i, j]; if (t is object) { // 有効? if (unitAbility.IsAbilityEffective(t)) { Map.MaskData[i, j] = false; } else { Map.MaskData[i, j] = true; } } } } } } // 支援専用アビリティは自分には使用できない if (!Map.MaskData[currentUnit.x, currentUnit.y]) { if (unitAbility.IsAbilityClassifiedAs("援")) { Map.MaskData[currentUnit.x, currentUnit.y] = true; } } if (!Expression.IsOptionDefined("大型マップ")) { GUI.Center(currentUnit.x, currentUnit.y); } GUI.MaskScreen(); if (CommandState == "コマンド選択") { CommandState = "ターゲット選択"; } else { CommandState = "移動後ターゲット選択"; } // カーソル自動移動を行う? if (!SRC.AutoMoveCursor) { GUI.UnlockGUI(); return; } // 自分から最も近い味方ユニットを探す { Unit t = null; foreach (Unit u in SRC.UList.Items) { if (u.Status == "出撃" && u.Party == "味方") { if (Map.MaskData[u.x, u.y] == false && !ReferenceEquals(u, SelectedUnit)) { if (t is null) { t = u; } else if (Math.Pow(Math.Abs((SelectedUnit.x - u.x)), 2d) + Math.Pow(Math.Abs((SelectedUnit.y - u.y)), 2d) < Math.Pow(Math.Abs((SelectedUnit.x - t.x)), 2d) + Math.Pow(Math.Abs((SelectedUnit.y - t.y)), 2d)) { t = u; } } } } // 適当がユニットがなければ自分自身を選択 if (t is null) { t = SelectedUnit; } // カーソルを移動 GUI.MoveCursorPos("ユニット選択", t); // ターゲットのステータスを表示 if (!ReferenceEquals(SelectedUnit, t)) { Status.DisplayUnitStatus(t); } } GUI.UnlockGUI(); }