Added script functions SetLeagueProgressData, GetLeagueProgressData, GetLeagueScore and SetLeaguePerformance.

heavy-resources
Sven Eberhardt 2014-04-20 15:33:36 +02:00
parent 59c59dd072
commit 4266b370d6
13 changed files with 268 additions and 20 deletions

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>GetLeagueProgressData</title>
<category>Network</category>
<subcat>League</subcat>
<version>5.5 OC</version>
<syntax>
<rtype>string</rtype>
<params>
<param>
<type>int</type>
<name>player_id</name>
<desc>ID of player whose progress data shall be returned. Use <funclink>GetPlayerID</funclink>() to get the ID of a joined player.</desc>
</param>
</params>
</syntax>
<desc>Gets the league progress data. See <funclink>SetLeagueProgressData</funclink> for more information.</desc>
<related><funclink>SetLeagueProgressData</funclink><funclink>GetLeagueScore</funclink></related>
</func>
<author>Sven2</author><date>2014-04</date>
</funcs>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>GetLeagueScore</title>
<category>Network</category>
<subcat>League</subcat>
<version>5.5 OC</version>
<syntax>
<rtype>int</rtype>
<params>
<param>
<type>int</type>
<name>player_id</name>
<desc>ID of player whose score shall shall be returned.</desc>
<optional />
</param>
</params>
</syntax>
<desc>Returns the league score of the given player. This function can be used for custom scoring e.g. in competition leagues.</desc>
<remark>Use <funclink>GetPlayerID</funclink>() to get the ID of a joined player.</remark>
<related><funclink>GetLeagueProgressData</funclink><funclink>SetLeaguePerformance</funclink></related>
</func>
<author>Sven2</author><date>2014-04</date>
</funcs>

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>SetLeaguePerformance</title>
<category>Network</category>
<subcat>League</subcat>
<version>5.5 OC</version>
<syntax>
<rtype>bool</rtype>
<params>
<param>
<type>int</type>
<name>score</name>
<desc>New player or scenario score</desc>
</param>
<param>
<type>int</type>
<name>player_id</name>
<desc>ID of player whose score shall be set. If not given, global performance for all players is set.</desc>
<optional />
</param>
</params>
</syntax>
<desc>Sets the league score. This function can be used for custom scenario scoring in competition or adventure leagues.</desc>
<remark>Use <funclink>GetPlayerID</funclink>() to get the ID of a joined player.</remark>
<examples>
<example>
<code>#appendto Rock
static g_rocks_collected;
func Entrance(clonk)
{
var plr = clonk-><funclink>GetController</funclink>();
if (clonk-><funclink>GetID</funclink>() == Clonk &amp;&amp; plr != NO_OWNER)
{
++g_rocks_collected;
<funclink>Log</funclink>("%s found a rock! Score: %d", <funclink>GetTaggedPlayerName</funclink>(plr), g_rocks_collected);
SetLeaguePerformance(g_rocks_collected);
return <funclink>RemoveObject</funclink>();
}
return <funclink>_inherited</funclink>(clonk, ...);
}</code>
<text>Rock script modification: Whenever a rock is collected by a Clonk, the score of all players is increased.</text>
</example>
</examples>
<related><funclink>SetLeagueProgressData</funclink><funclink>GetLeagueScore</funclink></related>
</func>
<author>Sven2</author><date>2014-04</date>
</funcs>

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>SetLeagueProgressData</title>
<category>Network</category>
<subcat>League</subcat>
<version>5.5 OC</version>
<syntax>
<rtype>bool</rtype>
<params>
<param>
<type>string</type>
<name>new_data</name>
<desc>New data string for this player in this scenario.</desc>
</param>
<param>
<type>int</type>
<name>player_id</name>
<desc>ID of player whose progress data shall be set. Use <funclink>GetPlayerID</funclink>() to get the ID of a joined player.</desc>
</param>
</params>
</syntax>
<desc>Sets the league progress data. This function can be used to store a per-scenario per-user data string in the league. The function is available for both melee and custom settlement leagues. The data is stored between league games and can later be retrieved using <funclink>GetLeagueProgressData</funclink>().</desc>
<remark>Each scenario may store up to 2048 characters. The string may only contain alphanumeric characters plus space (" ") and underscore ("_"). Invalid characters will be removed by the league and not returned when <funclink>GetLeagueProgressData</funclink> is called after the next scenario start.</remark>
<examples>
<example>
<code>func SetLeagueProgressScore(int plr, int new_progress)
{
// Safety: Valid players only
plrid = <funclink>GetPlayerID</funclink>(plr);
if (!plrid) return;
// Progress must be between 0 and 25
new_progress = <funclink>BoundBy</funclink>(new_progress, 0, 25);
// Get old progress from previous round
var progress_string = <funclink>GetLeagueProgressData</funclink>(plrid);
if (progress_string &amp;&amp; <funclink>GetLength</funclink>(progress_string))
{
var old_progress = <funclink>GetChar</funclink>(progress)-<funclink>GetChar</funclink>("A");
// If old progress was better than new progress, keep old progress
new_progress = <funclink>Max</funclink>(old_progress, new_progress);
}
// Set new progress
SetLeagueProgressData(<funclink>Format</funclink>("%c", <funclink>GetChar</funclink>("A") + new_progress));
<funclink>SetLeaguePerformance</funclink>(new_progress);
return true;
}</code>
<text>Helper script for a scenario that is using custom scoring in the league. LeagueProgressData is used to remember the last progress and ensure that progress never decreases.</text>
</example>
</examples>
<related><funclink>GetLeagueProgressData</funclink><funclink>SetLeaguePerformance</funclink></related>
</func>
<author>Sven2</author><date>2014-04</date>
</funcs>

