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)
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 ***********************************************************************/
15 #include <fc_config.h>
21 #include "mem.h" /* free() */
22 #include "support.h" /* fc_snprintf() */
26 #include "government.h"
30 #include "repodlgs_g.h"
33 #include "client_main.h"
34 #include "connectdlg_common.h" /* is_server_running() */
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
,
50 *num_entries_used
= 0;
54 if (NULL
== client
.conn
.playing
) {
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
)) {
64 cost
+= city_improvement_upkeep(pcity
, pimprove
);
65 if (is_improvement_redundant(pcity
, pimprove
)) {
70 city_list_iterate_end
;
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
86 if (government_of_player(client
.conn
.playing
) !=
87 game
.government_during_revolution
) {
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;
113 if (NULL
== client
.conn
.playing
) {
117 unit_type_iterate(unittype
) {
118 cost
= utype_upkeep_cost(unittype
, client
.conn
.playing
, O_GOLD
);
121 /* Short-circuit all of the following checks. */
128 city_list_iterate(client
.conn
.playing
->cities
, pcity
) {
129 unit_list_iterate(pcity
->units_supported
, punit
) {
130 if (unit_type_get(punit
) == unittype
) {
132 partial_cost
+= punit
->upkeep
[O_GOLD
];
135 } unit_list_iterate_end
;
136 } city_list_iterate_end
;
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
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."));
170 city_list_iterate(client
.conn
.playing
->cities
, pcity
) {
171 if (!pcity
->did_sell
&& city_has_building(pcity
, pimprove
)
173 || is_improvement_redundant(pcity
, pimprove
))) {
175 gold
+= impr_sell_gold(pimprove
);
176 city_sell_improvement(pcity
, improvement_number(pimprove
));
178 } city_list_iterate_end
;
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
);
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
199 ****************************************************************************/
200 void disband_all_units(struct unit_type
*punittype
, bool in_cities_only
,
201 char *message
, size_t message_sz
)
205 if (!can_client_issue_orders()) {
206 /* TRANS: Obscure observer error. */
207 fc_snprintf(message
, message_sz
, _("You cannot disband units."));
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
));
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
225 || (incity
&& city_owner(incity
) == client
.conn
.playing
))) {
227 request_unit_disband(punit
);
229 } unit_list_iterate_end
;
230 } city_list_iterate_end
;
233 fc_snprintf(message
, message_sz
, _("Disbanded %d %s."),
234 count
, utype_name_translation(punittype
));
236 fc_snprintf(message
, message_sz
, _("No %s could be disbanded."),
237 utype_name_translation(punittype
));