protected virtual void OnBattleEnded()
        {
            if (LastState == PvPBattleState.Preparing)
            {
                OnBattleCancelled();
            }

            Hidden = false;

            if (Options.Broadcasts.World.EndNotify)
            {
                WorldBroadcast("{0} has ended!", Name);
            }

            if (Options.Broadcasts.Local.EndNotify)
            {
                LocalBroadcast("{0} has ended!", Name);
            }

            SendGlobalSound(Options.Sounds.BattleEnded);

            CloseDoors(true);

            ProcessRanks();

            ForEachTeam(t => t.OnBattleEnded());

            TransferStatistics();

            PvPBattlesUI.RefreshAll(this);
        }
        protected virtual void OnBattleOpened()
        {
            Hidden = false;

            if (Options.Broadcasts.World.OpenNotify)
            {
                WorldBroadcast("{0} is queueing volunteers!", Name);
            }

            if (Options.Broadcasts.Local.OpenNotify)
            {
                LocalBroadcast("{0} is queueing volunteers!", Name);
            }

            SendGlobalSound(Options.Sounds.BattleOpened);

            Reset();

            ForEachTeam(t => t.OnBattleOpened());

            if (LastState == PvPBattleState.Internal)
            {
                foreach (var p in AutoPvP.Profiles.Values.Where(p => p != null && !p.Deleted && !p.IsSubscribed(this)))
                {
                    p.Subscribe(this);
                }
            }

            PvPBattlesUI.RefreshAll(this);
        }
        protected virtual void OnStateChanged(PvPBattleState oldState)
        {
            _StateTransition = true;

            LastState = oldState;

            if (IsInternal)
            {
                Options.Timing.SetAllTimes(DateTime.MinValue);

                OnBattleInternalized();
            }
            else
            {
                if (LastState == PvPBattleState.Internal)
                {
                    InvalidateRegions();
                }

                Options.Timing.SetTime(State, DateTime.UtcNow);

                switch (State)
                {
                case PvPBattleState.Queueing:
                    OnBattleOpened();
                    break;

                case PvPBattleState.Preparing:
                    OnBattlePreparing();
                    break;

                case PvPBattleState.Running:
                    OnBattleStarted();
                    break;

                case PvPBattleState.Ended:
                    OnBattleEnded();
                    break;
                }
            }

            LastStateChange = DateTime.UtcNow;

            _StateTransition = false;

            AutoPvP.InvokeBattleStateChanged(this);

            PvPBattlesUI.RefreshAll(this);
        }
        protected virtual void OnBattleInternalized()
        {
            if (LastState == PvPBattleState.Running)
            {
                OnBattleCancelled();
            }

            Reset();

            foreach (var p in AutoPvP.Profiles.Values.Where(p => p != null && !p.Deleted && p.IsSubscribed(this)))
            {
                p.Unsubscribe(this);
            }

            PvPBattlesUI.RefreshAll(this);
        }
        protected virtual void OnBattlePreparing()
        {
            Hidden = false;

            if (Options.Broadcasts.World.StartNotify)
            {
                WorldBroadcast("{0} is preparing!", Name);
            }

            if (Options.Broadcasts.Local.StartNotify)
            {
                LocalBroadcast("{0} is preparing!", Name);
            }

            SendGlobalSound(Options.Sounds.BattlePreparing);

            ForEachTeam(t => t.OnBattlePreparing());

            PvPBattlesUI.RefreshAll(this);
        }
        protected virtual void OnBattleStarted()
        {
            Hidden = false;

            if (Options.Broadcasts.World.StartNotify)
            {
                WorldBroadcast("{0} has begun!", Name);
            }

            if (Options.Broadcasts.Local.StartNotify)
            {
                LocalBroadcast("{0} has begun!", Name);
            }

            SendGlobalSound(Options.Sounds.BattleStarted);

            OpendDoors(true);

            ForEachTeam(t => t.OnBattleStarted());

            PvPBattlesUI.RefreshAll(this);
        }