Freeciv-3.4
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{
34 fc_assert_ret_val(proad != nullptr, -1);
35
36 return proad->id;
37}
38
39/************************************************************************/
43{
44 return proad->self;
45}
46
47/************************************************************************/
54
55/************************************************************************/
59{
60 struct extra_type_list *roads;
61
63
64 if (roads == nullptr || id < 0 || id >= extra_type_list_size(roads)) {
65 return nullptr;
66 }
67
69}
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 = nullptr;
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 != nullptr) {
142 extra_type_list_destroy(proad->integrators);
143 proad->integrators = nullptr;
144 }
146}
147
148/************************************************************************/
152{
153 return proad->compat;
154}
155
156/************************************************************************/
161{
162 if (compat == ROCO_NONE) {
163 return nullptr;
164 }
165
167 struct road_type *proad = extra_road_get(pextra);
168
170 return proad;
171 }
173
174 return nullptr;
175}
176
177/************************************************************************/
182{
183 if (gui_type == ROAD_GUI_OTHER) {
184 return nullptr;
185 }
186
188 struct road_type *proad = extra_road_get(pextra);
189
190 if (proad->gui_type == gui_type) {
191 return proad;
192 }
194
195 return nullptr;
196}
197
198/************************************************************************/
201bool road_can_be_built(const struct road_type *proad, const struct tile *ptile)
202{
203
204 if (!(road_extra_get(proad)->buildable)) {
205 /* Road type not buildable. */
206 return FALSE;
207 }
208
209 if (tile_has_road(ptile, proad)) {
210 /* Road exist already */
211 return FALSE;
212 }
213
214 if (tile_terrain(ptile)->road_time == 0) {
215 return FALSE;
216 }
217
218 return TRUE;
219}
220
221/************************************************************************/
225static bool are_road_reqs_fulfilled(const struct civ_map *nmap,
226 const struct road_type *proad,
227 const struct player *pplayer,
228 const struct unit *punit,
229 const struct tile *ptile)
230{
231 struct extra_type *pextra = road_extra_get(proad);
232 const struct req_context context = {
233 .player = pplayer,
234 .tile = ptile,
235 .unit = punit,
236 .unittype = punit ? unit_type_get(punit) : nullptr,
237 };
238
239 if (requirement_vector_size(&proad->first_reqs) > 0) {
240 bool beginning = TRUE;
241
242 extra_type_list_iterate(proad->integrators, iroad) {
243 /* FIXME: mixing cardinal and non-cardinal roads as integrators is
244 * probably not a good idea. */
249 break;
250 }
252 } else {
253 adjc_iterate(nmap, ptile, adjc_tile) {
256 break;
257 }
259 }
260
261 if (!beginning) {
262 break;
263 }
265
266 if (beginning) {
268 &(const struct req_context) {
269 .player = tile_owner(ptile),
270 },
271 &proad->first_reqs, RPT_POSSIBLE)) {
272 return FALSE;
273 }
274 }
275 }
276
277 return are_reqs_active(&context,
278 &(const struct req_context) {
279 .player = tile_owner(ptile),
280 },
281 &pextra->reqs, RPT_POSSIBLE);
282}
283
284/************************************************************************/
288 const struct road_type *proad,
289 const struct player *pplayer,
290 const struct tile *ptile)
291{
292 if (!can_build_extra_base(road_extra_get(proad), pplayer, ptile)) {
293 return FALSE;
294 }
295
296 return are_road_reqs_fulfilled(nmap, proad, pplayer, nullptr, ptile);
297}
298
299/************************************************************************/
302bool can_build_road(const struct civ_map *nmap,
303 struct road_type *proad,
304 const struct unit *punit,
305 const struct tile *ptile)
306{
307 struct player *pplayer = unit_owner(punit);
308
309 if (!can_build_extra_base(road_extra_get(proad), pplayer, ptile)) {
310 return FALSE;
311 }
312
313 return are_road_reqs_fulfilled(nmap, proad, pplayer, punit, ptile);
314}
315
316/************************************************************************/
320int count_road_near_tile(struct civ_map *nmap, const struct tile *ptile,
321 const struct road_type *proad)
322{
323 int count = 0;
324
325 if (proad == nullptr) {
326 return 0;
327 }
328
329 adjc_iterate(nmap, ptile, adjc_tile) {
331 count++;
332 }
334
335 return count;
336}
337
338/************************************************************************/
342 const struct tile *ptile,
343 const struct extra_type *priver)
344{
345 int count = 0;
346
348 if (priver == nullptr && tile_has_river(adjc_tile)) {
349 /* Some river */
350 count++;
351 } else if (priver != nullptr && tile_has_extra(adjc_tile, priver)) {
352 /* Specific river */
353 count++;
354 }
356
357 return count;
358}
359
360/************************************************************************/
364 const struct tile *ptile,
365 const struct extra_type *priver,
366 bool percentage)
367{
368 int count = 0;
369 int total = 0;
370
371 fc_assert(priver != nullptr);
372
375 count++;
376 }
377 total++;
379
380 if (percentage && count > 0) { /* Latter condition avoids div by zero */
381 count = count * 100 / total;
382 }
383
384 return count;
385}
386
387/************************************************************************/
391 const struct tile *ptile,
392 const struct extra_type *priver,
393 bool percentage)
394{
395 int count = 0;
396 int total = 0;
397
398 fc_assert(priver != nullptr);
399
400 adjc_iterate(nmap, ptile, adjc_tile) {
402 count++;
403 }
404 total++;
406
407 if (percentage && count > 0) { /* Latter condition avoids div by zero */
408 count = count * 100 / total;
409 }
410
411 return count;
412}
413
414/************************************************************************/
417bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
418{
419 return BV_ISSET(proad->flags, flag);
420}
421
422/************************************************************************/
427 const struct tile *ptile,
428 enum road_flag_id flag)
429{
431 if (road_has_flag(extra_road_get(pextra), flag)) {
433 if (tile_has_extra(adjc_tile, pextra)) {
434 return TRUE;
435 }
437 }
439
440 return FALSE;
441}
442
443/************************************************************************/
448 const struct tile *ptile,
449 enum road_flag_id flag)
450{
452 if (road_has_flag(extra_road_get(pextra), flag)) {
453 adjc_iterate(nmap, ptile, adjc_tile) {
454 if (tile_has_extra(adjc_tile, pextra)) {
455 return TRUE;
456 }
458 }
460
461 return FALSE;
462}
463
464/************************************************************************/
468 const struct tile *ptile)
469{
470 struct extra_type *pextra;
471
474 return FALSE;
475 }
476 } else if (tile_terrain(ptile)->road_time == 0) {
477 return FALSE;
478 }
479
480 pextra = road_extra_get(proad);
481
482 return are_reqs_active(&(const struct req_context) { .tile = ptile },
483 nullptr,
484 &pextra->reqs, RPT_POSSIBLE);
485}
486
487/************************************************************************/
490bool is_cardinal_only_road(const struct extra_type *pextra)
491{
492 const struct road_type *proad;
493
494 if (!is_extra_caused_by(pextra, EC_ROAD)) {
495 return FALSE;
496 }
497
498 proad = extra_road_get(pextra);
499
500 return proad->move_mode == RMM_CARDINAL || proad->move_mode == RMM_RELAXED;
501}
502
503/************************************************************************/
507{
508 return proad->move_cost >= 0;
509}
#define BV_ISSET(bv, bit)
Definition bitvector.h:86
char * roads
Definition comments.c:40
char * incite_cost
Definition comments.c:77
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:245
road_compat
Definition fc_types.h:948
@ ROCO_NONE
Definition fc_types.h:948
@ RPT_POSSIBLE
Definition fc_types.h:515
struct civ_game game
Definition game.c:62
#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:439
#define cardinal_adjc_iterate_end
Definition map.h:465
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:434
#define cardinal_adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:461
#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:302
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:417
bool is_cardinal_only_road(const struct extra_type *pextra)
Definition road.c:490
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:447
bool road_provides_move_bonus(const struct road_type *proad)
Definition road.c:506
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:363
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:225
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:467
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:201
int count_river_type_near_tile(struct civ_map *nmap, const struct tile *ptile, const struct extra_type *priver, bool percentage)
Definition road.c:390
int count_river_near_tile(struct civ_map *nmap, const struct tile *ptile, const struct extra_type *priver)
Definition road.c:341
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:287
struct road_type * road_by_gui_type(enum road_gui_type gui_type)
Definition road.c:181
bool is_road_flag_card_near(const struct civ_map *nmap, const struct tile *ptile, enum road_flag_id flag)
Definition road.c:426
int count_road_near_tile(struct civ_map *nmap, const struct tile *ptile, const struct road_type *proad)
Definition road.c:320
static struct compatibility compat[]
Definition savecompat.c:117
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:177
bool tile_has_river(const struct tile *ptile)
Definition tile.c:853
bool tile_has_road(const struct tile *ptile, const struct road_type *proad)
Definition tile.c:845
#define tile_terrain(_tile)
Definition tile.h:115
#define tile_has_extra(ptile, pextra)
Definition tile.h:152
#define tile_owner(_tile)
Definition tile.h:97
#define unit_owner(_pu)
Definition unit.h:407
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:126