forked from Mirrorlandia_minetest/minetest
Cavegen: Remove CavesRandomWalk dependency on Mapgen
This commit is contained in:
parent
68b1cd8d1b
commit
db1b4dc890
@ -31,23 +31,52 @@ NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6, 2.0
|
|||||||
//// CavesRandomWalk
|
//// CavesRandomWalk
|
||||||
////
|
////
|
||||||
|
|
||||||
CavesRandomWalk::CavesRandomWalk(Mapgen *mg, PseudoRandom *ps)
|
CavesRandomWalk::CavesRandomWalk(
|
||||||
|
INodeDefManager *ndef,
|
||||||
|
GenerateNotifier *gennotify,
|
||||||
|
int seed,
|
||||||
|
int water_level,
|
||||||
|
content_t water_source,
|
||||||
|
content_t lava_source)
|
||||||
{
|
{
|
||||||
this->mg = mg;
|
assert(ndef);
|
||||||
this->vm = mg->vm;
|
|
||||||
this->ndef = mg->ndef;
|
this->ndef = ndef;
|
||||||
this->water_level = mg->water_level;
|
this->gennotify = gennotify;
|
||||||
this->ps = ps;
|
this->seed = seed;
|
||||||
c_water_source = ndef->getId("mapgen_water_source");
|
this->water_level = water_level;
|
||||||
c_lava_source = ndef->getId("mapgen_lava_source");
|
|
||||||
c_ice = ndef->getId("mapgen_ice");
|
|
||||||
this->np_caveliquids = &nparams_caveliquids;
|
this->np_caveliquids = &nparams_caveliquids;
|
||||||
this->ystride = mg->csize.X;
|
|
||||||
this->lava_depth = DEFAULT_LAVA_DEPTH;
|
this->lava_depth = DEFAULT_LAVA_DEPTH;
|
||||||
|
|
||||||
if (c_ice == CONTENT_IGNORE)
|
c_water_source = water_source;
|
||||||
c_ice = CONTENT_AIR;
|
if (c_water_source == CONTENT_IGNORE)
|
||||||
|
c_water_source = ndef->getId("mapgen_water_source");
|
||||||
|
if (c_water_source == CONTENT_IGNORE)
|
||||||
|
c_water_source = CONTENT_AIR;
|
||||||
|
|
||||||
|
c_lava_source = lava_source;
|
||||||
|
if (c_lava_source == CONTENT_IGNORE)
|
||||||
|
c_lava_source = ndef->getId("mapgen_lava_source");
|
||||||
|
if (c_lava_source == CONTENT_IGNORE)
|
||||||
|
c_lava_source = CONTENT_AIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CavesRandomWalk::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax,
|
||||||
|
PseudoRandom *ps, int max_stone_height, s16 *heightmap)
|
||||||
|
{
|
||||||
|
assert(vm);
|
||||||
|
assert(ps);
|
||||||
|
|
||||||
|
this->vm = vm;
|
||||||
|
this->ps = ps;
|
||||||
|
this->node_min = nmin;
|
||||||
|
this->node_max = nmax;
|
||||||
|
this->heightmap = heightmap;
|
||||||
|
|
||||||
|
this->ystride = nmax.X - nmin.X + 1;
|
||||||
|
|
||||||
|
// Set initial parameters from randomness
|
||||||
dswitchint = ps->range(1, 14);
|
dswitchint = ps->range(1, 14);
|
||||||
flooded = ps->range(1, 2) == 2;
|
flooded = ps->range(1, 2) == 2;
|
||||||
|
|
||||||
@ -57,13 +86,7 @@ CavesRandomWalk::CavesRandomWalk(Mapgen *mg, PseudoRandom *ps)
|
|||||||
max_tunnel_diameter = ps->range(7, ps->range(8, 24));
|
max_tunnel_diameter = ps->range(7, ps->range(8, 24));
|
||||||
|
|
||||||
large_cave_is_flat = (ps->range(0, 1) == 0);
|
large_cave_is_flat = (ps->range(0, 1) == 0);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CavesRandomWalk::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height)
|
|
||||||
{
|
|
||||||
node_min = nmin;
|
|
||||||
node_max = nmax;
|
|
||||||
main_direction = v3f(0, 0, 0);
|
main_direction = v3f(0, 0, 0);
|
||||||
|
|
||||||
// Allowed route area size in nodes
|
// Allowed route area size in nodes
|
||||||
@ -107,18 +130,22 @@ void CavesRandomWalk::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height)
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Add generation notify begin event
|
// Add generation notify begin event
|
||||||
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
if (gennotify) {
|
||||||
GenNotifyType notifytype = GENNOTIFY_LARGECAVE_BEGIN;
|
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
||||||
mg->gennotify.addEvent(notifytype, abs_pos);
|
GenNotifyType notifytype = GENNOTIFY_LARGECAVE_BEGIN;
|
||||||
|
gennotify->addEvent(notifytype, abs_pos);
|
||||||
|
}
|
||||||
|
|
||||||
// Generate some tunnel starting from orp
|
// Generate some tunnel starting from orp
|
||||||
for (u16 j = 0; j < tunnel_routepoints; j++)
|
for (u16 j = 0; j < tunnel_routepoints; j++)
|
||||||
makeTunnel(j % dswitchint == 0);
|
makeTunnel(j % dswitchint == 0);
|
||||||
|
|
||||||
// Add generation notify end event
|
// Add generation notify end event
|
||||||
abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
if (gennotify) {
|
||||||
notifytype = GENNOTIFY_LARGECAVE_END;
|
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
||||||
mg->gennotify.addEvent(notifytype, abs_pos);
|
GenNotifyType notifytype = GENNOTIFY_LARGECAVE_END;
|
||||||
|
gennotify->addEvent(notifytype, abs_pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -197,7 +224,7 @@ void CavesRandomWalk::carveRoute(v3f vec, float f, bool randomize_xz)
|
|||||||
startp += of;
|
startp += of;
|
||||||
|
|
||||||
float nval = NoisePerlin3D(np_caveliquids, startp.X,
|
float nval = NoisePerlin3D(np_caveliquids, startp.X,
|
||||||
startp.Y, startp.Z, mg->seed);
|
startp.Y, startp.Z, seed);
|
||||||
MapNode liquidnode = (nval < 0.40 && node_max.Y < lava_depth) ?
|
MapNode liquidnode = (nval < 0.40 && node_max.Y < lava_depth) ?
|
||||||
lavanode : waternode;
|
lavanode : waternode;
|
||||||
|
|
||||||
@ -388,7 +415,7 @@ void CavesV6::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax,
|
|||||||
|
|
||||||
// Add generation notify end event
|
// Add generation notify end event
|
||||||
if (gennotify != NULL) {
|
if (gennotify != NULL) {
|
||||||
v3s16 abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
||||||
GenNotifyType notifytype = large_cave ?
|
GenNotifyType notifytype = large_cave ?
|
||||||
GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END;
|
GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END;
|
||||||
gennotify->addEvent(notifytype, abs_pos);
|
gennotify->addEvent(notifytype, abs_pos);
|
||||||
|
@ -25,17 +25,35 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
class GenerateNotifier;
|
class GenerateNotifier;
|
||||||
|
|
||||||
|
/*
|
||||||
|
CavesRandomWalk is an implementation of a cave-digging algorithm that
|
||||||
|
operates on the principle of a "random walk" to approximate the stochiastic
|
||||||
|
activity of cavern development.
|
||||||
|
|
||||||
|
In summary, this algorithm works by carving a randomly sized tunnel in a
|
||||||
|
random direction a random amount of times, randomly varying in width.
|
||||||
|
All randomness here is uniformly distributed; alternative distributions have
|
||||||
|
not yet been implemented.
|
||||||
|
|
||||||
|
This algorithm is very fast, executing in less than 1ms on average for an
|
||||||
|
80x80x80 chunk of map on a modern processor.
|
||||||
|
*/
|
||||||
class CavesRandomWalk {
|
class CavesRandomWalk {
|
||||||
public:
|
public:
|
||||||
Mapgen *mg;
|
|
||||||
MMVManip *vm;
|
MMVManip *vm;
|
||||||
INodeDefManager *ndef;
|
INodeDefManager *ndef;
|
||||||
|
GenerateNotifier *gennotify;
|
||||||
s16 *heightmap;
|
s16 *heightmap;
|
||||||
|
|
||||||
// variables
|
// configurable parameters
|
||||||
|
int seed;
|
||||||
|
int water_level;
|
||||||
int lava_depth;
|
int lava_depth;
|
||||||
NoiseParams *np_caveliquids;
|
NoiseParams *np_caveliquids;
|
||||||
|
|
||||||
|
// intermediate state variables
|
||||||
|
u16 ystride;
|
||||||
|
|
||||||
s16 min_tunnel_diameter;
|
s16 min_tunnel_diameter;
|
||||||
s16 max_tunnel_diameter;
|
s16 max_tunnel_diameter;
|
||||||
u16 tunnel_routepoints;
|
u16 tunnel_routepoints;
|
||||||
@ -62,17 +80,26 @@ public:
|
|||||||
|
|
||||||
content_t c_water_source;
|
content_t c_water_source;
|
||||||
content_t c_lava_source;
|
content_t c_lava_source;
|
||||||
content_t c_ice;
|
|
||||||
|
|
||||||
int water_level;
|
// ndef is a mandatory parameter.
|
||||||
u16 ystride;
|
// If gennotify is NULL, generation events are not logged.
|
||||||
|
CavesRandomWalk(INodeDefManager *ndef,
|
||||||
|
GenerateNotifier *gennotify = NULL,
|
||||||
|
int seed = 0,
|
||||||
|
int water_level = 1,
|
||||||
|
content_t water_source = CONTENT_IGNORE,
|
||||||
|
content_t lava_source = CONTENT_IGNORE);
|
||||||
|
|
||||||
CavesRandomWalk(Mapgen *mg, PseudoRandom *ps);
|
// vm and ps are mandatory parameters.
|
||||||
void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height);
|
// If heightmap is NULL, the surface level at all points is assumed to
|
||||||
|
// be water_level.
|
||||||
|
void makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax,
|
||||||
|
PseudoRandom *ps, int max_stone_height, s16 *heightmap);
|
||||||
|
|
||||||
|
private:
|
||||||
void makeTunnel(bool dirswitch);
|
void makeTunnel(bool dirswitch);
|
||||||
void carveRoute(v3f vec, float f, bool randomize_xz);
|
void carveRoute(v3f vec, float f, bool randomize_xz);
|
||||||
|
|
||||||
private:
|
|
||||||
inline bool isPosAboveSurface(v3s16 p);
|
inline bool isPosAboveSurface(v3s16 p);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -97,11 +124,13 @@ public:
|
|||||||
PseudoRandom *ps;
|
PseudoRandom *ps;
|
||||||
PseudoRandom *ps2;
|
PseudoRandom *ps2;
|
||||||
|
|
||||||
|
// configurable parameters
|
||||||
s16 *heightmap;
|
s16 *heightmap;
|
||||||
content_t c_water_source;
|
content_t c_water_source;
|
||||||
content_t c_lava_source;
|
content_t c_lava_source;
|
||||||
int water_level;
|
int water_level;
|
||||||
|
|
||||||
|
// intermediate state variables
|
||||||
u16 ystride;
|
u16 ystride;
|
||||||
|
|
||||||
s16 min_tunnel_diameter;
|
s16 min_tunnel_diameter;
|
||||||
|
@ -599,8 +599,10 @@ void MapgenBasic::generateCaves(s16 max_stone_y, s16 large_cave_depth)
|
|||||||
PseudoRandom ps(blockseed + 21343);
|
PseudoRandom ps(blockseed + 21343);
|
||||||
u32 bruises_count = ps.range(0, 2);
|
u32 bruises_count = ps.range(0, 2);
|
||||||
for (u32 i = 0; i < bruises_count; i++) {
|
for (u32 i = 0; i < bruises_count; i++) {
|
||||||
CavesRandomWalk cave(this, &ps);
|
CavesRandomWalk cave(ndef, &gennotify, seed, water_level,
|
||||||
cave.makeCave(node_min, node_max, max_stone_y);
|
c_water_source, CONTENT_IGNORE);
|
||||||
|
|
||||||
|
cave.makeCave(vm, node_min, node_max, &ps, max_stone_y, heightmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,8 +841,10 @@ void MapgenValleys::generateCaves(s16 max_stone_y, s16 large_cave_depth)
|
|||||||
if (node_max.Y <= large_cave_depth && !made_a_big_one) {
|
if (node_max.Y <= large_cave_depth && !made_a_big_one) {
|
||||||
u32 bruises_count = ps.range(0, 2);
|
u32 bruises_count = ps.range(0, 2);
|
||||||
for (u32 i = 0; i < bruises_count; i++) {
|
for (u32 i = 0; i < bruises_count; i++) {
|
||||||
CavesRandomWalk cave(this, &ps);
|
CavesRandomWalk cave(ndef, &gennotify, seed, water_level,
|
||||||
cave.makeCave(node_min, node_max, max_stone_y);
|
c_water_source, c_lava_source);
|
||||||
|
|
||||||
|
cave.makeCave(vm, node_min, node_max, &ps, max_stone_y, heightmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user