Freeciv-3.3
Loading...
Searching...
No Matches
terrain.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2003 - The Freeciv Project
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/* utility */
19#include "fcintl.h"
20#include "log.h" /* fc_assert */
21#include "mem.h" /* free */
22#include "rand.h"
23#include "shared.h"
24#include "string_vector.h"
25#include "support.h"
26
27/* common */
28#include "extras.h"
29#include "game.h"
30#include "map.h"
31#include "rgbcolor.h"
32#include "road.h"
33
34#include "terrain.h"
35
38
39/**********************************************************************/
42void terrains_init(void)
43{
44 int i;
45
46 for (i = 0; i < ARRAY_SIZE(civ_terrains); i++) {
47 int j;
48
49 /* Can't use terrain_by_number here because it does a bounds check. */
54
55 for (j = 0; j < MAX_EXTRA_TYPES; j++) {
57 }
58 }
59}
60
61/**********************************************************************/
64void terrains_free(void)
65{
66 terrain_type_iterate(pterrain) {
67 if (NULL != pterrain->helptext) {
68 strvec_destroy(pterrain->helptext);
69 pterrain->helptext = NULL;
70 }
71 if (pterrain->resources != NULL) {
72 /* Server allocates this on ruleset loading, client when
73 * ruleset packet is received. */
74 free(pterrain->resources);
75 pterrain->resources = NULL;
76 }
77 if (pterrain->resource_freq != NULL) {
78 /* Server allocates this on ruleset loading, client when
79 * ruleset packet is received. */
80 free(pterrain->resource_freq);
81 pterrain->resource_freq = NULL;
82 }
83 if (pterrain->rgb != NULL) {
84 /* Server allocates this on ruleset loading, client when
85 * ruleset packet is received. */
86 rgbcolor_destroy(pterrain->rgb);
87 pterrain->rgb = NULL;
88 }
90}
91
92/**********************************************************************/
96{
97 if (game.control.terrain_count > 0) {
98 return civ_terrains;
99 }
100 return NULL;
101}
102
103/**********************************************************************/
106const struct terrain *terrain_array_last(void)
107{
108 if (game.control.terrain_count > 0) {
110 }
111 return NULL;
112}
113
114/**********************************************************************/
121
122/**********************************************************************/
125char terrain_identifier(const struct terrain *pterrain)
126{
127 fc_assert_ret_val(pterrain, '\0');
128 return pterrain->identifier;
129}
130
131/**********************************************************************/
137Terrain_type_id terrain_index(const struct terrain *pterrain)
138{
139 fc_assert_ret_val(pterrain, -1);
140 return pterrain - civ_terrains;
141}
142
143/**********************************************************************/
147{
148 fc_assert_ret_val(pterrain, -1);
149 return pterrain->item_number;
150}
151
152/**********************************************************************/
156{
158 /* This isn't an error; some T_UNKNOWN callers depend on it. */
159 return NULL;
160 }
161 return &civ_terrains[type];
162}
163
164/**********************************************************************/
169{
171 return T_UNKNOWN;
172 }
173 terrain_type_iterate(pterrain) {
174 if (pterrain->identifier == identifier) {
175 return pterrain;
176 }
178
179 return T_UNKNOWN;
180}
181
182/**********************************************************************/
186{
187 const char *qname = Qn_(name);
188
189 terrain_type_iterate(pterrain) {
190 if (0 == fc_strcasecmp(terrain_rule_name(pterrain), qname)) {
191 return pterrain;
192 }
194
195 return T_UNKNOWN;
196}
197
198/**********************************************************************/
202{
203 terrain_type_iterate(pterrain) {
204 if (0 == strcmp(terrain_name_translation(pterrain), name)) {
205 return pterrain;
206 }
208
209 return T_UNKNOWN;
210}
211
212/**********************************************************************/
217{
218 int num = 0;
219 struct terrain *terr = NULL;
220
222 if (terrain_has_flag(pterr, flag)) {
223 num++;
224 if (fc_rand(num) == 1) {
225 terr = pterr;
226 }
227 }
229
230 return terr;
231}
232
233/**********************************************************************/
237const char *terrain_name_translation(const struct terrain *pterrain)
238{
239 return name_translation_get(&pterrain->name);
240}
241
242/**********************************************************************/
246const char *terrain_rule_name(const struct terrain *pterrain)
247{
248 return rule_name_get(&pterrain->name);
249}
250
251/**********************************************************************/
254bool terrain_has_resource(const struct terrain *pterrain,
255 const struct extra_type *presource)
256{
257 struct extra_type **r = pterrain->resources;
258
259 while (NULL != *r) {
260 if (*r == presource) {
261 return TRUE;
262 }
263 r++;
264 }
265 return FALSE;
266}
267
268/**********************************************************************/
272{
273 struct resource_type *presource;
274
275 presource = fc_malloc(sizeof(*presource));
276
277 pextra->data.resource = presource;
278
279 presource->self = pextra;
280
281 return presource;
282}
283
284/**********************************************************************/
288{
289 /* Resource structure itself is freed as part of extras destruction. */
290}
291
292/**********************************************************************/
295struct extra_type *resource_extra_get(const struct resource_type *presource)
296{
297 return presource->self;
298}
299
300/**********************************************************************/
304#define variable_adjc_iterate(nmap, center_tile, _tile, card_only) \
305{ \
306 enum direction8 *_tile##_list; \
307 int _tile##_count; \
308 \
309 if (card_only) { \
310 _tile##_list = MAP_CARDINAL_DIRS; \
311 _tile##_count = MAP_NUM_CARDINAL_DIRS; \
312 } else { \
313 _tile##_list = MAP_VALID_DIRS; \
314 _tile##_count = MAP_NUM_VALID_DIRS; \
315 } \
316 adjc_dirlist_iterate(nmap, center_tile, _tile, _tile##_dir, \
317 _tile##_list, _tile##_count) {
318
319#define variable_adjc_iterate_end \
320 } adjc_dirlist_iterate_end; \
321}
322
323/**********************************************************************/
327 const struct tile *ptile,
328 const struct terrain *pterrain,
329 bool check_self)
330{
331 if (pterrain == NULL) {
332 return FALSE;
333 }
334
336 if (tile_terrain(adjc_tile) == pterrain) {
337 return TRUE;
338 }
340
341 return check_self && ptile->terrain == pterrain;
342}
343
344/**********************************************************************/
348 const struct tile *ptile,
349 const struct terrain *pterrain,
350 bool check_self)
351{
352 if (pterrain == NULL) {
353 return FALSE;
354 }
355
356 adjc_iterate(nmap, ptile, adjc_tile) {
357 if (tile_terrain(adjc_tile) == pterrain) {
358 return TRUE;
359 }
361
362 return check_self && ptile->terrain == pterrain;
363}
364
365/**********************************************************************/
369 const struct tile *ptile,
370 bool cardinal_only, bool percentage,
372{
373 int count = 0, total = 0;
374
376 struct terrain *pterrain = tile_terrain(adjc_tile);
377
378 if (pterrain->property[prop] > 0) {
379 count++;
380 }
381 total++;
383
384 if (percentage && count > 0) { /* Latter condition avoids div by zero */
385 count = count * 100 / total;
386 }
387
388 return count;
389}
390
391/**********************************************************************/
395 const struct tile *ptile,
396 const struct extra_type *pres,
397 bool check_self)
398{
399 if (pres == NULL) {
400 return FALSE;
401 }
402
404 if (tile_resource(adjc_tile) == pres) {
405 return TRUE;
406 }
408
409 return check_self && tile_resource(ptile) == pres;
410}
411
412/**********************************************************************/
416 const struct tile *ptile,
417 const struct extra_type *pres,
418 bool check_self)
419{
420 if (pres == NULL) {
421 return FALSE;
422 }
423
424 adjc_iterate(nmap, ptile, adjc_tile) {
425 if (tile_resource(adjc_tile) == pres) {
426 return TRUE;
427 }
429
430 return check_self && tile_resource(ptile) == pres;
431}
432
433/**********************************************************************/
438 const struct tile *ptile,
439 enum terrain_flag_id flag)
440{
442 struct terrain* pterrain = tile_terrain(adjc_tile);
443
444 if (T_UNKNOWN != pterrain
445 && terrain_has_flag(pterrain, flag)) {
446 return TRUE;
447 }
449
450 return FALSE;
451}
452
453/**********************************************************************/
458 const struct tile *ptile,
459 enum terrain_flag_id flag)
460{
461 adjc_iterate(nmap, ptile, adjc_tile) {
462 struct terrain* pterrain = tile_terrain(adjc_tile);
463
464 if (T_UNKNOWN != pterrain
465 && terrain_has_flag(pterrain, flag)) {
466 return TRUE;
467 }
469
470 return FALSE;
471}
472
473/**********************************************************************/
478 const struct tile *ptile,
479 bool cardinal_only, bool percentage,
480 enum terrain_flag_id flag)
481{
482 int count = 0, total = 0;
483
485 struct terrain *pterrain = tile_terrain(adjc_tile);
486
487 if (T_UNKNOWN != pterrain
488 && terrain_has_flag(pterrain, flag)) {
489 count++;
490 }
491 total++;
493
494 if (percentage && count > 0) { /* Latter condition avoids div by zero */
495 count = count * 100 / total;
496 }
497
498 return count;
499}
500
501/**********************************************************************/
508{
509 static char s[256];
510 char *p;
511 int len;
512
513 s[0] = '\0';
514
515 extra_type_iterate(pextra) {
516 if (pextra->category == ECAT_INFRA
517 && BV_ISSET(extras, extra_index(pextra))) {
518 bool hidden = FALSE;
519
520 extra_type_iterate(top) {
521 int topi = extra_index(top);
522
523 if (BV_ISSET(pextra->hidden_by, topi)
524 && BV_ISSET(extras, topi)) {
525 hidden = TRUE;
526 break;
527 }
529
530 if (!hidden) {
531 cat_snprintf(s, sizeof(s), "%s/", extra_name_translation(pextra));
532 }
533 }
535
536 len = strlen(s);
537 p = s + len - 1;
538 if (len > 0 && *p == '/') {
539 *p = '\0';
540 }
541
542 return s;
543}
544
545/**********************************************************************/
550{
551 /* Semi-arbitrary preference order reflecting previous behavior */
552 static const enum extra_cause prefs[] = {
554 EC_MINE,
555 EC_BASE,
556 EC_ROAD,
557 EC_HUT,
562 EC_NONE
563 };
564 int i;
565
566 for (i = 0; i < ARRAY_SIZE(prefs); i++) {
569 && BV_ISSET(extras, extra_index(pextra))) {
570 return pextra;
571 }
573 }
574
575 return NULL;
576}
577
578/**********************************************************************/
582{
583 return pterrain->tclass;
584}
585
586/**********************************************************************/
591 const struct tile *ptile,
592 enum terrain_class tclass)
593{
595 struct terrain* pterrain = tile_terrain(adjc_tile);
596
597 if (pterrain != T_UNKNOWN) {
598 if (terrain_type_terrain_class(pterrain) == tclass) {
599 return TRUE;
600 }
601 }
603
604 return FALSE;
605}
606
607/**********************************************************************/
612 const struct tile *ptile,
614{
615 adjc_iterate(nmap, ptile, adjc_tile) {
616 struct terrain* pterrain = tile_terrain(adjc_tile);
617
618 if (pterrain != T_UNKNOWN) {
619 if (terrain_type_terrain_class(pterrain) == tclass) {
620 return TRUE;
621 }
622 }
624
625 return FALSE;
626}
627
628/**********************************************************************/
633 const struct tile *ptile,
634 bool cardinal_only, bool percentage,
636{
637 int count = 0, total = 0;
638
640 struct terrain *pterrain = tile_terrain(adjc_tile);
641
642 if (T_UNKNOWN != pterrain
643 && terrain_type_terrain_class(pterrain) == tclass) {
644 count++;
645 }
646 total++;
648
649 if (percentage && count > 0) { /* Latter condition avoids div by zero */
650 count = count * 100 / total;
651 }
652
653 return count;
654}
655
656/**********************************************************************/
661{
663 return NULL;
664 }
665
666 return _(terrain_class_name(tclass));
667}
668
669/**********************************************************************/
672bool terrain_can_support_alteration(const struct terrain *pterrain,
674{
675 switch (alter) {
676 case TA_CAN_IRRIGATE:
677 return (pterrain->irrigation_time > 0);
678 case TA_CAN_MINE:
679 return (pterrain->mining_time > 0);
680 case TA_CAN_ROAD:
681 return (pterrain->road_time > 0);
682 case TA_CAN_BASE:
683 return (pterrain->base_time > 0);
684 case TA_CAN_PLACE:
685 return (pterrain->placing_time > 0);
686 default:
687 break;
688 }
689
691
692 return FALSE;
693}
694
695/**********************************************************************/
698int terrain_extra_build_time(const struct terrain *pterrain,
699 enum unit_activity activity,
700 const struct extra_type *tgt)
701{
702 int factor;
703
704 if (tgt != NULL && tgt->build_time != 0) {
705 /* Extra specific build time */
706 return tgt->build_time;
707 }
708
709 if (tgt == NULL) {
710 factor = 1;
711 } else {
712 factor = tgt->build_time_factor;
713 }
714
715 /* Terrain and activity specific build time */
716 switch (activity) {
717 case ACTIVITY_BASE:
718 return pterrain->base_time * factor;
720 return pterrain->road_time * factor;
722 return pterrain->irrigation_time * factor;
723 case ACTIVITY_MINE:
724 return pterrain->mining_time * factor;
725 default:
727 return 0;
728 }
729}
730
731/**********************************************************************/
734int terrain_extra_removal_time(const struct terrain *pterrain,
735 enum unit_activity activity,
736 const struct extra_type *tgt)
737{
738 int factor;
739
740 if (tgt->removal_time != 0) {
741 /* Extra specific removal time */
742 return tgt->removal_time;
743 }
744
745 factor = tgt->removal_time_factor;
746
747 /* Terrain and activity specific removal time */
748 switch (activity) {
749 case ACTIVITY_CLEAN:
750 return pterrain->extra_removal_times[extra_index(tgt)] * factor;
751 case ACTIVITY_PILLAGE:
752 return pterrain->pillage_time * factor;
753 default:
755
756 return 0;
757 }
758}
759
760/**********************************************************************/
764{
765 int i;
766
767 for (i = 0; i < MAX_NUM_USER_TER_FLAGS; i++) {
769 }
770}
771
772/**********************************************************************/
776{
777 int i;
778
779 for (i = 0; i < MAX_NUM_USER_TER_FLAGS; i++) {
781 }
782}
783
784/**********************************************************************/
788 const char *helptxt)
789{
790 int tfid = id - TER_USER_1;
791
792 fc_assert_ret(id >= TER_USER_1 && id <= TER_USER_LAST);
793
797 }
798
799 if (name && name[0] != '\0') {
801 }
802
803 if (user_terrain_flags[tfid].helptxt != NULL) {
806 }
807
808 if (helptxt && helptxt[0] != '\0') {
810 }
811}
812
813/**********************************************************************/
817{
819 return NULL;
820 }
821
823}
824
825/**********************************************************************/
829{
830 fc_assert(id >= TER_USER_1 && id <= TER_USER_LAST);
831
833}
#define BV_ISSET(bv, bit)
Definition bitvector.h:86
char * incite_cost
Definition comments.c:76
static struct extra_type extras[MAX_EXTRA_TYPES]
Definition extras.c:31
bool is_extra_removed_by(const struct extra_type *pextra, enum extra_rmcause rmcause)
Definition extras.c:353
const char * extra_name_translation(const struct extra_type *pextra)
Definition extras.c:194
#define extra_type_by_cause_iterate_rev(_cause, _extra)
Definition extras.h:344
#define extra_type_by_cause_iterate_rev_end
Definition extras.h:349
#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
int Terrain_type_id
Definition fc_types.h:233
#define EC_NONE
Definition fc_types.h:820
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
#define _(String)
Definition fcintl.h:67
#define Qn_(String)
Definition fcintl.h:89
void user_flag_init(struct user_flag *flag)
Definition game.c:829
void user_flag_free(struct user_flag *flag)
Definition game.c:838
struct civ_game game
Definition game.c:61
GType type
Definition repodlgs.c:1313
const char * name
Definition inputfile.c:127
#define fc_assert_ret(condition)
Definition log.h:192
#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_FREE(ptr)
Definition mem.h:41
#define fc_strdup(str)
Definition mem.h:43
#define fc_malloc(sz)
Definition mem.h:34
static const char * rule_name_get(const struct name_translation *ptrans)
static const char * name_translation_get(const struct name_translation *ptrans)
int len
Definition packhand.c:127
#define fc_rand(_size)
Definition rand.h:56
void rgbcolor_destroy(struct rgbcolor *prgbcolor)
Definition rgbcolor.c:74
#define ARRAY_SIZE(x)
Definition shared.h:85
void strvec_destroy(struct strvec *psv)
struct packet_ruleset_control control
Definition game.h:83
struct resource_type * resource
Definition extras.h:156
int removal_time
Definition extras.h:120
int build_time_factor
Definition extras.h:119
struct extra_type::@26 data
int removal_time_factor
Definition extras.h:121
int build_time
Definition extras.h:118
struct extra_type * self
Definition terrain.h:56
int placing_time
Definition terrain.h:120
int property[MG_COUNT]
Definition terrain.h:147
struct extra_type ** resources
Definition terrain.h:97
int item_number
Definition terrain.h:76
int road_time
Definition terrain.h:106
struct name_translation name
Definition terrain.h:77
int pillage_time
Definition terrain.h:125
int mining_time
Definition terrain.h:118
struct rgbcolor * rgb
Definition terrain.h:155
enum terrain_class tclass
Definition terrain.h:90
int extra_removal_times[MAX_EXTRA_TYPES]
Definition terrain.h:128
int irrigation_time
Definition terrain.h:115
int base_time
Definition terrain.h:105
void * ruledit_dlg
Definition terrain.h:79
char identifier
Definition terrain.h:84
bool ruledit_disabled
Definition terrain.h:78
Definition tile.h:50
struct terrain * terrain
Definition tile.h:57
char * name
Definition game.h:74
char * helptxt
Definition game.h:75
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:186
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:986
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
int terrain_extra_removal_time(const struct terrain *pterrain, enum unit_activity activity, const struct extra_type *tgt)
Definition terrain.c:734
void user_terrain_flags_init(void)
Definition terrain.c:763
void terrains_free(void)
Definition terrain.c:64
struct terrain * terrain_by_rule_name(const char *name)
Definition terrain.c:185
bool is_terrain_class_near_tile(const struct civ_map *nmap, const struct tile *ptile, enum terrain_class tclass)
Definition terrain.c:611
char terrain_identifier(const struct terrain *pterrain)
Definition terrain.c:125
Terrain_type_id terrain_count(void)
Definition terrain.c:117
void terrains_init(void)
Definition terrain.c:42
struct extra_type * resource_extra_get(const struct resource_type *presource)
Definition terrain.c:295
int count_terrain_class_near_tile(const struct civ_map *nmap, const struct tile *ptile, bool cardinal_only, bool percentage, enum terrain_class tclass)
Definition terrain.c:632
bool is_terrain_class_card_near(const struct civ_map *nmap, const struct tile *ptile, enum terrain_class tclass)
Definition terrain.c:590
struct terrain * terrain_by_translated_name(const char *name)
Definition terrain.c:201
const char * terrain_class_name_translation(enum terrain_class tclass)
Definition terrain.c:660
int count_terrain_flag_near_tile(const struct civ_map *nmap, const struct tile *ptile, bool cardinal_only, bool percentage, enum terrain_flag_id flag)
Definition terrain.c:477
const char * get_infrastructure_text(bv_extras extras)
Definition terrain.c:507
const char * terrain_flag_id_name_cb(enum terrain_flag_id flag)
Definition terrain.c:816
Terrain_type_id terrain_index(const struct terrain *pterrain)
Definition terrain.c:137
bool is_resource_card_near(const struct civ_map *nmap, const struct tile *ptile, const struct extra_type *pres, bool check_self)
Definition terrain.c:394
const char * terrain_name_translation(const struct terrain *pterrain)
Definition terrain.c:237
#define variable_adjc_iterate(nmap, center_tile, _tile, card_only)
Definition terrain.c:304
struct terrain * terrain_array_first(void)
Definition terrain.c:95
struct terrain * rand_terrain_by_flag(enum terrain_flag_id flag)
Definition terrain.c:216
struct terrain * terrain_by_number(const Terrain_type_id type)
Definition terrain.c:155
bool terrain_can_support_alteration(const struct terrain *pterrain, enum terrain_alteration alter)
Definition terrain.c:672
bool is_terrain_card_near(const struct civ_map *nmap, const struct tile *ptile, const struct terrain *pterrain, bool check_self)
Definition terrain.c:326
const char * terrain_rule_name(const struct terrain *pterrain)
Definition terrain.c:246
bool is_resource_near_tile(const struct civ_map *nmap, const struct tile *ptile, const struct extra_type *pres, bool check_self)
Definition terrain.c:415
void resource_types_free(void)
Definition terrain.c:287
void user_terrain_flags_free(void)
Definition terrain.c:775
enum terrain_class terrain_type_terrain_class(const struct terrain *pterrain)
Definition terrain.c:581
const char * terrain_flag_helptxt(enum terrain_flag_id id)
Definition terrain.c:828
bool terrain_has_resource(const struct terrain *pterrain, const struct extra_type *presource)
Definition terrain.c:254
struct resource_type * resource_type_init(struct extra_type *pextra)
Definition terrain.c:271
bool is_terrain_flag_near_tile(const struct civ_map *nmap, const struct tile *ptile, enum terrain_flag_id flag)
Definition terrain.c:457
struct extra_type * get_preferred_pillage(bv_extras extras)
Definition terrain.c:549
void set_user_terrain_flag_name(enum terrain_flag_id id, const char *name, const char *helptxt)
Definition terrain.c:787
const struct terrain * terrain_array_last(void)
Definition terrain.c:106
static struct terrain civ_terrains[MAX_NUM_TERRAINS]
Definition terrain.c:36
int terrain_extra_build_time(const struct terrain *pterrain, enum unit_activity activity, const struct extra_type *tgt)
Definition terrain.c:698
static struct user_flag user_terrain_flags[MAX_NUM_USER_TER_FLAGS]
Definition terrain.c:37
Terrain_type_id terrain_number(const struct terrain *pterrain)
Definition terrain.c:146
struct terrain * terrain_by_identifier(const char identifier)
Definition terrain.c:168
bool is_terrain_flag_card_near(const struct civ_map *nmap, const struct tile *ptile, enum terrain_flag_id flag)
Definition terrain.c:437
int count_terrain_property_near_tile(const struct civ_map *nmap, const struct tile *ptile, bool cardinal_only, bool percentage, enum mapgen_terrain_property prop)
Definition terrain.c:368
#define variable_adjc_iterate_end
Definition terrain.c:319
bool is_terrain_near_tile(const struct civ_map *nmap, const struct tile *ptile, const struct terrain *pterrain, bool check_self)
Definition terrain.c:347
#define terrain_type_iterate(_p)
Definition terrain.h:267
#define T_UNKNOWN
Definition terrain.h:62
#define TERRAIN_UNKNOWN_IDENTIFIER
Definition terrain.h:88
#define terrain_type_iterate_end
Definition terrain.h:273
#define MAX_NUM_TERRAINS
Definition terrain.h:69
#define terrain_has_flag(terr, flag)
Definition terrain.h:177
#define MAX_NUM_USER_TER_FLAGS
Definition terrain.h:32
#define tile_resource(_tile)
Definition tile.h:103
#define tile_terrain(_tile)
Definition tile.h:115