Freeciv21
Develop your civilization from humble roots to a global empire
citizens.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
5  (" )(_..._) GNU General Public License as published by the Free
6  ^^ // \\ Software Foundation, either version 3 of the License,
7  or (at your option) any later version. You should have
8 received a copy of the GNU General Public License along with Freeciv21.
9  If not, see https://www.gnu.org/licenses/.
10  */
11 
12 // utility
13 #include "log.h"
14 #include "rand.h"
15 
16 // common
17 #include "city.h"
18 #include "game.h"
19 #include "player.h"
20 
21 #include "citizens.h"
22 
26 void citizens_init(struct city *pcity)
27 {
28  fc_assert_ret(pcity);
29 
30  if (!game.info.citizen_nationality) {
31  return;
32  }
33 
34  /* For the nationality of the citizens the informations for all player
35  * slots are allocated as once. Considering a size of citizens (= char)
36  * this results in an allocation of 2 * 128 * 1 bytes for the citizens
37  * per nation as well as the timer for a nationality change. */
38  if (pcity->nationality == nullptr) {
39  /* Allocate the memory*/
41  } else {
42  // Reset the nationality information.
43  memset(pcity->nationality, 0,
44  MAX_NUM_PLAYER_SLOTS * sizeof(*pcity->nationality));
45  }
46 }
47 
51 void citizens_free(struct city *pcity)
52 {
53  fc_assert_ret(pcity);
54 
55  delete[] pcity->nationality;
56  pcity->nationality = nullptr;
57 }
58 
65 citizens citizens_nation_get(const struct city *pcity,
66  const struct player_slot *pslot)
67 {
68  if (!game.info.citizen_nationality) {
69  return 0;
70  }
71 
72  fc_assert_ret_val(pslot != nullptr, 0);
73  fc_assert_ret_val(pcity != nullptr, 0);
74  fc_assert_ret_val(pcity->nationality != nullptr, 0);
75 
76  return *(pcity->nationality + player_slot_index(pslot));
77 }
78 
83 {
84  return citizens_count(pcity)
85  - citizens_nation_get(pcity, city_owner(pcity)->slot);
86 }
87 
96 void citizens_nation_add(struct city *pcity, const struct player_slot *pslot,
97  int add)
98 {
99  citizens nationality = citizens_nation_get(pcity, pslot);
100 
101  if (!game.info.citizen_nationality) {
102  return;
103  }
104 
105  fc_assert_ret(pslot != nullptr);
106  fc_assert_ret(pcity != nullptr);
107  fc_assert_ret(pcity->nationality != nullptr);
108 
109  fc_assert_ret(MAX_CITY_SIZE - nationality > add);
110  fc_assert_ret(nationality >= -add);
111 
112  citizens_nation_set(pcity, pslot, nationality + add);
113 }
114 
123 void citizens_nation_move(struct city *pcity,
124  const struct player_slot *pslot_from,
125  const struct player_slot *pslot_to, int move)
126 {
127  citizens_nation_add(pcity, pslot_from, -move);
128  citizens_nation_add(pcity, pslot_to, move);
129 }
130 
137 void citizens_nation_set(struct city *pcity, const struct player_slot *pslot,
138  citizens count)
139 {
140  if (!game.info.citizen_nationality) {
141  return;
142  }
143 
144  fc_assert_ret(pslot != nullptr);
145  fc_assert_ret(pcity != nullptr);
146  fc_assert_ret(pcity->nationality != nullptr);
147 
148  *(pcity->nationality + player_slot_index(pslot)) = count;
149 }
150 
154 citizens citizens_count(const struct city *pcity)
155 {
156  // Use int here to check for an possible overflow at the end.
157  int count = 0;
158 
159  if (!game.info.citizen_nationality) {
160  return city_size_get(pcity);
161  }
162 
163  citizens_iterate(pcity, pslot, nationality)
164  {
165  /* If the citizens of a nation is greater than 0 there should be a player
166  * for this nation. This test should only be done on the server as the
167  * client does not has the knowledge about all players all the time. */
169  || player_slot_get_player(pslot) != nullptr,
170  city_size_get(pcity));
171 
172  count += nationality;
173  }
175 
176  fc_assert_ret_val(count >= 0 && count <= MAX_CITY_SIZE,
177  city_size_get(pcity));
178 
179  return static_cast<citizens>(count);
180 }
181 
185 struct player_slot *citizens_random(const struct city *pcity)
186 {
187  int total = citizens_count(pcity);
188  int chocen = fc_rand(total);
189 
190  citizens_iterate(pcity, pslot, nationality)
191  {
192  chocen -= nationality;
193  if (chocen <= 0) {
194  return pslot;
195  }
196  }
198 
199  fc_assert(false);
200 
201  return nullptr;
202 }
void citizens_free(struct city *pcity)
Free citizens data.
Definition: citizens.cpp:51
void citizens_nation_move(struct city *pcity, const struct player_slot *pslot_from, const struct player_slot *pslot_to, int move)
Convert a (positive or negative) value to the citizens from one nation to another.
Definition: citizens.cpp:123
void citizens_nation_add(struct city *pcity, const struct player_slot *pslot, int add)
Add a (positive or negative) value to the citizens of the given nationality.
Definition: citizens.cpp:96
citizens citizens_nation_get(const struct city *pcity, const struct player_slot *pslot)
Get the number of citizens with the given nationality.
Definition: citizens.cpp:65
void citizens_nation_set(struct city *pcity, const struct player_slot *pslot, citizens count)
Set the number of citizens with the given nationality.
Definition: citizens.cpp:137
citizens citizens_nation_foreign(const struct city *pcity)
Get the number of foreign citizens.
Definition: citizens.cpp:82
struct player_slot * citizens_random(const struct city *pcity)
Return random citizen from city.
Definition: citizens.cpp:185
citizens citizens_count(const struct city *pcity)
Return the number of citizens in a city.
Definition: citizens.cpp:154
void citizens_init(struct city *pcity)
Initialise citizens data.
Definition: citizens.cpp:26
#define citizens_iterate_end
Definition: citizens.h:44
#define citizens_iterate(_pcity, _pslot, _nationality)
Definition: citizens.h:37
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
citizens city_size_get(const struct city *pcity)
Get the city size.
Definition: city.cpp:1101
#define MAX_CITY_SIZE
Definition: city.h:79
unsigned char citizens
Definition: fc_types.h:305
#define MAX_NUM_PLAYER_SLOTS
Definition: fc_types.h:24
struct civ_game game
Definition: game.cpp:47
bool is_server()
Is program type server?
Definition: game.cpp:57
#define fc_assert_ret(condition)
Definition: log.h:112
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
int player_slot_index(const struct player_slot *pslot)
Returns the index of the player slot.
Definition: player.cpp:373
struct player * player_slot_get_player(const struct player_slot *pslot)
Returns the team corresponding to the slot.
Definition: player.cpp:384
#define fc_rand(_size)
Definition: rand.h:16
Definition: city.h:291
citizens * nationality
Definition: city.h:310
struct packet_game_info info
Definition: game.h:80