Client LuaCsForBarotrauma
GameMain.cs
1 using Barotrauma.IO;
2 using Barotrauma.Media;
5 using Barotrauma.Steam;
8 using FarseerPhysics;
9 using FarseerPhysics.Dynamics;
10 using Microsoft.Xna.Framework;
11 using Microsoft.Xna.Framework.Graphics;
12 using Microsoft.Xna.Framework.Input;
13 using System;
14 using System.Collections.Generic;
15 using System.Diagnostics;
16 using System.Linq;
17 using System.Reflection;
18 using System.Threading;
20 using System.Collections.Immutable;
21 
22 namespace Barotrauma
23 {
24  class GameMain : Game
25  {
26  public static LuaCsSetup LuaCs;
27  public static bool ShowFPS;
28  public static bool ShowPerf;
29  public static bool DebugDraw;
33  public static bool DevMode;
34  public static bool IsSingleplayer => NetworkMember == null;
35  public static bool IsMultiplayer => NetworkMember != null;
36 
38 
39  private static Stopwatch performanceCounterTimer;
40  private static int updateCount = 0;
41  public static int CurrentUpdateRate
42  {
43  get; private set;
44  }
45 
46  public static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version;
47 
48  public readonly ImmutableArray<string> ConsoleArguments;
49 
50  public readonly Option<string> EgsExchangeCode;
51 
52  public static GameScreen GameScreen;
54 
57 
58  public static void ResetNetLobbyScreen()
59  {
64  }
65 
67 
69  public static TestScreen TestScreen;
74  public static CharacterEditor.CharacterEditorScreen CharacterEditorScreen;
75 
77 
78  public static Lights.LightManager LightManager;
79 
80  public static Sounds.SoundManager SoundManager;
81 
82  public static Thread MainThread { get; private set; }
83 
84  public static ContentPackage VanillaContent => ContentPackageManager.VanillaCorePackage;
85 
86  private static GameSession gameSession;
87  public static GameSession GameSession
88  {
89  get { return gameSession; }
90  set
91  {
92  if (gameSession == value) { return; }
93  if (gameSession?.GameMode != null && gameSession.GameMode != value?.GameMode)
94  {
95  gameSession.GameMode.Remove();
96  }
97  gameSession = value;
98  }
99  }
100 
102 
103  private static World world;
104  public static World World
105  {
106  get
107  {
108  if (world == null) { world = new World(new Vector2(0, -9.82f)); }
109  return world;
110  }
111  set { world = value; }
112  }
113 
114  public static LoadingScreen TitleScreen;
115  private bool loadingScreenOpen;
116 
117  private Thread initialLoadingThread;
118 
119  public bool HasLoaded { get; private set; }
120 
121  private readonly GameTime fixedTime;
122 
123  public Option<ConnectCommand> ConnectCommand = Option<ConnectCommand>.None();
124 
125  private static SpriteBatch spriteBatch;
126 
127  private Viewport defaultViewport;
128 
133  public event Action ResolutionChanged;
134 
135  public static bool IsExiting { get; private set; }
136 
137  public static bool IsFirstLaunch
138  {
139  get;
140  private set;
141  }
142 
143  public static GameMain Instance
144  {
145  get;
146  private set;
147  }
148 
150  {
151  get;
152  private set;
153  }
154 
155  public static WindowMode WindowMode
156  {
157  get;
158  private set;
159  }
160 
161  public static int GraphicsWidth
162  {
163  get;
164  private set;
165  }
166 
167  public static int GraphicsHeight
168  {
169  get;
170  private set;
171  }
172 
173  public static bool WindowActive
174  {
175  get
176  {
177  try
178  {
179  return Instance != null && !IsExiting && Instance.IsActive;
180  }
181  catch (NullReferenceException)
182  {
183  return false;
184  }
185  }
186  }
187 
188  public static GameClient Client;
190  {
191  get { return Client; }
192  }
193 
194  public static RasterizerState ScissorTestEnable
195  {
196  get;
197  private set;
198  }
199 
200  public bool LoadingScreenOpen
201  {
202  get { return loadingScreenOpen; }
203  }
204 
205  public bool Paused
206  {
207  get; private set;
208  }
209 
210  private const GraphicsProfile GfxProfile = GraphicsProfile.Reach;
211 
212 #if DEBUG
213  public static bool FirstLoad = true;
214 
215  public static bool CancelQuickStart;
216 #endif
217 
218  public static ChatMode ActiveChatMode { get; set; } = ChatMode.Radio;
219 
220  private static bool contentLoaded;
221 
222  private static readonly Queue<Action> postContentLoadActions = new();
223 
224  public GameMain(string[] args)
225  {
226  Content.RootDirectory = "Content";
227 #if DEBUG && WINDOWS
228  GraphicsAdapter.UseDebugLayers = true;
229 #endif
231  {
232  IsFullScreen = false,
233  GraphicsProfile = GfxProfile
234  };
235  GraphicsDeviceManager.ApplyChanges();
236 
237  Window.Title = "Barotrauma";
238 
239  Instance = this;
240 
241  if (!Directory.Exists(Content.RootDirectory))
242  {
243  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.");
244  }
245 
246  LuaCs = new LuaCsSetup();
247 
248  GameSettings.Init();
249  CreatureMetrics.Init();
250 
251  ConsoleArguments = args.ToImmutableArray();
252 
253  EgsExchangeCode = EosInterface.Login.ParseEgsExchangeCode(args);
254 
255  try
256  {
257  ConnectCommand = Barotrauma.Networking.ConnectCommand.Parse(ConsoleArguments);
258  }
259  catch (IndexOutOfRangeException e)
260  {
261  DebugConsole.ThrowError($"Failed to parse console arguments ({string.Join(' ', ConsoleArguments)})", e);
262  ConnectCommand = Option<ConnectCommand>.None();
263  }
264 
265  GUI.KeyboardDispatcher = new EventInput.KeyboardDispatcher(Window);
266 
268 
269  IsFixedTimeStep = false;
270 
272  fixedTime = new GameTime();
273 
274  FarseerPhysics.Settings.AllowSleep = true;
275  FarseerPhysics.Settings.ContinuousPhysics = false;
276  FarseerPhysics.Settings.VelocityIterations = 1;
277  FarseerPhysics.Settings.PositionIterations = 1;
278 
279  MainThread = Thread.CurrentThread;
280 
281  Window.FileDropped += OnFileDropped;
282  }
283 
284  public static void ExecuteAfterContentFinishedLoading(Action action)
285  {
286  if (contentLoaded)
287  {
288  action();
289  return;
290  }
291  postContentLoadActions.Enqueue(action);
292  }
293 
294  public static void OnFileDropped(object sender, FileDropEventArgs args)
295  {
296  if (!(Screen.Selected is { } screen)) { return; }
297 
298  string filePath = args.FilePath;
299  if (string.IsNullOrWhiteSpace(filePath)) { return; }
300 
301  string extension = Path.GetExtension(filePath).ToLower();
302 
303  System.IO.FileInfo info = new System.IO.FileInfo(args.FilePath);
304  if (!info.Exists) { return; }
305 
306  screen.OnFileDropped(filePath, extension);
307  }
308 
309  public void ApplyGraphicsSettings(bool recalculateFontsAndStyles = false)
310  {
311  static void updateConfig()
312  {
313  var config = GameSettings.CurrentConfig;
314  config.Graphics.Width = GraphicsWidth;
315  config.Graphics.Height = GraphicsHeight;
316  GameSettings.SetCurrentConfig(config);
317  }
318 
319  GraphicsWidth = GameSettings.CurrentConfig.Graphics.Width;
320  GraphicsHeight = GameSettings.CurrentConfig.Graphics.Height;
321 
322  if (GraphicsWidth <= 0 || GraphicsHeight <= 0)
323  {
324  GraphicsWidth = GraphicsDevice.DisplayMode.Width;
325  GraphicsHeight = GraphicsDevice.DisplayMode.Height;
326  updateConfig();
327  }
328 
329  switch (GameSettings.CurrentConfig.Graphics.DisplayMode)
330  {
331  case WindowMode.BorderlessWindowed:
332  GraphicsWidth = GraphicsDevice.DisplayMode.Width;
333  GraphicsHeight = GraphicsDevice.DisplayMode.Height;
334  updateConfig();
335  break;
336  case WindowMode.Windowed:
337  GraphicsWidth = Math.Min(GraphicsDevice.DisplayMode.Width, GraphicsWidth);
338  GraphicsHeight = Math.Min(GraphicsDevice.DisplayMode.Height, GraphicsHeight);
339  updateConfig();
340  break;
341  }
342  GraphicsDeviceManager.GraphicsProfile = GfxProfile;
343  GraphicsDeviceManager.PreferredBackBufferFormat = SurfaceFormat.Color;
344  GraphicsDeviceManager.PreferMultiSampling = false;
345  GraphicsDeviceManager.SynchronizeWithVerticalRetrace = GameSettings.CurrentConfig.Graphics.VSync;
346  SetWindowMode(GameSettings.CurrentConfig.Graphics.DisplayMode);
347 
348  defaultViewport = new Viewport(0, 0, GraphicsWidth, GraphicsHeight);
349 
350  if (recalculateFontsAndStyles)
351  {
352  GUIStyle.RecalculateFonts();
353  GUIStyle.RecalculateSizeRestrictions();
354  }
355 
356  ResolutionChanged?.Invoke();
357  }
358 
359  public void SetWindowMode(WindowMode windowMode)
360  {
361  WindowMode = windowMode;
362  GraphicsDeviceManager.HardwareModeSwitch = windowMode != WindowMode.BorderlessWindowed;
363  GraphicsDeviceManager.IsFullScreen = windowMode == WindowMode.Fullscreen || windowMode == WindowMode.BorderlessWindowed;
364  Window.IsBorderless = !GraphicsDeviceManager.HardwareModeSwitch;
365 
366  GraphicsDeviceManager.PreferredBackBufferWidth = GraphicsWidth;
367  GraphicsDeviceManager.PreferredBackBufferHeight = GraphicsHeight;
368 
369  GraphicsDeviceManager.ApplyChanges();
370 
371  if (windowMode == WindowMode.BorderlessWindowed)
372  {
373  GraphicsWidth = GraphicsDevice.PresentationParameters.Bounds.Width;
374  GraphicsHeight = GraphicsDevice.PresentationParameters.Bounds.Height;
375  GraphicsDevice.Viewport = new Viewport(0,0,GraphicsWidth,GraphicsHeight);
376  GraphicsDevice.ScissorRectangle = new Rectangle(0,0,GraphicsWidth,GraphicsHeight);
377  GraphicsDeviceManager.PreferredBackBufferWidth = GraphicsWidth;
378  GraphicsDeviceManager.PreferredBackBufferHeight = GraphicsHeight;
379 
380  GraphicsDeviceManager.ApplyChanges();
381  }
382  }
383 
384  public void ResetViewPort()
385  {
386  GraphicsDevice.Viewport = defaultViewport;
387  GraphicsDevice.ScissorRectangle = defaultViewport.Bounds;
388  }
389 
396  protected override void Initialize()
397  {
398  base.Initialize();
399 
401 
402  ScissorTestEnable = new RasterizerState() { ScissorTestEnable = true };
403 
404  Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Character));
405  Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Item));
406  Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Items.Components.ItemComponent));
407  Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Hull));
408 
409  performanceCounterTimer = Stopwatch.StartNew();
411  }
412 
417  protected override void LoadContent()
418  {
419  GraphicsWidth = GraphicsDevice.Viewport.Width;
420  GraphicsHeight = GraphicsDevice.Viewport.Height;
421 
423 
424  ConvertUnits.SetDisplayUnitToSimUnitRatio(Physics.DisplayToSimRation);
425 
426  spriteBatch = new SpriteBatch(GraphicsDevice);
427  TextureLoader.Init(GraphicsDevice);
428 
429  //do this here because we need it for the loading screen
430  WaterRenderer.Instance = new WaterRenderer(base.GraphicsDevice);
431 
432  GraphicsQuad.Init(GraphicsDevice);
433 
434  loadingScreenOpen = true;
435  TitleScreen = new LoadingScreen(GraphicsDevice)
436  {
437  WaitForLanguageSelection = GameSettings.CurrentConfig.Language == LanguageIdentifier.None
438  };
439 
440  Eos.EosAccount.LoginPlatformSpecific();
441 
442  initialLoadingThread = new Thread(Load);
443  initialLoadingThread.Start();
444  }
445 
446  private void Load()
447  {
448  static void log(string str)
449  {
450  if (GameSettings.CurrentConfig.VerboseLogging)
451  {
452  DebugConsole.NewMessage(str, Color.Lime);
453  }
454  }
455 
456  log("LOADING COROUTINE");
457 
458  ContentPackageManager.LoadVanillaFileList();
459 
461  {
462  ContentPackageManager.VanillaCorePackage.LoadFilesOfType<TextFile>();
463  TitleScreen.AvailableLanguages = TextManager.AvailableLanguages.OrderBy(l => l.Value != "english".ToIdentifier()).ThenBy(l => l.Value).ToArray();
465  {
466  Thread.Sleep((int)(Timing.Step * 1000));
467  }
468  LanguageIdentifier selectedLanguage = GameSettings.CurrentConfig.Language;
469  //unload text files at this point - we only loaded for the purposes of the language selection screen,
470  //they will be loaded "normally" with the rest of the files later
471  ContentPackageManager.VanillaCorePackage.UnloadFilesOfType<TextFile>();
472  //the selected language got unloaded, need to reselect it
473  var config = GameSettings.CurrentConfig;
474  config.Language = selectedLanguage;
475  GameSettings.SetCurrentConfig(config);
476  GameSettings.SaveCurrentConfig();
477  }
478 
479  SoundManager = new Sounds.SoundManager();
480  SoundManager.ApplySettings();
481 
482  if (GameSettings.CurrentConfig.EnableSplashScreen && !ConsoleArguments.Contains("-skipintro"))
483  {
484  var pendingSplashScreens = TitleScreen.PendingSplashScreens;
485  float baseVolume = MathHelper.Clamp(GameSettings.CurrentConfig.Audio.SoundVolume * 2.0f, 0.0f, 1.0f);
486  pendingSplashScreens.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_UTG.webm", baseVolume * 0.5f));
487  pendingSplashScreens.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_FF.webm", baseVolume));
488  pendingSplashScreens.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_Daedalic.webm", baseVolume * 0.1f));
489  }
490 
491  GUI.Init();
492 
493  LegacySteamUgcTransition.Prepare();
494  var contentPackageLoadRoutine = ContentPackageManager.Init();
495  foreach (var progress in contentPackageLoadRoutine
496  .Select(p => p.Result).Successes())
497  {
498  const float min = 1f, max = 70f;
499  if (IsExiting) { break; }
500  TitleScreen.LoadState = MathHelper.Lerp(min, max, progress);
501  }
502  if (IsExiting) { return; }
503 
504  var corePackage = ContentPackageManager.EnabledPackages.Core;
505  if (corePackage.EnableError.TryUnwrap(out var error))
506  {
507  if (error.ErrorsOrException.TryGet(out ImmutableArray<string> errorMessages))
508  {
509  throw new Exception($"Error while loading the core content package \"{corePackage.Name}\": {errorMessages.First()}");
510  }
511  else if (error.ErrorsOrException.TryGet(out Exception exception))
512  {
513  throw new Exception($"Error while loading the core content package \"{corePackage.Name}\": {exception.Message}", exception);
514  }
515  }
516 
517  TextManager.VerifyLanguageAvailable();
518 
520  DebugConsole.Init();
521 
522  ContentPackageManager.LogEnabledRegularPackageErrors();
523 
524 #if !DEBUG && !OSX
525  GameAnalyticsManager.InitIfConsented();
526 #endif
527 
528  TaskPool.Add("InitRelayNetworkAccess", SteamManager.InitRelayNetworkAccess(), (t) => { });
529 
530  HintManager.Init();
531  CoreEntityPrefab.InitCorePrefabs();
532  GameModePreset.Init();
533 
534  SaveUtil.DeleteDownloadedSubs();
535  SubmarineInfo.RefreshSavedSubs();
536 
537  TitleScreen.LoadState = 75.0f;
538 
539  GameScreen = new GameScreen(GraphicsDeviceManager.GraphicsDevice);
540 
542  LightManager = new Lights.LightManager(base.GraphicsDevice);
543 
544  TitleScreen.LoadState = 80.0f;
545 
546  MainMenuScreen = new MainMenuScreen(this);
548 
549  TitleScreen.LoadState = 85.0f;
550 
551  if (SteamManager.IsInitialized)
552  {
553  Steamworks.SteamFriends.OnGameRichPresenceJoinRequested += OnInvitedToSteamGame;
554  Steamworks.SteamFriends.OnGameLobbyJoinRequested += OnSteamLobbyJoinRequested;
555 
556  if (SteamManager.TryGetUnlockedAchievements(out List<Steamworks.Data.Achievement> achievements))
557  {
558  //check the achievements too, so we don't consider people who've played the game before this "gamelaunchcount" stat was added as being 1st-time-players
559  //(people who have played previous versions, but not unlocked any achievements, will be incorrectly considered 1st-time-players, but that should be a small enough group to not skew the statistics)
560  if (!achievements.Any() && SteamManager.GetStatInt(AchievementStat.GameLaunchCount) <= 0)
561  {
562  IsFirstLaunch = true;
563  GameAnalyticsManager.AddDesignEvent("FirstLaunch");
564  }
565  }
566  SteamManager.IncrementStat(AchievementStat.GameLaunchCount, 1);
567  }
568 
569 
570 
571  Eos.EosAccount.ExecuteAfterLogin(ProcessLaunchCountEos);
572 
574  TestScreen = new TestScreen();
575 
576  TitleScreen.LoadState = 90.0f;
577 
579 
580  TitleScreen.LoadState = 95.0f;
581 
585  CharacterEditorScreen = new CharacterEditor.CharacterEditorScreen();
587 
588 #if DEBUG
589  LevelGenerationParams.CheckValidity();
590 #endif
591 
593 
594  ContainerTagPrefab.CheckForContainerTagErrors();
595 
596  foreach (Identifier steamError in SteamManager.InitializationErrors)
597  {
598  new GUIMessageBox(TextManager.Get("Error"), TextManager.Get(steamError));
599  }
600 
601  GameSettings.OnGameMainHasLoaded?.Invoke();
602 
603  TitleScreen.LoadState = 100.0f;
604  HasLoaded = true;
605 
606  log("LOADING COROUTINE FINISHED");
607 #if CLIENT
608  LuaCsInstaller.CheckUpdate();
609 #endif
610 
611  contentLoaded = true;
612  while (postContentLoadActions.TryDequeue(out Action action))
613  {
614  action();
615  }
616  }
617 
618  private static void ProcessLaunchCountEos()
619  {
620  if (!EosInterface.Core.IsInitialized) { return; }
621 
622  static void trySetConnectCommand(string commandStr)
623  {
624  Instance.ConnectCommand = Instance.ConnectCommand.Fallback(Networking.ConnectCommand.Parse(commandStr));
625  }
626 
627  EosInterface.Presence.OnJoinGame.Register("onJoinGame".ToIdentifier(), static jgi => trySetConnectCommand(jgi.JoinCommand));
628  EosInterface.Presence.OnInviteAccepted.Register("onInviteAccepted".ToIdentifier(), static aii => trySetConnectCommand(aii.JoinCommand));
629 
630  TaskPool.AddWithResult("Eos.GameMain.Load.QueryStats", EosInterface.Achievements.QueryStats(AchievementStat.GameLaunchCount), static result =>
631  {
632  result.Match(
633  success: static stats =>
634  {
635  if (!stats.TryGetValue(AchievementStat.GameLaunchCount, out int launchCount)) { return; }
636 
637  if (launchCount > 0) { return; }
638 
639  IsFirstLaunch = true;
640  GameAnalyticsManager.AddDesignEvent("FirstLaunch_Epic");
641  },
642  failure: static error => DebugConsole.ThrowError($"Failed to query stats for launch count: {error}")
643  );
644 
645  TaskPool.Add("Eos.GameMain.Load.IngestStat", EosInterface.Achievements.IngestStats((AchievementStat.GameLaunchCount, 1)), TaskPool.IgnoredCallback);
646  });
647  }
648 
653  protected override void UnloadContent()
654  {
655  TextureLoader.CancelAll();
656  CoroutineManager.StopCoroutines("Load");
657  Video.Close();
659  SoundManager?.Dispose();
660  MainThread = null;
661  }
662 
663  private void OnInvitedToSteamGame(Steamworks.Friend friend, string connectCommand) => OnInvitedToSteamGame(connectCommand);
664 
665  private void OnInvitedToSteamGame(string connectCommand)
666  {
667  try
668  {
669  ConnectCommand = Barotrauma.Networking.ConnectCommand.Parse(ToolBox.SplitCommand(connectCommand));
670  }
671  catch (IndexOutOfRangeException e)
672  {
673 #if DEBUG
674  DebugConsole.ThrowError($"Failed to parse a Steam friend's connect invitation command ({connectCommand})", e);
675 #else
676  DebugConsole.Log($"Failed to parse a Steam friend's connect invitation command ({connectCommand})\n" + e.StackTrace.CleanupStackTrace());
677 #endif
678  ConnectCommand = Option<ConnectCommand>.None();
679  }
680  }
681 
682  private void OnSteamLobbyJoinRequested(Steamworks.Data.Lobby lobby, Steamworks.SteamId friendId)
683  {
684  SteamManager.JoinLobby(lobby.Id, true);
685  }
686 
692  protected override void Update(GameTime gameTime)
693  {
694  Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds;
695  if (Timing.Accumulator > Timing.AccumulatorMax)
696  {
697  //prevent spiral of death:
698  //if the game's running too slowly then we have no choice but to skip a bunch of steps
699  //otherwise it snowballs and becomes unplayable
700  Timing.Accumulator = Timing.Step;
701  }
702 
703  CrossThread.ProcessTasks();
704 
706 
707  if (SoundManager != null)
708  {
709  if (WindowActive || !GameSettings.CurrentConfig.Audio.MuteOnFocusLost)
710  {
711  SoundManager.ListenerGain = SoundManager.CompressionDynamicRangeGain;
712  }
713  else
714  {
715  SoundManager.ListenerGain = 0.0f;
716  }
717  }
718 
719  while (Timing.Accumulator >= Timing.Step)
720  {
721  Timing.TotalTime += Timing.Step;
722  if (!Paused)
723  {
724  Timing.TotalTimeUnpaused += Timing.Step;
725  }
726  Stopwatch sw = new Stopwatch();
727  sw.Start();
728 
729  fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly;
730  TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16);
731  fixedTime.ElapsedGameTime = addTime;
732  fixedTime.TotalGameTime.Add(addTime);
733  base.Update(fixedTime);
734 
735  PlayerInput.Update(Timing.Step);
736 
738 
739  if (loadingScreenOpen)
740  {
741  //reset accumulator if loading
742  // -> less choppy loading screens because the screen is rendered after each update
743  // -> no pause caused by leftover time in the accumulator when starting a new shift
744  ResetFrameTime();
745 
746  if (!TitleScreen.PlayingSplashScreen)
747  {
748  SoundPlayer.Update((float)Timing.Step);
749  GUI.ClearUpdateList();
750  GUI.UpdateGUIMessageBoxesOnly((float)Timing.Step);
751  }
752 
753  if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen &&
754  (!waitForKeyHit || ((PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.PrimaryMouseButtonClicked()) && WindowActive)))
755  {
756  loadingScreenOpen = false;
757  }
758 
759 #if DEBUG
760  if (PlayerInput.KeyHit(Keys.LeftShift))
761  {
762  CancelQuickStart = !CancelQuickStart;
763  }
764 
765  if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen &&
766  (GameSettings.CurrentConfig.AutomaticQuickStartEnabled ||
767  GameSettings.CurrentConfig.AutomaticCampaignLoadEnabled ||
768  GameSettings.CurrentConfig.TestScreenEnabled) && FirstLoad && !CancelQuickStart)
769  {
770  loadingScreenOpen = false;
771  FirstLoad = false;
772 
773  if (GameSettings.CurrentConfig.TestScreenEnabled)
774  {
775  TestScreen.Select();
776  }
777  else if (GameSettings.CurrentConfig.AutomaticQuickStartEnabled)
778  {
780  }
781  else if (GameSettings.CurrentConfig.AutomaticCampaignLoadEnabled)
782  {
783  var saveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Singleplayer);
784  if (saveFiles.Count() > 0)
785  {
786  try
787  {
788  SaveUtil.LoadGame(CampaignDataPath.CreateRegular(saveFiles.OrderBy(file => file.SaveTime).Last().FilePath));
789  }
790  catch (Exception e)
791  {
792  DebugConsole.ThrowError("Loading save \"" + saveFiles.Last() + "\" failed", e);
793  return;
794  }
795  }
796  }
797  }
798 #endif
799 
800  Client?.Update((float)Timing.Step);
801  }
802  else if (HasLoaded)
803  {
804  if (ConnectCommand.TryUnwrap(out var connectCommand))
805  {
806  if (Client != null)
807  {
808  Client.Quit();
809  Client = null;
810  }
812 
813  if (connectCommand.SteamLobbyIdOption.TryUnwrap(out var lobbyId))
814  {
815  SteamManager.JoinLobby(lobbyId.Value, joinServer: true);
816  }
817  else if (connectCommand.NameAndP2PEndpointsOption.TryUnwrap(out var nameAndEndpoint)
818  && nameAndEndpoint is { ServerName: var serverName, Endpoints: var endpoints })
819  {
820  Client = new GameClient(MultiplayerPreferences.Instance.PlayerName.FallbackNullOrEmpty(SteamManager.GetUsername()),
821  endpoints.Cast<Endpoint>().ToImmutableArray(),
822  string.IsNullOrWhiteSpace(serverName) ? endpoints.First().StringRepresentation : serverName,
823  Option<int>.None());
824  }
825 
826  ConnectCommand = Option<ConnectCommand>.None();
827  }
828 
829  SoundPlayer.Update((float)Timing.Step);
830 
831  if ((PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
832  && (PlayerInput.KeyDown(Keys.LeftShift) || PlayerInput.KeyDown(Keys.RightShift))
833  && PlayerInput.KeyHit(Keys.Tab)
834  && SocialOverlay.Instance is { } socialOverlay)
835  {
836  socialOverlay.IsOpen = !socialOverlay.IsOpen;
837  if (socialOverlay.IsOpen)
838  {
839  socialOverlay.RefreshFriendList();
840  }
841  }
842 
843  if (PlayerInput.KeyHit(Keys.Escape) && WindowActive)
844  {
845  // Check if a text input is selected.
846  if (GUI.KeyboardDispatcher.Subscriber != null)
847  {
848  if (GUI.KeyboardDispatcher.Subscriber is GUITextBox textBox)
849  {
850  textBox.Deselect();
851  }
852  GUI.KeyboardDispatcher.Subscriber = null;
853  }
854  else if (SocialOverlay.Instance is { IsOpen: true })
855  {
856  SocialOverlay.Instance.IsOpen = false;
857  }
858  //if a verification prompt (are you sure you want to x) is open, close it
859  else if (GUIMessageBox.VisibleBox is GUIMessageBox { UserData: "verificationprompt" })
860  {
862  }
863  else if (GUIMessageBox.VisibleBox?.UserData is RoundSummary { ContinueButton.Visible: true })
864  {
866  }
867  else if (ObjectiveManager.ContentRunning)
868  {
869  ObjectiveManager.CloseActiveContentGUI();
870  }
871  else if (GameSession.IsTabMenuOpen)
872  {
873  gameSession.ToggleTabMenu();
874  }
875  else if (GUIMessageBox.VisibleBox is GUIMessageBox { UserData: "bugreporter" })
876  {
878  }
879  else if (GUI.PauseMenuOpen)
880  {
881  GUI.TogglePauseMenu();
882  }
883  else if (GameSession?.Campaign is { ShowCampaignUI: true, ForceMapUI: false })
884  {
886  }
887  //open the pause menu if not controlling a character OR if the character has no UIs active that can be closed with ESC
888  else if ((Character.Controlled == null || !itemHudActive())
891  && !(Screen.Selected is SubEditorScreen editor && !editor.WiringMode && Character.Controlled?.SelectedItem != null))
892  {
893  // Otherwise toggle pausing, unless another window/interface is open.
894  GUI.TogglePauseMenu();
895  }
896 
897  static bool itemHudActive()
898  {
899  if (Character.Controlled?.SelectedItem == null) { return false; }
900  return
901  Character.Controlled.SelectedItem.ActiveHUDs.Any(ic => ic.GuiFrame != null) ||
902  ((Character.Controlled.ViewTarget as Item)?.Prefab?.FocusOnSelected ?? false);
903  }
904  }
905 
906 #if DEBUG
907  if (NetworkMember == null)
908  {
909  if (PlayerInput.KeyHit(Keys.P) && !(GUI.KeyboardDispatcher.Subscriber is GUITextBox))
910  {
911  DebugConsole.Paused = !DebugConsole.Paused;
912  }
913  }
914 #endif
915 
916  GUI.ClearUpdateList();
917  Paused =
918  (DebugConsole.IsOpen || DebugConsole.Paused ||
919  GUI.PauseMenuOpen || GUI.SettingsMenuOpen ||
920  (GameSession?.GameMode is TutorialMode && ObjectiveManager.ContentRunning)) &&
921  (NetworkMember == null || !NetworkMember.GameStarted);
923  {
924  Paused = true;
925  GameSession.GameMode.UpdateWhilePaused((float)Timing.Step);
926  }
927 
928 #if !DEBUG
929  if (NetworkMember == null && !WindowActive && !Paused && true && GameSettings.CurrentConfig.PauseOnFocusLost &&
932  {
933  GUI.TogglePauseMenu();
934  Paused = true;
935  }
936 #endif
937 
939 
941 
942  Client?.AddToGUIUpdateList();
943 
945 
946  FileSelection.AddToGUIUpdateList();
947 
948  DebugConsole.AddToGUIUpdateList();
949 
950  DebugConsole.Update((float)Timing.Step);
951 
952  if (!Paused)
953  {
954  Screen.Selected.Update(Timing.Step);
955  }
956  else if (ObjectiveManager.ContentRunning && GameSession?.GameMode is TutorialMode tutorialMode)
957  {
958  ObjectiveManager.VideoPlayer.Update();
959  tutorialMode.Update((float)Timing.Step);
960  }
961  else
962  {
963  if (Screen.Selected.Cam == null)
964  {
965  DebugConsole.Paused = false;
966  }
967  else
968  {
969  Screen.Selected.Cam.MoveCamera((float)Timing.Step, allowMove: DebugConsole.Paused, allowZoom: DebugConsole.Paused);
970  }
971  }
972 
973  Client?.Update((float)Timing.Step);
974 
975  GUI.Update((float)Timing.Step);
976 
977 #if DEBUG
978  if (DebugDraw && GUI.MouseOn != null && PlayerInput.IsCtrlDown() && PlayerInput.KeyHit(Keys.G))
979  {
980  List<GUIComponent> hierarchy = new List<GUIComponent>();
981  var currComponent = GUI.MouseOn;
982  while (currComponent != null)
983  {
984  hierarchy.Add(currComponent);
985  currComponent = currComponent.Parent;
986  }
987  DebugConsole.NewMessage("*********************");
988  foreach (var component in hierarchy)
989  {
990  if (component is { MouseRect: var mouseRect, Rect: var rect })
991  {
992  DebugConsole.NewMessage($"{component.GetType().Name} {component.Style?.Name ?? "[null]"} {rect.Bottom} {mouseRect.Bottom}", mouseRect!=rect ? Color.Lime : Color.Red);
993  }
994  }
995  }
996 #endif
997  }
998 
999  CoroutineManager.Update(Paused, (float)Timing.Step);
1000 
1001  SteamManager.Update((float)Timing.Step);
1002  EosInterface.Core.Update();
1003 
1004  TaskPool.Update();
1005 
1006  SoundManager?.Update();
1007 
1008  GameMain.LuaCs.Update();
1009 
1010  Timing.Accumulator -= Timing.Step;
1011 
1012  updateCount++;
1013 
1014  sw.Stop();
1015  PerformanceCounter.AddElapsedTicks("Update", sw.ElapsedTicks);
1016  PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks * 1000.0f / (float)Stopwatch.Frequency);
1017  }
1018 
1019  if (!Paused)
1020  {
1021  Timing.Alpha = Timing.Accumulator / Timing.Step;
1022  }
1023 
1024  if (performanceCounterTimer.ElapsedMilliseconds > 1000)
1025  {
1026  CurrentUpdateRate = (int)Math.Round(updateCount / (double)(performanceCounterTimer.ElapsedMilliseconds / 1000.0));
1027  performanceCounterTimer.Restart();
1028  updateCount = 0;
1029  }
1030  }
1031 
1032  public static void ResetFrameTime()
1033  {
1034  Timing.Accumulator = 0.0f;
1035  }
1036 
1037  private void FixRazerCortex()
1038  {
1039 #if WINDOWS
1040  //Razer Cortex's overlay is broken.
1041  //For whatever reason, it messes up the blendstate and,
1042  //because MonoGame reasonably assumes that you don't need
1043  //to touch it if you're setting it to the exact same one
1044  //you were already using, it doesn't fix Razer's mess.
1045  //Therefore, we need to change the blendstate TWICE:
1046  //once to force MonoGame to change it, and then again to
1047  //use the blendstate we actually want.
1048  var oldBlendState = GraphicsDevice.BlendState;
1049  GraphicsDevice.BlendState = oldBlendState == BlendState.Opaque ? BlendState.NonPremultiplied : BlendState.Opaque;
1050  GraphicsDevice.BlendState = oldBlendState;
1051 #endif
1052  }
1053 
1057  protected override void Draw(GameTime gameTime)
1058  {
1059  Stopwatch sw = new Stopwatch();
1060  sw.Start();
1061 
1062  FixRazerCortex();
1063 
1064  double deltaTime = gameTime.ElapsedGameTime.TotalSeconds;
1065 
1066  if (Timing.FrameLimit > 0)
1067  {
1068  double step = 1.0 / Timing.FrameLimit;
1069  while (!GameSettings.CurrentConfig.Graphics.VSync && sw.Elapsed.TotalSeconds + deltaTime < step)
1070  {
1071  Thread.Sleep(1);
1072  }
1073  }
1074 
1075  PerformanceCounter.Update(sw.Elapsed.TotalSeconds + deltaTime);
1076 
1077  if (loadingScreenOpen)
1078  {
1079  TitleScreen.Draw(spriteBatch, base.GraphicsDevice, (float)deltaTime);
1080  }
1081  else if (HasLoaded)
1082  {
1083  Screen.Selected.Draw(deltaTime, base.GraphicsDevice, spriteBatch);
1084  }
1085 
1086  if (DebugDraw && GUI.MouseOn != null)
1087  {
1088  spriteBatch.Begin();
1089  if (PlayerInput.IsCtrlDown() && PlayerInput.KeyDown(Keys.G))
1090  {
1091  List<GUIComponent> hierarchy = new List<GUIComponent>();
1092  var currComponent = GUI.MouseOn;
1093  while (currComponent != null)
1094  {
1095  hierarchy.Add(currComponent);
1096  currComponent = currComponent.Parent;
1097  }
1098 
1099  Color[] colors = { Color.Lime, Color.Yellow, Color.Aqua, Color.Red };
1100  for (int index = 0; index < hierarchy.Count; index++)
1101  {
1102  var component = hierarchy[index];
1103  if (component is { MouseRect: var mouseRect, Rect: var rect })
1104  {
1105  if (mouseRect.IsEmpty) { mouseRect = rect; }
1106  mouseRect.Location += (index%2,(index%4)/2);
1107  GUI.DrawRectangle(spriteBatch, mouseRect, colors[index%4]);
1108  }
1109  }
1110  }
1111  else
1112  {
1113  GUI.DrawRectangle(spriteBatch, GUI.MouseOn.MouseRect, Color.Lime);
1114  GUI.DrawRectangle(spriteBatch, GUI.MouseOn.Rect, Color.Cyan);
1115  }
1116  spriteBatch.End();
1117  }
1118 
1119  sw.Stop();
1120  PerformanceCounter.AddElapsedTicks("Draw", sw.ElapsedTicks);
1121  PerformanceCounter.DrawTimeGraph.Update(sw.ElapsedTicks * 1000.0f / (float)Stopwatch.Frequency);
1122  }
1123 
1124 
1125  public static void QuitToMainMenu(bool save, bool showVerificationPrompt)
1126  {
1127  if (showVerificationPrompt)
1128  {
1129  string text = (Screen.Selected is CharacterEditor.CharacterEditorScreen || Screen.Selected is SubEditorScreen) ? "PauseMenuQuitVerificationEditor" : "PauseMenuQuitVerification";
1130  var msgBox = new GUIMessageBox("", TextManager.Get(text), new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("Cancel") })
1131  {
1132  UserData = "verificationprompt"
1133  };
1134  msgBox.Buttons[0].OnClicked = (yesBtn, userdata) =>
1135  {
1136  QuitToMainMenu(save);
1137  return true;
1138  };
1139  msgBox.Buttons[0].OnClicked += msgBox.Close;
1140  msgBox.Buttons[1].OnClicked += msgBox.Close;
1141  }
1142  }
1143 
1144  public static void QuitToMainMenu(bool save)
1145  {
1146  CreatureMetrics.Save();
1147  if (save)
1148  {
1149  GUI.SetSavingIndicatorState(true);
1150 
1153  {
1155  }
1157 
1158  SaveUtil.SaveGame(GameSession.DataPath);
1159  }
1160 
1161  if (Client != null)
1162  {
1163  Client.Quit();
1164  Client = null;
1165  }
1166 
1167  CoroutineManager.StopCoroutines("EndCinematic");
1168 
1169  if (GameSession != null)
1170  {
1171  GameAnalyticsManager.AddProgressionEvent(GameAnalyticsManager.ProgressionStatus.Fail,
1172  GameSession.GameMode?.Preset.Identifier.Value ?? "none",
1174  string eventId = "QuitRound:" + (GameSession.GameMode?.Preset.Identifier.Value ?? "none") + ":";
1175  GameAnalyticsManager.AddDesignEvent(eventId + "EventManager:CurrentIntensity", GameSession.EventManager.CurrentIntensity);
1176  foreach (var activeEvent in GameSession.EventManager.ActiveEvents)
1177  {
1178  GameAnalyticsManager.AddDesignEvent(eventId + "EventManager:ActiveEvents:" + activeEvent.Prefab.Identifier);
1179  }
1180  GameSession.LogEndRoundStats(eventId);
1181  if (GameSession.GameMode is TutorialMode tutorialMode)
1182  {
1183  tutorialMode.Tutorial?.Stop();
1184  }
1185  }
1188  GameSession = null;
1189 
1190  GameMain.LuaCs.Stop();
1191  }
1192 
1193  public void ShowBugReporter()
1194  {
1195  if (GUIMessageBox.VisibleBox != null &&
1196  GUIMessageBox.VisibleBox.UserData as string == "bugreporter")
1197  {
1198  return;
1199  }
1200 
1201  var msgBox = new GUIMessageBox(TextManager.Get("bugreportbutton"), "")
1202  {
1203  UserData = "bugreporter",
1204  DrawOnTop = true
1205  };
1206  var linkHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), msgBox.Content.RectTransform)) { Stretch = true, RelativeSpacing = 0.025f };
1207  linkHolder.RectTransform.MaxSize = new Point(int.MaxValue, linkHolder.Rect.Height);
1208 
1209 #if !UNSTABLE
1210  new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), linkHolder.RectTransform), TextManager.Get("bugreportfeedbackform"), style: "MainMenuGUIButton", textAlignment: Alignment.Left)
1211  {
1212  UserData = "https://steamcommunity.com/app/602960/discussions/1/",
1213  OnClicked = (btn, userdata) =>
1214  {
1215  if (!SteamManager.OverlayCustomUrl(userdata as string))
1216  {
1217  ShowOpenUriPrompt(userdata as string);
1218  }
1219  msgBox.Close();
1220  return true;
1221  }
1222  };
1223 #endif
1224 
1225  new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), linkHolder.RectTransform), TextManager.Get("bugreportgithubform"), style: "MainMenuGUIButton", textAlignment: Alignment.Left)
1226  {
1227  UserData = "https://github.com/FakeFishGames/Barotrauma/discussions/new?category=bug-reports",
1228  OnClicked = (btn, userdata) =>
1229  {
1230  ShowOpenUriPrompt(userdata as string);
1231  msgBox.Close();
1232  return true;
1233  }
1234  };
1235 
1236  msgBox.InnerFrame.RectTransform.MinSize = new Point(0,
1237  msgBox.InnerFrame.Rect.Height + linkHolder.Rect.Height + msgBox.Content.AbsoluteSpacing * 2 + (int)(50 * GUI.Scale));
1238  }
1239 
1240  static bool waitForKeyHit = true;
1241  public CoroutineHandle ShowLoading(IEnumerable<CoroutineStatus> loader, bool waitKeyHit = true)
1242  {
1243  waitForKeyHit = waitKeyHit;
1244  loadingScreenOpen = true;
1245  TitleScreen.LoadState = 0f;
1246  return CoroutineManager.StartCoroutine(TitleScreen.DoLoading(loader));
1247  }
1248 
1249  protected override void OnExiting(object sender, EventArgs args)
1250  {
1251  IsExiting = true;
1252  CreatureMetrics.Save();
1253  DebugConsole.NewMessage("Exiting...");
1254  Client?.Quit();
1255  SteamManager.ShutDown();
1256 
1257  try
1258  {
1259  SaveUtil.CleanUnnecessarySaveFiles();
1260  }
1261  catch (Exception e)
1262  {
1263  DebugConsole.ThrowError("Error while cleaning unnecessary save files", e);
1264  }
1265 
1266  if (GameAnalyticsManager.SendUserStatistics) { GameAnalyticsManager.ShutDown(); }
1267  if (GameSettings.CurrentConfig.SaveDebugConsoleLogs
1268  || GameSettings.CurrentConfig.VerboseLogging) { DebugConsole.SaveLogs(); }
1269 
1270  base.OnExiting(sender, args);
1271  }
1272 
1273  public static GUIMessageBox ShowOpenUriPrompt(string url, string promptTextTag = "openlinkinbrowserprompt", string promptExtensionTag = null)
1274  {
1275  LocalizedString text = TextManager.GetWithVariable(promptTextTag, "[link]", url);
1276  LocalizedString extensionText = TextManager.Get(promptExtensionTag);
1277  if (!extensionText.IsNullOrEmpty())
1278  {
1279  text += $"\n\n{extensionText}";
1280  }
1281  return ShowOpenUriPrompt(url, text);
1282  }
1283 
1284  public static GUIMessageBox ShowOpenUriPrompt(string url, LocalizedString promptText)
1285  {
1286  if (string.IsNullOrEmpty(url)) { return null; }
1287  if (GUIMessageBox.VisibleBox?.UserData as string == "verificationprompt") { return null; }
1288 
1289  var msgBox = new GUIMessageBox("", promptText, new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") })
1290  {
1291  UserData = "verificationprompt"
1292  };
1293  msgBox.Buttons[0].OnClicked = (btn, userdata) =>
1294  {
1295  try
1296  {
1297  ToolBox.OpenFileWithShell(url);
1298  }
1299  catch (Exception e)
1300  {
1301  DebugConsole.ThrowError($"Failed to open the url {url}", e);
1302  }
1303  msgBox.Close();
1304  return true;
1305  };
1306  msgBox.Buttons[1].OnClicked = msgBox.Close;
1307  return msgBox;
1308  }
1309 
1310  /*
1311  * On some systems, IME input is enabled by default, and being able to set the game to a state
1312  * where it doesn't accept IME input on game launch seems very inconsistent.
1313  * This function quickly cycles through IME input states and is called from couple different places
1314  * to ensure that IME input is disabled properly when it's not needed.
1315  */
1316  public static void ResetIMEWorkaround()
1317  {
1318  Rectangle rect = new Rectangle(0, 0, GraphicsWidth, GraphicsHeight);
1319  TextInput.SetTextInputRect(rect);
1320  TextInput.StartTextInput();
1321  TextInput.SetTextInputRect(rect);
1322  TextInput.StopTextInput();
1323  }
1324  }
1325 }
void MoveCamera(float deltaTime, bool allowMove=true, bool allowZoom=true, bool allowInput=true, bool? followSub=null)
Definition: Camera.cs:255
void HandleSaveAndQuit()
Handles updating store stock, registering event history and relocating items (i.e....
override void End(CampaignMode.TransitionType transitionType=CampaignMode.TransitionType.None)
Item????????? SelectedItem
The primary selected item. It can be any device that character interacts with. This excludes items li...
Responsible for keeping track of the characters in the player crew, saving and loading their orders,...
RectTransform RectTransform
static readonly List< GUIComponent > MessageBoxes
List< GUIButton > Buttons
static GUIComponent VisibleBox
static int GraphicsWidth
Definition: GameMain.cs:162
static LevelEditorScreen LevelEditorScreen
Definition: GameMain.cs:71
static CharacterEditor.CharacterEditorScreen CharacterEditorScreen
Definition: GameMain.cs:74
static NetLobbyScreen NetLobbyScreen
Definition: GameMain.cs:55
static ContentPackage VanillaContent
Definition: GameMain.cs:84
void ResetViewPort()
Definition: GameMain.cs:384
static bool IsExiting
Definition: GameMain.cs:135
static SpriteEditorScreen SpriteEditorScreen
Definition: GameMain.cs:72
static bool IsFirstLaunch
Definition: GameMain.cs:138
CoroutineHandle ShowLoading(IEnumerable< CoroutineStatus > loader, bool waitKeyHit=true)
Definition: GameMain.cs:1241
static void ResetFrameTime()
Definition: GameMain.cs:1032
static RasterizerState ScissorTestEnable
Definition: GameMain.cs:195
static Thread MainThread
Definition: GameMain.cs:82
static PerformanceCounter PerformanceCounter
Definition: GameMain.cs:37
static GUIMessageBox ShowOpenUriPrompt(string url, string promptTextTag="openlinkinbrowserprompt", string promptExtensionTag=null)
Definition: GameMain.cs:1273
static SubEditorScreen SubEditorScreen
Definition: GameMain.cs:68
static int GraphicsHeight
Definition: GameMain.cs:168
static void QuitToMainMenu(bool save)
Definition: GameMain.cs:1144
static bool ShowPerf
Definition: GameMain.cs:28
static void ExecuteAfterContentFinishedLoading(Action action)
Definition: GameMain.cs:284
Option< ConnectCommand > ConnectCommand
Definition: GameMain.cs:123
override void Draw(GameTime gameTime)
This is called when the game should draw itself.
Definition: GameMain.cs:1057
static Lights.LightManager LightManager
Definition: GameMain.cs:78
static GUIMessageBox ShowOpenUriPrompt(string url, LocalizedString promptText)
Definition: GameMain.cs:1284
static World World
Definition: GameMain.cs:105
override void OnExiting(object sender, EventArgs args)
Definition: GameMain.cs:1249
static ChatMode ActiveChatMode
Definition: GameMain.cs:218
static bool IsMultiplayer
Definition: GameMain.cs:35
static bool IsSingleplayer
Definition: GameMain.cs:34
static readonly Version Version
Definition: GameMain.cs:46
override void UnloadContent()
UnloadContent will be called once per game and is the place to unload all content.
Definition: GameMain.cs:653
Action ResolutionChanged
NOTE: Use very carefully. You need to ensure that you ALWAYS unsubscribe from this when you no longer...
Definition: GameMain.cs:133
static int CurrentUpdateRate
Definition: GameMain.cs:42
static GameScreen GameScreen
Definition: GameMain.cs:52
static ParticleEditorScreen ParticleEditorScreen
Definition: GameMain.cs:70
static MainMenuScreen MainMenuScreen
Definition: GameMain.cs:53
static NetworkMember NetworkMember
Definition: GameMain.cs:190
static CampaignEndScreen CampaignEndScreen
Definition: GameMain.cs:76
static void OnFileDropped(object sender, FileDropEventArgs args)
Definition: GameMain.cs:294
static bool DebugDraw
Definition: GameMain.cs:29
static ParticleManager ParticleManager
Definition: GameMain.cs:101
override void Update(GameTime gameTime)
Allows the game to run logic such as updating the world, checking for collisions, gathering input,...
Definition: GameMain.cs:692
static GameClient Client
Definition: GameMain.cs:188
static GameMain Instance
Definition: GameMain.cs:144
static void QuitToMainMenu(bool save, bool showVerificationPrompt)
Definition: GameMain.cs:1125
static EventEditorScreen EventEditorScreen
Definition: GameMain.cs:73
static bool WindowActive
Definition: GameMain.cs:174
void ShowBugReporter()
Definition: GameMain.cs:1193
void SetWindowMode(WindowMode windowMode)
Definition: GameMain.cs:359
void ApplyGraphicsSettings(bool recalculateFontsAndStyles=false)
Definition: GameMain.cs:309
static ServerListScreen ServerListScreen
Definition: GameMain.cs:66
static TestScreen TestScreen
Definition: GameMain.cs:69
static LoadingScreen TitleScreen
Definition: GameMain.cs:114
static bool DevMode
Doesn't automatically enable los or bot AI or do anything like that. Probably not fully implemented.
Definition: GameMain.cs:33
static LuaCsSetup LuaCs
Definition: GameMain.cs:26
static void ResetNetLobbyScreen()
Definition: GameMain.cs:58
static GraphicsDeviceManager GraphicsDeviceManager
Definition: GameMain.cs:150
override void Initialize()
Allows the game to perform any initialization it needs to before starting to run. This is where it ca...
Definition: GameMain.cs:396
static ModDownloadScreen ModDownloadScreen
Definition: GameMain.cs:56
static void ResetIMEWorkaround()
Definition: GameMain.cs:1316
override void LoadContent()
LoadContent will be called once per game and is the place to load all of your content.
Definition: GameMain.cs:417
static Sounds.SoundManager SoundManager
Definition: GameMain.cs:80
readonly ImmutableArray< string > ConsoleArguments
Definition: GameMain.cs:48
readonly Option< string > EgsExchangeCode
Definition: GameMain.cs:50
static bool ShowFPS
Definition: GameMain.cs:27
GameMain(string[] args)
Definition: GameMain.cs:224
readonly Identifier Identifier
void LogEndRoundStats(string eventId, TraitorManager.TraitorResults? traitorResults=null)
void Update(float newValue)
Definition: Graph.cs:32
IEnumerable< ItemComponent > ActiveHUDs
void Draw(SpriteBatch spriteBatch, GraphicsDevice graphics, float deltaTime)
readonly ConcurrentQueue< PendingSplashScreen > PendingSplashScreens
Triplet.first = filepath, Triplet.second = resolution, Triplet.third = audio gain
LanguageIdentifier[] AvailableLanguages
IEnumerable< CoroutineStatus > DoLoading(IEnumerable< CoroutineStatus > loader)
void QuickStart(bool fixedSeed=false, Identifier sub=default, float difficulty=50, LevelGenerationParams levelGenerationParams=null)
static void Close()
Definition: Video.cs:39
static MultiplayerPreferences Instance
abstract string StringRepresentation
Definition: Endpoint.cs:7
void AddElapsedTicks(string identifier, long ticks)
bool Update(double deltaTime)
static bool KeyDown(InputType inputType)
Point?? MaxSize
Max size in pixels. Does not affect scaling.
virtual void AddToGUIUpdateList()
By default, submits the screen's main GUIFrame and, if requested upon construction,...
virtual void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
static WaterRenderer Instance
static ? SocialOverlay Instance
static void Init()
static CampaignDataPath CreateRegular(string savePath)
Creates a CampaignDataPath with the same load and save path.
static readonly LanguageIdentifier None
Definition: TextPack.cs:12