OpenClonk
C4Teams.h
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2011-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 // player team management for teamwork melees
17 
18 #ifndef INC_C4Teams
19 #define INC_C4Teams
20 
21 #include "lib/C4InputValidation.h"
22 
23 // constant used by lobby to indicate invisible, random team
24 const int32_t TEAMID_Unknown = -1;
25 
26 // constant used by InitScenarioPlayer() to indicate creation of a new team
27 const int32_t TEAMID_New = -1;
28 
29 // one player team
30 class C4Team
31 {
32 private:
33  // std::vector...
34  // containing player info IDs
35  int32_t *piPlayers{nullptr};
36  int32_t iPlayerCount{0};
37  int32_t iPlayerCapacity{0};
38 
39 public:
40  // copying
41  C4Team(const C4Team &rCopy);
42  C4Team &operator = (const C4Team &rCopy);
43 
44 protected:
45  // team identification; usually > 0 for a valid team
46  int32_t iID{0};
47  char Name[C4MaxName+1];
48  int32_t iPlrStartIndex{0}; // 0 for unassigned; 1 to 4 if all players of that team shall be assigned a specific [Player*]-section in the Scenario.txt
49  uint32_t dwClr{0}; // team color
50  StdCopyStrBuf sIconSpec; // icon drawing specification for offline or runtime team selection dialog
51  int32_t iMaxPlayer{0}; // maximum number of players allowed in this team - 0 for infinite
52 
53  friend class C4TeamList;
54 
55 public:
56  C4Team() { *Name=0; }
57  ~C4Team() { Clear(); }
58 
59  void Clear();
60  void AddPlayer(class C4PlayerInfo &rInfo, bool fAdjustPlayer); // add player by info; adjusts ID in info and at any joined player
61  void RemoveIndexedPlayer(int32_t iIndex); // remove info at index; this changes the local list only
62  void RemovePlayerByID(int32_t iID);
63 
64  int32_t GetPlayerCount() const { return iPlayerCount; }
65  const char *GetName() const { return Name; }
66  int32_t GetID() const { return iID; }
67  bool IsPlayerIDInTeam(int32_t iID); // search list for a player with the given ID
68  int32_t GetFirstUnjoinedPlayerID() const; // search for a player that does not have the join-flag set
69  int32_t GetPlrStartIndex() const { return iPlrStartIndex; }
70  uint32_t GetColor() const { return dwClr; }
71  const char *GetIconSpec() const { return sIconSpec.getData(); }
72  bool IsFull() const { return iMaxPlayer && (iPlayerCount >= iMaxPlayer); } // whether no more players may join this team
73  StdStrBuf GetNameWithParticipants() const; // compose team name like "Team 1 (boni, GhostBear, Clonko)"
74  bool HasWon() const; // return true if any member player of the team has won
75 
76  int32_t GetIndexedPlayer(int32_t iIndex) const { return Inside<int32_t>(iIndex, 0, iPlayerCount-1) ? piPlayers[iIndex] : 0; }
77 
78  void CompileFunc(StdCompiler *pComp);
79 
80  // this rechecks teams for all (not removed) players; sets players here by team selection in player infos
81  void RecheckPlayers();
82 
83  // this assigns a team color if it's still zero
84  void RecheckColor(C4TeamList &rForList);
85 };
86 
87 // global team list
89 {
90 public:
91  // team config constants
93  {
94  TEAM_None = 0,
98  TEAM_Dist = 4,
101  TEAM_TeamColors = 7
102  };
103 
104  // team distribution configuration
105  enum TeamDist
106  {
108  TEAMDIST_Free = 0, // anyone can choose teams
109  TEAMDIST_Host = 1, // host decides teams
110  TEAMDIST_None = 2, // no teams
111  TEAMDIST_Random = 3, // fixed random teams
112  TEAMDIST_RandomInv = 4, // fixed random teams invisible in lobby
114  };
115 
116 private:
117  // std::vector...
118  C4Team **ppList{nullptr};
119  int32_t iTeamCount{0};
120  int32_t iTeamCapacity{0};
121 
122  int32_t iLastTeamID{0};
123  bool fAllowHostilityChange{true}; // hostility not fixed
124  bool fAllowTeamSwitch{false}; // teams not fixed
125  bool fActive{true};
126  bool fCustom{false}; // set if read from team file or changed in scenario
127  bool fTeamColors{false}; // if set, player colors are determined by team colors
128  bool fAutoGenerateTeams{false}; // teams are generated automatically so there's enough teams for everyone
129  TeamDist eTeamDist{TEAMDIST_Free};
130  int32_t iMaxScriptPlayers{0}; // maximum number of script players to be added in the lobby
131  StdStrBuf sScriptPlayerNames; // default script player names
132 
133 public:
134  C4TeamList() = default;
136  void Clear();
137 
138  C4TeamList &operator =(const C4TeamList &rCopy);
139 
140 private:
141  // no copying
142  C4TeamList(const C4TeamList &rCopy);
143 
144 private:
145  void AddTeam(C4Team *pNewTeam); // add a team; grow list if necessary
146  void ClearTeams(); // delete all teams
147  int32_t GetFreeTeamID();
148  bool GenerateDefaultTeams(int32_t iUpToID); // generate Team 1, Team 2, etc.
149 
150 public:
151  C4Team *GetTeamByID(int32_t iID) const; // get team by ID
152  C4Team *GetGenerateTeamByID(int32_t iID); // get team by ID; generate if not existant. Always generate for TEAMID_New.
153  C4Team *GetTeamByIndex(int32_t iIndex) const; // get team by list index, to enumerate all teams
154  C4Team *GetTeamByName(const char *szName) const; // match team name; case sensitive and not trimmed
155  C4Team *GetTeamByPlayerID(int32_t iID) const; // get team by player ID (not number!)
156  int32_t GetLargestTeamID() const;
157  C4Team *GetRandomSmallestTeam() const; // get team with least amount of players in it
158  int32_t GetTeamCount() const { return iTeamCount; }
159 
160  C4Team *CreateTeam(const char *szName); // create a custom team
161 
162  bool IsMultiTeams() const { return fActive; } // teams can be selected
163  bool IsCustom() const { return fCustom; } // whether teams are not generated as default
164  bool IsHostilityChangeAllowed() const { return fAllowHostilityChange; } // allow (temporary) hostility changes at runtime
165  bool IsTeamSwitchAllowed() const { return fAllowTeamSwitch; } // allow permanent team changes at runtime
166  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)
167  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)
168  bool CanLocalSeeTeam() const;
169  bool IsTeamColors() const { return fTeamColors; } // whether team colors are enabled
170  bool IsRandomTeam() const { return eTeamDist==TEAMDIST_Random ||eTeamDist==TEAMDIST_RandomInv; } // whether a random team mode is selected
171  bool IsJoin2TeamAllowed(int32_t idTeam, C4PlayerType plrType); // checks whether a team ID is valid and still available for new joins
172  bool IsAutoGenerateTeams() const { return fAutoGenerateTeams; }
173  bool IsRuntimeJoinTeamChoice() const { return IsCustom() && IsMultiTeams(); } // whether players joining at runtime must select a team first
174  int32_t GetMaxScriptPlayers() const { return iMaxScriptPlayers; } // return max number of script players to be added inthe lobby
175  int32_t GetForcedTeamSelection(int32_t idForPlayer) const; // if there's only one team for the player to join, return that team ID
176  StdStrBuf GetScriptPlayerName() const; // get a name to assign to a new script player. Try to avoid name conflicts
177  bool IsTeamVisible() const; // teams invisible during lobby time if TEAMDIST_RandomInv
178 
179  void EnforceLeagueRules(); // enforce some league settings, such as disallowing runtime team change
180 
181  // assign a team ID to player info; recheck if any user-set team infos are valid within the current team options
182  // creates a new team for melee; assigns the least-used team for teamwork melee
183  // host/single-call only; using UnsyncedRandom!
184  bool RecheckPlayerInfoTeams(C4PlayerInfo &rNewJoin, bool fByHost);
185 
186  // compiler
187  void CompileFunc(StdCompiler *pComp);
188  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
189  bool Save(C4Group &hGroup); // save to group file (C4CFN_Teams)
190 
191  // this rechecks teams for all (not removed) players; sets players here by team selection in player infos
192  void RecheckPlayers();
193 
194  // this reorders any unjoined players to teams if they are unevenly filled and team distribution is random
195  // any changed players will be flagged "updated"
196  void RecheckTeams();
197 
198  // Makes sure that there's the right amount of teams when switching to random teams.
199  void EnsureTeamCount();
200 
201  // marks all unjoined players as not-in-team and reassigns a team for them
202  // also automatically flags all affected player infos as updated
203  void ReassignAllTeams();
204 
205 private:
206  // team distribution configuration
207  StdStrBuf GetTeamDistName(TeamDist eTeamDist) const;
208 public:
209  void FillTeamDistOptions(C4GUI::ComboBox_FillCB *pFiller) const;
210  void SendSetTeamDist(TeamDist eNewDist);
211  TeamDist GetTeamDist() const { return eTeamDist; }
213  bool HasTeamDistOptions() const;
214  void SetTeamDistribution(TeamDist eToVal);
215  void SendSetTeamColors(bool fEnabled);
216  void SetTeamColors(bool fEnabled);
217 
218  // return number of non-empty teams. if players have not been assigned, project a guess on future team count.
219  int32_t GetStartupTeamCount(int32_t startup_player_count);
220 };
221 
222 #endif // INC_C4Teams
C4PlayerType
Definition: C4Constants.h:152
const unsigned int C4MaxName
const int32_t TEAMID_Unknown
Definition: C4Teams.h:24
const int32_t TEAMID_New
Definition: C4Teams.h:27
Definition: C4Teams.h:31
void AddPlayer(class C4PlayerInfo &rInfo, bool fAdjustPlayer)
Definition: C4Teams.cpp:52
bool IsFull() const
Definition: C4Teams.h:72
void RecheckPlayers()
Definition: C4Teams.cpp:140
int32_t iID
Definition: C4Teams.h:46
void RecheckColor(C4TeamList &rForList)
Definition: C4Teams.cpp:169
void Clear()
Definition: C4Teams.cpp:44
C4Team & operator=(const C4Team &rCopy)
uint32_t dwClr
Definition: C4Teams.h:49
bool HasWon() const
Definition: C4Teams.cpp:234
StdStrBuf GetNameWithParticipants() const
Definition: C4Teams.cpp:209
void CompileFunc(StdCompiler *pComp)
Definition: C4Teams.cpp:125
uint32_t GetColor() const
Definition: C4Teams.h:70
char Name[C4MaxName+1]
Definition: C4Teams.h:47
C4Team()
Definition: C4Teams.h:56
int32_t GetID() const
Definition: C4Teams.h:66
~C4Team()
Definition: C4Teams.h:57
int32_t GetIndexedPlayer(int32_t iIndex) const
Definition: C4Teams.h:76
const char * GetIconSpec() const
Definition: C4Teams.h:71
bool IsPlayerIDInTeam(int32_t iID)
Definition: C4Teams.cpp:105
int32_t GetPlrStartIndex() const
Definition: C4Teams.h:69
int32_t GetFirstUnjoinedPlayerID() const
Definition: C4Teams.cpp:112
void RemoveIndexedPlayer(int32_t iIndex)
Definition: C4Teams.cpp:83
int32_t iMaxPlayer
Definition: C4Teams.h:51
StdCopyStrBuf sIconSpec
Definition: C4Teams.h:50
int32_t GetPlayerCount() const
Definition: C4Teams.h:64
void RemovePlayerByID(int32_t iID)
Definition: C4Teams.cpp:94
const char * GetName() const
Definition: C4Teams.h:65
int32_t iPlrStartIndex
Definition: C4Teams.h:48
bool IsRuntimeJoinTeamChoice() const
Definition: C4Teams.h:173
void Clear()
Definition: C4Teams.cpp:255
int32_t GetLargestTeamID() const
Definition: C4Teams.cpp:427
int32_t GetStartupTeamCount(int32_t startup_player_count)
Definition: C4Teams.cpp:913
C4Team * GetTeamByIndex(int32_t iIndex) const
Definition: C4Teams.cpp:404
@ TEAMDIST_First
Definition: C4Teams.h:107
@ TEAMDIST_Random
Definition: C4Teams.h:111
@ TEAMDIST_Host
Definition: C4Teams.h:109
@ TEAMDIST_Last
Definition: C4Teams.h:113
@ TEAMDIST_None
Definition: C4Teams.h:110
@ TEAMDIST_Free
Definition: C4Teams.h:108
@ TEAMDIST_RandomInv
Definition: C4Teams.h:112
C4Team * GetTeamByPlayerID(int32_t iID) const
Definition: C4Teams.cpp:420
bool IsMultiTeams() const
Definition: C4Teams.h:162
void EnsureTeamCount()
Definition: C4Teams.cpp:719
C4Team * GetTeamByID(int32_t iID) const
Definition: C4Teams.cpp:383
C4Team * CreateTeam(const char *szName)
Definition: C4Teams.cpp:360
bool IsTeamVisible() const
Definition: C4Teams.cpp:454
void EnforceLeagueRules()
Definition: C4Teams.cpp:856
void CompileFunc(StdCompiler *pComp)
Definition: C4Teams.cpp:545
void SetTeamDistribution(TeamDist eToVal)
Definition: C4Teams.cpp:809
C4Team * GetRandomSmallestTeam() const
Definition: C4Teams.cpp:435
@ TEAM_None
Definition: C4Teams.h:94
@ TEAM_Dist
Definition: C4Teams.h:98
@ TEAM_Active
Definition: C4Teams.h:96
@ TEAM_AllowTeamSwitch
Definition: C4Teams.h:99
@ TEAM_Custom
Definition: C4Teams.h:95
@ TEAM_AllowHostilityChange
Definition: C4Teams.h:97
@ TEAM_TeamColors
Definition: C4Teams.h:101
@ TEAM_AutoGenerateTeams
Definition: C4Teams.h:100
void RecheckPlayers()
Definition: C4Teams.cpp:663
bool Save(C4Group &hGroup)
Definition: C4Teams.cpp:646
bool Load(C4Group &hGroup, class C4Scenario *pInitDefault, class C4LangStringTable *pLang)
Definition: C4Teams.cpp:604
bool CanLocalChooseTeam() const
Definition: C4Teams.cpp:292
bool IsHostilityChangeAllowed() const
Definition: C4Teams.h:164
~C4TeamList()
Definition: C4Teams.h:135
int32_t GetMaxScriptPlayers() const
Definition: C4Teams.h:174
bool IsAutoGenerateTeams() const
Definition: C4Teams.h:172
bool IsTeamColors() const
Definition: C4Teams.h:169
TeamDist GetTeamDist() const
Definition: C4Teams.h:211
StdStrBuf GetScriptPlayerName() const
Definition: C4Teams.cpp:899
void FillTeamDistOptions(C4GUI::ComboBox_FillCB *pFiller) const
Definition: C4Teams.cpp:778
void SetTeamColors(bool fEnabled)
Definition: C4Teams.cpp:839
StdStrBuf GetTeamDistString() const
Definition: C4Teams.cpp:797
bool IsJoin2TeamAllowed(int32_t idTeam, C4PlayerType plrType)
Definition: C4Teams.cpp:534
bool RecheckPlayerInfoTeams(C4PlayerInfo &rNewJoin, bool fByHost)
Definition: C4Teams.cpp:463
int32_t GetTeamCount() const
Definition: C4Teams.h:158
C4Team * GetGenerateTeamByID(int32_t iID)
Definition: C4Teams.cpp:390
bool IsCustom() const
Definition: C4Teams.h:163
C4TeamList & operator=(const C4TeamList &rCopy)
Definition: C4Teams.cpp:273
void SendSetTeamDist(TeamDist eNewDist)
Definition: C4Teams.cpp:790
bool IsRandomTeam() const
Definition: C4Teams.h:170
bool IsTeamSwitchAllowed() const
Definition: C4Teams.h:165
void SendSetTeamColors(bool fEnabled)
Definition: C4Teams.cpp:833
bool HasTeamDistOptions() const
Definition: C4Teams.cpp:803
bool CanLocalSeeTeam() const
Definition: C4Teams.cpp:327
void RecheckTeams()
Definition: C4Teams.cpp:669
int32_t GetForcedTeamSelection(int32_t idForPlayer) const
Definition: C4Teams.cpp:863
void ReassignAllTeams()
Definition: C4Teams.cpp:732
C4Team * GetTeamByName(const char *szName) const
Definition: C4Teams.cpp:412
C4TeamList()=default
const char * getData() const
Definition: StdBuf.h:442