Skip to content

Commit c3e179f

Browse files
committedNov 9, 2015
Cavegen: Make mgfractal use mgv5 cavegen
Remove CaveFractal Add a lava depth constant to CaveV5 to make it universal
1 parent 63e7137 commit c3e179f

File tree

4 files changed

+15
-303
lines changed

4 files changed

+15
-303
lines changed
 

Diff for: ‎src/cavegen.cpp

+9-252
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2323
#include "mapgen_v5.h"
2424
#include "mapgen_v6.h"
2525
#include "mapgen_v7.h"
26-
#include "mapgen_fractal.h"
2726
#include "cavegen.h"
2827

2928
NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6, 2.0);
@@ -32,17 +31,18 @@ NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6, 2.0
3231
///////////////////////////////////////// Caves V5
3332

3433

35-
CaveV5::CaveV5(MapgenV5 *mg, PseudoRandom *ps)
34+
CaveV5::CaveV5(Mapgen *mg, PseudoRandom *ps)
3635
{
3736
this->mg = mg;
3837
this->vm = mg->vm;
3938
this->ndef = mg->ndef;
4039
this->water_level = mg->water_level;
4140
this->ps = ps;
42-
this->c_water_source = mg->c_water_source;
43-
this->c_lava_source = mg->c_lava_source;
44-
this->c_ice = mg->c_ice;
41+
c_water_source = ndef->getId("mapgen_water_source");
42+
c_lava_source = ndef->getId("mapgen_lava_source");
43+
c_ice = ndef->getId("mapgen_ice");
4544
this->np_caveliquids = &nparams_caveliquids;
45+
this->ystride = mg->csize.X;
4646

4747
dswitchint = ps->range(1, 14);
4848
flooded = ps->range(1, 2) == 2;
@@ -150,7 +150,7 @@ void CaveV5::makeTunnel(bool dirswitch)
150150
p = orpi + veci + of + rs / 2;
151151
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
152152
p.X >= node_min.X && p.X <= node_max.X) {
153-
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
153+
u32 index = (p.Z - node_min.Z) * ystride + (p.X - node_min.X);
154154
s16 h = mg->heightmap[index];
155155
if (h < p.Y)
156156
return;
@@ -161,7 +161,7 @@ void CaveV5::makeTunnel(bool dirswitch)
161161
p = orpi + of + rs / 2;
162162
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
163163
p.X >= node_min.X && p.X <= node_max.X) {
164-
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
164+
u32 index = (p.Z - node_min.Z) * ystride + (p.X - node_min.X);
165165
s16 h = mg->heightmap[index];
166166
if (h < p.Y)
167167
return;
@@ -215,7 +215,8 @@ void CaveV5::carveRoute(v3f vec, float f, bool randomize_xz)
215215

216216
float nval = NoisePerlin3D(np_caveliquids, startp.X,
217217
startp.Y, startp.Z, mg->seed);
218-
MapNode liquidnode = nval < 0.40 ? lavanode : waternode;
218+
MapNode liquidnode = (nval < 0.40 && node_max.Y < MGV5_LAVA_DEPTH) ?
219+
lavanode : waternode;
219220

220221
v3f fp = orp + vec * f;
221222
fp.X += 0.1 * ps->range(-10, 10);
@@ -808,247 +809,3 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz)
808809
}
809810
}
810811
}
811-
812-
813-
///////////////////////////////////////// Caves Fractal
814-
815-
816-
CaveFractal::CaveFractal(MapgenFractal *mg, PseudoRandom *ps)
817-
{
818-
this->mg = mg;
819-
this->vm = mg->vm;
820-
this->ndef = mg->ndef;
821-
this->water_level = mg->water_level;
822-
this->ps = ps;
823-
this->c_water_source = mg->c_water_source;
824-
this->c_lava_source = mg->c_lava_source;
825-
this->c_ice = mg->c_ice;
826-
this->np_caveliquids = &nparams_caveliquids;
827-
828-
dswitchint = ps->range(1, 14);
829-
flooded = ps->range(1, 2) == 2;
830-
831-
part_max_length_rs = ps->range(2, 4);
832-
tunnel_routepoints = ps->range(5, ps->range(15, 30));
833-
min_tunnel_diameter = 5;
834-
max_tunnel_diameter = ps->range(7, ps->range(8, 24));
835-
836-
large_cave_is_flat = (ps->range(0, 1) == 0);
837-
}
838-
839-
840-
void CaveFractal::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height)
841-
{
842-
node_min = nmin;
843-
node_max = nmax;
844-
main_direction = v3f(0, 0, 0);
845-
846-
// Allowed route area size in nodes
847-
ar = node_max - node_min + v3s16(1, 1, 1);
848-
// Area starting point in nodes
849-
of = node_min;
850-
851-
// Allow a bit more
852-
//(this should be more than the maximum radius of the tunnel)
853-
s16 insure = 10;
854-
s16 more = MYMAX(MAP_BLOCKSIZE - max_tunnel_diameter / 2 - insure, 1);
855-
ar += v3s16(1,0,1) * more * 2;
856-
of -= v3s16(1,0,1) * more;
857-
858-
route_y_min = 0;
859-
// Allow half a diameter + 7 over stone surface
860-
route_y_max = -of.Y + max_stone_y + max_tunnel_diameter / 2 + 7;
861-
862-
// Limit maximum to area
863-
route_y_max = rangelim(route_y_max, 0, ar.Y - 1);
864-
865-
s16 min = 0;
866-
if (node_min.Y < water_level && node_max.Y > water_level) {
867-
min = water_level - max_tunnel_diameter/3 - of.Y;
868-
route_y_max = water_level + max_tunnel_diameter/3 - of.Y;
869-
}
870-
route_y_min = ps->range(min, min + max_tunnel_diameter);
871-
route_y_min = rangelim(route_y_min, 0, route_y_max);
872-
873-
s16 route_start_y_min = route_y_min;
874-
s16 route_start_y_max = route_y_max;
875-
876-
route_start_y_min = rangelim(route_start_y_min, 0, ar.Y - 1);
877-
route_start_y_max = rangelim(route_start_y_max, route_start_y_min, ar.Y - 1);
878-
879-
// Randomize starting position
880-
orp = v3f(
881-
(float)(ps->next() % ar.X) + 0.5,
882-
(float)(ps->range(route_start_y_min, route_start_y_max)) + 0.5,
883-
(float)(ps->next() % ar.Z) + 0.5
884-
);
885-
886-
// Add generation notify begin event
887-
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
888-
GenNotifyType notifytype = GENNOTIFY_LARGECAVE_BEGIN;
889-
mg->gennotify.addEvent(notifytype, abs_pos);
890-
891-
// Generate some tunnel starting from orp
892-
for (u16 j = 0; j < tunnel_routepoints; j++)
893-
makeTunnel(j % dswitchint == 0);
894-
895-
// Add generation notify end event
896-
abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
897-
notifytype = GENNOTIFY_LARGECAVE_END;
898-
mg->gennotify.addEvent(notifytype, abs_pos);
899-
}
900-
901-
902-
void CaveFractal::makeTunnel(bool dirswitch)
903-
{
904-
// Randomize size
905-
s16 min_d = min_tunnel_diameter;
906-
s16 max_d = max_tunnel_diameter;
907-
rs = ps->range(min_d, max_d);
908-
s16 rs_part_max_length_rs = rs * part_max_length_rs;
909-
910-
v3s16 maxlen;
911-
maxlen = v3s16(
912-
rs_part_max_length_rs,
913-
rs_part_max_length_rs / 2,
914-
rs_part_max_length_rs
915-
);
916-
917-
v3f vec;
918-
// Jump downward sometimes
919-
vec = v3f(
920-
(float)(ps->next() % maxlen.X) - (float)maxlen.X / 2,
921-
(float)(ps->next() % maxlen.Y) - (float)maxlen.Y / 2,
922-
(float)(ps->next() % maxlen.Z) - (float)maxlen.Z / 2
923-
);
924-
925-
// Do not make caves that are above ground.
926-
// It is only necessary to check the startpoint and endpoint.
927-
v3s16 orpi(orp.X, orp.Y, orp.Z);
928-
v3s16 veci(vec.X, vec.Y, vec.Z);
929-
v3s16 p;
930-
931-
p = orpi + veci + of + rs / 2;
932-
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
933-
p.X >= node_min.X && p.X <= node_max.X) {
934-
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
935-
s16 h = mg->heightmap[index];
936-
if (h < p.Y)
937-
return;
938-
} else if (p.Y > water_level) {
939-
return; // If it's not in our heightmap, use a simple heuristic
940-
}
941-
942-
p = orpi + of + rs / 2;
943-
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
944-
p.X >= node_min.X && p.X <= node_max.X) {
945-
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
946-
s16 h = mg->heightmap[index];
947-
if (h < p.Y)
948-
return;
949-
} else if (p.Y > water_level) {
950-
return;
951-
}
952-
953-
vec += main_direction;
954-
955-
v3f rp = orp + vec;
956-
if (rp.X < 0)
957-
rp.X = 0;
958-
else if (rp.X >= ar.X)
959-
rp.X = ar.X - 1;
960-
961-
if (rp.Y < route_y_min)
962-
rp.Y = route_y_min;
963-
else if (rp.Y >= route_y_max)
964-
rp.Y = route_y_max - 1;
965-
966-
if (rp.Z < 0)
967-
rp.Z = 0;
968-
else if (rp.Z >= ar.Z)
969-
rp.Z = ar.Z - 1;
970-
971-
vec = rp - orp;
972-
973-
float veclen = vec.getLength();
974-
if (veclen < 0.05)
975-
veclen = 1.0;
976-
977-
// Every second section is rough
978-
bool randomize_xz = (ps->range(1, 2) == 1);
979-
980-
// Carve routes
981-
for (float f = 0; f < 1.0; f += 1.0 / veclen)
982-
carveRoute(vec, f, randomize_xz);
983-
984-
orp = rp;
985-
}
986-
987-
988-
void CaveFractal::carveRoute(v3f vec, float f, bool randomize_xz)
989-
{
990-
MapNode airnode(CONTENT_AIR);
991-
MapNode waternode(c_water_source);
992-
MapNode lavanode(c_lava_source);
993-
994-
v3s16 startp(orp.X, orp.Y, orp.Z);
995-
startp += of;
996-
997-
float nval = NoisePerlin3D(np_caveliquids, startp.X,
998-
startp.Y, startp.Z, mg->seed);
999-
MapNode liquidnode = (nval < 0.40 && node_max.Y < MGFRACTAL_LAVA_DEPTH) ?
1000-
lavanode : waternode;
1001-
1002-
v3f fp = orp + vec * f;
1003-
fp.X += 0.1 * ps->range(-10, 10);
1004-
fp.Z += 0.1 * ps->range(-10, 10);
1005-
v3s16 cp(fp.X, fp.Y, fp.Z);
1006-
1007-
s16 d0 = -rs/2;
1008-
s16 d1 = d0 + rs;
1009-
if (randomize_xz) {
1010-
d0 += ps->range(-1, 1);
1011-
d1 += ps->range(-1, 1);
1012-
}
1013-
1014-
for (s16 z0 = d0; z0 <= d1; z0++) {
1015-
s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1);
1016-
for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) {
1017-
s16 maxabsxz = MYMAX(abs(x0), abs(z0));
1018-
1019-
s16 si2 = rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1);
1020-
1021-
for (s16 y0 = -si2; y0 <= si2; y0++) {
1022-
if (large_cave_is_flat) {
1023-
// Make large caves not so tall
1024-
if (rs > 7 && abs(y0) >= rs / 3)
1025-
continue;
1026-
}
1027-
1028-
v3s16 p(cp.X + x0, cp.Y + y0, cp.Z + z0);
1029-
p += of;
1030-
1031-
if (vm->m_area.contains(p) == false)
1032-
continue;
1033-
1034-
u32 i = vm->m_area.index(p);
1035-
content_t c = vm->m_data[i].getContent();
1036-
if (!ndef->get(c).is_ground_content)
1037-
continue;
1038-
1039-
int full_ymin = node_min.Y - MAP_BLOCKSIZE;
1040-
int full_ymax = node_max.Y + MAP_BLOCKSIZE;
1041-
1042-
if (flooded && full_ymin < water_level &&
1043-
full_ymax > water_level)
1044-
vm->m_data[i] = (p.Y <= water_level) ?
1045-
waternode : airnode;
1046-
else if (flooded && full_ymax < water_level)
1047-
vm->m_data[i] = (p.Y < startp.Y - 4) ?
1048-
liquidnode : airnode;
1049-
else
1050-
vm->m_data[i] = airnode;
1051-
}
1052-
}
1053-
}
1054-
}

