Esempio n. 1
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            Timing.TotalTime    = gameTime.TotalGameTime.TotalSeconds;
            Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds;
            int updateIterations = (int)Math.Floor(Timing.Accumulator / Timing.Step);

            if (Timing.Accumulator > Timing.Step * 6.0)
            {
                //if the game's running too slowly then we have no choice
                //but to skip a bunch of steps
                //otherwise it snowballs and becomes unplayable
                Timing.Accumulator = Timing.Step;
            }
            PlayerInput.UpdateVariable();

            bool paused = true;

            if (SoundManager != null)
            {
                if (WindowActive || !Config.MuteOnFocusLost)
                {
                    SoundManager.ListenerGain = 1.0f;
                }
                else
                {
                    SoundManager.ListenerGain = 0.0f;
                }
            }

            while (Timing.Accumulator >= Timing.Step)
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();

                fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly;
                TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16);
                fixedTime.ElapsedGameTime = addTime;
                fixedTime.TotalGameTime.Add(addTime);
                base.Update(fixedTime);

                PlayerInput.Update(Timing.Step);

                if (loadingScreenOpen)
                {
                    //reset accumulator if loading
                    // -> less choppy loading screens because the screen is rendered after each update
                    // -> no pause caused by leftover time in the accumulator when starting a new shift
                    GameMain.ResetFrameTime();

                    if (TitleScreen.LoadState >= 100.0f &&
                        (!waitForKeyHit || PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.LeftButtonClicked()))
                    {
                        loadingScreenOpen = false;
                    }

                    if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine))
                    {
                        string errMsg = "Loading was interrupted due to an error";
                        if (loadingCoroutine.Exception != null)
                        {
                            errMsg += ": " + loadingCoroutine.Exception.Message + "\n" + loadingCoroutine.Exception.StackTrace;
                        }
                        throw new Exception(errMsg);
                    }
                }
                else if (hasLoaded)
                {
                    SoundPlayer.Update((float)Timing.Step);

                    if (PlayerInput.KeyHit(Keys.Escape))
                    {
                        // Check if a text input is selected.
                        if (GUI.KeyboardDispatcher.Subscriber != null)
                        {
                            if (GUI.KeyboardDispatcher.Subscriber is GUITextBox textBox)
                            {
                                textBox.Deselect();
                            }
                            GUI.KeyboardDispatcher.Subscriber = null;
                        }
                        //if a verification prompt (are you sure you want to x) is open, close it
                        else if (GUIMessageBox.VisibleBox as GUIMessageBox != null &&
                                 GUIMessageBox.VisibleBox.UserData as string == "verificationprompt")
                        {
                            ((GUIMessageBox)GUIMessageBox.VisibleBox).Close();
                        }
                        else if (Tutorial.Initialized && Tutorial.ContentRunning)
                        {
                            (GameMain.GameSession.GameMode as TutorialMode).Tutorial.CloseActiveContentGUI();
                        }
                        else if ((Character.Controlled?.SelectedConstruction == null || !Character.Controlled.SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null)) &&
                                 Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null)
                        {
                            // Otherwise toggle pausing, unless another window/interface is open.
                            GUI.TogglePauseMenu();
                        }
                    }

                    GUI.ClearUpdateList();
                    paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen || Tutorial.ContentRunning) &&
                             (NetworkMember == null || !NetworkMember.GameStarted);

                    Screen.Selected.AddToGUIUpdateList();

                    if (Client != null)
                    {
                        Client.AddToGUIUpdateList();
                    }

                    DebugConsole.AddToGUIUpdateList();

                    DebugConsole.Update(this, (float)Timing.Step);
                    paused = paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted));

                    if (!paused)
                    {
                        Screen.Selected.Update(Timing.Step);
                    }
                    else if (Tutorial.Initialized && Tutorial.ContentRunning)
                    {
                        (GameSession.GameMode as TutorialMode).Update((float)Timing.Step);
                    }

                    if (NetworkMember != null)
                    {
                        NetworkMember.Update((float)Timing.Step);
                    }

                    GUI.Update((float)Timing.Step);
                }

                CoroutineManager.Update((float)Timing.Step, paused ? 0.0f : (float)Timing.Step);

                SteamManager.Update((float)Timing.Step);

                Timing.Accumulator -= Timing.Step;

                sw.Stop();
                PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks);
                PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks / (float)TimeSpan.TicksPerMillisecond);
                PerformanceCounter.UpdateIterationsGraph.Update(updateIterations);
            }

            if (!paused)
            {
                Timing.Alpha = Timing.Accumulator / Timing.Step;
            }
        }
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            Timing.TotalTime    = gameTime.TotalGameTime.TotalSeconds;
            Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds;
            PlayerInput.UpdateVariable();

            bool paused = true;

            while (Timing.Accumulator >= Timing.Step)
            {
                fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly;
                TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16);
                fixedTime.ElapsedGameTime = addTime;
                fixedTime.TotalGameTime.Add(addTime);
                base.Update(fixedTime);

                if (WindowActive)
                {
                    PlayerInput.Update(Timing.Step);
                }

                if (loadingScreenOpen)
                {
                    //reset accumulator if loading
                    // -> less choppy loading screens because the screen is rendered after each update
                    // -> no pause caused by leftover time in the accumulator when starting a new shift
                    Timing.Accumulator = 0.0f;

                    if (TitleScreen.LoadState >= 100.0f &&
                        (!waitForKeyHit || PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.LeftButtonClicked()))
                    {
                        loadingScreenOpen = false;
                    }

                    if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine))
                    {
                        throw new Exception("Loading was interrupted due to an error");
                    }
                }
                else if (hasLoaded)
                {
                    SoundPlayer.Update((float)Timing.Step);

                    if (PlayerInput.KeyHit(Keys.Escape))
                    {
                        GUI.TogglePauseMenu();
                    }

                    GUIComponent.ClearUpdateList();
                    paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen) &&
                             (NetworkMember == null || !NetworkMember.GameStarted);

                    if (!paused)
                    {
                        Screen.Selected.AddToGUIUpdateList();
                    }

                    if (NetworkMember != null)
                    {
                        NetworkMember.AddToGUIUpdateList();
                    }

                    GUI.AddToGUIUpdateList();
                    DebugConsole.AddToGUIUpdateList();
                    GUIComponent.UpdateMouseOn();

                    DebugConsole.Update(this, (float)Timing.Step);
                    paused = paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted));

                    if (!paused)
                    {
                        Screen.Selected.Update(Timing.Step);
                    }

                    if (NetworkMember != null)
                    {
                        NetworkMember.Update((float)Timing.Step);
                    }

                    GUI.Update((float)Timing.Step);
                }

                CoroutineManager.Update((float)Timing.Step, paused ? 0.0f : (float)Timing.Step);

                Timing.Accumulator -= Timing.Step;
            }

            if (!paused)
            {
                Timing.Alpha = Timing.Accumulator / Timing.Step;
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            Timing.TotalTime    = gameTime.TotalGameTime.TotalSeconds;
            Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds;
            int updateIterations = (int)Math.Floor(Timing.Accumulator / Timing.Step);

            if (Timing.Accumulator > Timing.Step * 6.0)
            {
                //if the game's running too slowly then we have no choice
                //but to skip a bunch of steps
                //otherwise it snowballs and becomes unplayable
                Timing.Accumulator = Timing.Step;
            }
            PlayerInput.UpdateVariable();

            bool paused = true;

            while (Timing.Accumulator >= Timing.Step)
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();

                fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly;
                TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16);
                fixedTime.ElapsedGameTime = addTime;
                fixedTime.TotalGameTime.Add(addTime);
                base.Update(fixedTime);

                PlayerInput.Update(Timing.Step);

                if (loadingScreenOpen)
                {
                    //reset accumulator if loading
                    // -> less choppy loading screens because the screen is rendered after each update
                    // -> no pause caused by leftover time in the accumulator when starting a new shift
                    Timing.Accumulator = 0.0f;

                    if (TitleScreen.LoadState >= 100.0f &&
                        (!waitForKeyHit || PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.LeftButtonClicked()))
                    {
                        loadingScreenOpen = false;
                    }

                    if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine))
                    {
                        string errMsg = "Loading was interrupted due to an error";
                        if (loadingCoroutine.Exception != null)
                        {
                            errMsg += ": " + loadingCoroutine.Exception.Message + "\n" + loadingCoroutine.Exception.StackTrace;
                        }
                        throw new Exception(errMsg);
                    }
                }
                else if (hasLoaded)
                {
                    SoundPlayer.Update((float)Timing.Step);

                    if (PlayerInput.KeyHit(Keys.Escape))
                    {
                        GUI.TogglePauseMenu();
                    }

                    GUI.ClearUpdateList();
                    paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen) &&
                             (NetworkMember == null || !NetworkMember.GameStarted);

                    Screen.Selected.AddToGUIUpdateList();

                    if (NetworkMember != null)
                    {
                        NetworkMember.AddToGUIUpdateList();
                    }

                    DebugConsole.AddToGUIUpdateList();

                    DebugConsole.Update(this, (float)Timing.Step);
                    paused = paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted));

                    if (!paused)
                    {
                        Screen.Selected.Update(Timing.Step);
                    }

                    if (NetworkMember != null)
                    {
                        NetworkMember.Update((float)Timing.Step);
                    }

                    GUI.Update((float)Timing.Step);
                }

                CoroutineManager.Update((float)Timing.Step, paused ? 0.0f : (float)Timing.Step);

                SteamManager.Update((float)Timing.Step);

                Timing.Accumulator -= Timing.Step;

                sw.Stop();
                PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks);
                PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks / (float)TimeSpan.TicksPerMillisecond);
                PerformanceCounter.UpdateIterationsGraph.Update(updateIterations);
            }

            if (!paused)
            {
                Timing.Alpha = Timing.Accumulator / Timing.Step;
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds;
            int updateIterations = (int)Math.Floor(Timing.Accumulator / Timing.Step);

            if (Timing.Accumulator > Timing.Step * 6.0)
            {
                //if the game's running too slowly then we have no choice
                //but to skip a bunch of steps
                //otherwise it snowballs and becomes unplayable
                Timing.Accumulator = Timing.Step;
            }

            CrossThread.ProcessTasks();

            PlayerInput.UpdateVariable();

            if (SoundManager != null)
            {
                if (WindowActive || !Config.MuteOnFocusLost)
                {
                    SoundManager.ListenerGain = SoundManager.CompressionDynamicRangeGain;
                }
                else
                {
                    SoundManager.ListenerGain = 0.0f;
                }
            }

            while (Timing.Accumulator >= Timing.Step)
            {
                Timing.TotalTime += Timing.Step;

                Stopwatch sw = new Stopwatch();
                sw.Start();

                fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly;
                TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16);
                fixedTime.ElapsedGameTime = addTime;
                fixedTime.TotalGameTime.Add(addTime);
                base.Update(fixedTime);

                PlayerInput.Update(Timing.Step);


                if (loadingScreenOpen)
                {
                    //reset accumulator if loading
                    // -> less choppy loading screens because the screen is rendered after each update
                    // -> no pause caused by leftover time in the accumulator when starting a new shift
                    ResetFrameTime();

                    if (!TitleScreen.PlayingSplashScreen)
                    {
                        SoundPlayer.Update((float)Timing.Step);
                    }

                    if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen &&
                        (!waitForKeyHit || ((PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.PrimaryMouseButtonClicked()) && WindowActive)))
                    {
                        loadingScreenOpen = false;
                    }

#if DEBUG
                    if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen && (Config.AutomaticQuickStartEnabled || Config.AutomaticCampaignLoadEnabled) && FirstLoad && !PlayerInput.KeyDown(Keys.LeftShift))
                    {
                        loadingScreenOpen = false;
                        FirstLoad         = false;

                        if (Config.AutomaticQuickStartEnabled)
                        {
                            MainMenuScreen.QuickStart();
                        }
                        else if (Config.AutomaticCampaignLoadEnabled)
                        {
                            IEnumerable <string> saveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Singleplayer);

                            if (saveFiles.Count() > 0)
                            {
                                saveFiles = saveFiles.OrderBy(file => File.GetLastWriteTime(file));
                                try
                                {
                                    SaveUtil.LoadGame(saveFiles.Last());
                                }
                                catch (Exception e)
                                {
                                    DebugConsole.ThrowError("Loading save \"" + saveFiles.Last() + "\" failed", e);
                                    return;
                                }
                            }
                        }
                    }
