Freeciv-3.2
Loading...
Searching...
No Matches
mapgen_topology.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2004 - Marcelo J. Burda
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#ifdef HAVE_CONFIG_H
14#include <fc_config.h>
15#endif
16
17#include <math.h> /* sqrt */
18
19/* utility */
20#include "log.h"
21
22/* common */
23#include "game.h"
24#include "map.h"
25
26#include "mapgen_topology.h"
27
29
30/************************************************************************/
38int map_colatitude(const struct tile *ptile)
39{
40 int latitude;
42
43 latitude = map_signed_latitude(ptile);
44 latitude = MAX(latitude, -latitude);
45
46 return colat_from_abs_lat(latitude);
47}
48
49/************************************************************************/
53bool near_singularity(const struct tile *ptile)
54{
56}
57
58
59/************************************************************************/
63static void set_sizes(double size, int Xratio, int Yratio)
64{
65 /* Some code in generator assumes even dimension, so this is set to 2.
66 * Future topologies may also require even dimensions. */
67 /* The generator works also for odd values; keep this here for autogenerated
68 * height and width. */
69 const int even = 2;
70
71 /* In iso-maps we need to double the map.ysize factor, since xsize is
72 * in native coordinates which are compressed 2x in the X direction. */
73 const int iso = MAP_IS_ISOMETRIC ? 2 : 1;
74
75 /* We have:
76 *
77 * 1000 * size = xsize * ysize
78 *
79 * And to satisfy the ratios and other constraints we set
80 *
81 * xsize = i_size * xratio * even
82 * ysize = i_size * yratio * even * iso
83 *
84 * For any value of "i_size". So with some substitution
85 *
86 * 1000 * size = i_size * i_size * xratio * yratio * even * even * iso
87 * i_size = sqrt(1000 * size / (xratio * yratio * even * even * iso))
88 *
89 * Make sure to round off i_size to preserve exact wanted ratios,
90 * that may be importante for some topologies.
91 */
92 const int i_size
93 = sqrt((float)(size)
94 / (float)(Xratio * Yratio * iso * even * even)) + 0.49;
95
96 /* Now build xsize and ysize value as described above. */
97 wld.map.xsize = Xratio * i_size * even;
98 wld.map.ysize = Yratio * i_size * even * iso;
99
100 /* Now make sure the size isn't too large for this ratio or the overall map
101 * size (MAP_INDEX_SIZE) is larger than the maximal allowed size
102 * (MAP_MAX_SIZE * 1000). If it is then decrease the size and try again. */
105 || MAP_INDEX_SIZE > MAP_MAX_SIZE * 1000) {
106 fc_assert(size > 100.0);
107 set_sizes(size - 100.0, Xratio, Yratio);
108 return;
109 }
110
111 /* If the ratio is too big for some topology the simplest way to avoid
112 * this error is to set the maximum size smaller for all topologies! */
113 if (wld.map.server.size * 1000 > size + 900.0) {
114 /* Warning when size is set uselessly big */
115 log_error("Requested size of %d is too big for this topology.",
117 }
118
119 /* xsize and ysize must be between MAP_MIN_LINEAR_SIZE and
120 * MAP_MAX_LINEAR_SIZE. */
123
124 log_normal(_("Creating a map of size %d x %d = %d tiles (%d requested)."),
126 (int) size);
127}
128
129/************************************************************************/
135static void get_ratios(int *x_ratio, int *y_ratio)
136{
139 /* Ratios for torus map. */
140 *x_ratio = 1;
141 *y_ratio = 1;
142 } else {
143 /* Ratios for classic map. */
144 *x_ratio = 3;
145 *y_ratio = 2;
146 }
147 } else {
149 /* Ratios for uranus map. */
150 *x_ratio = 2;
151 *y_ratio = 3;
152 } else {
153 /* Ratios for flat map. */
154 *x_ratio = 1;
155 *y_ratio = 1;
156 }
157 }
158}
159
160/************************************************************************/
166{
167 int sqsize;
168 double map_size;
169
170 /* The server behavior to create the map is defined by 'map.server.mapsize'.
171 * Calculate the xsize/ysize if it is not directly defined. */
172 if (autosize) {
173 int x_ratio, y_ratio;
174
175 switch (wld.map.server.mapsize) {
176 case MAPSIZE_XYSIZE:
177 wld.map.server.size = (float)(wld.map.xsize * wld.map.ysize) / 1000.0 + 0.5;
179 / (player_count() * 100));
180 log_normal(_("Creating a map of size %d x %d = %d tiles (map size: "
181 "%d)."), wld.map.xsize, wld.map.ysize, wld.map.xsize * wld.map.ysize,
183 break;
184
185 case MAPSIZE_PLAYER:
188
189 if (map_size < MAP_MIN_SIZE * 1000) {
191 map_size = MAP_MIN_SIZE * 1000;
192 log_normal(_("Map size calculated for %d (land) tiles per player "
193 "and %d player(s) too small. Setting map size to the "
194 "minimal size %d."), wld.map.server.tilesperplayer,
196 } else if (map_size > MAP_MAX_SIZE * 1000) {
198 map_size = MAP_MAX_SIZE * 1000;
199 log_normal(_("Map size calculated for %d (land) tiles per player "
200 "and %d player(s) too large. Setting map size to the "
201 "maximal size %d."), wld.map.server.tilesperplayer,
203 } else {
204 wld.map.server.size = (double) map_size / 1000.0 + 0.5;
205 log_normal(_("Setting map size to %d (approx. %d (land) tiles for "
206 "each of the %d player(s))."), wld.map.server.size,
208 }
211 break;
212
213 case MAPSIZE_FULLSIZE:
214 /* Set map.xsize and map.ysize based on map.size. */
218 / (player_count() * 100));
219 break;
220 }
221 } else {
222 wld.map.server.size = (double) map_num_tiles() / 1000.0 + 0.5;
224 / (player_count() * 100));
225 }
226
227 sqsize = get_sqsize();
228
229 /* Initialize the ICE_BASE_LEVEL */
230
231 /* If maps has strip like poles we get smaller poles
232 * (less playables than island poles)
233 * 5% for little maps
234 * 2% for big ones, if map.server.temperature == 50
235 * except if separate poles is set */
237 /* With separatepoles option strip poles are useless */
239 (MAX(0, 100 * COLD_LEVEL / 3 - 1 * MAX_COLATITUDE)
240 + 1 * MAX_COLATITUDE * sqsize) / (100 * sqsize);
241 } else {
242 /* Any way strip poles are not so playable as isle poles */
244 (MAX(0, 100 * COLD_LEVEL / 3 - 2 * MAX_COLATITUDE)
245 + 2 * MAX_COLATITUDE * sqsize) / (100 * sqsize);
246 }
247
248 /* Correction for single-pole and similar map types
249 * The pole should be the same size relative to world size,
250 * so the smaller the actual latitude range,
251 * the smaller the ice base level has to be.
252 * However: Don't scale down by more than a half. */
257 / (2 * MAP_MAX_LATITUDE));
258 }
259
260 if (wld.map.server.huts_absolute >= 0) {
263 }
264
266}
267
268/************************************************************************/
271int get_sqsize(void)
272{
273 int sqsize = sqrt(MAP_INDEX_SIZE / 1000);
274
275 return MAX(1, sqsize);
276}
char * incite_cost
Definition comments.c:75
#define CITY_MAP_DEFAULT_RADIUS
Definition fc_types.h:82
#define _(String)
Definition fcintl.h:67
struct world wld
Definition game.c:63
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_normal(message,...)
Definition log.h:107
#define log_error(message,...)
Definition log.h:103
int map_num_tiles(void)
Definition map.c:1014
void map_init_topology(struct civ_map *nmap)
Definition map.c:303
int map_signed_latitude(const struct tile *ptile)
Definition map.c:1550
bool is_singular_tile(const struct tile *ptile, int dist)
Definition map.c:1581
#define MAP_MAX_SIZE
Definition map.h:624
#define MAP_MAX_LATITUDE
Definition map.h:574
#define MAP_MAX_LINEAR_SIZE
Definition map.h:640
#define MAP_INDEX_SIZE
Definition map.h:137
#define MAP_IS_ISOMETRIC
Definition map.h:42
#define MAP_MIN_LINEAR_SIZE
Definition map.h:641
#define MAP_MIN_SIZE
Definition map.h:623
#define current_wrap_has_flag(flag)
Definition map.h:51
#define MAP_REAL_LATITUDE_RANGE(_nmap)
Definition map.h:590
@ MAPSIZE_FULLSIZE
Definition map_types.h:39
@ MAPSIZE_PLAYER
Definition map_types.h:40
@ MAPSIZE_XYSIZE
Definition map_types.h:43
static void get_ratios(int *x_ratio, int *y_ratio)
void generator_init_topology(bool autosize)
int get_sqsize(void)
int ice_base_colatitude
static void set_sizes(double size, int Xratio, int Yratio)
int map_colatitude(const struct tile *ptile)
bool near_singularity(const struct tile *ptile)
#define colat_from_abs_lat(_lat)
#define COLD_LEVEL
#define MAX_COLATITUDE
int player_count(void)
Definition player.c:817
#define CLIP(lower, current, upper)
Definition shared.h:57
#define MAX(x, y)
Definition shared.h:54
size_t size
Definition specvec.h:72
int xsize
Definition map_types.h:78
int ysize
Definition map_types.h:78
enum mapsize_type mapsize
Definition map_types.h:88
struct civ_map::@42::@44 server
int size
Definition map_types.h:89
int tilesperplayer
Definition map_types.h:90
int landpercent
Definition map_types.h:97
int huts
Definition map_types.h:94
bool separatepoles
Definition map_types.h:101
int huts_absolute
Definition map_types.h:95
Definition tile.h:50
struct civ_map map