Freeciv21
Develop your civilization from humble roots to a global empire
repodlgs_common.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2023 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 "support.h" // fc_snprintf()
18 
19 // common
20 #include "game.h"
21 #include "government.h"
22 
23 // client
24 #include "citydlg_common.h"
25 #include "client_main.h"
26 #include "control.h"
27 #include "repodlgs_common.h"
28 
34  int *num_entries_used, int *total_cost,
35  int *total_income)
36 {
37  *num_entries_used = 0;
38  *total_cost = 0;
39  *total_income = 0;
40  QString str;
41 
42  if (nullptr == client.conn.playing) {
43  return;
44  }
45 
46  improvement_iterate(pimprove)
47  {
48  if (is_improvement(pimprove)) {
49  QStringList redundant_cities;
50  int count = 0, cost = 0;
52  {
53  if (city_has_building(pcity, pimprove)) {
54  count++;
55  cost += city_improvement_upkeep(pcity, pimprove);
56  if (is_improvement_redundant(pcity, pimprove)) {
57  redundant_cities.append(pcity->name);
58  }
59  }
60  }
62 
63  if (count == 0) {
64  continue;
65  }
66 
67  if (redundant_cities.isEmpty()) {
68  str = (_("None"));
69  } else {
70  // Convert the string list we built to a standard string for display.
71  str = redundant_cities.join(", ");
72  }
73 
74  entries[*num_entries_used].type = pimprove;
75  entries[*num_entries_used].count = count;
76  entries[*num_entries_used].redundant = redundant_cities.size();
77  entries[*num_entries_used].total_cost = cost;
78  entries[*num_entries_used].cost = cost / count;
79  entries[*num_entries_used].city_names = str;
80  (*num_entries_used)++;
81 
82  /* Currently there is no building expense under anarchy. It's
83  * not a good idea to hard-code this in the client, but what
84  * else can we do? */
87  *total_cost += cost;
88  }
89  }
90  }
92 
94  {
95  *total_income += pcity->prod[O_GOLD];
96  if (city_production_has_flag(pcity, IF_GOLD)) {
97  *total_income += MAX(0, pcity->surplus[O_SHIELD]);
98  }
99  }
101 }
102 
108  int *num_entries_used, int *total_cost)
109 {
110  int count, cost, partial_cost;
111 
112  *num_entries_used = 0;
113  *total_cost = 0;
114 
115  if (nullptr == client.conn.playing) {
116  return;
117  }
118 
119  unit_type_iterate(unittype)
120  {
121  cost = utype_upkeep_cost(unittype, client.conn.playing, O_GOLD);
122 
123  if (cost == 0) {
124  // Short-circuit all of the following checks.
125  continue;
126  }
127 
128  count = 0;
129  partial_cost = 0;
130 
132  {
133  unit_list_iterate(pcity->units_supported, punit)
134  {
135  if (unit_type_get(punit) == unittype) {
136  count++;
137  partial_cost += punit->upkeep[O_GOLD];
138  }
139  }
141  }
143 
144  if (count == 0) {
145  continue;
146  }
147 
148  (*total_cost) += partial_cost;
149 
150  entries[*num_entries_used].type = unittype;
151  entries[*num_entries_used].count = count;
152  entries[*num_entries_used].cost = cost;
153  entries[*num_entries_used].total_cost = partial_cost;
154  (*num_entries_used)++;
155  }
157 }
158 
167 void sell_all_improvements(const struct impr_type *pimprove,
168  bool redundant_only, char *message,
169  size_t message_sz)
170 {
171  int count = 0, gold = 0;
172 
173  if (!can_client_issue_orders()) {
174  fc_snprintf(message, message_sz, _("You cannot sell improvements."));
175  return;
176  }
177 
179  {
180  if (!pcity->did_sell && city_has_building(pcity, pimprove)
181  && (!redundant_only || is_improvement_redundant(pcity, pimprove))) {
182  count++;
183  gold += impr_sell_gold(pimprove);
184  city_sell_improvement(pcity, improvement_number(pimprove));
185  }
186  }
188 
189  if (count > 0) {
190  // FIXME: plurality of count is ignored!
191  /* TRANS: "Sold 3 Harbor for 90 gold." (Pluralisation is in gold --
192  * second %d -- not in buildings.) */
193  fc_snprintf(
194  message, message_sz,
195  PL_("Sold %d %s for %d gold.", "Sold %d %s for %d gold.", gold),
196  count, improvement_name_translation(pimprove), gold);
197  } else {
198  fc_snprintf(message, message_sz, _("No %s could be sold."),
199  improvement_name_translation(pimprove));
200  }
201 }
202 
210 void disband_all_units(const struct unit_type *punittype,
211  bool in_cities_only, char *message, size_t message_sz)
212 {
213  int count = 0;
214 
215  if (!can_client_issue_orders()) {
216  // TRANS: Obscure observer error.
217  fc_snprintf(message, message_sz, _("You cannot disband units."));
218  return;
219  }
220 
221  if (!utype_can_do_action(punittype, ACTION_DISBAND_UNIT)) {
222  fc_snprintf(message, message_sz, _("%s cannot be disbanded."),
223  utype_name_translation(punittype));
224  return;
225  }
226 
228  {
229  /* Only supported units are disbanded. Units with no homecity have no
230  * cost and are not disbanded. */
231  unit_list_iterate(pcity->units_supported, punit)
232  {
233  struct city *incity = tile_city(unit_tile(punit));
234 
235  if (unit_type_get(punit) == punittype
236  && (!in_cities_only
237  || (incity && city_owner(incity) == client.conn.playing))) {
238  count++;
239  request_unit_disband(punit);
240  }
241  }
243  }
245 
246  if (count > 0) {
247  fc_snprintf(message, message_sz, _("Disbanded %d %s."), count,
248  utype_name_translation(punittype));
249  } else {
250  fc_snprintf(message, message_sz, _("No %s could be disbanded."),
251  utype_name_translation(punittype));
252  }
253 }
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Return TRUE iff the city has this building in it.
Definition: city.cpp:1189
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
int city_improvement_upkeep(const struct city *pcity, const struct impr_type *b)
Return the upkeep (gold) needed each turn to upkeep the given improvement in the given city.
Definition: city.cpp:1202
bool city_production_has_flag(const struct city *pcity, enum impr_flag_id flag)
Return TRUE when the current production has this flag.
Definition: city.cpp:691
#define city_list_iterate(citylist, pcity)
Definition: city.h:482
#define city_list_iterate_end
Definition: city.h:484
int city_sell_improvement(struct city *pcity, Impr_type_id sell_id)
Change the production of a given city.
struct civclient client
bool can_client_issue_orders()
Returns TRUE iff the client can issue orders (such as giving unit commands).
void request_unit_disband(struct unit *punit)
Send request to disband unit to server.
Definition: control.cpp:1853
@ O_SHIELD
Definition: fc_types.h:86
@ O_GOLD
Definition: fc_types.h:88
#define PL_(String1, String2, n)
Definition: fcintl.h:54
#define _(String)
Definition: fcintl.h:50
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
int impr_sell_gold(const struct impr_type *pimprove)
Returns the amount of gold received when this improvement is sold.
bool is_improvement_redundant(const struct city *pcity, const struct impr_type *pimprove)
Returns TRUE if an improvement in a city is redundant, that is, the city wouldn't lose anything by lo...
bool is_improvement(const struct impr_type *pimprove)
Is this building a regular improvement?
Impr_type_id improvement_number(const struct impr_type *pimprove)
Return the improvement index.
const char * improvement_name_translation(const struct impr_type *pimprove)
Return the (translated) name of the given improvement.
#define improvement_iterate_end
Definition: improvement.h:199
#define improvement_iterate(_p)
Definition: improvement.h:193
void get_economy_report_units_data(struct unit_entry *entries, int *num_entries_used, int *total_cost)
Returns an array of units with gold_upkeep.
void get_economy_report_data(struct improvement_entry *entries, int *num_entries_used, int *total_cost, int *total_income)
Fills out the array of struct improvement_entry given by entries.
void sell_all_improvements(const struct impr_type *pimprove, bool redundant_only, char *message, size_t message_sz)
Sell all improvements of the given type in all cities.
void disband_all_units(const struct unit_type *punittype, bool in_cities_only, char *message, size_t message_sz)
Disband all supported units of the given type.
#define MAX(x, y)
Definition: shared.h:48
Definition: city.h:291
struct government * government_during_revolution
Definition: game.h:85
struct connection conn
Definition: client_main.h:89
struct player * playing
Definition: connection.h:142
int cost
QString city_names
struct impr_type * type
int total_cost
int count
int redundant
struct city_list * cities
Definition: player.h:263
int total_cost
struct unit_type * type
int count
int cost
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
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 unit_tile(_pu)
Definition: unit.h:371
#define unit_list_iterate(unitlist, punit)
Definition: unitlist.h:25
#define unit_list_iterate_end
Definition: unitlist.h:27
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
Definition: unittype.cpp:114
int utype_upkeep_cost(const struct unit_type *ut, struct player *pplayer, Output_type_id otype)
Returns the upkeep of a unit of this type under the given government.
Definition: unittype.cpp:123
const char * utype_name_translation(const struct unit_type *punittype)
Return the (translated) name of the unit type.
Definition: unittype.cpp:1256
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Return TRUE iff units of the given type can do the specified generalized (ruleset defined) action ena...
Definition: unittype.cpp:386
#define unit_type_iterate(_p)
Definition: unittype.h:785
#define unit_type_iterate_end
Definition: unittype.h:791