diff options
-rw-r--r-- | src/cavegen.cpp | 261 | ||||
-rw-r--r-- | src/cavegen.h | 53 | ||||
-rw-r--r-- | src/mapgen_fractal.cpp | 2 | ||||
-rw-r--r-- | src/mapgen_fractal.h | 2 |
4 files changed, 15 insertions, 303 deletions
diff --git a/src/cavegen.cpp b/src/cavegen.cpp index e0303900e..e1516af08 100644 --- a/src/cavegen.cpp +++ b/src/cavegen.cpp @@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapgen_v5.h" #include "mapgen_v6.h" #include "mapgen_v7.h" -#include "mapgen_fractal.h" #include "cavegen.h" 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 ///////////////////////////////////////// Caves V5 -CaveV5::CaveV5(MapgenV5 *mg, PseudoRandom *ps) +CaveV5::CaveV5(Mapgen *mg, PseudoRandom *ps) { this->mg = mg; this->vm = mg->vm; this->ndef = mg->ndef; this->water_level = mg->water_level; this->ps = ps; - this->c_water_source = mg->c_water_source; - this->c_lava_source = mg->c_lava_source; - this->c_ice = mg->c_ice; + c_water_source = ndef->getId("mapgen_water_source"); + c_lava_source = ndef->getId("mapgen_lava_source"); + c_ice = ndef->getId("mapgen_ice"); this->np_caveliquids = &nparams_caveliquids; + this->ystride = mg->csize.X; dswitchint = ps->range(1, 14); flooded = ps->range(1, 2) == 2; @@ -150,7 +150,7 @@ void CaveV5::makeTunnel(bool dirswitch) p = orpi + veci + of + rs / 2; if (p.Z >= node_min.Z && p.Z <= node_max.Z && p.X >= node_min.X && p.X <= node_max.X) { - u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X); + u32 index = (p.Z - node_min.Z) * ystride + (p.X - node_min.X); s16 h = mg->heightmap[index]; if (h < p.Y) return; @@ -161,7 +161,7 @@ void CaveV5::makeTunnel(bool dirswitch) p = orpi + of + rs / 2; if (p.Z >= node_min.Z && p.Z <= node_max.Z && p.X >= node_min.X && p.X <= node_max.X) { - u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X); + u32 index = (p.Z - node_min.Z) * ystride + (p.X - node_min.X); s16 h = mg->heightmap[index]; if (h < p.Y) return; @@ -215,7 +215,8 @@ void CaveV5::carveRoute(v3f vec, float f, bool randomize_xz) float nval = NoisePerlin3D(np_caveliquids, startp.X, startp.Y, startp.Z, mg->seed); - MapNode liquidnode = nval < 0.40 ? lavanode : waternode; + MapNode liquidnode = (nval < 0.40 && node_max.Y < MGV5_LAVA_DEPTH) ? + lavanode : waternode; v3f fp = orp + vec * f; fp.X += 0.1 * ps->range(-10, 10); @@ -808,247 +809,3 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz) } } } - - -///////////////////////////////////////// Caves Fractal - - -CaveFractal::CaveFractal(MapgenFractal *mg, PseudoRandom *ps) -{ - this->mg = mg; - this->vm = mg->vm; - this->ndef = mg->ndef; - this->water_level = mg->water_level; - this->ps = ps; - this->c_water_source = mg->c_water_source; - this->c_lava_source = mg->c_lava_source; - this->c_ice = mg->c_ice; - this->np_caveliquids = &nparams_caveliquids; - - dswitchint = ps->range(1, 14); - flooded = ps->range(1, 2) == 2; - - part_max_length_rs = ps->range(2, 4); - tunnel_routepoints = ps->range(5, ps->range(15, 30)); - min_tunnel_diameter = 5; - max_tunnel_diameter = ps->range(7, ps->range(8, 24)); - - large_cave_is_flat = (ps->range(0, 1) == 0); -} - - -void CaveFractal::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) -{ - node_min = nmin; - node_max = nmax; - main_direction = v3f(0, 0, 0); - - // Allowed route area size in nodes - ar = node_max - node_min + v3s16(1, 1, 1); - // Area starting point in nodes - of = node_min; - - // Allow a bit more - //(this should be more than the maximum radius of the tunnel) - s16 insure = 10; - s16 more = MYMAX(MAP_BLOCKSIZE - max_tunnel_diameter / 2 - insure, 1); - ar += v3s16(1,0,1) * more * 2; - of -= v3s16(1,0,1) * more; - - route_y_min = 0; - // Allow half a diameter + 7 over stone surface - route_y_max = -of.Y + max_stone_y + max_tunnel_diameter / 2 + 7; - - // Limit maximum to area - route_y_max = rangelim(route_y_max, 0, ar.Y - 1); - - s16 min = 0; - if (node_min.Y < water_level && node_max.Y > water_level) { - min = water_level - max_tunnel_diameter/3 - of.Y; - route_y_max = water_level + max_tunnel_diameter/3 - of.Y; - } - route_y_min = ps->range(min, min + max_tunnel_diameter); - route_y_min = rangelim(route_y_min, 0, route_y_max); - - s16 route_start_y_min = route_y_min; - s16 route_start_y_max = route_y_max; - - route_start_y_min = rangelim(route_start_y_min, 0, ar.Y - 1); - route_start_y_max = rangelim(route_start_y_max, route_start_y_min, ar.Y - 1); - - // Randomize starting position - orp = v3f( - (float)(ps->next() % ar.X) + 0.5, - (float)(ps->range(route_start_y_min, route_start_y_max)) + 0.5, - (float)(ps->next() % ar.Z) + 0.5 - ); - - // Add generation notify begin event - v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); - GenNotifyType notifytype = GENNOTIFY_LARGECAVE_BEGIN; - mg->gennotify.addEvent(notifytype, abs_pos); - - // Generate some tunnel starting from orp - for (u16 j = 0; j < tunnel_routepoints; j++) - makeTunnel(j % dswitchint == 0); - - // Add generation notify end event - abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); - notifytype = GENNOTIFY_LARGECAVE_END; - mg->gennotify.addEvent(notifytype, abs_pos); -} - - -void CaveFractal::makeTunnel(bool dirswitch) -{ - // Randomize size - s16 min_d = min_tunnel_diameter; - s16 max_d = max_tunnel_diameter; - rs = ps->range(min_d, max_d); - s16 rs_part_max_length_rs = rs * part_max_length_rs; - - v3s16 maxlen; - maxlen = v3s16( - rs_part_max_length_rs, - rs_part_max_length_rs / 2, - rs_part_max_length_rs - ); - - v3f vec; - // Jump downward sometimes - vec = v3f( - (float)(ps->next() % maxlen.X) - (float)maxlen.X / 2, - (float)(ps->next() % maxlen.Y) - (float)maxlen.Y / 2, - (float)(ps->next() % maxlen.Z) - (float)maxlen.Z / 2 - ); - - // Do not make caves that are above ground. - // It is only necessary to check the startpoint and endpoint. - v3s16 orpi(orp.X, orp.Y, orp.Z); - v3s16 veci(vec.X, vec.Y, vec.Z); - v3s16 p; - - p = orpi + veci + of + rs / 2; - if (p.Z >= node_min.Z && p.Z <= node_max.Z && - p.X >= node_min.X && p.X <= node_max.X) { - u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X); - s16 h = mg->heightmap[index]; - if (h < p.Y) - return; - } else if (p.Y > water_level) { - return; // If it's not in our heightmap, use a simple heuristic - } - - p = orpi + of + rs / 2; - if (p.Z >= node_min.Z && p.Z <= node_max.Z && - p.X >= node_min.X && p.X <= node_max.X) { - u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X); - s16 h = mg->heightmap[index]; - if (h < p.Y) - return; - } else if (p.Y > water_level) { - return; - } - - vec += main_direction; - - v3f rp = orp + vec; - if (rp.X < 0) - rp.X = 0; - else if (rp.X >= ar.X) - rp.X = ar.X - 1; - - if (rp.Y < route_y_min) - rp.Y = route_y_min; - else if (rp.Y >= route_y_max) - rp.Y = route_y_max - 1; - - if (rp.Z < 0) - rp.Z = 0; - else if (rp.Z >= ar.Z) - rp.Z = ar.Z - 1; - - vec = rp - orp; - - float veclen = vec.getLength(); - if (veclen < 0.05) - veclen = 1.0; - - // Every second section is rough - bool randomize_xz = (ps->range(1, 2) == 1); - - // Carve routes - for (float f = 0; f < 1.0; f += 1.0 / veclen) - carveRoute(vec, f, randomize_xz); - - orp = rp; -} - - -void CaveFractal::carveRoute(v3f vec, float f, bool randomize_xz) -{ - MapNode airnode(CONTENT_AIR); - MapNode waternode(c_water_source); - MapNode lavanode(c_lava_source); - - v3s16 startp(orp.X, orp.Y, orp.Z); - startp += of; - - float nval = NoisePerlin3D(np_caveliquids, startp.X, - startp.Y, startp.Z, mg->seed); - MapNode liquidnode = (nval < 0.40 && node_max.Y < MGFRACTAL_LAVA_DEPTH) ? - lavanode : waternode; - - v3f fp = orp + vec * f; - fp.X += 0.1 * ps->range(-10, 10); - fp.Z += 0.1 * ps->range(-10, 10); - v3s16 cp(fp.X, fp.Y, fp.Z); - - s16 d0 = -rs/2; - s16 d1 = d0 + rs; - if (randomize_xz) { - d0 += ps->range(-1, 1); - d1 += ps->range(-1, 1); - } - - for (s16 z0 = d0; z0 <= d1; z0++) { - s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1); - for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) { - s16 maxabsxz = MYMAX(abs(x0), abs(z0)); - - s16 si2 = rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1); - - for (s16 y0 = -si2; y0 <= si2; y0++) { - if (large_cave_is_flat) { - // Make large caves not so tall - if (rs > 7 && abs(y0) >= rs / 3) - continue; - } - - v3s16 p(cp.X + x0, cp.Y + y0, cp.Z + z0); - p += of; - - if (vm->m_area.contains(p) == false) - continue; - - u32 i = vm->m_area.index(p); - content_t c = vm->m_data[i].getContent(); - if (!ndef->get(c).is_ground_content) - continue; - - int full_ymin = node_min.Y - MAP_BLOCKSIZE; - int full_ymax = node_max.Y + MAP_BLOCKSIZE; - - if (flooded && full_ymin < water_level && - full_ymax > water_level) - vm->m_data[i] = (p.Y <= water_level) ? - waternode : airnode; - else if (flooded && full_ymax < water_level) - vm->m_data[i] = (p.Y < startp.Y - 4) ? - liquidnode : airnode; - else - vm->m_data[i] = airnode; - } - } - } -} diff --git a/src/cavegen.h b/src/cavegen.h index 22ee5804d..a1124711b 100644 --- a/src/cavegen.h +++ b/src/cavegen.h @@ -21,17 +21,16 @@ with this program; if not, write to the Free Software Foundation, Inc., #define CAVEGEN_HEADER #define VMANIP_FLAG_CAVE VOXELFLAG_CHECKED1 +#define MGV5_LAVA_DEPTH -256 #define MGV7_LAVA_DEPTH -256 -#define MGFRACTAL_LAVA_DEPTH -256 class MapgenV5; class MapgenV6; class MapgenV7; -class MapgenFractal; class CaveV5 { public: - MapgenV5 *mg; + Mapgen *mg; MMVManip *vm; INodeDefManager *ndef; @@ -66,9 +65,10 @@ public: content_t c_ice; int water_level; + int ystride; CaveV5() {} - CaveV5(MapgenV5 *mg, PseudoRandom *ps); + CaveV5(Mapgen *mg, PseudoRandom *ps); void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height); void makeTunnel(bool dirswitch); void carveRoute(v3f vec, float f, bool randomize_xz); @@ -163,49 +163,4 @@ public: void carveRoute(v3f vec, float f, bool randomize_xz); }; -class CaveFractal { -public: - MapgenFractal *mg; - MMVManip *vm; - INodeDefManager *ndef; - - NoiseParams *np_caveliquids; - - s16 min_tunnel_diameter; - s16 max_tunnel_diameter; - u16 tunnel_routepoints; - int dswitchint; - int part_max_length_rs; - - bool large_cave_is_flat; - bool flooded; - - s16 max_stone_y; - v3s16 node_min; - v3s16 node_max; - - v3f orp; // starting point, relative to caved space - v3s16 of; // absolute coordinates of caved space - v3s16 ar; // allowed route area - s16 rs; // tunnel radius size - v3f main_direction; - - s16 route_y_min; - s16 route_y_max; - - PseudoRandom *ps; - - content_t c_water_source; - content_t c_lava_source; - content_t c_ice; - - int water_level; - - CaveFractal() {} - CaveFractal(MapgenFractal *mg, PseudoRandom *ps); - void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height); - void makeTunnel(bool dirswitch); - void carveRoute(v3f vec, float f, bool randomize_xz); -}; - #endif diff --git a/src/mapgen_fractal.cpp b/src/mapgen_fractal.cpp index a33e19840..5eebc17b3 100644 --- a/src/mapgen_fractal.cpp +++ b/src/mapgen_fractal.cpp @@ -634,7 +634,7 @@ void MapgenFractal::generateCaves(s16 max_stone_y) PseudoRandom ps(blockseed + 21343); u32 bruises_count = (ps.range(1, 4) == 1) ? ps.range(1, 2) : 0; for (u32 i = 0; i < bruises_count; i++) { - CaveFractal cave(this, &ps); + CaveV5 cave(this, &ps); cave.makeCave(node_min, node_max, max_stone_y); } } diff --git a/src/mapgen_fractal.h b/src/mapgen_fractal.h index ee947dba2..f3c023081 100644 --- a/src/mapgen_fractal.h +++ b/src/mapgen_fractal.h @@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapgen.h" -#define MGFRACTAL_LARGE_CAVE_DEPTH -32 +#define MGFRACTAL_LARGE_CAVE_DEPTH -33 /////////////////// Mapgen Fractal flags #define MGFRACTAL_JULIA 0x01 |