Freeciv-3.1: /fast/freeciv/nightly/S3_1/common/team.c Source File

Freeciv-3.1

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
31 struct 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
40 struct team {
41 struct player_list *plrlist;
42 struct team_slot *slot;
43};
44
45static struct {
46 struct team_slot *slots;
47 int used_slots;
48} team_slots;
49
50/************************************************************************/
53 void team_slots_init(void)
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 = NULL;
65 tslot->defined_name = NULL;
66 tslot->rule_name = NULL;
67#ifdef FREECIV_ENABLE_NLS
68 tslot->name_translation = NULL;
69#endif
70 }
71 team_slots.used_slots = 0;
72}
73
74/************************************************************************/
77 bool team_slots_initialised(void)
78{
79 return (team_slots.slots != NULL);
80}
81
82/************************************************************************/
85 void team_slots_free(void)
86{
87 team_slots_iterate(tslot) {
88 if (NULL != tslot->team) {
89 team_destroy(tslot->team);
90 }
91 if (NULL != tslot->defined_name) {
92 free(tslot->defined_name);
93 }
94 if (NULL != tslot->rule_name) {
95 free(tslot->rule_name);
96 }
97#ifdef FREECIV_ENABLE_NLS
98 if (NULL != tslot->name_translation) {
99 free(tslot->name_translation);
100 }
101#endif /* FREECIV_ENABLE_NLS */
102 } team_slots_iterate_end;
103 free(team_slots.slots);
104 team_slots.slots = NULL;
105
106 team_slots.used_slots = 0;
107}
108
109/************************************************************************/
112 int team_slot_count(void)
113{
114 return (MAX_NUM_TEAM_SLOTS);
115}
116
117/************************************************************************/
120 struct team_slot *team_slot_first(void)
121{
122 return team_slots.slots;
123}
124
125/************************************************************************/
128 struct team_slot *team_slot_next(struct team_slot *tslot)
129{
130 tslot++;
131 return (tslot < team_slots.slots + team_slot_count() ? tslot : NULL);
132}
133
134
135/************************************************************************/
138 int team_slot_index(const struct team_slot *tslot)
139{
140 fc_assert_ret_val(team_slots_initialised(), -1);
141 fc_assert_ret_val(tslot != NULL, -1);
142
143 return tslot - team_slots.slots;
144}
145
146/************************************************************************/
150 struct team *team_slot_get_team(const struct team_slot *tslot)
151{
152 fc_assert_ret_val(team_slots_initialised(), NULL);
153 fc_assert_ret_val(tslot != NULL, NULL);
154
155 return tslot->team;
156}
157
158/************************************************************************/
162 bool team_slot_is_used(const struct team_slot *tslot)
163{
164 /* No team slot available, if the game is not initialised. */
165 if (!team_slots_initialised()) {
166 return FALSE;
167 }
168
169 return NULL != tslot->team;
170}
171
172/************************************************************************/
175 struct team_slot *team_slot_by_number(int team_id)
176{
177 if (!team_slots_initialised()
178 || !(0 <= team_id && team_id < team_slot_count())) {
179 return NULL;
180 }
181
182 return team_slots.slots + team_id;
183}
184
185/************************************************************************/
189 struct team_slot *team_slot_by_rule_name(const char *team_name)
190{
191 fc_assert_ret_val(team_name != NULL, NULL);
192
193 team_slots_iterate(tslot) {
194 const char *tname = team_slot_rule_name(tslot);
195
196 if (NULL != tname && 0 == fc_strcasecmp(tname, team_name)) {
197 return tslot;
198 }
199 } team_slots_iterate_end;
200
201 return NULL;
202}
203
204/************************************************************************/
207 static inline void team_slot_create_default_name(struct team_slot *tslot)
208{
209 char buf[MAX_LEN_NAME];
210
211 fc_assert(NULL == tslot->defined_name);
212 fc_assert(NULL == tslot->rule_name);
213#ifdef FREECIV_ENABLE_NLS
214 fc_assert(NULL == tslot->name_translation);
215#endif /* FREECIV_ENABLE_NLS */
216
217 fc_snprintf(buf, sizeof(buf), "Team %d", team_slot_index(tslot) + 1);
218 tslot->rule_name = fc_strdup(buf);
219
220#ifdef FREECIV_ENABLE_NLS
221 fc_snprintf(buf, sizeof(buf), _("Team %d"), team_slot_index(tslot) + 1);
222 tslot->name_translation = fc_strdup(buf);
223#endif /* FREECIV_ENABLE_NLS */
224
225 log_verbose("No name defined for team %d! Creating a default name: %s.",
226 team_slot_index(tslot), tslot->rule_name);
227}
228
229/************************************************************************/
233 const char *team_slot_rule_name(const struct team_slot *tslot)
234{
235 fc_assert_ret_val(team_slots_initialised(), NULL);
236 fc_assert_ret_val(NULL != tslot, NULL);
237
238 if (NULL == tslot->rule_name) {
239 /* Get the team slot as changeable (not _const_) struct. */
240 struct team_slot *changeable
241 = team_slot_by_number(team_slot_index(tslot));
242 team_slot_create_default_name(changeable);
243 return changeable->rule_name;
244 }
245
246 return tslot->rule_name;
247}
248
249/************************************************************************/
253 const char *team_slot_name_translation(const struct team_slot *tslot)
254{
255#ifdef FREECIV_ENABLE_NLS
256 fc_assert_ret_val(team_slots_initialised(), NULL);
257 fc_assert_ret_val(NULL != tslot, NULL);
258
259 if (NULL == tslot->name_translation) {
260 /* Get the team slot as changeable (not _const_) struct. */
261 struct team_slot *changeable
262 = team_slot_by_number(team_slot_index(tslot));
263 team_slot_create_default_name(changeable);
264 return changeable->name_translation;
265 }
266
267 return tslot->name_translation;
268#else /* FREECIV_ENABLE_NLS */
269 return team_slot_rule_name(tslot);
270#endif /* FREECIV_ENABLE_NLS */
271}
272
273/************************************************************************/
277 const char *team_slot_defined_name(const struct team_slot *tslot)
278{
279 fc_assert_ret_val(team_slots_initialised(), NULL);
280 fc_assert_ret_val(NULL != tslot, NULL);
281
282 return tslot->defined_name;
283}
284
285/************************************************************************/
288 void team_slot_set_defined_name(struct team_slot *tslot,
289 const char *team_name)
290{
291 fc_assert_ret(team_slots_initialised());
292 fc_assert_ret(NULL != tslot);
293 fc_assert_ret(NULL != team_name);
294
295 if (NULL != tslot->defined_name) {
296 free(tslot->defined_name);
297 }
298 tslot->defined_name = fc_strdup(team_name);
299
300 if (NULL != tslot->rule_name) {
301 free(tslot->rule_name);
302 }
303 tslot->rule_name = fc_strdup(Qn_(team_name));
304
305#ifdef FREECIV_ENABLE_NLS
306 if (NULL != tslot->name_translation) {
307 free(tslot->name_translation);
308 }
309 tslot->name_translation = fc_strdup(Q_(team_name));
310#endif /* FREECIV_ENABLE_NLS */
311}
312
313/************************************************************************/
317 struct team *team_new(struct team_slot *tslot)
318{
319 struct team *pteam;
320
321 fc_assert_ret_val(team_slots_initialised(), NULL);
322
323 if (tslot == NULL) {
324 team_slots_iterate(aslot) {
325 if (!team_slot_is_used(aslot)) {
326 tslot = aslot;
327 break;
328 }
329 } team_slots_iterate_end;
330
331 if (tslot == NULL) {
332 return NULL;
333 }
334 } else if (tslot->team != NULL) {
335 return tslot->team;
336 }
337
338 /* Now create the team. */
339 log_debug("Create team for slot %d.", team_slot_index(tslot));
340 pteam = fc_calloc(1, sizeof(*pteam));
341 pteam->slot = tslot;
342 tslot->team = pteam;
343
344 /* Set default values. */
345 pteam->plrlist = player_list_new();
346
347 /* Increase number of teams. */
348 team_slots.used_slots++;
349
350 return pteam;
351}
352
353/************************************************************************/
356 void team_destroy(struct team *pteam)
357{
358 struct team_slot *tslot;
359
360 fc_assert_ret(team_slots_initialised());
361 fc_assert(0 == player_list_size(pteam->plrlist));
362
363 tslot = pteam->slot;
364 fc_assert(tslot->team == pteam);
365
366 player_list_destroy(pteam->plrlist);
367 free(pteam);
368 tslot->team = NULL;
369 team_slots.used_slots--;
370}
371
372/************************************************************************/
375 int team_count(void)
376{
377 return team_slots.used_slots;
378}
379
380/************************************************************************/
383 int team_index(const struct team *pteam)
384{
385 return team_number(pteam);
386}
387
388/************************************************************************/
391 int team_number(const struct team *pteam)
392{
393 fc_assert_ret_val(NULL != pteam, -1);
394 return team_slot_index(pteam->slot);
395}
396
397/************************************************************************/
400 struct team *team_by_number(const int team_id)
401{
402 const struct team_slot *tslot = team_slot_by_number(team_id);
403
404 return (NULL != tslot ? team_slot_get_team(tslot) : NULL);
405}
406
407/************************************************************************/
410 const char *team_rule_name(const struct team *pteam)
411{
412 fc_assert_ret_val(NULL != pteam, NULL);
413
414 return team_slot_rule_name(pteam->slot);
415}
416
417/************************************************************************/
420 const char *team_name_translation(const struct team *pteam)
421{
422 fc_assert_ret_val(NULL != pteam, NULL);
423
424 return team_slot_name_translation(pteam->slot);
425}
426
427/************************************************************************/
432 int team_pretty_name(const struct team *pteam, char *buf, size_t buf_len)
433{
434 if (NULL != pteam) {
435 if (NULL != pteam->slot->defined_name) {
436 /* TRANS: %s is ruleset-chosen team name (e.g. "Red") */
437 return fc_snprintf(buf, buf_len, _("team %s"),
438 team_slot_name_translation(pteam->slot));
439 } else {
440 /* The generated name already contains word "Team" so don't repeat it.
441 * Also note that number of teams may have changed since the name
442 * was originally generated, so the number in it can be
443 * something else than current team_number(). */
444 return fc_snprintf(buf, buf_len, "%s", team_name_translation(pteam));
445 }
446 }
447
448 /* No need to translate, it's an error. */
449 fc_strlcpy(buf, "(null team)", buf_len);
450 return -1;
451}
452
453/************************************************************************/
456 const struct player_list *team_members(const struct team *pteam)
457{
458 fc_assert_ret_val(NULL != pteam, NULL);
459
460 return pteam->plrlist;
461}
462
463/************************************************************************/
467 bool team_add_player(struct player *pplayer, struct team *pteam)
468{
469 fc_assert_ret_val(pplayer != NULL, FALSE);
470
471 if (pteam == NULL) {
472 pteam = team_new(NULL);
473 } else if (pteam == pplayer->team) {
474 /* It is the team of the player. */
475 return TRUE;
476 }
477
478 if (pteam == NULL) {
479 return FALSE;
480 }
481
482 log_debug("Adding player %d/%s to team %s.", player_number(pplayer),
483 pplayer->username, team_rule_name(pteam));
484
485 /* Remove the player from the old team, if any. */
486 team_remove_player(pplayer);
487
488 /* Put the player on the new team. */
489 pplayer->team = pteam;
490 player_list_append(pteam->plrlist, pplayer);
491
492 return TRUE;
493}
494
495/************************************************************************/
502 void team_remove_player(struct player *pplayer)
503{
504 struct team *pteam;
505
506 if (pplayer->team != NULL) {
507 pteam = pplayer->team;
508
509 log_debug("Removing player %d/%s from team %s (%d)",
510 player_number(pplayer), player_name(pplayer),
511 team_rule_name(pteam), player_list_size(pteam->plrlist));
512 player_list_remove(pteam->plrlist, pplayer);
513
514 if (player_list_size(pteam->plrlist) == 0) {
515 team_destroy(pteam);
516 }
517 }
518
519 pplayer->team = NULL;
520}
MAX_LEN_NAME
#define MAX_LEN_NAME
Definition fc_types.h:66
fcintl.h
Q_
#define Q_(String)
Definition fcintl.h:70
_
#define _(String)
Definition fcintl.h:67
Qn_
#define Qn_(String)
Definition fcintl.h:89
game.h
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
log_verbose
#define log_verbose(message,...)
Definition log.h:109
fc_assert
#define fc_assert(condition)
Definition log.h:176
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_debug
#define log_debug(message,...)
Definition log.h:115
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
fc_strdup
#define fc_strdup(str)
Definition mem.h:43
player_number
int player_number(const struct player *pplayer)
Definition player.c:828
player_name
const char * player_name(const struct player *pplayer)
Definition player.c:886
player.h
shared.h
name_translation
Definition name_translation.h:35
player
Definition player.h:249
player::username
char username[MAX_LEN_NAME]
Definition player.h:252
player::team
struct team * team
Definition player.h:261
team_slot
Definition team.c:31
team_slot::defined_name
char * defined_name
Definition team.c:33
team_slot::rule_name
char * rule_name
Definition team.c:34
team_slot::team
struct team * team
Definition team.c:32
team
Definition team.c:40
team::slot
struct team_slot * slot
Definition team.c:42
team::plrlist
struct player_list * plrlist
Definition team.c:41
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
fc_strlcpy
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:787
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
support.h
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
team_count
int team_count(void)
Definition team.c:375
team_index
int team_index(const struct team *pteam)
Definition team.c:383
team_by_number
struct team * team_by_number(const int team_id)
Definition team.c:400
team_name_translation
const char * team_name_translation(const struct team *pteam)
Definition team.c:420
team_slot_by_number
struct team_slot * team_slot_by_number(int team_id)
Definition team.c:175
team_slots_free
void team_slots_free(void)
Definition team.c:85
team_rule_name
const char * team_rule_name(const struct team *pteam)
Definition team.c:410
team_slot_create_default_name
static void team_slot_create_default_name(struct team_slot *tslot)
Definition team.c:207
team_slot_get_team
struct team * team_slot_get_team(const struct team_slot *tslot)
Definition team.c:150
used_slots
int used_slots
Definition team.c:47
team_slot_name_translation
const char * team_slot_name_translation(const struct team_slot *tslot)
Definition team.c:253
team_slot_first
struct team_slot * team_slot_first(void)
Definition team.c:120
team_slot_defined_name
const char * team_slot_defined_name(const struct team_slot *tslot)
Definition team.c:277
team_number
int team_number(const struct team *pteam)
Definition team.c:391
team_destroy
void team_destroy(struct team *pteam)
Definition team.c:356
team_slots_initialised
bool team_slots_initialised(void)
Definition team.c:77
team_slot_next
struct team_slot * team_slot_next(struct team_slot *tslot)
Definition team.c:128
team_add_player
bool team_add_player(struct player *pplayer, struct team *pteam)
Definition team.c:467
team_new
struct team * team_new(struct team_slot *tslot)
Definition team.c:317
team_pretty_name
int team_pretty_name(const struct team *pteam, char *buf, size_t buf_len)
Definition team.c:432
team_slot_index
int team_slot_index(const struct team_slot *tslot)
Definition team.c:138
team_slot_by_rule_name
struct team_slot * team_slot_by_rule_name(const char *team_name)
Definition team.c:189
team_members
const struct player_list * team_members(const struct team *pteam)
Definition team.c:456
team_slots_init
void team_slots_init(void)
Definition team.c:53
team_remove_player
void team_remove_player(struct player *pplayer)
Definition team.c:502
team_slot_count
int team_slot_count(void)
Definition team.c:112
team_slots
static struct @78 team_slots
team_slot_is_used
bool team_slot_is_used(const struct team_slot *tslot)
Definition team.c:162
team_slot_set_defined_name
void team_slot_set_defined_name(struct team_slot *tslot, const char *team_name)
Definition team.c:288
team_slot_rule_name
const char * team_slot_rule_name(const struct team_slot *tslot)
Definition team.c:233
slots
struct team_slot * slots
Definition team.c:46
team.h
team_slots_iterate_end
#define team_slots_iterate_end
Definition team.h:75
team_slots_iterate
#define team_slots_iterate(_tslot)
Definition team.h:70
MAX_NUM_TEAM_SLOTS
#define MAX_NUM_TEAM_SLOTS
Definition team.h:25