Freeciv21
Develop your civilization from humble roots to a global empire
government.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 // utility
15 #include "fcintl.h"
16 #include "log.h"
17 #include "shared.h"
18 #include "support.h"
19 
20 // common
21 #include "game.h"
22 #include "nation.h"
23 #include "player.h"
24 #include "tech.h"
25 
26 #include "government.h"
27 
28 std::vector<government> governments;
34 {
35  for (auto &gov : governments) {
36  if (0 == strcmp(government_name_translation(&gov), name)) {
37  return &gov;
38  }
39  }
40 
41  return nullptr;
42 }
43 
49 {
50  const char *qname = Qn_(name);
51 
52  for (auto &gov : governments) {
53  if (0 == fc_strcasecmp(government_rule_name(&gov), qname)) {
54  return &gov;
55  }
56  };
57 
58  return nullptr;
59 }
60 
65 {
66  return game.control.government_count;
67 }
68 
76 {
77  fc_assert_ret_val(nullptr != pgovern, 0);
78  return pgovern - &governments[0];
79 }
80 
85 {
86  fc_assert_ret_val(nullptr != pgovern, 0);
87  return pgovern->item_number;
88 }
89 
97 {
98  if (gov < 0 || gov >= game.control.government_count) {
99  return nullptr;
100  }
101  return &governments[gov];
102 }
103 
107 struct government *government_of_player(const struct player *pplayer)
108 {
109  fc_assert_ret_val(nullptr != pplayer, nullptr);
110  return pplayer->government;
111 }
112 
116 struct government *government_of_city(const struct city *pcity)
117 {
118  fc_assert_ret_val(nullptr != pcity, nullptr);
119  return government_of_player(city_owner(pcity));
120 }
121 
126 const char *government_rule_name(const struct government *pgovern)
127 {
128  fc_assert_ret_val(nullptr != pgovern, nullptr);
129  return rule_name_get(&pgovern->name);
130 }
131 
136 const char *government_name_translation(const struct government *pgovern)
137 {
138  fc_assert_ret_val(nullptr != pgovern, nullptr);
139 
140  return name_translation_get(&pgovern->name);
141 }
142 
147 const char *government_name_for_player(const struct player *pplayer)
148 {
150 }
151 
159 bool can_change_to_government(struct player *pplayer,
160  const struct government *gov)
161 {
162  fc_assert_ret_val(nullptr != gov, false);
163 
164  if (!pplayer) {
165  return false;
166  }
167 
168  if (get_player_bonus(pplayer, EFT_ANY_GOVERNMENT) > 0) {
169  // Note, this may allow govs that are on someone else's "tech tree".
170  return true;
171  }
172 
173  return are_reqs_active(pplayer, nullptr, nullptr, nullptr, nullptr,
174  nullptr, nullptr, nullptr, nullptr, nullptr,
175  &gov->reqs, RPT_CERTAIN);
176 }
177 
181 struct ruler_title {
182  const struct nation_type *pnation;
183  struct name_translation male;
184  struct name_translation female;
185 };
186 
190 static struct ruler_title *ruler_title_new(const struct nation_type *pnation,
191  const char *domain,
192  const char *ruler_male_title,
193  const char *ruler_female_title)
194 {
195  auto *pruler_title = new ruler_title;
196 
197  pruler_title->pnation = pnation;
198  name_set(&pruler_title->male, domain, ruler_male_title);
199  name_set(&pruler_title->female, domain, ruler_female_title);
200 
201  return pruler_title;
202 }
203 
207 static void ruler_title_destroy(struct ruler_title *pruler_title)
208 {
209  delete pruler_title;
210 }
211 
215 static bool ruler_title_check(const struct ruler_title *pruler_title)
216 {
217  bool ret = true;
218 
219  if (!formats_match(rule_name_get(&pruler_title->male), "%s")) {
220  if (nullptr != pruler_title->pnation) {
221  qCritical("\"%s\" male ruler title for nation \"%s\" (nb %d) "
222  "is not a format. It should match \"%%s\"",
223  rule_name_get(&pruler_title->male),
224  nation_rule_name(pruler_title->pnation),
225  nation_index(pruler_title->pnation));
226  } else {
227  qCritical("\"%s\" male ruler title is not a format. "
228  "It should match \"%%s\"",
229  rule_name_get(&pruler_title->male));
230  }
231  ret = false;
232  }
233 
234  if (!formats_match(rule_name_get(&pruler_title->female), "%s")) {
235  if (nullptr != pruler_title->pnation) {
236  qCritical("\"%s\" female ruler title for nation \"%s\" (nb %d) "
237  "is not a format. It should match \"%%s\"",
238  rule_name_get(&pruler_title->female),
239  nation_rule_name(pruler_title->pnation),
240  nation_index(pruler_title->pnation));
241  } else {
242  qCritical("\"%s\" female ruler title is not a format. "
243  "It should match \"%%s\"",
244  rule_name_get(&pruler_title->female));
245  }
246  ret = false;
247  }
248 
249  if (!formats_match(name_translation_get(&pruler_title->male), "%s")) {
250  if (nullptr != pruler_title->pnation) {
251  qCritical("Translation of \"%s\" male ruler title for nation \"%s\" "
252  "(nb %d) is not a format (\"%s\"). It should match \"%%s\"",
253  rule_name_get(&pruler_title->male),
254  nation_rule_name(pruler_title->pnation),
255  nation_index(pruler_title->pnation),
256  name_translation_get(&pruler_title->male));
257  } else {
258  qCritical("Translation of \"%s\" male ruler title is not a format "
259  "(\"%s\"). It should match \"%%s\"",
260  rule_name_get(&pruler_title->male),
261  name_translation_get(&pruler_title->male));
262  }
263  ret = false;
264  }
265 
266  if (!formats_match(name_translation_get(&pruler_title->female), "%s")) {
267  if (nullptr != pruler_title->pnation) {
268  qCritical("Translation of \"%s\" female ruler title for nation \"%s\" "
269  "(nb %d) is not a format (\"%s\"). It should match \"%%s\"",
270  rule_name_get(&pruler_title->female),
271  nation_rule_name(pruler_title->pnation),
272  nation_index(pruler_title->pnation),
273  name_translation_get(&pruler_title->female));
274  } else {
275  qCritical("Translation of \"%s\" female ruler title is not a format "
276  "(\"%s\"). It should match \"%%s\"",
277  rule_name_get(&pruler_title->female),
278  name_translation_get(&pruler_title->female));
279  }
280  ret = false;
281  }
282 
283  return ret;
284 }
285 
289 QHash<const struct nation_type *, struct ruler_title *> *
290 government_ruler_titles(const struct government *pgovern)
291 {
292  fc_assert_ret_val(nullptr != pgovern, nullptr);
293  return pgovern->ruler_titles;
294 }
295 
301  struct government *pgovern, const struct nation_type *pnation,
302  const char *ruler_male_title, const char *ruler_female_title)
303 {
304  const char *domain = nullptr;
305  struct ruler_title *pruler_title;
306 
307  if (pnation != nullptr) {
308  domain = pnation->translation_domain;
309  }
310  pruler_title =
311  ruler_title_new(pnation, domain, ruler_male_title, ruler_female_title);
312 
313  if (!ruler_title_check(pruler_title)) {
314  ruler_title_destroy(pruler_title);
315  return nullptr;
316  }
317 
318  if (pgovern->ruler_titles->contains(pnation)) {
319  if (nullptr != pnation) {
320  qCritical("Ruler title for government \"%s\" (nb %d) and "
321  "nation \"%s\" (nb %d) was set twice.",
322  government_rule_name(pgovern), government_number(pgovern),
324  } else {
325  qCritical("Default ruler title for government \"%s\" (nb %d) "
326  "was set twice.",
327  government_rule_name(pgovern), government_number(pgovern));
328  }
329  } else {
330  pgovern->ruler_titles->insert(pnation, pruler_title);
331  }
332 
333  return pruler_title;
334 }
335 
339 const struct nation_type *
340 ruler_title_nation(const struct ruler_title *pruler_title)
341 {
342  return pruler_title->pnation;
343 }
344 
348 const char *
350 {
351  return untranslated_name(&pruler_title->male);
352 }
353 
357 const char *
359 {
360  return untranslated_name(&pruler_title->female);
361 }
362 
366 const char *ruler_title_for_player(const struct player *pplayer, char *buf,
367  size_t buf_len)
368 {
369  const struct government *pgovern = government_of_player(pplayer);
370  const struct nation_type *pnation = nation_of_player(pplayer);
371  struct ruler_title *pruler_title;
372 
373  fc_assert_ret_val(nullptr != buf, nullptr);
374  fc_assert_ret_val(0 < buf_len, nullptr);
375 
376  // Try specific nation rule title.
377  if (!pgovern->ruler_titles->contains(pnation)
378  // Try default rule title.
379  && !pgovern->ruler_titles->contains(nullptr)) {
380  qCritical("Missing title for government \"%s\" (nb %d) "
381  "nation \"%s\" (nb %d).",
382  government_rule_name(pgovern), government_number(pgovern),
384  if (pplayer->is_male) {
385  fc_snprintf(buf, buf_len, _("Mr. %s"), player_name(pplayer));
386  } else {
387  fc_snprintf(buf, buf_len, _("Ms. %s"), player_name(pplayer));
388  }
389  } else {
390  pruler_title = pgovern->ruler_titles->value(pnation);
391  if (!pruler_title) {
392  pruler_title = pgovern->ruler_titles->value(nullptr);
393  }
394  fc_snprintf(buf, buf_len,
396  ? &pruler_title->male
397  : &pruler_title->female),
398  player_name(pplayer));
399  }
400 
401  return buf;
402 }
403 
408 {
409  item_number = 0;
410  ruler_titles = new QHash<const struct nation_type *, struct ruler_title *>;
411  helptext = nullptr;
412  requirement_vector_init(&reqs);
413  changed_to_times = 0;
414  ruledit_disabled = false;
415  ai.better = nullptr;
416 }
417 
422 {
423  for (auto *a : ruler_titles->values()) {
424  delete a;
425  }
426  delete ruler_titles;
427  delete helptext;
428  ruler_titles = nullptr;
429  helptext = nullptr;
430 
431  requirement_vector_free(&reqs);
432 }
433 
437 void governments_alloc(int num)
438 {
439  fc_assert(0 == governments.size());
440  governments.resize(num);
441  game.control.government_count = num;
442 
443  int i = 0;
444  for (auto &gov : governments) {
445  gov.item_number = i++;
446  }
447 }
448 
453 {
454  governments.clear();
455  game.control.government_count = 0;
456 }
457 
463 {
464  if (game.info.revolentype == REVOLEN_QUICKENING
465  || game.info.revolentype == REVOLEN_RANDQUICK) {
466  /* We need to know the target government at the onset of the revolution
467  * in order to know how long anarchy will last. */
468  return false;
469  }
470  return true;
471 }
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Returns the effect bonus for a player.
Definition: effects.cpp:673
@ RPT_CERTAIN
Definition: fc_types.h:568
@ REVOLEN_RANDQUICK
Definition: fc_types.h:1091
@ REVOLEN_QUICKENING
Definition: fc_types.h:1090
int Government_type_id
Definition: fc_types.h:298
#define _(String)
Definition: fcintl.h:50
#define Qn_(String)
Definition: fcintl.h:66
struct civ_game game
Definition: game.cpp:47
struct government * government_of_player(const struct player *pplayer)
Return the government of a player.
Definition: government.cpp:107
struct government * government_by_number(const Government_type_id gov)
Return the government with the given index.
Definition: government.cpp:96
const char * government_name_for_player(const struct player *pplayer)
Return the (translated) name of the given government of a player.
Definition: government.cpp:147
void governments_free()
De-allocate the currently allocated governments.
Definition: government.cpp:452
const struct nation_type * ruler_title_nation(const struct ruler_title *pruler_title)
Return the nation of the rule title.
Definition: government.cpp:340
bool untargeted_revolution_allowed()
Is it possible to start a revolution without specifying the target government in the current game?
Definition: government.cpp:462
Government_type_id government_count()
Return the number of governments.
Definition: government.cpp:64
const char * government_rule_name(const struct government *pgovern)
Return the (untranslated) rule name of the government.
Definition: government.cpp:126
struct government * government_of_city(const struct city *pcity)
Return the government of the player who owns the city.
Definition: government.cpp:116
const char * ruler_title_for_player(const struct player *pplayer, char *buf, size_t buf_len)
Return the ruler title of the player (translated).
Definition: government.cpp:366
QHash< const struct nation_type *, struct ruler_title * > * government_ruler_titles(const struct government *pgovern)
Returns all ruler titles for a government type.
Definition: government.cpp:290
static void ruler_title_destroy(struct ruler_title *pruler_title)
Free a ruler title.
Definition: government.cpp:207
const char * ruler_title_female_untranslated_name(const struct ruler_title *pruler_title)
Return the female rule title name.
Definition: government.cpp:358
const char * ruler_title_male_untranslated_name(const struct ruler_title *pruler_title)
Return the male rule title name.
Definition: government.cpp:349
struct government * government_by_rule_name(const char *name)
Returns the government that has the given (untranslated) rule name.
Definition: government.cpp:48
void governments_alloc(int num)
Allocate the governments.
Definition: government.cpp:437
struct ruler_title * government_ruler_title_new(struct government *pgovern, const struct nation_type *pnation, const char *ruler_male_title, const char *ruler_female_title)
Add a new ruler title for the nation.
Definition: government.cpp:300
std::vector< government > governments
Definition: government.cpp:28
bool can_change_to_government(struct player *pplayer, const struct government *gov)
Can change to government if appropriate tech exists, and one of:
Definition: government.cpp:159
static struct ruler_title * ruler_title_new(const struct nation_type *pnation, const char *domain, const char *ruler_male_title, const char *ruler_female_title)
Create a new ruler title.
Definition: government.cpp:190
Government_type_id government_number(const struct government *pgovern)
Return the government index.
Definition: government.cpp:84
Government_type_id government_index(const struct government *pgovern)
Return the government index.
Definition: government.cpp:75
static bool ruler_title_check(const struct ruler_title *pruler_title)
Return TRUE if the ruler title is valid.
Definition: government.cpp:215
const char * government_name_translation(const struct government *pgovern)
Return the (translated) name of the given government.
Definition: government.cpp:136
struct government * government_by_translated_name(const char *name)
Returns the government that has the given (translated) name.
Definition: government.cpp:33
const char * name
Definition: inputfile.cpp:118
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
static void name_set(struct name_translation *ptrans, const char *domain, const char *vernacular_name)
static const char * untranslated_name(const struct name_translation *ptrans)
static const char * rule_name_get(const struct name_translation *ptrans)
static const char * name_translation_get(const struct name_translation *ptrans)
const char * nation_rule_name(const struct nation_type *pnation)
Return the (untranslated) rule name of the nation (adjective form).
Definition: nation.cpp:115
Nation_type_id nation_index(const struct nation_type *pnation)
Return the nation index.
Definition: nation.cpp:464
struct nation_type * nation_of_player(const struct player *pplayer)
Return the nation of a player.
Definition: nation.cpp:419
const char * player_name(const struct player *pplayer)
Return the leader name of the player.
Definition: player.cpp:816
bool are_reqs_active(const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct action *target_action, const struct requirement_vector *reqs, const enum req_problem_type prob_type, const enum vision_layer vision_layer, const enum national_intelligence nintel)
Checks the requirement(s) to see if they are active on the given target.
bool formats_match(const char *format1, const char *format2)
Returns TRUE iff both formats are compatible (if 'format1' can be used instead 'format2' and reciproc...
Definition: shared.cpp:1621
Definition: city.h:291
struct packet_ruleset_control control
Definition: game.h:74
struct packet_game_info info
Definition: game.h:80
struct requirement_vector reqs
Definition: government.h:41
bool ruledit_disabled
Definition: government.h:38
Government_type_id item_number
Definition: government.h:36
QHash< const struct nation_type *, struct ruler_title * > * ruler_titles
Definition: government.h:42
int changed_to_times
Definition: government.h:43
struct government::@38 ai
QVector< QString > * helptext
Definition: government.h:44
struct name_translation name
Definition: government.h:37
~government()
De-allocate resources associated with the given government.
Definition: government.cpp:421
government()
Allocate resources associated with the given government.
Definition: government.cpp:407
char * translation_domain
Definition: nation.h:79
Definition: player.h:231
bool is_male
Definition: player.h:239
struct government * government
Definition: player.h:240
Ruler titles.
Definition: government.cpp:181
struct name_translation male
Definition: government.cpp:183
struct name_translation female
Definition: government.cpp:184
const struct nation_type * pnation
Definition: government.cpp:182
int fc_snprintf(char *str, size_t n, const char *format,...)
See also fc_utf8_snprintf_trunc(), fc_utf8_snprintf_rep().
Definition: support.cpp:537
int fc_strcasecmp(const char *str0, const char *str1)
Compare strings like strcmp(), but ignoring case.
Definition: support.cpp:89