Freeciv-3.3
Loading...
Searching...
No Matches
infracache.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/* common */
19#include "city.h"
20#include "game.h"
21#include "map.h"
22#include "player.h"
23#include "tile.h"
24
25/* server */
26#include "maphand.h"
27
28/* server/advisors */
29#include "advbuilding.h"
30#include "autoworkers.h"
31
32#include "infracache.h"
33
34/* Cache activities within the city map */
40
41static adv_want adv_calc_cultivate(const struct city *pcity,
42 const struct tile *ptile);
43static adv_want adv_calc_plant(const struct city *pcity,
44 const struct tile *ptile);
45static adv_want adv_calc_transform(const struct city *pcity,
46 const struct tile *ptile);
47static adv_want adv_calc_extra(const struct city *pcity,
48 const struct tile *ptile,
49 const struct extra_type *pextra);
50static adv_want adv_calc_rmextra(const struct city *pcity,
51 const struct tile *ptile,
52 const struct extra_type *pextra);
53
54/**********************************************************************/
63 const struct tile *ptile)
64{
67
68 fc_assert_ret_val(ptile != NULL, -1);
69
71 new_terrain = old_terrain->cultivate_result;
72
74 struct tile *vtile;
75
77 /* Not a valid activity. */
78 return -1;
79 }
80 /* Irrigation would change the terrain type, clearing conflicting
81 * extras in the process. Calculate the benefit of doing so. */
82 vtile = tile_virtual_new(ptile);
83
87
88 return goodness;
89 } else {
90 return -1;
91 }
92}
93
94/**********************************************************************/
102static adv_want adv_calc_plant(const struct city *pcity,
103 const struct tile *ptile)
104{
107
108 fc_assert_ret_val(ptile != NULL, -1);
109
110 old_terrain = tile_terrain(ptile);
111 new_terrain = old_terrain->plant_result;
112
114 struct tile *vtile;
115
117 /* Not a valid activity. */
118 return -1;
119 }
120 /* Mining would change the terrain type, clearing conflicting
121 * extras in the process. Calculate the benefit of doing so. */
122 vtile = tile_virtual_new(ptile);
123
127
128 return goodness;
129 } else {
130 return -1;
131 }
132}
133
134/**********************************************************************/
143 const struct tile *ptile)
144{
146 struct tile *vtile;
148 const struct civ_map *nmap = &(wld.map);
149
150 fc_assert_ret_val(ptile != NULL, -1);
151
152 old_terrain = tile_terrain(ptile);
153 new_terrain = old_terrain->transform_result;
154
156 return -1;
157 }
158
160 /* Can't do this terrain conversion here. */
161 return -1;
162 }
163
165 return -1;
166 }
167
168 vtile = tile_virtual_new(ptile);
172
173 return goodness;
174}
175
176/**********************************************************************/
188static adv_want adv_calc_extra(const struct city *pcity,
189 const struct tile *ptile,
190 const struct extra_type *pextra)
191{
192 adv_want goodness = -1;
193
194 fc_assert_ret_val(ptile != NULL, -1);
195
196 if (player_can_build_extra(pextra, city_owner(pcity), ptile)) {
197 struct tile *vtile = tile_virtual_new(ptile);
198
199 tile_add_extra(vtile, pextra);
200
203 && !can_extras_coexist(pextra, cextra)) {
205 }
207
210 }
211
212 return goodness;
213}
214
215/**********************************************************************/
223static adv_want adv_calc_rmextra(const struct city *pcity,
224 const struct tile *ptile,
225 const struct extra_type *pextra)
226{
227 adv_want goodness = -1;
228
229 fc_assert_ret_val(ptile != NULL, -1);
230
231 if (player_can_remove_extra(pextra, city_owner(pcity), ptile)) {
232 struct tile *vtile = tile_virtual_new(ptile);
233
234 tile_remove_extra(vtile, pextra);
235
238 }
239
240 return goodness;
241}
242
243/**********************************************************************/
251{
252 const struct civ_map *nmap = &(wld.map);
253
254 city_list_iterate(pplayer->cities, pcity) {
255 struct tile *pcenter = city_tile(pcity);
256 int radius_sq = city_map_radius_sq_get(pcity);
257
261 -1);
264
265 city_tile_iterate_index(nmap, radius_sq, pcenter, ptile, cindex) {
267 adv_calc_plant(pcity, ptile));
269 adv_calc_cultivate(pcity, ptile));
271 adv_calc_transform(pcity, ptile));
272
273 /* road_bonus() is handled dynamically later; it takes into
274 * account settlers that have already been assigned to building
275 * roads this turn. */
276 extra_type_iterate(pextra) {
277 /* We have no use for extra value, if workers cannot be assigned
278 * to build it, so don't use time to calculate values otherwise */
279 if (pextra->buildable
281 adv_city_worker_extra_set(pcity, cindex, pextra,
282 adv_calc_extra(pcity, ptile, pextra));
283 } else {
284 adv_city_worker_extra_set(pcity, cindex, pextra, 0);
285 }
286 if (tile_has_extra(ptile, pextra)
288 adv_city_worker_rmextra_set(pcity, cindex, pextra,
289 adv_calc_rmextra(pcity, ptile, pextra));
290 } else {
291 adv_city_worker_rmextra_set(pcity, cindex, pextra, 0);
292 }
296}
297
298/**********************************************************************/
303adv_want city_tile_value(const struct city *pcity, const struct tile *ptile,
304 int foodneed, int prodneed)
305{
306 int food = city_tile_output_now(pcity, ptile, O_FOOD);
307 int shield = city_tile_output_now(pcity, ptile, O_SHIELD);
308 int trade = city_tile_output_now(pcity, ptile, O_TRADE);
309 adv_want value = 0;
310
311 /* Each food, trade, and shield gets a certain weighting. We also benefit
312 * tiles that have at least one of an item - this promotes balance and
313 * also accounts for INC_TILE effects. */
314 value += food * FOOD_WEIGHTING;
315 if (food > 0) {
316 value += FOOD_WEIGHTING / 2;
317 }
318 value += shield * SHIELD_WEIGHTING;
319 if (shield > 0) {
320 value += SHIELD_WEIGHTING / 2;
321 }
322 value += trade * TRADE_WEIGHTING;
323 if (trade > 0) {
324 value += TRADE_WEIGHTING / 2;
325 }
326
327 return value;
328}
329
330/**********************************************************************/
335 enum unit_activity act_id, adv_want value)
336{
337 if (pcity->server.adv->act_cache_radius_sq
339 log_debug("update activity cache for %s: radius_sq changed from "
340 "%d to %d", city_name_get(pcity),
341 pcity->server.adv->act_cache_radius_sq,
344 }
345
348 fc_assert_ret(NULL != pcity->server.adv->act_cache);
349 fc_assert_ret(pcity->server.adv->act_cache_radius_sq
352
353 (pcity->server.adv->act_cache[city_tile_index]).act[act_id] = value;
354}
355
356/**********************************************************************/
361 int city_tile_index,
362 enum unit_activity act_id)
363{
366 fc_assert_ret_val(NULL != pcity->server.adv->act_cache, 0);
367 fc_assert_ret_val(pcity->server.adv->act_cache_radius_sq
370
371 return (pcity->server.adv->act_cache[city_tile_index]).act[act_id];
372}
373
374/**********************************************************************/
379 const struct extra_type *pextra, int value)
380{
381 if (pcity->server.adv->act_cache_radius_sq
383 log_debug("update activity cache for %s: radius_sq changed from "
384 "%d to %d", city_name_get(pcity),
385 pcity->server.adv->act_cache_radius_sq,
388 }
389
392 fc_assert_ret(NULL != pcity->server.adv->act_cache);
393 fc_assert_ret(pcity->server.adv->act_cache_radius_sq
396
397 (pcity->server.adv->act_cache[city_tile_index]).extra[extra_index(pextra)] = value;
398}
399
400/**********************************************************************/
405 const struct extra_type *pextra, int value)
406{
407 if (pcity->server.adv->act_cache_radius_sq
409 log_debug("update activity cache for %s: radius_sq changed from "
410 "%d to %d", city_name_get(pcity),
411 pcity->server.adv->act_cache_radius_sq,
414 }
415
418 fc_assert_ret(NULL != pcity->server.adv->act_cache);
419 fc_assert_ret(pcity->server.adv->act_cache_radius_sq
422
423 (pcity->server.adv->act_cache[city_tile_index]).rmextra[extra_index(pextra)] = value;
424}
425
426/**********************************************************************/
431 const struct extra_type *pextra)
432{
435 fc_assert_ret_val(NULL != pcity->server.adv->act_cache, 0);
436 fc_assert_ret_val(pcity->server.adv->act_cache_radius_sq
439
440 return (pcity->server.adv->act_cache[city_tile_index]).extra[extra_index(pextra)];
441}
442
443/**********************************************************************/
448 const struct extra_type *pextra)
449{
452 fc_assert_ret_val(NULL != pcity->server.adv->act_cache, 0);
453 fc_assert_ret_val(pcity->server.adv->act_cache_radius_sq
456
457 return (pcity->server.adv->act_cache[city_tile_index]).rmextra[extra_index(pextra)];
458}
459
460/**********************************************************************/
464{
465 int radius_sq = city_map_radius_sq_get(pcity);
466
469
470 /* initialize act_cache if needed */
471 if (pcity->server.adv->act_cache == NULL
472 || pcity->server.adv->act_cache_radius_sq == -1
473 || pcity->server.adv->act_cache_radius_sq != radius_sq) {
474 pcity->server.adv->act_cache
475 = fc_realloc(pcity->server.adv->act_cache,
476 city_map_tiles(radius_sq)
477 * sizeof(*(pcity->server.adv->act_cache)));
478 /* initialize with 0 */
479 memset(pcity->server.adv->act_cache, 0,
480 city_map_tiles(radius_sq)
481 * sizeof(*(pcity->server.adv->act_cache)));
482 pcity->server.adv->act_cache_radius_sq = radius_sq;
483 }
484}
485
486/**********************************************************************/
490{
491 pcity->server.adv = fc_calloc(1, sizeof(*pcity->server.adv));
492
493 pcity->server.adv->act_cache = NULL;
494 pcity->server.adv->act_cache_radius_sq = -1;
495 /* Allocate memory for pcity->ai->act_cache */
497}
498
499/**********************************************************************/
503{
505
506 if (pcity->server.adv) {
507 if (pcity->server.adv->act_cache) {
508 FC_FREE(pcity->server.adv->act_cache);
509 }
511 }
512}
#define action_id_get_activity(act_id)
Definition actions.h:462
#define TRADE_WEIGHTING
Definition advbuilding.h:21
#define FOOD_WEIGHTING
Definition advbuilding.h:19
#define SHIELD_WEIGHTING
Definition advbuilding.h:20
#define aw_transform_action_iterate(_act_)
Definition autoworkers.h:74
#define aw_transform_action_iterate_end
Definition autoworkers.h:78
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
int city_tile_output_now(const struct city *pcity, const struct tile *ptile, Output_type_id otype)
Definition city.c:1384
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:137
int city_map_tiles(int city_radius_sq)
Definition city.c:171
#define city_list_iterate(citylist, pcity)
Definition city.h:505
#define city_tile(_pcity_)
Definition city.h:561
#define city_tile_iterate_index(_nmap, _radius_sq, _city_tile, _tile, _index)
Definition city.h:198
#define city_tile_iterate_index_end
Definition city.h:206
#define city_owner(_pcity_)
Definition city.h:560
#define city_list_iterate_end
Definition city.h:507
#define city_map_iterate_end
Definition city.h:174
#define city_map_iterate(_radius_sq, _index, _x, _y)
Definition city.h:170
#define city_map_tiles_from_city(_pcity)
Definition city.h:124
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
bool is_extra_removed_by_worker_action(const struct extra_type *pextra)
Definition extras.c:1059
bool is_extra_caused_by_worker_action(const struct extra_type *pextra)
Definition extras.c:1046
bool player_can_build_extra(const struct extra_type *pextra, const struct player *pplayer, const struct tile *ptile)
Definition extras.c:468
bool can_extras_coexist(const struct extra_type *pextra1, const struct extra_type *pextra2)
Definition extras.c:1017
bool player_can_remove_extra(const struct extra_type *pextra, const struct player *pplayer, const struct tile *ptile)
Definition extras.c:595
#define extra_type_iterate(_p)
Definition extras.h:315
#define extra_type_iterate_end
Definition extras.h:321
#define extra_index(_e_)
Definition extras.h:183
float adv_want
Definition fc_types.h:1063
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
@ O_SHIELD
Definition fc_types.h:101
@ O_FOOD
Definition fc_types.h:101
@ O_TRADE
Definition fc_types.h:101
struct world wld
Definition game.c:62
static adv_want adv_calc_transform(const struct city *pcity, const struct tile *ptile)
Definition infracache.c:142
adv_want adv_city_worker_act_get(const struct city *pcity, int city_tile_index, enum unit_activity act_id)
Definition infracache.c:360
void adv_city_free(struct city *pcity)
Definition infracache.c:502
static adv_want adv_calc_extra(const struct city *pcity, const struct tile *ptile, const struct extra_type *pextra)
Definition infracache.c:188
static adv_want adv_calc_rmextra(const struct city *pcity, const struct tile *ptile, const struct extra_type *pextra)
Definition infracache.c:223
void adv_city_worker_extra_set(struct city *pcity, int city_tile_index, const struct extra_type *pextra, int value)
Definition infracache.c:378
void adv_city_update(struct city *pcity)
Definition infracache.c:463
void adv_city_worker_act_set(struct city *pcity, int city_tile_index, enum unit_activity act_id, adv_want value)
Definition infracache.c:334
int adv_city_worker_extra_get(const struct city *pcity, int city_tile_index, const struct extra_type *pextra)
Definition infracache.c:430
void initialize_infrastructure_cache(struct player *pplayer)
Definition infracache.c:250
void adv_city_worker_rmextra_set(struct city *pcity, int city_tile_index, const struct extra_type *pextra, int value)
Definition infracache.c:404
int adv_city_worker_rmextra_get(const struct city *pcity, int city_tile_index, const struct extra_type *pextra)
Definition infracache.c:447
static adv_want adv_calc_cultivate(const struct city *pcity, const struct tile *ptile)
Definition infracache.c:62
static adv_want adv_calc_plant(const struct city *pcity, const struct tile *ptile)
Definition infracache.c:102
void adv_city_alloc(struct city *pcity)
Definition infracache.c:489
adv_want city_tile_value(const struct city *pcity, const struct tile *ptile, int foodneed, int prodneed)
Definition infracache.c:303
#define fc_assert_ret(condition)
Definition log.h:192
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define log_debug(message,...)
Definition log.h:116
bool terrain_surroundings_allow_change(const struct civ_map *nmap, const struct tile *ptile, const struct terrain *pterrain)
Definition map.c:787
#define fc_calloc(n, esz)
Definition mem.h:38
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_realloc(ptr, sz)
Definition mem.h:36
Definition city.h:317
struct city_list * cities
Definition player.h:281
Definition tile.h:50
struct unit::@84::@87 server
struct unit_adv * adv
Definition unit.h:239
adv_want extra[MAX_EXTRA_TYPES]
Definition infracache.c:37
adv_want rmextra[MAX_EXTRA_TYPES]
Definition infracache.c:38
adv_want act[ACTIVITY_LAST]
Definition infracache.c:36
struct civ_map map
#define T_NONE
Definition terrain.h:61
#define terrain_has_flag(terr, flag)
Definition terrain.h:176
void tile_add_extra(struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:955
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1035
void tile_remove_extra(struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:965
void tile_change_terrain(struct tile *ptile, struct terrain *pterrain)
Definition tile.c:496
struct tile * tile_virtual_new(const struct tile *ptile)
Definition tile.c:981
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_terrain(_tile)
Definition tile.h:111
#define tile_has_extra(ptile, pextra)
Definition tile.h:148