Freeciv-3.4
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;
41 fc_assert_ret_val(ptile != nullptr, MAX_COLATITUDE / 2);
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/************************************************************************/
62static void set_sizes(double size, int Xratio, int Yratio)
63{
64 /* Some code in generator assumes even dimension, so this is set to 2.
65 * Future topologies may also require even dimensions. */
66 /* The generator works also for odd values; keep this here for autogenerated
67 * height and width. */
68 const int even = 2;
69
70 /* In iso-maps we need to double the map.ysize factor, since xsize is
71 * in native coordinates which are compressed 2x in the X direction. */
72 const int iso = MAP_IS_ISOMETRIC ? 2 : 1;
73
74 /* We have:
75 *
76 * 1000 * size = xsize * ysize
77 *
78 * And to satisfy the ratios and other constraints we set
79 *
80 * xsize = i_size * xratio * even
81 * ysize = i_size * yratio * even * iso
82 *
83 * For any value of "i_size". So with some substitution
84 *
85 * 1000 * size = i_size * i_size * xratio * yratio * even * even * iso
86 * i_size = sqrt(1000 * size / (xratio * yratio * even * even * iso))
87 *
88 * Make sure to round off i_size to preserve exact wanted ratios,
89 * that may be importante for some topologies.
90 */
91 const int i_size
92 = sqrt((float)(size)
93 / (float)(Xratio * Yratio * iso * even * even)) + 0.49;
94
95 /* Now build xsize and ysize value as described above. */
96 wld.map.xsize = Xratio * i_size * even;
97 wld.map.ysize = Yratio * i_size * even * iso;
98
99 /* Now make sure the size isn't too large for this ratio or the overall map
100 * size (MAP_INDEX_SIZE) is larger than the maximal allowed size
101 * (MAP_MAX_SIZE * 1000). If it is then decrease the size and try again. */
104 || MAP_INDEX_SIZE > MAP_MAX_SIZE * 1000) {
105 fc_assert(size > 100.0);
106 set_sizes(size - 100.0, Xratio, Yratio);
107 return;
108 }
109
110 /* If the ratio is too big for some topology the simplest way to avoid
111 * this error is to set the maximum size smaller for all topologies! */
112 if (wld.map.server.size * 1000 > size + 900.0) {
113 /* Warning when size is set uselessly big */
114 log_error("Requested size of %d is too big for this topology.",
116 }
117
118 /* xsize and ysize must be between MAP_MIN_LINEAR_SIZE and
119 * MAP_MAX_LINEAR_SIZE. */
122
123 log_normal(_("Creating a map of size %d x %d = %d tiles (%d requested)."),
125 (int) size);
126}
127
128/************************************************************************/
134static void get_ratios(int *x_ratio, int *y_ratio)
135{
138 /* Ratios for torus map. */
139 *x_ratio = 1;
140 *y_ratio = 1;
141 } else {
142 /* Ratios for classic map. */
143 *x_ratio = 3;
144 *y_ratio = 2;
145 }
146 } else {
148 /* Ratios for uranus map. */
149 *x_ratio = 2;
150 *y_ratio = 3;
151 } else {
152 /* Ratios for flat map. */
153 *x_ratio = 1;
154 *y_ratio = 1;
155 }
156 }
157}
158
159/************************************************************************/
165{
166 int sqsize;
167 double map_size;
168
169 /* The server behavior to create the map is defined by 'map.server.mapsize'.
170 * Calculate the xsize/ysize if it is not directly defined. */
171 if (autosize) {
172 int x_ratio, y_ratio;
173
174 switch (wld.map.server.mapsize) {
175 case MAPSIZE_XYSIZE:
176 wld.map.server.size = (float)(wld.map.xsize * wld.map.ysize) / 1000.0 + 0.5;
178 / (player_count() * 100));
179 log_normal(_("Creating a map of size %d x %d = %d tiles (map size: "
180 "%d)."), wld.map.xsize, wld.map.ysize, wld.map.xsize * wld.map.ysize,
182 break;
183
184 case MAPSIZE_PLAYER:
187
188 if (map_size < MAP_MIN_SIZE * 1000) {
190 map_size = MAP_MIN_SIZE * 1000;
191 log_normal(_("Map size calculated for %d (land) tiles per player "
192 "and %d player(s) too small. Setting map size to the "
193 "minimal size %d."), wld.map.server.tilesperplayer,
195 } else if (map_size > MAP_MAX_SIZE * 1000) {
197 map_size = MAP_MAX_SIZE * 1000;
198 log_normal(_("Map size calculated for %d (land) tiles per player "
199 "and %d player(s) too large. Setting map size to the "
200 "maximal size %d."), wld.map.server.tilesperplayer,
202 } else {
203 wld.map.server.size = (double) map_size / 1000.0 + 0.5;
204 log_normal(_("Setting map size to %d (approx. %d (land) tiles for "
205 "each of the %d player(s))."), wld.map.server.size,
207 }
210 break;
211
212 case MAPSIZE_FULLSIZE:
213 /* Set map.xsize and map.ysize based on map.size. */
217 / (player_count() * 100));
218 break;
219 }
220 } else {
221 wld.map.server.size = (double) map_num_tiles() / 1000.0 + 0.5;
223 / (player_count() * 100));
224 }
225
226 sqsize = get_sqsize();
227
228 /* Initialize the ICE_BASE_LEVEL */
229
230 /* If maps has strip like poles we get smaller poles
231 * (less playables than island poles)
232 * 5% for little maps
233 * 2% for big ones, if map.server.temperature == 50
234 * except if separate poles is set */
236 /* With separatepoles option strip poles are useless */
238 (MAX(0, 100 * COLD_LEVEL / 3 - 1 * MAX_COLATITUDE)
239 + 1 * MAX_COLATITUDE * sqsize) / (100 * sqsize);
240 } else {
241 /* Any way strip poles are not so playable as isle poles */
243 (MAX(0, 100 * COLD_LEVEL / 3 - 2 * MAX_COLATITUDE)
244 + 2 * MAX_COLATITUDE * sqsize) / (100 * sqsize);
245 }
246
247 /* Correction for single-pole and similar map types
248 * The pole should be the same size relative to world size,
249 * so the smaller the actual latitude range,
250 * the smaller the ice base level has to be.
251 * However: Don't scale down by more than a half. */
256 / (2 * MAP_MAX_LATITUDE));
257 }
258
259 if (wld.map.server.huts_absolute >= 0) {
262 }
263
265}
266
267/************************************************************************/
270int get_sqsize(void)
271{
272 int sqsize = sqrt(MAP_INDEX_SIZE / 1000);
273
274 return MAX(1, sqsize);
275}
char * incite_cost
Definition comments.c:77
#define CITY_MAP_DEFAULT_RADIUS
Definition fc_types.h:84
#define _(String)
Definition fcintl.h:67
struct world wld
Definition game.c:63
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define log_normal(message,...)
Definition log.h:108
#define log_error(message,...)
Definition log.h:104
int map_num_tiles(void)
Definition map.c:1161
void map_init_topology(struct civ_map *nmap)
Definition map.c:315
int map_signed_latitude(const struct tile *ptile)
Definition map.c:1701
bool is_singular_tile(const struct tile *ptile, int dist)
Definition map.c:1732
#define MAP_MAX_SIZE
Definition map.h:661
#define MAP_MAX_LATITUDE
Definition map.h:611
#define MAP_MAX_LINEAR_SIZE
Definition map.h:677
#define MAP_MIN_LINEAR_SIZE
Definition map.h:678
#define MAP_MIN_SIZE
Definition map.h:660
#define current_wrap_has_flag(flag)
Definition map.h:46
#define MAP_REAL_LATITUDE_RANGE(_nmap)
Definition map.h:627
@ 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:806
#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:79
int ysize
Definition map_types.h:79
enum mapsize_type mapsize
Definition map_types.h:101
int size
Definition map_types.h:102
int tilesperplayer
Definition map_types.h:103
int landpercent
Definition map_types.h:110
struct civ_map::@44::@46 server
int huts
Definition map_types.h:107
bool separatepoles
Definition map_types.h:114
int huts_absolute
Definition map_types.h:108
Definition tile.h:50
struct civ_map map
#define MAP_INDEX_SIZE
#define MAP_IS_ISOMETRIC