254 lines
6.9 KiB
Ucode
254 lines
6.9 KiB
Ucode
/**
|
|
* Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
|
|
*/
|
|
|
|
/**
|
|
* This class is responsible for mapping properties in an OnlineStatsRead
|
|
* class to the UI. It maintains a set of different read objects that are
|
|
* switched between at run time. This allows you to show leaderboards by
|
|
* age (one week, month, year, etc.) from the same UI by having this
|
|
* data store just use different query objects
|
|
*
|
|
* NOTE: Each game needs to derive at least one class from this one in
|
|
* order to expose the game's specific stats class(es)
|
|
*/
|
|
class UIDataStore_OnlineStats extends UIDataStore_Remote
|
|
native(inherit)
|
|
abstract
|
|
transient;
|
|
|
|
/**
|
|
* The OnlineStatsRead derived classes to load and populate the UI with
|
|
*/
|
|
var array<class<OnlineStatsRead> > StatsReadClasses;
|
|
|
|
/** Cached FName for faster compares */
|
|
var const name StatsReadName;
|
|
|
|
struct native PlayerNickMetaData
|
|
{
|
|
/** Cached FName for faster compares */
|
|
var const name PlayerNickName;
|
|
/** The name displayed in column headings in the UI */
|
|
var localized string PlayerNickColumnName;
|
|
};
|
|
|
|
var const PlayerNickMetaData PlayerNickData;
|
|
|
|
struct native RankMetaData
|
|
{
|
|
/** Cached FName for faster compares */
|
|
var const name RankName;
|
|
/** The name displayed in column headings in the UI */
|
|
var localized string RankColumnName;
|
|
};
|
|
|
|
/** Cached FName for faster compares */
|
|
var const RankMetaData RankNameMetaData;
|
|
|
|
/** Cached FName for faster compares */
|
|
var const name TotalRowsName;
|
|
|
|
/** The set of stats read objects that will be used for display purposes */
|
|
var array<OnlineStatsRead> StatsReadObjects;
|
|
|
|
/**
|
|
* The OnlineStatsRead object that will be exposed to the UI. One of the objects
|
|
* from the array above. The game specific version of this class needs to change
|
|
* the current setting based on its rules
|
|
*/
|
|
var OnlineStatsRead StatsRead;
|
|
|
|
/** The types of stats to fetch */
|
|
enum EStatsFetchType
|
|
{
|
|
/** The player's stats */
|
|
SFT_Player,
|
|
/** The player and people above/below them */
|
|
SFT_CenteredOnPlayer,
|
|
/** The player's frinds list and them */
|
|
SFT_Friends,
|
|
/** The top n ranked players */
|
|
SFT_TopRankings,
|
|
};
|
|
|
|
/** The current type to read */
|
|
var EStatsFetchType CurrentReadType;
|
|
|
|
/** The stats interface to use for reading stats data */
|
|
var OnlineStatsInterface StatsInterface;
|
|
|
|
/** The player interface to use for performing player specific functions */
|
|
var OnlinePlayerInterface PlayerInterface;
|
|
|
|
cpptext
|
|
{
|
|
protected:
|
|
// UIDataStore interface
|
|
|
|
/**
|
|
* Loads and creates an instance of the registered stats read object
|
|
*/
|
|
virtual void InitializeDataStore(void);
|
|
}
|
|
|
|
/**
|
|
* Grabs the interface pointers and sets the read delegate
|
|
*/
|
|
event Init()
|
|
{
|
|
local OnlineSubsystem OnlineSub;
|
|
|
|
OnlineSub = class'GameEngine'.static.GetOnlineSubsystem();
|
|
if ( OnlineSub != None )
|
|
{
|
|
// Grab the stats and player interfaces
|
|
StatsInterface = OnlineSub.StatsInterface;
|
|
PlayerInterface = OnlineSub.PlayerInterface;
|
|
|
|
// Set the delegate that tells the UI to refresh
|
|
StatsInterface.AddReadOnlineStatsCompleteDelegate(OnReadComplete);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function should be overloaded with a game specific version. It is used
|
|
* to determine which search class to use and in which mode
|
|
*/
|
|
function SetStatsReadInfo()
|
|
{
|
|
StatsRead = StatsReadObjects[0];
|
|
CurrentReadType = SFT_Player;
|
|
}
|
|
|
|
/**
|
|
* Tells the online subsystem to re-read the stats data using the current read
|
|
* mode and the current object to add the results to
|
|
*/
|
|
event bool RefreshStats(byte ControllerIndex)
|
|
{
|
|
SetStatsReadInfo();
|
|
// Clear the previous results and tell the UI to update
|
|
StatsInterface.FreeStats(StatsRead);
|
|
OnReadComplete(true);
|
|
|
|
// Figure out what type of stats read we are doing
|
|
switch (CurrentReadType)
|
|
{
|
|
case SFT_Player:
|
|
//@HSL_BEGIN_XBOX
|
|
if (StatsInterface.ReadOnlineStatsForPlayer(ControllerIndex, StatsRead) == false)
|
|
//@HSL_END_XBOX
|
|
{
|
|
// Clear the delegate that tells the UI to refresh
|
|
`warn("Querying Player failed.");
|
|
return false;
|
|
}
|
|
return true;
|
|
|
|
case SFT_CenteredOnPlayer:
|
|
if (StatsInterface.ReadOnlineStatsByRankAroundPlayer(ControllerIndex, StatsRead, 10) == false)
|
|
{
|
|
// Clear the delegate that tells the UI to refresh
|
|
`warn("Querying CenteredOnPlayer failed.");
|
|
return false;
|
|
}
|
|
return true;
|
|
|
|
case SFT_Friends:
|
|
if (StatsInterface.ReadOnlineStatsForFriends(ControllerIndex, StatsRead) == false)
|
|
{
|
|
// Clear the delegate that tells the UI to refresh
|
|
`warn("Querying Friends failed.");
|
|
return false;
|
|
}
|
|
return true;
|
|
|
|
case SFT_TopRankings:
|
|
//@todo joeg -- expose a way to do virtual paging...different Kismet object?
|
|
//@HSL_BEGIN_XBOX
|
|
if (StatsInterface.ReadOnlineStatsByRank(ControllerIndex, StatsRead) == false)
|
|
//@HSL_END_XBOX
|
|
{
|
|
// Clear the delegate that tells the UI to refresh
|
|
`log("Querying Top Rankings failed.");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Displays the gamercard for the specified list index
|
|
*
|
|
* @param ConrollerIndex the ControllerId for the player displaying the gamercard
|
|
* @param ListIndex the item in the list to display the gamercard for
|
|
*/
|
|
event bool ShowGamercard(byte ConrollerIndex,int ListIndex)
|
|
{
|
|
local OnlineSubsystem OnlineSub;
|
|
local OnlinePlayerInterfaceEx PlayerExt;
|
|
local UniqueNetId PlayerId;
|
|
|
|
// Validate the specified index is within the stats results
|
|
if (ListIndex >= 0 && ListIndex < StatsRead.Rows.Length)
|
|
{
|
|
OnlineSub = class'GameEngine'.static.GetOnlineSubsystem();
|
|
if (OnlineSub != None)
|
|
{
|
|
PlayerExt = OnlineSub.PlayerInterfaceEx;
|
|
if (PlayerExt != None)
|
|
{
|
|
// Get the player id of the player we are going to show the gamer card of
|
|
PlayerId = StatsRead.Rows[ListIndex].PlayerId;
|
|
// Show the gamer card
|
|
return PlayerExt.ShowGamerCardUI(ConrollerIndex,PlayerId);
|
|
}
|
|
else
|
|
{
|
|
`warn("OnlineSubsystem does not support the extended player interface. Can't show gamercard");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
`warn("No OnlineSubsystem present. Can't show gamercard");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
`warn("Invalid index ("$ListIndex$") specified for online game to show the gamercard of");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called by the online subsystem when the stats read has completed
|
|
*
|
|
* @param bWasSuccessful whether the stats read was successful or not
|
|
*/
|
|
function OnReadComplete(bool bWasSuccessful)
|
|
{
|
|
// If the call worked, sort the items before telling the list to refresh
|
|
if (bWasSuccessful)
|
|
{
|
|
SortResultsByRank(StatsRead);
|
|
}
|
|
//@todo - display a message box upon error?
|
|
// Notify any subscribers that we have new data
|
|
RefreshSubscribers();
|
|
}
|
|
|
|
/**
|
|
* Sorts the returned results by their rank (lowest to highest)
|
|
*/
|
|
native static function SortResultsByRank(OnlineStatsRead StatsToSort);
|
|
|
|
defaultproperties
|
|
{
|
|
// Change this value in the derived class
|
|
Tag=OnlineStats
|
|
StatsReadName=StatsReadResults
|
|
PlayerNickData=(PlayerNickName="Player Nick")
|
|
RankNameMetaData=(RankName="Rank")
|
|
TotalRowsName="TotalRows"
|
|
}
|