#endif

                    if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine))
                    {
                        throw new LoadingException(loadingCoroutine.Exception);
                    }
                }
                else if (hasLoaded)
                {
                    if (ConnectLobby != 0)
                    {
                        if (Client != null)
                        {
                            Client.Disconnect();
                            Client = null;

                            GameMain.MainMenuScreen.Select();
                        }
                        Steam.SteamManager.JoinLobby(ConnectLobby, true);

                        ConnectLobby    = 0;
                        ConnectEndpoint = null;
                        ConnectName     = null;
                    }
                    else if (!string.IsNullOrWhiteSpace(ConnectEndpoint))
                    {
                        if (Client != null)
                        {
                            Client.Disconnect();
                            Client = null;

                            GameMain.MainMenuScreen.Select();
                        }
                        UInt64 serverSteamId = SteamManager.SteamIDStringToUInt64(ConnectEndpoint);
                        Client = new GameClient(Config.PlayerName,
                                                serverSteamId != 0 ? null : ConnectEndpoint,
                                                serverSteamId,
                                                string.IsNullOrWhiteSpace(ConnectName) ? ConnectEndpoint : ConnectName);
                        ConnectLobby    = 0;
                        ConnectEndpoint = null;
                        ConnectName     = null;
                    }

                    SoundPlayer.Update((float)Timing.Step);

                    if (PlayerInput.KeyHit(Keys.Escape) && WindowActive)
                    {
                        // Check if a text input is selected.
                        if (GUI.KeyboardDispatcher.Subscriber != null)
                        {
                            if (GUI.KeyboardDispatcher.Subscriber is GUITextBox textBox)
                            {
                                textBox.Deselect();
                            }
                            GUI.KeyboardDispatcher.Subscriber = null;
                        }
                        //if a verification prompt (are you sure you want to x) is open, close it
                        else if (GUIMessageBox.VisibleBox as GUIMessageBox != null &&
                                 GUIMessageBox.VisibleBox.UserData as string == "verificationprompt")
                        {
                            ((GUIMessageBox)GUIMessageBox.VisibleBox).Close();
                        }
                        else if (GUIMessageBox.VisibleBox?.UserData is RoundSummary roundSummary &&
                                 roundSummary.ContinueButton != null &&
                                 roundSummary.ContinueButton.Visible)
                        {
                            GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox);
                        }
                        else if (Tutorial.Initialized && Tutorial.ContentRunning)
                        {
                            (GameSession.GameMode as TutorialMode).Tutorial.CloseActiveContentGUI();
                        }
                        else if (GameSession.IsTabMenuOpen)
                        {
                            gameSession.ToggleTabMenu();
                        }
                        else if (GUI.PauseMenuOpen)
                        {
                            GUI.TogglePauseMenu();
                        }
                        //open the pause menu if not controlling a character OR if the character has no UIs active that can be closed with ESC
                        else if ((Character.Controlled == null || !itemHudActive())
                                 //TODO: do we need to check Inventory.SelectedSlot?
                                 && Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null &&
                                 !CrewManager.IsCommandInterfaceOpen &&
                                 !(Screen.Selected is SubEditorScreen editor && !editor.WiringMode && Character.Controlled?.SelectedConstruction != null))
                        {
                            // Otherwise toggle pausing, unless another window/interface is open.
                            GUI.TogglePauseMenu();
                        }
Esempio n. 5
0
        public override void Draw(SpriteBatch spriteBatch)
        {
            if (overlayColor.A > 0)
            {
                if (overlaySprite != null)
                {
                    GUI.DrawRectangle(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * (overlayColor.A / 255.0f), isFilled: true);
                    float scale = Math.Max(GameMain.GraphicsWidth / overlaySprite.size.X, GameMain.GraphicsHeight / overlaySprite.size.Y);
                    overlaySprite.Draw(spriteBatch, new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2, overlayColor, overlaySprite.size / 2, scale: scale);
                }
                else
                {
                    GUI.DrawRectangle(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), overlayColor, isFilled: true);
                }
                if (!string.IsNullOrEmpty(overlayText) && overlayTextColor.A > 0)
                {
                    var     backgroundSprite = GUI.Style.GetComponentStyle("CommandBackground").GetDefaultSprite();
                    Vector2 centerPos        = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2;
                    backgroundSprite.Draw(spriteBatch,
                                          centerPos,
                                          Color.White * (overlayTextColor.A / 255.0f),
                                          origin: backgroundSprite.size / 2,
                                          rotate: 0.0f,
                                          scale: new Vector2(1.5f, 0.7f) * (GameMain.GraphicsWidth / 3 / backgroundSprite.size.X));

                    string  wrappedText = ToolBox.WrapText(overlayText, GameMain.GraphicsWidth / 3, GUI.Font);
                    Vector2 textSize    = GUI.Font.MeasureString(wrappedText);
                    Vector2 textPos     = centerPos - textSize / 2;
                    GUI.DrawString(spriteBatch, textPos + Vector2.One, wrappedText, Color.Black * (overlayTextColor.A / 255.0f));
                    GUI.DrawString(spriteBatch, textPos, wrappedText, overlayTextColor);

                    if (!string.IsNullOrEmpty(overlayTextBottom))
                    {
                        Vector2 bottomTextPos = centerPos + new Vector2(0.0f, textSize.Y + 30 * GUI.Scale) - GUI.Font.MeasureString(overlayTextBottom) / 2;
                        GUI.DrawString(spriteBatch, bottomTextPos + Vector2.One, overlayTextBottom, Color.Black * (overlayTextColor.A / 255.0f));
                        GUI.DrawString(spriteBatch, bottomTextPos, overlayTextBottom, overlayTextColor);
                    }
                }
            }

            if (GUI.DisableHUD || GUI.DisableUpperHUD || ForceMapUI || CoroutineManager.IsCoroutineRunning("LevelTransition"))
            {
                endRoundButton.Visible = false;
                if (ReadyCheckButton != null)
                {
                    ReadyCheckButton.Visible = false;
                }
                return;
            }
            if (Submarine.MainSub == null)
            {
                return;
            }

            endRoundButton.Visible = false;
            var    availableTransition = GetAvailableTransition(out _, out Submarine leavingSub);
            string buttonText          = "";

            switch (availableTransition)
            {
            case TransitionType.ProgressToNextLocation:
            case TransitionType.ProgressToNextEmptyLocation:
                if (Level.Loaded.EndOutpost == null || !Level.Loaded.EndOutpost.DockedTo.Contains(leavingSub))
                {
                    buttonText             = TextManager.GetWithVariable("EnterLocation", "[locationname]", Level.Loaded.EndLocation?.Name ?? "[ERROR]");
                    endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
                }
                break;

            case TransitionType.LeaveLocation:
                buttonText             = TextManager.GetWithVariable("LeaveLocation", "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
                endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
                break;

            case TransitionType.ReturnToPreviousLocation:
            case TransitionType.ReturnToPreviousEmptyLocation:
                if (Level.Loaded.StartOutpost == null || !Level.Loaded.StartOutpost.DockedTo.Contains(leavingSub))
                {
                    buttonText             = TextManager.GetWithVariable("EnterLocation", "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
                    endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
                }

                break;

            case TransitionType.None:
            default:
                if (Level.Loaded.Type == LevelData.LevelType.Outpost &&
                    (Character.Controlled?.Submarine?.Info.Type == SubmarineType.Player || (Character.Controlled?.CurrentHull?.OutpostModuleTags?.Contains("airlock") ?? false)))
                {
                    buttonText             = TextManager.GetWithVariable("LeaveLocation", "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
                    endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
                }
                else
                {
                    endRoundButton.Visible = false;
                }
                break;
            }

            if (ReadyCheckButton != null)
            {
                ReadyCheckButton.Visible = endRoundButton.Visible;
            }

            if (endRoundButton.Visible)
            {
                if (!AllowedToEndRound())
                {
                    buttonText = TextManager.Get("map");
                }
                endRoundButton.Text = ToolBox.LimitString(buttonText, endRoundButton.Font, endRoundButton.Rect.Width - 5);
                if (endRoundButton.Text != buttonText)
                {
                    endRoundButton.ToolTip = buttonText;
                }
                if (Character.Controlled?.ViewTarget is Item item)
                {
                    Turret turret = item.GetComponent <Turret>();
                    endRoundButton.RectTransform.ScreenSpaceOffset = turret == null ? Point.Zero : new Point(0, (int)(turret.UIElementHeight * 1.25f));
                }
                else if (Character.Controlled?.CharacterHealth?.SuicideButton?.Visible ?? false)
                {
                    endRoundButton.RectTransform.ScreenSpaceOffset = new Point(0, Character.Controlled.CharacterHealth.SuicideButton.Rect.Height);
                }
                else
                {
                    endRoundButton.RectTransform.ScreenSpaceOffset = Point.Zero;
                }
            }
            endRoundButton.DrawManually(spriteBatch);
            if (this is MultiPlayerCampaign)
            {
                ReadyCheckButton?.DrawManually(spriteBatch);
            }
        }
Esempio n. 6
0
        public override void Draw(SpriteBatch spriteBatch)
        {
            if (overlayColor.A > 0)
            {
                if (overlaySprite != null)
                {
                    GUI.DrawRectangle(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * (overlayColor.A / 255.0f), isFilled: true);
                    float scale = Math.Max(GameMain.GraphicsWidth / overlaySprite.size.X, GameMain.GraphicsHeight / overlaySprite.size.Y);
                    overlaySprite.Draw(spriteBatch, new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2, overlayColor, overlaySprite.size / 2, scale: scale);
                }
                else
                {
                    GUI.DrawRectangle(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), overlayColor, isFilled: true);
                }
                if (!string.IsNullOrEmpty(overlayText) && overlayTextColor.A > 0)
                {
                    var     backgroundSprite = GUI.Style.GetComponentStyle("CommandBackground").GetDefaultSprite();
                    Vector2 centerPos        = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2;
                    string  wrappedText      = ToolBox.WrapText(overlayText, GameMain.GraphicsWidth / 3, GUI.Font);
                    Vector2 textSize         = GUI.Font.MeasureString(wrappedText);
                    Vector2 textPos          = centerPos - textSize / 2;
                    backgroundSprite.Draw(spriteBatch,
                                          centerPos,
                                          Color.White * (overlayTextColor.A / 255.0f),
                                          origin: backgroundSprite.size / 2,
                                          rotate: 0.0f,
                                          scale: new Vector2(GameMain.GraphicsWidth / 2 / backgroundSprite.size.X, textSize.Y / backgroundSprite.size.Y * 1.5f));

                    GUI.DrawString(spriteBatch, textPos + Vector2.One, wrappedText, Color.Black * (overlayTextColor.A / 255.0f));
                    GUI.DrawString(spriteBatch, textPos, wrappedText, overlayTextColor);

                    if (!string.IsNullOrEmpty(overlayTextBottom))
                    {
                        Vector2 bottomTextPos = centerPos + new Vector2(0.0f, textSize.Y / 2 + 40 * GUI.Scale) - GUI.Font.MeasureString(overlayTextBottom) / 2;
                        GUI.DrawString(spriteBatch, bottomTextPos + Vector2.One, overlayTextBottom, Color.Black * (overlayTextColor.A / 255.0f));
                        GUI.DrawString(spriteBatch, bottomTextPos, overlayTextBottom, overlayTextColor);
                    }
                }
            }

            if (GUI.DisableHUD || GUI.DisableUpperHUD || ForceMapUI || CoroutineManager.IsCoroutineRunning("LevelTransition"))
            {
                endRoundButton.Visible = false;
                if (ReadyCheckButton != null)
                {
                    ReadyCheckButton.Visible = false;
                }
                return;
            }
            if (Submarine.MainSub == null || Level.Loaded == null)
            {
                return;
            }

            endRoundButton.Visible = false;
            var    availableTransition = GetAvailableTransition(out _, out Submarine leavingSub);
            string buttonText          = "";

            switch (availableTransition)
            {
            case TransitionType.ProgressToNextLocation:
            case TransitionType.ProgressToNextEmptyLocation:
                if (Level.Loaded.EndOutpost == null || !Level.Loaded.EndOutpost.DockedTo.Contains(leavingSub))
                {
                    string textTag = availableTransition == TransitionType.ProgressToNextLocation ? "EnterLocation" : "EnterEmptyLocation";
                    buttonText             = TextManager.GetWithVariable(textTag, "[locationname]", Level.Loaded.EndLocation?.Name ?? "[ERROR]");
                    endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
                }
                break;

            case TransitionType.LeaveLocation:
                buttonText             = TextManager.GetWithVariable("LeaveLocation", "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
                endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
                break;

            case TransitionType.ReturnToPreviousLocation:
            case TransitionType.ReturnToPreviousEmptyLocation:
                if (Level.Loaded.StartOutpost == null || !Level.Loaded.StartOutpost.DockedTo.Contains(leavingSub))
                {
                    string textTag = availableTransition == TransitionType.ReturnToPreviousLocation ? "EnterLocation" : "EnterEmptyLocation";
                    buttonText             = TextManager.GetWithVariable(textTag, "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
                    endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
                }

                break;

            case TransitionType.None:
            default:
                if (Level.Loaded.Type == LevelData.LevelType.Outpost &&
                    (Character.Controlled?.Submarine?.Info.Type == SubmarineType.Player || (Character.Controlled?.CurrentHull?.OutpostModuleTags.Contains("airlock") ?? false)))
                {
                    buttonText             = TextManager.GetWithVariable("LeaveLocation", "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
                    endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
                }
                else
                {
                    endRoundButton.Visible = false;
                }
                break;
            }

            if (ReadyCheckButton != null)
            {
                ReadyCheckButton.Visible = endRoundButton.Visible;
            }

            if (endRoundButton.Visible)
            {
                if (!AllowedToEndRound())
                {
                    buttonText = TextManager.Get("map");
                }
                else if (prevCampaignUIAutoOpenType != availableTransition &&
                         (availableTransition == TransitionType.ProgressToNextEmptyLocation || availableTransition == TransitionType.ReturnToPreviousEmptyLocation))
                {
                    HintManager.OnAvailableTransition(availableTransition);
                    //opening the campaign map pauses the game and prevents HintManager from running -> update it manually to get the hint to show up immediately
                    HintManager.Update();
                    Map.SelectLocation(-1);
                    endRoundButton.OnClicked(EndRoundButton, null);
                    prevCampaignUIAutoOpenType = availableTransition;
                }
                endRoundButton.Text = ToolBox.LimitString(buttonText, endRoundButton.Font, endRoundButton.Rect.Width - 5);
                if (endRoundButton.Text != buttonText)
                {
                    endRoundButton.ToolTip = buttonText;
                }
                if (Character.Controlled?.CharacterHealth?.SuicideButton?.Visible ?? false)
                {
                    endRoundButton.RectTransform.ScreenSpaceOffset = new Point(0, Character.Controlled.CharacterHealth.SuicideButton.Rect.Height);
                }
                else if (GameMain.Client != null && GameMain.Client.IsFollowSubTickBoxVisible)
                {
                    endRoundButton.RectTransform.ScreenSpaceOffset = new Point(0, HUDLayoutSettings.Padding + GameMain.Client.FollowSubTickBox.Rect.Height);
                }
                else
                {
                    endRoundButton.RectTransform.ScreenSpaceOffset = Point.Zero;
                }
            }
            endRoundButton.DrawManually(spriteBatch);
            if (this is MultiPlayerCampaign && ReadyCheckButton != null)
            {
                ReadyCheckButton.RectTransform.ScreenSpaceOffset = endRoundButton.RectTransform.ScreenSpaceOffset;
                ReadyCheckButton.DrawManually(spriteBatch);
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            Timing.TotalTime    = gameTime.TotalGameTime.TotalSeconds;
            Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds;
            int updateIterations = (int)Math.Floor(Timing.Accumulator / Timing.Step);

            if (Timing.Accumulator > Timing.Step * 6.0)
            {
                //if the game's running too slowly then we have no choice
                //but to skip a bunch of steps
                //otherwise it snowballs and becomes unplayable
                Timing.Accumulator = Timing.Step;
            }

            CrossThread.ProcessTasks();

            PlayerInput.UpdateVariable();

            bool paused = true;

            if (SoundManager != null)
            {
                if (WindowActive || !Config.MuteOnFocusLost)
                {
                    SoundManager.ListenerGain = SoundManager.CompressionDynamicRangeGain;
                }
                else
                {
                    SoundManager.ListenerGain = 0.0f;
                }
            }

            while (Timing.Accumulator >= Timing.Step)
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();

                fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly;
                TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16);
                fixedTime.ElapsedGameTime = addTime;
                fixedTime.TotalGameTime.Add(addTime);
                base.Update(fixedTime);

                PlayerInput.Update(Timing.Step);


                if (loadingScreenOpen)
                {
                    //reset accumulator if loading
                    // -> less choppy loading screens because the screen is rendered after each update
                    // -> no pause caused by leftover time in the accumulator when starting a new shift
                    GameMain.ResetFrameTime();

                    if (!TitleScreen.PlayingSplashScreen)
                    {
                        SoundPlayer.Update((float)Timing.Step);
                    }

                    if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen &&
                        (!waitForKeyHit || ((PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.LeftButtonClicked()) && WindowActive)))
                    {
                        loadingScreenOpen = false;
                    }

                    if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine))
                    {
                        string errMsg = "Loading was interrupted due to an error";
                        if (loadingCoroutine.Exception != null)
                        {
                            errMsg += ": " + loadingCoroutine.Exception.Message + "\n" + loadingCoroutine.Exception.StackTrace;
                        }
                        throw new Exception(errMsg);
                    }
                }
                else if (hasLoaded)
                {
                    if (ConnectLobby != 0)
                    {
                        if (Client != null)
                        {
                            Client.Disconnect();
                            Client = null;

                            GameMain.MainMenuScreen.Select();
                        }
                        Steam.SteamManager.JoinLobby(ConnectLobby, true);

                        ConnectLobby    = 0;
                        ConnectEndpoint = null;
                        ConnectName     = null;
                    }
                    else if (!string.IsNullOrWhiteSpace(ConnectEndpoint))
                    {
                        if (Client != null)
                        {
                            Client.Disconnect();
                            Client = null;

                            GameMain.MainMenuScreen.Select();
                        }
                        UInt64 serverSteamId = SteamManager.SteamIDStringToUInt64(ConnectEndpoint);
                        Client = new GameClient(Config.PlayerName,
                                                serverSteamId != 0 ? null : ConnectEndpoint,
                                                serverSteamId,
                                                string.IsNullOrWhiteSpace(ConnectName) ? ConnectEndpoint : ConnectName);
                        ConnectLobby    = 0;
                        ConnectEndpoint = null;
                        ConnectName     = null;
                    }

                    SoundPlayer.Update((float)Timing.Step);

                    if (PlayerInput.KeyHit(Keys.Escape) && WindowActive)
                    {
                        // Check if a text input is selected.
                        if (GUI.KeyboardDispatcher.Subscriber != null)
                        {
                            if (GUI.KeyboardDispatcher.Subscriber is GUITextBox textBox)
                            {
                                textBox.Deselect();
                            }
                            GUI.KeyboardDispatcher.Subscriber = null;
                        }
                        //if a verification prompt (are you sure you want to x) is open, close it
                        else if (GUIMessageBox.VisibleBox as GUIMessageBox != null &&
                                 GUIMessageBox.VisibleBox.UserData as string == "verificationprompt")
                        {
                            ((GUIMessageBox)GUIMessageBox.VisibleBox).Close();
                        }
                        else if (Tutorial.Initialized && Tutorial.ContentRunning)
                        {
                            (GameSession.GameMode as TutorialMode).Tutorial.CloseActiveContentGUI();
                        }
                        else if (GUI.PauseMenuOpen)
                        {
                            GUI.TogglePauseMenu();
                        }
                        //open the pause menu if not controlling a character OR if the character has no UIs active that can be closed with ESC
                        else if (Character.Controlled == null ||
                                 ((Character.Controlled.SelectedConstruction == null || !Character.Controlled.SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null))
                                  //TODO: do we need to check Inventory.SelectedSlot?
                                  && Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null))
                        {
                            // Otherwise toggle pausing, unless another window/interface is open.
                            GUI.TogglePauseMenu();
                        }
                    }

#if DEBUG
                    if (GameMain.NetworkMember == null)
                    {
                        if (PlayerInput.KeyHit(Keys.P) && !(GUI.KeyboardDispatcher.Subscriber is GUITextBox))
                        {
                            DebugConsole.Paused = !DebugConsole.Paused;
                        }
                    }
#endif

                    GUI.ClearUpdateList();
                    paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen || Tutorial.ContentRunning || DebugConsole.Paused) &&
                             (NetworkMember == null || !NetworkMember.GameStarted);

#if !DEBUG
                    if (NetworkMember == null && !WindowActive && !paused && true && Screen.Selected != MainMenuScreen && Config.PauseOnFocusLost)
                    {
                        GUI.TogglePauseMenu();
                        paused = true;
                    }
#endif

                    Screen.Selected.AddToGUIUpdateList();

                    if (Client != null)
                    {
                        Client.AddToGUIUpdateList();
                    }

                    DebugConsole.AddToGUIUpdateList();

                    DebugConsole.Update((float)Timing.Step);
                    paused = paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted));

                    if (!paused)
                    {
                        Screen.Selected.Update(Timing.Step);
                    }
                    else if (Tutorial.Initialized && Tutorial.ContentRunning)
                    {
                        (GameSession.GameMode as TutorialMode).Update((float)Timing.Step);
                    }
                    else if (DebugConsole.Paused)
                    {
                        if (Screen.Selected.Cam == null)
                        {
                            DebugConsole.Paused = false;
                        }
                        else
                        {
                            Screen.Selected.Cam.MoveCamera((float)Timing.Step);
                        }
                    }

                    if (NetworkMember != null)
                    {
                        NetworkMember.Update((float)Timing.Step);
                    }

                    GUI.Update((float)Timing.Step);
                }

                CoroutineManager.Update((float)Timing.Step, paused ? 0.0f : (float)Timing.Step);

                SteamManager.Update((float)Timing.Step);

                SoundManager?.Update();

                Timing.Accumulator -= Timing.Step;

                sw.Stop();
                PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks);
                PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks / (float)TimeSpan.TicksPerMillisecond);
                PerformanceCounter.UpdateIterationsGraph.Update(updateIterations);
            }

            if (!paused)
            {
                Timing.Alpha = Timing.Accumulator / Timing.Step;
            }
        }
