Freeciv-3.3
Loading...
Searching...
No Matches
road.c
Go to the documentation of this file.
1/****************************************************************************
2 Freeciv - Copyright (C) 2004 - The Freeciv Team
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 "extras.h"
20#include "fc_types.h"
21#include "game.h"
22#include "map.h"
23#include "movement.h"
24#include "name_translation.h"
25#include "unittype.h"
26
27#include "road.h"
28
29/************************************************************************/
33{
35
36 return proad->id;
37}
38
39/************************************************************************/
43{
44 return proad->self;
45}
46
47/************************************************************************/
54
55/************************************************************************/
70
71/************************************************************************/
75int compare_road_move_cost(const struct extra_type *const *p,
76 const struct extra_type *const *q)
77{
78 const struct road_type *proad = extra_road_get(*p);
79 const struct road_type *qroad = extra_road_get(*q);
80
81 if (proad->move_cost > qroad->move_cost) {
82 return -1; /* q is faster */
83 } else if (proad->move_cost == qroad->move_cost) {
84 return 0;
85 } else {
86 return 1; /* p is faster */
87 }
88}
89
90/************************************************************************/
93void road_type_init(struct extra_type *pextra, int idx)
94{
95 struct road_type *proad;
96
97 proad = fc_malloc(sizeof(*proad));
98
99 pextra->data.road = proad;
100
101 requirement_vector_init(&proad->first_reqs);
102
103 proad->id = idx;
104 proad->integrators = NULL;
105 proad->self = pextra;
106}
107
108/************************************************************************/
112{
114 struct road_type *proad = extra_road_get(pextra);
115
116 proad->integrators = extra_type_list_new();
117 /* Roads always integrate with themselves. */
118 extra_type_list_append(proad->integrators, pextra);
121
122 if (BV_ISSET(proad->integrates, road_number(oroad))) {
123 extra_type_list_append(proad->integrators, oextra);
124 }
126 extra_type_list_unique(proad->integrators);
129}
130
131/************************************************************************/
135{
137 struct road_type *proad = extra_road_get(pextra);
138
139 requirement_vector_free(&proad->first_reqs);
140
141 if (proad->integrators != NULL) {
142 extra_type_list_destroy(proad->integrators);
143 proad->integrators = NULL;
144 }
146}
147
148/************************************************************************/
152{
153 return proad->compat;
154}
155
156/************************************************************************/
161{
162 if (compat == ROCO_NONE) {
163 return NULL;
164 }
165
167 struct road_type *proad = extra_road_get(pextra);
169 return proad;
170 }
172
173 return NULL;
174}
175
176/************************************************************************/
181{
182 if (gui_type == ROAD_GUI_OTHER) {
183 return NULL;
184 }
185
187 struct road_type *proad = extra_road_get(pextra);
188
189 if (proad->gui_type == gui_type) {
190 return proad;
191 }
193
194 return NULL;
195}
196
197/************************************************************************/
200bool road_can_be_built(const struct road_type *proad, const struct tile *ptile)
201{
202
203 if (!(road_extra_get(proad)->buildable)) {
204 /* Road type not buildable. */
205 return FALSE;
206 }
207
208 if (tile_has_road(ptile, proad)) {
209 /* Road exist already */
210 return FALSE;
211 }
212
213 if (tile_terrain(ptile)->road_time == 0) {
214 return FALSE;
215 }
216
217 return TRUE;
218}
219
220/************************************************************************/
224static bool are_road_reqs_fulfilled(const struct civ_map *nmap,
225 const struct road_type *proad,
226 const struct player *pplayer,
227 const struct unit *punit,
228 const struct tile *ptile)
229{
230 struct extra_type *pextra = road_extra_get(proad);
231 const struct req_context context = {
232 .player = pplayer,
233 .tile = ptile,
234 .unit = punit,
235 .unittype = punit ? unit_type_get(punit) : NULL,
236 };
237
238 if (requirement_vector_size(&proad->first_reqs) > 0) {
239 bool beginning = TRUE;
240
241 extra_type_list_iterate(proad->integrators, iroad) {
242 /* FIXME: mixing cardinal and non-cardinal roads as integrators is
243 * probably not a good idea. */
248 break;
249 }
251 } else {
252 adjc_iterate(nmap, ptile, adjc_tile) {
255 break;
256 }
258 }
259
260 if (!beginning) {
261 break;
262 }
264
265 if (beginning) {
267 &(const struct req_context) {
268 .player = tile_owner(ptile),
269 },
270 &proad->first_reqs, RPT_POSSIBLE)) {
271 return FALSE;
272 }
273 }
274 }
275
276 return are_reqs_active(&context,
277 &(const struct req_context) {
278 .player = tile_owner(ptile),
279 },
280 &pextra->reqs, RPT_POSSIBLE);
281}
282
283/************************************************************************/
287 const struct road_type *proad,
288 const struct player *pplayer,
289 const struct tile *ptile)
290{
291 if (!can_build_extra_base(road_extra_get(proad), pplayer, ptile)) {
292 return FALSE;
293 }
294
295 return are_road_reqs_fulfilled(nmap, proad, pplayer, NULL, ptile);
296}
297
298/************************************************************************/
301bool can_build_road(const struct civ_map *nmap,
302 struct road_type *proad,
303 const struct unit *punit,
304 const struct tile *ptile)
305{
306 struct player *pplayer = unit_owner(punit);
307
308 if (!can_build_extra_base(road_extra_get(proad), pplayer, ptile)) {
309 return FALSE;
310 }
311
312 return are_road_reqs_fulfilled(nmap, proad, pplayer, punit, ptile);
313}
314
315/************************************************************************/
319int count_road_near_tile(struct civ_map *nmap, const struct tile *ptile,
320 const struct road_type *proad)
321{
322 int count = 0;
323
324 if (proad == NULL) {
325 return 0;
326 }
327
328 adjc_iterate(nmap, ptile, adjc_tile) {
330 count++;
331 }
333
334 return count;
335}
336
337/************************************************************************/
341 const struct tile *ptile,
342 const struct extra_type *priver)
343{
344 int count = 0;
345
347 if (priver == NULL && tile_has_river(adjc_tile)) {
348 /* Some river */
349 count++;
350 } else if (priver != NULL && tile_has_extra(adjc_tile, priver)) {
351 /* Specific river */
352 count++;
353 }
355
356 return count;
357}
358
359/************************************************************************/
363 const struct tile *ptile,
364 const struct extra_type *priver,
365 bool percentage)
366{
367 int count = 0;
368 int total = 0;
369
371
374 count++;
375 }
376 total++;
378
379 if (percentage && count > 0) { /* Latter condition avoids div by zero */
380 count = count * 100 / total;
381 }
382
383 return count;
384}
385
386/************************************************************************/
390 const struct tile *ptile,
391 const struct extra_type *priver,
392 bool percentage)
393{
394 int count = 0;
395 int total = 0;
396
398
399 adjc_iterate(nmap, ptile, adjc_tile) {
401 count++;
402 }
403 total++;
405
406 if (percentage && count > 0) { /* Latter condition avoids div by zero */
407 count = count * 100 / total;
408 }
409
410 return count;
411}
412
413/************************************************************************/
416bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
417{
418 return BV_ISSET(proad->flags, flag);
419}
420
421/************************************************************************/
426 const struct tile *ptile,
427 enum road_flag_id flag)
428{
430 if (road_has_flag(extra_road_get(pextra), flag)) {
432 if (tile_has_extra(adjc_tile, pextra)) {
433 return TRUE;
434 }
436 }
438
439 return FALSE;
440}
441
442/************************************************************************/
447 const struct tile *ptile,
448 enum road_flag_id flag)
449{
451 if (road_has_flag(extra_road_get(pextra), flag)) {
452 adjc_iterate(nmap, ptile, adjc_tile) {
453 if (tile_has_extra(adjc_tile, pextra)) {
454 return TRUE;
455 }
457 }
459
460 return FALSE;
461}
462
463/************************************************************************/
467 const struct tile *ptile)
468{
469 struct extra_type *pextra;
470
473 return FALSE;
474 }
475 } else if (tile_terrain(ptile)->road_time == 0) {
476 return FALSE;
477 }
478
479 pextra = road_extra_get(proad);
480
481 return are_reqs_active(&(const struct req_context) { .tile = ptile },
482 NULL,
483 &pextra->reqs, RPT_POSSIBLE);
484}
485
486/************************************************************************/
489bool is_cardinal_only_road(const struct extra_type *pextra)
490{
491 const struct road_type *proad;
492
493 if (!is_extra_caused_by(pextra, EC_ROAD)) {
494 return FALSE;
495 }
496
497 proad = extra_road_get(pextra);
498
499 return proad->move_mode == RMM_CARDINAL || proad->move_mode == RMM_RELAXED;
500}
501
502/************************************************************************/
506{
507 return proad->move_cost >= 0;
508}
#define BV_ISSET(bv, bit)
Definition bitvector.h:86
char * roads
Definition comments.c:40
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 * punit
Definition dialogs_g.h:74
bool can_build_extra_base(const struct extra_type *pextra, const struct player *pplayer, const struct tile *ptile)
Definition extras.c:413
struct extra_type_list * extra_type_list_by_cause(enum extra_cause cause)
Definition extras.c:249
#define extra_type_list_iterate(extralist, pextra)
Definition extras.h:165
#define is_extra_caused_by(e, c)
Definition extras.h:203
#define extra_type_list_iterate_end
Definition extras.h:167
#define extra_road_get(_e_)
Definition extras.h:191
#define extra_type_by_cause_iterate_end
Definition extras.h:339
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:333
int Road_type_id
Definition fc_types.h:243
road_compat
Definition fc_types.h:961
@ ROCO_NONE
Definition fc_types.h:961
@ RPT_POSSIBLE
Definition fc_types.h:532
struct civ_game game
Definition game.c:61
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define adjc_iterate_end
Definition map.h:430
#define cardinal_adjc_iterate_end
Definition map.h:456
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:425
#define cardinal_adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:452
#define fc_malloc(sz)
Definition mem.h:34
bool are_reqs_active(const struct req_context *context, const struct req_context *other_context, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
Road_type_id road_count(void)
Definition road.c:50
bool can_build_road(const struct civ_map *nmap, struct road_type *proad, const struct unit *punit, const struct tile *ptile)
Definition road.c:301
struct extra_type * road_extra_get(const struct road_type *proad)
Definition road.c:42
Road_type_id road_number(const struct road_type *proad)
Definition road.c:32
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Definition road.c:416
bool is_cardinal_only_road(const struct extra_type *pextra)
Definition road.c:489
void road_integrators_cache_init(void)
Definition road.c:111
enum road_compat road_compat_special(const struct road_type *proad)
Definition road.c:151
bool is_road_flag_near_tile(const struct civ_map *nmap, const struct tile *ptile, enum road_flag_id flag)
Definition road.c:446
bool road_provides_move_bonus(const struct road_type *proad)
Definition road.c:505
void road_types_free(void)
Definition road.c:134
int count_river_type_tile_card(struct civ_map *nmap, const struct tile *ptile, const struct extra_type *priver, bool percentage)
Definition road.c:362
static bool are_road_reqs_fulfilled(const struct civ_map *nmap, const struct road_type *proad, const struct player *pplayer, const struct unit *punit, const struct tile *ptile)
Definition road.c:224
struct road_type * road_by_number(Road_type_id id)
Definition road.c:58
void road_type_init(struct extra_type *pextra, int idx)
Definition road.c:93
bool is_native_tile_to_road(const struct road_type *proad, const struct tile *ptile)
Definition road.c:466
int compare_road_move_cost(const struct extra_type *const *p, const struct extra_type *const *q)
Definition road.c:75
struct road_type * road_by_compat_special(enum road_compat compat)
Definition road.c:160
bool road_can_be_built(const struct road_type *proad, const struct tile *ptile)
Definition road.c:200
int count_river_type_near_tile(struct civ_map *nmap, const struct tile *ptile, const struct extra_type *priver, bool percentage)
Definition road.c:389
int count_river_near_tile(struct civ_map *nmap, const struct tile *ptile, const struct extra_type *priver)
Definition road.c:340
bool player_can_build_road(const struct civ_map *nmap, const struct road_type *proad, const struct player *pplayer, const struct tile *ptile)
Definition road.c:286
struct road_type * road_by_gui_type(enum road_gui_type gui_type)
Definition road.c:180
bool is_road_flag_card_near(const struct civ_map *nmap, const struct tile *ptile, enum road_flag_id flag)
Definition road.c:425
int count_road_near_tile(struct civ_map *nmap, const struct tile *ptile, const struct road_type *proad)
Definition road.c:319
static struct compatibility compat[]
Definition savecompat.c:112
struct packet_ruleset_control control
Definition game.h:83
struct road_type * road
Definition extras.h:155
struct extra_type::@26 data
struct requirement_vector reqs
Definition extras.h:106
const struct player * player
enum road_gui_type gui_type
Definition road.h:80
Definition tile.h:50
Definition unit.h:140
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define terrain_has_flag(terr, flag)
Definition terrain.h:176
bool tile_has_river(const struct tile *ptile)
Definition tile.c:852
bool tile_has_road(const struct tile *ptile, const struct road_type *proad)
Definition tile.c:844
#define tile_terrain(_tile)
Definition tile.h:111
#define tile_has_extra(ptile, pextra)
Definition tile.h:148
#define tile_owner(_tile)
Definition tile.h:97
#define unit_owner(_pu)
Definition unit.h:403
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123