private IEnumerable <object> DoEndCampaignCameraTransition()
        {
            Character controlled = Character.Controlled;

            if (controlled != null)
            {
                controlled.AIController.Enabled = false;
            }

            GUI.DisableHUD = true;
            ISpatialEntity endObject  = Level.Loaded.LevelObjectManager.GetAllObjects().FirstOrDefault(obj => obj.Prefab.SpawnPos == LevelObjectPrefab.SpawnPosType.LevelEnd);
            var            transition = new CameraTransition(endObject ?? Submarine.MainSub, GameMain.GameScreen.Cam,
                                                             null, Alignment.Center,
                                                             fadeOut: true,
                                                             duration: 10,
                                                             startZoom: null, endZoom: 0.2f);

            while (transition.Running)
            {
                yield return(CoroutineStatus.Running);
            }
            GameMain.CampaignEndScreen.Select();
            GUI.DisableHUD = false;

            yield return(CoroutineStatus.Success);
        }
        private IEnumerable <object> DoLevelTransition()
        {
            SoundPlayer.OverrideMusicType     = CrewManager.GetCharacters().Any(c => !c.IsDead) ? "endround" : "crewdead";
            SoundPlayer.OverrideMusicDuration = 18.0f;

            Level prevLevel = Level.Loaded;

            bool success = CrewManager.GetCharacters().Any(c => !c.IsDead);

            crewDead = false;

            var continueButton = GameMain.GameSession.RoundSummary?.ContinueButton;

            if (continueButton != null)
            {
                continueButton.Visible = false;
            }

            Character.Controlled = null;

            yield return(new WaitForSeconds(0.1f));

            GameMain.Client.EndCinematic?.Stop();
            var endTransition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null,
                                                     Alignment.Center,
                                                     fadeOut: false,
                                                     duration: EndTransitionDuration);

            GameMain.Client.EndCinematic = endTransition;

            Location portraitLocation = Map?.SelectedLocation ?? Map?.CurrentLocation ?? Level.Loaded?.StartLocation;

            if (portraitLocation != null)
            {
                overlaySprite = portraitLocation.Type.GetPortrait(portraitLocation.PortraitId);
            }
            float fadeOutDuration = endTransition.Duration;
            float t = 0.0f;

            while (t < fadeOutDuration || endTransition.Running)
            {
                t           += CoroutineManager.UnscaledDeltaTime;
                overlayColor = Color.Lerp(Color.Transparent, Color.White, t / fadeOutDuration);
                yield return(CoroutineStatus.Running);
            }
            overlayColor = Color.White;
            yield return(CoroutineStatus.Running);

            //--------------------------------------

            //wait for the new level to be loaded
            DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, seconds: 30);

            while (Level.Loaded == prevLevel || Level.Loaded == null)
            {
                if (DateTime.Now > timeOut || Screen.Selected != GameMain.GameScreen)
                {
                    break;
                }
                yield return(CoroutineStatus.Running);
            }

            endTransition.Stop();
            overlayColor = Color.Transparent;

            if (DateTime.Now > timeOut)
            {
                GameMain.NetLobbyScreen.Select();
            }
            if (!(Screen.Selected is RoundSummaryScreen))
            {
                if (continueButton != null)
                {
                    continueButton.Visible = true;
                }
            }

            yield return(CoroutineStatus.Success);
        }
        private IEnumerable <object> DoInitialCameraTransition()
        {
            while (GameMain.Instance.LoadingScreenOpen)
            {
                yield return(CoroutineStatus.Running);
            }

            if (GameMain.Client.LateCampaignJoin)
            {
                GameMain.Client.LateCampaignJoin = false;
                yield return(CoroutineStatus.Success);
            }

            Character prevControlled = Character.Controlled;

            if (prevControlled?.AIController != null)
            {
                prevControlled.AIController.Enabled = false;
            }
            GUI.DisableHUD = true;
            if (IsFirstRound)
            {
                Character.Controlled = null;

                if (prevControlled != null)
                {
                    prevControlled.ClearInputs();
                }

                overlayColor     = Color.LightGray;
                overlaySprite    = Map.CurrentLocation.Type.GetPortrait(Map.CurrentLocation.PortraitId);
                overlayTextColor = Color.Transparent;
                overlayText      = TextManager.GetWithVariables("campaignstart",
                                                                new string[] { "xxxx", "yyyy" },
                                                                new string[] { Map.CurrentLocation.Name, TextManager.Get("submarineclass." + Submarine.MainSub.Info.SubmarineClass) });
                float fadeInDuration = 1.0f;
                float textDuration   = 10.0f;
                float timer          = 0.0f;
                while (timer < textDuration)
                {
                    // Try to grab the controlled here to prevent inputs, assigned late on multiplayer
                    if (Character.Controlled != null)
                    {
                        prevControlled       = Character.Controlled;
                        Character.Controlled = null;
                        prevControlled.ClearInputs();
                    }
                    GameMain.GameScreen.Cam.Freeze = true;
                    overlayTextColor = Color.Lerp(Color.Transparent, Color.White, (timer - 1.0f) / fadeInDuration);
                    timer            = Math.Min(timer + CoroutineManager.DeltaTime, textDuration);
                    yield return(CoroutineStatus.Running);
                }
                var transition = new CameraTransition(prevControlled, GameMain.GameScreen.Cam,
                                                      null, null,
                                                      fadeOut: false,
                                                      duration: 5,
                                                      startZoom: 1.5f, endZoom: 1.0f)
                {
                    AllowInterrupt             = true,
                    RemoveControlFromCharacter = false
                };
                fadeInDuration   = 1.0f;
                timer            = 0.0f;
                overlayTextColor = Color.Transparent;
                overlayText      = "";
                while (timer < fadeInDuration)
                {
                    overlayColor = Color.Lerp(Color.LightGray, Color.Transparent, timer / fadeInDuration);
                    timer       += CoroutineManager.DeltaTime;
                    yield return(CoroutineStatus.Running);
                }
                overlayColor = Color.Transparent;
                while (transition.Running)
                {
                    yield return(CoroutineStatus.Running);
                }

                if (prevControlled != null)
                {
                    Character.Controlled = prevControlled;
                }
            }
            else
            {
                var transition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam,
                                                      null, null,
                                                      fadeOut: false,
                                                      duration: 5,
                                                      startZoom: 0.5f, endZoom: 1.0f)
                {
                    AllowInterrupt             = true,
                    RemoveControlFromCharacter = true
                };
                while (transition.Running)
                {
                    yield return(CoroutineStatus.Running);
                }
            }

            if (prevControlled != null)
            {
                prevControlled.SelectedConstruction = null;
                if (prevControlled.AIController != null)
                {
                    prevControlled.AIController.Enabled = true;
                }
            }
            GUI.DisableHUD = false;
            yield return(CoroutineStatus.Success);
        }
        protected override IEnumerable <object> DoLevelTransition(TransitionType transitionType, LevelData newLevel, Submarine leavingSub, bool mirror, List <TraitorMissionResult> traitorResults = null)
        {
            NextLevel = newLevel;
            bool success = CrewManager.GetCharacters().Any(c => !c.IsDead);

            SoundPlayer.OverrideMusicType     = success ? "endround" : "crewdead";
            SoundPlayer.OverrideMusicDuration = 18.0f;
            crewDead = false;

            GameMain.GameSession.EndRound("", traitorResults, transitionType);
            var          continueButton = GameMain.GameSession.RoundSummary?.ContinueButton;
            RoundSummary roundSummary   = null;

            if (GUIMessageBox.VisibleBox?.UserData is RoundSummary)
            {
                roundSummary = GUIMessageBox.VisibleBox?.UserData as RoundSummary;
            }
            if (continueButton != null)
            {
                continueButton.Visible = false;
            }

            lastControlledCharacter = Character.Controlled;
            Character.Controlled    = null;

            switch (transitionType)
            {
            case TransitionType.None:
                throw new InvalidOperationException("Level transition failed (no transitions available).");

            case TransitionType.ReturnToPreviousLocation:
                //deselect destination on map
                map.SelectLocation(-1);
                break;

            case TransitionType.ProgressToNextLocation:
                Map.MoveToNextLocation();
                break;
            }

            Map.ProgressWorld(transitionType, (float)(Timing.TotalTime - GameMain.GameSession.RoundStartTime));

            var endTransition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null,
                                                     transitionType == TransitionType.LeaveLocation ? Alignment.BottomCenter : Alignment.Center,
                                                     fadeOut: false,
                                                     duration: EndTransitionDuration);

            GUI.ClearMessages();

            Location portraitLocation = Map.SelectedLocation ?? Map.CurrentLocation;

            overlaySprite = portraitLocation.Type.GetPortrait(portraitLocation.PortraitId);
            float fadeOutDuration = endTransition.Duration;
            float t = 0.0f;

            while (t < fadeOutDuration || endTransition.Running)
            {
                t           += CoroutineManager.UnscaledDeltaTime;
                overlayColor = Color.Lerp(Color.Transparent, Color.White, t / fadeOutDuration);
                yield return(CoroutineStatus.Running);
            }
            overlayColor = Color.White;
            yield return(CoroutineStatus.Running);

            //--------------------------------------

            bool save = false;

            if (success)
            {
                if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub))
                {
                    Submarine.MainSub = leavingSub;
                    GameMain.GameSession.Submarine = leavingSub;
                    var subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub);
                    foreach (Submarine sub in subsToLeaveBehind)
                    {
                        MapEntity.mapEntityList.RemoveAll(e => e.Submarine == sub && e is LinkedSubmarine);
                        LinkedSubmarine.CreateDummy(leavingSub, sub);
                    }
                }

                GameMain.GameSession.SubmarineInfo = new SubmarineInfo(GameMain.GameSession.Submarine);

                if (PendingSubmarineSwitch != null)
                {
                    SubmarineInfo previousSub = GameMain.GameSession.SubmarineInfo;
                    GameMain.GameSession.SubmarineInfo = PendingSubmarineSwitch;
                    PendingSubmarineSwitch             = null;

                    for (int i = 0; i < GameMain.GameSession.OwnedSubmarines.Count; i++)
                    {
                        if (GameMain.GameSession.OwnedSubmarines[i].Name == previousSub.Name)
                        {
                            GameMain.GameSession.OwnedSubmarines[i] = previousSub;
                            break;
                        }
                    }
                }

                SaveUtil.SaveGame(GameMain.GameSession.SavePath);
            }
            else
            {
                PendingSubmarineSwitch = null;
                EnableRoundSummaryGameOverState();
            }

            //--------------------------------------

            SelectSummaryScreen(roundSummary, newLevel, mirror, () =>
            {
                GameMain.GameScreen.Select();
                if (continueButton != null)
                {
                    continueButton.Visible = true;
                }

                GUI.DisableHUD = false;
                GUI.ClearCursorWait();
                overlayColor = Color.Transparent;
            });

            yield return(CoroutineStatus.Success);
        }
        private IEnumerable <object> DoInitialCameraTransition()
        {
            while (GameMain.Instance.LoadingScreenOpen)
            {
                yield return(CoroutineStatus.Running);
            }
            Character prevControlled = Character.Controlled;

            if (prevControlled?.AIController != null)
            {
                prevControlled.AIController.Enabled = false;
            }
            Character.Controlled = null;
            if (prevControlled != null)
            {
                prevControlled.ClearInputs();
            }

            GUI.DisableHUD = true;
            while (GameMain.Instance.LoadingScreenOpen)
            {
                yield return(CoroutineStatus.Running);
            }

            if (IsFirstRound || showCampaignResetText)
            {
                overlayColor     = Color.LightGray;
                overlaySprite    = Map.CurrentLocation.Type.GetPortrait(Map.CurrentLocation.PortraitId);
                overlayTextColor = Color.Transparent;
                overlayText      = TextManager.GetWithVariables(showCampaignResetText ? "campaignend4" : "campaignstart",
                                                                new string[] { "xxxx", "yyyy" },
                                                                new string[] { Map.CurrentLocation.Name, TextManager.Get("submarineclass." + Submarine.MainSub.Info.SubmarineClass) });
                string pressAnyKeyText = TextManager.Get("pressanykey");
                float  fadeInDuration  = 2.0f;
                float  textDuration    = 10.0f;
                float  timer           = 0.0f;
                while (true)
                {
                    if (timer > fadeInDuration)
                    {
                        overlayTextBottom = pressAnyKeyText;
                        if (PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.PrimaryMouseButtonClicked())
                        {
                            break;
                        }
                    }
                    overlayTextColor = Color.Lerp(Color.Transparent, Color.White, (timer - 1.0f) / fadeInDuration);
                    timer            = Math.Min(timer + CoroutineManager.DeltaTime, textDuration);
                    yield return(CoroutineStatus.Running);
                }
                var transition = new CameraTransition(prevControlled, GameMain.GameScreen.Cam,
                                                      null, null,
                                                      fadeOut: false,
                                                      duration: 5,
                                                      startZoom: 1.5f, endZoom: 1.0f)
                {
                    AllowInterrupt             = true,
                    RemoveControlFromCharacter = false
                };
                fadeInDuration   = 1.0f;
                timer            = 0.0f;
                overlayTextColor = Color.Transparent;
                overlayText      = "";
                while (timer < fadeInDuration)
                {
                    overlayColor = Color.Lerp(Color.LightGray, Color.Transparent, timer / fadeInDuration);
                    timer       += CoroutineManager.DeltaTime;
                    yield return(CoroutineStatus.Running);
                }
                overlayColor = Color.Transparent;
                while (transition.Running)
                {
                    yield return(CoroutineStatus.Running);
                }
                showCampaignResetText = false;
            }
            else
            {
                ISpatialEntity transitionTarget;
                if (prevControlled != null)
                {
                    transitionTarget = prevControlled;
                }
                else
                {
                    transitionTarget = Submarine.MainSub;
                }

                var transition = new CameraTransition(transitionTarget, GameMain.GameScreen.Cam,
                                                      null, null,
                                                      fadeOut: false,
                                                      duration: 5,
                                                      startZoom: 0.5f, endZoom: 1.0f)
                {
                    AllowInterrupt             = true,
                    RemoveControlFromCharacter = false
                };
                while (transition.Running)
                {
                    yield return(CoroutineStatus.Running);
                }
            }

            if (prevControlled != null)
            {
                prevControlled.SelectedConstruction = null;
                if (prevControlled.AIController != null)
                {
                    prevControlled.AIController.Enabled = true;
                }
            }

            if (prevControlled != null)
            {
                Character.Controlled = prevControlled;
            }
            GUI.DisableHUD = false;
            yield return(CoroutineStatus.Success);
        }
        private IEnumerable <object> DoInitialCameraTransition()
        {
            while (GameMain.Instance.LoadingScreenOpen)
            {
                yield return(CoroutineStatus.Running);
            }
            Character prevControlled = Character.Controlled;

            if (prevControlled?.AIController != null)
            {
                prevControlled.AIController.Enabled = false;
            }
            Character.Controlled = null;
            prevControlled?.ClearInputs();

            GUI.DisableHUD = true;
            while (GameMain.Instance.LoadingScreenOpen)
            {
                yield return(CoroutineStatus.Running);
            }

            if (IsFirstRound || showCampaignResetText)
            {
                overlayColor     = Color.LightGray;
                overlaySprite    = Map.CurrentLocation.Type.GetPortrait(Map.CurrentLocation.PortraitId);
                overlayTextColor = Color.Transparent;
                overlayText      = TextManager.GetWithVariables(showCampaignResetText ? "campaignend4" : "campaignstart",
                                                                new string[] { "xxxx", "yyyy" },
                                                                new string[] { Map.CurrentLocation.Name, TextManager.Get("submarineclass." + Submarine.MainSub.Info.SubmarineClass) });
                string pressAnyKeyText = TextManager.Get("pressanykey");
                float  fadeInDuration  = 2.0f;
                float  textDuration    = 10.0f;
                float  timer           = 0.0f;
                while (true)
                {
                    if (timer > fadeInDuration)
                    {
                        overlayTextBottom = pressAnyKeyText;
                        if (PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.PrimaryMouseButtonClicked())
                        {
                            break;
                        }
                    }
                    if (GameMain.GameSession == null)
                    {
                        GUI.DisableHUD = false;
                        yield return(CoroutineStatus.Success);
                    }
                    overlayTextColor = Color.Lerp(Color.Transparent, Color.White, (timer - 1.0f) / fadeInDuration);
                    timer            = Math.Min(timer + CoroutineManager.UnscaledDeltaTime, textDuration);
                    yield return(CoroutineStatus.Running);
                }
                var outpost = GameMain.GameSession.Level.StartOutpost;
                var borders = outpost.GetDockedBorders();
                borders.Location += outpost.WorldPosition.ToPoint();
                GameMain.GameScreen.Cam.Position = new Vector2(borders.X + borders.Width / 2, borders.Y - borders.Height / 2);
                float startZoom = 0.8f /
                                  ((float)Math.Max(borders.Width, borders.Height) / (float)GameMain.GameScreen.Cam.Resolution.X);
                GameMain.GameScreen.Cam.MinZoom = Math.Min(startZoom, GameMain.GameScreen.Cam.MinZoom);
                var transition = new CameraTransition(prevControlled, GameMain.GameScreen.Cam,
                                                      null, null,
                                                      fadeOut: false,
                                                      losFadeIn: true,
                                                      waitDuration: 1,
                                                      panDuration: 5,
                                                      startZoom: startZoom, endZoom: 1.0f)
                {
                    AllowInterrupt             = true,
                    RemoveControlFromCharacter = false
                };
                fadeInDuration   = 1.0f;
                timer            = 0.0f;
                overlayTextColor = Color.Transparent;
                overlayText      = "";
                while (timer < fadeInDuration)
                {
                    overlayColor = Color.Lerp(Color.LightGray, Color.Transparent, timer / fadeInDuration);
                    timer       += CoroutineManager.UnscaledDeltaTime;
                    yield return(CoroutineStatus.Running);
                }
                overlayColor = Color.Transparent;
                while (transition.Running)
                {
                    yield return(CoroutineStatus.Running);
                }
                showCampaignResetText = false;
            }
            else
            {
                ISpatialEntity transitionTarget;
                transitionTarget = (ISpatialEntity)prevControlled ?? Submarine.MainSub;

                var transition = new CameraTransition(transitionTarget, GameMain.GameScreen.Cam,
                                                      null, null,
                                                      fadeOut: false,
                                                      losFadeIn: prevControlled != null,
                                                      panDuration: 5,
                                                      startZoom: 0.5f, endZoom: 1.0f)
                {
                    AllowInterrupt             = true,
                    RemoveControlFromCharacter = false
                };
                while (transition.Running)
                {
                    yield return(CoroutineStatus.Running);
                }
            }

            if (prevControlled != null)
            {
                prevControlled.SelectedConstruction = null;
                if (prevControlled.AIController != null)
                {
                    prevControlled.AIController.Enabled = true;
                }
            }

            if (prevControlled != null)
            {
                Character.Controlled = prevControlled;
            }
            GUI.DisableHUD = false;
            yield return(CoroutineStatus.Success);
        }