Пример #1
0
        // イベントを登録しておき、後で実行
        public void RegisterEvent(params string[] Args)
        {
            var item = string.Join(" ", Args);

            EventQue.Enqueue(item);
        }
Пример #2
0
        // イベントの実行
        public void HandleEvent(params string[] Args)
        {
            SRC.LogDebug(">", Args);

            // 画面入力をロック
            var prev_is_gui_locked = GUI.IsGUILocked;

            if (!GUI.IsGUILocked)
            {
                GUI.LockGUI();
            }

            // 現在選択されているユニット&ターゲットをイベント用に設定
            // (SearchLabel()実行時の式計算用にあらかじめ設定しておく)
            SelectedUnitForEvent = Commands.SelectedUnit;
            // 引数に指定されたユニットを優先
            if (Args.Length > 1)
            {
                if (SRC.PList.IsDefined(Args[1]))
                {
                    var p = SRC.PList.Item(Args[1]);
                    if (p.Unit is object)
                    {
                        SelectedUnitForEvent = p.Unit;
                    }
                }
            }
            SelectedTargetForEvent = Commands.SelectedTarget;

            // イベントキューを作成
            // XXX キューをいつ処理しきるのか?
            //event_que_idx = Information.UBound(EventQue);
            switch (Args[0])
            {
            case "プロローグ":
            {
                EventQue.Enqueue("プロローグ");
                SRC.Stage = "プロローグ";
                break;
            }

            case "エピローグ":
            {
                EventQue.Enqueue("エピローグ");
                SRC.Stage = "エピローグ";
                break;
            }

            case "破壊":
            {
                EventQue.Enqueue("破壊 " + Args[1]);
                var p      = SRC.PList.Item(Args[1]);
                var uparty = p.Party;
                if (p.Unit != null)
                {
                    var u = p.Unit;
                    // 格納されていたユニットも破壊しておく
                    while (u.CountUnitOnBoard() > 0)
                    {
                        var onBoardUnit = u.UnitOnBoards.First();
                        onBoardUnit.UnloadUnit(onBoardUnit.ID);
                        onBoardUnit.Status = "破壊";
                        onBoardUnit.HP     = 0;
                        EventQue.Enqueue("マップ攻撃破壊 " + onBoardUnit.MainPilot().ID);
                    }
                    uparty = u.Party0;
                }

                // 全滅の判定
                var flag = false;
                foreach (Unit currentU in SRC.UList.Items)
                {
                    if ((currentU.Party0 ?? "") == (uparty ?? "") &&
                        currentU.Status == "出撃" &&
                        !currentU.IsConditionSatisfied("憑依"))
                    {
                        flag = true;
                        break;
                    }
                }
                if (!flag)
                {
                    EventQue.Enqueue("全滅 " + uparty);
                }
                break;
            }

            case "マップ攻撃破壊":
            {
                EventQue.Enqueue("マップ攻撃破壊 " + Args[1]);
                var p      = SRC.PList.Item(Args[1]);
                var uparty = p.Party;
                if (p.Unit != null)
                {
                    var u = p.Unit;
                    // 格納されていたユニットも破壊しておく
                    while (u.CountUnitOnBoard() > 0)
                    {
                        var onBoardUnit = u.UnitOnBoards.First();
                        onBoardUnit.UnloadUnit(onBoardUnit.ID);
                        onBoardUnit.Status = "破壊";
                        onBoardUnit.HP     = 0;
                        EventQue.Enqueue("マップ攻撃破壊 " + onBoardUnit.MainPilot().ID);
                    }
                    uparty = u.Party0;
                }

                // XXX 全滅の処理どこでやってんの?

                break;
            }

            case "ターン":
                EventQue.Enqueue(string.Join(" ", "ターン ", "全", Args[2]));
                EventQue.Enqueue(string.Join(" ", "ターン ", Args[1], Args[2]));
                break;

            case "損傷率":
                EventQue.Enqueue(string.Join(" ", "損傷率", Args[1], Args[2]));
                break;

            case "攻撃":
                EventQue.Enqueue(string.Join(" ", "攻撃", Args[1], Args[2]));
                break;

            case "攻撃後":
                EventQue.Enqueue(string.Join(" ", "攻撃後", Args[1], Args[2]));
                break;

            case "会話":
                EventQue.Enqueue(string.Join(" ", "会話", Args[1], Args[2]));
                break;

            case "接触":
                EventQue.Enqueue(string.Join(" ", "接触", Args[1], Args[2]));
                break;

            case "進入":
                EventQue.Enqueue(string.Join(" ", "進入", Args[1], Args[2], Args[3]));
                EventQue.Enqueue(string.Join(" ", "進入", Args[1], Map.Terrain(Conversions.ToInteger(Args[2]), Conversions.ToInteger(Args[3])).Name));
                if (Conversions.ToInteger(Args[2]) == 1)
                {
                    EventQue.Enqueue(string.Join(" ", "脱出", Args[1], "W"));
                }
                else if (Conversions.ToInteger(Args[2]) == Map.MapWidth)
                {
                    EventQue.Enqueue(string.Join(" ", "脱出", Args[1], "E"));
                }
                else if (Conversions.ToInteger(Args[3]) == 1)
                {
                    EventQue.Enqueue(string.Join(" ", "脱出", Args[1], "N"));
                }
                else if (Conversions.ToInteger(Args[3]) == Map.MapHeight)
                {
                    EventQue.Enqueue(string.Join(" ", "脱出", Args[1], "S"));
                }
                break;

            case "収納":
                EventQue.Enqueue(string.Join(" ", "収納", Args[1]));
                break;

            case "使用":
                EventQue.Enqueue(string.Join(" ", "使用", Args[1], Args[2]));
                break;

            case "使用後":
                EventQue.Enqueue(string.Join(" ", "使用後", Args[1], Args[2]));
                break;

            case "行動終了":
                EventQue.Enqueue(string.Join(" ", "行動終了", Args[1]));
                break;

            case "ユニットコマンド":
                var cmd1 = string.Join(" ", "ユニットコマンド", Args[1], Args[2]);
                if (IsEventDefined(cmd1))
                {
                    EventQue.Enqueue(cmd1);
                }
                else
                {
                    var cmd2 = string.Join(" ", "ユニットコマンド", Args[1], SRC.PList.Item(Args[2]).Unit.Name);
                    EventQue.Enqueue(cmd2);
                }
                break;

            default:
                EventQue.Enqueue(string.Join(" ", Args));
                break;
            }

            if (CallDepth > MaxCallDepth)
            {
                GUI.ErrorMessage("サブルーチンの呼び出し階層が" + SrcFormatter.Format(MaxCallDepth) + "を超えているため、イベントの処理が出来ません");
                CallDepth = MaxCallDepth;
                return;
            }

            // 現在の状態を保存
            ArgIndexStack[CallDepth] = ArgIndex;
            VarIndexStack[CallDepth] = VarIndex;
            ForIndexStack[CallDepth] = ForIndex;
            SaveBasePoint();

            // 呼び出し階層数をインクリメント
            var prev_call_depth = CallDepth;

            CallDepth = (CallDepth + 1);

            // 各イベントを発生させる
            // XXX キューのスキップすんの?
            //i = event_que_idx;
            SRC.IsCanceled = false;
            while (EventQue.Count > 0)
            {
                var eventItem = EventQue.Dequeue();
                SRC.LogDebug("EventQue.Dequeue", eventItem);

                // 前のイベントで他のユニットが出現している可能性があるので
                // 本当に全滅したのか判定
                if (GeneralLib.LIndex(eventItem, 1) == "全滅")
                {
                    var uparty = GeneralLib.LIndex(eventItem, 2);
                    if (SRC.UList.Items.Any(u => u.Party0 == uparty &&
                                            u.Status == "出撃" &&
                                            !u.IsConditionSatisfied("憑依")))
                    {
                        continue;
                    }
                }

                CurrentLabel = -1;
                var ret             = -1;
                var main_event_done = false;
                while (true)
                {
                    // 現在選択されているユニット&ターゲットをイベント用に設定
                    // SearchLabel()で入れ替えられる可能性があるので、毎回設定し直す必要あり
                    SelectedUnitForEvent = Commands.SelectedUnit;
                    // 引数に指定されたユニットを優先
                    if (Args.Length > 1)
                    {
                        if (SRC.PList.IsDefined(Args[1]))
                        {
                            var p = SRC.PList.Item(Args[1]);
                            if (p.Unit is object)
                            {
                                SelectedUnitForEvent = p.Unit;
                            }
                        }
                    }
                    SelectedTargetForEvent = Commands.SelectedTarget;

                    // 実行するイベントラベルを探す
                    do
                    {
                        if (Information.IsNumeric(eventItem))
                        {
                            // 数値の場合はラベルの示す位置が指定されたとみなす
                            // (マップコマンド、ユニットコマンド)
                            if (CurrentLabel < 0)
                            {
                                ret = Conversions.ToInteger(eventItem);
                            }
                            else
                            {
                                ret = -1;
                            }
                        }
                        else
                        {
                            // 数値以外はラベルを探す
                            ret = SearchLabel(eventItem, CurrentLabel + 1);
                        }

                        // ラベルが見つからなければ終わり
                        if (ret < 0)
                        {
                            break;
                        }

                        CurrentLabel = ret;
                        if (!EventData[ret].IsAlwaysEventLabel)
                        {
                            // 常時イベントではないイベントは1度しか実行しない
                            if (main_event_done)
                            {
                                ret = -1;
                            }
                            else
                            {
                                main_event_done = true;
                            }
                        }
                    }while (ret < 0);

                    if (ret < 0)
                    {
                        break;
                    }

                    // 戦闘後のイベント実行前にはいくつかの後始末が必要
                    if (!EventData[ret].IsAlwaysEventLabel)
                    {
                        if (Args[0] == "破壊" ||
                            Args[0] == "損傷率" ||
                            Args[0] == "攻撃後" ||
                            Args[0] == "全滅")
                        {
                            // 画面をクリア
                            if (GUI.MainFormVisible)
                            {
                                Status.ClearUnitStatus();
                                GUI.RedrawScreen();
                            }

                            // メッセージウィンドウを閉じる
                            if (GUI.MessageFormVisible)
                            {
                                GUI.CloseMessageForm();
                            }
                        }
                    }

                    // ラベルの行は実行しても無駄なので
                    ret = ret + 1;
                    GUI.DoEvents();

                    // イベントの各コマンドを実行
                    do
                    {
                        CurrentLineNum = ret;
                        if (CurrentLineNum >= EventCmd.Count)
                        {
                            break;
                        }

                        ret = EventCmd[CurrentLineNum].Exec();
                    }while (ret > 0);

                    // ステージが終了 or キャンセル?
                    if (SRC.IsScenarioFinished || SRC.IsCanceled)
                    {
                        break;
                    }
                }
                // ステージが終了 or キャンセル?
                if (SRC.IsScenarioFinished || SRC.IsCanceled)
                {
                    break;
                }
            }
            ;

            if (CallDepth >= 0)
            {
                // 呼び出し階層数を元に戻す
                // (サブルーチン内でExitが呼ばれることがあるので単純に-1出来ない)
                CallDepth = prev_call_depth;

                // イベント実行前の状態に復帰
                ArgIndex = ArgIndexStack[CallDepth];
                VarIndex = VarIndexStack[CallDepth];
                ForIndex = ForIndexStack[CallDepth];
            }
            else
            {
                ArgIndex = 0;
                VarIndex = 0;
                ForIndex = 0;
            }

            //// イベントキューを元に戻す
            //Array.Resize(EventQue, GeneralLib.MinLng(event_que_idx - 1, Information.UBound(EventQue)) + 1);

            // フォント設定をデフォルトに戻す
            // XXX 位置はリセットしない?
            GUI.ResetDrawString();
            GUI.PermanentStringMode = false;
            GUI.KeepStringMode      = false;

            // オブジェクト色をデフォルトに戻す
            // XXX これはEventsが持ってていいのか?
            ObjColor      = Color.White;
            ObjFillColor  = Color.White;
            ObjFillStyle  = FillStyle.VbFSTransparent;
            ObjDrawWidth  = 1;
            ObjDrawOption = "";

            // 描画の基準座標位置を元に戻す
            RestoreBasePoint();

            // 画面入力のロックを解除
            if (!prev_is_gui_locked)
            {
                GUI.UnlockGUI();
            }
        }