Freeciv-3.2
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) {
266 if (!are_reqs_active(&context, tile_owner(ptile),
267 &proad->first_reqs, RPT_POSSIBLE)) {
268 return FALSE;
269 }
270 }
271 }
272
273 return are_reqs_active(&context, tile_owner(ptile),
274 &pextra->reqs, RPT_POSSIBLE);
275}
276
277/************************************************************************/
281 const struct road_type *proad,
282 const struct player *pplayer,
283 const struct tile *ptile)
284{
285 if (!can_build_extra_base(road_extra_get(proad), pplayer, ptile)) {
286 return FALSE;
287 }
288
289 return are_road_reqs_fulfilled(nmap, proad, pplayer, NULL, ptile);
290}
291
292/************************************************************************/
295bool can_build_road(const struct civ_map *nmap,
296 struct road_type *proad,
297 const struct unit *punit,
298 const struct tile *ptile)
299{
300 struct player *pplayer = unit_owner(punit);
301
302 if (!can_build_extra_base(road_extra_get(proad), pplayer, ptile)) {
303 return FALSE;
304 }
305
306 return are_road_reqs_fulfilled(nmap, proad, pplayer, punit, ptile);
307}
308
309/************************************************************************/
313int count_road_near_tile(struct civ_map *nmap, const struct tile *ptile,
314 const struct road_type *proad)
315{
316 int count = 0;
317
318 if (proad == NULL) {
319 return 0;
320 }
321
322 adjc_iterate(nmap, ptile, adjc_tile) {
324 count++;
325 }
327
328 return count;
329}
330
331/************************************************************************/
335 const struct tile *ptile,
336 const struct extra_type *priver)
337{
338 int count = 0;
339
341 if (priver == NULL && tile_has_river(adjc_tile)) {
342 /* Some river */
343 count++;
344 } else if (priver != NULL && tile_has_extra(adjc_tile, priver)) {
345 /* Specific river */
346 count++;
347 }
349
350 return count;
351}
352
353/************************************************************************/
357 const struct tile *ptile,
358 const struct extra_type *priver,
359 bool percentage)
360{
361 int count = 0;
362 int total = 0;
363
365
368 count++;
369 }
370 total++;
372
373 if (percentage && count > 0) { /* Latter condition avoids div by zero */
374 count = count * 100 / total;
375 }
376
377 return count;
378}
379
380/************************************************************************/
384 const struct tile *ptile,
385 const struct extra_type *priver,
386 bool percentage)
387{
388 int count = 0;
389 int total = 0;
390
392
393 adjc_iterate(nmap, ptile, adjc_tile) {
395 count++;
396 }
397 total++;
399
400 if (percentage && count > 0) { /* Latter condition avoids div by zero */
401 count = count * 100 / total;
402 }
403
404 return count;
405}
406
407/************************************************************************/
410bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
411{
412 return BV_ISSET(proad->flags, flag);
413}
414
415/************************************************************************/
420 const struct tile *ptile,
421 enum road_flag_id flag)
422{
424 if (road_has_flag(extra_road_get(pextra), flag)) {
426 if (tile_has_extra(adjc_tile, pextra)) {
427 return TRUE;
428 }
430 }
432
433 return FALSE;
434}
435
436/************************************************************************/
441 const struct tile *ptile,
442 enum road_flag_id flag)
443{
445 if (road_has_flag(extra_road_get(pextra), flag)) {
446 adjc_iterate(nmap, ptile, adjc_tile) {
447 if (tile_has_extra(adjc_tile, pextra)) {
448 return TRUE;
449 }
451 }
453
454 return FALSE;
455}
456
457/************************************************************************/
461 const struct tile *ptile)
462{
463 struct extra_type *pextra;
464
467 return FALSE;
468 }
469 } else if (tile_terrain(ptile)->road_time == 0) {
470 return FALSE;
471 }
472
473 pextra = road_extra_get(proad);
474
475 return are_reqs_active(&(const struct req_context) { .tile = ptile },
476 NULL,
477 &pextra->reqs, RPT_POSSIBLE);
478}
479
480/************************************************************************/
483bool is_cardinal_only_road(const struct extra_type *pextra)
484{
485 const struct road_type *proad;
486
487 if (!is_extra_caused_by(pextra, EC_ROAD)) {
488 return FALSE;
489 }
490
491 proad = extra_road_get(pextra);
492
493 return proad->move_mode == RMM_CARDINAL || proad->move_mode == RMM_RELAXED;
494}
495
496/************************************************************************/
500{
501 return proad->move_cost >= 0;
502}
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
char * roads
Definition comments.c:40
char * incite_cost
Definition comments.c:75
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:384
road_compat
Definition fc_types.h:1253
@ ROCO_NONE
Definition fc_types.h:1253
@ RPT_POSSIBLE
Definition fc_types.h:700
struct civ_game game
Definition game.c:62
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define adjc_iterate_end
Definition map.h:433
#define cardinal_adjc_iterate_end
Definition map.h:459
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:428
#define cardinal_adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:455
#define fc_malloc(sz)
Definition mem.h:34
bool are_reqs_active(const struct req_context *context, const struct player *other_player, 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:295
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:410
bool is_cardinal_only_road(const struct extra_type *pextra)
Definition road.c:483
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:440
bool road_provides_move_bonus(const struct road_type *proad)
Definition road.c:499
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:356
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:460
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:383
int count_river_near_tile(struct civ_map *nmap, const struct tile *ptile, const struct extra_type *priver)
Definition road.c:334
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:280
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:419
int count_road_near_tile(struct civ_map *nmap, const struct tile *ptile, const struct road_type *proad)
Definition road.c:313
static struct compatibility compat[]
Definition savecompat.c:105
struct packet_ruleset_control control
Definition game.h:83
struct road_type * road
Definition extras.h:155
struct extra_type::@25 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:138
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define terrain_has_flag(terr, flag)
Definition terrain.h:283
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:110
#define tile_has_extra(ptile, pextra)
Definition tile.h:147
#define tile_owner(_tile)
Definition tile.h:96
#define unit_owner(_pu)
Definition unit.h:396
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123