Esempio n. 8
0
        public override void Update(float deltaTime)
        {
            if (CoroutineManager.IsCoroutineRunning("LevelTransition") || Level.Loaded == null)
            {
                return;
            }

            if (ShowCampaignUI || ForceMapUI)
            {
                if (CampaignUI == null)
                {
                    InitCampaignUI();
                }
                Character.DisableControls = true;
            }

            base.Update(deltaTime);

            if (PlayerInput.SecondaryMouseButtonClicked() ||
                PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape))
            {
                ShowCampaignUI = false;
                if (GUIMessageBox.VisibleBox?.UserData is RoundSummary roundSummary &&
                    roundSummary.ContinueButton != null &&
                    roundSummary.ContinueButton.Visible)
                {
                    GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox);
                }
            }

            if (!GUI.DisableHUD && !GUI.DisableUpperHUD)
            {
                endRoundButton.UpdateManually(deltaTime);
                if (CoroutineManager.IsCoroutineRunning("LevelTransition") || ForceMapUI)
                {
                    return;
                }
            }

            if (Level.Loaded.Type == LevelData.LevelType.Outpost)
            {
                if (wasDocked)
                {
                    var  connectedSubs = Submarine.MainSub.GetConnectedSubs();
                    bool isDocked      = Level.Loaded.StartOutpost != null && connectedSubs.Contains(Level.Loaded.StartOutpost);
                    if (!isDocked)
                    {
                        //undocked from outpost, need to choose a destination
                        ForceMapUI = true;
                        if (CampaignUI == null)
                        {
                            InitCampaignUI();
                        }
                        CampaignUI.SelectTab(InteractionType.Map);
                    }
                }
                else
                {
                    //wasn't initially docked (sub doesn't have a docking port?)
                    // -> choose a destination when the sub is far enough from the start outpost
                    if (!Submarine.MainSub.AtStartPosition)
                    {
                        ForceMapUI = true;
                        if (CampaignUI == null)
                        {
                            InitCampaignUI();
                        }
                        CampaignUI.SelectTab(InteractionType.Map);
                    }
                }

                if (CampaignUI == null)
                {
                    InitCampaignUI();
                }
            }
            else
            {
                var transitionType = GetAvailableTransition(out _, out _);
                if (transitionType == TransitionType.None && CampaignUI?.SelectedTab == InteractionType.Map)
                {
                    ShowCampaignUI = false;
                }
            }
        }
