2009-05-08 13:28:41 +00:00
/*
* OpenClonk , http : //www.openclonk.org
*
2013-12-17 20:01:09 +00:00
* Copyright ( c ) 2005 - 2009 , RedWolf Design GmbH , http : //www.clonk.de/
2016-04-03 18:18:29 +00:00
* Copyright ( c ) 2011 - 2016 , The OpenClonk Team and contributors
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* Distributed under the terms of the ISC license ; see accompanying file
* " COPYING " for details .
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* " Clonk " is a registered trademark of Matthes Bender , used with permission .
* See accompanying file " TRADEMARK " for details .
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* To redistribute this file separately , substitute the full license texts
* for the above references .
2009-05-08 13:28:41 +00:00
*/
// player team management for teamwork melees
# ifndef INC_C4Teams
# define INC_C4Teams
2016-04-03 18:07:56 +00:00
# include "lib/C4InputValidation.h"
2009-08-12 20:03:50 +00:00
2009-05-08 13:28:41 +00:00
// constant used by lobby to indicate invisible, random team
const int32_t TEAMID_Unknown = - 1 ;
// constant used by InitScenarioPlayer() to indicate creation of a new team
const int32_t TEAMID_New = - 1 ;
// one player team
class C4Team
2010-03-28 17:58:21 +00:00
{
private :
// std::vector...
// containing player info IDs
int32_t * piPlayers ;
int32_t iPlayerCount ;
int32_t iPlayerCapacity ;
public :
// copying
C4Team ( const C4Team & rCopy ) ;
C4Team & operator = ( const C4Team & rCopy ) ;
protected :
// team identification; usually > 0 for a valid team
int32_t iID ;
char Name [ C4MaxName + 1 ] ;
int32_t iPlrStartIndex ; // 0 for unassigned; 1 to 4 if all players of that team shall be assigned a specific [Player*]-section in the Scenario.txt
uint32_t dwClr ; // team color
StdCopyStrBuf sIconSpec ; // icon drawing specification for offline or runtime team selection dialog
int32_t iMaxPlayer ; // maximum number of players allowed in this team - 0 for infinite
friend class C4TeamList ;
public :
C4Team ( ) : piPlayers ( NULL ) , iPlayerCount ( 0 ) , iPlayerCapacity ( 0 ) , iID ( 0 ) , iPlrStartIndex ( 0 ) , dwClr ( 0 ) , iMaxPlayer ( 0 ) { * Name = 0 ; }
~ C4Team ( ) { Clear ( ) ; }
void Clear ( ) ;
void AddPlayer ( class C4PlayerInfo & rInfo , bool fAdjustPlayer ) ; // add player by info; adjusts ID in info and at any joined player
void RemoveIndexedPlayer ( int32_t iIndex ) ; // remove info at index; this changes the local list only
void RemovePlayerByID ( int32_t iID ) ;
int32_t GetPlayerCount ( ) const { return iPlayerCount ; }
const char * GetName ( ) const { return Name ; }
int32_t GetID ( ) const { return iID ; }
bool IsPlayerIDInTeam ( int32_t iID ) ; // search list for a player with the given ID
int32_t GetFirstUnjoinedPlayerID ( ) const ; // search for a player that does not have the join-flag set
int32_t GetPlrStartIndex ( ) const { return iPlrStartIndex ; }
uint32_t GetColor ( ) const { return dwClr ; }
const char * GetIconSpec ( ) const { return sIconSpec . getData ( ) ; }
bool IsFull ( ) const { return iMaxPlayer & & ( iPlayerCount > = iMaxPlayer ) ; } // whether no more players may join this team
StdStrBuf GetNameWithParticipants ( ) const ; // compose team name like "Team 1 (boni, GhostBear, Clonko)"
bool HasWon ( ) const ; // return true if any member player of the team has won
int32_t GetIndexedPlayer ( int32_t iIndex ) const { return Inside < int32_t > ( iIndex , 0 , iPlayerCount - 1 ) ? piPlayers [ iIndex ] : 0 ; }
void CompileFunc ( StdCompiler * pComp ) ;
// this rechecks teams for all (not removed) players; sets players here by team selection in player infos
void RecheckPlayers ( ) ;
// this assigns a team color if it's still zero
void RecheckColor ( C4TeamList & rForList ) ;
} ;
2009-05-08 13:28:41 +00:00
// global team list
class C4TeamList
2010-03-28 17:58:21 +00:00
{
public :
// team config constants
enum ConfigValue
2009-05-08 13:28:41 +00:00
{
2010-03-28 17:58:21 +00:00
TEAM_None = 0 ,
TEAM_Custom = 1 ,
TEAM_Active = 2 ,
TEAM_AllowHostilityChange = 3 ,
TEAM_Dist = 4 ,
TEAM_AllowTeamSwitch = 5 ,
TEAM_AutoGenerateTeams = 6 ,
TEAM_TeamColors = 7
} ;
// team distribution configuration
enum TeamDist
{
TEAMDIST_First = 0 ,
TEAMDIST_Free = 0 , // anyone can choose teams
TEAMDIST_Host = 1 , // host decides teams
2011-11-08 17:27:32 +00:00
TEAMDIST_None = 2 , // no teams
TEAMDIST_Random = 3 , // fixed random teams
TEAMDIST_RandomInv = 4 , // fixed random teams invisible in lobby
TEAMDIST_Last = 4 ,
2009-05-08 13:28:41 +00:00
} ;
2010-03-28 17:58:21 +00:00
private :
// std::vector...
C4Team * * ppList ;
int32_t iTeamCount ;
int32_t iTeamCapacity ;
int32_t iLastTeamID ;
bool fAllowHostilityChange ; // hostility not fixed
bool fAllowTeamSwitch ; // teams not fixed
bool fActive ;
bool fCustom ; // set if read from team file or changed in scenario
bool fTeamColors ; // if set, player colors are determined by team colors
bool fAutoGenerateTeams ; // teams are generated automatically so there's enough teams for everyone
TeamDist eTeamDist ;
int32_t iMaxScriptPlayers ; // maximum number of script players to be added in the lobby
StdStrBuf sScriptPlayerNames ; // default script player names
public :
C4TeamList ( ) : ppList ( NULL ) , iTeamCount ( 0 ) , iTeamCapacity ( 0 ) , iLastTeamID ( 0 ) , fAllowHostilityChange ( true ) , fAllowTeamSwitch ( false ) ,
fActive ( true ) , fCustom ( false ) , fTeamColors ( false ) , fAutoGenerateTeams ( false ) , eTeamDist ( TEAMDIST_Free ) , iMaxScriptPlayers ( 0 ) { }
~ C4TeamList ( ) { Clear ( ) ; }
void Clear ( ) ;
C4TeamList & operator = ( const C4TeamList & rCopy ) ;
private :
// no copying
C4TeamList ( const C4TeamList & rCopy ) ;
private :
void AddTeam ( C4Team * pNewTeam ) ; // add a team; grow list if necessary
2011-11-08 17:27:32 +00:00
void ClearTeams ( ) ; // delete all teams
2010-03-28 17:58:21 +00:00
int32_t GetFreeTeamID ( ) ;
bool GenerateDefaultTeams ( int32_t iUpToID ) ; // generate Team 1, Team 2, etc.
public :
C4Team * GetTeamByID ( int32_t iID ) const ; // get team by ID
C4Team * GetGenerateTeamByID ( int32_t iID ) ; // get team by ID; generate if not existant. Always generate for TEAMID_New.
C4Team * GetTeamByIndex ( int32_t iIndex ) const ; // get team by list index, to enumerate all teams
C4Team * GetTeamByName ( const char * szName ) const ; // match team name; case sensitive and not trimmed
C4Team * GetTeamByPlayerID ( int32_t iID ) const ; // get team by player ID (not number!)
int32_t GetLargestTeamID ( ) const ;
C4Team * GetRandomSmallestTeam ( ) const ; // get team with least amount of players in it
int32_t GetTeamCount ( ) const { return iTeamCount ; }
C4Team * CreateTeam ( const char * szName ) ; // create a custom team
bool IsMultiTeams ( ) const { return fActive ; } // teams can be selected
bool IsCustom ( ) const { return fCustom ; } // whether teams are not generated as default
bool IsHostilityChangeAllowed ( ) const { return fAllowHostilityChange ; } // allow (temporary) hostility changes at runtime
bool IsTeamSwitchAllowed ( ) const { return fAllowTeamSwitch ; } // allow permanent team changes at runtime
bool CanLocalChooseTeam ( ) const ; // whether the local host can determine teams (e.g., not if teams are random, or if all except the player's current team are full)
bool CanLocalChooseTeam ( int32_t idPlayer ) const ; // whether the local host can determine teams (e.g., not if teams are random, or if all except the player's current team are full)
bool CanLocalSeeTeam ( ) const ;
bool IsTeamColors ( ) const { return fTeamColors ; } // whether team colors are enabled
2011-11-08 17:27:32 +00:00
bool IsRandomTeam ( ) const { return eTeamDist = = TEAMDIST_Random | | eTeamDist = = TEAMDIST_RandomInv ; } // whether a random team mode is selected
2010-03-28 17:58:21 +00:00
bool IsJoin2TeamAllowed ( int32_t idTeam ) ; // checks whether a team ID is valid and still available for new joins
bool IsAutoGenerateTeams ( ) const { return fAutoGenerateTeams ; }
bool IsRuntimeJoinTeamChoice ( ) const { return IsCustom ( ) & & IsMultiTeams ( ) ; } // whether players joining at runtime must select a team first
int32_t GetMaxScriptPlayers ( ) const { return iMaxScriptPlayers ; } // return max number of script players to be added inthe lobby
int32_t GetForcedTeamSelection ( int32_t idForPlayer ) const ; // if there's only one team for the player to join, return that team ID
StdStrBuf GetScriptPlayerName ( ) const ; // get a name to assign to a new script player. Try to avoid name conflicts
bool IsTeamVisible ( ) const ; // teams invisible during lobby time if TEAMDIST_RandomInv
void EnforceLeagueRules ( ) ; // enforce some league settings, such as disallowing runtime team change
// assign a team ID to player info; recheck if any user-set team infos are valid within the current team options
// creates a new team for melee; assigns the least-used team for teamwork melee
// host/single-call only; using SafeRandom!
bool RecheckPlayerInfoTeams ( C4PlayerInfo & rNewJoin , bool fByHost ) ;
// compiler
void CompileFunc ( StdCompiler * pComp ) ;
bool Load ( C4Group & hGroup , class C4Scenario * pInitDefault , class C4LangStringTable * pLang ) ; // clear self and load from group file (C4CFN_Teams); init default by scen if no team fiel is present
bool Save ( C4Group & hGroup ) ; // save to group file (C4CFN_Teams)
// this rechecks teams for all (not removed) players; sets players here by team selection in player infos
void RecheckPlayers ( ) ;
// this reorders any unjoined players to teams if they are unevenly filled and team distribution is random
// any changed players will be flagged "updated"
void RecheckTeams ( ) ;
// marks all unjoined players as not-in-team and reassigns a team for them
// also automatically flags all affected player infos as updated
void ReassignAllTeams ( ) ;
private :
// team distribution configuration
StdStrBuf GetTeamDistName ( TeamDist eTeamDist ) const ;
public :
void FillTeamDistOptions ( C4GUI : : ComboBox_FillCB * pFiller ) const ;
void SendSetTeamDist ( TeamDist eNewDist ) ;
TeamDist GetTeamDist ( ) const { return eTeamDist ; }
StdStrBuf GetTeamDistString ( ) const ;
bool HasTeamDistOptions ( ) const ;
void SetTeamDistribution ( TeamDist eToVal ) ;
void SendSetTeamColors ( bool fEnabled ) ;
void SetTeamColors ( bool fEnabled ) ;
2015-09-07 03:20:24 +00:00
// return number of non-empty teams. if players have not been assigned, project a guess on future team count.
int32_t GetStartupTeamCount ( int32_t startup_player_count ) ;
2010-03-28 17:58:21 +00:00
} ;
2009-05-08 13:28:41 +00:00
# endif // INC_C4Teams