Freeciv21
Develop your civilization from humble roots to a global empire
citymap.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2020 Freeciv21 and Freeciv contributors. This file is
3  __ __ part of Freeciv21. Freeciv21 is free software: you can
4 / \\..// \ redistribute it and/or modify it under the terms of the GNU
5  ( oo ) General Public License as published by the Free Software
6  \__/ Foundation, either version 3 of the License, or (at your
7  option) any later version. You should have received
8  a copy of the GNU General Public License along with Freeciv21. If not,
9  see https://www.gnu.org/licenses/.
10  */
11 
12 // utility
13 #include "log.h"
14 #include "support.h"
15 
16 // common
17 #include "city.h"
18 #include "game.h"
19 #include "map.h"
20 #include "unit.h"
21 #include "unitlist.h"
22 #include "unittype.h"
23 
24 #include "citymap.h"
25 
26 /* CITYMAP - reserve space for cities
27  *
28  * The citymap is a large int double array that corresponds to
29  * the freeciv main map. For each tile, it stores three different
30  * and exclusive values in a single int: A positive int tells you
31  * how many cities can use this tile (a crowdedness inidicator). A
32  * value of zero indicates that the tile is presently unused and
33  * available. A negative value means that this tile is occupied
34  * and reserved by some city or unit: in this case the value gives
35  * the negative of the ID of the city or unit that has reserved the
36  * tile.
37  *
38  * Code that uses the citymap should modify its behaviour based on
39  * positive values encountered, and never attempt to steal a tile
40  * which has a negative value.
41  */
42 
43 std::vector<int> citymap;
44 
45 #define log_citymap log_debug
46 
51 void citymap_turn_init(struct player *pplayer)
52 {
53  /* The citymap is reinitialized at the start of ever turn. This includes
54  * a call to realloc, which only really matters if this is the first turn
55  * of the game (but it's easier than a separate function to do this). */
56  citymap.clear();
57  citymap = std::vector<int>(MAP_INDEX_SIZE, 0);
58 
59  players_iterate(pother)
60  {
61  city_list_iterate(pother->cities, pcity)
62  {
63  struct tile *pcenter = city_tile(pcity);
64 
65  // reserve at least the default (squared) city radius
68  pcenter, ptile)
69  {
70  struct city *pwork = tile_worked(ptile);
71 
72  if (nullptr != pwork) {
73  citymap[tile_index(ptile)] = -(pwork->id);
74  } else {
75  citymap[tile_index(ptile)]++;
76  }
77  }
79  }
81  }
83 
84  unit_list_iterate(pplayer->units, punit)
85  {
86  if (unit_is_cityfounder(punit)
87  && punit->server.adv->task == AUT_BUILD_CITY) {
88  // use default (squared) city radius
89  city_tile_iterate(CITY_MAP_DEFAULT_RADIUS_SQ, punit->goto_tile, ptile)
90  {
91  if (citymap[tile_index(ptile)] >= 0) {
92  citymap[tile_index(ptile)]++;
93  }
94  }
96 
97  citymap[tile_index(punit->goto_tile)] = -(punit->id);
98  }
99  }
101 }
102 
106 void citymap_free() { citymap.clear(); }
107 
113 void citymap_reserve_city_spot(struct tile *ptile, int id)
114 {
115 #ifdef FREECIV_DEBUG
116  log_citymap("id %d reserving (%d, %d), was %d", id, TILE_XY(ptile),
117  citymap[tile_index(ptile)]);
118  fc_assert_ret(0 <= citymap[tile_index(ptile)]);
119 #endif // FREECIV_DEBUG
120 
121  /* Tiles will now be "reserved" by actual workers, so free excess
122  * reservations. Also mark tiles for city overlapping, or 'crowding'.
123  * Uses the default city map size / squared city radius. */
125  {
126  if (citymap[tile_index(ptile1)] == -id) {
127  citymap[tile_index(ptile1)] = 0;
128  }
129  if (citymap[tile_index(ptile1)] >= 0) {
130  citymap[tile_index(ptile1)]++;
131  }
132  }
134 
135  citymap[tile_index(ptile)] = -(id);
136 }
137 
141 void citymap_free_city_spot(struct tile *ptile, int id)
142 {
144  {
145  if (citymap[tile_index(ptile1)] == -(id)) {
146  citymap[tile_index(ptile1)] = 0;
147  } else if (citymap[tile_index(ptile1)] > 0) {
148  citymap[tile_index(ptile1)]--;
149  }
150  }
152 }
153 
158 void citymap_reserve_tile(struct tile *ptile, int id)
159 {
160 #ifdef FREECIV_DEBUG
162 #endif
163 
164  citymap[tile_index(ptile)] = -id;
165 }
166 
172 int citymap_read(struct tile *ptile) { return citymap[tile_index(ptile)]; }
173 
178 bool citymap_is_reserved(struct tile *ptile)
179 {
180  if (nullptr != tile_worked(ptile)
181  || citymap.empty() /*|| tile_city(ptile)*/) {
182  return true;
183  }
184  return (citymap[tile_index(ptile)] < 0);
185 }
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
Definition: city.cpp:1095
int city_map_radius_sq_get(const struct city *pcity)
Returns the current squared radius of the city.
Definition: city.cpp:130
#define city_list_iterate(citylist, pcity)
Definition: city.h:482
#define city_tile_iterate(_radius_sq, _city_tile, _tile)
Definition: city.h:202
#define city_list_iterate_end
Definition: city.h:484
#define CITY_MAP_DEFAULT_RADIUS_SQ
Definition: city.h:55
#define city_tile_iterate_end
Definition: city.h:209
void citymap_free_city_spot(struct tile *ptile, int id)
Reverse any reservations we have made in the surrounding area.
Definition: citymap.cpp:141
void citymap_reserve_tile(struct tile *ptile, int id)
Reserve additional tiles as desired (eg I would reserve best available food tile in addition to adjac...
Definition: citymap.cpp:158
void citymap_reserve_city_spot(struct tile *ptile, int id)
This function reserves a single tile for a (possibly virtual) city with a settler's or a city's id.
Definition: citymap.cpp:113
std::vector< int > citymap
Definition: citymap.cpp:43
bool citymap_is_reserved(struct tile *ptile)
A tile is reserved if it contains a city or unit id, or a worker is assigned to it.
Definition: citymap.cpp:178
int citymap_read(struct tile *ptile)
Returns a positive value if within a city radius, which is 1 x number of cities you are within the ra...
Definition: citymap.cpp:172
void citymap_free()
Free resources allocated for citymap.
Definition: citymap.cpp:106
#define log_citymap
Definition: citymap.cpp:45
void citymap_turn_init(struct player *pplayer)
Initialize citymap by reserving worked tiles and establishing the crowdedness of (virtual) cities.
Definition: citymap.cpp:51
@ AUT_BUILD_CITY
Definition: fc_types.h:287
#define fc_assert_ret(condition)
Definition: log.h:112
#define MAP_INDEX_SIZE
Definition: map.h:91
#define players_iterate_end
Definition: player.h:520
#define players_iterate(_pplayer)
Definition: player.h:514
#define MAX(x, y)
Definition: shared.h:48
Definition: city.h:291
int id
Definition: city.h:296
Definition: player.h:231
struct unit_list * units
Definition: player.h:264
Definition: tile.h:42
#define tile_index(_pt_)
Definition: tile.h:70
#define tile_worked(_tile)
Definition: tile.h:97
#define TILE_XY(ptile)
Definition: tile.h:36
bool unit_is_cityfounder(const struct unit *punit)
Is a cityfounder unit?
Definition: unit.cpp:2389
#define unit_list_iterate(unitlist, punit)
Definition: unitlist.h:25
#define unit_list_iterate_end
Definition: unitlist.h:27