Esempio n. 9
0
        public void LoadNewLevel()
        {
            if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
            {
                return;
            }

            if (CoroutineManager.IsCoroutineRunning("LevelTransition"))
            {
                DebugConsole.ThrowError("Level transition already running.\n" + Environment.StackTrace.CleanupStackTrace());
                return;
            }

            BeforeLevelLoading?.Invoke();
            BeforeLevelLoading = null;

            if (Level.Loaded == null || Submarine.MainSub == null)
            {
                LoadInitialLevel();
                return;
            }

            var availableTransition = GetAvailableTransition(out LevelData nextLevel, out Submarine leavingSub);

            if (availableTransition == TransitionType.None)
            {
                DebugConsole.ThrowError("Failed to load a new campaign level. No available level transitions " +
                                        "(current location: " + (map.CurrentLocation?.Name ?? "null") + ", " +
                                        "selected location: " + (map.SelectedLocation?.Name ?? "null") + ", " +
                                        "leaving sub: " + (leavingSub?.Info?.Name ?? "null") + ", " +
                                        "at start: " + (leavingSub?.AtStartExit.ToString() ?? "null") + ", " +
                                        "at end: " + (leavingSub?.AtEndExit.ToString() ?? "null") + ")\n" +
                                        Environment.StackTrace.CleanupStackTrace());
                return;
            }
            if (nextLevel == null)
            {
                DebugConsole.ThrowError("Failed to load a new campaign level. No available level transitions " +
                                        "(transition type: " + availableTransition + ", " +
                                        "current location: " + (map.CurrentLocation?.Name ?? "null") + ", " +
                                        "selected location: " + (map.SelectedLocation?.Name ?? "null") + ", " +
                                        "leaving sub: " + (leavingSub?.Info?.Name ?? "null") + ", " +
                                        "at start: " + (leavingSub?.AtStartExit.ToString() ?? "null") + ", " +
                                        "at end: " + (leavingSub?.AtEndExit.ToString() ?? "null") + ")\n" +
                                        Environment.StackTrace.CleanupStackTrace());
                return;
            }
#if CLIENT
            ShowCampaignUI = ForceMapUI = false;
#endif
            DebugConsole.NewMessage("Transitioning to " + (nextLevel?.Seed ?? "null") +
                                    " (current location: " + (map.CurrentLocation?.Name ?? "null") + ", " +
                                    "selected location: " + (map.SelectedLocation?.Name ?? "null") + ", " +
                                    "leaving sub: " + (leavingSub?.Info?.Name ?? "null") + ", " +
                                    "at start: " + (leavingSub?.AtStartExit.ToString() ?? "null") + ", " +
                                    "at end: " + (leavingSub?.AtEndExit.ToString() ?? "null") + ", " +
                                    "transition type: " + availableTransition + ")");

            IsFirstRound = false;
            bool mirror = map.SelectedConnection != null && map.CurrentLocation != map.SelectedConnection.Locations[0];
            CoroutineManager.StartCoroutine(DoLevelTransition(availableTransition, nextLevel, leavingSub, mirror), "LevelTransition");
        }
