119 && (nat_x < dist || nat_x >=
wld.
map.
xsize - dist)) {
128 && (nat_y < dist || nat_y >=
wld.
map.
ysize - dist)) {
143 return index1->
dist - index2->dist;
155 - abs(index2->dx + index2->dy)
156 : abs(index1->
dy) - abs(index2->dy));
158 return (diff != 0 ? diff : index1->
dist - index2->dist);
170 - abs(index2->dx - index2->dy)
171 : abs(index1->
dx) - abs(index2->dx));
173 return (diff != 0 ? diff : index1->
dist - index2->dist);
205 #define fair_do_iso_hex_symetry2 fair_do_rotation
280 for (steps =
fc_rand(99) % 3; steps > 0; steps--) {
293 for (steps =
fc_rand(99) % 3; steps > 0; steps--) {
310 int startpos_team_id)
318 for (pstile = psource; pstile < smax_tile; pstile++) {
331 if (pttile ==
nullptr) {
354 for (pstile = psource; pstile < smax_tile; pstile++) {
395 for (i = 0; i < 10; i++) {
422 const struct iter_index *outwards_indices,
int startpos_team_id)
433 x = tx + outwards_indices[i].
dx;
434 y = ty + outwards_indices[i].
dy;
463 bool land_around =
false;
491 if (pftile2 !=
nullptr) {
521 if (pftile -
pmap == k) {
540 if (phut !=
nullptr) {
574 enum mapgen_terrain_property target;
575 enum mapgen_terrain_property prefer;
576 enum mapgen_terrain_property avoid;
578 {0, MG_TEMPERATE, MG_GREEN, MG_MOUNTAINOUS},
579 {0, MG_FOLIAGE, MG_TEMPERATE,
MG_UNUSED},
580 {0, MG_DRY, MG_TEMPERATE, MG_GREEN},
581 {0, MG_MOUNTAINOUS, MG_GREEN,
MG_UNUSED},
582 {0, MG_MOUNTAINOUS,
MG_UNUSED, MG_GREEN},
583 {0, MG_WET, MG_TEMPERATE, MG_FOLIAGE},
588 struct fair_tile *pftile, *pftile2, *pftile3;
590 const int sea_around_island =
592 const int sea_around_island_sq =
597 fantasy = (
size * 2) / 5;
602 land_tiles[0] = pftile;
605 log_debug(
"Generating an island with %d land tiles [fantasy=%d].",
size,
609 while (i < fantasy) {
610 pftile = land_tiles[
fc_rand(i)];
621 land_tiles[i++] = pftile2;
629 pftile = land_tiles[i -
fc_rand(fantasy) - 1];
640 land_tiles[i++] = pftile2;
646 for (i = 0; i < startpos_num;) {
665 for (i = 0; i <
size; i++) {
666 pftile = land_tiles[i];
674 }
while (
terrain[j].count == 0);
683 for (i = 0; i <
size; i++) {
686 sea_around_island_sq, ptile)
697 if (startpos_num > 0) {
713 int length_max = 3, length, l;
718 bool connectable_river_around, ocean_around;
722 for (i = 0; i < n; i++) {
736 connectable_river_around =
false;
737 ocean_around =
false;
740 if (pftile2 ==
nullptr) {
750 connectable_river_around =
true;
754 if (ocean_around || river_around > 1
755 || (river_around == 1 && !connectable_river_around)) {
759 if (connectable_river_around) {
770 dir = direction8_invalid();
779 for (l = 2; l < length_max; l++) {
782 if (pftile2 ==
nullptr
788 connectable_river_around =
false;
789 ocean_around =
false;
798 if (pftile3 ==
nullptr) {
809 connectable_river_around =
true;
813 if (river_around > 1 && !connectable_river_around) {
815 }
else if (ocean_around || connectable_river_around) {
820 if (finished &&
fc_rand(++dirs_num) == 0) {
826 if (pend ==
nullptr) {
830 log_debug(
"Make river from (%d, %d) to (%d, %d) [dir=%s, length=%d]",
839 if (pftile == pend) {
849 if (startpos_num > 0) {
866 pftile = pisland + i;
882 struct terrain *deepest_ocean =
885 int playermass, islandmass1, islandmass2, islandmass3;
887 int players_per_island = 1;
888 int teams_num = 0, team_players_num = 0, single_players_num = 0;
897 single_players_num++;
900 team_players_num += i;
908 &&
wld.
map.
server.team_placement == TEAM_PLACEMENT_CONTINENT) {
917 if (
wld.
map.
server.team_placement != TEAM_PLACEMENT_DISABLED) {
934 players_per_island = 3;
936 players_per_island = 2;
940 if (
wld.
map.
server.team_placement == TEAM_PLACEMENT_CONTINENT) {
945 if (players_per_island == 1) {
946 players_per_island = i;
947 }
else if (i != players_per_island) {
950 players_per_island = 1;
964 if (players_per_island == 1) {
974 ptile->extras_owner =
nullptr;
997 islandmass1 = (players_per_island * playermass * 7) / 10;
998 if (islandmass1 < min_island_size) {
999 islandmass1 = min_island_size;
1001 islandmass2 = (playermass * 2) / 10;
1002 if (islandmass2 < min_island_size) {
1003 islandmass2 = min_island_size;
1005 islandmass3 = playermass / 10;
1006 if (islandmass3 < min_island_size) {
1007 islandmass3 = min_island_size;
1010 qDebug(
"Creating a map with fair island generator");
1012 log_debug(
"players_per_island=%d", players_per_island);
1015 log_debug(
"teams_num=%d, team_players_num=%d, single_players_num=%d",
1016 teams_num, team_players_num, single_players_num);
1017 log_debug(
"playermass=%d, islandmass1=%d, islandmass2=%d, islandmass3=%d",
1018 playermass, islandmass1, islandmass2, islandmass3);
1022 while (--iter >= 0) {
1054 log_debug(
"Place main islands on the map.");
1057 if (
wld.
map.
server.team_placement != TEAM_PLACEMENT_DISABLED
1058 && team_players_num > 0) {
1061 outwards_indices[
wld.map.num_iterate_outwards_indices];
1062 int start_x[teams_num], start_y[teams_num];
1068 sizeof(outwards_indices));
1070 case TEAM_PLACEMENT_DISABLED:
1073 case TEAM_PLACEMENT_CLOSEST:
1074 case TEAM_PLACEMENT_CONTINENT:
1078 outwards_indices[j].
dx, outwards_indices[j].
dy);
1083 case TEAM_PLACEMENT_HORIZONTAL:
1087 case TEAM_PLACEMENT_VERTICAL:
1100 for (j = 0; j < teams_num; j++) {
1101 start_x[j] = (
wld.
map.
xsize * (2 * j + 1)) / (2 * teams_num) +
dx;
1102 start_y[j] = (
wld.
map.
ysize * (2 * j + 1)) / (2 * teams_num) +
dy;
1117 int members_count = player_list_size(
team_members(pteam));
1121 if (members_count <= 1) {
1127 qDebug(
"Team %d (%s) will start on (%d, %d)", team_id,
1130 for (k = 0; k < members_count; k += players_per_island) {
1132 outwards_indices, team_id)) {
1133 qDebug(
"Failed to place island number %d for team %d (%s).", k,
1147 fc_assert(!done || i == team_players_num);
1154 qDebug(
"Failed to place island number %d.", i);
1164 log_debug(
"Create and place small islands on the map.");
1168 qDebug(
"Failed to place small island2 number %d.", i);
1180 qDebug(
"Failed to place small island3 number %d.", i);
1197 islandmass1 = (islandmass1 * 99) / 100;
1198 if (islandmass1 < min_island_size) {
1199 islandmass1 = min_island_size;
1201 islandmass2 = (islandmass2 * 99) / 100;
1202 if (islandmass2 < min_island_size) {
1203 islandmass2 = min_island_size;
1205 islandmass3 = (islandmass3 * 99) / 100;
1206 if (islandmass3 < min_island_size) {
1207 islandmass3 = min_island_size;
1212 qDebug(
"Failed to create map after %d iterations.", iter);
1238 ptile->extras = pftile->
extras;
1262 qDebug(
"Fair island map created with success!");
bool BV_ISSET(const BV &bv, int bit)
#define CITY_MAP_DEFAULT_RADIUS
#define CITY_MAP_DEFAULT_RADIUS_SQ
static int fair_team_placement_vertical(const void *a, const void *b)
Compare two iter_index values for doing vertical team placement.
static struct fair_tile * fair_map_pos_tile(struct fair_tile *pmap, int x, int y)
Get the tile at the position ('x', 'y').
static void fair_do_symetry2(int *x, int *y)
Symetry matrix.
static void fair_map_make_resources(struct fair_tile *pmap)
Add resources on 'pmap'.
static void fair_do_iso_hex_symetry1(int *x, int *y)
Symetry matrix for hexgonal-isometric topology.
static void fair_geometry_rand(struct fair_geometry_data *data)
Push random transformations to 'data'.
void(* fair_geometry_func)(int *x, int *y)
static void fair_do_geometry(const struct fair_geometry_data *data, int *x, int *y)
Perform transformations defined into 'data' to position ('x', 'y').
static void fair_map_destroy(struct fair_tile *pmap)
Free a map.
static bool fair_map_tile_border(struct fair_tile *pmap, struct fair_tile *ptile, int dist)
Returns whether 'ptile' is at least at 'dist' tiles (in real distance) to the border.
static void fair_map_tile_pos(struct fair_tile *pmap, struct fair_tile *ptile, int *x, int *y)
Get the coordinates of tile 'ptile'.
static void fair_do_hex_symetry1(int *x, int *y)
Symetry matrix for hexagonal topologies.
static void fair_do_hex_symetry2(int *x, int *y)
Symetry matrix for hexagonal topologies.
static struct fair_tile * fair_map_tile_step(struct fair_tile *pmap, struct fair_tile *ptile, enum direction8 dir)
Get the next tile in direction 'dir'.
#define fair_do_iso_hex_symetry2
static int fair_team_placement_horizontal(const void *a, const void *b)
Compare two iter_index values for doing horizontal team placement.
static struct fair_tile * fair_map_island_new(int size, int startpos_num)
Generate a map where an island would be placed in the center.
static void fair_do_rotation(int *x, int *y)
Rotation matrix, also symetry matrix for hexagonal-isometric topology.
static bool fair_map_place_island_rand(struct fair_tile *ptarget, struct fair_tile *psource)
Attempts to copy 'psource' to 'ptarget' at a random position, with random geometric effects.
static void fair_map_make_huts(struct fair_tile *pmap)
Add huts on 'pmap'.
bool map_generate_fair_islands()
Build a map using generator 'FAIR'.
static int fair_team_placement_closest(const void *a, const void *b)
Compare two iter_index values for doing closest team placement.
static void fair_do_iso_hex_rotation(int *x, int *y)
Rotation matrix for hexgonal-isometric topology.
static bool fair_map_place_island_team(struct fair_tile *ptarget, int tx, int ty, struct fair_tile *psource, const struct iter_index *outwards_indices, int startpos_team_id)
Attempts to copy 'psource' to 'ptarget' as close as possible of position 'x', 'y' for players of the ...
static bool fair_map_copy(struct fair_tile *ptarget, int tx, int ty, struct fair_tile *psource, const struct fair_geometry_data *data, int startpos_team_id)
Copy 'psource' on 'ptarget' at position ('tx', 'ty'), performing transformations defined into 'data'.
static void fair_do_symetry1(int *x, int *y)
Symetry matrix.
static void fair_do_hex_rotation(int *x, int *y)
Rotation matrix for hexgonal topology.
fair_tile_flag
Fair island generator types.
#define fc_assert(condition)
#define fc_assert_ret_val(condition, val)
#define log_debug(message,...)
int map_num_tiles()
Returns the total number of (real) positions (or tiles) on the map.
bool startpos_allows_all(const struct startpos *psp)
Returns TRUE if any nation can start here.
int map_vector_to_sq_distance(int dx, int dy)
Return the sq_distance for a given vector.
struct startpos * map_startpos_new(struct tile *ptile)
Create a new start position at the given tile and return it.
bool is_cardinal_dir(enum direction8 dir)
Returns TRUE iff the given direction is a cardinal one.
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Return the tile for the given index position.
bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
Allow the nation to start at the start position.
bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y)
If the position is real, it will be normalized and TRUE will be returned.
#define current_topo_has_flag(flag)
#define native_pos_to_index(nat_x, nat_y)
static int index_to_map_pos_y(int mindex)
#define square_iterate(nmap, center_tile, radius, tile_itr)
#define adjc_iterate(nmap, center_tile, itr_tile)
#define MAP_TO_NATIVE_POS(pnat_x, pnat_y, map_x, map_y)
#define NATIVE_TO_MAP_POS(pmap_x, pmap_y, nat_x, nat_y)
#define square_iterate_end
#define circle_iterate(nmap, center_tile, sq_radius, tile_itr)
static int index_to_map_pos_x(int mindex)
#define whole_map_iterate(_map, _tile)
#define index_to_native_pos(pnat_x, pnat_y, mindex)
#define whole_map_iterate_end
#define index_to_map_pos(pmap_x, pmap_y, mindex)
#define circle_iterate_end
#define DIRSTEP(dest_x, dest_y, dir)
void make_polar()
Add frozen tiles in the arctic zone.
struct extra_type * river_types[MAX_ROAD_TYPES]
struct terrain * pick_ocean(int depth, bool frozen)
Picks an ocean terrain to match the given depth.
struct terrain * pick_terrain_by_flag(enum terrain_flag_id flag)
Return a random terrain that has the specified flag.
struct terrain * pick_terrain(enum mapgen_terrain_property target, enum mapgen_terrain_property prefer, enum mapgen_terrain_property avoid)
Pick a terrain based on the target property and a property to avoid.
struct nation_type * nation_of_player(const struct player *pplayer)
Return the nation of a player.
int player_count()
Return the number of players.
#define player_list_iterate(playerlist, pplayer)
#define player_list_iterate_end
bool is_cardinal_only_road(const struct extra_type *pextra)
Is extra cardinal only road.
void array_shuffle(int *array, int n)
Randomize the elements of an array using the Fisher-Yates shuffle.
#define CLIP(lower, current, upper)
#define FC_WRAP(value, range)
enum direction8 valid_dirs[8]
int num_iterate_outwards_indices
struct iter_index * iterate_outwards_indices
enum direction8 cardinal_dirs[8]
struct civ_map::@39::@41 server
fair_geometry_func transform[4]
struct terrain * pterrain
enum fair_tile_flag flags
struct extra_type * presource
struct extra_type ** resources
struct team * team_by_number(const int team_id)
Return struct team pointer for the given team index.
const char * team_rule_name(const struct team *pteam)
Returns the name (untranslated) of the team.
int team_number(const struct team *pteam)
Return the team index/number/id.
const struct player_list * team_members(const struct team *pteam)
Returns the member list of the team.
#define teams_iterate_end
#define teams_iterate(_pteam)
#define TERRAIN_OCEAN_DEPTH_MINIMUM
#define TERRAIN_OCEAN_DEPTH_MAXIMUM
#define terrain_has_flag(terr, flag)
void tile_add_extra(struct tile *ptile, const struct extra_type *pextra)
Adds extra to tile.
void tile_set_terrain(struct tile *ptile, struct terrain *pterrain)
Set the given terrain at the specified tile.
void tile_virtual_destroy(struct tile *vtile)
Frees all memory used by the virtual tile, including freeing virtual units in the tile's unit list an...
void tile_set_owner(struct tile *ptile, struct player *pplayer, struct tile *claimer)
Set the owner of a tile (may be nullptr).
void tile_set_resource(struct tile *ptile, struct extra_type *presource)
Set the given resource at the specified tile.
void tile_set_continent(struct tile *ptile, Continent_id val)
Set the continent ID of the tile.
struct tile * tile_virtual_new(const struct tile *ptile)
Returns a virtual tile.
#define tile_resource(_tile)
#define tile_terrain(_tile)
static const bv_extras * tile_extras(const struct tile *ptile)