Freeciv21
Develop your civilization from humble roots to a global empire
score.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2020 Freeciv21 and Freeciv contributors. This file is
3  __ __ part of Freeciv21. Freeciv21 is free software: you can
4 / \\..// \ redistribute it and/or modify it under the terms of the GNU
5  ( oo ) General Public License as published by the Free Software
6  \__/ Foundation, either version 3 of the License, or (at your
7  option) any later version. You should have received
8  a copy of the GNU General Public License along with Freeciv21. If not,
9  see https://www.gnu.org/licenses/.
10  */
11 
12 #include <cstdio>
13 #include <cstring>
14 
15 // Qt
16 #include <QString>
17 
18 // utility
19 #include "bitvector.h"
20 #include "log.h"
21 #include "shared.h"
22 
23 // common
24 #include "culture.h"
25 #include "game.h"
26 #include "improvement.h"
27 #include "map.h"
28 #include "player.h"
29 #include "research.h"
30 #include "specialist.h"
31 #include "unit.h"
32 #include "unitlist.h"
33 
34 // server
35 #include "plrhand.h"
36 #include "score.h"
37 #include "srv_main.h"
38 
39 static int get_spaceship_score(const struct player *pplayer);
40 
46 #define USER_AREA_MULT 1000
47 
48 struct claim_map {
49  struct {
52 };
53 
58 #define LAND_AREA_DEBUG 0
59 
60 #if LAND_AREA_DEBUG >= 2
61 
66 static char when_char(int when)
67 {
68  static char list[] = {
69  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
70  'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
71  'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c',
72  'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
73  'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
74 
75  return (when >= 0 && when < sizeof(list)) ? list[when] : '?';
76 }
77 
78 /*
79  * Writes the map_char_expr expression for each position on the map.
80  * map_char_expr is provided with the variables x,y to evaluate the
81  * position. The 'type' argument is used for formatting by printf; for
82  * instance it should be "%c" for characters. The data is printed in a
83  * native orientation to make it easier to read.
84  */
85 #define WRITE_MAP_DATA(type, map_char_expr) \
86  { \
87  int nat_x, nat_y; \
88  for (nat_x = 0; nat_x < map.xsize; nat_x++) { \
89  printf("%d", nat_x % 10); \
90  } \
91  putchar('\n'); \
92  for (nat_y = 0; nat_y < map.ysize; nat_y++) { \
93  printf("%d ", nat_y % 10); \
94  for (nat_x = 0; nat_x < map.xsize; nat_x++) { \
95  int x, y; \
96  NATIVE_TO_MAP_POS(&x, &y, nat_x, nat_y); \
97  printf(type, map_char_expr); \
98  } \
99  printf(" %d\n", nat_y % 10); \
100  } \
101  }
102 
106 static void print_landarea_map(struct claim_map *pcmap, int turn)
107 {
108  int p;
109 
110  player_slots_iterate(pslot)
111  {
112  if (player_slot_index(pslot) >= 32 && player_slot_is_used(pslot)) {
113  qCritical("Debugging not possible! Player slots >= 32 are used.");
114  return;
115  }
116  }
118 
119  if (turn == 0) {
120  putchar('\n');
121  }
122 
123  if (turn == 0) {
124  printf("Player Info...\n");
125 
126  for (p = 0; p < player_count(); p++) {
127  printf(".know (%d)\n ", p);
128  WRITE_MAP_DATA("%c",
129  BV_ISSET(pcmap->claims[map_pos_to_index(x, y)].know, p)
130  ? 'X'
131  : '-');
132  printf(".cities (%d)\n ", p);
133  WRITE_MAP_DATA(
134  "%c", BV_ISSET(pcmap->claims[map_pos_to_index(x, y)].cities, p)
135  ? 'O'
136  : '-');
137  }
138  }
139 
140  printf("Turn %d (%c)...\n", turn, when_char(turn));
141 
142  printf(".whom\n ");
143  WRITE_MAP_DATA((pcmap->claims[map_pos_to_index(x, y)].whom == 32) ? "%c"
144  : "%X",
145  (pcmap->claims[map_pos_to_index(x, y)].whom == 32)
146  ? '-'
147  : pcmap->claims[map_pos_to_index(x, y)].whom);
148 
149  printf(".when\n ");
150  WRITE_MAP_DATA("%c",
151  when_char(pcmap->claims[map_pos_to_index(x, y)].when));
152 }
153 
154 #endif // LAND_AREA_DEBUG > 2
155 
159 static void build_landarea_map(struct claim_map *pcmap)
160 {
161  bv_player *claims = new bv_player[MAP_INDEX_SIZE]();
162 
163  memset(pcmap, 0, sizeof(*pcmap));
164 
165  // First calculate claims: which tiles are owned by each player.
166  players_iterate(pplayer)
167  {
168  city_list_iterate(pplayer->cities, pcity)
169  {
170  struct tile *pcenter = city_tile(pcity);
171 
172  city_tile_iterate(city_map_radius_sq_get(pcity), pcenter, tile1)
173  {
174  BV_SET(claims[tile_index(tile1)], player_index(city_owner(pcity)));
175  }
177  }
179  }
181 
182  whole_map_iterate(&(wld.map), ptile)
183  {
184  struct player *owner = nullptr;
185  bv_player *pclaim = &claims[tile_index(ptile)];
186 
187  if (is_ocean_tile(ptile)) {
188  // Nothing.
189  } else if (nullptr != tile_city(ptile)) {
190  owner = city_owner(tile_city(ptile));
191  pcmap->player[player_index(owner)].settledarea++;
192  } else if (nullptr != tile_worked(ptile)) {
193  owner = city_owner(tile_worked(ptile));
194  pcmap->player[player_index(owner)].settledarea++;
195  } else if (unit_list_size(ptile->units) > 0) {
196  // Because of allied stacking these calculations are a bit off.
197  owner = unit_owner(unit_list_get(ptile->units, 0));
198  if (BV_ISSET(*pclaim, player_index(owner))) {
199  pcmap->player[player_index(owner)].settledarea++;
200  }
201  }
202 
203  if (BORDERS_DISABLED != game.info.borders) {
204  /* If borders are enabled, use owner information directly from the
205  * map. Otherwise use the calculations above. */
206  owner = tile_owner(ptile);
207  }
208  if (owner) {
209  pcmap->player[player_index(owner)].landarea++;
210  }
211  }
213 
214  delete[] claims;
215 
216 #if LAND_AREA_DEBUG >= 2
217  print_landarea_map(pcmap, turn);
218 #endif
219 }
220 
224 static void get_player_landarea(struct claim_map *pcmap,
225  struct player *pplayer, int *return_landarea,
226  int *return_settledarea)
227 {
228  if (pcmap && pplayer) {
229 #if LAND_AREA_DEBUG >= 1
230  printf("%-14s", player_name(pplayer));
231 #endif
232  if (return_landarea) {
233  *return_landarea =
234  USER_AREA_MULT * pcmap->player[player_index(pplayer)].landarea;
235 #if LAND_AREA_DEBUG >= 1
236  printf(" l=%d", *return_landarea / USER_AREA_MULT);
237 #endif
238  }
239  if (return_settledarea) {
240  *return_settledarea =
241  USER_AREA_MULT * pcmap->player[player_index(pplayer)].settledarea;
242 #if LAND_AREA_DEBUG >= 1
243  printf(" s=%d", *return_settledarea / USER_AREA_MULT);
244 #endif
245  }
246 #if LAND_AREA_DEBUG >= 1
247  printf("\n");
248 #endif
249  }
250 }
251 
255 void calc_civ_score(struct player *pplayer)
256 {
257  const struct research *presearch;
258  struct city *wonder_city;
259  int landarea = 0, settledarea = 0;
260  static struct claim_map cmap;
261 
262  pplayer->score.happy = 0;
263  pplayer->score.content = 0;
264  pplayer->score.unhappy = 0;
265  pplayer->score.angry = 0;
266  specialist_type_iterate(sp) { pplayer->score.specialists[sp] = 0; }
268  pplayer->score.wonders = 0;
269  pplayer->score.techs = 0;
270  pplayer->score.techout = 0;
271  pplayer->score.goldout = 0;
272  pplayer->score.landarea = 0;
273  pplayer->score.settledarea = 0;
274  pplayer->score.population = 0;
275  pplayer->score.cities = 0;
276  pplayer->score.improvements = 0;
277  pplayer->score.all_wonders = 0;
278  pplayer->score.units = 0;
279  pplayer->score.pollution = 0;
280  pplayer->score.bnp = 0;
281  pplayer->score.mfg = 0;
282  pplayer->score.food = 0;
283  pplayer->score.literacy = 0;
284  pplayer->score.spaceship = 0;
285  pplayer->score.culture = player_culture(pplayer);
286 
287  if (is_barbarian(pplayer)) {
288  return;
289  }
290 
291  city_list_iterate(pplayer->cities, pcity)
292  {
293  int bonus;
294 
295  pplayer->score.happy += pcity->feel[CITIZEN_HAPPY][FEELING_FINAL];
296  pplayer->score.content += pcity->feel[CITIZEN_CONTENT][FEELING_FINAL];
297  pplayer->score.unhappy += pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL];
298  pplayer->score.angry += pcity->feel[CITIZEN_ANGRY][FEELING_FINAL];
300  {
301  pplayer->score.specialists[sp] += pcity->specialists[sp];
302  }
304  pplayer->score.population += city_population(pcity);
305  pplayer->score.cities++;
306  pplayer->score.pollution += pcity->pollution;
307  pplayer->score.techout += pcity->prod[O_SCIENCE];
308  /* XXX: BEFORE upkeep paid (consider gold_upkeep_style) */
309  pplayer->score.goldout += pcity->prod[O_GOLD];
310  pplayer->score.bnp += pcity->surplus[O_TRADE];
311  pplayer->score.mfg += pcity->surplus[O_SHIELD]; /* after upkeep paid */
312  pplayer->score.food += pcity->surplus[O_FOOD]; /* after upkeep paid */
313 
314  city_built_iterate(pcity, impr)
315  {
316  /* Great wonders are also counted separately */
317  if (is_improvement(impr)) {
318  pplayer->score.improvements++;
319  } else if (is_wonder(impr)) {
320  pplayer->score.all_wonders++;
321  }
322  }
324 
325  bonus = get_final_city_output_bonus(pcity, O_SCIENCE) - 100;
326  bonus = CLIP(0, bonus, 100);
327  pplayer->score.literacy += (city_population(pcity) * bonus) / 100;
328  }
330 
331  build_landarea_map(&cmap);
332 
333  get_player_landarea(&cmap, pplayer, &landarea, &settledarea);
334  pplayer->score.landarea = landarea;
335  pplayer->score.settledarea = settledarea;
336 
337  presearch = research_get(pplayer);
339  {
340  if (research_invention_state(presearch, i) == TECH_KNOWN) {
341  pplayer->score.techs++;
342  }
343  }
345  pplayer->score.techs += research_get(pplayer)->future_tech * 5 / 2;
346 
347  unit_list_iterate(pplayer->units, punit)
348  {
349  if (is_military_unit(punit)) {
350  pplayer->score.units++;
351  }
352  }
354 
356  {
357  if (is_great_wonder(i) && (wonder_city = city_from_great_wonder(i))
358  && player_owns_city(pplayer, wonder_city)) {
359  pplayer->score.wonders++;
360  }
361  }
363 
364  pplayer->score.spaceship = pplayer->spaceship.state;
365 
366  pplayer->score.game = get_civ_score(pplayer);
367 }
368 
372 static int get_units_score(const struct player *pplayer)
373 {
374  return (pplayer->score.units_built / 10 + pplayer->score.units_killed / 3);
375 }
376 
380 int get_civ_score(const struct player *pplayer)
381 {
382  /* We used to count pplayer->score.happy here too, but this is too easily
383  * manipulated by players at the endturn. */
384  return (total_player_citizens(pplayer) + pplayer->score.techs * 2
385  + pplayer->score.wonders * 5 + get_spaceship_score(pplayer)
386  + get_units_score(pplayer) + pplayer->score.culture / 50);
387 }
388 
392 static int get_spaceship_score(const struct player *pplayer)
393 {
394  if (pplayer->score.spaceship == SSHIP_ARRIVED) {
395  /* How much should a spaceship be worth?
396  * This gives 100 points per 10,000 citizens. */
397  return static_cast<int>(
398  (pplayer->spaceship.population * pplayer->spaceship.success_rate)
399  / 100.0);
400  } else {
401  return 0;
402  }
403 }
404 
408 int total_player_citizens(const struct player *pplayer)
409 {
410  int count = (pplayer->score.happy + pplayer->score.content
411  + pplayer->score.unhappy + pplayer->score.angry);
412 
413  specialist_type_iterate(sp) { count += pplayer->score.specialists[sp]; }
415 
416  return count;
417 }
418 
440 void rank_users(bool interrupt)
441 {
442  FILE *fp;
443  int i, t_winner_score = 0;
444  enum victory_state { VS_NONE, VS_LOSER, VS_WINNER };
445  enum victory_state plr_state[MAX_NUM_PLAYER_SLOTS];
446  struct player *spacerace_winner = nullptr;
447  struct team *t_winner = nullptr;
448 
449  // don't output ranking info if we haven't enabled it via cmdline
450  if (srvarg.ranklog_filename.isNull()) {
451  return;
452  }
453 
454  fp = fc_fopen(srvarg.ranklog_filename.toUtf8().constData(), "w");
455 
456  // don't fail silently, at least print an error
457  if (!fp) {
458  qCritical("couldn't open ranking log file: \"%s\"",
459  qUtf8Printable(srvarg.ranklog_filename));
460  return;
461  }
462 
463  // initialize plr_state
464  for (i = 0; i < MAX_NUM_PLAYER_SLOTS; i++) {
465  plr_state[i] = VS_NONE;
466  }
467 
468  // do we have a spacerace winner?
469  players_iterate(pplayer)
470  {
471  if (pplayer->spaceship.state == SSHIP_ARRIVED) {
472  spacerace_winner = pplayer;
473  break;
474  }
475  }
477 
478  /* make this easy: if we have a spacerace winner, then treat all others
479  * who are still alive as surrendered */
480  if (spacerace_winner) {
481  players_iterate(pplayer)
482  {
483  if (pplayer != spacerace_winner) {
484  player_status_add(pplayer, PSTATUS_SURRENDER);
485  }
486  }
488  }
489 
490  if (!interrupt) {
491  // game ended for a victory condition
492 
493  /* first pass: locate those alive who haven't surrendered, set them to
494  * win; barbarians won't count, and everybody else is a loser for now. */
495  players_iterate(pplayer)
496  {
497  if (is_barbarian(pplayer)) {
498  plr_state[player_index(pplayer)] = VS_NONE;
499  } else if (pplayer->is_alive
500  && !player_status_check(pplayer, PSTATUS_SURRENDER)) {
501  plr_state[player_index(pplayer)] = VS_WINNER;
502  } else {
503  plr_state[player_index(pplayer)] = VS_LOSER;
504  }
505  }
507 
508  // second pass: find the teammates of those winners, they win too.
509  players_iterate(pplayer)
510  {
511  if (plr_state[player_index(pplayer)] == VS_WINNER) {
512  players_iterate(aplayer)
513  {
514  if (aplayer->team == pplayer->team) {
515  plr_state[player_index(aplayer)] = VS_WINNER;
516  }
517  }
519  }
520  }
522  } else {
523  // game ended via endturn
524  // i) determine the winner team
525  teams_iterate(pteam)
526  {
527  int t_score = 0;
528  const struct player_list *members = team_members(pteam);
529  player_list_iterate(members, pplayer)
530  {
531  if (pplayer->is_alive
532  && !player_status_check(pplayer, PSTATUS_SURRENDER)) {
533  t_score += get_civ_score(pplayer);
534  }
535  }
537  if (t_score > t_winner_score) {
538  t_winner = pteam;
539  t_winner_score = t_score;
540  }
541  }
543 
544  /* ii) set all the members of the team as winners, the others as losers
545  */
546  players_iterate(pplayer)
547  {
548  if (pplayer->team == t_winner) {
549  plr_state[player_index(pplayer)] = VS_WINNER;
550  } else {
551  /* if no winner team is found (each one as same score) all them lose
552  */
553  plr_state[player_index(pplayer)] = VS_LOSER;
554  }
555  }
557  }
558 
559  // write out ranking information to file
560  fprintf(fp, "turns: %d\n", game.info.turn);
561  fprintf(fp, "winners: ");
562  players_iterate(pplayer)
563  {
564  if (plr_state[player_index(pplayer)] == VS_WINNER) {
565  fprintf(fp, "%s,%s,%s,%i,, ", pplayer->ranked_username,
566  player_name(pplayer), pplayer->username,
567  get_civ_score(pplayer));
568  }
569  }
571  fprintf(fp, "\nlosers: ");
572  players_iterate(pplayer)
573  {
574  if (plr_state[player_index(pplayer)] == VS_LOSER) {
575  fprintf(fp, "%s,%s,%s,%i,, ", pplayer->ranked_username,
576  player_name(pplayer), pplayer->username,
577  get_civ_score(pplayer));
578  }
579  }
581  fprintf(fp, "\n");
582 
583  fclose(fp);
584 }
#define BV_SET(bv, bit)
Definition: bitvector.h:44
bool BV_ISSET(const BV &bv, int bit)
Definition: bitvector.h:37
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
int city_population(const struct city *pcity)
Returns how many thousand citizen live in this city.
Definition: city.cpp:1137
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
Definition: city.cpp:1095
int get_final_city_output_bonus(const struct city *pcity, Output_type_id otype)
Return the factor (in %) by which the city's output should be multiplied.
Definition: city.cpp:2114
int city_map_radius_sq_get(const struct city *pcity)
Returns the current squared radius of the city.
Definition: city.cpp:130
#define city_list_iterate(citylist, pcity)
Definition: city.h:482
#define city_tile_iterate(_radius_sq, _city_tile, _tile)
Definition: city.h:202
@ CITIZEN_ANGRY
Definition: city.h:243
@ CITIZEN_HAPPY
Definition: city.h:240
@ CITIZEN_CONTENT
Definition: city.h:241
@ CITIZEN_UNHAPPY
Definition: city.h:242
#define city_list_iterate_end
Definition: city.h:484
@ FEELING_FINAL
Definition: city.h:256
#define city_tile_iterate_end
Definition: city.h:209
#define city_built_iterate(_pcity, _p)
Definition: city.h:752
#define city_built_iterate_end
Definition: city.h:759
int player_culture(const struct player *plr)
Return current culture score of the player.
Definition: culture.cpp:40
#define MAX_NUM_PLAYER_SLOTS
Definition: fc_types.h:24
@ O_SHIELD
Definition: fc_types.h:86
@ O_FOOD
Definition: fc_types.h:85
@ O_TRADE
Definition: fc_types.h:87
@ O_SCIENCE
Definition: fc_types.h:90
@ O_GOLD
Definition: fc_types.h:88
@ BORDERS_DISABLED
Definition: fc_types.h:863
struct civ_game game
Definition: game.cpp:47
struct world wld
Definition: game.cpp:48
struct city * city_from_great_wonder(const struct impr_type *pimprove)
Get the world city with this great wonder.
bool is_improvement(const struct impr_type *pimprove)
Is this building a regular improvement?
bool is_wonder(const struct impr_type *pimprove)
Returns whether improvement is some kind of wonder.
bool is_great_wonder(const struct impr_type *pimprove)
Is this building a great wonder?
#define improvement_iterate_end
Definition: improvement.h:199
#define improvement_iterate(_p)
Definition: improvement.h:193
#define MAP_INDEX_SIZE
Definition: map.h:91
static int map_pos_to_index(struct civ_map *nmap, int map_x, int map_y)
Definition: map.h:596
#define whole_map_iterate(_map, _tile)
Definition: map.h:473
#define whole_map_iterate_end
Definition: map.h:480
struct city_list * cities
Definition: packhand.cpp:122
bool player_slot_is_used(const struct player_slot *pslot)
Returns TRUE is this slot is "used" i.e.
Definition: player.cpp:395
int player_count()
Return the number of players.
Definition: player.cpp:739
int player_slot_index(const struct player_slot *pslot)
Returns the index of the player slot.
Definition: player.cpp:373
int player_index(const struct player *pplayer)
Return the player index.
Definition: player.cpp:748
const char * player_name(const struct player *pplayer)
Return the leader name of the player.
Definition: player.cpp:816
bool player_owns_city(const struct player *pplayer, const struct city *pcity)
Return TRUE iff the given player owns the city.
Definition: player.cpp:227
#define players_iterate_end
Definition: player.h:520
#define players_iterate(_pplayer)
Definition: player.h:514
#define player_list_iterate(playerlist, pplayer)
Definition: player.h:541
static bool is_barbarian(const struct player *pplayer)
Definition: player.h:474
#define player_slots_iterate(_pslot)
Definition: player.h:505
#define player_list_iterate_end
Definition: player.h:543
#define player_slots_iterate_end
Definition: player.h:509
void player_status_add(struct player *plr, enum player_status pstatus)
Add a status flag to a player.
Definition: plrhand.cpp:3145
bool player_status_check(struct player *plr, enum player_status pstatus)
Check player status flag.
Definition: plrhand.cpp:3153
struct research * research_get(const struct player *pplayer)
Returns the research structure associated with the player.
Definition: research.cpp:110
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Returns state of the tech for current research.
Definition: research.cpp:609
static void get_player_landarea(struct claim_map *pcmap, struct player *pplayer, int *return_landarea, int *return_settledarea)
Returns the given player's land and settled areas from a claim map.
Definition: score.cpp:224
void calc_civ_score(struct player *pplayer)
Calculates the civilization score for the player.
Definition: score.cpp:255
#define USER_AREA_MULT
Allocates, fills and returns a land area claim map.
Definition: score.cpp:46
int get_civ_score(const struct player *pplayer)
Return the civilization score (a numerical value) for the player.
Definition: score.cpp:380
static void build_landarea_map(struct claim_map *pcmap)
Count landarea, settled area, and claims map for all players.
Definition: score.cpp:159
void rank_users(bool interrupt)
At the end of a game, figure the winners and losers of the game and output to a suitable place.
Definition: score.cpp:440
static int get_units_score(const struct player *pplayer)
Return the score given by the units stats.
Definition: score.cpp:372
static int get_spaceship_score(const struct player *pplayer)
Return the spaceship score.
Definition: score.cpp:392
int total_player_citizens(const struct player *pplayer)
Return the total number of citizens in the player's nation.
Definition: score.cpp:408
#define CLIP(lower, current, upper)
Definition: shared.h:51
@ SSHIP_ARRIVED
Definition: spaceship.h:81
#define specialist_type_iterate_end
Definition: specialist.h:73
#define specialist_type_iterate(sp)
Definition: specialist.h:67
struct server_arguments srvarg
Definition: srv_main.cpp:118
Definition: city.h:291
struct packet_game_info info
Definition: game.h:80
int landarea
Definition: score.cpp:50
struct claim_map::@107 player[MAX_NUM_PLAYER_SLOTS]
int settledarea
Definition: score.cpp:50
int units_killed
Definition: player.h:99
int landarea
Definition: player.h:85
int food
Definition: player.h:96
int mfg
Definition: player.h:95
int all_wonders
Definition: player.h:90
int population
Definition: player.h:87
int improvements
Definition: player.h:89
int goldout
Definition: player.h:84
int pollution
Definition: player.h:92
int wonders
Definition: player.h:81
int settledarea
Definition: player.h:86
int specialists[SP_MAX]
Definition: player.h:80
int angry
Definition: player.h:79
int techout
Definition: player.h:83
int game
Definition: player.h:103
int units
Definition: player.h:91
int units_built
Definition: player.h:98
int content
Definition: player.h:77
int happy
Definition: player.h:76
int spaceship
Definition: player.h:97
int culture
Definition: player.h:102
int unhappy
Definition: player.h:78
int cities
Definition: player.h:88
int bnp
Definition: player.h:94
int literacy
Definition: player.h:93
int techs
Definition: player.h:82
double success_rate
Definition: spaceship.h:112
enum spaceship_state state
Definition: spaceship.h:105
Definition: player.h:231
struct city_list * cities
Definition: player.h:263
struct unit_list * units
Definition: player.h:264
struct player_spaceship spaceship
Definition: player.h:268
struct player_score score
Definition: player.h:265
int future_tech
Definition: research.h:35
QString ranklog_filename
Definition: srv_main.h:46
Definition: team.cpp:35
Definition: tile.h:42
struct civ_map map
Definition: world_object.h:21
FILE * fc_fopen(const char *filename, const char *opentype)
Wrapper function for fopen() with filename conversion to local encoding on Windows.
Definition: support.cpp:255
const struct player_list * team_members(const struct team *pteam)
Returns the member list of the team.
Definition: team.cpp:427
#define teams_iterate_end
Definition: team.h:76
#define teams_iterate(_pteam)
Definition: team.h:71
#define advance_index_iterate_end
Definition: tech.h:226
#define A_FIRST
Definition: tech.h:37
#define advance_index_iterate(_start, _index)
Definition: tech.h:221
#define is_ocean_tile(ptile)
Definition: terrain.h:279
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
Definition: tile.cpp:72
#define tile_index(_pt_)
Definition: tile.h:70
#define tile_worked(_tile)
Definition: tile.h:97
#define tile_owner(_tile)
Definition: tile.h:78
bool is_military_unit(const struct unit *punit)
Military units are capable of enforcing martial law.
Definition: unit.cpp:300
#define unit_owner(_pu)
Definition: unit.h:370
#define unit_list_iterate(unitlist, punit)
Definition: unitlist.h:25
#define unit_list_iterate_end
Definition: unitlist.h:27