Esempio n. 10
0
        public override void Update(float deltaTime)
        {
            if (CoroutineManager.IsCoroutineRunning("LevelTransition") || CoroutineManager.IsCoroutineRunning("SubmarineTransition") || gameOver)
            {
                return;
            }

            base.Update(deltaTime);

            if (PlayerInput.RightButtonClicked() ||
                PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape))
            {
                ShowCampaignUI = false;
                if (GUIMessageBox.VisibleBox?.UserData is RoundSummary roundSummary &&
                    roundSummary.ContinueButton != null &&
                    roundSummary.ContinueButton.Visible)
                {
                    GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.VisibleBox);
                }
            }

#if DEBUG
            if (PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.R))
            {
                if (GUIMessageBox.MessageBoxes.Any())
                {
                    GUIMessageBox.MessageBoxes.Remove(GUIMessageBox.MessageBoxes.Last());
                }

                GUIFrame summaryFrame = GameMain.GameSession.RoundSummary.CreateSummaryFrame(GameMain.GameSession, "", null);
                GUIMessageBox.MessageBoxes.Add(summaryFrame);
                GameMain.GameSession.RoundSummary.ContinueButton.OnClicked = (_, __) => { GUIMessageBox.MessageBoxes.Remove(summaryFrame); return(true); };
            }