Diff for: ‎src/cavegen.h

+4-49
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2121
#define CAVEGEN_HEADER
2222

2323
#define VMANIP_FLAG_CAVE VOXELFLAG_CHECKED1
24+
#define MGV5_LAVA_DEPTH -256
2425
#define MGV7_LAVA_DEPTH -256
25-
#define MGFRACTAL_LAVA_DEPTH -256
2626

2727
class MapgenV5;
2828
class MapgenV6;
2929
class MapgenV7;
30-
class MapgenFractal;
3130

3231
class CaveV5 {
3332
public:
34-
MapgenV5 *mg;
33+
Mapgen *mg;
3534
MMVManip *vm;
3635
INodeDefManager *ndef;
3736

@@ -66,9 +65,10 @@ class CaveV5 {
6665
content_t c_ice;
6766

6867
int water_level;
68+
int ystride;
6969

7070
CaveV5() {}
71-
CaveV5(MapgenV5 *mg, PseudoRandom *ps);
71+
CaveV5(Mapgen *mg, PseudoRandom *ps);
7272
void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height);
7373
void makeTunnel(bool dirswitch);
7474
void carveRoute(v3f vec, float f, bool randomize_xz);
@@ -163,49 +163,4 @@ class CaveV7 {
163163
void carveRoute(v3f vec, float f, bool randomize_xz);
164164
};
165165

166-
class CaveFractal {
167-
public:
168-
MapgenFractal *mg;
169-
MMVManip *vm;
170-
INodeDefManager *ndef;
171-
172-
NoiseParams *np_caveliquids;
173-
174-
s16 min_tunnel_diameter;
175-
s16 max_tunnel_diameter;
176-
u16 tunnel_routepoints;
177-
int dswitchint;
178-
int part_max_length_rs;
179-
180-
bool large_cave_is_flat;
181-
bool flooded;
182-
183-
s16 max_stone_y;
184-
v3s16 node_min;
185-
v3s16 node_max;
186-
187-
v3f orp; // starting point, relative to caved space
188-
v3s16 of; // absolute coordinates of caved space
189-
v3s16 ar; // allowed route area
190-
s16 rs; // tunnel radius size
191-
v3f main_direction;
192-
193-
s16 route_y_min;
194-
s16 route_y_max;
195-
196-
PseudoRandom *ps;
197-
198-
content_t c_water_source;
199-
content_t c_lava_source;
200-
content_t c_ice;
201-
202-
int water_level;
203-
204-
CaveFractal() {}
205-
CaveFractal(MapgenFractal *mg, PseudoRandom *ps);
206-
void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height);
207-
void makeTunnel(bool dirswitch);
208-
void carveRoute(v3f vec, float f, bool randomize_xz);
209-
};
210-
211166
#endif

Diff for: ‎src/mapgen_fractal.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ void MapgenFractal::generateCaves(s16 max_stone_y)
634634
PseudoRandom ps(blockseed + 21343);
635635
u32 bruises_count = (ps.range(1, 4) == 1) ? ps.range(1, 2) : 0;
636636
for (u32 i = 0; i < bruises_count; i++) {
637-
CaveFractal cave(this, &ps);
637+
CaveV5 cave(this, &ps);
638638
cave.makeCave(node_min, node_max, max_stone_y);
639639
}
640640
}

0 commit comments

Comments
 (0)
Please sign in to comment.