Example #1
0
        // 「アビリティ」コマンドを開始
        // 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();
        }