3 * Summary: Dungeon heightmap routines.
10 #include "dgn-height.h"
14 void dgn_initialise_heightmap(int height
)
16 env
.heightmap
.reset(new grid_heightmap
);
17 for (rectangle_iterator
ri(0); ri
; ++ri
)
18 dgn_height_at(*ri
) = height
;
21 int resolve_range(int_range range
, int nrolls
)
23 return random_range(range
.first
, range
.second
, nrolls
);
26 void dgn_island_centred_at(const coord_def
&c
,
29 int_range height_delta_range
,
35 dgn_island_centred_at(c
, n_points
, radius
,
36 int_range(-height_delta_range
.second
,
37 -height_delta_range
.first
),
42 for (int i
= 0; i
< n_points
; ++i
)
44 const int thisrad
= random2(1 + radius
);
45 const coord_def p
= dgn_random_point_from(c
, thisrad
, border_margin
);
47 dgn_height_at(p
) += resolve_range(height_delta_range
);
51 void dgn_smooth_height_at(coord_def c
, int radius
, int max_height
)
53 const int height
= dgn_height_at(c
);
54 if (max_height
!= DGN_UNDEFINED_HEIGHT
&& height
> max_height
)
57 const int max_delta
= radius
* radius
* 2 + 2;
60 for (int y
= c
.y
- radius
; y
<= c
.y
+ radius
; ++y
)
62 for (int x
= c
.x
- radius
; x
<= c
.x
+ radius
; ++x
)
64 const coord_def
p(x
, y
);
67 const int nheight
= dgn_height_at(p
);
68 if (max_height
!= DGN_UNDEFINED_HEIGHT
&& nheight
> max_height
)
70 const coord_def off
= c
- p
;
71 const int weight
= max_delta
- off
.abs();
73 total
+= nheight
* weight
;
76 dgn_height_at(c
) = total
/ divisor
;
79 void dgn_smooth_heights(int radius
, int npasses
)
81 for (int i
= 0; i
< npasses
; ++i
)
83 const int xspan
= GXM
/ 2, yspan
= GYM
/ 2;
84 for (int y
= yspan
- 1; y
>= 0; --y
)
85 for (int x
= xspan
- 1; x
>= 0; --x
)
87 dgn_smooth_height_at(coord_def(x
, y
), radius
);
88 dgn_smooth_height_at(coord_def(2 * xspan
- x
- 1, y
), radius
);
89 dgn_smooth_height_at(coord_def(x
, 2 * yspan
- y
- 1), radius
);
90 dgn_smooth_height_at(coord_def(2 * xspan
- x
- 1,
97 //////////////////////////////////////////////////////////////////////
100 void dgn_island_plan::build(int nislands
)
102 for (int i
= 0; i
< nislands
; ++i
)
106 coord_def
dgn_island_plan::pick_island_spot()
109 // Try to find a spot that's not too close to other islands; this
110 // is not a guarantee, though.
111 for (int i
= 0; i
< 15; ++i
)
113 // Primary island centres should have a little clearance
114 // around them, so use 2x the actual margin.
115 c
= dgn_random_point_in_margin(level_border_depth
* 2);
117 bool collides
= false;
118 for (int j
= 0, size
= islands
.size(); j
< size
; ++j
)
120 const coord_def island
= islands
[j
];
121 const coord_def dist
= island
- c
;
122 if (dist
.abs() < island_separation_dist2
)
131 islands
.push_back(c
);
135 void dgn_island_plan::build_island()
137 const coord_def c
= pick_island_spot();
138 dgn_island_centred_at(c
, resolve_range(n_island_centre_delta_points
),
139 resolve_range(island_centre_radius_range
),
140 island_centre_point_height_increment
,
142 x_chance_in_y(atoll_roll
, 100));
144 const int additional_heights
= resolve_range(n_aux_centres
);
145 for (int i
= 0; i
< additional_heights
; ++i
)
147 const int addition_offset
= resolve_range(aux_centre_offset_range
);
149 const coord_def offsetC
=
150 dgn_random_point_from(c
, addition_offset
, level_border_depth
);
151 if (!offsetC
.origin())
152 dgn_island_centred_at(
153 offsetC
, resolve_range(n_island_aux_delta_points
),
154 resolve_range(island_aux_radius_range
),
155 island_aux_point_height_increment
,
157 x_chance_in_y(atoll_roll
, 100));
161 coord_def
dgn_island_plan::pick_and_remove_random_island()
164 return coord_def(0, 0);
166 const int lucky_island
= random2(islands
.size());
167 const coord_def c
= islands
[lucky_island
];
168 islands
.erase(islands
.begin() + lucky_island
);