Exemple #1
0
        public MapWindow(WarPresentationModel model)
        {
            Contract.Requires(model != null);

            model.MapWindow = this;

            // フィールドの初期化
            _model = model;
            _chipPixelSize = WarGlobal.ChipSize;
            _offsetX = -_chipPixelSize.Width / 2;

            InitializeComponent();
            InitializeMapPanel();

            // イベント等の追加
            Global.MainLoop.TickEvents.Add(0, ElapseEvent);
            Closed += (sender_, e_) =>
                Global.MainLoop.TickEvents.Remove(ElapseEvent);

            model.ScopeChangedEvent += scope => {
                Action<Point2> func = p => _mapPanel.Invalidate(false);
                if (scope != null)
                    model.CursorChipPointChangedEvent += func;
                else
                    model.CursorChipPointChangedEvent -= func;
                // スコープが変化したので再描画
                _mapPanel.Invalidate(false);
            };
            WarMap.Changed += _ => _mapPanel.Invalidate(false);

            model.Situation.ActiveUnitChanged += unit =>
                CenteringByChipPoint(unit.Location);
        }
        protected override void CreateDeployUnitPhase(WarPresentationModel model, List<List<WarUnit>> friendUnits, List<WarUnit> enemyUnits, MainWindow mainWindow)
        {
            Phases.DeployUnitPhase.Start = situation_ =>
            {
                // 味方軍の配置
                int i = 0;
                foreach (var funits in friendUnits)
                {
                    foreach (var unit in funits)
                    {
                        situation_.Map.Deploy(unit, new Point2(i + 5, 5));
                        i++;
                    }
                }

                //敵軍の配置
                i = 0;
                foreach (var unit in enemyUnits)
                {
                    situation_.Map.Deploy(unit, new Point2(i + 3, 0));
                    i++;
                }

                //初期配置描画をなくすために、nullをつっこむ
                situation_.Map.InitDeployCandidate = null;

                situation_.PhaseManager.ChangePhase(situation_, Phases.BattlePhase);
            };
        }
        protected virtual void CreateBattlePhase(WarPresentationModel model, List<List<WarUnit>> friendUnits, List<WarUnit> enemyUnits, MainWindow mainWindow)
        {
            Phases.BattlePhase.Start = situation_ =>
            {
                situation_.PhaseManager.StartPhase(situation_, Phases.TurnPhase);
            };

            Phases.BattlePhase.Exit = situation_ =>
            {
                //TODO: area更新、経験値はリアルタイムで
                //_battleArea.Unitsを更新

                //街、道、壁の更新
                updateAreaWithCityRoadWall(situation_.Map);

                switch (_result)
                {
                    case BattleResult.Win:
                        if (_friendProvince != null)
                            _battleArea.Province = _friendProvince;
                        break;
                    case BattleResult.Lose:
                        break;
                    case BattleResult.TwentyTurn:
                        MessageBox.Show("20ターン経過しました。消耗戦になるので退却します。");
                        break;
                    default:
                        break;
                }
                mainWindow.Dispose();
                _battleFinish();
            };
        }
 public void CreatePhase(WarPresentationModel model, List<List<WarUnit>> friendUnits, List<WarUnit> enemyUnits, MainWindow mainWindow)
 {
     CreateDeployUnitPhase(model, friendUnits, enemyUnits, mainWindow);
     CreateBattlePhase(model, friendUnits, enemyUnits, mainWindow);
     CreateTurnPhase(model, friendUnits, enemyUnits, mainWindow);
     CreateInitiativePhase(model, friendUnits, enemyUnits, mainWindow);
 }
        public DeploymentWindow(List<List<WarUnit>> deployingUnitsList, WarPresentationModel model, WarMap warMap, Action finishDelegate)
        {
            InitializeComponent();
            _deployingUnitsList = deployingUnitsList;
            _index = 0;
            _model = model;
            _warMap = warMap;
            _finishDelegate = finishDelegate;
            _model.SelectMapChipEvent += Deploy;
            _model.CancelMapChipEvent += Undeploy;

            initializeDeployment();
        }
        public void ShowMapWindow(Situation situation, WarPresentationModel model)
        {
            // �Ƃ肠�����S�ẴE�B���h�E��\������
            // MapWindow �C���X�^���X�̐���
            var mapWindow = new MapWindow(model);
            mainDock = mapWindow;
            mainDock.AllowEndUserDocking = false;
            mainDock.Show(dockPanel, DockState.Document);

            var commandWindow = new CommandWindow(model);
            commandWindow.Show(mapWindow.Pane, DockAlignment.Top, 0.12);

            var mapChipInfoWindow = new MapChipInfoWindow(model);
            mapChipInfoWindow.Show(commandWindow.Pane, DockAlignment.Right, 0.5);

            // UnitMiniInfoWindow�\���p
            Action<Point2> showUnitMiniInfoWindow = delegate(Point2 p) {
                var unit = model.WarMap[p].Unit;
                if (unit != null)
                {
                    MiniUnitInfoWindow.ShowWindow(this, unit);
                }
                else
                {
                    MiniUnitInfoWindow.HideWindow();
                }
            };

            // MapChip�N���b�N�ɂ��UnitInfoWindow�̕\���̃f���Q�[�g��lj�
            model.SelectMapChipEvent += p => {
                var unit = model.WarMap[p].Unit;
                if (unit != null && model.Scope == null)
                    UnitInfoWindow.ShowWindow(this, unit);
                else
                    UnitInfoWindow.HideWindow();
            };

            model.CursorChipPointChangedEvent += showUnitMiniInfoWindow;
            model.CursorEnterEvent += showUnitMiniInfoWindow;
            model.CursorLeaveEvent += delegate {
                if (MiniUnitInfoWindow.IsInitialized && !MiniUnitInfoWindow.IsOnCursor)
                    MiniUnitInfoWindow.HideWindow();
            };
        }
        /// <summary>
        /// このウインドウを表示する
        /// </summary>
        /// <param name="model"></param>
        /// <param name="doer"></param>
        /// <param name="finished"></param>
        /// <param name="index">魔法の属性を示すインデックス値</param>
        public void Show(WarPresentationModel model, WarUnit doer, Action finished, int index)
        {
            Debug.Assert(0 <= index && index <= 5, "予期せぬindex値を受け取りました: " + index);

            _model = model;
            var situation = model.Situation;

            // ボタンの全消去
            flowButtonPanel.Controls.Clear();

            // ボタンの追加
            var magicDatasList = _magicCommands[index, doer.MagicLevels[magicAttributes[index]]];
            for (int j = 0; j < magicDatasList.Count; j++)
            {
                var magicDatas = magicDatasList[j];
                for (int i = 0; i < magicDatas.Count; i++)
                {
                    var magicData = magicDatas[i];
                    var arc = new ActionArguments(situation, model);

                    var button = new Button {
                        Enabled = magicData.Action.CanBoot(arc, doer),
                        Text = magicData.Name + (i + 1),
                    };
                    button.Click += (sender_, e_) => {
                        Visible = false;
                        model.CancelCommandStack.Push(delegate {
                            Visible = true;
                            return true; // キャンセル処理の完了
                        });
                        magicData.Action.Boot(arc, doer, finished);
                    };
                    button.MouseEnter += delegate { PointingMagic = magicData; };
                    button.MouseLeave += delegate { PointingMagic = null; };
                    flowButtonPanel.Controls.Add(button);
                }
            }

            SetDetail(null);
            Text = doer.Name;
            Visible = true;
        }
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="model">ウインドウを仲介するクラス</param>
        public CommandWindow(WarPresentationModel model)
        {
            this.model = model;
            InitializeComponent();
            // 全てのボタンを作らないようにキャッシュを利用
            buttons = new Dictionary<IBattleCommand, Button>();

            Situation.ActiveUnitChanged += unit => {
                if (unit.Side.IsPlayer)
                {
                    Text = unit.Name;
                    TabText = unit.Name;
                    ResetCommandButtons();
                    Enabled = true;
                }
                else
                {
                    Enabled = false;
                }
            };
        }
        public void Show(WarPresentationModel model, WarUnit doer, Action finished)
        {
            // ボタンクリックイベントのためにフィールドを設定する
            _model = model;
            _doer = doer;
            _finished = finished;

            for (int i = 0; i < _buttonTable.Length; i++)
            {
                _buttonTable[i].Enabled = doer.MagicLevels[_magicAttributes[i]] > 0;
            }

            // キャンセル処理の登録
            model.CancelCommandStack.Push(delegate {
                Visible = false;
                return false; // 次のキャンセル処理へ続く
            });

            // ウィンドウの表示
            Visible = true;
        }
 public ActionArguments(Situation situation, WarPresentationModel model)
 {
     Situation = situation;
     Model = model;
 }
        public void Initialize()
        {
            // 戦争用データのロード
            var areaFileName = string.Format("BMap_NO{0}", _area.No);
            // TODO: 地形の読み込みは一回だけで良い
            var landformLoader = new LandformLoader(_gamePath);
            landformLoader.Load();
            var warMapLoader = new WarMapLoader(_gamePath);
            var warMap = warMapLoader.Load(areaFileName, 100, 200, 300,
                _conquerInfo.SelectToList(conquer => conquer.Item1));

            // キャラクタのロード
            var friends = new WarSide(true);
            var enemies = new WarSide(false);
            var units = new WarUnitCollection();

            //初期配置の時に必要になるので用意
            var friendUnits = new List<List<WarUnit>>();
            var enemyUnits = new List<WarUnit>();

            WarGlobal.UnitBuilder = new WarUnitBuilder(_gamePath, _units);

            // 味方軍
            foreach (var conquer in _conquerInfo)
            {
                friendUnits.Add(new List<WarUnit>());
                foreach (var unit in conquer.Item2)
                {
                    var warUnit = WarGlobal.UnitBuilder.Create(unit, friends, conquer.Item3);
                    units.AddUnit(warUnit);
                    friendUnits.Last().Add(warUnit);
                }
            }

            //敵軍
            foreach (var unit in _area.Units)
            {
                var warUnit = WarGlobal.UnitBuilder.Create(unit, enemies, _area);
                units.AddUnit(warUnit);
                enemyUnits.Add(warUnit);
            }

            // クラスの初期化
            var situation = new Situation(warMap, new[] { friends, enemies }, units);
            var model = new WarPresentationModel(situation);

            // ウィンドウの表示
            var mainWindow = new MainWindow();
            mainWindow.ShowMapWindow(situation, model);
            mainWindow.Show();

            //PhaseManager関連
            _phaseCreator.CreatePhase(model, friendUnits, enemyUnits, mainWindow);

            // 配置フェーズの開始
            situation.PhaseManager.StartPhase(situation, Phases.DeployUnitPhase);
        }
 public MapChipInfoWindow(WarPresentationModel model)
 {
     InitializeComponent();
     _model = model;
     model.CursorChipPointChangedEvent += (p => Invalidate(true));
 }
        protected virtual void CreateDeployUnitPhase(WarPresentationModel model, List<List<WarUnit>> friendUnits, List<WarUnit> enemyUnits, MainWindow mainWindow)
        {
            Phases.DeployUnitPhase.Start = situation_ =>
            {
                var deployWindow = new DeploymentWindow(friendUnits, model, situation_.Map, () =>
                {
                    //敵軍の配置
                    int i = 0;
                    foreach (var unit in enemyUnits)
                    {
                        situation_.Map.Deploy(unit, new Point2(i + 10, 10));
                        i++;
                    }

                    //いらなくなったので、早めにGCで消えてもらう
                    friendUnits = null;
                    enemyUnits = null;

                    situation_.PhaseManager.ChangePhase(situation_, Phases.BattlePhase);
                });

                deployWindow.Show();
            };
        }
        protected virtual void CreateTurnPhase(WarPresentationModel model, List<List<WarUnit>> friendUnits, List<WarUnit> enemyUnits, MainWindow mainWindow)
        {
            Phases.TurnPhase.Start = situation_ =>
            {
                situation_.TurnManager.Turn++;
                mainWindow.SetTurn(situation_.TurnManager.Turn);

                var unit = situation_.TurnManager.GetInitiativeUnit(situation_);
                if (unit != null)
                {
                    situation_.ActiveUnit = unit;
                    situation_.PhaseManager.StartPhase(situation_, Phases.InitiativePhase);
                }
                else
                {
                    situation_.PhaseManager.ExitPhase(situation_);
                }
            };

            Phases.TurnPhase.Exit = situation_ =>
            {
                if (situation_.TurnCount >= 20)
                    _result = BattleResult.TwentyTurn;

                if (_result != BattleResult.None)
                {
                    situation_.PhaseManager.ExitPhase(situation_);
                    return;
                }

                foreach (var unit in situation_.Units.Alive)
                {
                    if (unit.Status.HpAutoHeal > 0)
                    {
                        unit.HealHP(situation_, unit, unit.Status.HpAutoHeal);
                        model.SetHealAnimationOnMap(unit.Status.HpAutoHeal, unit.Location, null);
                    }
                    if (unit.Status.MpAutoHeal > 0)
                    {
                        unit.HealMP(situation_, unit, unit.Status.MpAutoHeal);
                        var anime = model.CreateStringAnimationOnMap(unit.Status.MpAutoHeal.ToString(), unit.Location, Color.Blue, 500);
                        model.ChipAnimations.Add(new ExtendTimeAnimationSprite(anime, 700, 0));
                    }
                }
                situation_.PhaseManager.StartPhase(situation_, Phases.TurnPhase);
            };
        }
        protected virtual void CreateInitiativePhase(WarPresentationModel model, List<List<WarUnit>> friendUnits, List<WarUnit> enemyUnits, MainWindow mainWindow)
        {
            Phases.InitiativePhase.Start = situation_ =>
            {
                model.MapWindow.Refresh();
                if (situation_.ActiveUnit.Side.IsPlayer)
                {
                    // ユニットのコマンド状態を初期化する
                    situation_.ActiveUnit.ResetCommandState();
                }
                else
                {
                    #region AI

                    var doer = situation_.ActiveUnit;
                    var ar = new ActionArguments(situation_, model);

                    var actionEnumrator = new AI.AI().GetActionWithCoroutine(situation_);

                    Action actionCoroutine = null;

                    // AIの行動選択と実行のコルーチン
                    actionCoroutine = () =>
                    {
                        // 非同期実行のためのAIの行動選択デリゲートの生成
                        Func<bool> selectNextAction = actionEnumrator.MoveNext;
                        var asyncResult = selectNextAction.BeginInvoke(null, null);

                        // TaskList にAIの行動選択完了後の、戦闘行動実行を予約する
                        // TaskList を使うことで、ウィンドウメッセージ処理のスレッドによる同期実行が行われる
                        TaskList<int>.Task task = null;
                        task = (taskArgs_, time_) =>
                        {
                            // 非同期実行が完了するまでは何もしない
                            if (!asyncResult.IsCompleted) return;

                            // 非同期実行が完了すれば、戻り値を取得する
                            if (selectNextAction.EndInvoke(asyncResult))
                            {
                                // AIが選択したActionが存在する
                                var battleAction = actionEnumrator.Current.Item1;
                                battleAction.BootAI(ar, doer, Delegates.NOP);
                                battleAction.Execute(ar, doer, actionEnumrator.Current.Item2, actionCoroutine);
                            }
                            else
                            {
                                // AIが選択したActionが存在しないので、ユニットの行動終了
                                situation_.PhaseManager.ExitPhase(situation_);
                            }
                            // タスクリストからこのデリゲートを削除する
                            Global.MainLoop.TickEvents.Remove(task);
                        };
                        Global.MainLoop.TickEvents.Add(Double.MinValue, task);
                    };

                    // AIの行動選択と実行のコルーチンを実行
                    actionCoroutine();

                    #endregion
                }
            };

            Phases.InitiativePhase.Exit = situation_ =>
            {
                var friends = situation_.Sides.Single(side => side.IsPlayer);
                var enemies = situation_.Sides.Single(side => !side.IsPlayer);

                _result = checkBattleEnd(situation_, friends, enemies);
                if (_result != BattleResult.None)
                {
                    situation_.PhaseManager.ExitPhase(situation_);
                    return;
                }

                model.CancelCommandStack.Clear();
                situation_.ActiveUnit.Side.UpdateForceAndBrave(situation_.Units.Alive);

                var unit = situation_.TurnManager.GetInitiativeUnit(situation_);
                if (unit != null)
                {
                    situation_.ActiveUnit = unit;
                    situation_.PhaseManager.StartPhase(situation_, Phases.InitiativePhase);
                }
                else
                {
                    situation_.PhaseManager.ExitPhase(situation_);
                }
            };
        }