View File

@ -113,7 +113,7 @@ void C4ConfigGraphics::CompileFunc(StdCompiler *pComp)
pComp->Value(mkNamingAdapt(NoOffscreenBlits, "NoOffscreenBlits", 1 ));
pComp->Value(mkNamingAdapt(ClipManuallyE, "ClipManuallyE", 1 ));
pComp->Value(mkNamingAdapt(MultiSampling, "MultiSampling", 4 ));
pComp->Value(mkNamingAdapt(AutoFrameSkip, "AutoFrameSkip", true ));
pComp->Value(mkNamingAdapt(AutoFrameSkip, "AutoFrameSkip", 1 ));
}
void C4ConfigSound::CompileFunc(StdCompiler *pComp)

View File

@ -48,6 +48,8 @@ void C4PlayerInfo::Clear()
iLeagueProjectedGain = -1;
eType = C4PT_User;
idExtraData = C4ID::None;
iLeaguePerformance = 0;
sLeagueProgressData.Clear();
}
void C4PlayerInfo::DeleteTempFile()
@ -248,6 +250,8 @@ void C4PlayerInfo::CompileFunc(StdCompiler *pComp)
pComp->Value(mkNamingAdapt(mkIntPackAdapt(iLeagueRankSymbol), "LeagueRankSymbol", 0));
pComp->Value(mkNamingAdapt(mkIntPackAdapt(iLeagueProjectedGain), "ProjectedGain", -1));
pComp->Value(mkNamingAdapt(mkParAdapt(sClanTag, StdCompiler::RCT_All), "ClanTag", ""));
pComp->Value(mkNamingAdapt(mkIntPackAdapt(iLeaguePerformance), "LeaguePerformance", 0));
pComp->Value(mkNamingAdapt(sLeagueProgressData, "LeagueProgressData", ""));
// file resource
if (pComp->isCompiler() && Game.C4S.Head.Replay)

View File

