#region File Description
//-----------------------------------------------------------------------------
// ProfileSignInScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.GamerServices;
using GameStateManagement;
#endregion
namespace CatapultGame
{
///
/// In order to play a networked game, you must have a player profile signed in.
/// If you want to play on Live, that has to be a Live profile. Rather than just
/// failing with an error message, it is nice if we can automatically bring up the
/// Guide screen when we detect that no suitable profiles are currently signed in,
/// so the user can easily correct the problem. This screen checks the sign in
/// state, and brings up the Guide user interface if there is a problem with it.
/// It then raises an event as soon as a valid profile has been signed in.
///
/// There are two scenarios for how this can work. If no good profile is signed in:
///
/// - MainMenuScreen activates the ProfileSignInScreen
/// - ProfileSignInScreen activates the Guide user interface
/// - User signs in a profile
/// - ProfileSignInScreen raises the ProfileSignedIn event
/// - This advances to the CreateOrFindSessionScreen
///
/// Alternatively, there might already be a valid profile signed in. In this case:
///
/// - MainMenuScreen activates the ProfileSignInScreen
/// - ProfileSignInScreen notices everything is already good
/// - ProfileSignInScreen raises the ProfileSignedIn event
/// - This advances to the CreateOrFindSessionScreen
///
/// In this second case, the ProfileSignInScreen is only active for a single
/// Update, so the user just sees a transition directly from the MainMenuScreen
/// to the CreateOrFindSessionScreen.
///
class ProfileSignInScreen : GameScreen
{
#region Fields
NetworkSessionType sessionType;
bool haveShownGuide;
bool haveShownMarketplace;
#endregion
#region Events
public event EventHandler ProfileSignedIn;
#endregion
#region Initialization
///
/// Constructs a new profile sign in screen.
///
public ProfileSignInScreen(NetworkSessionType sessionType)
{
this.sessionType = sessionType;
IsPopup = true;
}
#endregion
#region Update
///
/// Updates the profile sign in screen.
///
public override void Update(GameTime gameTime, bool otherScreenHasFocus,
bool coveredByOtherScreen)
{
base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
if (ValidProfileSignedIn())
{
// As soon as we detect a suitable profile is signed in,
// we raise the profile signed in event, then go away.
if (ProfileSignedIn != null)
ProfileSignedIn(this, EventArgs.Empty);
ExitScreen();
}
else if (IsActive && !Guide.IsVisible)
{
// If we are in trial mode, and they want to play online, and a profile
// is signed in, take them to marketplace so they can purchase the game.
if ((Guide.IsTrialMode) &&
(NetworkSessionComponent.IsOnlineSessionType(sessionType)) &&
(Gamer.SignedInGamers[ControllingPlayer.Value] != null) &&
(!haveShownMarketplace))
{
ShowMarketplace();
haveShownMarketplace = true;
}
else if (!haveShownGuide && !haveShownMarketplace)
{
// No suitable profile is signed in, and we haven't already shown
// the Guide. Let's show it now, so they can sign in a profile.
Guide.ShowSignIn(1,
NetworkSessionComponent.IsOnlineSessionType(sessionType));
haveShownGuide = true;
}
else
{
// Hmm. No suitable profile is signed in, but we already showed
// the Guide, and the Guide isn't still visible. There is only
// one thing that can explain this: they must have cancelled the
// Guide without signing in a profile. We'd better just exit,
// which will leave us on the same menu as before.
ExitScreen();
}
}
}
///
/// Helper checks whether a valid player profile is signed in.
///
bool ValidProfileSignedIn()
{
// If there is no profile signed in, that is never good.
SignedInGamer gamer = Gamer.SignedInGamers[ControllingPlayer.Value];
if (gamer == null)
return false;
// If we want to play in a Live session, also make sure the profile is
// signed in to Live, and that it has the privilege for online gameplay.
if (NetworkSessionComponent.IsOnlineSessionType(sessionType))
{
if (!gamer.IsSignedInToLive)
return false;
if (!gamer.Privileges.AllowOnlineSessions)
return false;
}
// Okeydokey, this looks good.
return true;
}
///
/// LIVE networking is not supported in trial mode. Rather than just giving
/// the user an error, this function asks if they want to purchase the full
/// game, then takes them to Marketplace where they can do that. Once the
/// Guide is active, the user can either make the purchase, or cancel it.
/// When the Guide closes, ProfileSignInScreen.Update will notice that
/// Guide.IsVisible has gone back to false, at which point it will check if
/// the game is still in trial mode, and either exit the screen or proceed
/// forward accordingly.
///
void ShowMarketplace()
{
MessageBoxScreen confirmMarketplaceMessageBox =
new MessageBoxScreen(Resources.ConfirmMarketplace);
confirmMarketplaceMessageBox.Accepted += delegate
{
Guide.ShowMarketplace(ControllingPlayer.Value);
};
ScreenManager.AddScreen(confirmMarketplaceMessageBox, ControllingPlayer);
}
#endregion
}
}