Freeciv-3.2
Loading...
Searching...
No Matches
fracture_map.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996-2016 - 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#ifdef HAVE_CONFIG_H
14#include <fc_config.h>
15#endif
16
17/* utility */
18#include "rand.h"
19
20/* common */
21#include "map.h"
22
23/* server/generator */
24#include "height_map.h"
25#include "mapgen_topology.h"
26#include "mapgen_utils.h"
27
28#include "fracture_map.h"
29
30static void circle_bresenham(int xc, int yc, int r, int nn);
31static void fmfill(int x, int y, int c, int r);
32static int local_ave_elevation(struct tile *ptile);
33
34extern int *height_map;
35int num_landmass = 50;
36
37typedef struct {
38 int x;
39 int y;
40} map_point;
41
42typedef struct {
43 int minX, minY;
44 int maxX, maxY;
47
48/* Landmass: a chunk of rock with common properties */
51
52/**********************************************************************/
56{
57 int nn, mm;
58 int rad;
59 int x,y;
60 struct tile *ptile1;
61
62 /* Calculate the mountain level. map.server.mountains specifies the
63 * percentage of land that is turned into hills and mountains. */
65 * (100 - wld.map.server.steepness))
66 / 100 + hmap_shore_level);
67
68 /* For larger maps, increase the number of landmasses - makes the map more interesting */
69 num_landmass = 20 + 15 * get_sqsize();
73
74 /* Setup a whole bunch of landmasses along the view bordere. These will be sunken
75 to create ocean terrain.*/
76 nn = 0;
77 for (x = 3; x < wld.map.xsize; x += 5, nn++) {
79 fracture_points[nn].y = 3;
80 }
81 for (x = 3; x < wld.map.xsize; x += 5, nn++) {
84 }
85 for (y = 3; y < wld.map.ysize; y += 5, nn++) {
86 fracture_points[nn].x = 3;
88 }
89 for (y = 3; y < wld.map.ysize; y += 5, nn++) {
92 }
93
94 /* pick remaining points randomly */
95 mm = nn;
96 for (; nn < mm + num_landmass; nn++) {
99 }
100 for (nn = 0; nn < mm + num_landmass; nn++) {
101 landmass[nn].minX = wld.map.xsize - 1;
102 landmass[nn].minY = wld.map.ysize - 1;
103 landmass[nn].maxX = 0;
104 landmass[nn].maxY = 0;
108 ptile1->continent = nn + 1;
109 }
110
111 /* Assign a base elevation to the landmass */
112 for (nn = 0; nn < mm + num_landmass; nn++) {
113 if (nn < mm) { /* sink the border masses */
114 landmass[nn].elevation = 0;
115 } else {
116 landmass[nn].elevation = fc_rand(1000);
117 }
118 }
119
120 /* Assign cells to landmass. Gradually expand the radius of the
121 fracture point. */
122 for (rad = 1; rad < (wld.map.xsize >> 1); rad++) {
123 for (nn = 0; nn < mm + num_landmass; nn++) {
125 }
126 }
127
128 /* put in some random fuzz */
129 whole_map_iterate(&(wld.map), ptile) {
130 if (hmap(ptile) > hmap_shore_level) {
131 hmap(ptile) = hmap(ptile) + fc_rand(4) - 2;
132 }
133 if (hmap(ptile) <= hmap_shore_level) {
134 hmap(ptile) = hmap_shore_level + 1;
135 }
137
139 free(landmass);
141}
142
143/**********************************************************************/
148static void circle_bresenham(int xc, int yc, int r, int nn)
149{
150 int x = 0;
151 int y = r;
152 int p = 3 - 2 * r;
153
154 if (!r) {
155 return;
156 }
157
158 while (y >= x) { /* only formulate 1/8 of circle */
159 fmfill(xc-x, yc-y, nn, r); /* upper left left */
160 fmfill(xc-y, yc-x, nn, r); /* upper upper left */
161 fmfill(xc+y, yc-x, nn, r); /* upper upper right */
162 fmfill(xc+x, yc-y, nn, r); /* upper right right */
163 fmfill(xc-x, yc+y, nn, r); /* lower left left */
164 fmfill(xc-y, yc+x, nn, r); /* lower lower left */
165 fmfill(xc+y, yc+x, nn, r); /* lower lower right */
166 fmfill(xc+x, yc+y, nn, r); /* lower right right */
167 if (p < 0) {
168 p += 4 * x++ + 6;
169 } else {
170 p += 4 * (x++ - y--) + 10;
171 }
172 }
173}
174
175/**********************************************************************/
179static void fmfill(int x, int y, int c, int r)
180{
181 int x_less, x_more, y_less, y_more;
182 struct tile *ptileXY;
183 struct tile *ptileX2Y;
184 struct tile *ptileX1Y;
185 struct tile *ptileXY2;
186 struct tile *ptileXY1;
187 struct tile *ptileX2Y1;
188 struct tile *ptileX2Y2;
189 struct tile *ptileX1Y2;
190 struct tile *ptileX1Y1;
191
192 if (x < 0) {
193 x = wld.map.xsize + x;
194 } else if (x > wld.map.xsize) {
195 x = x - wld.map.xsize;
196 }
197 x_less = x - 1;
198 if (x_less < 0) {
199 x_less = wld.map.xsize - 1;
200 }
201 x_more = x + 1;
202 if (x_more >= wld.map.xsize) {
203 x_more = 0;
204 }
205 y_less = y - 1;
206 if (y_less < 0) {
207 y_less = wld.map.ysize - 1;
208 }
209 y_more = y + 1;
210 if (y_more >= wld.map.ysize) {
211 y_more = 0;
212 }
213
214 if (y >= 0 && y < wld.map.ysize) {
224
225 if (ptileXY->continent == 0 ) {
226 ptileXY->continent = c;
227 ptileX2Y->continent = c;
228 ptileX1Y->continent = c;
229 ptileXY2->continent = c;
230 ptileXY1->continent = c;
231 ptileX2Y2->continent = c;
232 ptileX2Y1->continent = c;
233 ptileX1Y2->continent = c;
234 ptileX1Y1->continent = c;
244 /* This bit of code could track the maximum and minimum extent
245 * of the landmass. */
246 if (x < landmass[c-1].minX) {
247 landmass[c-1].minX = x;
248 }
249 if (x > landmass[c-1].maxX) {
250 landmass[c-1].maxX = x;
251 }
252 if (y < landmass[c-1].minY) {
253 landmass[c-1].minY = y;
254 }
255 if (y > landmass[c-1].maxY) {
256 landmass[c-1].maxY = y;
257 }
258 }
259 }
260}
261
262/**********************************************************************/
266static int local_ave_elevation(struct tile *ptile)
267{
268 int ele;
269 int n;
270
271 n = ele = 0;
272 square_iterate(&(wld.map), ptile, 3, tile2) {
273 ele = ele + hmap(tile2);
274 n++;
276
277 if (ele > 0) { /* Avoids div by zero, as means also that n > 0 */
278 ele /= n;
279 }
280
281 return ele;
282}
283
284/**********************************************************************/
293{
294 bool choose_mountain;
295 bool choose_hill;
296 int landarea;
297 int total_mtns;
298 int iter;
299
300 /* Compute the land area */
301 landarea = 0;
302 whole_map_iterate(&(wld.map), ptile) {
303 if (hmap(ptile) > hmap_shore_level) {
304 landarea++;
305 }
307
308 /* Iteration 1
309 Choose hills and mountains based on local elevation.
310 */
311 total_mtns = 0;
312 whole_map_iterate(&(wld.map), ptile) {
313 if (not_placed(ptile) && hmap(ptile) > hmap_shore_level) { /* Place on land only */
314 /* Mountains */
315 choose_mountain = (hmap(ptile) > local_ave_elevation(ptile) * 1.20)
316 || (area_is_too_flat(ptile, hmap_mountain_level, hmap(ptile)) && (fc_rand(10) < 4));
317
318 choose_hill = (hmap(ptile) > local_ave_elevation(ptile) * 1.10)
319 || (area_is_too_flat(ptile, hmap_mountain_level, hmap(ptile)) && (fc_rand(10) < 4));
320 /* The following avoids hills and mountains directly along the coast. */
321 if (count_terrain_class_near_tile(&(wld.map), ptile, TRUE, TRUE, TC_OCEAN) > 0) {
324 }
325 if (choose_mountain) {
326 total_mtns++;
328 map_set_placed(ptile);
329 } else if (choose_hill) {
330 /* hills */
331 total_mtns++;
333 map_set_placed(ptile);
334 }
335 }
337
338 /* Iteration 2
339 Make sure the map has at least the minimum number of mountains according to the
340 map steepness setting.
341 The iteration limit is a failsafe to prevent the iteration from taking forever.
342 */
343 for (iter = 0; total_mtns < (landarea * wld.map.server.steepness) / 100 && iter < 50;
344 iter++) {
345 whole_map_iterate(&(wld.map), ptile) {
346 if (not_placed(ptile) && hmap(ptile) > hmap_shore_level) { /* place on land only */
347 choose_mountain = fc_rand(10000) < 10;
348 choose_hill = fc_rand(10000) < 10;
349 if (choose_mountain) {
350 total_mtns++;
352 map_set_placed(ptile);
353 } else if (choose_hill) {
354 /* hills */
355 total_mtns++;
357 map_set_placed(ptile);
358 }
359 }
360 if (total_mtns >= landarea * wld.map.server.steepness / 100) {
361 break;
362 }
364 }
365}
#define n
Definition astring.c:77
char * incite_cost
Definition comments.c:75
void make_fracture_map(void)
static int local_ave_elevation(struct tile *ptile)
int num_landmass
void make_fracture_relief(void)
static void fmfill(int x, int y, int c, int r)
static map_landmass * landmass
static void circle_bresenham(int xc, int yc, int r, int nn)
static map_point * fracture_points
int * height_map
Definition height_map.c:29
int hmap_mountain_level
#define MG_UNUSED
int hmap_shore_level
Definition height_map.c:30
struct world wld
Definition game.c:63
bool area_is_too_flat(struct tile *ptile, int thill, int my_height)
Definition height_map.c:269
#define hmap_max_level
Definition height_map.h:33
#define hmap(_tile)
Definition height_map.h:17
struct tile * native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Definition map.c:443
#define MAP_INDEX_SIZE
Definition map.h:137
#define square_iterate(nmap, center_tile, radius, tile_itr)
Definition map.h:391
#define square_iterate_end
Definition map.h:394
#define whole_map_iterate(_map, _tile)
Definition map.h:545
#define whole_map_iterate_end
Definition map.h:554
int get_sqsize(void)
void map_set_placed(struct tile *ptile)
bool not_placed(const struct tile *ptile)
struct terrain * pick_terrain(enum mapgen_terrain_property target, enum mapgen_terrain_property prefer, enum mapgen_terrain_property avoid)
#define adjust_int_map(int_map, int_map_min, int_map_max)
#define fc_malloc(sz)
Definition mem.h:34
#define fc_rand(_size)
Definition rand.h:56
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
int xsize
Definition map_types.h:78
int ysize
Definition map_types.h:78
struct civ_map::@42::@44 server
int steepness
Definition map_types.h:105
Definition tile.h:50
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
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:633
void tile_set_terrain(struct tile *ptile, struct terrain *pterrain)
Definition tile.c:124