@ -95,13 +95,15 @@ private:
int32_t iLeagueScoreProjected;// score on league server in case of win
int32_t iLeagueProjectedGain; // projected league score increase if game is won - -1 for unknown; valid values always positive
ValidatedStdCopyStrBuf<C4InVal::VAL_NameAllowEmpty> sClanTag; // clan ("team") tag
int32_t iLeaguePerformance; // script-set league performance value, only set temporarily for masterserver end reference
StdCopyStrBuf sLeagueProgressData; // level progress data as reported by league
public:
C4PlayerInfo() // construct empty
: dwFlags(0), eType(C4PT_User), iID(0), pRes(0), szFilename(), dwColor(0xffffffff),
dwOriginalColor(0xffffffff), dwAlternateColor(0), idSavegamePlayer(0), idTeam(0), iInGameNumber(-1),
iInGameJoinFrame(-1), iInGamePartFrame(-1), idExtraData(C4ID::None), sLeagueAccount(""),
iLeagueScore(0), iLeagueRank(0), iLeagueRankSymbol(0), iLeagueProjectedGain(-1) { }
iLeagueScore(0), iLeagueRank(0), iLeagueRankSymbol(0), iLeagueProjectedGain(-1), iLeaguePerformance(0) { }
void Clear(); // clear fields
@ -132,8 +134,12 @@ public:
bool SetSavegameResume(C4PlayerInfo *pSavegameInfo); // take over savegame player data to do resume
void SetAuthID(const char *sznAuthID)
{ szAuthID = sznAuthID; }
void SetLeagueData(const char *szAccount, const char *szNewClanTag, int32_t iScore, int32_t iRank, int32_t iRankSymbol)
{ sLeagueAccount.CopyValidated(szAccount); sClanTag.CopyValidated(szNewClanTag); iLeagueScore = iScore; iLeagueRank = iRank; iLeagueRankSymbol = iRankSymbol; }
void SetLeagueData(const char *szAccount, const char *szNewClanTag, int32_t iScore, int32_t iRank, int32_t iRankSymbol, const char *szProgressData)
{ sLeagueAccount.CopyValidated(szAccount); sClanTag.CopyValidated(szNewClanTag); iLeagueScore = iScore; iLeagueRank = iRank; iLeagueRankSymbol = iRankSymbol; sLeagueProgressData.Copy(szProgressData); }
void SetLeaguePerformance(int32_t iNewPerf)
{ iLeaguePerformance = iNewPerf; }
void SetLeagueProgressData(const char *szNewProgressData)
{ if (szNewProgressData) sLeagueProgressData.Copy(szNewProgressData); else sLeagueProgressData.Clear(); }
void SetVotedOut()
{ dwFlags |= PIF_VotedOut; }
void SetLeagueProjectedGain(int32_t iProjectedGain)
@ -183,6 +189,7 @@ public:
int32_t GetInGameNumber() const { return iInGameNumber; } // returns player number the player had in the game
bool IsLeagueProjectedGainValid() const { return iLeagueProjectedGain>=0; }
int32_t GetLeagueProjectedGain() const { return iLeagueProjectedGain; } // get score gain in primary league if this player's team wins
const char *GetLeagueProgressData() const { return sLeagueProgressData.getData(); }
int32_t GetID() const { return iID; } // get unique ID, if assigned
int32_t GetTeam() const { return idTeam; }

View File

