Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaClient/Source/GameMain.cs
T
Joonas Rikkonen 58c92888b7 2ad9b5d...2f107db
commit 2f107db0475bf4b9a8b6f405b9ce8ec489cbc0ba
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Thu Feb 7 16:30:24 2019 +0200

    Another nullref fix to the OpenHealthWindow property setter. Closes #1090

commit 1d15d18d2501bedaa1b42ac8e0e7e09e2600960e
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Thu Feb 7 16:19:05 2019 +0200

    Fixed crashing when an incompatible content package is selected in config.xml or if the content package cannot be found. Happened because the game attempted to use TextManager.Get before text files had been loaded. Partially fixes #1093

commit 9ec1980fe90bcae65333c188b265ba16a6db6c05
Author: ezjamsen <ezjames.fi@gmail.com>
Date:   Thu Feb 7 16:16:53 2019 +0200

    added correct effects for alien blood

commit b6d2c56910b5d58477703abc6785ef80719a89a6
Author: ezjamsen <ezjames.fi@gmail.com>
Date:   Thu Feb 7 15:41:25 2019 +0200

    adjustments to fent, glue and antibiotics

commit 8df16acdaac0a521fe09fb62c6815a46a87f6f25
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Thu Feb 7 15:30:51 2019 +0200

    More descriptive ping exception error messages (only shown in debug builds now), some extra checks to prevent using the workshop without steam (although the checks that actually matter are implemented at Steam's side now)

commit 959c503c140196287ab60ec2357feb8bd5c85b18
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Thu Feb 7 14:00:48 2019 +0200

    Don't allow severing the joint between a moloch's shell and the "bladder"

commit 0c0b033016c2e82b8cf1b5a4e3f6faa9cde39f40
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Thu Feb 7 13:51:58 2019 +0200

    Fixed incorrect item panel positioning in the crew command interface when the sub is docked to something. Closes #1082

commit 68366a4bf3c73b70288f043199d3ab9b2f5f4d06
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Thu Feb 7 13:23:38 2019 +0200

    Fixed outdated damage modifiers in security and clown gear (used damage types instead of afflictions), not defining any affliction types for a damage modifier makes it affect all types of damage. Closes #1088

commit 5d3ab5084b8bc5357bc4a53993ad8dfcc44d0412
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Thu Feb 7 13:04:55 2019 +0200

    Fixed client-side nullref exception if the round ends while the health window is open. Closes #1090

commit 8249d789a60dfe4bcdd1705d26d6ca36ed407058
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Thu Feb 7 12:48:34 2019 +0200

    The dedicated server doesn't initialize a Steam client (not required to use any of the Steam server functionality). Fixes players being unable to log in as a client when they're hosting a dedicated server on another machine. TODO: SteamCMD support

commit 55fb0bb1ba4bb8385dabbf6e40d4651bf86294a9
Author: ezjamsen <ezjames.fi@gmail.com>
Date:   Thu Feb 7 12:31:46 2019 +0200

    Added linked hulls

commit 937d50dca50d8c889a7c11b55765c208d2d16b67
Merge: 8109ae1a3 57731761f
Author: EdusFF <pitkanen.eetu@gmail.com>
Date:   Thu Feb 7 12:16:43 2019 +0200

    Merge branch 'dev' of https://github.com/Regalis11/Barotrauma into dev

commit 8109ae1a3377910ff9bf066ccac582d879dfb0a4
Author: EdusFF <pitkanen.eetu@gmail.com>
Date:   Thu Feb 7 12:16:37 2019 +0200

    Fixed: AI not reloading coilgun if an empty box of ammunition is inserted.

commit 57731761f64bb33a4f4e7baa38367cfb7cf1f873
Author: itchyOwl <lauri.harkanen@gmail.com>
Date:   Thu Feb 7 12:10:59 2019 +0200

    Refactor character head customization logic and store the data in a dedicated class. In the net lobby, generate new head when the user presses the right arrow button. Pressing the left arrow will restore the previous head. When the user presses the right arrow after the left arrow, the first head is restored again. So it's effectively (and technically) undo/redo logic.

commit 37577931e2706ce432cee2d48cd55990bc2bab4a
Author: itchyOwl <lauri.harkanen@gmail.com>
Date:   Thu Feb 7 12:04:49 2019 +0200

    Add properties for getting the count of the undo and redo stacks.

commit f226beb05a55749ac961e3a33ac594fdf903fc3b
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Wed Feb 6 21:15:56 2019 +0200

    Fixes to hull linking & displaying them as one hull on the minimap:
    - Links between hulls are now saved.
    - Simplified grouping logic (just store a list of linked hulls in hulldata).
    - Fixed water/oxygen calculations (use the average of the values instead of their sum).
    TODO: DRY (there's now duplicate linking logic in Item and Hull), merge the hull sprites on the minimap, maybe automatize the linking?

commit 5dfea1fbb24c5bd91605caf65baaac9aca9cfbbf
Merge: 2ad9b5de4 d06a1557f
Author: Joonas Rikkonen <poe.regalis@gmail.com>
Date:   Wed Feb 6 20:18:31 2019 +0200

    Merge branch 'dev' of https://github.com/Regalis11/Barotrauma into dev

commit d06a1557ffb85cd32bbb884fadef60b6d9dd27cf
Author: Alex <olimpickusa6@gmail.com>
Date:   Wed Feb 6 18:26:40 2019 +0200

    Test for connecting hulls task
2019-03-18 21:13:11 +02:00

692 lines
25 KiB
C#

using Barotrauma.Networking;
using Barotrauma.Particles;
using Barotrauma.Steam;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using GameAnalyticsSDK.Net;
using System.IO;
using System.Threading;
using Barotrauma.Tutorials;
namespace Barotrauma
{
class GameMain : Game
{
public static bool ShowFPS = false;
public static bool ShowPerf = false;
public static bool DebugDraw;
public static bool IsMultiplayer => Client != null || Server != null;
public static PerformanceCounter PerformanceCounter;
public static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version;
public static GameScreen GameScreen;
public static MainMenuScreen MainMenuScreen;
public static LobbyScreen LobbyScreen;
public static NetLobbyScreen NetLobbyScreen;
public static ServerListScreen ServerListScreen;
public static SteamWorkshopScreen SteamWorkshopScreen;
public static SubEditorScreen SubEditorScreen;
public static ParticleEditorScreen ParticleEditorScreen;
public static LevelEditorScreen LevelEditorScreen;
public static SpriteEditorScreen SpriteEditorScreen;
public static CharacterEditorScreen CharacterEditorScreen;
public static Lights.LightManager LightManager;
public static Sounds.SoundManager SoundManager;
public static HashSet<ContentPackage> SelectedPackages
{
get { return Config?.SelectedContentPackages; }
}
private static ContentPackage vanillaContent;
public static ContentPackage VanillaContent
{
get
{
if (vanillaContent == null)
{
// TODO: Dynamic method for defining and finding the vanilla content package.
vanillaContent = SelectedPackages.Single(cp => Path.GetFileName(cp.Path).ToLowerInvariant() == "vanilla 0.9.xml");
}
return vanillaContent;
}
}
private static GameSession gameSession;
public static GameSession GameSession
{
get { return gameSession; }
set
{
if (gameSession == value) { return; }
if (gameSession?.GameMode != null && gameSession.GameMode != value?.GameMode)
{
gameSession.GameMode.Remove();
}
gameSession = value;
}
}
public static NetworkMember NetworkMember;
public static ParticleManager ParticleManager;
public static DecalManager DecalManager;
public static World World;
public static LoadingScreen TitleScreen;
private bool loadingScreenOpen;
public static GameSettings Config;
private CoroutineHandle loadingCoroutine;
private bool hasLoaded;
private GameTime fixedTime;
private static SpriteBatch spriteBatch;
private Viewport defaultViewport;
public event Action OnResolutionChanged;
public static GameMain Instance
{
get;
private set;
}
public static GraphicsDeviceManager GraphicsDeviceManager
{
get;
private set;
}
private static bool FullscreenOnTabIn;
public static WindowMode WindowMode
{
get;
private set;
}
public static int GraphicsWidth
{
get;
private set;
}
public static int GraphicsHeight
{
get;
private set;
}
public static bool WindowActive
{
get { return Instance == null || Instance.IsActive; }
}
public static GameServer Server
{
get { return NetworkMember as GameServer; }
}
public static GameClient Client
{
get { return NetworkMember as GameClient; }
}
public static RasterizerState ScissorTestEnable
{
get;
private set;
}
public bool LoadingScreenOpen
{
get { return loadingScreenOpen; }
}
public GameMain()
{
GraphicsDeviceManager = new GraphicsDeviceManager(this);
Window.Title = "Barotrauma";
Instance = this;
Config = new GameSettings("config.xml");
if (Config.WasGameUpdated)
{
UpdaterUtil.CleanOldFiles();
Config.WasGameUpdated = false;
Config.Save();
}
ApplyGraphicsSettings();
Content.RootDirectory = "Content";
PerformanceCounter = new PerformanceCounter();
IsFixedTimeStep = false;
Timing.Accumulator = 0.0f;
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;
}
public void ApplyGraphicsSettings()
{
GraphicsWidth = Config.GraphicsWidth;
GraphicsHeight = Config.GraphicsHeight;
GraphicsDeviceManager.GraphicsProfile = GraphicsProfile.Reach;
GraphicsDeviceManager.PreferredBackBufferFormat = SurfaceFormat.Color;
GraphicsDeviceManager.PreferMultiSampling = false;
GraphicsDeviceManager.SynchronizeWithVerticalRetrace = Config.VSyncEnabled;
if (Config.WindowMode == WindowMode.Windowed)
{
//for whatever reason, window isn't centered automatically
//since MonoGame 3.6 (nuget package might be broken), so
//let's do it manually
Window.Position = new Point((GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width - GraphicsWidth) / 2,
(GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height - GraphicsHeight) / 2);
}
GraphicsDeviceManager.PreferredBackBufferWidth = GraphicsWidth;
GraphicsDeviceManager.PreferredBackBufferHeight = GraphicsHeight;
SetWindowMode(Config.WindowMode);
defaultViewport = GraphicsDevice.Viewport;
OnResolutionChanged?.Invoke();
}
public void SetWindowMode(WindowMode windowMode)
{
WindowMode = windowMode;
#if !(OSX)
GraphicsDeviceManager.HardwareModeSwitch = Config.WindowMode != WindowMode.BorderlessWindowed;
#else
// Force borderless on macOS.
GraphicsDeviceManager.HardwareModeSwitch = Config.WindowMode != WindowMode.BorderlessWindowed && Config.WindowMode != WindowMode.Fullscreen;
#endif
GraphicsDeviceManager.IsFullScreen = Config.WindowMode == WindowMode.Fullscreen || Config.WindowMode == WindowMode.BorderlessWindowed;
Window.IsBorderless = !GraphicsDeviceManager.HardwareModeSwitch;
GraphicsDeviceManager.ApplyChanges();
}
public void ResetViewPort()
{
GraphicsDevice.Viewport = defaultViewport;
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
base.Initialize();
ScissorTestEnable = new RasterizerState() { ScissorTestEnable = true };
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Character));
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Item));
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Items.Components.ItemComponent));
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Hull));
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
GraphicsWidth = GraphicsDevice.Viewport.Width;
GraphicsHeight = GraphicsDevice.Viewport.Height;
ConvertUnits.SetDisplayUnitToSimUnitRatio(Physics.DisplayToSimRation);
spriteBatch = new SpriteBatch(GraphicsDevice);
TextureLoader.Init(GraphicsDevice);
loadingScreenOpen = true;
TitleScreen = new LoadingScreen(GraphicsDevice);
loadingCoroutine = CoroutineManager.StartCoroutine(Load());
#if WINDOWS
var myForm = (System.Windows.Forms.Form)System.Windows.Forms.Form.FromHandle(Window.Handle);
myForm.Deactivate += new EventHandler(HandleDefocus);
myForm.Activated += new EventHandler(HandleFocus);
#endif
}
private void HandleDefocus(object sender, EventArgs e)
{
if (GraphicsDeviceManager.IsFullScreen && GraphicsDeviceManager.HardwareModeSwitch)
{
GraphicsDeviceManager.IsFullScreen = false;
GraphicsDeviceManager.ApplyChanges();
FullscreenOnTabIn = true;
Thread.Sleep(500);
}
}
private void HandleFocus(object sender, EventArgs e)
{
if (FullscreenOnTabIn)
{
GraphicsDeviceManager.HardwareModeSwitch = true;
GraphicsDeviceManager.IsFullScreen = true;
GraphicsDeviceManager.ApplyChanges();
FullscreenOnTabIn = false;
Thread.Sleep(500);
}
}
private void InitUserStats()
{
if (GameSettings.ShowUserStatisticsPrompt)
{
var userStatsPrompt = new GUIMessageBox(
"Do you want to help us make Barotrauma better?",
"Do you allow Barotrauma to send usage statistics and error reports to the developers? The data is anonymous, " +
"does not contain any personal information and is only used to help us diagnose issues and improve Barotrauma.",
new string[] { "Yes", "No" });
userStatsPrompt.Buttons[0].OnClicked += (btn, userdata) =>
{
GameSettings.ShowUserStatisticsPrompt = false;
GameSettings.SendUserStatistics = true;
GameAnalyticsManager.Init();
return true;
};
userStatsPrompt.Buttons[0].OnClicked += userStatsPrompt.Close;
userStatsPrompt.Buttons[1].OnClicked += (btn, userdata) =>
{
GameSettings.ShowUserStatisticsPrompt = false;
GameSettings.SendUserStatistics = false;
return true;
};
userStatsPrompt.Buttons[1].OnClicked += userStatsPrompt.Close;
}
else if (GameSettings.SendUserStatistics)
{
GameAnalyticsManager.Init();
}
}
private IEnumerable<object> Load()
{
if (GameSettings.VerboseLogging)
{
DebugConsole.NewMessage("LOADING COROUTINE", Color.Lime);
}
SoundManager = new Sounds.SoundManager();
SoundManager.SetCategoryGainMultiplier("default", Config.SoundVolume);
SoundManager.SetCategoryGainMultiplier("ui", Config.SoundVolume);
SoundManager.SetCategoryGainMultiplier("waterambience", Config.SoundVolume);
SoundManager.SetCategoryGainMultiplier("music", Config.MusicVolume);
GUI.Init(Window, Config.SelectedContentPackages, GraphicsDevice);
DebugConsole.Init();
SteamManager.Initialize();
if (SelectedPackages.Count == 0)
{
DebugConsole.Log("No content packages selected");
}
else
{
DebugConsole.Log("Selected content packages: " + string.Join(", ", SelectedPackages.Select(cp => cp.Name)));
}
InitUserStats();
yield return CoroutineStatus.Running;
LightManager = new Lights.LightManager(base.GraphicsDevice, Content);
WaterRenderer.Instance = new WaterRenderer(base.GraphicsDevice, Content);
TitleScreen.LoadState = 1.0f;
yield return CoroutineStatus.Running;
GUI.LoadContent();
TitleScreen.LoadState = 2.0f;
yield return CoroutineStatus.Running;
MissionPrefab.Init();
MapEntityPrefab.Init();
Tutorials.Tutorial.Init();
MapGenerationParams.Init();
LevelGenerationParams.LoadPresets();
ScriptedEventSet.LoadPrefabs();
AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions));
TitleScreen.LoadState = 10.0f;
yield return CoroutineStatus.Running;
StructurePrefab.LoadAll(GetFilesOfType(ContentType.Structure));
TitleScreen.LoadState = 15.0f;
yield return CoroutineStatus.Running;
ItemPrefab.LoadAll(GetFilesOfType(ContentType.Item));
TitleScreen.LoadState = 25.0f;
yield return CoroutineStatus.Running;
JobPrefab.LoadAll(GetFilesOfType(ContentType.Jobs));
// Add any missing jobs from the prefab into Config.JobNamePreferences.
foreach (JobPrefab job in JobPrefab.List)
{
if (!Config.JobPreferences.Contains(job.Identifier)) { Config.JobPreferences.Add(job.Identifier); }
}
NPCConversation.LoadAll(GetFilesOfType(ContentType.NPCConversations));
ItemAssemblyPrefab.LoadAll();
TitleScreen.LoadState = 30.0f;
yield return CoroutineStatus.Running;
Debug.WriteLine("sounds");
var soundLoadingCoroutine = CoroutineManager.StartCoroutine(SoundPlayer.Init());
int i = 0;
while (!SoundPlayer.Initialized)
{
if (soundLoadingCoroutine.Exception != null)
{
throw soundLoadingCoroutine.Exception;
}
i++;
TitleScreen.LoadState = SoundPlayer.SoundCount == 0 ?
30.0f :
Math.Min(30.0f + 40.0f * i / Math.Max(SoundPlayer.SoundCount, 1), 70.0f);
yield return CoroutineStatus.Running;
}
TitleScreen.LoadState = 70.0f;
yield return CoroutineStatus.Running;
GameModePreset.Init();
Submarine.RefreshSavedSubs();
TitleScreen.LoadState = 80.0f;
yield return CoroutineStatus.Running;
GameScreen = new GameScreen(GraphicsDeviceManager.GraphicsDevice, Content);
TitleScreen.LoadState = 90.0f;
yield return CoroutineStatus.Running;
MainMenuScreen = new MainMenuScreen(this);
LobbyScreen = new LobbyScreen();
ServerListScreen = new ServerListScreen();
if (SteamManager.USE_STEAM)
{
SteamWorkshopScreen = new SteamWorkshopScreen();
}
SubEditorScreen = new SubEditorScreen();
ParticleEditorScreen = new ParticleEditorScreen();
LevelEditorScreen = new LevelEditorScreen();
SpriteEditorScreen = new SpriteEditorScreen();
CharacterEditorScreen = new CharacterEditorScreen();
yield return CoroutineStatus.Running;
ParticleManager = new ParticleManager(GameScreen.Cam);
ParticleManager.LoadPrefabs();
LevelObjectPrefab.LoadAll();
DecalManager = new DecalManager();
yield return CoroutineStatus.Running;
LocationType.Init();
MainMenuScreen.Select();
CheckContentPackage();
TitleScreen.LoadState = 100.0f;
hasLoaded = true;
if (GameSettings.VerboseLogging)
{
DebugConsole.NewMessage("LOADING COROUTINE FINISHED", Color.Lime);
}
yield return CoroutineStatus.Success;
}
private void CheckContentPackage()
{
foreach (ContentPackage contentPackage in Config.SelectedContentPackages)
{
var exePaths = contentPackage.GetFilesOfType(ContentType.Executable);
if (exePaths.Count() > 0 && AppDomain.CurrentDomain.FriendlyName != exePaths.First())
{
var msgBox = new GUIMessageBox(TextManager.Get("Error"),
TextManager.Get("IncorrectExe")
.Replace("[selectedpackage]", contentPackage.Name)
.Replace("[exename]", exePaths.First()),
new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
msgBox.Buttons[0].OnClicked += (_, userdata) =>
{
string fullPath = Path.GetFullPath(exePaths.First());
Process.Start(fullPath);
Exit();
return true;
};
msgBox.Buttons[1].OnClicked = msgBox.Close;
break;
}
}
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
SoundManager.Dispose();
}
/// <summary>
/// Returns the file paths of all files of the given type in the currently selected content packages.
/// </summary>
public IEnumerable<string> GetFilesOfType(ContentType type)
{
return ContentPackage.GetFilesOfType(SelectedPackages, type);
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
Timing.TotalTime = gameTime.TotalGameTime.TotalSeconds;
Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds;
int updateIterations = (int)Math.Floor(Timing.Accumulator / Timing.Step);
if (Timing.Accumulator > Timing.Step * 6.0)
{
//if the game's running too slowly then we have no choice
//but to skip a bunch of steps
//otherwise it snowballs and becomes unplayable
Timing.Accumulator = Timing.Step;
}
PlayerInput.UpdateVariable();
bool paused = true;
while (Timing.Accumulator >= Timing.Step)
{
Stopwatch sw = new Stopwatch();
sw.Start();
fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly;
TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16);
fixedTime.ElapsedGameTime = addTime;
fixedTime.TotalGameTime.Add(addTime);
base.Update(fixedTime);
PlayerInput.Update(Timing.Step);
if (loadingScreenOpen)
{
//reset accumulator if loading
// -> less choppy loading screens because the screen is rendered after each update
// -> no pause caused by leftover time in the accumulator when starting a new shift
Timing.Accumulator = 0.0f;
if (TitleScreen.LoadState >= 100.0f &&
(!waitForKeyHit || PlayerInput.GetKeyboardState.GetPressedKeys().Length>0 || PlayerInput.LeftButtonClicked()))
{
loadingScreenOpen = false;
}
if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine))
{
string errMsg = "Loading was interrupted due to an error";
if (loadingCoroutine.Exception != null)
{
errMsg += ": " + loadingCoroutine.Exception.Message + "\n" + loadingCoroutine.Exception.StackTrace;
}
throw new Exception(errMsg);
}
}
else if (hasLoaded)
{
SoundPlayer.Update((float)Timing.Step);
if (PlayerInput.KeyHit(Keys.Escape)) GUI.TogglePauseMenu();
GUI.ClearUpdateList();
paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen || ContextualTutorial.ContentRunning) &&
(NetworkMember == null || !NetworkMember.GameStarted);
Screen.Selected.AddToGUIUpdateList();
if (NetworkMember != null)
{
NetworkMember.AddToGUIUpdateList();
}
DebugConsole.AddToGUIUpdateList();
DebugConsole.Update(this, (float)Timing.Step);
paused = paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted));
if (!paused)
{
Screen.Selected.Update(Timing.Step);
}
else if (ContextualTutorial.Initialized && ContextualTutorial.ContentRunning && GameSession.GameMode is SinglePlayerCampaign)
{
(GameSession.GameMode as SinglePlayerCampaign).ContextualTutorial.Update((float)Timing.Step);
}
if (NetworkMember != null)
{
NetworkMember.Update((float)Timing.Step);
}
GUI.Update((float)Timing.Step);
}
CoroutineManager.Update((float)Timing.Step, paused ? 0.0f : (float)Timing.Step);
SteamManager.Update((float)Timing.Step);
Timing.Accumulator -= Timing.Step;
sw.Stop();
PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks);
PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks / (float)TimeSpan.TicksPerMillisecond);
PerformanceCounter.UpdateIterationsGraph.Update(updateIterations);
}
if (!paused) Timing.Alpha = Timing.Accumulator / Timing.Step;
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
protected override void Draw(GameTime gameTime)
{
Stopwatch sw = new Stopwatch();
sw.Start();
double deltaTime = gameTime.ElapsedGameTime.TotalSeconds;
PerformanceCounter.Update(deltaTime);
if (loadingScreenOpen)
{
TitleScreen.Draw(spriteBatch, base.GraphicsDevice, (float)deltaTime);
}
else if (hasLoaded)
{
Screen.Selected.Draw(deltaTime, base.GraphicsDevice, spriteBatch);
}
if (DebugDraw && GUI.MouseOn != null)
{
spriteBatch.Begin();
GUI.DrawRectangle(spriteBatch, GUI.MouseOn.MouseRect, Color.Lime);
spriteBatch.End();
}
sw.Stop();
PerformanceCounter.AddElapsedTicks("Draw total", sw.ElapsedTicks);
PerformanceCounter.DrawTimeGraph.Update(sw.ElapsedTicks / (float)TimeSpan.TicksPerMillisecond);
}
static bool waitForKeyHit = true;
public CoroutineHandle ShowLoading(IEnumerable<object> loader, bool waitKeyHit = true)
{
waitForKeyHit = waitKeyHit;
loadingScreenOpen = true;
TitleScreen.LoadState = null;
return CoroutineManager.StartCoroutine(TitleScreen.DoLoading(loader));
}
protected override void OnExiting(object sender, EventArgs args)
{
if (NetworkMember != null) NetworkMember.Disconnect();
SteamManager.ShutDown();
if (GameSettings.SendUserStatistics) GameAnalytics.OnStop();
base.OnExiting(sender, args);
}
}
}