Freeciv-3.4
Loading...
Searching...
No Matches
team.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2005 - The Freeciv Project
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdlib.h>
19
20/* utility */
21#include "fcintl.h"
22#include "log.h"
23#include "shared.h"
24#include "support.h"
25
26/* common */
27#include "game.h"
28#include "player.h"
29#include "team.h"
30
31struct team_slot {
32 struct team *team;
33 char *defined_name; /* Defined by the ruleset. */
34 char *rule_name; /* Usable untranslated name. */
35#ifdef FREECIV_ENABLE_NLS
36 char *name_translation; /* Translated name. */
37#endif
38};
39
40struct team {
42 struct team_slot *slot;
43};
44
45static struct {
49
50/************************************************************************/
54{
55 int i;
56
57 /* Init team slots and names. */
58 team_slots.slots = fc_calloc(team_slot_count(), sizeof(*team_slots.slots));
59 /* Can't use the defined functions as the needed data will be
60 * defined here. */
61 for (i = 0; i < team_slot_count(); i++) {
62 struct team_slot *tslot = team_slots.slots + i;
63
64 tslot->team = nullptr;
65 tslot->defined_name = nullptr;
66 tslot->rule_name = nullptr;
67#ifdef FREECIV_ENABLE_NLS
68 tslot->name_translation = nullptr;
69#endif
70 }
71 team_slots.used_slots = 0;
72}
73
74/************************************************************************/
78{
79 return (team_slots.slots != nullptr);
80}
81
82/************************************************************************/
86{
88 if (tslot->team != nullptr) {
89 team_destroy(tslot->team);
90 }
91 if (tslot->defined_name != nullptr) {
92 free(tslot->defined_name);
93 }
94 if (tslot->rule_name != nullptr) {
95 free(tslot->rule_name);
96 }
97#ifdef FREECIV_ENABLE_NLS
98 if (tslot->name_translation != nullptr) {
99 free(tslot->name_translation);
100 }
101#endif /* FREECIV_ENABLE_NLS */
103 free(team_slots.slots);
104 team_slots.slots = nullptr;
105
106 team_slots.used_slots = 0;
107}
108
109/************************************************************************/
113{
114 return (MAX_NUM_TEAM_SLOTS);
115}
116
117/************************************************************************/
121{
122 return team_slots.slots;
123}
124
125/************************************************************************/
129{
130 tslot++;
131 return (tslot < team_slots.slots + team_slot_count() ? tslot : nullptr);
132}
133
134
135/************************************************************************/
139{
141
142 return tslot - team_slots.slots;
143}
144
145/************************************************************************/
150{
152
153 return tslot->team;
154}
155
156/************************************************************************/
161{
162 /* No team slot available, if the game is not initialised. */
163 if (!team_slots_initialised()) {
164 return FALSE;
165 }
166
167 return tslot->team != nullptr;
168}
169
170/************************************************************************/
173struct team_slot *team_slot_by_number(int team_id)
174{
176 || !(0 <= team_id && team_id < team_slot_count())) {
177 return nullptr;
178 }
179
180 return team_slots.slots + team_id;
181}
182
183/************************************************************************/
187struct team_slot *team_slot_by_rule_name(const char *team_name)
188{
190 const char *tname = team_slot_rule_name(tslot);
191
192 if (tname != nullptr && 0 == fc_strcasecmp(tname, team_name)) {
193 return tslot;
194 }
196
197 return nullptr;
198}
199
200/************************************************************************/
204{
205 char buf[MAX_LEN_NAME];
206
207 fc_assert(tslot->defined_name == nullptr);
208 fc_assert(tslot->rule_name == nullptr);
209#ifdef FREECIV_ENABLE_NLS
210 fc_assert(tslot->name_translation == nullptr);
211#endif /* FREECIV_ENABLE_NLS */
212
213 fc_snprintf(buf, sizeof(buf), "Team %d", team_slot_index(tslot) + 1);
214 tslot->rule_name = fc_strdup(buf);
215
216#ifdef FREECIV_ENABLE_NLS
217 fc_snprintf(buf, sizeof(buf), _("Team %d"), team_slot_index(tslot) + 1);
218 tslot->name_translation = fc_strdup(buf);
219#endif /* FREECIV_ENABLE_NLS */
220
221 log_verbose("No name defined for team %d! Creating a default name: %s.",
222 team_slot_index(tslot), tslot->rule_name);
223}
224
225/************************************************************************/
229const char *team_slot_rule_name(const struct team_slot *tslot)
230{
232
233 if (tslot->rule_name == nullptr) {
234 /* Get the team slot as changeable (not _const_) struct. */
235 struct team_slot *changeable
238 return changeable->rule_name;
239 }
240
241 return tslot->rule_name;
242}
243
244/************************************************************************/
249{
251
252#ifdef FREECIV_ENABLE_NLS
253 if (tslot->name_translation == nullptr) {
254 /* Get the team slot as changeable (not _const_) struct. */
255 struct team_slot *changeable
257
259 return changeable->name_translation;
260 }
261
262 return tslot->name_translation;
263#else /* FREECIV_ENABLE_NLS */
265#endif /* FREECIV_ENABLE_NLS */
266}
267
268/************************************************************************/
272const char *team_slot_defined_name(const struct team_slot *tslot)
273{
275
276 return tslot->defined_name;
277}
278
279/************************************************************************/
283 const char *team_name)
284{
286
287 if (tslot->defined_name != nullptr) {
288 free(tslot->defined_name);
289 }
290 tslot->defined_name = fc_strdup(team_name);
291
292 if (tslot->rule_name != nullptr) {
293 free(tslot->rule_name);
294 }
295 tslot->rule_name = fc_strdup(Qn_(team_name));
296
297#ifdef FREECIV_ENABLE_NLS
298 if (tslot->name_translation != nullptr) {
299 free(tslot->name_translation);
300 }
301 tslot->name_translation = fc_strdup(Q_(team_name));
302#endif /* FREECIV_ENABLE_NLS */
303}
304
305/************************************************************************/
309struct team *team_new(struct team_slot *tslot)
310{
311 struct team *pteam;
312
314
315 if (tslot == nullptr) {
317 if (!team_slot_is_used(aslot)) {
318 tslot = aslot;
319 break;
320 }
322
323 if (tslot == nullptr) {
324 return nullptr;
325 }
326 } else if (tslot->team != nullptr) {
327 return tslot->team;
328 }
329
330 /* Now create the team. */
331 log_debug("Create team for slot %d.", team_slot_index(tslot));
332 pteam = fc_calloc(1, sizeof(*pteam));
333 pteam->slot = tslot;
334 tslot->team = pteam;
335
336 /* Set default values. */
337 pteam->plrlist = player_list_new();
338
339 /* Increase number of teams. */
340 team_slots.used_slots++;
341
342 return pteam;
343}
344
345/************************************************************************/
349{
350 struct team_slot *tslot;
351
353 fc_assert(0 == player_list_size(pteam->plrlist));
354
355 tslot = pteam->slot;
356 fc_assert(tslot->team == pteam);
357
358 player_list_destroy(pteam->plrlist);
359 free(pteam);
360 tslot->team = nullptr;
361 team_slots.used_slots--;
362}
363
364/************************************************************************/
367int team_count(void)
368{
369 return team_slots.used_slots;
370}
371
372/************************************************************************/
375int team_index(const struct team *pteam)
376{
377 return team_number(pteam);
378}
379
380/************************************************************************/
383int team_number(const struct team *pteam)
384{
385 return team_slot_index(pteam->slot);
386}
387
388/************************************************************************/
391struct team *team_by_number(const int team_id)
392{
393 const struct team_slot *tslot = team_slot_by_number(team_id);
394
395 return (tslot != nullptr ? team_slot_get_team(tslot) : nullptr);
396}
397
398/************************************************************************/
401const char *team_rule_name(const struct team *pteam)
402{
403 return team_slot_rule_name(pteam->slot);
404}
405
406/************************************************************************/
409const char *team_name_translation(const struct team *pteam)
410{
411 return team_slot_name_translation(pteam->slot);
412}
413
414/************************************************************************/
419int team_pretty_name(const struct team *pteam, char *buf, size_t buf_len)
420{
421 if (pteam != nullptr) {
422 if (pteam->slot->defined_name != nullptr) {
423 /* TRANS: %s is ruleset-chosen team name (e.g. "Red") */
424 return fc_snprintf(buf, buf_len, _("team %s"),
426 } else {
427 /* The generated name already contains word "Team" so don't repeat it.
428 * Also note that number of teams may have changed since the name
429 * was originally generated, so the number in it can be
430 * something else than current team_number(). */
432 }
433 }
434
435 /* No need to translate, it's an error. */
436 fc_strlcpy(buf, "(null team)", buf_len);
437 return -1;
438}
439
440/************************************************************************/
443const struct player_list *team_members(const struct team *pteam)
444{
445 return pteam->plrlist;
446}
447
448/************************************************************************/
452bool team_add_player(struct player *pplayer, struct team *pteam)
453{
454 if (pteam == nullptr) {
455 pteam = team_new(nullptr);
456 } else if (pteam == pplayer->team) {
457 /* It is the team of the player. */
458 return TRUE;
459 }
460
461 if (pteam == nullptr) {
462 return FALSE;
463 }
464
465 log_debug("Adding player %d/%s to team %s.", player_number(pplayer),
466 pplayer->username, team_rule_name(pteam));
467
468 /* Remove the player from the old team, if any. */
469 team_remove_player(pplayer);
470
471 /* Put the player on the new team. */
472 pplayer->team = pteam;
473 player_list_append(pteam->plrlist, pplayer);
474
475 return TRUE;
476}
477
478/************************************************************************/
485void team_remove_player(struct player *pplayer)
486{
487 struct team *pteam;
488
489 if (pplayer->team != nullptr) {
490 pteam = pplayer->team;
491
492 log_debug("Removing player %d/%s from team %s (%d)",
493 player_number(pplayer), player_name(pplayer),
495 player_list_remove(pteam->plrlist, pplayer);
496
497 if (player_list_size(pteam->plrlist) == 0) {
499 }
500 }
501
502 pplayer->team = nullptr;
503}
char * incite_cost
Definition comments.c:77
#define MAX_LEN_NAME
Definition fc_types.h:68
#define Q_(String)
Definition fcintl.h:70
#define _(String)
Definition fcintl.h:67
#define Qn_(String)
Definition fcintl.h:89
#define fc_assert_ret(condition)
Definition log.h:192
#define log_verbose(message,...)
Definition log.h:110
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define log_debug(message,...)
Definition log.h:116
#define fc_calloc(n, esz)
Definition mem.h:38
#define fc_strdup(str)
Definition mem.h:43
int player_number(const struct player *pplayer)
Definition player.c:826
const char * player_name(const struct player *pplayer)
Definition player.c:885
char username[MAX_LEN_NAME]
Definition player.h:252
struct team * team
Definition player.h:261
char * defined_name
Definition team.c:33
char * rule_name
Definition team.c:34
struct team * team
Definition team.c:32
Definition team.c:40
struct team_slot * slot
Definition team.c:42
struct player_list * plrlist
Definition team.c:41
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:777
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:186
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
int team_count(void)
Definition team.c:367
int team_index(const struct team *pteam)
Definition team.c:375
struct team * team_by_number(const int team_id)
Definition team.c:391
const char * team_name_translation(const struct team *pteam)
Definition team.c:409
struct team_slot * team_slot_by_number(int team_id)
Definition team.c:173
void team_slots_free(void)
Definition team.c:85
const char * team_rule_name(const struct team *pteam)
Definition team.c:401
static void team_slot_create_default_name(struct team_slot *tslot)
Definition team.c:203
struct team * team_slot_get_team(const struct team_slot *tslot)
Definition team.c:149
int used_slots
Definition team.c:47
const char * team_slot_name_translation(const struct team_slot *tslot)
Definition team.c:248
static struct @82 team_slots
struct team_slot * team_slot_first(void)
Definition team.c:120
const char * team_slot_defined_name(const struct team_slot *tslot)
Definition team.c:272
int team_number(const struct team *pteam)
Definition team.c:383
void team_destroy(struct team *pteam)
Definition team.c:348
bool team_slots_initialised(void)
Definition team.c:77
struct team_slot * team_slot_next(struct team_slot *tslot)
Definition team.c:128
bool team_add_player(struct player *pplayer, struct team *pteam)
Definition team.c:452
struct team * team_new(struct team_slot *tslot)
Definition team.c:309
int team_pretty_name(const struct team *pteam, char *buf, size_t buf_len)
Definition team.c:419
int team_slot_index(const struct team_slot *tslot)
Definition team.c:138
struct team_slot * team_slot_by_rule_name(const char *team_name)
Definition team.c:187
const struct player_list * team_members(const struct team *pteam)
Definition team.c:443
void team_slots_init(void)
Definition team.c:53
void team_remove_player(struct player *pplayer)
Definition team.c:485
int team_slot_count(void)
Definition team.c:112
bool team_slot_is_used(const struct team_slot *tslot)
Definition team.c:160
void team_slot_set_defined_name(struct team_slot *tslot, const char *team_name)
Definition team.c:282
const char * team_slot_rule_name(const struct team_slot *tslot)
Definition team.c:229
struct team_slot * slots
Definition team.c:46
#define team_slots_iterate_end
Definition team.h:89
#define team_slots_iterate(_tslot)
Definition team.h:84
#define MAX_NUM_TEAM_SLOTS
Definition team.h:27