Freeciv-3.3
Loading...
Searching...
No Matches
advbuilding.c
Go to the documentation of this file.
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.
7
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***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18/* utility */
19#include "rand.h"
20
21/* common */
22#include "ai.h"
23#include "city.h"
24#include "effects.h"
25#include "game.h"
26#include "movement.h"
27#include "player.h"
28#include "specialist.h"
29
30/* common/aicore */
31#include "path_finding.h"
32#include "pf_tools.h"
33
34/* server */
35#include "citytools.h"
36#include "plrhand.h"
37#include "srv_log.h"
38
39/* server/advisors */
40#include "advdata.h"
41#include "advtools.h"
42#include "infracache.h" /* adv_city */
43
44/* ai */
45#include "handicaps.h"
46
47#include "advbuilding.h"
48
49/**********************************************************************/
58static void calculate_city_clusters(struct player *pplayer)
59{
60 struct unit_type *punittype;
61 struct unit *ghost;
62 int range;
63 const struct civ_map *nmap = &(wld.map);
64
65 city_list_iterate(pplayer->cities, pcity) {
66 pcity->server.adv->downtown = 0;
68
70 return; /* Ruleset has no help wonder unit */
71 }
72
75
76 if (punittype == NULL) {
77 /* Simulate future unit */
79 }
80
82 "Non existence of wonder helper unit not caught");
83
86
87 city_list_iterate(pplayer->cities, pcity) {
88 struct pf_parameter parameter;
89 struct pf_map *pfm;
91
94 parameter.omniscience = !has_handicap(pplayer, H_MAP);
95 pfm = pf_map_new(&parameter);
96
97 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
98 struct city *acity = tile_city(ptile);
99
100 if (move_cost > range) {
101 break;
102 }
103 if (acity == NULL) {
104 continue;
105 }
106 if (city_owner(acity) == pplayer) {
107 city_data->downtown++;
108 }
110
113
115}
116
117/**********************************************************************/
120static void ba_human_wants(struct player *pplayer, struct city *wonder_city)
121{
122 /* Clear old building wants.
123 * Do this separately from the iteration over improvement types
124 * because each iteration could actually update more than one improvement,
125 * if improvements have improvements as requirements.
126 */
127 city_list_iterate(pplayer->cities, pcity) {
128 /* For a human player, any building is worth building until discarded */
129 improvement_iterate(pimprove) {
130 pcity->server.adv->building_want[improvement_index(pimprove)] = 1;
133
134 improvement_iterate(pimprove) {
135 if (can_player_build_improvement_later(pplayer, pimprove)) {
136 city_list_iterate(pplayer->cities, pcity) {
137 if (pcity != wonder_city && is_wonder(pimprove)) {
138 /* Only wonder city should build wonders! */
139 pcity->server.adv->building_want[improvement_index(pimprove)] = 0;
140 } else if (!can_city_build_improvement_later(pcity, pimprove)
141 || (!is_improvement_productive(pcity, pimprove))) {
142 /* Don't consider impossible or unproductive buildings */
143 pcity->server.adv->building_want[improvement_index(pimprove)] = 0;
144 } else if (city_has_building(pcity, pimprove)) {
145 /* Never want to build something we already have. */
146 pcity->server.adv->building_want[improvement_index(pimprove)] = 0;
147 }
148 /* else wait until a later turn */
150 } else {
151 /* An impossible improvement */
152 city_list_iterate(pplayer->cities, pcity) {
153 pcity->server.adv->building_want[improvement_index(pimprove)] = 0;
155 }
157
158#ifdef FREECIV_DEBUG
159 /* This logging is relatively expensive, so activate only if necessary */
160 city_list_iterate(pplayer->cities, pcity) {
161 improvement_iterate(pimprove) {
162 if (pcity->server.adv->building_want[improvement_index(pimprove)] != 0) {
163 CITY_LOG(LOG_DEBUG, pcity, "want to build %s with " ADV_WANT_PRINTF,
164 improvement_rule_name(pimprove),
165 pcity->server.adv->building_want[improvement_index(pimprove)]);
166 }
169#endif /* FREECIV_DEBUG */
170}
171
172/**********************************************************************/
175void building_advisor(struct player *pplayer)
176{
177 struct adv_data *adv = adv_data_get(pplayer, NULL);
178 struct city *wonder_city = game_city_by_number(adv->wonder_city);
179
180 CALL_FUNC_EACH_AI(build_adv_init, pplayer);
181
182 if (wonder_city && city_owner(wonder_city) != pplayer) {
183 /* We lost it to the enemy! */
184 adv->wonder_city = 0;
185 wonder_city = NULL;
186 }
187
188 /* Preliminary analysis - find our Wonder City. Also check if it
189 * is sane to continue building the wonder in it. If either does
190 * not check out, make a Wonder City. */
191 if (NULL == wonder_city
192 || 0 >= wonder_city->surplus[O_SHIELD]
193 || VUT_UTYPE == wonder_city->production.kind /* changed to defender? */
194 || !is_wonder(wonder_city->production.value.building)
195 || !can_city_build_improvement_now(wonder_city,
196 wonder_city->production.value.building)
197 || !is_improvement_productive(wonder_city,
198 wonder_city->production.value.building)) {
199 /* Find a new wonder city! */
200 int best_candidate_value = 0;
201 struct city *best_candidate = NULL;
202 /* Whether ruleset has a help wonder unit type */
203 bool has_help =
205
207
208 city_list_iterate(pplayer->cities, pcity) {
209 int value = pcity->surplus[O_SHIELD];
211 struct adv_city *city_data = pcity->server.adv;
212
213 if (is_ai(pplayer)) {
214 bool result = TRUE;
215
216 /* AI has opportunity to say that this city cannot be
217 * wonder city */
218 CALL_PLR_AI_FUNC(consider_wonder_city, pplayer, pcity, &result);
219 if (!result) {
220 continue;
221 }
222 }
223
225 value /= 2;
226 }
227
228 /* Downtown is the number of cities within a certain pf range.
229 * These may be able to help with caravans. Also look at the whole
230 * continent. */
231 if (first_role_unit_for_player(pplayer,
233 value += city_data->downtown;
234
235 if (place >= 0) {
236 value += adv->stats.cities[place] / 8;
237 }
238 }
239
240 if (place >= 0 && adv->continents[place].threat > 0) {
241 /* We have threatening neighbors: -25% */
242 value -= value / 4;
243 }
244
245 /* Require that there is at least some neighbors for wonder helpers,
246 * if ruleset supports it. */
247 if (value > best_candidate_value
248 && (!has_help || (place >= 0 && adv->stats.cities[place] > 5))
249 && (!has_help || city_data->downtown > 3)) {
251 best_candidate_value = value;
252 }
254
255 if (best_candidate) {
256 CITY_LOG(LOG_DEBUG, best_candidate, "chosen as wonder-city!");
257 adv->wonder_city = best_candidate->id;
258 wonder_city = best_candidate;
259 }
260 }
261
262 if (is_ai(pplayer)) {
263 CALL_PLR_AI_FUNC(build_adv_prepare, pplayer, pplayer, adv);
264 CALL_PLR_AI_FUNC(build_adv_adjust_want, pplayer, pplayer, wonder_city);
265 } else {
266 ba_human_wants(pplayer, wonder_city);
267 }
268}
269
270/**********************************************************************/
273void building_advisor_choose(struct city *pcity, struct adv_choice *choice)
274{
275 struct player *plr = city_owner(pcity);
276 struct impr_type *chosen = NULL;
277 adv_want want = 0;
278
279 improvement_iterate(pimprove) {
280 int id;
281
282 if (is_wonder(pimprove)) {
283 continue; /* Humans should not be advised to build wonders or palace */
284 }
285
286 id = improvement_index(pimprove);
287 if (pcity->server.adv->building_want[id] > want
289 want = pcity->server.adv->building_want[id];
290 chosen = pimprove;
291 }
293
294 choice->want = want;
295 choice->value.building = chosen;
296
297 if (chosen != NULL) {
298 choice->type = CT_BUILDING;
299
300 CITY_LOG(LOG_DEBUG, pcity, "advisor wants to build %s with want "
303 } else {
304 choice->type = CT_NONE;
305 }
306 choice->need_boat = FALSE;
307
308 /* Allow AI to override */
309 CALL_PLR_AI_FUNC(choose_building, plr, pcity, choice);
310}
311
312/**********************************************************************/
315void advisor_choose_build(struct player *pplayer, struct city *pcity)
316{
317 struct adv_choice choice;
318
320
321 if (valid_improvement(choice.value.building)) {
322 struct universal target = {
324 .value = {.building = choice.value.building}
325 };
326
327 change_build_target(pplayer, pcity, &target, E_IMP_AUTO);
328 return;
329 }
330
331 /* Build the first thing we can think of (except moving small wonder). */
332 improvement_iterate(pimprove) {
334 && pimprove->genus != IG_SMALL_WONDER) {
335 struct universal target = {
337 .value = {.building = pimprove}
338 };
339
340 change_build_target(pplayer, pcity, &target, E_IMP_AUTO);
341 return;
342 }
344}
#define action_id_get_role(act_id)
Definition actions.h:457
static void calculate_city_clusters(struct player *pplayer)
Definition advbuilding.c:58
void building_advisor(struct player *pplayer)
static void ba_human_wants(struct player *pplayer, struct city *wonder_city)
void building_advisor_choose(struct city *pcity, struct adv_choice *choice)
void advisor_choose_build(struct player *pplayer, struct city *pcity)
@ CT_NONE
Definition advchoice.h:37
@ CT_BUILDING
Definition advchoice.h:38
struct adv_data * adv_data_get(struct player *pplayer, bool *caller_closes)
Definition advdata.c:606
#define CALL_FUNC_EACH_AI(_func,...)
Definition ai.h:387
#define CALL_PLR_AI_FUNC(_func, _player,...)
Definition ai.h:377
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1240
bool can_city_build_improvement_now(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:854
bool can_city_build_improvement_later(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:871
#define city_list_iterate(citylist, pcity)
Definition city.h:505
#define city_owner(_pcity_)
Definition city.h:560
#define city_list_iterate_end
Definition city.h:507
void change_build_target(struct player *pplayer, struct city *pcity, struct universal *target, enum event_type event)
Definition citytools.c:3188
char * incite_cost
Definition comments.c:76
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
int int id
Definition editgui_g.h:28
float adv_want
Definition fc_types.h:1063
#define ADV_WANT_PRINTF
Definition fc_types.h:1064
@ O_SHIELD
Definition fc_types.h:101
signed short Continent_id
Definition fc_types.h:231
struct world wld
Definition game.c:62
struct city * game_city_by_number(int id)
Definition game.c:106
bool has_handicap(const struct player *pplayer, enum handicap_type htype)
Definition handicaps.c:66
@ H_MAP
Definition handicaps.h:28
const struct impr_type * valid_improvement(const struct impr_type *pimprove)
bool can_player_build_improvement_later(const struct player *p, const struct impr_type *pimprove)
const char * improvement_rule_name(const struct impr_type *pimprove)
Impr_type_id improvement_index(const struct impr_type *pimprove)
bool is_wonder(const struct impr_type *pimprove)
bool is_improvement_productive(const struct city *pcity, const struct impr_type *pimprove)
#define improvement_iterate_end
#define improvement_iterate(_p)
#define fc_assert_msg(condition, message,...)
Definition log.h:182
@ LOG_DEBUG
Definition log.h:35
int unit_move_rate(const struct unit *punit)
Definition movement.c:89
struct pf_map * pf_map_new(const struct pf_parameter *parameter)
void pf_map_destroy(struct pf_map *pfm)
#define pf_map_move_costs_iterate_end
#define pf_map_move_costs_iterate(ARG_pfm, NAME_tile, NAME_cost, COND_from_start)
void pft_fill_unit_parameter(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit *punit)
Definition pf_tools.c:843
#define is_ai(plr)
Definition player.h:232
#define CITY_LOG(loglevel, pcity, msg,...)
Definition srv_log.h:83
bool threat
Definition advdata.h:47
enum choice_type type
Definition advchoice.h:46
adv_want want
Definition advchoice.h:48
universals_u value
Definition advchoice.h:47
bool need_boat
Definition advchoice.h:49
int * cities
Definition advdata.h:96
struct adv_area_info * continents
Definition advdata.h:61
int wonder_city
Definition advdata.h:55
struct adv_data::@94 stats
Definition city.h:317
int surplus[O_LAST]
Definition city.h:352
struct universal production
Definition city.h:393
struct adv_city * adv
Definition city.h:449
struct city_list * cities
Definition player.h:281
Definition unit.h:140
struct unit::@84::@87 server
struct tile * tile
Definition unit.h:142
struct unit_adv * adv
Definition unit.h:239
enum universals_n kind
Definition fc_types.h:608
universals_u value
Definition fc_types.h:607
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
bool is_terrain_class_near_tile(const struct civ_map *nmap, const struct tile *ptile, enum terrain_class tclass)
Definition terrain.c:612
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_continent(_tile)
Definition tile.h:93
const struct impr_type * building
Definition fc_types.h:546
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1661
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1766
void unit_tile_set(struct unit *punit, struct tile *ptile)
Definition unit.c:1284
struct unit_type * first_role_unit_for_player(const struct player *pplayer, int role)
Definition unittype.c:2329
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2259
int num_role_units(int role)
Definition unittype.c:2209
struct unit_type * best_role_unit_for_player(const struct player *pplayer, int role)
Definition unittype.c:2304
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:377