Stop sharing requirement_unit_state_ereq().
[freeciv.git] / client / repodlgs_common.c
blob196f0b9fd2826ea7e2e61b579294fba0d10ff745
1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 /* utility */
19 #include "fcintl.h"
20 #include "log.h"
21 #include "mem.h" /* free() */
22 #include "support.h" /* fc_snprintf() */
24 /* common */
25 #include "game.h"
26 #include "government.h"
27 #include "unitlist.h"
29 /* client/include */
30 #include "repodlgs_g.h"
32 /* client */
33 #include "client_main.h"
34 #include "connectdlg_common.h" /* is_server_running() */
35 #include "control.h"
36 #include "options.h"
37 #include "packhand_gen.h"
39 #include "repodlgs_common.h"
42 /****************************************************************
43 Fills out the array of struct improvement_entry given by
44 entries. The array must be able to hold at least B_LAST entries.
45 *****************************************************************/
46 void get_economy_report_data(struct improvement_entry *entries,
47 int *num_entries_used, int *total_cost,
48 int *total_income)
50 *num_entries_used = 0;
51 *total_cost = 0;
52 *total_income = 0;
54 if (NULL == client.conn.playing) {
55 return;
58 improvement_iterate(pimprove) {
59 if (is_improvement(pimprove)) {
60 int count = 0, redundant = 0, cost = 0;
61 city_list_iterate(client.conn.playing->cities, pcity) {
62 if (city_has_building(pcity, pimprove)) {
63 count++;
64 cost += city_improvement_upkeep(pcity, pimprove);
65 if (is_improvement_redundant(pcity, pimprove)) {
66 redundant++;
70 city_list_iterate_end;
72 if (count == 0) {
73 continue;
76 entries[*num_entries_used].type = pimprove;
77 entries[*num_entries_used].count = count;
78 entries[*num_entries_used].redundant = redundant;
79 entries[*num_entries_used].total_cost = cost;
80 entries[*num_entries_used].cost = cost / count;
81 (*num_entries_used)++;
83 /* Currently there is no building expense under anarchy. It's
84 * not a good idea to hard-code this in the client, but what
85 * else can we do? */
86 if (government_of_player(client.conn.playing) !=
87 game.government_during_revolution) {
88 *total_cost += cost;
91 } improvement_iterate_end;
93 city_list_iterate(client.conn.playing->cities, pcity) {
94 *total_income += pcity->prod[O_GOLD];
95 if (city_production_has_flag(pcity, IF_GOLD)) {
96 *total_income += MAX(0, pcity->surplus[O_SHIELD]);
98 } city_list_iterate_end;
101 /******************************************************************
102 Returns an array of units with gold_upkeep. Number of units in
103 the array is added to num_entries_used.
104 ******************************************************************/
105 void get_economy_report_units_data(struct unit_entry *entries,
106 int *num_entries_used, int *total_cost)
108 int count, cost, partial_cost;
110 *num_entries_used = 0;
111 *total_cost = 0;
113 if (NULL == client.conn.playing) {
114 return;
117 unit_type_iterate(unittype) {
118 cost = utype_upkeep_cost(unittype, client.conn.playing, O_GOLD);
120 if (cost == 0) {
121 /* Short-circuit all of the following checks. */
122 continue;
125 count = 0;
126 partial_cost = 0;
128 city_list_iterate(client.conn.playing->cities, pcity) {
129 unit_list_iterate(pcity->units_supported, punit) {
130 if (unit_type_get(punit) == unittype) {
131 count++;
132 partial_cost += punit->upkeep[O_GOLD];
135 } unit_list_iterate_end;
136 } city_list_iterate_end;
138 if (count == 0) {
139 continue;
142 (*total_cost) += partial_cost;
144 entries[*num_entries_used].type = unittype;
145 entries[*num_entries_used].count = count;
146 entries[*num_entries_used].cost = cost;
147 entries[*num_entries_used].total_cost = partial_cost;
148 (*num_entries_used)++;
150 } unit_type_iterate_end;
153 /****************************************************************************
154 Sell all improvements of the given type in all cities. If "redundant_only"
155 is specified then only those improvements that are replaced will be sold.
157 The "message" string will be filled with a GUI-friendly message about
158 what was sold.
159 ****************************************************************************/
160 void sell_all_improvements(struct impr_type *pimprove, bool redundant_only,
161 char *message, size_t message_sz)
163 int count = 0, gold = 0;
165 if (!can_client_issue_orders()) {
166 fc_snprintf(message, message_sz, _("You cannot sell improvements."));
167 return;
170 city_list_iterate(client.conn.playing->cities, pcity) {
171 if (!pcity->did_sell && city_has_building(pcity, pimprove)
172 && (!redundant_only
173 || is_improvement_redundant(pcity, pimprove))) {
174 count++;
175 gold += impr_sell_gold(pimprove);
176 city_sell_improvement(pcity, improvement_number(pimprove));
178 } city_list_iterate_end;
180 if (count > 0) {
181 /* FIXME: plurality of count is ignored! */
182 /* TRANS: "Sold 3 Harbor for 90 gold." (Pluralisation is in gold --
183 * second %d -- not in buildings.) */
184 fc_snprintf(message, message_sz, PL_("Sold %d %s for %d gold.",
185 "Sold %d %s for %d gold.", gold),
186 count, improvement_name_translation(pimprove), gold);
187 } else {
188 fc_snprintf(message, message_sz, _("No %s could be sold."),
189 improvement_name_translation(pimprove));
193 /****************************************************************************
194 Disband all supported units of the given type. If in_cities_only is
195 specified then only units inside our cities will be disbanded.
197 The "message" string will be filled with a GUI-friendly message about
198 what was sold.
199 ****************************************************************************/
200 void disband_all_units(struct unit_type *punittype, bool in_cities_only,
201 char *message, size_t message_sz)
203 int count = 0;
205 if (!can_client_issue_orders()) {
206 /* TRANS: Obscure observer error. */
207 fc_snprintf(message, message_sz, _("You cannot disband units."));
208 return;
211 if (!utype_can_do_action(punittype, ACTION_DISBAND_UNIT)) {
212 fc_snprintf(message, message_sz, _("%s cannot be disbanded."),
213 utype_name_translation(punittype));
214 return;
217 city_list_iterate(client.conn.playing->cities, pcity) {
218 /* Only supported units are disbanded. Units with no homecity have no
219 * cost and are not disbanded. */
220 unit_list_iterate(pcity->units_supported, punit) {
221 struct city *incity = tile_city(unit_tile(punit));
223 if (unit_type_get(punit) == punittype
224 && (!in_cities_only
225 || (incity && city_owner(incity) == client.conn.playing))) {
226 count++;
227 request_unit_disband(punit);
229 } unit_list_iterate_end;
230 } city_list_iterate_end;
232 if (count > 0) {
233 fc_snprintf(message, message_sz, _("Disbanded %d %s."),
234 count, utype_name_translation(punittype));
235 } else {
236 fc_snprintf(message, message_sz, _("No %s could be disbanded."),
237 utype_name_translation(punittype));