@ -40,6 +40,7 @@ void C4RoundResultsPlayer::CompileFunc(StdCompiler *pComp)
pComp->Value(mkNamingAdapt(iLeagueScoreGain, "GameScore", -1)); // name used in league reply!
pComp->Value(mkNamingAdapt(iLeagueRankNew, "Rank", 0)); // name used in league reply!
pComp->Value(mkNamingAdapt(iLeagueRankSymbolNew, "RankSymbol", 0)); // name used in league reply!
pComp->Value(mkNamingAdapt(sLeagueProgressData, "LeagueProgressData", StdCopyStrBuf()));
StdEnumEntry<LeagueStatus> LeagueStatusEntries[] =
{
{ "", RRPLS_Unknown },
@ -71,6 +72,12 @@ void C4RoundResultsPlayer::EvaluatePlayer(C4Player *pPlr)
fctBigIcon.Create(pPlr->BigIcon.Wdt, pPlr->BigIcon.Hgt);
pPlr->BigIcon.Draw(fctBigIcon);
}
// progress data by player
C4PlayerInfo *pInfo = pPlr->GetInfo();
if (pInfo)
{
sLeagueProgressData.Copy(pInfo->GetLeagueProgressData());
}
// BigIcon from info: Doesn't work for some cases when player files got deleted already
/*C4PlayerInfo *pInfo = pPlr->GetInfo();
assert(pInfo);
@ -86,6 +93,7 @@ void C4RoundResultsPlayer::EvaluateLeague(C4RoundResultsPlayer *pLeaguePlayerInf
iLeagueScoreGain = pLeaguePlayerInfo->iLeagueScoreGain;
iLeagueRankNew = pLeaguePlayerInfo->iLeagueRankNew;
iLeagueRankSymbolNew = pLeaguePlayerInfo->iLeagueRankSymbolNew;
sLeagueProgressData =pLeaguePlayerInfo->sLeagueProgressData;
}
void C4RoundResultsPlayer::AddCustomEvaluationString(const char *szCustomString)
@ -107,6 +115,7 @@ bool C4RoundResultsPlayer::operator ==(const C4RoundResultsPlayer &cmp)
if (iLeagueRankNew != cmp.iLeagueRankNew) return false;
if (iLeagueRankSymbolNew != cmp.iLeagueRankSymbolNew) return false;
if (eLeagueStatus != cmp.eLeagueStatus) return false;
if (sLeagueProgressData != cmp.sLeagueProgressData) return false;
return true;
}
@ -124,6 +133,7 @@ C4RoundResultsPlayer &C4RoundResultsPlayer::operator =(const C4RoundResultsPlaye
iLeagueRankNew = cpy.iLeagueRankNew;
iLeagueRankSymbolNew = cpy.iLeagueRankSymbolNew;
eLeagueStatus = cpy.eLeagueStatus;
sLeagueProgressData = cpy.sLeagueProgressData;
return *this;
}
@ -361,15 +371,28 @@ bool C4RoundResults::SettlementScoreIsHidden()
return fHideSettlementScore;
}
void C4RoundResults::SetLeaguePerformance(int32_t iNewPerf)
void C4RoundResults::SetLeaguePerformance(int32_t iNewPerf, int32_t idPlayer)
{
// Store to be sent later
iLeaguePerformance = iNewPerf;
}
// Store to be sent later. idPlayer == 0 means global performance.
if(!idPlayer)
{
iLeaguePerformance = iNewPerf;
}
else
{
C4RoundResultsPlayer *pOwnPlr = Players.GetCreateByID(idPlayer);
pOwnPlr->SetLeaguePerformance(iNewPerf);
}
}
int32_t C4RoundResults::GetLeaguePerformance() const
int32_t C4RoundResults::GetLeaguePerformance(int32_t idPlayer) const
{
return iLeaguePerformance;
if(!idPlayer)
return iLeaguePerformance;
else
if(C4RoundResultsPlayer *pPlr = Players.GetByID(idPlayer))
return pPlr->GetLeaguePerformance();
return 0;
}
bool C4RoundResults::Load(C4Group &hGroup, const char *szFilename)

View File

@ -51,13 +51,15 @@ private:
int32_t iLeagueScoreGain; // league score gained by this round - -1 for unknown
int32_t iLeagueRankNew; // rank on league server after this round
int32_t iLeagueRankSymbolNew; // rank symbol on league server after this round
int32_t iLeaguePerformance; // script-set performance value, effect league-dependent
StdCopyStrBuf sLeagueProgressData; // scenario-specific data to store more proigress info (which levels were done, etc.)
enum LeagueStatus
{
RRPLS_Unknown=0, RRPLS_Lost, RRPLS_Won
} eLeagueStatus; // whether player lost or won
public:
C4RoundResultsPlayer() : id(0), iTotalPlayingTime(0), iScoreOld(-1), iScoreNew(-1), iLeagueScoreNew(-1), iLeagueScoreGain(0), iLeagueRankNew(0), iLeagueRankSymbolNew(0), eLeagueStatus(RRPLS_Unknown) {}
C4RoundResultsPlayer() : id(0), iTotalPlayingTime(0), iScoreOld(-1), iScoreNew(-1), iLeagueScoreNew(-1), iLeagueScoreGain(0), iLeagueRankNew(0), iLeagueRankSymbolNew(0), iLeaguePerformance(0), sLeagueProgressData(), eLeagueStatus(RRPLS_Unknown) {}
C4RoundResultsPlayer(const C4RoundResultsPlayer &cpy) { *this=cpy; }
void CompileFunc(StdCompiler *pComp);
@ -75,12 +77,14 @@ public:
int32_t GetLeagueScoreGain() const { return iLeagueScoreGain; }
int32_t GetLeagueRankNew() const { return iLeagueRankNew; } // returns rank on league server after round evaluation (0 for not assigned)
int32_t GetLeagueRankSymbolNew() const { return iLeagueRankSymbolNew; }
int32_t GetLeaguePerformance() const { return iLeaguePerformance; }
void EvaluateLeague(C4RoundResultsPlayer *pLeaguePlayer); // called from league evaluation; set league fields
void EvaluatePlayer(C4Player *pPlr); // called from C4Player::Evaluate; set fields by player
void SetID(int32_t idNew) { this->id=idNew; }
void AddCustomEvaluationString(const char *szCustomString);
void SetLeaguePerformance(int32_t iNewPerf) { iLeaguePerformance = iNewPerf; }
bool operator ==(const C4RoundResultsPlayer &cmp);
C4RoundResultsPlayer &operator =(const C4RoundResultsPlayer &cpy);
@ -182,10 +186,10 @@ public:
void HideSettlementScore(bool fHide=true);
bool SettlementScoreIsHidden();
// Set league performance
// Used for settlement league scenarios that use a measure different from the elapsed game time
void SetLeaguePerformance(int32_t iNewPerf);
int32_t GetLeaguePerformance() const;
// Used for special league scenarios, e.g. settlement scenarios that wish to use a
// measure different from the elapsed game time
void SetLeaguePerformance(int32_t iNewPerf, int32_t idPlayer = 0);
int32_t GetLeaguePerformance(int32_t idPlayer = 0) const;
const C4RoundResultsPlayers &GetPlayers() const { return Players; }
const char *GetCustomEvaluationStrings() const { return sCustomEvaluationStrings.getData(); }

View File

@ -927,11 +927,14 @@ static bool FnSurrenderPlayer(C4PropList * _this, long iPlr)
}
// undocumented!
static bool FnSetLeaguePerformance(C4PropList * _this, long iScore)
{
Game.RoundResults.SetLeaguePerformance(iScore);
static bool FnSetLeaguePerformance(C4PropList * _this, long iScore, long idPlayer)
{
if(!Game.Parameters.isLeague()) return false;
if(idPlayer && !Game.PlayerInfos.GetPlayerInfoByID(idPlayer)) return false;
Game.RoundResults.SetLeaguePerformance(iScore, idPlayer);
return true;
}
}
static const int32_t CSPF_FixedAttributes = 1<<0,
CSPF_NoScenarioInit = 1<<1,
@ -1132,6 +1135,34 @@ static C4String *FnGetLeague(C4PropList * _this, long idx)
return String(sIdxLeague.getData());
}
static int32_t FnGetLeagueScore(C4PropList * _this, long idPlayer)
{
// security
if (idPlayer < 1) return 0;
// get info
C4PlayerInfo *pInfo = Game.PlayerInfos.GetPlayerInfoByID(idPlayer);
if (!pInfo) return 0;
// get league score
return pInfo->getLeagueScore();
}
static bool FnSetLeagueProgressData(C4PropList * _this, C4String *pNewData, long idPlayer)
{
if(!Game.Parameters.League.getLength()) return false;
C4PlayerInfo *info = Game.PlayerInfos.GetPlayerInfoByID(idPlayer);
if (!info) return false;
info->SetLeagueProgressData(pNewData ? pNewData->GetCStr() : NULL);
return TRUE;
}
static C4String *FnGetLeagueProgressData(C4PropList * _this, long idPlayer)
{
if(!Game.Parameters.League.getLength()) return NULL;
C4PlayerInfo *info = Game.PlayerInfos.GetPlayerInfoByID(idPlayer);
if (!info) return NULL;
return String(info->GetLeagueProgressData());
}
// undocumented!
static bool FnTestMessageBoard(C4PropList * _this, long iForPlr, bool fTestIfInUse)
{
@ -2430,7 +2461,10 @@ void InitGameFunctionMap(C4AulScriptEngine *pEngine)
AddFunc(pEngine, "GetPlayerByIndex", FnGetPlayerByIndex);
AddFunc(pEngine, "EliminatePlayer", FnEliminatePlayer);
AddFunc(pEngine, "SurrenderPlayer", FnSurrenderPlayer);
AddFunc(pEngine, "FnGetLeagueScore", FnGetLeagueScore);
AddFunc(pEngine, "SetLeaguePerformance", FnSetLeaguePerformance);
AddFunc(pEngine, "SetLeagueProgressData", FnSetLeagueProgressData);
AddFunc(pEngine, "GetLeagueProgressData", FnGetLeagueProgressData);
AddFunc(pEngine, "CreateScriptPlayer", FnCreateScriptPlayer);
AddFunc(pEngine, "GetCursor", FnGetCursor);
AddFunc(pEngine, "GetViewCursor", FnGetViewCursor);

View File

@ -165,6 +165,12 @@ int32_t C4LeagueResponseHeadAuthCheck::getRankSymbol(const char *szLeague) const
return 0;
}
const char *C4LeagueResponseHeadAuthCheck::getProgressData(const char *szLeague) const
{
// progress data is the same for all leagues
return ProgressData.getData();
}
void C4LeagueResponseHeadAuthCheck::CompileFunc(StdCompiler *pComp)
{
// Base members
@ -176,6 +182,9 @@ void C4LeagueResponseHeadAuthCheck::CompileFunc(StdCompiler *pComp)
pComp->Value(mkNamingAdapt(mkArrayAdapt(Ranks, C4NetMaxLeagues, 0), "Rank"));
pComp->Value(mkNamingAdapt(mkArrayAdapt(RankSymbols, C4NetMaxLeagues, 0), "RankSymbol"));
// Progress data (per scenario; not per league)
pComp->Value(mkNamingAdapt(mkParAdapt(ProgressData, StdCompiler::RCT_All), "ProgressData", ""));
// Clan tag
pComp->Value(mkNamingAdapt(mkParAdapt(ClanTag, StdCompiler::RCT_All), "ClanTag", ""));
@ -466,7 +475,7 @@ bool C4LeagueClient::GetAuthCheckReply(StdStrBuf *pMessage, const char *szLeague
if (pMessage)
pMessage->Copy(Head.getMessage());
if (szLeague && pPlrInfo)
pPlrInfo->SetLeagueData(Head.getAccount(), Head.getClanTag(), Head.getScore(szLeague), Head.getRank(szLeague), Head.getRankSymbol(szLeague));
pPlrInfo->SetLeagueData(Head.getAccount(), Head.getClanTag(), Head.getScore(szLeague), Head.getRank(szLeague), Head.getRankSymbol(szLeague), Head.getProgressData(szLeague));
return Head.isSuccess();
}

View File

@ -166,12 +166,14 @@ private:
int32_t Ranks[C4NetMaxLeagues];
int32_t RankSymbols[C4NetMaxLeagues];
StdCopyStrBuf ClanTag;
StdCopyStrBuf ProgressData;
public:
int32_t getScore(const char *szLeague) const;
int32_t getRank(const char *szLeague) const;
int32_t getRankSymbol(const char *szLeague) const;
const char *getClanTag() const { return ClanTag.getData(); }
const char *getProgressData(const char *szLeague) const;
void CompileFunc(StdCompiler *pComp);
};

View File

@ -52,11 +52,16 @@ void C4Network2Reference::InitLocal()
Parameters = ::Game.Parameters;
// Discard player resources (we don't want these infos in the reference)
// Add league performance (but only after game end)
C4ClientPlayerInfos *pClientInfos; C4PlayerInfo *pPlayerInfo;
int32_t i, j;
for (i = 0; (pClientInfos = Parameters.PlayerInfos.GetIndexedInfo(i)); i++)
for (j = 0; (pPlayerInfo = pClientInfos->GetPlayerInfo(j)); j++)
{
pPlayerInfo->DiscardResource();
if(::Game.GameOver)
pPlayerInfo->SetLeaguePerformance(::Game.RoundResults.GetLeaguePerformance(pPlayerInfo->GetID()));
}
// Special additional information in reference
Icon = ::Game.C4S.Head.Icon;