#endif

            if (ShowCampaignUI || ForceMapUI)
            {
                Character.DisableControls = true;
            }

            if (!GUI.DisableHUD && !GUI.DisableUpperHUD)
            {
                endRoundButton.UpdateManually(deltaTime);
                if (CoroutineManager.IsCoroutineRunning("LevelTransition") || ForceMapUI)
                {
                    return;
                }
            }

            if (Level.Loaded.Type == LevelData.LevelType.Outpost)
            {
                KeepCharactersCloseToOutpost(deltaTime);
                if (wasDocked)
                {
                    var  connectedSubs = Submarine.MainSub.GetConnectedSubs();
                    bool isDocked      = Level.Loaded.StartOutpost != null && connectedSubs.Contains(Level.Loaded.StartOutpost);
                    if (!isDocked)
                    {
                        //undocked from outpost, need to choose a destination
                        ForceMapUI = true;
                        CampaignUI.SelectTab(InteractionType.Map);
                    }
                }
                else
                {
                    //wasn't initially docked (sub doesn't have a docking port?)
                    // -> choose a destination when the sub is far enough from the start outpost
                    if (!Submarine.MainSub.AtStartPosition)
                    {
                        ForceMapUI = true;
                        CampaignUI.SelectTab(InteractionType.Map);
                    }
                }
            }
            else
            {
                var transitionType = GetAvailableTransition(out _, out Submarine leavingSub);
                if (transitionType == TransitionType.End)
                {
                    EndCampaign();
                }
                if (transitionType == TransitionType.ProgressToNextLocation &&
                    Level.Loaded.EndOutpost != null && Level.Loaded.EndOutpost.DockedTo.Contains(leavingSub))
                {
                    LoadNewLevel();
                }
                else if (transitionType == TransitionType.ReturnToPreviousLocation &&
                         Level.Loaded.StartOutpost != null && Level.Loaded.StartOutpost.DockedTo.Contains(leavingSub))
                {
                    LoadNewLevel();
                }
                else if (transitionType == TransitionType.None && CampaignUI.SelectedTab == InteractionType.Map)
                {
                    ShowCampaignUI = false;
                }
            }

            if (!crewDead)
            {
                if (!CrewManager.GetCharacters().Any(c => !c.IsDead))
                {
                    crewDead = true;
                }
            }
            else
            {
                endTimer -= deltaTime;
                if (endTimer <= 0.0f)
                {
                    GameOver();
                }
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            Timing.TotalTime    = gameTime.TotalGameTime.TotalSeconds;
            Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds;
            PlayerInput.UpdateVariable();

            bool paused = true;

            if (GameMain.NilMod.UseExperimentalFPSLagPrevention && !loadingScreenOpen)
            {
                if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 2)
                {
                    Timing.Step = 1.0 / 8.0;
                    FarseerPhysics.Settings.VelocityIterations    = 10;
                    FarseerPhysics.Settings.PositionIterations    = 4;
                    FarseerPhysics.Settings.TOIPositionIterations = 25;
                    FarseerPhysics.Settings.TOIVelocityIterations = 10;
                }
                else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 4)
                {
                    Timing.Step = 1.0 / 10.0;
                    FarseerPhysics.Settings.VelocityIterations    = 10;
                    FarseerPhysics.Settings.PositionIterations    = 4;
                    FarseerPhysics.Settings.TOIPositionIterations = 25;
                    FarseerPhysics.Settings.TOIVelocityIterations = 10;
                }
                else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 6)
                {
                    Timing.Step = 1.0 / 12.0;
                    FarseerPhysics.Settings.VelocityIterations    = 10;
                    FarseerPhysics.Settings.PositionIterations    = 4;
                    FarseerPhysics.Settings.TOIPositionIterations = 25;
                    FarseerPhysics.Settings.TOIVelocityIterations = 10;
                }
                else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 8)
                {
                    Timing.Step = 1.0 / 15.0;
                    FarseerPhysics.Settings.VelocityIterations    = 9;
                    FarseerPhysics.Settings.PositionIterations    = 4;
                    FarseerPhysics.Settings.TOIPositionIterations = 22;
                    FarseerPhysics.Settings.TOIVelocityIterations = 9;
                }
                else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 10)
                {
                    Timing.Step = 1.0 / 20.0;
                    FarseerPhysics.Settings.VelocityIterations    = 9;
                    FarseerPhysics.Settings.PositionIterations    = 4;
                    FarseerPhysics.Settings.TOIPositionIterations = 22;
                    FarseerPhysics.Settings.TOIVelocityIterations = 9;
                }
                else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 12)
                {
                    Timing.Step = 1.0 / 25.0;
                    FarseerPhysics.Settings.VelocityIterations    = 9;
                    FarseerPhysics.Settings.PositionIterations    = 4;
                    FarseerPhysics.Settings.TOIPositionIterations = 22;
                    FarseerPhysics.Settings.TOIVelocityIterations = 9;
                }
                else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 14)
                {
                    Timing.Step = 1.0 / 30.0;
                    FarseerPhysics.Settings.VelocityIterations    = 8;
                    FarseerPhysics.Settings.PositionIterations    = 3;
                    FarseerPhysics.Settings.TOIPositionIterations = 20;
                    FarseerPhysics.Settings.TOIVelocityIterations = 8;
                }
                else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 16)
                {
                    Timing.Step = 1.0 / 35.0;
                    FarseerPhysics.Settings.VelocityIterations    = 8;
                    FarseerPhysics.Settings.PositionIterations    = 3;
                    FarseerPhysics.Settings.TOIPositionIterations = 20;
                    FarseerPhysics.Settings.TOIVelocityIterations = 8;
                }
                else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 18)
                {
                    Timing.Step = 1.0 / 40.0;
                    FarseerPhysics.Settings.VelocityIterations    = 8;
                    FarseerPhysics.Settings.PositionIterations    = 3;
                    FarseerPhysics.Settings.TOIPositionIterations = 20;
                    FarseerPhysics.Settings.TOIVelocityIterations = 8;
                }
                else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 20)
                {
                    Timing.Step = 1.0 / 45.0;
                    FarseerPhysics.Settings.VelocityIterations    = 8;
                    FarseerPhysics.Settings.PositionIterations    = 3;
                    FarseerPhysics.Settings.TOIPositionIterations = 20;
                    FarseerPhysics.Settings.TOIVelocityIterations = 8;
                }
                else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 22)
                {
                    Timing.Step = 1.0 / 50.0;
                    FarseerPhysics.Settings.VelocityIterations    = 8;
                    FarseerPhysics.Settings.PositionIterations    = 3;
                    FarseerPhysics.Settings.TOIPositionIterations = 20;
                    FarseerPhysics.Settings.TOIVelocityIterations = 8;
                }
                else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 25)
                {
                    Timing.Step = 1.0 / 55.0;
                    FarseerPhysics.Settings.VelocityIterations    = 8;
                    FarseerPhysics.Settings.PositionIterations    = 3;
                    FarseerPhysics.Settings.TOIPositionIterations = 20;
                    FarseerPhysics.Settings.TOIVelocityIterations = 8;
                }
                else
                {
                    Timing.Step = 1.0 / 60.0;
                    FarseerPhysics.Settings.VelocityIterations    = 8;
                    FarseerPhysics.Settings.PositionIterations    = 3;
                    FarseerPhysics.Settings.TOIPositionIterations = 20;
                    FarseerPhysics.Settings.TOIVelocityIterations = 8;
                }
            }
            else
            {
                Timing.Step = 1.0 / 60.0;
                FarseerPhysics.Settings.VelocityIterations    = 8;
                FarseerPhysics.Settings.PositionIterations    = 3;
                FarseerPhysics.Settings.TOIPositionIterations = 20;
                FarseerPhysics.Settings.TOIVelocityIterations = 8;
            }

            while (Timing.Accumulator >= Timing.Step)
            {
                NilModProfiler.SWMainUpdateLoop.Start();
                fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly;
                TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16);

                if (GameMain.NilMod.UseExperimentalFPSLagPrevention)
                {
                    if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 2)
                    {
                        addTime = new TimeSpan(0, 0, 0, 0, 125);
                    }
                    else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 4)
                    {
                        addTime = new TimeSpan(0, 0, 0, 0, 100);
                    }
                    else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 6)
                    {
                        addTime = new TimeSpan(0, 0, 0, 0, 83);
                    }
                    else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 8)
                    {
                        addTime = new TimeSpan(0, 0, 0, 0, 66);
                    }
                    else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 10)
                    {
                        addTime = new TimeSpan(0, 0, 0, 0, 50);
                    }
                    else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 12)
                    {
                        addTime = new TimeSpan(0, 0, 0, 0, 40);
                    }
                    else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 14)
                    {
                        addTime = new TimeSpan(0, 0, 0, 0, 33);
                    }
                    else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 16)
                    {
                        addTime = new TimeSpan(0, 0, 0, 0, 28);
                    }
                    else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 18)
                    {
                        addTime = new TimeSpan(0, 0, 0, 0, 25);
                    }
                    else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 20)
                    {
                        addTime = new TimeSpan(0, 0, 0, 0, 22);
                    }
                    else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 22)
                    {
                        addTime = new TimeSpan(0, 0, 0, 0, 20);
                    }
                    else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 25)
                    {
                        addTime = new TimeSpan(0, 0, 0, 0, 18);
                    }
                    else
                    {
                        addTime = new TimeSpan(0, 0, 0, 0, 16);
                    }
                }

                fixedTime.ElapsedGameTime = addTime;
                fixedTime.TotalGameTime.Add(addTime);
                base.Update(fixedTime);

                NilModProfiler.SWPlayerInput.Start();
                if (WindowActive)
                {
                    PlayerInput.Update(Timing.Step);
                }
                NilModProfiler.RecordPlayerInput();

                if (loadingScreenOpen)
                {
                    //reset accumulator if loading
                    // -> less choppy loading screens because the screen is rendered after each update
                    // -> no pause caused by leftover time in the accumulator when starting a new shift
                    if (TitleScreen.LoadState >= 100f)
                    {
                        Timing.Accumulator     = 0.0f;
                        this.TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 12);
                    }
                    else
                    {
                        Timing.Accumulator     = Timing.Step * 1.99;
                        this.TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 1);
                    }

                    if (TitleScreen.LoadState >= 100.0f &&
                        (!waitForKeyHit || PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.LeftButtonClicked()))
                    {
                        loadingScreenOpen = false;
                    }

                    if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine))
                    {
                        throw new Exception("Loading was interrupted due to an error");
                    }
                }
                else if (hasLoaded)
                {
                    NilMod.Update((float)Timing.Step);

                    NilModProfiler.SWSoundPlayer.Start();
                    SoundPlayer.Update((float)Timing.Step);
                    NilModProfiler.RecordSoundPlayer();

                    if (PlayerInput.KeyHit(Keys.Escape))
                    {
                        GUI.TogglePauseMenu();
                    }

                    GUIComponent.ClearUpdateList();
                    paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen) &&
                             (NetworkMember == null || !NetworkMember.GameStarted);

                    if (!paused)
                    {
                        Screen.Selected.AddToGUIUpdateList();
                    }

                    if (NetworkMember != null)
                    {
                        NetworkMember.AddToGUIUpdateList();
                    }

                    GUI.AddToGUIUpdateList();
                    DebugConsole.AddToGUIUpdateList();
                    GUIComponent.UpdateMouseOn();

                    NilModProfiler.SWDebugConsole.Start();
                    DebugConsole.Update(this, (float)Timing.Step);
                    paused = paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted));
                    NilModProfiler.RecordDebugConsole();

                    if (!paused)
                    {
                        NilModProfiler.SWGameScreen.Start();
                        Screen.Selected.Update(Timing.Step);
                        NilModProfiler.RecordGameScreen();
                    }

                    if (NetworkMember != null)
                    {
                        NilModProfiler.SWNetworkMember.Start();
                        NetworkMember.Update((float)Timing.Step);
                        NilModProfiler.RecordNetworkMember();
                    }

                    NilModProfiler.SWGUIUpdate.Start();
                    GUI.Update((float)Timing.Step);
                    NilModProfiler.RecordGUIUpdate();
                }

                NilModProfiler.SWCoroutineManager.Start();
                CoroutineManager.Update((float)Timing.Step, paused ? 0.0f : (float)Timing.Step);
                NilModProfiler.RecordCoroutineManager();

                Timing.Accumulator -= Timing.Step;
                if (NilModProfiler.SWMainUpdateLoop.ElapsedTicks > 0)
                {
                    NilModProfiler.RecordMainLoopUpdate();
                }
            }

            GameMain.NilModProfiler.Update((float)Timing.Step);

            if (!paused)
            {
                Timing.Alpha = Timing.Accumulator / Timing.Step;
            }
        }