public MainMenuScreen(GameMain game) { menuTabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length + 1]; buttonsTab = new GUIFrame(new Rectangle(0, 0, 0, 0), Color.Transparent, Alignment.Left | Alignment.CenterY); buttonsTab.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f); int y = (int)(GameMain.GraphicsHeight * 0.3f); Rectangle panelRect = new Rectangle( 290, y, 500, 360); GUIButton button = new GUIButton(new Rectangle(50, y, 200, 30), TextManager.Get("TutorialButton"), null, Alignment.TopLeft, Alignment.Left, "", buttonsTab); button.Color = button.Color * 0.8f; button.OnClicked = TutorialButtonClicked; button = new GUIButton(new Rectangle(50, y + 60, 200, 30), TextManager.Get("NewGameButton"), null, Alignment.TopLeft, Alignment.Left, "", buttonsTab); button.Color = button.Color * 0.8f; button.UserData = Tab.NewGame; button.OnClicked = SelectTab; button = new GUIButton(new Rectangle(50, y + 100, 200, 30), TextManager.Get("LoadGameButton"), null, Alignment.TopLeft, Alignment.Left, "", buttonsTab); button.Color = button.Color * 0.8f; button.UserData = Tab.LoadGame; button.OnClicked = SelectTab; button = new GUIButton(new Rectangle(50, y + 160, 200, 30), TextManager.Get("JoinServerButton"), null, Alignment.TopLeft, Alignment.Left, "", buttonsTab); button.Color = button.Color * 0.8f; //button.UserData = (int)Tabs.JoinServer; button.OnClicked = JoinServerClicked; button = new GUIButton(new Rectangle(50, y + 200, 200, 30), TextManager.Get("HostServerButton"), null, Alignment.TopLeft, Alignment.Left, "", buttonsTab); button.Color = button.Color * 0.8f; button.UserData = Tab.HostServer; button.OnClicked = SelectTab; button = new GUIButton(new Rectangle(50, y + 260, 200, 30), TextManager.Get("SubEditorButton"), null, Alignment.TopLeft, Alignment.Left, "", buttonsTab); button.Color = button.Color * 0.8f; button.OnClicked = (GUIButton btn, object userdata) => { GameMain.SubEditorScreen.Select(); return(true); }; button = new GUIButton(new Rectangle(50, y + 320, 200, 30), TextManager.Get("SettingsButton"), null, Alignment.TopLeft, Alignment.Left, "", buttonsTab); button.Color = button.Color * 0.8f; button.UserData = Tab.Settings; button.OnClicked = SelectTab; button = new GUIButton(new Rectangle(0, 0, 150, 30), TextManager.Get("QuitButton"), Alignment.BottomRight, "", buttonsTab); button.Color = button.Color * 0.8f; button.OnClicked = QuitClicked; panelRect.Y += 10; //---------------------------------------------------------------------- menuTabs[(int)Tab.NewGame] = new GUIFrame(panelRect, ""); menuTabs[(int)Tab.NewGame].Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f); menuTabs[(int)Tab.LoadGame] = new GUIFrame(panelRect, ""); campaignSetupUI = new CampaignSetupUI(false, menuTabs[(int)Tab.NewGame], menuTabs[(int)Tab.LoadGame]); campaignSetupUI.LoadGame = LoadGame; campaignSetupUI.StartNewGame = StartGame; //---------------------------------------------------------------------- menuTabs[(int)Tab.HostServer] = new GUIFrame(panelRect, ""); new GUITextBlock(new Rectangle(0, 0, 100, 30), TextManager.Get("ServerName"), "", Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]); serverNameBox = new GUITextBox(new Rectangle(160, 0, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, "", menuTabs[(int)Tab.HostServer]); new GUITextBlock(new Rectangle(0, 50, 100, 30), TextManager.Get("ServerPort"), "", Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]); portBox = new GUITextBox(new Rectangle(160, 50, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, "", menuTabs[(int)Tab.HostServer]); portBox.Text = NetConfig.DefaultPort.ToString(); portBox.ToolTip = "Server port"; new GUITextBlock(new Rectangle(0, 100, 100, 30), TextManager.Get("MaxPlayers"), "", Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]); maxPlayersBox = new GUITextBox(new Rectangle(195, 100, 30, 30), null, null, Alignment.TopLeft, Alignment.Center, "", menuTabs[(int)Tab.HostServer]); maxPlayersBox.Text = "8"; maxPlayersBox.Enabled = false; var minusPlayersBox = new GUIButton(new Rectangle(160, 100, 30, 30), "-", "", menuTabs[(int)Tab.HostServer]); minusPlayersBox.UserData = -1; minusPlayersBox.OnClicked = ChangeMaxPlayers; var plusPlayersBox = new GUIButton(new Rectangle(230, 100, 30, 30), "+", "", menuTabs[(int)Tab.HostServer]); plusPlayersBox.UserData = 1; plusPlayersBox.OnClicked = ChangeMaxPlayers; new GUITextBlock(new Rectangle(0, 150, 100, 30), TextManager.Get("Password"), "", Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tab.HostServer]); passwordBox = new GUITextBox(new Rectangle(160, 150, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, "", menuTabs[(int)Tab.HostServer]); isPublicBox = new GUITickBox(new Rectangle(10, 200, 20, 20), TextManager.Get("PublicServer"), Alignment.TopLeft, menuTabs[(int)Tab.HostServer]); isPublicBox.ToolTip = TextManager.Get("PublicServerToolTip"); useUpnpBox = new GUITickBox(new Rectangle(10, 250, 20, 20), TextManager.Get("AttemptUPnP"), Alignment.TopLeft, menuTabs[(int)Tab.HostServer]); useUpnpBox.ToolTip = TextManager.Get("AttemptUPnPToolTip"); GUIButton hostButton = new GUIButton(new Rectangle(0, 0, 100, 30), TextManager.Get("StartServerButton"), Alignment.BottomRight, "", menuTabs[(int)Tab.HostServer]); hostButton.OnClicked = HostServerClicked; this.game = game; }
static void CrashDump(GameMain game, string filePath, Exception exception) { int existingFiles = 0; string originalFilePath = filePath; while (File.Exists(filePath)) { existingFiles++; filePath = Path.GetFileNameWithoutExtension(originalFilePath) + " (" + (existingFiles + 1) + ")" + Path.GetExtension(originalFilePath); } DebugConsole.DequeueMessages(); StreamWriter sw = new StreamWriter(filePath); StringBuilder sb = new StringBuilder(); sb.AppendLine("Barotrauma Client crash report (generated on " + DateTime.Now + ")"); sb.AppendLine("\n"); sb.AppendLine("Barotrauma seems to have crashed. Sorry for the inconvenience! "); sb.AppendLine("\n"); #if DEBUG sb.AppendLine("Game version " + GameMain.Version + " (debug build)"); #else sb.AppendLine("Game version " + GameMain.Version); #endif if (GameMain.Config != null) { sb.AppendLine("Graphics mode: " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight + " (" + GameMain.Config.WindowMode.ToString() + ")"); } if (GameMain.SelectedPackages != null) { sb.AppendLine("Selected content packages: " + (!GameMain.SelectedPackages.Any() ? "None" : string.Join(", ", GameMain.SelectedPackages.Select(c => c.Name)))); } sb.AppendLine("Level seed: " + ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed)); sb.AppendLine("Loaded submarine: " + ((Submarine.MainSub == null) ? "None" : Submarine.MainSub.Name + " (" + Submarine.MainSub.MD5Hash + ")")); sb.AppendLine("Selected screen: " + (Screen.Selected == null ? "None" : Screen.Selected.ToString())); if (GameMain.Client != null) { sb.AppendLine("Client (" + (GameMain.Client.GameStarted ? "Round had started)" : "Round hadn't been started)")); } sb.AppendLine("\n"); sb.AppendLine("System info:"); sb.AppendLine(" Operating system: " + System.Environment.OSVersion + (System.Environment.Is64BitOperatingSystem ? " 64 bit" : " x86")); if (game == null) { sb.AppendLine(" Game not initialized"); } else { if (game.GraphicsDevice == null) { sb.AppendLine(" Graphics device not set"); } else { if (game.GraphicsDevice.Adapter == null) { sb.AppendLine(" Graphics adapter not set"); } else { sb.AppendLine(" GPU name: " + game.GraphicsDevice.Adapter.Description); sb.AppendLine(" Display mode: " + game.GraphicsDevice.Adapter.CurrentDisplayMode); } sb.AppendLine(" GPU status: " + game.GraphicsDevice.GraphicsDeviceStatus); } } sb.AppendLine("\n"); sb.AppendLine("Exception: " + exception.Message); if (exception.TargetSite != null) { sb.AppendLine("Target site: " + exception.TargetSite.ToString()); } sb.AppendLine("Stack trace: "); sb.AppendLine(exception.StackTrace); sb.AppendLine("\n"); sb.AppendLine("Last debug messages:"); for (int i = DebugConsole.Messages.Count - 1; i >= 0; i--) { sb.AppendLine("[" + DebugConsole.Messages[i].Time + "] " + DebugConsole.Messages[i].Text); } string crashReport = sb.ToString(); sw.WriteLine(crashReport); sw.Close(); if (GameSettings.SaveDebugConsoleLogs) { DebugConsole.SaveLogs(); } if (GameSettings.SendUserStatistics) { CrashMessageBox("A crash report (\"" + filePath + "\") was saved in the root folder of the game and sent to the developers."); GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport); GameAnalytics.OnStop(); } else { CrashMessageBox("A crash report (\"" + filePath + "\") was saved in the root folder of the game. The error was not sent to the developers because user statistics have been disabled, but" + " if you'd like to help fix this bug, you may post it on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/"); } }
public static void Update(GameMain game, float deltaTime) { lock (queuedMessages) { while (queuedMessages.Count > 0) { var newMsg = queuedMessages.Dequeue(); AddMessage(newMsg); if (GameSettings.SaveDebugConsoleLogs) { unsavedMessages.Add(newMsg); if (unsavedMessages.Count >= messagesPerFile) { SaveLogs(); unsavedMessages.Clear(); } } } } if (activeQuestionText != null && (listBox.children.Count == 0 || listBox.children[listBox.children.Count - 1] != activeQuestionText)) { listBox.children.Remove(activeQuestionText); listBox.children.Add(activeQuestionText); } if (PlayerInput.KeyHit(Keys.F3)) { isOpen = !isOpen; if (isOpen) { textBox.Select(); AddToGUIUpdateList(); } else { GUIComponent.ForceMouseOn(null); textBox.Deselect(); } } if (isOpen) { frame.Update(deltaTime); Character.DisableControls = true; if (PlayerInput.KeyHit(Keys.Up)) { textBox.Text = SelectMessage(-1); } else if (PlayerInput.KeyHit(Keys.Down)) { textBox.Text = SelectMessage(1); } else if (PlayerInput.KeyHit(Keys.Tab)) { textBox.Text = AutoComplete(textBox.Text); } if (PlayerInput.KeyHit(Keys.Enter)) { ExecuteCommand(textBox.Text); textBox.Text = ""; } } }
public MainMenuScreen(GameMain game) { backgroundVignette = new Sprite("Content/UI/MainMenuVignette.png", Vector2.Zero); new GUIImage(new RectTransform(new Vector2(0.4f, 0.25f), Frame.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.08f, 0.05f), AbsoluteOffset = new Point(-8, -8) }, style: "TitleText") { Color = Color.Black * 0.5f, CanBeFocused = false }; titleText = new GUIImage(new RectTransform(new Vector2(0.4f, 0.25f), Frame.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.08f, 0.05f) }, style: "TitleText"); buttonsParent = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 0.85f), parent: Frame.RectTransform, anchor: Anchor.CenterLeft) { AbsoluteOffset = new Point(50, 0) }) { Stretch = true, RelativeSpacing = 0.02f }; // === CAMPAIGN var campaignHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.1f, 0.0f) }, isHorizontal: true); new GUIImage(new RectTransform(new Vector2(0.2f, 0.7f), campaignHolder.RectTransform), "MainMenuCampaignIcon") { CanBeFocused = false }; //spacing new GUIFrame(new RectTransform(new Vector2(0.02f, 0.0f), campaignHolder.RectTransform), style: null); var campaignNavigation = new GUILayoutGroup(new RectTransform(new Vector2(0.75f, 0.75f), parent: campaignHolder.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.25f) }); new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), campaignNavigation.RectTransform), TextManager.Get("CampaignLabel"), textAlignment: Alignment.Left, font: GUI.LargeFont, textColor: Color.Black, style: "MainMenuGUITextBlock") { ForceUpperCase = true }; var campaignButtons = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), parent: campaignNavigation.RectTransform), style: "MainMenuGUIFrame"); var campaignList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.2f), parent: campaignButtons.RectTransform)) { Stretch = false, RelativeSpacing = 0.035f }; new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), campaignList.RectTransform), TextManager.Get("TutorialButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton") { ForceUpperCase = true, UserData = Tab.Tutorials, OnClicked = (tb, userdata) => { SelectTab(tb, userdata); return(true); } }; new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), campaignList.RectTransform), TextManager.Get("LoadGameButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton") { ForceUpperCase = true, UserData = Tab.LoadGame, OnClicked = (tb, userdata) => { SelectTab(tb, userdata); return(true); } }; new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), campaignList.RectTransform), TextManager.Get("NewGameButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton") { ForceUpperCase = true, UserData = Tab.NewGame, OnClicked = (tb, userdata) => { SelectTab(tb, userdata); return(true); } }; // === MULTIPLAYER var multiplayerHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.05f, 0.0f) }, isHorizontal: true); new GUIImage(new RectTransform(new Vector2(0.2f, 0.7f), multiplayerHolder.RectTransform), "MainMenuMultiplayerIcon") { CanBeFocused = false }; //spacing new GUIFrame(new RectTransform(new Vector2(0.02f, 0.0f), multiplayerHolder.RectTransform), style: null); var multiplayerNavigation = new GUILayoutGroup(new RectTransform(new Vector2(0.75f, 0.75f), parent: multiplayerHolder.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.25f) }); new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), multiplayerNavigation.RectTransform), TextManager.Get("MultiplayerLabel"), textAlignment: Alignment.Left, font: GUI.LargeFont, textColor: Color.Black, style: "MainMenuGUITextBlock") { ForceUpperCase = true }; var multiplayerButtons = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), parent: multiplayerNavigation.RectTransform), style: "MainMenuGUIFrame"); var multiplayerList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.2f), parent: multiplayerButtons.RectTransform)) { Stretch = false, RelativeSpacing = 0.035f }; joinServerButton = new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), multiplayerList.RectTransform), TextManager.Get("JoinServerButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton") { ForceUpperCase = true, UserData = Tab.JoinServer, OnClicked = (tb, userdata) => { SelectTab(tb, userdata); return(true); } }; hostServerButton = new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), multiplayerList.RectTransform), TextManager.Get("HostServerButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton") { ForceUpperCase = true, UserData = Tab.HostServer, OnClicked = (tb, userdata) => { SelectTab(tb, userdata); return(true); } }; // === CUSTOMIZE var customizeHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.15f, 0.0f) }, isHorizontal: true); new GUIImage(new RectTransform(new Vector2(0.2f, 0.7f), customizeHolder.RectTransform), "MainMenuCustomizeIcon") { CanBeFocused = false }; //spacing new GUIFrame(new RectTransform(new Vector2(0.02f, 0.0f), customizeHolder.RectTransform), style: null); var customizeNavigation = new GUILayoutGroup(new RectTransform(new Vector2(0.75f, 0.75f), parent: customizeHolder.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.25f) }); new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), customizeNavigation.RectTransform), TextManager.Get("CustomizeLabel"), textAlignment: Alignment.Left, font: GUI.LargeFont, textColor: Color.Black, style: "MainMenuGUITextBlock") { ForceUpperCase = true }; var customizeButtons = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), parent: customizeNavigation.RectTransform), style: "MainMenuGUIFrame"); var customizeList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.2f), parent: customizeButtons.RectTransform)) { Stretch = false, RelativeSpacing = 0.035f }; if (Steam.SteamManager.USE_STEAM) { steamWorkshopButton = new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), customizeList.RectTransform), TextManager.Get("SteamWorkshopButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton") { ForceUpperCase = true, Enabled = false, UserData = Tab.SteamWorkshop, OnClicked = SelectTab }; /*#if OSX && !DEBUG * steamWorkshopButton.Text += " (Not yet available on MacOS)"; #endif*/ } new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), customizeList.RectTransform), TextManager.Get("SubEditorButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton") { ForceUpperCase = true, UserData = Tab.SubmarineEditor, OnClicked = (tb, userdata) => { SelectTab(tb, userdata); return(true); } }; new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), customizeList.RectTransform), TextManager.Get("CharacterEditorButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton") { ForceUpperCase = true, UserData = Tab.CharacterEditor, OnClicked = (tb, userdata) => { SelectTab(tb, userdata); return(true); } }; // === OPTION var optionHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.8f), parent: buttonsParent.RectTransform), isHorizontal: true); new GUIImage(new RectTransform(new Vector2(0.15f, 0.6f), optionHolder.RectTransform), "MainMenuOptionIcon") { CanBeFocused = false }; //spacing new GUIFrame(new RectTransform(new Vector2(0.01f, 0.0f), optionHolder.RectTransform), style: null); var optionButtons = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 1.0f), parent: optionHolder.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.0f) }); var optionList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.25f), parent: optionButtons.RectTransform)) { Stretch = false, RelativeSpacing = 0.035f }; new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), optionList.RectTransform), TextManager.Get("SettingsButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton") { ForceUpperCase = true, UserData = Tab.Settings, OnClicked = SelectTab }; //TODO: translate new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), optionList.RectTransform), TextManager.Get("CreditsButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton") { ForceUpperCase = true, UserData = Tab.Credits, OnClicked = SelectTab }; new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), optionList.RectTransform), TextManager.Get("QuitButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton") { ForceUpperCase = true, OnClicked = QuitClicked }; //debug button for quickly starting a new round #if DEBUG new GUIButton(new RectTransform(new Point(300, 30), Frame.RectTransform, Anchor.TopRight) { AbsoluteOffset = new Point(40, 40) }, "Quickstart (dev)", style: "GUIButtonLarge", color: Color.Red) { IgnoreLayoutGroups = true, UserData = Tab.QuickStartDev, OnClicked = (tb, userdata) => { SelectTab(tb, userdata); return(true); } }; #endif var minButtonSize = new Point(120, 20); var maxButtonSize = new Point(480, 80); /*new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("TutorialButton"), style: "GUIButtonLarge") * { * UserData = Tab.Tutorials, * OnClicked = SelectTab, * Enabled = false * };*/ /* var buttons = GUI.CreateButtons(9, new Vector2(1, 0.04f), buttonsParent.RectTransform, anchor: Anchor.BottomLeft, * minSize: minButtonSize, maxSize: maxButtonSize, relativeSpacing: 0.005f, extraSpacing: i => i % 2 == 0 ? 20 : 0); * buttons.ForEach(b => b.Color *= 0.8f); * SetupButtons(buttons); * buttons.ForEach(b => b.TextBlock.SetTextPos());*/ var relativeSize = new Vector2(0.6f, 0.65f); var minSize = new Point(600, 400); var maxSize = new Point(2000, 1500); var anchor = Anchor.CenterRight; var pivot = Pivot.CenterRight; Vector2 relativeSpacing = new Vector2(0.05f, 0.0f); menuTabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length + 1]; menuTabs[(int)Tab.Settings] = new GUIFrame(new RectTransform(new Vector2(relativeSize.X, 0.8f), GUI.Canvas, anchor, pivot, minSize, maxSize) { RelativeOffset = relativeSpacing }, style: null); menuTabs[(int)Tab.NewGame] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize) { RelativeOffset = relativeSpacing }); var paddedNewGame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), menuTabs[(int)Tab.NewGame].RectTransform, Anchor.Center), style: null); menuTabs[(int)Tab.LoadGame] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize) { RelativeOffset = relativeSpacing }); var paddedLoadGame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), menuTabs[(int)Tab.LoadGame].RectTransform, Anchor.Center), style: null); campaignSetupUI = new CampaignSetupUI(false, paddedNewGame, paddedLoadGame, Submarine.SavedSubmarines) { LoadGame = LoadGame, StartNewGame = StartGame }; var hostServerScale = new Vector2(0.7f, 1.0f); menuTabs[(int)Tab.HostServer] = new GUIFrame(new RectTransform( Vector2.Multiply(relativeSize, hostServerScale), GUI.Canvas, anchor, pivot, minSize.Multiply(hostServerScale), maxSize.Multiply(hostServerScale)) { RelativeOffset = relativeSpacing }); CreateHostServerFields(); //---------------------------------------------------------------------- menuTabs[(int)Tab.Tutorials] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize) { RelativeOffset = relativeSpacing }); //PLACEHOLDER var tutorialList = new GUIListBox( new RectTransform(new Vector2(0.95f, 0.85f), menuTabs[(int)Tab.Tutorials].RectTransform, Anchor.TopCenter) { RelativeOffset = new Vector2(0.0f, 0.1f) }, false, null, ""); foreach (Tutorial tutorial in Tutorial.Tutorials) { var tutorialText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), tutorialList.Content.RectTransform), tutorial.DisplayName, textAlignment: Alignment.Center, font: GUI.LargeFont) { UserData = tutorial }; } tutorialList.OnSelected += (component, obj) => { TutorialMode.StartTutorial(obj as Tutorial); return(true); }; this.game = game; menuTabs[(int)Tab.Credits] = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: null, color: Color.Black * 0.5f) { CanBeFocused = false }; var creditsContainer = new GUIFrame(new RectTransform(new Vector2(0.75f, 1.5f), menuTabs[(int)Tab.Credits].RectTransform, Anchor.CenterRight), style: "OuterGlow", color: Color.Black * 0.8f); creditsPlayer = new CreditsPlayer(new RectTransform(Vector2.One, creditsContainer.RectTransform), "Content/Texts/Credits.xml"); new GUIButton(new RectTransform(new Vector2(0.1f, 0.05f), menuTabs[(int)Tab.Credits].RectTransform, Anchor.BottomLeft) { RelativeOffset = new Vector2(0.25f, 0.02f) }, TextManager.Get("Back"), style: "GUIButtonLarge") { OnClicked = SelectTab }; }
static void CrashDump(GameMain game, string filePath, Exception exception) { DebugConsole.DequeueMessages(); StreamWriter sw = new StreamWriter(filePath); StringBuilder sb = new StringBuilder(); sb.AppendLine("Barotrauma Client crash report (generated on " + DateTime.Now + ")"); sb.AppendLine("\n"); sb.AppendLine("Barotrauma seems to have crashed. Sorry for the inconvenience! "); sb.AppendLine("If you'd like to help fix the bug that caused the crash, please send this file to the developers on the Undertow Games forums."); sb.AppendLine("\n"); sb.AppendLine("Game version " + GameMain.Version); sb.AppendLine("Graphics mode: " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight + " (" + GameMain.Config.WindowMode.ToString() + ")"); sb.AppendLine("Selected content package: " + GameMain.SelectedPackage.Name); sb.AppendLine("Level seed: " + ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed)); sb.AppendLine("Loaded submarine: " + ((Submarine.MainSub == null) ? "None" : Submarine.MainSub.Name + " (" + Submarine.MainSub.MD5Hash + ")")); sb.AppendLine("Selected screen: " + (Screen.Selected == null ? "None" : Screen.Selected.ToString())); if (GameMain.Server != null) { sb.AppendLine("Server (" + (GameMain.Server.GameStarted ? "Round had started)" : "Round hadn't been started)")); } else if (GameMain.Client != null) { sb.AppendLine("Client (" + (GameMain.Client.GameStarted ? "Round had started)" : "Round hadn't been started)")); } sb.AppendLine("\n"); sb.AppendLine("System info:"); sb.AppendLine(" Operating system: " + System.Environment.OSVersion + (System.Environment.Is64BitOperatingSystem ? " 64 bit" : " x86")); if (game.GraphicsDevice == null) { sb.AppendLine(" Graphics device not set"); } else { if (game.GraphicsDevice.Adapter == null) { sb.AppendLine(" Graphics adapter not set"); } else { sb.AppendLine(" GPU name: " + game.GraphicsDevice.Adapter.Description); sb.AppendLine(" Display mode: " + game.GraphicsDevice.Adapter.CurrentDisplayMode); } sb.AppendLine(" GPU status: " + game.GraphicsDevice.GraphicsDeviceStatus); } sb.AppendLine("\n"); sb.AppendLine("Exception: " + exception.Message); sb.AppendLine("Target site: " + exception.TargetSite.ToString()); sb.AppendLine("Stack trace: "); sb.AppendLine(exception.StackTrace); sb.AppendLine("\n"); sb.AppendLine("Last debug messages:"); for (int i = DebugConsole.Messages.Count - 1; i > 0; i--) { sb.AppendLine(" " + DebugConsole.Messages[i].Time + " - " + DebugConsole.Messages[i].Text); } sw.WriteLine(sb.ToString()); sw.Close(); CrashMessageBox("A crash report (\"crashreport.txt\") was saved in the root folder of the game." + " If you'd like to help fix this bug, please post the report on the Undertow Games forums."); }
static void CrashDump(GameMain game, string filePath, Exception exception) { int existingFiles = 0; string originalFilePath = filePath; while (File.Exists(filePath)) { existingFiles++; filePath = Path.GetFileNameWithoutExtension(originalFilePath) + " (" + (existingFiles + 1) + ")" + Path.GetExtension(originalFilePath); } DebugConsole.DequeueMessages(); Md5Hash exeHash = null; try { string exePath = System.Reflection.Assembly.GetEntryAssembly().Location; var md5 = System.Security.Cryptography.MD5.Create(); byte[] exeBytes = File.ReadAllBytes(exePath); exeHash = new Md5Hash(exeBytes); } catch { //do nothing, generate the rest of the crash report } StringBuilder sb = new StringBuilder(); sb.AppendLine("Barotrauma Client crash report (generated on " + DateTime.Now + ")"); sb.AppendLine("\n"); sb.AppendLine("Barotrauma seems to have crashed. Sorry for the inconvenience! "); sb.AppendLine("\n"); try { if (exception is GameMain.LoadingException) { //exception occurred in loading screen: //assume content packages are the culprit and reset them XDocument doc = XMLExtensions.TryLoadXml(GameSettings.PlayerSavePath); XDocument baseDoc = XMLExtensions.TryLoadXml(GameSettings.SavePath); if (doc != null && baseDoc != null) { XElement newElement = new XElement(doc.Root.Name); newElement.Add(doc.Root.Attributes()); newElement.Add(doc.Root.Elements().Where(e => !e.Name.LocalName.Equals("contentpackage", StringComparison.InvariantCultureIgnoreCase))); newElement.Add(baseDoc.Root.Elements().Where(e => e.Name.LocalName.Equals("contentpackage", StringComparison.InvariantCultureIgnoreCase))); XDocument newDoc = new XDocument(newElement); newDoc.Save(GameSettings.PlayerSavePath); sb.AppendLine("To prevent further startup errors, installed mods will be disabled the next time you launch the game."); sb.AppendLine("\n"); } } } catch { //welp i guess we couldn't reset the config! } if (exeHash?.Hash != null) { sb.AppendLine(exeHash.Hash); } sb.AppendLine("\n"); sb.AppendLine("Game version " + GameMain.Version + " (" + AssemblyInfo.BuildString + ", branch " + AssemblyInfo.GitBranch + ", revision " + AssemblyInfo.GitRevision + ")"); if (GameMain.Config != null) { sb.AppendLine("Graphics mode: " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight + " (" + GameMain.Config.WindowMode.ToString() + ")"); sb.AppendLine("VSync " + (GameMain.Config.VSyncEnabled ? "ON" : "OFF")); sb.AppendLine("Language: " + (GameMain.Config.Language ?? "none")); } if (GameMain.Config.AllEnabledPackages != null) { sb.AppendLine("Selected content packages: " + (!GameMain.Config.AllEnabledPackages.Any() ? "None" : string.Join(", ", GameMain.Config.AllEnabledPackages.Select(c => c.Name)))); } sb.AppendLine("Level seed: " + ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed)); sb.AppendLine("Loaded submarine: " + ((Submarine.MainSub == null) ? "None" : Submarine.MainSub.Info.Name + " (" + Submarine.MainSub.Info.MD5Hash + ")")); sb.AppendLine("Selected screen: " + (Screen.Selected == null ? "None" : Screen.Selected.ToString())); if (SteamManager.IsInitialized) { sb.AppendLine("SteamManager initialized"); } if (GameMain.Client != null) { sb.AppendLine("Client (" + (GameMain.Client.GameStarted ? "Round had started)" : "Round hadn't been started)")); } sb.AppendLine("\n"); sb.AppendLine("System info:"); sb.AppendLine(" Operating system: " + System.Environment.OSVersion + (System.Environment.Is64BitOperatingSystem ? " 64 bit" : " x86")); if (game == null) { sb.AppendLine(" Game not initialized"); } else { if (game.GraphicsDevice == null) { sb.AppendLine(" Graphics device not set"); } else { if (game.GraphicsDevice.Adapter == null) { sb.AppendLine(" Graphics adapter not set"); } else { sb.AppendLine(" GPU name: " + game.GraphicsDevice.Adapter.Description); sb.AppendLine(" Display mode: " + game.GraphicsDevice.Adapter.CurrentDisplayMode); } sb.AppendLine(" GPU status: " + game.GraphicsDevice.GraphicsDeviceStatus); } } sb.AppendLine("\n"); sb.AppendLine("Exception: " + exception.Message + " (" + exception.GetType().ToString() + ")"); #if WINDOWS if (exception is SharpDXException sharpDxException && ((uint)sharpDxException.HResult) == 0x887A0005) { var dxDevice = (SharpDX.Direct3D11.Device)game.GraphicsDevice.Handle; sb.AppendLine("Device removed reason: " + dxDevice.DeviceRemovedReason.ToString()); } #endif if (exception.TargetSite != null) { sb.AppendLine("Target site: " + exception.TargetSite.ToString()); } if (exception.StackTrace != null) { sb.AppendLine("Stack trace: "); sb.AppendLine(exception.StackTrace.CleanupStackTrace()); sb.AppendLine("\n"); } if (exception.InnerException != null) { sb.AppendLine("InnerException: " + exception.InnerException.Message); if (exception.InnerException.TargetSite != null) { sb.AppendLine("Target site: " + exception.InnerException.TargetSite.ToString()); } if (exception.InnerException.StackTrace != null) { sb.AppendLine("Stack trace: "); sb.AppendLine(exception.InnerException.StackTrace.CleanupStackTrace()); } } sb.AppendLine("Last debug messages:"); for (int i = DebugConsole.Messages.Count - 1; i >= 0; i--) { sb.AppendLine("[" + DebugConsole.Messages[i].Time + "] " + DebugConsole.Messages[i].Text); } string crashReport = sb.ToString(); File.WriteAllText(filePath, crashReport); if (GameSettings.SaveDebugConsoleLogs) { DebugConsole.SaveLogs(); } if (GameSettings.SendUserStatistics) { CrashMessageBox("A crash report (\"" + filePath + "\") was saved in the root folder of the game and sent to the developers.", filePath); GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport); GameAnalytics.OnQuit(); } else { CrashMessageBox("A crash report (\"" + filePath + "\") was saved in the root folder of the game. The error was not sent to the developers because user statistics have been disabled, but" + " if you'd like to help fix this bug, you may post it on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/", filePath); } }
public GameMain(string[] args) { Content.RootDirectory = "Content"; #if DEBUG && WINDOWS GraphicsAdapter.UseDebugLayers = true; #endif GraphicsDeviceManager = new GraphicsDeviceManager(this) { IsFullScreen = false, GraphicsProfile = GfxProfile }; GraphicsDeviceManager.ApplyChanges(); Window.Title = "Barotrauma"; Instance = this; if (!Directory.Exists(Content.RootDirectory)) { throw new Exception("Content folder not found. If you are trying to compile the game from the source code and own a legal copy of the game, you can copy the Content folder from the game's files to BarotraumaShared/Content."); } Config = new GameSettings(); Md5Hash.LoadCache(); ConsoleArguments = args; ConnectName = null; ConnectEndpoint = null; ConnectLobby = 0; try { ToolBox.ParseConnectCommand(ConsoleArguments, out ConnectName, out ConnectEndpoint, out ConnectLobby); } catch (IndexOutOfRangeException e) { DebugConsole.ThrowError($"Failed to parse console arguments ({string.Join(' ', ConsoleArguments)})", e); ConnectName = null; ConnectEndpoint = null; ConnectLobby = 0; } GUI.KeyboardDispatcher = new EventInput.KeyboardDispatcher(Window); PerformanceCounter = new PerformanceCounter(); IsFixedTimeStep = false; GameMain.ResetFrameTime(); fixedTime = new GameTime(); World = new World(new Vector2(0, -9.82f)); FarseerPhysics.Settings.AllowSleep = true; FarseerPhysics.Settings.ContinuousPhysics = false; FarseerPhysics.Settings.VelocityIterations = 1; FarseerPhysics.Settings.PositionIterations = 1; MainThread = Thread.CurrentThread; }
static void CrashDump(GameMain game, string filePath, Exception exception) { int existingFiles = 0; string originalFilePath = filePath; while (File.Exists(filePath)) { existingFiles++; filePath = Path.GetFileNameWithoutExtension(originalFilePath) + " (" + (existingFiles + 1) + ")" + Path.GetExtension(originalFilePath); } StreamWriter sw = new StreamWriter(filePath); StringBuilder sb = new StringBuilder(); sb.AppendLine("Barotrauma Dedicated Server crash report (generated on " + DateTime.Now + ")"); sb.AppendLine("\n"); sb.AppendLine("Barotrauma seems to have crashed. Sorry for the inconvenience! "); sb.AppendLine("\n"); #if DEBUG sb.AppendLine("Game version " + GameMain.Version + " (debug build)"); #else sb.AppendLine("Game version " + GameMain.Version); #endif sb.AppendLine("Selected content packages: " + (!GameMain.SelectedPackages.Any() ? "None" : string.Join(", ", GameMain.SelectedPackages.Select(c => c.Name)))); sb.AppendLine("Level seed: " + ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed)); sb.AppendLine("Loaded submarine: " + ((Submarine.MainSub == null) ? "None" : Submarine.MainSub.Name + " (" + Submarine.MainSub.MD5Hash + ")")); sb.AppendLine("Selected screen: " + (Screen.Selected == null ? "None" : Screen.Selected.ToString())); if (GameMain.Server != null) { sb.AppendLine("Server (" + (GameMain.Server.GameStarted ? "Round had started)" : "Round hadn't been started)")); } sb.AppendLine("\n"); sb.AppendLine("System info:"); sb.AppendLine(" Operating system: " + System.Environment.OSVersion + (System.Environment.Is64BitOperatingSystem ? " 64 bit" : " x86")); sb.AppendLine("\n"); sb.AppendLine("Exception: " + exception.Message); sb.AppendLine("Target site: " + exception.TargetSite.ToString()); sb.AppendLine("Stack trace: "); sb.AppendLine(exception.StackTrace); sb.AppendLine("\n"); if (exception.InnerException != null) { sb.AppendLine("InnerException: " + exception.InnerException.Message); if (exception.InnerException.TargetSite != null) { sb.AppendLine("Target site: " + exception.InnerException.TargetSite.ToString()); } sb.AppendLine("Stack trace: "); sb.AppendLine(exception.InnerException.StackTrace); } sb.AppendLine("Last debug messages:"); for (int i = DebugConsole.Messages.Count - 1; i > 0 && i > DebugConsole.Messages.Count - 15; i--) { sb.AppendLine(" " + DebugConsole.Messages[i].Time + " - " + DebugConsole.Messages[i].Text); } string crashReport = sb.ToString(); Console.ForegroundColor = ConsoleColor.Red; Console.Write(crashReport); sw.WriteLine(sb.ToString()); sw.Close(); if (GameSettings.SendUserStatistics) { GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport); GameAnalytics.OnQuit(); Console.Write("A crash report (\"crashreport.log\") was saved in the root folder of the game and sent to the developers."); } else { Console.Write("A crash report(\"crashreport.log\") was saved in the root folder of the game. The error was not sent to the developers because user statistics have been disabled, but" + " if you'd like to help fix this bug, you may post it on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/"); } SteamManager.ShutDown(); }
public void StartRound(Level level, bool mirrorLevel = false) { //make sure no status effects have been carried on from the next round //(they should be stopped in EndRound, this is a safeguard against cases where the round is ended ungracefully) StatusEffect.StopAll(); #if CLIENT GameMain.LightManager.LosEnabled = GameMain.Client == null || GameMain.Client.CharacterInfo != null; if (GameMain.Client == null) { GameMain.LightManager.LosMode = GameMain.Config.LosMode; } #endif this.Level = level; if (SubmarineInfo == null) { DebugConsole.ThrowError("Couldn't start game session, submarine not selected."); return; } if (SubmarineInfo.IsFileCorrupted) { DebugConsole.ThrowError("Couldn't start game session, submarine file corrupted."); return; } Submarine.Unload(); Submarine = Submarine.MainSub = new Submarine(SubmarineInfo); Submarine.MainSub = Submarine; if (GameMode.Mission != null && GameMode.Mission.TeamCount > 1 && Submarine.MainSubs[1] == null) { Submarine.MainSubs[1] = new Submarine(SubmarineInfo, true); } if (level != null) { level.Generate(mirrorLevel); if (level.StartOutpost != null) { //start by placing the sub below the outpost Rectangle outpostBorders = Level.Loaded.StartOutpost.GetDockedBorders(); Rectangle subBorders = Submarine.GetDockedBorders(); Vector2 startOutpostSize = Vector2.Zero; if (Level.Loaded.StartOutpost != null) { startOutpostSize = Level.Loaded.StartOutpost.Borders.Size.ToVector2(); } Submarine.SetPosition( Level.Loaded.StartOutpost.WorldPosition - new Vector2(0.0f, outpostBorders.Height / 2 + subBorders.Height / 2)); //find the port that's the nearest to the outpost and dock if one is found float closestDistance = 0.0f; DockingPort myPort = null, outPostPort = null; foreach (DockingPort port in DockingPort.List) { if (port.IsHorizontal || port.Docked) { continue; } if (port.Item.Submarine == level.StartOutpost) { outPostPort = port; continue; } if (port.Item.Submarine != Submarine) { continue; } //the submarine port has to be at the top of the sub if (port.Item.WorldPosition.Y < Submarine.WorldPosition.Y) { continue; } float dist = Vector2.DistanceSquared(port.Item.WorldPosition, level.StartOutpost.WorldPosition); if (myPort == null || dist < closestDistance || (port.MainDockingPort && !myPort.MainDockingPort)) { myPort = port; closestDistance = dist; } } if (myPort != null && outPostPort != null) { Vector2 portDiff = myPort.Item.WorldPosition - Submarine.WorldPosition; Submarine.SetPosition((outPostPort.Item.WorldPosition - portDiff) - Vector2.UnitY * outPostPort.DockedDistance); myPort.Dock(outPostPort); myPort.Lock(true); } } else { Submarine.SetPosition(Submarine.FindSpawnPos(level.StartPosition)); } } foreach (var sub in Submarine.Loaded) { if (sub.Info.IsOutpost) { sub.DisableObstructedWayPoints(); } } Entity.Spawner = new EntitySpawner(); if (GameMode.Mission != null) { Mission = GameMode.Mission; } if (GameMode != null) { GameMode.Start(); } if (GameMode.Mission != null) { int prevEntityCount = Entity.GetEntityList().Count; Mission.Start(Level.Loaded); if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient && Entity.GetEntityList().Count != prevEntityCount) { DebugConsole.ThrowError( "Entity count has changed after starting a mission as a client. " + "The clients should not instantiate entities themselves when starting the mission," + " but instead the server should inform the client of the spawned entities using Mission.ServerWriteInitial."); } } EventManager?.StartRound(level); SteamAchievementManager.OnStartRound(); if (GameMode != null) { GameMode.ShowStartMessage(); if (GameMain.NetworkMember == null) { //only place items and corpses here in single player //the server does this after loading the respawn shuttle Level?.SpawnCorpses(); AutoItemPlacer.PlaceIfNeeded(GameMode); } if (GameMode is MultiPlayerCampaign mpCampaign && GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) { mpCampaign.CargoManager.CreateItems(); } } GameAnalyticsManager.AddDesignEvent("Submarine:" + Submarine.Info.Name); GameAnalyticsManager.AddDesignEvent("Level", ToolBox.StringToInt(level?.Seed ?? "[NO_LEVEL]")); GameAnalyticsManager.AddProgressionEvent(GameAnalyticsSDK.Net.EGAProgressionStatus.Start, GameMode.Preset.Identifier, (Mission == null ? "None" : Mission.GetType().ToString())); #if CLIENT if (GameMode is SinglePlayerCampaign) { SteamAchievementManager.OnBiomeDiscovered(level.Biome); } if (!(GameMode is SubTestMode)) { RoundSummary = new RoundSummary(this); } GameMain.GameScreen.ColorFade(Color.Black, Color.TransparentBlack, 5.0f); if (!(GameMode is TutorialMode) && !(GameMode is SubTestMode)) { GUI.AddMessage("", Color.Transparent, 3.0f, playSound: false); GUI.AddMessage(level.Biome.DisplayName, Color.Lerp(Color.CadetBlue, Color.DarkRed, level.Difficulty / 100.0f), 5.0f, playSound: false); GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Destination"), EndLocation.Name), Color.CadetBlue, playSound: false); GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Mission"), (Mission == null ? TextManager.Get("None") : Mission.Name)), Color.CadetBlue, playSound: false); } #endif RoundStartTime = Timing.TotalTime; GameMain.ResetFrameTime(); }
public static void ExecuteCommand(string command, GameMain game) { if (string.IsNullOrWhiteSpace(command)) { return; } string[] commands = command.Split(' '); if (!commands[0].ToLowerInvariant().Equals("admin")) { NewMessage(textBox.Text, Color.White); } #if !DEBUG if (GameMain.Client != null && !IsCommandPermitted(commands[0].ToLowerInvariant(), GameMain.Client)) { ThrowError("You're not permitted to use the command \"" + commands[0].ToLowerInvariant() + "\"!"); return; } #endif switch (commands[0].ToLowerInvariant()) { case "help": NewMessage("menu: go to main menu", Color.Cyan); NewMessage("game: enter the \"game screen\"", Color.Cyan); NewMessage("edit: switch to submarine editor", Color.Cyan); NewMessage("edit [submarine name]: load a submarine and switch to submarine editor", Color.Cyan); NewMessage("load [submarine name]: load a submarine", Color.Cyan); NewMessage("save [submarine name]: save the current submarine using the specified name", Color.Cyan); NewMessage(" ", Color.Cyan); NewMessage("spawn [creaturename] [near/inside/outside]: spawn a creature at a random spawnpoint (use the second parameter to only select spawnpoints near/inside/outside the submarine)", Color.Cyan); NewMessage("spawnitem [itemname] [cursor/inventory]: spawn an item at the position of the cursor, in the inventory of the controlled character or at a random spawnpoint if the last parameter is omitted", Color.Cyan); NewMessage(" ", Color.Cyan); NewMessage("lights: disable lighting", Color.Cyan); NewMessage("los: disable the line of sight effect", Color.Cyan); NewMessage("freecam: detach the camera from the controlled character", Color.Cyan); NewMessage("control [character name]: start controlling the specified character", Color.Cyan); NewMessage(" ", Color.Cyan); NewMessage("water: allows adding water into rooms or removing it by holding the left/right mouse buttons", Color.Cyan); NewMessage("fire: allows putting up fires by left clicking", Color.Cyan); NewMessage(" ", Color.Cyan); NewMessage("teleport: teleport the controlled character to the position of the cursor", Color.Cyan); NewMessage("teleport [character name]: teleport the specified character to the position of the cursor", Color.Cyan); NewMessage("heal: restore the controlled character to full health", Color.Cyan); NewMessage("heal [character name]: restore the specified character to full health", Color.Cyan); NewMessage("revive: bring the controlled character back from the dead", Color.Cyan); NewMessage("revive [character name]: bring the specified character back from the dead", Color.Cyan); NewMessage("killmonsters: immediately kills all AI-controlled enemies in the level", Color.Cyan); NewMessage(" ", Color.Cyan); NewMessage("fixwalls: fixes all the walls", Color.Cyan); NewMessage("fixitems: fixes every item/device in the sub", Color.Cyan); NewMessage("oxygen: replenishes the oxygen in every room to 100%", Color.Cyan); NewMessage("power [amount]: immediately sets the temperature of the reactor to the specified value", Color.Cyan); NewMessage(" ", Color.Cyan); NewMessage("kick [name]: kick a player out from the server", Color.Cyan); NewMessage("ban [name]: kick and ban the player from the server", Color.Cyan); NewMessage("banip [IP address]: ban the IP address from the server", Color.Cyan); NewMessage("debugdraw: toggles the \"debug draw mode\"", Color.Cyan); NewMessage("netstats: toggles the visibility of the network statistics panel", Color.Cyan); break; case "createfilelist": UpdaterUtil.SaveFileList("filelist.xml"); break; case "spawn": case "spawncharacter": if (commands.Length == 1) { return; } Character spawnedCharacter = null; Vector2 spawnPosition = Vector2.Zero; WayPoint spawnPoint = null; if (commands.Length > 2) { switch (commands[2].ToLowerInvariant()) { case "inside": spawnPoint = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub); break; case "outside": spawnPoint = WayPoint.GetRandom(SpawnType.Enemy); break; case "near": case "close": float closestDist = -1.0f; foreach (WayPoint wp in WayPoint.WayPointList) { if (wp.Submarine != null) { continue; } //don't spawn inside hulls if (Hull.FindHull(wp.WorldPosition, null) != null) { continue; } float dist = Vector2.Distance(wp.WorldPosition, GameMain.GameScreen.Cam.WorldViewCenter); if (closestDist < 0.0f || dist < closestDist) { spawnPoint = wp; closestDist = dist; } } break; case "cursor": spawnPosition = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition); break; default: spawnPoint = WayPoint.GetRandom(commands[1].ToLowerInvariant() == "human" ? SpawnType.Human : SpawnType.Enemy); break; } } else { spawnPoint = WayPoint.GetRandom(commands[1].ToLowerInvariant() == "human" ? SpawnType.Human : SpawnType.Enemy); } if (string.IsNullOrWhiteSpace(commands[1])) { return; } if (spawnPoint != null) { spawnPosition = spawnPoint.WorldPosition; } if (commands[1].ToLowerInvariant() == "human") { spawnedCharacter = Character.Create(Character.HumanConfigFile, spawnPosition); if (GameMain.GameSession != null) { SinglePlayerMode mode = GameMain.GameSession.gameMode as SinglePlayerMode; if (mode != null) { Character.Controlled = spawnedCharacter; GameMain.GameSession.CrewManager.AddCharacter(Character.Controlled); GameMain.GameSession.CrewManager.SelectCharacter(null, Character.Controlled); } } } else { spawnedCharacter = Character.Create( "Content/Characters/" + commands[1].First().ToString().ToUpper() + commands[1].Substring(1) + "/" + commands[1].ToLower() + ".xml", spawnPosition); } break; case "spawnitem": if (commands.Length < 2) { return; } Vector2? spawnPos = null; Inventory spawnInventory = null; int extraParams = 0; switch (commands.Last()) { case "cursor": extraParams = 1; spawnPos = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition); break; case "inventory": extraParams = 1; spawnInventory = Character.Controlled == null ? null : Character.Controlled.Inventory; break; default: extraParams = 0; break; } string itemName = string.Join(" ", commands.Skip(1).Take(commands.Length - extraParams - 1)).ToLowerInvariant(); var itemPrefab = MapEntityPrefab.list.Find(ip => ip.Name.ToLowerInvariant() == itemName) as ItemPrefab; if (itemPrefab == null) { ThrowError("Item \"" + itemName + "\" not found!"); return; } if (spawnPos == null && spawnInventory == null) { var wp = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub); spawnPos = wp == null ? Vector2.Zero : wp.WorldPosition; } if (spawnPos != null) { Item.Spawner.AddToSpawnQueue(itemPrefab, (Vector2)spawnPos); } else if (spawnInventory != null) { Item.Spawner.AddToSpawnQueue(itemPrefab, spawnInventory); } break; case "disablecrewai": HumanAIController.DisableCrewAI = !HumanAIController.DisableCrewAI; break; case "enablecrewai": HumanAIController.DisableCrewAI = false; break; /*case "admin": * if (commands.Length < 2) break; * * if (GameMain.Server != null) * { * GameMain.Server.AdminAuthPass = commands[1]; * * } * else if (GameMain.Client != null) * { * GameMain.Client.RequestAdminAuth(commands[1]); * } * break;*/ case "kick": if (GameMain.NetworkMember == null || commands.Length < 2) { break; } GameMain.NetworkMember.KickPlayer(string.Join(" ", commands.Skip(1)), false); break; case "ban": if (GameMain.NetworkMember == null || commands.Length < 2) { break; } GameMain.NetworkMember.KickPlayer(string.Join(" ", commands.Skip(1)), true); break; case "banip": { if (GameMain.Server == null || commands.Length < 2) { break; } var client = GameMain.Server.ConnectedClients.Find(c => c.Connection.RemoteEndPoint.Address.ToString() == commands[1]); if (client == null) { GameMain.Server.BanList.BanPlayer("Unnamed", commands[1]); } else { GameMain.Server.KickClient(client, true); } } break; case "startclient": if (commands.Length == 1) { return; } if (GameMain.Client == null) { GameMain.NetworkMember = new GameClient("Name"); GameMain.Client.ConnectToServer(commands[1]); } break; case "mainmenuscreen": case "mainmenu": case "menu": GameMain.GameSession = null; List <Character> characters = new List <Character>(Character.CharacterList); foreach (Character c in characters) { c.Remove(); } GameMain.MainMenuScreen.Select(); break; case "gamescreen": case "game": GameMain.GameScreen.Select(); break; case "editmapscreen": case "editmap": case "edit": if (commands.Length > 1) { Submarine.Load(string.Join(" ", commands.Skip(1)), true); } GameMain.EditMapScreen.Select(); break; case "test": Submarine.Load("aegir mark ii", true); GameMain.DebugDraw = true; GameMain.LightManager.LosEnabled = false; GameMain.EditMapScreen.Select(); break; case "editcharacter": case "editchar": GameMain.EditCharacterScreen.Select(); break; case "controlcharacter": case "control": { if (commands.Length < 2) { break; } var character = FindMatchingCharacter(commands, true); if (character != null) { Character.Controlled = character; } } break; case "setclientcharacter": { if (GameMain.Server == null) { break; } int separatorIndex = Array.IndexOf(commands, ";"); if (separatorIndex == -1 || commands.Length < 4) { ThrowError("Invalid parameters. The command should be formatted as \"setclientcharacter [client] ; [character]\""); break; } string[] commandsLeft = commands.Take(separatorIndex).ToArray(); string[] commandsRight = commands.Skip(separatorIndex).ToArray(); string clientName = String.Join(" ", commandsLeft.Skip(1)); var client = GameMain.Server.ConnectedClients.Find(c => c.name == clientName); if (client == null) { ThrowError("Client \"" + clientName + "\" not found."); } var character = FindMatchingCharacter(commandsRight, false); GameMain.Server.SetClientCharacter(client, character); } break; case "teleportcharacter": case "teleport": var tpCharacter = FindMatchingCharacter(commands, false); if (commands.Length < 2) { tpCharacter = Character.Controlled; } if (tpCharacter != null) { var cam = GameMain.GameScreen.Cam; tpCharacter.AnimController.CurrentHull = null; tpCharacter.Submarine = null; tpCharacter.AnimController.SetPosition(ConvertUnits.ToSimUnits(cam.ScreenToWorld(PlayerInput.MousePosition))); tpCharacter.AnimController.FindHull(cam.ScreenToWorld(PlayerInput.MousePosition), true); } break; case "godmode": if (Submarine.MainSub == null) { return; } Submarine.MainSub.GodMode = !Submarine.MainSub.GodMode; break; case "lockx": Submarine.LockX = !Submarine.LockX; break; case "locky": Submarine.LockY = !Submarine.LockY; break; case "dumpids": try { int count = commands.Length < 2 ? 10 : int.Parse(commands[1]); Entity.DumpIds(count); } catch { return; } break; case "heal": Character healedCharacter = null; if (commands.Length == 1) { healedCharacter = Character.Controlled; } else { healedCharacter = FindMatchingCharacter(commands); } if (healedCharacter != null) { healedCharacter.AddDamage(CauseOfDeath.Damage, -healedCharacter.MaxHealth, null); healedCharacter.Oxygen = 100.0f; healedCharacter.Bleeding = 0.0f; healedCharacter.Stun = 0.0f; } break; case "revive": Character revivedCharacter = null; if (commands.Length == 1) { revivedCharacter = Character.Controlled; } else { revivedCharacter = FindMatchingCharacter(commands); } if (revivedCharacter != null) { revivedCharacter.Revive(false); if (GameMain.Server != null) { foreach (Client c in GameMain.Server.ConnectedClients) { if (c.Character != revivedCharacter) { continue; } //clients stop controlling the character when it dies, force control back GameMain.Server.SetClientCharacter(c, revivedCharacter); break; } } } break; case "freeze": if (Character.Controlled != null) { Character.Controlled.AnimController.Frozen = !Character.Controlled.AnimController.Frozen; } break; case "freecamera": case "freecam": Character.Controlled = null; GameMain.GameScreen.Cam.TargetPos = Vector2.Zero; break; case "editwater": case "water": if (GameMain.Client == null) { Hull.EditWater = !Hull.EditWater; } break; case "fire": if (GameMain.Client == null) { Hull.EditFire = !Hull.EditFire; } break; case "fixitems": foreach (Item it in Item.ItemList) { it.Condition = 100.0f; } break; case "fixhull": case "fixwalls": foreach (Structure w in Structure.WallList) { for (int i = 0; i < w.SectionCount; i++) { w.AddDamage(i, -100000.0f); } } break; case "power": Item reactorItem = Item.ItemList.Find(i => i.GetComponent <Reactor>() != null); if (reactorItem == null) { return; } float power = 5000.0f; if (commands.Length > 1) { float.TryParse(commands[1], out power); } var reactor = reactorItem.GetComponent <Reactor>(); reactor.ShutDownTemp = power == 0 ? 0 : 7000.0f; reactor.AutoTemp = true; reactor.Temperature = power; if (GameMain.Server != null) { reactorItem.CreateServerEvent(reactor); } break; case "shake": GameMain.GameScreen.Cam.Shake = 10.0f; break; case "losenabled": case "los": case "drawlos": GameMain.LightManager.LosEnabled = !GameMain.LightManager.LosEnabled; break; case "lighting": case "lightingenabled": case "light": case "lights": GameMain.LightManager.LightingEnabled = !GameMain.LightManager.LightingEnabled; break; case "oxygen": case "air": foreach (Hull hull in Hull.hullList) { hull.OxygenPercentage = 100.0f; } break; case "tutorial": TutorialMode.StartTutorial(Tutorials.TutorialType.TutorialTypes[0]); break; case "editortutorial": GameMain.EditMapScreen.Select(); GameMain.EditMapScreen.StartTutorial(); break; case "lobbyscreen": case "lobby": GameMain.LobbyScreen.Select(); break; case "savemap": case "savesub": case "save": if (commands.Length < 2) { break; } if (GameMain.EditMapScreen.CharacterMode) { GameMain.EditMapScreen.ToggleCharacterMode(); } string fileName = string.Join(" ", commands.Skip(1)); if (fileName.Contains("../")) { DebugConsole.ThrowError("Illegal symbols in filename (../)"); return; } if (Submarine.SaveCurrent(System.IO.Path.Combine(Submarine.SavePath, fileName + ".sub"))) { NewMessage("Sub saved", Color.Green); //Submarine.Loaded.First().CheckForErrors(); } break; case "loadmap": case "loadsub": case "load": if (commands.Length < 2) { break; } Submarine.Load(string.Join(" ", commands.Skip(1)), true); break; case "cleansub": for (int i = MapEntity.mapEntityList.Count - 1; i >= 0; i--) { MapEntity me = MapEntity.mapEntityList[i]; if (me.SimPosition.Length() > 2000.0f) { DebugConsole.NewMessage("Removed " + me.Name + " (simposition " + me.SimPosition + ")", Color.Orange); MapEntity.mapEntityList.RemoveAt(i); } else if (me.MoveWithLevel) { DebugConsole.NewMessage("Removed " + me.Name + " (MoveWithLevel==true)", Color.Orange); MapEntity.mapEntityList.RemoveAt(i); } else if (me is Item) { Item item = me as Item; var wire = item.GetComponent <Wire>(); if (wire == null) { continue; } if (wire.GetNodes().Count > 0 && !wire.Connections.Any(c => c != null)) { wire.Item.Drop(null); DebugConsole.NewMessage("Dropped wire (ID: " + wire.Item.ID + ") - attached on wall but no connections found", Color.Orange); } } } break; case "messagebox": if (commands.Length < 3) { break; } new GUIMessageBox(commands[1], commands[2]); break; case "debugdraw": GameMain.DebugDraw = !GameMain.DebugDraw; break; case "disablehud": case "hud": GUI.DisableHUD = !GUI.DisableHUD; GameMain.Instance.IsMouseVisible = !GameMain.Instance.IsMouseVisible; break; case "followsub": Camera.FollowSub = !Camera.FollowSub; break; case "drawaitargets": case "showaitargets": AITarget.ShowAITargets = !AITarget.ShowAITargets; break; case "killmonsters": foreach (Character c in Character.CharacterList) { if (!(c.AIController is EnemyAIController)) { continue; } c.AddDamage(CauseOfDeath.Damage, 10000.0f, null); } break; case "netstats": if (GameMain.Server == null) { return; } GameMain.Server.ShowNetStats = !GameMain.Server.ShowNetStats; break; #if DEBUG case "spamevents": foreach (Item item in Item.ItemList) { for (int i = 0; i < item.components.Count; i++) { if (item.components[i] is IServerSerializable) { GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, i }); } var itemContainer = item.GetComponent <ItemContainer>(); if (itemContainer != null) { GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.InventoryState }); } GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.Status }); item.NeedsPositionUpdate = true; } } foreach (Character c in Character.CharacterList) { GameMain.Server.CreateEntityEvent(c, new object[] { NetEntityEvent.Type.Status }); } foreach (Structure wall in Structure.WallList) { GameMain.Server.CreateEntityEvent(wall); } break; case "spamchatmessages": int msgCount = 1000; if (commands.Length > 1) { int.TryParse(commands[1], out msgCount); } int msgLength = 50; if (commands.Length > 2) { int.TryParse(commands[2], out msgLength); } for (int i = 0; i < msgCount; i++) { if (GameMain.Server != null) { GameMain.Server.SendChatMessage(ToolBox.RandomSeed(msgLength), ChatMessageType.Default); } else { GameMain.Client.SendChatMessage(ToolBox.RandomSeed(msgLength)); } } break; #endif case "cleanbuild": GameMain.Config.MusicVolume = 0.5f; GameMain.Config.SoundVolume = 0.5f; DebugConsole.NewMessage("Music and sound volume set to 0.5", Color.Green); GameMain.Config.GraphicsWidth = 0; GameMain.Config.GraphicsHeight = 0; GameMain.Config.WindowMode = WindowMode.Fullscreen; DebugConsole.NewMessage("Resolution set to 0 x 0 (screen resolution will be used)", Color.Green); DebugConsole.NewMessage("Fullscreen enabled", Color.Green); GameSettings.VerboseLogging = false; if (GameMain.Config.MasterServerUrl != "http://www.undertowgames.com/baromaster") { DebugConsole.ThrowError("MasterServerUrl \"" + GameMain.Config.MasterServerUrl + "\"!"); } GameMain.Config.Save("config.xml"); var saveFiles = System.IO.Directory.GetFiles(SaveUtil.SaveFolder); foreach (string saveFile in saveFiles) { System.IO.File.Delete(saveFile); DebugConsole.NewMessage("Deleted " + saveFile, Color.Green); } if (System.IO.Directory.Exists(System.IO.Path.Combine(SaveUtil.SaveFolder, "temp"))) { System.IO.Directory.Delete(System.IO.Path.Combine(SaveUtil.SaveFolder, "temp"), true); DebugConsole.NewMessage("Deleted temp save folder", Color.Green); } if (System.IO.Directory.Exists(ServerLog.SavePath)) { var logFiles = System.IO.Directory.GetFiles(ServerLog.SavePath); foreach (string logFile in logFiles) { System.IO.File.Delete(logFile); DebugConsole.NewMessage("Deleted " + logFile, Color.Green); } } if (System.IO.File.Exists("filelist.xml")) { System.IO.File.Delete("filelist.xml"); DebugConsole.NewMessage("Deleted filelist", Color.Green); } if (System.IO.File.Exists("Submarines/TutorialSub.sub")) { System.IO.File.Delete("Submarines/TutorialSub.sub"); DebugConsole.NewMessage("Deleted TutorialSub from the submarine folder", Color.Green); } if (System.IO.File.Exists(GameServer.SettingsFile)) { System.IO.File.Delete(GameServer.SettingsFile); DebugConsole.NewMessage("Deleted server settings", Color.Green); } if (System.IO.File.Exists(GameServer.ClientPermissionsFile)) { System.IO.File.Delete(GameServer.ClientPermissionsFile); DebugConsole.NewMessage("Deleted client permission file", Color.Green); } if (System.IO.File.Exists("crashreport.txt")) { System.IO.File.Delete("crashreport.txt"); DebugConsole.NewMessage("Deleted crashreport.txt", Color.Green); } if (!System.IO.File.Exists("Content/Map/TutorialSub.sub")) { DebugConsole.ThrowError("TutorialSub.sub not found!"); } break; default: NewMessage("Command not found", Color.Red); break; } }
public MainMenuScreen(GameMain game) { buttonsParent = new GUILayoutGroup(new RectTransform(new Vector2(0.15f, 0.5f), parent: Frame.RectTransform, anchor: Anchor.BottomLeft) { RelativeOffset = new Vector2(0, 0.1f), AbsoluteOffset = new Point(50, 0) }) { Stretch = true, RelativeSpacing = 0.02f }; //debug button for quickly starting a new round new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform, Anchor.TopCenter, Pivot.BottomCenter) { AbsoluteOffset = new Point(0, -40) }, "Quickstart (dev)", style: "GUIButtonLarge", color: Color.Red) { IgnoreLayoutGroups = true, OnClicked = (tb, userdata) => { Submarine selectedSub = null; string subName = GameMain.Config.QuickStartSubmarineName; if (!string.IsNullOrEmpty(subName)) { DebugConsole.NewMessage($"Loading the predefined quick start sub \"{subName}\"", Color.White); selectedSub = Submarine.SavedSubmarines.FirstOrDefault(s => s.Name.ToLower() == subName.ToLower()); if (selectedSub == null) { DebugConsole.NewMessage($"Cannot find a sub that matches the name \"{subName}\".", Color.Red); } } if (selectedSub == null) { DebugConsole.NewMessage("Loading a random sub.", Color.White); var subs = Submarine.SavedSubmarines.Where(s => !s.HasTag(SubmarineTag.Shuttle) && !s.HasTag(SubmarineTag.HideInMenus)); selectedSub = subs.ElementAt(Rand.Int(subs.Count())); } var gamesession = new GameSession( selectedSub, "Data/Saves/test.xml", GameModePreset.list.Find(gm => gm.Name == "SPSandbox"), missionPrefab: null); //(gamesession.GameMode as SinglePlayerCampaign).GenerateMap(ToolBox.RandomSeed(8)); gamesession.StartRound(ToolBox.RandomSeed(8)); GameMain.GameScreen.Select(); string[] jobIdentifiers = new string[] { "captain", "engineer", "mechanic" }; for (int i = 0; i < 3; i++) { var spawnPoint = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub); if (spawnPoint == null) { DebugConsole.ThrowError("No spawnpoints found in the selected submarine. Quickstart failed."); GameMain.MainMenuScreen.Select(); return(true); } var characterInfo = new CharacterInfo( Character.HumanConfigFile, jobPrefab: JobPrefab.List.Find(j => j.Identifier == jobIdentifiers[i])); if (characterInfo.Job == null) { DebugConsole.ThrowError("Failed to find the job \"" + jobIdentifiers[i] + "\"!"); } var newCharacter = Character.Create(Character.HumanConfigFile, spawnPoint.WorldPosition, ToolBox.RandomSeed(8), characterInfo); newCharacter.GiveJobItems(spawnPoint); gamesession.CrewManager.AddCharacter(newCharacter); Character.Controlled = newCharacter; } return(true); } }; var minButtonSize = new Point(120, 20); var maxButtonSize = new Point(240, 40); new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("TutorialButton"), style: "GUIButtonLarge") { UserData = Tab.Tutorials, OnClicked = SelectTab, Enabled = false }; new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), buttonsParent.RectTransform), style: null); //spacing new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("NewGameButton"), style: "GUIButtonLarge") { UserData = Tab.NewGame, OnClicked = SelectTab }; new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("LoadGameButton"), style: "GUIButtonLarge") { UserData = Tab.LoadGame, OnClicked = SelectTab }; new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), buttonsParent.RectTransform), style: null); //spacing new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("JoinServerButton"), style: "GUIButtonLarge") { OnClicked = JoinServerClicked }; new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("HostServerButton"), style: "GUIButtonLarge") { UserData = Tab.HostServer, OnClicked = SelectTab }; new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), buttonsParent.RectTransform), style: null); //spacing new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("SubEditorButton"), style: "GUIButtonLarge") { OnClicked = (btn, userdata) => { GameMain.SubEditorScreen.Select(); return(true); } }; new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("CharacterEditorButton"), style: "GUIButtonLarge") { OnClicked = (btn, userdata) => { Submarine.MainSub = null; GameMain.CharacterEditorScreen.Select(); return(true); } }; if (Steam.SteamManager.USE_STEAM) { steamWorkshopButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("SteamWorkshopButton"), style: "GUIButtonLarge") { Enabled = false, OnClicked = SteamWorkshopClicked }; } new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), buttonsParent.RectTransform), style: null); //spacing new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("SettingsButton"), style: "GUIButtonLarge") { UserData = Tab.Settings, OnClicked = SelectTab }; new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonsParent.RectTransform), TextManager.Get("QuitButton"), style: "GUIButtonLarge") { OnClicked = QuitClicked }; /* var buttons = GUI.CreateButtons(9, new Vector2(1, 0.04f), buttonsParent.RectTransform, anchor: Anchor.BottomLeft, * minSize: minButtonSize, maxSize: maxButtonSize, relativeSpacing: 0.005f, extraSpacing: i => i % 2 == 0 ? 20 : 0); * buttons.ForEach(b => b.Color *= 0.8f); * SetupButtons(buttons); * buttons.ForEach(b => b.TextBlock.SetTextPos());*/ var relativeSize = new Vector2(0.5f, 0.5f); var minSize = new Point(600, 400); var maxSize = new Point(900, 600); var anchor = Anchor.Center; var pivot = Pivot.Center; menuTabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length + 1]; menuTabs[(int)Tab.NewGame] = new GUIFrame(new RectTransform(relativeSize, Frame.RectTransform, anchor, pivot, minSize, maxSize)); var paddedNewGame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), menuTabs[(int)Tab.NewGame].RectTransform, Anchor.Center), style: null); menuTabs[(int)Tab.LoadGame] = new GUIFrame(new RectTransform(relativeSize, Frame.RectTransform, anchor, pivot, minSize, maxSize)); var paddedLoadGame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), menuTabs[(int)Tab.LoadGame].RectTransform, Anchor.Center), style: null); campaignSetupUI = new CampaignSetupUI(false, paddedNewGame, paddedLoadGame) { LoadGame = LoadGame, StartNewGame = StartGame }; var hostServerScale = new Vector2(0.7f, 1.0f); menuTabs[(int)Tab.HostServer] = new GUIFrame(new RectTransform( Vector2.Multiply(relativeSize, hostServerScale), Frame.RectTransform, anchor, pivot, minSize.Multiply(hostServerScale), maxSize.Multiply(hostServerScale))); CreateHostServerFields(); //---------------------------------------------------------------------- menuTabs[(int)Tab.Tutorials] = new GUIFrame(new RectTransform(relativeSize, Frame.RectTransform, anchor, pivot, minSize, maxSize)); //PLACEHOLDER var tutorialList = new GUIListBox( new RectTransform(new Vector2(0.95f, 0.85f), menuTabs[(int)Tab.Tutorials].RectTransform, Anchor.TopCenter) { RelativeOffset = new Vector2(0.0f, 0.1f) }, false, null, ""); foreach (Tutorial tutorial in Tutorial.Tutorials) { var tutorialText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), tutorialList.Content.RectTransform), tutorial.Name, textAlignment: Alignment.Center, font: GUI.LargeFont) { UserData = tutorial }; } tutorialList.OnSelected += (component, obj) => { TutorialMode.StartTutorial(obj as Tutorial); return(true); }; UpdateTutorialList(); this.game = game; }
static void CrashDump(GameMain game, string filePath, Exception exception) { DebugConsole.DequeueMessages(); StreamWriter sw = new StreamWriter(filePath); StringBuilder sb = new StringBuilder(); sb.AppendLine("Barotrauma Client crash report (generated on " + DateTime.Now + ")"); sb.AppendLine("\n"); sb.AppendLine("Barotrauma seems to have crashed. Sorry for the inconvenience! "); sb.AppendLine("\n"); #if DEBUG sb.AppendLine("Game version " + GameMain.Version + " NILMOD SERVER MODIFICATION" + " (debug build)"); #else sb.AppendLine("Game version " + GameMain.Version + " NILMOD SERVER MODIFICATION"); #endif sb.AppendLine("Nilmod version stamp: " + NilMod.NilModVersionDate); sb.AppendLine("Graphics mode: " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight + " (" + GameMain.Config.WindowMode.ToString() + ")"); sb.AppendLine("Selected content package: " + GameMain.SelectedPackage.Name); sb.AppendLine("Level seed: " + ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed)); sb.AppendLine("Loaded submarine: " + ((Submarine.MainSub == null) ? "None" : Submarine.MainSub.Name + " (" + Submarine.MainSub.MD5Hash + ")")); sb.AppendLine("Selected screen: " + (Screen.Selected == null ? "None" : Screen.Selected.ToString())); if (GameMain.GameSession != null) { if (GameMain.GameSession.GameMode != null) { sb.AppendLine("Gamemode: " + GameMain.GameSession.GameMode.Name); } if (GameMain.GameSession.Mission != null) { sb.AppendLine("Mission: " + GameMain.GameSession.Mission.Name); } } if (Character.CharacterList != null && Character.CharacterList.Count > 0) { sb.AppendLine("\n"); if (Character.CharacterList.FindAll(c => c.Removed).Count > 0) { sb.AppendLine("Removed character references detected, " + Character.CharacterList.Count + " Characters in list, " + Character.CharacterList.FindAll(c => c.Removed).Count + " Removed."); } int foundnullanimcontroller = 0; int foundnulllimbs = 0; int foundzerolengthlimbs = 0; for (int i = Character.CharacterList.Count - 1; i >= 0; i--) { if (Character.CharacterList[i].AnimController == null) { foundnullanimcontroller += 1; } else { if (Character.CharacterList[i].AnimController.Limbs == null) { foundnulllimbs += 1; } else if (Character.CharacterList[i].AnimController.Limbs.Length < 1) { foundzerolengthlimbs += 1; } } } if (foundnullanimcontroller > 0) { sb.AppendLine(foundnullanimcontroller + " Characters with null AnimControllers found."); } if (foundnulllimbs > 0) { sb.AppendLine(foundnulllimbs + " Characters with null limbs[] reference found."); } if (foundzerolengthlimbs > 0) { sb.AppendLine(foundzerolengthlimbs + " characters with 0 limbs found."); } } if (GameMain.Server != null) { sb.AppendLine("Server (" + (GameMain.Server.GameStarted ? "Round had started)" : "Round hadn't been started)")); } else if (GameMain.Client != null) { sb.AppendLine("Client (" + (GameMain.Client.GameStarted ? "Round had started)" : "Round hadn't been started)")); } sb.AppendLine("\n"); sb.AppendLine("System info:"); sb.AppendLine(" Operating system: " + System.Environment.OSVersion + (System.Environment.Is64BitOperatingSystem ? " 64 bit" : " x86")); if (game.GraphicsDevice == null) { sb.AppendLine(" Graphics device not set"); } else { if (game.GraphicsDevice.Adapter == null) { sb.AppendLine(" Graphics adapter not set"); } else { sb.AppendLine(" GPU name: " + game.GraphicsDevice.Adapter.Description); sb.AppendLine(" Display mode: " + game.GraphicsDevice.Adapter.CurrentDisplayMode); } sb.AppendLine(" GPU status: " + game.GraphicsDevice.GraphicsDeviceStatus); } #if LINUX if (GameMain.NilMod != null && GameMain.NilMod.CrashRestart) { sb.AppendLine("\n"); sb.AppendLine("Attempted restart of process using: " + System.Diagnostics.Process.Start(System.Reflection.Assembly.GetEntryAssembly().CodeBase + "\\Barotrauma NilEdit.exe")); sb.AppendLine("\n"); } #else if (GameMain.NilMod != null && GameMain.NilMod.CrashRestart) { sb.AppendLine("\n"); sb.AppendLine("Attempted restart of process using: " + Application.StartupPath + "\\Barotrauma NilEdit.exe"); sb.AppendLine("\n"); } #endif sb.AppendLine("\n"); sb.AppendLine("This was running NilMod Code!"); sb.AppendLine("\n"); sb.AppendLine("Exception: " + exception.Message); sb.AppendLine("Target site: " + exception.TargetSite.ToString()); sb.AppendLine("Stack trace: "); sb.AppendLine(exception.StackTrace); sb.AppendLine("\n"); sb.AppendLine("Last debug messages:"); if (game != null) { if (GameMain.NilMod != null) { if (GameMain.NilMod.DebugConsoleTimeStamp) { for (int i = DebugConsole.Messages.Count - 1; i > 0; i--) { sb.AppendLine(DebugConsole.Messages[i].Text); } } else { for (int i = DebugConsole.Messages.Count - 1; i > 0; i--) { sb.AppendLine("[" + DebugConsole.Messages[i].Time + "] " + DebugConsole.Messages[i].Text); } } } else { for (int i = DebugConsole.Messages.Count - 1; i > 0; i--) { sb.AppendLine("[" + DebugConsole.Messages[i].Time + "] " + DebugConsole.Messages[i].Text); } } } else { for (int i = DebugConsole.Messages.Count - 1; i > 0; i--) { sb.AppendLine("[" + DebugConsole.Messages[i].Time + "] " + DebugConsole.Messages[i].Text); } } string crashReport = sb.ToString(); sw.WriteLine(crashReport); sw.Close(); if (GameMain.NilMod != null) { if (GameMain.NilMod.CrashRestart && GameMain.NilMod.SuccesfulStart) { if (GameSettings.SaveDebugConsoleLogs) { DebugConsole.SaveLogs(); } if (GameSettings.SendUserStatistics) { GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport); GameAnalytics.OnStop(); } CrashRestart(null, exception); } else { if (GameSettings.SaveDebugConsoleLogs) { DebugConsole.SaveLogs(); } if (GameSettings.SendUserStatistics) { CrashMessageBox("A crash report (\"crashreport.log\") was saved in the root folder of the game and sent to the developers."); GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport); GameAnalytics.OnStop(); } else { CrashMessageBox("A crash report (\"crashreport.log\") was saved in the root folder of the game." + Environment.NewLine + "If you'd like to help fix this bug, please post the report on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/" + Environment.NewLine + "Alternatively, If you believe this to be a mod bug, please post the report on the forum topic or the mods GitHub issue tracker: https://github.com/NilanthAnimosus/Barotrauma---Nilanths-Edits/issues"); } } } else { if (GameSettings.SaveDebugConsoleLogs) { DebugConsole.SaveLogs(); } CrashMessageBox("A crash report (\"crashreport.log\") was saved in the root folder of the game." + Environment.NewLine + "If you'd like to help fix this bug, please post the report on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/" + Environment.NewLine + "Alternatively, If you believe this to be a mod bug, please post the report on the forum topic or the mods GitHub issue tracker: https://github.com/NilanthAnimosus/Barotrauma---Nilanths-Edits/issues"); } }
public void StartRound(Level level, bool reloadSub = true, bool loadSecondSub = false, bool mirrorLevel = false) { #if CLIENT GameMain.LightManager.LosEnabled = GameMain.Client == null || GameMain.Client.CharacterInfo != null; if (GameMain.Client == null) { GameMain.LightManager.LosMode = GameMain.Config.LosMode; } #endif this.Level = level; if (Submarine == null) { DebugConsole.ThrowError("Couldn't start game session, submarine not selected"); return; } if (reloadSub || Submarine.MainSub != Submarine) { Submarine.Load(true); } Submarine.MainSub = Submarine; if (loadSecondSub) { if (Submarine.MainSubs[1] == null) { Submarine.MainSubs[1] = new Submarine(Submarine.MainSub.FilePath, Submarine.MainSub.MD5Hash.Hash, true); Submarine.MainSubs[1].Load(false); } else if (reloadSub) { Submarine.MainSubs[1].Load(false); } } if (level != null) { level.Generate(mirrorLevel); if (level.StartOutpost != null) { //start by placing the sub below the outpost Rectangle outpostBorders = Level.Loaded.StartOutpost.GetDockedBorders(); Rectangle subBorders = Submarine.GetDockedBorders(); Vector2 startOutpostSize = Vector2.Zero; if (Level.Loaded.StartOutpost != null) { startOutpostSize = Level.Loaded.StartOutpost.Borders.Size.ToVector2(); } Submarine.SetPosition( Level.Loaded.StartOutpost.WorldPosition - new Vector2(0.0f, outpostBorders.Height / 2 + subBorders.Height / 2)); //find the port that's the nearest to the outpost and dock if one is found float closestDistance = 0.0f; DockingPort myPort = null, outPostPort = null; foreach (DockingPort port in DockingPort.List) { if (port.IsHorizontal || port.Docked) { continue; } if (port.Item.Submarine == level.StartOutpost) { outPostPort = port; continue; } if (port.Item.Submarine != Submarine) { continue; } //the submarine port has to be at the top of the sub if (port.Item.WorldPosition.Y < Submarine.WorldPosition.Y) { continue; } float dist = Vector2.DistanceSquared(port.Item.WorldPosition, level.StartOutpost.WorldPosition); if (myPort == null || dist < closestDistance) { myPort = port; closestDistance = dist; } } if (myPort != null && outPostPort != null) { Vector2 portDiff = myPort.Item.WorldPosition - Submarine.WorldPosition; Submarine.SetPosition((outPostPort.Item.WorldPosition - portDiff) - Vector2.UnitY * outPostPort.DockedDistance); myPort.Dock(outPostPort); myPort.Lock(true); } } else { Submarine.SetPosition(Submarine.FindSpawnPos(level.StartPosition)); } } foreach (var sub in Submarine.Loaded) { if (sub.IsOutpost) { sub.DisableObstructedWayPoints(); } } Entity.Spawner = new EntitySpawner(); if (GameMode.Mission != null) { Mission = GameMode.Mission; } if (GameMode != null) { GameMode.Start(); } if (GameMode.Mission != null) { Mission.Start(Level.Loaded); } EventManager.StartRound(level); SteamAchievementManager.OnStartRound(); if (GameMode != null) { GameMode.MsgBox(); if (GameMode is MultiPlayerCampaign mpCampaign && GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) { mpCampaign.CargoManager.CreateItems(); } } GameAnalyticsManager.AddDesignEvent("Submarine:" + Submarine.Name); GameAnalyticsManager.AddDesignEvent("Level", ToolBox.StringToInt(level.Seed)); GameAnalyticsManager.AddProgressionEvent(GameAnalyticsSDK.Net.EGAProgressionStatus.Start, GameMode.Preset.Identifier, (Mission == null ? "None" : Mission.GetType().ToString())); #if CLIENT if (GameMode is SinglePlayerCampaign) { SteamAchievementManager.OnBiomeDiscovered(level.Biome); } roundSummary = new RoundSummary(this); GameMain.GameScreen.ColorFade(Color.Black, Color.TransparentBlack, 5.0f); if (!(GameMode is TutorialMode)) { GUI.AddMessage("", Color.Transparent, 3.0f, playSound: false); //TODO: re-enable when biome names have been translated //GUI.AddMessage(level.Biome.Name, Color.Lerp(Color.CadetBlue, Color.DarkRed, level.Difficulty / 100.0f), 5.0f, playSound: false); GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Destination"), EndLocation.Name), Color.CadetBlue, playSound: false); GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Mission"), (Mission == null ? TextManager.Get("None") : Mission.Name)), Color.CadetBlue, playSound: false); } #endif RoundStartTime = Timing.TotalTime; GameMain.ResetFrameTime(); }
static void Main() { GameMain game = null; #if !DEBUG try { #endif game = new GameMain(); //game.GraphicsDevice.PresentationParameters.IsFullScreen = false; #if !DEBUG } catch (Exception e) { if (game != null) { game.Dispose(); } CrashDump(null, "crashreport.log", e); return; } #endif #if DEBUG game.Run(); #else bool attemptRestart = false; do { try { game.Run(); attemptRestart = false; } catch (Exception e) { if (restartAttempts < 5 && CheckException(game, e)) { attemptRestart = true; restartAttempts++; } else { CrashDump(game, "crashreport.log", e); attemptRestart = false; } } } while (attemptRestart); #endif #if !DEBUG try { #endif game.Dispose(); #if !DEBUG } catch (Exception e) { CrashDump(null, "crashreport.log", e); } #endif }
/// <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 GameMain.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 && FirstLoad) { loadingScreenOpen = false; FirstLoad = false; MainMenuScreen.QuickStart(); } #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 (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(); } bool itemHudActive() { if (Character.Controlled?.SelectedConstruction == null) { return(false); } return (Character.Controlled.SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null) || ((Character.Controlled.ViewTarget as Item)?.Prefab?.FocusOnSelected ?? false)); } } #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(); } FileSelection.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); TaskPool.Update(); SoundManager?.Update(); Timing.Accumulator -= Timing.Step; sw.Stop(); PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks); PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks * 1000.0f / (float)Stopwatch.Frequency); PerformanceCounter.UpdateIterationsGraph.Update(updateIterations); } if (!Paused) { Timing.Alpha = Timing.Accumulator / Timing.Step; } }
private static bool CheckException(GameMain game, Exception e) { #if WINDOWS if (e is SharpDX.SharpDXException sharpDxException) { DebugConsole.NewMessage("SharpDX exception caught. (" + e.Message + ", " + sharpDxException.ResultCode.Code.ToString("X") + "). Attempting to fix...", Microsoft.Xna.Framework.Color.Red); switch ((UInt32)sharpDxException.ResultCode.Code) { case 0x887A0022: //DXGI_ERROR_NOT_CURRENTLY_AVAILABLE switch (restartAttempts) { case 0: //just wait and try again DebugConsole.NewMessage("Retrying after 100 ms...", Microsoft.Xna.Framework.Color.Red); System.Threading.Thread.Sleep(100); return(true); case 1: //force focus to this window DebugConsole.NewMessage("Forcing focus to the window and retrying...", Microsoft.Xna.Framework.Color.Red); var myForm = (Form)Control.FromHandle(game.Window.Handle); myForm.Focus(); return(true); case 2: //try disabling hardware mode switch if (GameMain.Config.WindowMode == WindowMode.Fullscreen) { DebugConsole.NewMessage("Failed to set fullscreen mode, switching configuration to borderless windowed.", Microsoft.Xna.Framework.Color.Red); GameMain.Config.WindowMode = WindowMode.BorderlessWindowed; GameMain.Config.SaveNewPlayerConfig(); } return(false); default: DebugConsole.NewMessage("Failed to resolve the DXGI_ERROR_NOT_CURRENTLY_AVAILABLE exception. Give up and let it crash :(", Microsoft.Xna.Framework.Color.Red); return(false); } case 0x80070057: //E_INVALIDARG/Invalid Arguments DebugConsole.NewMessage("Invalid graphics settings, attempting to fix...", Microsoft.Xna.Framework.Color.Red); GameMain.Config.GraphicsWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width; GameMain.Config.GraphicsHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height; DebugConsole.NewMessage("Display size set to " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight, Microsoft.Xna.Framework.Color.Red); game.ApplyGraphicsSettings(); return(true); default: DebugConsole.NewMessage("Unknown SharpDX exception code (" + sharpDxException.ResultCode.Code.ToString("X") + ")", Microsoft.Xna.Framework.Color.Red); return(false); } } #endif return(false); }
private void InitializeLevel(Level level) { //make sure no status effects have been carried on from the next round //(they should be stopped in EndRound, this is a safeguard against cases where the round is ended ungracefully) StatusEffect.StopAll(); #if CLIENT GameMain.LightManager.LosEnabled = GameMain.Client == null || GameMain.Client.CharacterInfo != null; if (GameMain.Client == null) { GameMain.LightManager.LosMode = GameMain.Config.LosMode; } #endif LevelData = level?.LevelData; Level = level; PlaceSubAtStart(Level); foreach (var sub in Submarine.Loaded) { if (sub.Info.IsOutpost) { sub.DisableObstructedWayPoints(); } } Entity.Spawner = new EntitySpawner(); if (GameMode.Mission != null) { Mission = GameMode.Mission; } if (GameMode != null) { GameMode.Start(); } if (GameMode.Mission != null) { int prevEntityCount = Entity.GetEntities().Count(); Mission.Start(Level.Loaded); if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient && Entity.GetEntities().Count() != prevEntityCount) { DebugConsole.ThrowError( "Entity count has changed after starting a mission as a client. " + "The clients should not instantiate entities themselves when starting the mission," + " but instead the server should inform the client of the spawned entities using Mission.ServerWriteInitial."); } } EventManager?.StartRound(Level.Loaded); SteamAchievementManager.OnStartRound(); if (GameMode != null) { GameMode.ShowStartMessage(); if (GameMain.NetworkMember == null) { //only place items and corpses here in single player //the server does this after loading the respawn shuttle Level?.SpawnNPCs(); Level?.SpawnCorpses(); Level?.PrepareBeaconStation(); AutoItemPlacer.PlaceIfNeeded(); } if (GameMode is MultiPlayerCampaign mpCampaign) { if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) { mpCampaign.CargoManager.CreatePurchasedItems(); #if SERVER mpCampaign.SendCrewState(false, null); #endif } mpCampaign.UpgradeManager.ApplyUpgrades(); mpCampaign.UpgradeManager.SanityCheckUpgrades(Submarine); } if (GameMode is CampaignMode) { Submarine.WarmStartPower(); } } GameMain.Config.RecentlyEncounteredCreatures.Clear(); GameMain.GameScreen.Cam.Position = Character.Controlled?.WorldPosition ?? Submarine.MainSub.WorldPosition; RoundStartTime = Timing.TotalTime; GameMain.ResetFrameTime(); IsRunning = true; }
/// <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 = 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.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) { 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(); } 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); #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(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; } }
static void CrashDump(GameMain game, string filePath, Exception exception) { int existingFiles = 0; string originalFilePath = filePath; while (File.Exists(filePath)) { existingFiles++; filePath = Path.GetFileNameWithoutExtension(originalFilePath) + " (" + (existingFiles + 1) + ")" + Path.GetExtension(originalFilePath); } DebugConsole.DequeueMessages(); string exePath = System.Reflection.Assembly.GetEntryAssembly().Location; var md5 = System.Security.Cryptography.MD5.Create(); Md5Hash exeHash = null; try { using (var stream = File.OpenRead(exePath)) { exeHash = new Md5Hash(stream); } } catch { //gotta catch them all, we don't want to throw an exception while writing a crash report } StreamWriter sw = new StreamWriter(filePath); StringBuilder sb = new StringBuilder(); sb.AppendLine("Barotrauma Client crash report (generated on " + DateTime.Now + ")"); sb.AppendLine("\n"); sb.AppendLine("Barotrauma seems to have crashed. Sorry for the inconvenience! "); sb.AppendLine("\n"); if (exeHash?.Hash != null) { sb.AppendLine(exeHash.Hash); } sb.AppendLine("\n"); #if DEBUG sb.AppendLine("Game version " + GameMain.Version + " (debug build)"); #else sb.AppendLine("Game version " + GameMain.Version); #endif if (GameMain.Config != null) { sb.AppendLine("Graphics mode: " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight + " (" + GameMain.Config.WindowMode.ToString() + ")"); } if (GameMain.SelectedPackages != null) { sb.AppendLine("Selected content packages: " + (!GameMain.SelectedPackages.Any() ? "None" : string.Join(", ", GameMain.SelectedPackages.Select(c => c.Name)))); } sb.AppendLine("Level seed: " + ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed)); sb.AppendLine("Loaded submarine: " + ((Submarine.MainSub == null) ? "None" : Submarine.MainSub.Name + " (" + Submarine.MainSub.MD5Hash + ")")); sb.AppendLine("Selected screen: " + (Screen.Selected == null ? "None" : Screen.Selected.ToString())); if (SteamManager.IsInitialized) { sb.AppendLine("SteamManager initialized"); } if (GameMain.Client != null) { sb.AppendLine("Client (" + (GameMain.Client.GameStarted ? "Round had started)" : "Round hadn't been started)")); } sb.AppendLine("\n"); sb.AppendLine("System info:"); sb.AppendLine(" Operating system: " + System.Environment.OSVersion + (System.Environment.Is64BitOperatingSystem ? " 64 bit" : " x86")); if (game == null) { sb.AppendLine(" Game not initialized"); } else { if (game.GraphicsDevice == null) { sb.AppendLine(" Graphics device not set"); } else { if (game.GraphicsDevice.Adapter == null) { sb.AppendLine(" Graphics adapter not set"); } else { sb.AppendLine(" GPU name: " + game.GraphicsDevice.Adapter.Description); sb.AppendLine(" Display mode: " + game.GraphicsDevice.Adapter.CurrentDisplayMode); } sb.AppendLine(" GPU status: " + game.GraphicsDevice.GraphicsDeviceStatus); } } sb.AppendLine("\n"); sb.AppendLine("Exception: " + exception.Message); #if WINDOWS if (exception is SharpDXException sharpDxException && ((uint)sharpDxException.HResult) == 0x887A0005) { var dxDevice = (SharpDX.Direct3D11.Device)game.GraphicsDevice.Handle; sb.AppendLine("Device removed reason: " + dxDevice.DeviceRemovedReason.ToString()); } #endif if (exception.TargetSite != null) { sb.AppendLine("Target site: " + exception.TargetSite.ToString()); } sb.AppendLine("Stack trace: "); sb.AppendLine(exception.StackTrace); sb.AppendLine("\n"); if (exception.InnerException != null) { sb.AppendLine("InnerException: " + exception.InnerException.Message); if (exception.InnerException.TargetSite != null) { sb.AppendLine("Target site: " + exception.InnerException.TargetSite.ToString()); } sb.AppendLine("Stack trace: "); sb.AppendLine(exception.InnerException.StackTrace); } sb.AppendLine("Last debug messages:"); for (int i = DebugConsole.Messages.Count - 1; i >= 0; i--) { sb.AppendLine("[" + DebugConsole.Messages[i].Time + "] " + DebugConsole.Messages[i].Text); } string crashReport = sb.ToString(); sw.WriteLine(crashReport); sw.Close(); if (GameSettings.SaveDebugConsoleLogs) { DebugConsole.SaveLogs(); } if (GameSettings.SendUserStatistics) { CrashMessageBox("A crash report (\"" + filePath + "\") was saved in the root folder of the game and sent to the developers.", filePath); GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport); GameAnalytics.OnQuit(); } else { CrashMessageBox("A crash report (\"" + filePath + "\") was saved in the root folder of the game. The error was not sent to the developers because user statistics have been disabled, but" + " if you'd like to help fix this bug, you may post it on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/", filePath); } }