54
56
const int DIR_DX[8] = { -1, 0, 1, -1, 1, -1, 0, 1 };
55
57
const int DIR_DY[8] = { -1, -1, -1, 0, 0, 1, 1, 1 };
58
* (These must correspond to enum tile_special_type in terrain.h.)
60
static const char *tile_special_type_names[] =
77
59
/****************************************************************************
78
60
Return a bitfield of the specials on the tile that are infrastructure.
79
61
****************************************************************************/
80
enum tile_special_type get_tile_infrastructure_set(const struct tile *ptile)
82
return (ptile->special
83
& (S_ROAD | S_RAILROAD | S_IRRIGATION | S_FARMLAND | S_MINE
84
| S_FORTRESS | S_AIRBASE));
87
/***************************************************************
88
Return a (static) string with terrain name;
91
eg: "Hills (Coals) [Pollution]"
92
***************************************************************/
93
const char *map_get_tile_info_text(const struct tile *ptile)
97
struct tile_type *ptype = get_tile_type(ptile->terrain);
99
sz_strlcpy(s, ptype->terrain_name);
100
if (tile_has_special(ptile, S_RIVER)) {
102
sz_strlcat(s, get_special_name(S_RIVER));
106
if (tile_has_special(ptile, S_SPECIAL_1)) {
113
sz_strlcat(s, ptype->special_1_name);
115
if (tile_has_special(ptile, S_SPECIAL_2)) {
122
sz_strlcat(s, ptype->special_2_name);
129
if (tile_has_special(ptile, S_POLLUTION)) {
136
sz_strlcat(s, get_special_name(S_POLLUTION));
138
if (tile_has_special(ptile, S_FALLOUT)) {
145
sz_strlcat(s, get_special_name(S_FALLOUT));
62
bv_special get_tile_infrastructure_set(const struct tile *ptile,
68
BV_CLR_ALL(pspresent);
69
for (i = 0; infrastructure_specials[i] != S_LAST; i++) {
70
if (tile_has_special(ptile, infrastructure_specials[i])) {
71
BV_SET(pspresent, infrastructure_specials[i]);
154
81
/***************************************************************
479
396
void map_allocate(void)
481
398
freelog(LOG_DEBUG, "map_allocate (was %p) (%d,%d)",
482
map.tiles, map.xsize, map.ysize);
399
(void *)map.tiles, map.xsize, map.ysize);
484
401
assert(map.tiles == NULL);
485
map.tiles = fc_malloc(map.xsize * map.ysize * sizeof(struct tile));
402
map.tiles = fc_malloc(MAP_INDEX_SIZE * sizeof(*map.tiles));
404
/* Note this use of whole_map_iterate may be a bit sketchy, since the
405
* tile values (ptile->index, etc.) haven't been set yet. It might be
406
* better to do a manual loop here. */
486
407
whole_map_iterate(ptile) {
487
int index, nat_x, nat_y, map_x, map_y;
489
index = ptile - map.tiles;
490
index_to_native_pos(&nat_x, &nat_y, index);
491
index_to_map_pos(&map_x, &map_y, index);
493
CHECK_MAP_POS(map_x, map_y);
494
CHECK_NATIVE_POS(nat_x, nat_y);
496
/* HACK: these fields are declared const to keep anyone from changing
497
* them. But we have to set them somewhere! This should be the only
499
*(int *)&ptile->index = index;
500
*(int *)&ptile->x = map_x;
501
*(int *)&ptile->y = map_y;
502
*(int *)&ptile->nat_x = nat_x;
503
*(int *)&ptile->nat_y = nat_y;
408
ptile->index = ptile - map.tiles;
409
index_to_map_pos(&ptile->x, &ptile->y, ptile->index);
410
index_to_native_pos(&ptile->nat_x, &ptile->nat_y, ptile->index);
411
CHECK_INDEX(ptile->index);
412
CHECK_MAP_POS(ptile->x, ptile->y);
413
CHECK_NATIVE_POS(ptile->nat_x, ptile->nat_y);
505
415
tile_init(ptile);
506
416
} whole_map_iterate_end;
684
555
****************************************************************************/
685
556
bool is_safe_ocean(const struct tile *ptile)
687
adjc_iterate(ptile, tile1) {
688
Terrain_type_id ter = map_get_terrain(tile1);
689
if (!terrain_has_flag(ter, TER_UNSAFE_COAST) && ter != T_UNKNOWN) {
697
/***************************************************************
698
Returns whether you can put a city on land near enough to use
700
***************************************************************/
701
bool is_sea_usable(const struct tile *ptile)
703
map_city_radius_iterate(ptile, tile1) {
704
if (!is_ocean(map_get_terrain(tile1))) {
707
} map_city_radius_iterate_end;
712
/***************************************************************
714
***************************************************************/
715
int get_tile_food_base(const struct tile *ptile)
717
if (tile_has_special(ptile, S_SPECIAL_1))
718
return get_tile_type(ptile->terrain)->food_special_1;
719
else if (tile_has_special(ptile, S_SPECIAL_2))
720
return get_tile_type(ptile->terrain)->food_special_2;
722
return get_tile_type(ptile->terrain)->food;
725
/***************************************************************
727
***************************************************************/
728
int get_tile_shield_base(const struct tile *ptile)
730
if (tile_has_special(ptile, S_SPECIAL_1))
731
return get_tile_type(ptile->terrain)->shield_special_1;
732
else if(tile_has_special(ptile, S_SPECIAL_2))
733
return get_tile_type(ptile->terrain)->shield_special_2;
735
return get_tile_type(ptile->terrain)->shield;
738
/***************************************************************
740
***************************************************************/
741
int get_tile_trade_base(const struct tile *ptile)
743
if (tile_has_special(ptile, S_SPECIAL_1))
744
return get_tile_type(ptile->terrain)->trade_special_1;
745
else if (tile_has_special(ptile, S_SPECIAL_2))
746
return get_tile_type(ptile->terrain)->trade_special_2;
748
return get_tile_type(ptile->terrain)->trade;
751
/***************************************************************
752
Return a (static) string with special(s) name(s);
755
***************************************************************/
756
const char *map_get_infrastructure_text(enum tile_special_type spe)
763
/* Since railroad requires road, Road/Railroad is redundant */
764
if (contains_special(spe, S_RAILROAD))
765
cat_snprintf(s, sizeof(s), "%s/", _("Railroad"));
766
else if (contains_special(spe, S_ROAD))
767
cat_snprintf(s, sizeof(s), "%s/", _("Road"));
769
/* Likewise for farmland on irrigation */
770
if (contains_special(spe, S_FARMLAND))
771
cat_snprintf(s, sizeof(s), "%s/", _("Farmland"));
772
else if (contains_special(spe, S_IRRIGATION))
773
cat_snprintf(s, sizeof(s), "%s/", _("Irrigation"));
775
if (contains_special(spe, S_MINE))
776
cat_snprintf(s, sizeof(s), "%s/", _("Mine"));
778
if (contains_special(spe, S_FORTRESS))
779
cat_snprintf(s, sizeof(s), "%s/", _("Fortress"));
781
if (contains_special(spe, S_AIRBASE))
782
cat_snprintf(s, sizeof(s), "%s/", _("Airbase"));
784
p = s + strlen(s) - 1;
791
/****************************************************************************
792
Return the prerequesites needed before building the given infrastructure.
793
****************************************************************************/
794
enum tile_special_type map_get_infrastructure_prerequisite(enum tile_special_type spe)
796
enum tile_special_type prereq = S_NO_SPECIAL;
798
if (contains_special(spe, S_RAILROAD)) {
801
if (contains_special(spe, S_FARMLAND)) {
802
prereq |= S_IRRIGATION;
808
/***************************************************************
810
***************************************************************/
811
enum tile_special_type get_preferred_pillage(enum tile_special_type pset)
813
if (contains_special(pset, S_FARMLAND))
815
if (contains_special(pset, S_IRRIGATION))
817
if (contains_special(pset, S_MINE))
819
if (contains_special(pset, S_FORTRESS))
821
if (contains_special(pset, S_AIRBASE))
823
if (contains_special(pset, S_RAILROAD))
825
if (contains_special(pset, S_ROAD))
558
return count_terrain_flag_near_tile(ptile, FALSE, TRUE,
559
TER_UNSAFE_COAST) < 100;
830
562
/***************************************************************
832
564
***************************************************************/
833
565
bool is_water_adjacent_to_tile(const struct tile *ptile)
835
if (is_ocean(ptile->terrain)
836
|| tile_has_special(ptile, S_RIVER)
837
|| tile_has_special(ptile, S_IRRIGATION))
567
if (ptile->terrain != T_UNKNOWN
568
&& (is_ocean(ptile->terrain)
569
|| tile_has_special(ptile, S_RIVER)
570
|| tile_has_special(ptile, S_IRRIGATION))) {
840
574
cardinal_adjc_iterate(ptile, tile1) {
841
if (is_ocean(tile1->terrain)
842
|| tile_has_special(tile1, S_RIVER)
843
|| tile_has_special(tile1, S_IRRIGATION))
575
if (ptile->terrain != T_UNKNOWN
576
&& (is_ocean(tile1->terrain)
577
|| tile_has_special(tile1, S_RIVER)
578
|| tile_has_special(tile1, S_IRRIGATION))) {
845
581
} cardinal_adjc_iterate_end;
850
/***************************************************************
852
***************************************************************/
853
int map_build_road_time(const struct tile *ptile)
855
return get_tile_type(ptile->terrain)->road_time * ACTIVITY_FACTOR;
858
/***************************************************************
860
***************************************************************/
861
int map_build_irrigation_time(const struct tile *ptile)
863
return get_tile_type(ptile->terrain)->irrigation_time * ACTIVITY_FACTOR;
866
/***************************************************************
868
***************************************************************/
869
int map_build_mine_time(const struct tile *ptile)
871
return get_tile_type(ptile->terrain)->mining_time * ACTIVITY_FACTOR;
874
/***************************************************************
876
***************************************************************/
877
int map_transform_time(const struct tile *ptile)
879
return get_tile_type(ptile->terrain)->transform_time * ACTIVITY_FACTOR;
882
/***************************************************************
884
***************************************************************/
885
int map_build_rail_time(const struct tile *ptile)
887
return get_tile_type(ptile->terrain)->rail_time * ACTIVITY_FACTOR;
890
/***************************************************************
892
***************************************************************/
893
int map_build_airbase_time(const struct tile *ptile)
895
return get_tile_type(ptile->terrain)->airbase_time * ACTIVITY_FACTOR;
898
/***************************************************************
900
***************************************************************/
901
int map_build_fortress_time(const struct tile *ptile)
903
return get_tile_type(ptile->terrain)->fortress_time * ACTIVITY_FACTOR;
906
/***************************************************************
908
***************************************************************/
909
int map_clean_pollution_time(const struct tile *ptile)
911
return get_tile_type(ptile->terrain)->clean_pollution_time * ACTIVITY_FACTOR;
914
/***************************************************************
916
***************************************************************/
917
int map_clean_fallout_time(const struct tile *ptile)
919
return get_tile_type(ptile->terrain)->clean_fallout_time * ACTIVITY_FACTOR;
922
/***************************************************************
923
Time to complete given activity on given tile.
924
***************************************************************/
925
int map_activity_time(enum unit_activity activity, const struct tile *ptile)
928
case ACTIVITY_POLLUTION:
929
return map_clean_pollution_time(ptile);
931
return map_build_road_time(ptile);
933
return map_build_mine_time(ptile);
934
case ACTIVITY_IRRIGATE:
935
return map_build_irrigation_time(ptile);
936
case ACTIVITY_FORTRESS:
937
return map_build_fortress_time(ptile);
938
case ACTIVITY_RAILROAD:
939
return map_build_rail_time(ptile);
940
case ACTIVITY_TRANSFORM:
941
return map_transform_time(ptile);
942
case ACTIVITY_AIRBASE:
943
return map_build_airbase_time(ptile);
944
case ACTIVITY_FALLOUT:
945
return map_clean_fallout_time(ptile);
951
/***************************************************************
953
***************************************************************/
954
static void clear_infrastructure(struct tile *ptile)
956
map_clear_special(ptile, S_INFRASTRUCTURE_MASK);
959
/***************************************************************
961
***************************************************************/
962
static void clear_dirtiness(struct tile *ptile)
964
map_clear_special(ptile, S_POLLUTION | S_FALLOUT);
967
/***************************************************************
969
***************************************************************/
970
void map_irrigate_tile(struct tile *ptile)
972
Terrain_type_id now, result;
974
now = ptile->terrain;
975
result = get_tile_type(now)->irrigation_result;
978
if (map_has_special(ptile, S_IRRIGATION)) {
979
map_set_special(ptile, S_FARMLAND);
981
map_set_special(ptile, S_IRRIGATION);
983
} else if (result != T_NONE) {
984
map_set_terrain(ptile, result);
985
if (is_ocean(result)) {
986
clear_infrastructure(ptile);
987
clear_dirtiness(ptile);
989
/* FIXME: When rest of code can handle
990
* rivers in oceans, don't clear this! */
991
map_clear_special(ptile, S_RIVER);
993
reset_move_costs(ptile);
995
map_clear_special(ptile, S_MINE);
998
/***************************************************************
1000
***************************************************************/
1001
void map_mine_tile(struct tile *ptile)
1003
Terrain_type_id now, result;
1005
now = ptile->terrain;
1006
result = get_tile_type(now)->mining_result;
1008
if (now == result) {
1009
map_set_special(ptile, S_MINE);
1010
} else if (result != T_NONE) {
1011
map_set_terrain(ptile, result);
1012
if (is_ocean(result)) {
1013
clear_infrastructure(ptile);
1014
clear_dirtiness(ptile);
1016
/* FIXME: When rest of code can handle
1017
* rivers in oceans, don't clear this! */
1018
map_clear_special(ptile, S_RIVER);
1020
reset_move_costs(ptile);
1022
map_clear_special(ptile, S_FARMLAND);
1023
map_clear_special(ptile, S_IRRIGATION);
1026
/***************************************************************
1028
***************************************************************/
1029
void change_terrain(struct tile *ptile, Terrain_type_id type)
1031
map_set_terrain(ptile, type);
1032
if (is_ocean(type)) {
1033
clear_infrastructure(ptile);
1034
clear_dirtiness(ptile);
1035
map_clear_special(ptile, S_RIVER); /* FIXME: When rest of code can handle
1036
rivers in oceans, don't clear this! */
1039
reset_move_costs(ptile);
1041
/* Clear mining/irrigation if resulting terrain type cannot support
1042
that feature. (With current rules, this should only clear mines,
1043
but I'm including both cases in the most general form for possible
1044
future ruleset expansion. -GJW) */
1046
if (get_tile_type(type)->mining_result != type)
1047
map_clear_special(ptile, S_MINE);
1049
if (get_tile_type(type)->irrigation_result != type)
1050
map_clear_special(ptile, S_FARMLAND | S_IRRIGATION);
1053
/***************************************************************
1055
***************************************************************/
1056
void map_transform_tile(struct tile *ptile)
1058
Terrain_type_id now, result;
1060
now = ptile->terrain;
1061
result = get_tile_type(now)->transform_result;
1063
if (result != T_NONE) {
1064
change_terrain(ptile, result);
1068
586
/**************************************************************************
1069
587
This function returns true if the tile at the given location can be
1070
588
"reclaimed" from ocean into land. This is the case only when there are
1146
return(get_tile_type(t2->terrain)->movement_cost*SINGLE_MOVE);
684
return t2->terrain->movement_cost * SINGLE_MOVE;
1149
/***************************************************************
1150
tile_move_cost_ai is used to fill the move_cost array of struct
1151
tile. The cached values of this array are used in server/gotohand.c
1152
and client/goto.c. tile_move_cost_ai returns the move cost as
687
/****************************************************************************
688
map_move_cost_ai returns the move cost as
1153
689
calculated by tile_move_cost_ptrs (with no unit pointer to get
1154
690
unit-independent results) EXCEPT if either of the source or
1155
691
destination tile is an ocean tile. Then the result of the method
1156
692
shows if a ship can take the step from the source position to the
1157
693
destination position (return value is MOVE_COST_FOR_VALID_SEA_STEP)
1158
or not (return value is maxcost).
694
or not. An arbitrarily high value will be returned if the move is
1160
A ship can take the step if:
1161
- both tiles are ocean or
1162
- one of the tiles is ocean and the other is a city or is unknown
1163
***************************************************************/
1164
static int tile_move_cost_ai(struct tile *tile0, struct tile *tile1,
697
FIXME: this function can't be used for air units because it returns
698
sea<->land moves as impossible.
699
****************************************************************************/
700
int map_move_cost_ai(const struct tile *tile0, const struct tile *tile1)
702
const int maxcost = 72; /* Arbitrary. */
1167
704
assert(!is_server
1168
705
|| (tile0->terrain != T_UNKNOWN && tile1->terrain != T_UNKNOWN));
707
/* A ship can take the step if:
708
* - both tiles are ocean or
709
* - one of the tiles is ocean and the other is a city or is unknown
711
* Note tileX->terrain will only be T_UNKNOWN at the client. */
1170
712
if (is_ocean(tile0->terrain) && is_ocean(tile1->terrain)) {
1171
713
return MOVE_COST_FOR_VALID_SEA_STEP;
1191
736
/***************************************************************
1193
***************************************************************/
1194
static void debug_log_move_costs(const char *str, struct tile *tile0)
1196
/* the %x don't work so well for oceans, where
1197
move_cost[]==-3 ,.. --dwp
1199
freelog(LOG_DEBUG, "%s (%d, %d) [%x%x%x%x%x%x%x%x]", str,
1201
tile0->move_cost[0], tile0->move_cost[1],
1202
tile0->move_cost[2], tile0->move_cost[3],
1203
tile0->move_cost[4], tile0->move_cost[5],
1204
tile0->move_cost[6], tile0->move_cost[7]);
1207
/***************************************************************
1208
Recalculate tile->move_cost[] for (x,y), and for adjacent
1209
tiles in direction back to (x,y). That is, call this when
1210
something has changed on (x,y), eg roads, city, transform, etc.
1211
***************************************************************/
1212
void reset_move_costs(struct tile *ptile)
1214
int maxcost = 72; /* should be big enough without being TOO big */
1216
debug_log_move_costs("Resetting move costs for", ptile);
1218
/* trying to move off the screen is the default */
1219
memset(ptile->move_cost, maxcost, sizeof(ptile->move_cost));
1221
adjc_dir_iterate(ptile, tile1, dir) {
1222
ptile->move_cost[dir] = tile_move_cost_ai(ptile, tile1, maxcost);
1223
/* reverse: not at all obfuscated now --dwp */
1224
tile1->move_cost[DIR_REVERSE(dir)] =
1225
tile_move_cost_ai(tile1, ptile, maxcost);
1226
} adjc_dir_iterate_end;
1227
debug_log_move_costs("Reset move costs for", ptile);
1230
/***************************************************************
1231
Initialize tile->move_cost[] for all tiles, where move_cost[i]
1232
is the unit-independent cost to move _from_ that tile, to
1233
adjacent tile in direction specified by i.
1234
***************************************************************/
1235
void initialize_move_costs(void)
1237
int maxcost = 72; /* should be big enough without being TOO big */
1239
whole_map_iterate(ptile) {
1240
/* trying to move off the screen is the default */
1241
memset(ptile->move_cost, maxcost, sizeof(ptile->move_cost));
1243
adjc_dir_iterate(ptile, tile1, dir) {
1244
ptile->move_cost[dir] = tile_move_cost_ai(ptile, tile1, maxcost);
1246
adjc_dir_iterate_end;
1247
} whole_map_iterate_end;
1250
/***************************************************************
1251
737
The cost to move punit from where it is to tile x,y.
1252
738
It is assumed the move is a valid one, e.g. the tiles are adjacent.
1253
739
***************************************************************/
1267
753
/***************************************************************
1269
***************************************************************/
1270
Continent_id map_get_continent(const struct tile *ptile)
1272
return ptile->continent;
1275
/***************************************************************
1277
***************************************************************/
1278
void map_set_continent(struct tile *ptile, Continent_id val)
1280
ptile->continent = val;
1283
/***************************************************************
1285
***************************************************************/
1286
Terrain_type_id map_get_terrain(const struct tile *ptile)
1288
return ptile->terrain;
1291
/***************************************************************
1293
***************************************************************/
1294
void map_set_terrain(struct tile *ptile, Terrain_type_id ter)
1296
ptile->terrain = ter;
1299
/***************************************************************
1301
***************************************************************/
1302
enum tile_special_type map_get_special(const struct tile *ptile)
1304
return ptile->special;
1307
/***************************************************************
1308
Returns TRUE iff the given special is found at the given map
1310
***************************************************************/
1311
bool map_has_special(const struct tile *ptile, enum tile_special_type special)
1313
return contains_special(ptile->special, special);
1316
/***************************************************************
1317
Returns TRUE iff the given tile has the given special.
1318
***************************************************************/
1319
bool tile_has_special(const struct tile *ptile,
1320
enum tile_special_type special)
1322
return contains_special(ptile->special, special);
1325
/***************************************************************
1326
Returns TRUE iff the given special is found in the given set.
1327
***************************************************************/
1328
bool contains_special(enum tile_special_type set,
1329
enum tile_special_type to_test_for)
1331
enum tile_special_type masked = set & to_test_for;
1333
assert(0 == (int) S_NO_SPECIAL);
1336
* contains_special should only be called with one S_* in
1339
assert(masked == S_NO_SPECIAL || masked == to_test_for);
1341
return masked == to_test_for;
1344
/***************************************************************
1346
***************************************************************/
1347
void map_set_special(struct tile *ptile, enum tile_special_type spe)
1349
ptile->special |= spe;
1351
if (contains_special(spe, S_ROAD) || contains_special(spe, S_RAILROAD)) {
1352
reset_move_costs(ptile);
1356
/***************************************************************
1358
***************************************************************/
1359
void map_clear_special(struct tile *ptile, enum tile_special_type spe)
1361
ptile->special &= ~spe;
1363
if (contains_special(spe, S_ROAD) || contains_special(spe, S_RAILROAD)) {
1364
reset_move_costs(ptile);
1368
/***************************************************************
1369
Remove any specials which may exist at these map co-ordinates.
1370
***************************************************************/
1371
void map_clear_all_specials(struct tile *ptile)
1373
ptile->special = S_NO_SPECIAL;
1376
/***************************************************************
1378
***************************************************************/
1379
struct city *map_get_city(const struct tile *ptile)
1384
/***************************************************************
1386
***************************************************************/
1387
void map_set_city(struct tile *ptile, struct city *pcity)
1389
ptile->city = pcity;
1392
/***************************************************************
1393
754
Are (x1,y1) and (x2,y2) really the same when adjusted?
1394
755
This function might be necessary ALOT of places...
1395
756
***************************************************************/