Rewrite generate notification mechanism
Add support for notify-on-decoration Clean up mapgen constructors Clean up mapgen.cpp code style somewhat Remove trailing whitespace from some files
This commit is contained in:
parent
2b119e1e19
commit
5062b99cb0
@ -1533,10 +1533,11 @@ minetest.get_perlin(seeddiff, octaves, persistence, scale)
|
|||||||
^ Return world-specific perlin noise (int(worldseed)+seeddiff)
|
^ Return world-specific perlin noise (int(worldseed)+seeddiff)
|
||||||
minetest.get_voxel_manip()
|
minetest.get_voxel_manip()
|
||||||
^ Return voxel manipulator object
|
^ Return voxel manipulator object
|
||||||
minetest.set_gen_notify(flags)
|
minetest.set_gen_notify(flags, {deco_ids})
|
||||||
^ Set the types of on-generate notifications that should be collected
|
^ Set the types of on-generate notifications that should be collected
|
||||||
^ flags is a comma-delimited combination of:
|
^ flags is a flag field with the available flags:
|
||||||
^ dungeon, temple, cave_begin, cave_end, large_cave_begin, large_cave_end
|
^ dungeon, temple, cave_begin, cave_end, large_cave_begin, large_cave_end, decoration
|
||||||
|
^ The second parameter is a list of IDS of decorations which notification is requested for
|
||||||
minetest.get_mapgen_object(objectname)
|
minetest.get_mapgen_object(objectname)
|
||||||
^ Return requested mapgen object if available (see Mapgen objects)
|
^ Return requested mapgen object if available (see Mapgen objects)
|
||||||
minetest.set_mapgen_params(MapgenParams)
|
minetest.set_mapgen_params(MapgenParams)
|
||||||
@ -2220,7 +2221,9 @@ current mapgen.
|
|||||||
Returns a table mapping requested generation notification types to arrays of positions at which the
|
Returns a table mapping requested generation notification types to arrays of positions at which the
|
||||||
corresponding generated structures are located at within the current chunk. To set the capture of positions
|
corresponding generated structures are located at within the current chunk. To set the capture of positions
|
||||||
of interest to be recorded on generate, use minetest.set_gen_notify().
|
of interest to be recorded on generate, use minetest.set_gen_notify().
|
||||||
Possible fields of the table returned are: dungeon, temple, cave_begin, cave_end, large_cave_begin, large_cave_end
|
Possible fields of the table returned are:
|
||||||
|
dungeon, temple, cave_begin, cave_end, large_cave_begin, large_cave_end, decoration
|
||||||
|
Decorations have a key in the format of "decoration#id", where id is the numeric unique decoration ID.
|
||||||
|
|
||||||
Registered entities
|
Registered entities
|
||||||
--------------------
|
--------------------
|
||||||
|
106
src/cavegen.cpp
106
src/cavegen.cpp
@ -45,7 +45,7 @@ CaveV6::CaveV6(MapgenV6 *mg, PseudoRandom *ps, PseudoRandom *ps2, bool is_large_
|
|||||||
max_tunnel_diameter = ps->range(2, 6);
|
max_tunnel_diameter = ps->range(2, 6);
|
||||||
dswitchint = ps->range(1, 14);
|
dswitchint = ps->range(1, 14);
|
||||||
flooded = true;
|
flooded = true;
|
||||||
|
|
||||||
if (large_cave) {
|
if (large_cave) {
|
||||||
part_max_length_rs = ps->range(2,4);
|
part_max_length_rs = ps->range(2,4);
|
||||||
tunnel_routepoints = ps->range(5, ps->range(15,30));
|
tunnel_routepoints = ps->range(5, ps->range(15,30));
|
||||||
@ -55,7 +55,7 @@ CaveV6::CaveV6(MapgenV6 *mg, PseudoRandom *ps, PseudoRandom *ps2, bool is_large_
|
|||||||
part_max_length_rs = ps->range(2,9);
|
part_max_length_rs = ps->range(2,9);
|
||||||
tunnel_routepoints = ps->range(10, ps->range(15,30));
|
tunnel_routepoints = ps->range(10, ps->range(15,30));
|
||||||
}
|
}
|
||||||
|
|
||||||
large_cave_is_flat = (ps->range(0,1) == 0);
|
large_cave_is_flat = (ps->range(0,1) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,21 +109,21 @@ void CaveV6::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) {
|
|||||||
(float)(ps->next() % ar.Z) + 0.5
|
(float)(ps->next() % ar.Z) + 0.5
|
||||||
);
|
);
|
||||||
|
|
||||||
int notifytype = large_cave ? GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
|
// Add generation notify begin event
|
||||||
if (mg->gennotify & (1 << notifytype)) {
|
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
||||||
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype];
|
GenNotifyType notifytype = large_cave ?
|
||||||
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z));
|
GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
|
||||||
}
|
mg->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);
|
||||||
|
|
||||||
notifytype = large_cave ? GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END;
|
// Add generation notify end event
|
||||||
if (mg->gennotify & (1 << notifytype)) {
|
abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
||||||
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype];
|
notifytype = large_cave ?
|
||||||
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z));
|
GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
|
||||||
}
|
mg->gennotify.addEvent(notifytype, abs_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -179,31 +179,31 @@ void CaveV6::makeTunnel(bool dirswitch) {
|
|||||||
rp.X = 0;
|
rp.X = 0;
|
||||||
else if (rp.X >= ar.X)
|
else if (rp.X >= ar.X)
|
||||||
rp.X = ar.X - 1;
|
rp.X = ar.X - 1;
|
||||||
|
|
||||||
if (rp.Y < route_y_min)
|
if (rp.Y < route_y_min)
|
||||||
rp.Y = route_y_min;
|
rp.Y = route_y_min;
|
||||||
else if (rp.Y >= route_y_max)
|
else if (rp.Y >= route_y_max)
|
||||||
rp.Y = route_y_max - 1;
|
rp.Y = route_y_max - 1;
|
||||||
|
|
||||||
if (rp.Z < 0)
|
if (rp.Z < 0)
|
||||||
rp.Z = 0;
|
rp.Z = 0;
|
||||||
else if (rp.Z >= ar.Z)
|
else if (rp.Z >= ar.Z)
|
||||||
rp.Z = ar.Z - 1;
|
rp.Z = ar.Z - 1;
|
||||||
|
|
||||||
vec = rp - orp;
|
vec = rp - orp;
|
||||||
|
|
||||||
float veclen = vec.getLength();
|
float veclen = vec.getLength();
|
||||||
// As odd as it sounds, veclen is *exactly* 0.0 sometimes, causing a FPE
|
// As odd as it sounds, veclen is *exactly* 0.0 sometimes, causing a FPE
|
||||||
if (veclen < 0.05)
|
if (veclen < 0.05)
|
||||||
veclen = 1.0;
|
veclen = 1.0;
|
||||||
|
|
||||||
// Every second section is rough
|
// Every second section is rough
|
||||||
bool randomize_xz = (ps2->range(1, 2) == 1);
|
bool randomize_xz = (ps2->range(1, 2) == 1);
|
||||||
|
|
||||||
// Carve routes
|
// Carve routes
|
||||||
for (float f = 0; f < 1.0; f += 1.0 / veclen)
|
for (float f = 0; f < 1.0; f += 1.0 / veclen)
|
||||||
carveRoute(vec, f, randomize_xz);
|
carveRoute(vec, f, randomize_xz);
|
||||||
|
|
||||||
orp = rp;
|
orp = rp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,10 +212,10 @@ void CaveV6::carveRoute(v3f vec, float f, bool randomize_xz) {
|
|||||||
MapNode airnode(CONTENT_AIR);
|
MapNode airnode(CONTENT_AIR);
|
||||||
MapNode waternode(c_water_source);
|
MapNode waternode(c_water_source);
|
||||||
MapNode lavanode(c_lava_source);
|
MapNode lavanode(c_lava_source);
|
||||||
|
|
||||||
v3s16 startp(orp.X, orp.Y, orp.Z);
|
v3s16 startp(orp.X, orp.Y, orp.Z);
|
||||||
startp += of;
|
startp += of;
|
||||||
|
|
||||||
v3f fp = orp + vec * f;
|
v3f fp = orp + vec * f;
|
||||||
fp.X += 0.1 * ps->range(-10, 10);
|
fp.X += 0.1 * ps->range(-10, 10);
|
||||||
fp.Z += 0.1 * ps->range(-10, 10);
|
fp.Z += 0.1 * ps->range(-10, 10);
|
||||||
@ -227,13 +227,13 @@ void CaveV6::carveRoute(v3f vec, float f, bool randomize_xz) {
|
|||||||
d0 += ps->range(-1, 1);
|
d0 += ps->range(-1, 1);
|
||||||
d1 += ps->range(-1, 1);
|
d1 += ps->range(-1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (s16 z0 = d0; z0 <= d1; z0++) {
|
for (s16 z0 = d0; z0 <= d1; z0++) {
|
||||||
s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1);
|
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++) {
|
for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) {
|
||||||
s16 maxabsxz = MYMAX(abs(x0), abs(z0));
|
s16 maxabsxz = MYMAX(abs(x0), abs(z0));
|
||||||
s16 si2 = rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1);
|
s16 si2 = rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1);
|
||||||
for (s16 y0 = -si2; y0 <= si2; y0++) {
|
for (s16 y0 = -si2; y0 <= si2; y0++) {
|
||||||
if (large_cave_is_flat) {
|
if (large_cave_is_flat) {
|
||||||
// Make large caves not so tall
|
// Make large caves not so tall
|
||||||
if (rs > 7 && abs(y0) >= rs / 3)
|
if (rs > 7 && abs(y0) >= rs / 3)
|
||||||
@ -293,7 +293,7 @@ CaveV7::CaveV7(MapgenV7 *mg, PseudoRandom *ps, bool is_large_cave) {
|
|||||||
|
|
||||||
dswitchint = ps->range(1, 14);
|
dswitchint = ps->range(1, 14);
|
||||||
flooded = ps->range(1, 2) == 2;
|
flooded = ps->range(1, 2) == 2;
|
||||||
|
|
||||||
if (large_cave) {
|
if (large_cave) {
|
||||||
part_max_length_rs = ps->range(2, 4);
|
part_max_length_rs = ps->range(2, 4);
|
||||||
tunnel_routepoints = ps->range(5, ps->range(15, 30));
|
tunnel_routepoints = ps->range(5, ps->range(15, 30));
|
||||||
@ -305,7 +305,7 @@ CaveV7::CaveV7(MapgenV7 *mg, PseudoRandom *ps, bool is_large_cave) {
|
|||||||
min_tunnel_diameter = 2;
|
min_tunnel_diameter = 2;
|
||||||
max_tunnel_diameter = ps->range(2, 6);
|
max_tunnel_diameter = ps->range(2, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
large_cave_is_flat = (ps->range(0, 1) == 0);
|
large_cave_is_flat = (ps->range(0, 1) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,21 +358,21 @@ void CaveV7::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) {
|
|||||||
(float)(ps->next() % ar.Z) + 0.5
|
(float)(ps->next() % ar.Z) + 0.5
|
||||||
);
|
);
|
||||||
|
|
||||||
int notifytype = large_cave ? GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
|
// Add generation notify begin event
|
||||||
if (mg->gennotify & (1 << notifytype)) {
|
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
||||||
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype];
|
GenNotifyType notifytype = large_cave ?
|
||||||
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z));
|
GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
|
||||||
}
|
mg->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);
|
||||||
|
|
||||||
notifytype = large_cave ? GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END;
|
// Add generation notify end event
|
||||||
if (mg->gennotify & (1 << notifytype)) {
|
abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
|
||||||
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype];
|
notifytype = large_cave ?
|
||||||
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z));
|
GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END;
|
||||||
}
|
mg->gennotify.addEvent(notifytype, abs_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -428,7 +428,7 @@ void CaveV7::makeTunnel(bool dirswitch) {
|
|||||||
v3s16 orpi(orp.X, orp.Y, orp.Z);
|
v3s16 orpi(orp.X, orp.Y, orp.Z);
|
||||||
v3s16 veci(vec.X, vec.Y, vec.Z);
|
v3s16 veci(vec.X, vec.Y, vec.Z);
|
||||||
v3s16 p;
|
v3s16 p;
|
||||||
|
|
||||||
p = orpi + veci + of + rs / 2;
|
p = orpi + veci + of + rs / 2;
|
||||||
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
|
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
|
||||||
p.X >= node_min.X && p.X <= node_max.X) {
|
p.X >= node_min.X && p.X <= node_max.X) {
|
||||||
@ -439,7 +439,7 @@ void CaveV7::makeTunnel(bool dirswitch) {
|
|||||||
} else if (p.Y > water_level) {
|
} else if (p.Y > water_level) {
|
||||||
return; // If it's not in our heightmap, use a simple heuristic
|
return; // If it's not in our heightmap, use a simple heuristic
|
||||||
}
|
}
|
||||||
|
|
||||||
p = orpi + of + rs / 2;
|
p = orpi + of + rs / 2;
|
||||||
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
|
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
|
||||||
p.X >= node_min.X && p.X <= node_max.X) {
|
p.X >= node_min.X && p.X <= node_max.X) {
|
||||||
@ -447,7 +447,7 @@ void CaveV7::makeTunnel(bool dirswitch) {
|
|||||||
s16 h = mg->ridge_heightmap[index];
|
s16 h = mg->ridge_heightmap[index];
|
||||||
if (h < p.Y)
|
if (h < p.Y)
|
||||||
return;
|
return;
|
||||||
} else if (p.Y > water_level) {
|
} else if (p.Y > water_level) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -459,23 +459,23 @@ void CaveV7::makeTunnel(bool dirswitch) {
|
|||||||
rp.X = 0;
|
rp.X = 0;
|
||||||
else if (rp.X >= ar.X)
|
else if (rp.X >= ar.X)
|
||||||
rp.X = ar.X - 1;
|
rp.X = ar.X - 1;
|
||||||
|
|
||||||
if (rp.Y < route_y_min)
|
if (rp.Y < route_y_min)
|
||||||
rp.Y = route_y_min;
|
rp.Y = route_y_min;
|
||||||
else if (rp.Y >= route_y_max)
|
else if (rp.Y >= route_y_max)
|
||||||
rp.Y = route_y_max - 1;
|
rp.Y = route_y_max - 1;
|
||||||
|
|
||||||
if (rp.Z < 0)
|
if (rp.Z < 0)
|
||||||
rp.Z = 0;
|
rp.Z = 0;
|
||||||
else if (rp.Z >= ar.Z)
|
else if (rp.Z >= ar.Z)
|
||||||
rp.Z = ar.Z - 1;
|
rp.Z = ar.Z - 1;
|
||||||
|
|
||||||
vec = rp - orp;
|
vec = rp - orp;
|
||||||
|
|
||||||
float veclen = vec.getLength();
|
float veclen = vec.getLength();
|
||||||
if (veclen < 0.05)
|
if (veclen < 0.05)
|
||||||
veclen = 1.0;
|
veclen = 1.0;
|
||||||
|
|
||||||
// Every second section is rough
|
// Every second section is rough
|
||||||
bool randomize_xz = (ps->range(1, 2) == 1);
|
bool randomize_xz = (ps->range(1, 2) == 1);
|
||||||
|
|
||||||
@ -487,7 +487,7 @@ void CaveV7::makeTunnel(bool dirswitch) {
|
|||||||
// Carve routes
|
// Carve routes
|
||||||
for (float f = 0; f < 1.0; f += 1.0 / veclen)
|
for (float f = 0; f < 1.0; f += 1.0 / veclen)
|
||||||
carveRoute(vec, f, randomize_xz, is_ravine);
|
carveRoute(vec, f, randomize_xz, is_ravine);
|
||||||
|
|
||||||
orp = rp;
|
orp = rp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,14 +496,14 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
|
|||||||
MapNode airnode(CONTENT_AIR);
|
MapNode airnode(CONTENT_AIR);
|
||||||
MapNode waternode(c_water_source);
|
MapNode waternode(c_water_source);
|
||||||
MapNode lavanode(c_lava_source);
|
MapNode lavanode(c_lava_source);
|
||||||
|
|
||||||
v3s16 startp(orp.X, orp.Y, orp.Z);
|
v3s16 startp(orp.X, orp.Y, orp.Z);
|
||||||
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, mg->seed);
|
||||||
MapNode liquidnode = nval < 0.40 ? lavanode : waternode;
|
MapNode liquidnode = nval < 0.40 ? lavanode : waternode;
|
||||||
|
|
||||||
v3f fp = orp + vec * f;
|
v3f fp = orp + vec * f;
|
||||||
fp.X += 0.1 * ps->range(-10, 10);
|
fp.X += 0.1 * ps->range(-10, 10);
|
||||||
fp.Z += 0.1 * ps->range(-10, 10);
|
fp.Z += 0.1 * ps->range(-10, 10);
|
||||||
@ -515,23 +515,23 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
|
|||||||
d0 += ps->range(-1, 1);
|
d0 += ps->range(-1, 1);
|
||||||
d1 += ps->range(-1, 1);
|
d1 += ps->range(-1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool flat_cave_floor = !large_cave && ps->range(0, 2) == 2;
|
bool flat_cave_floor = !large_cave && ps->range(0, 2) == 2;
|
||||||
bool should_make_cave_hole = ps->range(1, 10) == 1;
|
bool should_make_cave_hole = ps->range(1, 10) == 1;
|
||||||
|
|
||||||
for (s16 z0 = d0; z0 <= d1; z0++) {
|
for (s16 z0 = d0; z0 <= d1; z0++) {
|
||||||
s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1);
|
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++) {
|
for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) {
|
||||||
s16 maxabsxz = MYMAX(abs(x0), abs(z0));
|
s16 maxabsxz = MYMAX(abs(x0), abs(z0));
|
||||||
|
|
||||||
s16 si2 = is_ravine ? MYMIN(ps->range(25, 26), ar.Y) :
|
s16 si2 = is_ravine ? MYMIN(ps->range(25, 26), ar.Y) :
|
||||||
rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1);
|
rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1);
|
||||||
|
|
||||||
for (s16 y0 = -si2; y0 <= si2; y0++) {
|
for (s16 y0 = -si2; y0 <= si2; y0++) {
|
||||||
// Make better floors in small caves
|
// Make better floors in small caves
|
||||||
if(flat_cave_floor && y0 <= -rs/2 && rs<=7)
|
if(flat_cave_floor && y0 <= -rs/2 && rs<=7)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (large_cave_is_flat) {
|
if (large_cave_is_flat) {
|
||||||
// Make large caves not so tall
|
// Make large caves not so tall
|
||||||
if (rs > 7 && abs(y0) >= rs / 3)
|
if (rs > 7 && abs(y0) >= rs / 3)
|
||||||
@ -540,7 +540,7 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
|
|||||||
|
|
||||||
v3s16 p(cp.X + x0, cp.Y + y0, cp.Z + z0);
|
v3s16 p(cp.X + x0, cp.Y + y0, cp.Z + z0);
|
||||||
p += of;
|
p += of;
|
||||||
|
|
||||||
if (!is_ravine && mg->heightmap && should_make_cave_hole &&
|
if (!is_ravine && mg->heightmap && should_make_cave_hole &&
|
||||||
p.X <= node_max.X && p.Z <= node_max.Z) {
|
p.X <= node_max.X && p.Z <= node_max.Z) {
|
||||||
int maplen = node_max.X - node_min.X + 1;
|
int maplen = node_max.X - node_min.X + 1;
|
||||||
@ -553,13 +553,13 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
u32 i = vm->m_area.index(p);
|
u32 i = vm->m_area.index(p);
|
||||||
|
|
||||||
// Don't replace air, water, lava, or ice
|
// Don't replace air, water, lava, or ice
|
||||||
content_t c = vm->m_data[i].getContent();
|
content_t c = vm->m_data[i].getContent();
|
||||||
if (!ndef->get(c).is_ground_content || c == CONTENT_AIR ||
|
if (!ndef->get(c).is_ground_content || c == CONTENT_AIR ||
|
||||||
c == c_water_source || c == c_lava_source || c == c_ice)
|
c == c_water_source || c == c_lava_source || c == c_ice)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (large_cave) {
|
if (large_cave) {
|
||||||
int full_ymin = node_min.Y - MAP_BLOCKSIZE;
|
int full_ymin = node_min.Y - MAP_BLOCKSIZE;
|
||||||
int full_ymax = node_max.Y + MAP_BLOCKSIZE;
|
int full_ymax = node_max.Y + MAP_BLOCKSIZE;
|
||||||
@ -573,7 +573,7 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
|
|||||||
} else {
|
} else {
|
||||||
if (c == CONTENT_IGNORE)
|
if (c == CONTENT_IGNORE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vm->m_data[i] = airnode;
|
vm->m_data[i] = airnode;
|
||||||
vm->m_flags[i] |= VMANIP_FLAG_CAVE;
|
vm->m_flags[i] |= VMANIP_FLAG_CAVE;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ DungeonGen::DungeonGen(Mapgen *mapgen, DungeonParams *dparams) {
|
|||||||
#ifdef DGEN_USE_TORCHES
|
#ifdef DGEN_USE_TORCHES
|
||||||
c_torch = ndef->getId("default:torch");
|
c_torch = ndef->getId("default:torch");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dparams) {
|
if (dparams) {
|
||||||
memcpy(&dp, dparams, sizeof(dp));
|
memcpy(&dp, dparams, sizeof(dp));
|
||||||
} else {
|
} else {
|
||||||
@ -95,7 +95,7 @@ void DungeonGen::generate(u32 bseed, v3s16 nmin, v3s16 nmax) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add it
|
// Add it
|
||||||
makeDungeon(v3s16(1,1,1) * MAP_BLOCKSIZE);
|
makeDungeon(v3s16(1,1,1) * MAP_BLOCKSIZE);
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ void DungeonGen::generate(u32 bseed, v3s16 nmin, v3s16 nmax) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("== gen dungeons: %dms\n", t.stop());
|
//printf("== gen dungeons: %dms\n", t.stop());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ void DungeonGen::makeDungeon(v3s16 start_padding)
|
|||||||
random.range(0,areasize.X-roomsize.X-1-start_padding.X),
|
random.range(0,areasize.X-roomsize.X-1-start_padding.X),
|
||||||
random.range(0,areasize.Y-roomsize.Y-1-start_padding.Y),
|
random.range(0,areasize.Y-roomsize.Y-1-start_padding.Y),
|
||||||
random.range(0,areasize.Z-roomsize.Z-1-start_padding.Z));
|
random.range(0,areasize.Z-roomsize.Z-1-start_padding.Z));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check that we're not putting the room to an unknown place,
|
Check that we're not putting the room to an unknown place,
|
||||||
otherwise it might end up floating in the air
|
otherwise it might end up floating in the air
|
||||||
@ -181,10 +181,7 @@ void DungeonGen::makeDungeon(v3s16 start_padding)
|
|||||||
makeRoom(roomsize, roomplace);
|
makeRoom(roomsize, roomplace);
|
||||||
|
|
||||||
v3s16 room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2);
|
v3s16 room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2);
|
||||||
if (mg->gennotify & (1 << dp.notifytype)) {
|
mg->gennotify.addEvent(dp.notifytype, room_center);
|
||||||
std::vector <v3s16> *nvec = mg->gen_notifications[dp.notifytype];
|
|
||||||
nvec->push_back(room_center);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DGEN_USE_TORCHES
|
#ifdef DGEN_USE_TORCHES
|
||||||
// Place torch at room center (for testing)
|
// Place torch at room center (for testing)
|
||||||
@ -212,7 +209,7 @@ void DungeonGen::makeDungeon(v3s16 start_padding)
|
|||||||
// Create walker and find a place for a door
|
// Create walker and find a place for a door
|
||||||
v3s16 doorplace;
|
v3s16 doorplace;
|
||||||
v3s16 doordir;
|
v3s16 doordir;
|
||||||
|
|
||||||
m_pos = walker_start_place;
|
m_pos = walker_start_place;
|
||||||
if (!findPlaceForDoor(doorplace, doordir))
|
if (!findPlaceForDoor(doorplace, doordir))
|
||||||
return;
|
return;
|
||||||
@ -253,7 +250,7 @@ void DungeonGen::makeRoom(v3s16 roomsize, v3s16 roomplace)
|
|||||||
{
|
{
|
||||||
MapNode n_cobble(dp.c_cobble);
|
MapNode n_cobble(dp.c_cobble);
|
||||||
MapNode n_air(CONTENT_AIR);
|
MapNode n_air(CONTENT_AIR);
|
||||||
|
|
||||||
// Make +-X walls
|
// Make +-X walls
|
||||||
for (s16 z = 0; z < roomsize.Z; z++)
|
for (s16 z = 0; z < roomsize.Z; z++)
|
||||||
for (s16 y = 0; y < roomsize.Y; y++)
|
for (s16 y = 0; y < roomsize.Y; y++)
|
||||||
@ -393,10 +390,10 @@ void DungeonGen::makeCorridor(v3s16 doorplace,
|
|||||||
u32 partlength = random.range(1, 13);
|
u32 partlength = random.range(1, 13);
|
||||||
u32 partcount = 0;
|
u32 partcount = 0;
|
||||||
s16 make_stairs = 0;
|
s16 make_stairs = 0;
|
||||||
|
|
||||||
if (random.next() % 2 == 0 && partlength >= 3)
|
if (random.next() % 2 == 0 && partlength >= 3)
|
||||||
make_stairs = random.next() % 2 ? 1 : -1;
|
make_stairs = random.next() % 2 ? 1 : -1;
|
||||||
|
|
||||||
for (u32 i = 0; i < length; i++) {
|
for (u32 i = 0; i < length; i++) {
|
||||||
v3s16 p = p0 + dir;
|
v3s16 p = p0 + dir;
|
||||||
if (partcount != 0)
|
if (partcount != 0)
|
||||||
@ -409,7 +406,7 @@ void DungeonGen::makeCorridor(v3s16 doorplace,
|
|||||||
VMANIP_FLAG_DUNGEON_UNTOUCHABLE, MapNode(dp.c_cobble), 0);
|
VMANIP_FLAG_DUNGEON_UNTOUCHABLE, MapNode(dp.c_cobble), 0);
|
||||||
makeHole(p);
|
makeHole(p);
|
||||||
makeHole(p - dir);
|
makeHole(p - dir);
|
||||||
|
|
||||||
// TODO: fix stairs code so it works 100% (quite difficult)
|
// TODO: fix stairs code so it works 100% (quite difficult)
|
||||||
|
|
||||||
// exclude stairs from the bottom step
|
// exclude stairs from the bottom step
|
||||||
@ -419,11 +416,11 @@ void DungeonGen::makeCorridor(v3s16 doorplace,
|
|||||||
((make_stairs == -1) && i != length - 1))) {
|
((make_stairs == -1) && i != length - 1))) {
|
||||||
// rotate face 180 deg if making stairs backwards
|
// rotate face 180 deg if making stairs backwards
|
||||||
int facedir = dir_to_facedir(dir * make_stairs);
|
int facedir = dir_to_facedir(dir * make_stairs);
|
||||||
|
|
||||||
u32 vi = vm->m_area.index(p.X - dir.X, p.Y - 1, p.Z - dir.Z);
|
u32 vi = vm->m_area.index(p.X - dir.X, p.Y - 1, p.Z - dir.Z);
|
||||||
if (vm->m_data[vi].getContent() == dp.c_cobble)
|
if (vm->m_data[vi].getContent() == dp.c_cobble)
|
||||||
vm->m_data[vi] = MapNode(dp.c_stair, 0, facedir);
|
vm->m_data[vi] = MapNode(dp.c_stair, 0, facedir);
|
||||||
|
|
||||||
vi = vm->m_area.index(p.X, p.Y, p.Z);
|
vi = vm->m_area.index(p.X, p.Y, p.Z);
|
||||||
if (vm->m_data[vi].getContent() == dp.c_cobble)
|
if (vm->m_data[vi].getContent() == dp.c_cobble)
|
||||||
vm->m_data[vi] = MapNode(dp.c_stair, 0, facedir);
|
vm->m_data[vi] = MapNode(dp.c_stair, 0, facedir);
|
||||||
|
@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include "voxel.h"
|
#include "voxel.h"
|
||||||
#include "noise.h"
|
#include "noise.h"
|
||||||
|
#include "mapgen.h"
|
||||||
|
|
||||||
#define VMANIP_FLAG_DUNGEON_INSIDE VOXELFLAG_CHECKED1
|
#define VMANIP_FLAG_DUNGEON_INSIDE VOXELFLAG_CHECKED1
|
||||||
#define VMANIP_FLAG_DUNGEON_PRESERVE VOXELFLAG_CHECKED2
|
#define VMANIP_FLAG_DUNGEON_PRESERVE VOXELFLAG_CHECKED2
|
||||||
@ -30,7 +31,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
class ManualMapVoxelManipulator;
|
class ManualMapVoxelManipulator;
|
||||||
class INodeDefManager;
|
class INodeDefManager;
|
||||||
class Mapgen;
|
|
||||||
|
|
||||||
v3s16 rand_ortho_dir(PseudoRandom &random, bool diagonal_dirs);
|
v3s16 rand_ortho_dir(PseudoRandom &random, bool diagonal_dirs);
|
||||||
v3s16 turn_xz(v3s16 olddir, int t);
|
v3s16 turn_xz(v3s16 olddir, int t);
|
||||||
@ -44,7 +44,7 @@ struct DungeonParams {
|
|||||||
content_t c_moss;
|
content_t c_moss;
|
||||||
content_t c_stair;
|
content_t c_stair;
|
||||||
|
|
||||||
int notifytype;
|
GenNotifyType notifytype;
|
||||||
bool diagonal_dirs;
|
bool diagonal_dirs;
|
||||||
float mossratio;
|
float mossratio;
|
||||||
v3s16 holesize;
|
v3s16 holesize;
|
||||||
@ -65,14 +65,14 @@ public:
|
|||||||
|
|
||||||
content_t c_torch;
|
content_t c_torch;
|
||||||
DungeonParams dp;
|
DungeonParams dp;
|
||||||
|
|
||||||
//RoomWalker
|
//RoomWalker
|
||||||
v3s16 m_pos;
|
v3s16 m_pos;
|
||||||
v3s16 m_dir;
|
v3s16 m_dir;
|
||||||
|
|
||||||
DungeonGen(Mapgen *mg, DungeonParams *dparams);
|
DungeonGen(Mapgen *mg, DungeonParams *dparams);
|
||||||
void generate(u32 bseed, v3s16 full_node_min, v3s16 full_node_max);
|
void generate(u32 bseed, v3s16 full_node_min, v3s16 full_node_max);
|
||||||
|
|
||||||
void makeDungeon(v3s16 start_padding);
|
void makeDungeon(v3s16 start_padding);
|
||||||
void makeRoom(v3s16 roomsize, v3s16 roomplace);
|
void makeRoom(v3s16 roomsize, v3s16 roomplace);
|
||||||
void makeCorridor(v3s16 doorplace, v3s16 doordir,
|
void makeCorridor(v3s16 doorplace, v3s16 doordir,
|
||||||
@ -84,7 +84,7 @@ public:
|
|||||||
bool findPlaceForDoor(v3s16 &result_place, v3s16 &result_dir);
|
bool findPlaceForDoor(v3s16 &result_place, v3s16 &result_dir);
|
||||||
bool findPlaceForRoomDoor(v3s16 roomsize, v3s16 &result_doorplace,
|
bool findPlaceForRoomDoor(v3s16 roomsize, v3s16 &result_doorplace,
|
||||||
v3s16 &result_doordir, v3s16 &result_roomplace);
|
v3s16 &result_doordir, v3s16 &result_roomplace);
|
||||||
|
|
||||||
void randomizeDir()
|
void randomizeDir()
|
||||||
{
|
{
|
||||||
m_dir = rand_ortho_dir(random, dp.diagonal_dirs);
|
m_dir = rand_ortho_dir(random, dp.diagonal_dirs);
|
||||||
|
@ -94,7 +94,7 @@ EmergeManager::EmergeManager(IGameDef *gamedef) {
|
|||||||
this->oremgr = new OreManager(gamedef);
|
this->oremgr = new OreManager(gamedef);
|
||||||
this->decomgr = new DecorationManager(gamedef);
|
this->decomgr = new DecorationManager(gamedef);
|
||||||
this->schemmgr = new SchematicManager(gamedef);
|
this->schemmgr = new SchematicManager(gamedef);
|
||||||
this->gennotify = 0;
|
this->gen_notify_on = 0;
|
||||||
|
|
||||||
// Note that accesses to this variable are not synchronized.
|
// Note that accesses to this variable are not synchronized.
|
||||||
// This is because the *only* thread ever starting or stopping
|
// This is because the *only* thread ever starting or stopping
|
||||||
|
@ -89,7 +89,8 @@ public:
|
|||||||
u16 qlimit_diskonly;
|
u16 qlimit_diskonly;
|
||||||
u16 qlimit_generate;
|
u16 qlimit_generate;
|
||||||
|
|
||||||
u32 gennotify;
|
u32 gen_notify_on;
|
||||||
|
std::set<u32> gen_notify_on_deco_ids;
|
||||||
|
|
||||||
//// Block emerge queue data structures
|
//// Block emerge queue data structures
|
||||||
JMutex queuemutex;
|
JMutex queuemutex;
|
||||||
|
129
src/mapgen.cpp
129
src/mapgen.cpp
@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "content_sao.h"
|
#include "content_sao.h"
|
||||||
#include "nodedef.h"
|
#include "nodedef.h"
|
||||||
|
#include "emerge.h"
|
||||||
#include "content_mapnode.h" // For content_mapnode_get_new_name
|
#include "content_mapnode.h" // For content_mapnode_get_new_name
|
||||||
#include "voxelalgorithms.h"
|
#include "voxelalgorithms.h"
|
||||||
#include "profiler.h"
|
#include "profiler.h"
|
||||||
@ -55,36 +56,53 @@ FlagDesc flagdesc_gennotify[] = {
|
|||||||
{"cave_end", 1 << GENNOTIFY_CAVE_END},
|
{"cave_end", 1 << GENNOTIFY_CAVE_END},
|
||||||
{"large_cave_begin", 1 << GENNOTIFY_LARGECAVE_BEGIN},
|
{"large_cave_begin", 1 << GENNOTIFY_LARGECAVE_BEGIN},
|
||||||
{"large_cave_end", 1 << GENNOTIFY_LARGECAVE_END},
|
{"large_cave_end", 1 << GENNOTIFY_LARGECAVE_END},
|
||||||
|
{"decoration", 1 << GENNOTIFY_DECORATION},
|
||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Mapgen::Mapgen()
|
||||||
|
{
|
||||||
|
generating = false;
|
||||||
|
id = -1;
|
||||||
|
seed = 0;
|
||||||
|
water_level = 0;
|
||||||
|
flags = 0;
|
||||||
|
|
||||||
Mapgen::Mapgen() {
|
|
||||||
seed = 0;
|
|
||||||
water_level = 0;
|
|
||||||
generating = false;
|
|
||||||
id = -1;
|
|
||||||
vm = NULL;
|
vm = NULL;
|
||||||
ndef = NULL;
|
ndef = NULL;
|
||||||
heightmap = NULL;
|
heightmap = NULL;
|
||||||
biomemap = NULL;
|
biomemap = NULL;
|
||||||
|
|
||||||
for (unsigned int i = 0; i != NUM_GEN_NOTIFY; i++)
|
|
||||||
gen_notifications[i] = new std::vector<v3s16>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Mapgen::~Mapgen() {
|
Mapgen::Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge) :
|
||||||
for (unsigned int i = 0; i != NUM_GEN_NOTIFY; i++)
|
gennotify(emerge->gen_notify_on, &emerge->gen_notify_on_deco_ids)
|
||||||
delete gen_notifications[i];
|
{
|
||||||
|
generating = false;
|
||||||
|
id = mapgenid;
|
||||||
|
seed = (int)params->seed;
|
||||||
|
water_level = params->water_level;
|
||||||
|
flags = params->flags;
|
||||||
|
csize = v3s16(1, 1, 1) * (params->chunksize * MAP_BLOCKSIZE);
|
||||||
|
|
||||||
|
vm = NULL;
|
||||||
|
ndef = NULL;
|
||||||
|
heightmap = NULL;
|
||||||
|
biomemap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Mapgen::~Mapgen()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns Y one under area minimum if not found
|
// Returns Y one under area minimum if not found
|
||||||
s16 Mapgen::findGroundLevelFull(v2s16 p2d) {
|
s16 Mapgen::findGroundLevelFull(v2s16 p2d)
|
||||||
|
{
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
s16 y_nodes_max = vm->m_area.MaxEdge.Y;
|
s16 y_nodes_max = vm->m_area.MaxEdge.Y;
|
||||||
s16 y_nodes_min = vm->m_area.MinEdge.Y;
|
s16 y_nodes_min = vm->m_area.MinEdge.Y;
|
||||||
@ -102,7 +120,8 @@ s16 Mapgen::findGroundLevelFull(v2s16 p2d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax) {
|
s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax)
|
||||||
|
{
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
u32 i = vm->m_area.index(p2d.X, ymax, p2d.Y);
|
u32 i = vm->m_area.index(p2d.X, ymax, p2d.Y);
|
||||||
s16 y;
|
s16 y;
|
||||||
@ -118,7 +137,8 @@ s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax) {
|
void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax)
|
||||||
|
{
|
||||||
if (!heightmap)
|
if (!heightmap)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -141,7 +161,8 @@ void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Mapgen::updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax) {
|
void Mapgen::updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax)
|
||||||
|
{
|
||||||
bool isliquid, wasliquid;
|
bool isliquid, wasliquid;
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
|
|
||||||
@ -165,7 +186,8 @@ void Mapgen::updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nm
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Mapgen::setLighting(v3s16 nmin, v3s16 nmax, u8 light) {
|
void Mapgen::setLighting(v3s16 nmin, v3s16 nmax, u8 light)
|
||||||
|
{
|
||||||
ScopeProfiler sp(g_profiler, "EmergeThread: mapgen lighting update", SPT_AVG);
|
ScopeProfiler sp(g_profiler, "EmergeThread: mapgen lighting update", SPT_AVG);
|
||||||
VoxelArea a(nmin, nmax);
|
VoxelArea a(nmin, nmax);
|
||||||
|
|
||||||
@ -179,7 +201,8 @@ void Mapgen::setLighting(v3s16 nmin, v3s16 nmax, u8 light) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Mapgen::lightSpread(VoxelArea &a, v3s16 p, u8 light) {
|
void Mapgen::lightSpread(VoxelArea &a, v3s16 p, u8 light)
|
||||||
|
{
|
||||||
if (light <= 1 || !a.contains(p))
|
if (light <= 1 || !a.contains(p))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -202,7 +225,8 @@ void Mapgen::lightSpread(VoxelArea &a, v3s16 p, u8 light) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Mapgen::calcLighting(v3s16 nmin, v3s16 nmax) {
|
void Mapgen::calcLighting(v3s16 nmin, v3s16 nmax)
|
||||||
|
{
|
||||||
VoxelArea a(nmin, nmax);
|
VoxelArea a(nmin, nmax);
|
||||||
bool block_is_underground = (water_level >= nmax.Y);
|
bool block_is_underground = (water_level >= nmax.Y);
|
||||||
|
|
||||||
@ -264,7 +288,8 @@ void Mapgen::calcLighting(v3s16 nmin, v3s16 nmax) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Mapgen::calcLightingOld(v3s16 nmin, v3s16 nmax) {
|
void Mapgen::calcLightingOld(v3s16 nmin, v3s16 nmax)
|
||||||
|
{
|
||||||
enum LightBank banks[2] = {LIGHTBANK_DAY, LIGHTBANK_NIGHT};
|
enum LightBank banks[2] = {LIGHTBANK_DAY, LIGHTBANK_NIGHT};
|
||||||
VoxelArea a(nmin, nmax);
|
VoxelArea a(nmin, nmax);
|
||||||
bool block_is_underground = (water_level > nmax.Y);
|
bool block_is_underground = (water_level > nmax.Y);
|
||||||
@ -287,6 +312,72 @@ void Mapgen::calcLightingOld(v3s16 nmin, v3s16 nmax) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GenerateNotifier::GenerateNotifier()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GenerateNotifier::GenerateNotifier(u32 notify_on,
|
||||||
|
std::set<u32> *notify_on_deco_ids)
|
||||||
|
{
|
||||||
|
m_notify_on = notify_on;
|
||||||
|
m_notify_on_deco_ids = notify_on_deco_ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GenerateNotifier::setNotifyOn(u32 notify_on)
|
||||||
|
{
|
||||||
|
m_notify_on = notify_on;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GenerateNotifier::setNotifyOnDecoIds(std::set<u32> *notify_on_deco_ids)
|
||||||
|
{
|
||||||
|
m_notify_on_deco_ids = notify_on_deco_ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GenerateNotifier::addEvent(GenNotifyType type, v3s16 pos, u32 id)
|
||||||
|
{
|
||||||
|
if (!(m_notify_on & (1 << type)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (type == GENNOTIFY_DECORATION &&
|
||||||
|
m_notify_on_deco_ids->find(id) == m_notify_on_deco_ids->end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
GenNotifyEvent gne;
|
||||||
|
gne.type = type;
|
||||||
|
gne.pos = pos;
|
||||||
|
gne.id = id;
|
||||||
|
m_notify_events.push_back(gne);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GenerateNotifier::getEvents(
|
||||||
|
std::map<std::string, std::vector<v3s16> > &event_map,
|
||||||
|
bool peek_events)
|
||||||
|
{
|
||||||
|
std::list<GenNotifyEvent>::iterator it;
|
||||||
|
|
||||||
|
for (it = m_notify_events.begin(); it != m_notify_events.end(); ++it) {
|
||||||
|
GenNotifyEvent &gn = *it;
|
||||||
|
std::string name = (gn.type == GENNOTIFY_DECORATION) ?
|
||||||
|
"decoration#"+ itos(gn.id) :
|
||||||
|
flagdesc_gennotify[gn.type].name;
|
||||||
|
|
||||||
|
event_map[name].push_back(gn.pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!peek_events)
|
||||||
|
m_notify_events.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
40
src/mapgen.h
40
src/mapgen.h
@ -34,8 +34,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define MG_FLAT 0x08
|
#define MG_FLAT 0x08
|
||||||
#define MG_LIGHT 0x10
|
#define MG_LIGHT 0x10
|
||||||
|
|
||||||
#define NUM_GEN_NOTIFY 6
|
|
||||||
|
|
||||||
class Settings;
|
class Settings;
|
||||||
class ManualMapVoxelManipulator;
|
class ManualMapVoxelManipulator;
|
||||||
class INodeDefManager;
|
class INodeDefManager;
|
||||||
@ -61,13 +59,39 @@ enum MapgenObject {
|
|||||||
MGOBJ_GENNOTIFY
|
MGOBJ_GENNOTIFY
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GenNotify {
|
enum GenNotifyType {
|
||||||
GENNOTIFY_DUNGEON,
|
GENNOTIFY_DUNGEON,
|
||||||
GENNOTIFY_TEMPLE,
|
GENNOTIFY_TEMPLE,
|
||||||
GENNOTIFY_CAVE_BEGIN,
|
GENNOTIFY_CAVE_BEGIN,
|
||||||
GENNOTIFY_CAVE_END,
|
GENNOTIFY_CAVE_END,
|
||||||
GENNOTIFY_LARGECAVE_BEGIN,
|
GENNOTIFY_LARGECAVE_BEGIN,
|
||||||
GENNOTIFY_LARGECAVE_END
|
GENNOTIFY_LARGECAVE_END,
|
||||||
|
GENNOTIFY_DECORATION,
|
||||||
|
NUM_GENNOTIFY_TYPES
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GenNotifyEvent {
|
||||||
|
GenNotifyType type;
|
||||||
|
v3s16 pos;
|
||||||
|
u32 id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GenerateNotifier {
|
||||||
|
public:
|
||||||
|
GenerateNotifier();
|
||||||
|
GenerateNotifier(u32 notify_on, std::set<u32> *notify_on_deco_ids);
|
||||||
|
|
||||||
|
void setNotifyOn(u32 notify_on);
|
||||||
|
void setNotifyOnDecoIds(std::set<u32> *notify_on_deco_ids);
|
||||||
|
|
||||||
|
bool addEvent(GenNotifyType type, v3s16 pos, u32 id=0);
|
||||||
|
void getEvents(std::map<std::string, std::vector<v3s16> > &event_map,
|
||||||
|
bool peek_events=false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
u32 m_notify_on;
|
||||||
|
std::set<u32> *m_notify_on_deco_ids;
|
||||||
|
std::list<GenNotifyEvent> m_notify_events;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MapgenSpecificParams {
|
struct MapgenSpecificParams {
|
||||||
@ -85,7 +109,8 @@ struct MapgenParams {
|
|||||||
|
|
||||||
MapgenSpecificParams *sparams;
|
MapgenSpecificParams *sparams;
|
||||||
|
|
||||||
MapgenParams() {
|
MapgenParams()
|
||||||
|
{
|
||||||
mg_name = DEFAULT_MAPGEN;
|
mg_name = DEFAULT_MAPGEN;
|
||||||
seed = 0;
|
seed = 0;
|
||||||
water_level = 1;
|
water_level = 1;
|
||||||
@ -99,6 +124,7 @@ class Mapgen {
|
|||||||
public:
|
public:
|
||||||
int seed;
|
int seed;
|
||||||
int water_level;
|
int water_level;
|
||||||
|
u32 flags;
|
||||||
bool generating;
|
bool generating;
|
||||||
int id;
|
int id;
|
||||||
ManualMapVoxelManipulator *vm;
|
ManualMapVoxelManipulator *vm;
|
||||||
@ -108,10 +134,10 @@ public:
|
|||||||
u8 *biomemap;
|
u8 *biomemap;
|
||||||
v3s16 csize;
|
v3s16 csize;
|
||||||
|
|
||||||
u32 gennotify;
|
GenerateNotifier gennotify;
|
||||||
std::vector<v3s16> *gen_notifications[NUM_GEN_NOTIFY];
|
|
||||||
|
|
||||||
Mapgen();
|
Mapgen();
|
||||||
|
Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge);
|
||||||
virtual ~Mapgen();
|
virtual ~Mapgen();
|
||||||
|
|
||||||
s16 findGroundLevelFull(v2s16 p2d);
|
s16 findGroundLevelFull(v2s16 p2d);
|
||||||
|
@ -39,7 +39,8 @@ void MapgenSinglenodeParams::writeParams(Settings *settings) {
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
MapgenSinglenode::MapgenSinglenode(int mapgenid,
|
MapgenSinglenode::MapgenSinglenode(int mapgenid,
|
||||||
MapgenParams *params, EmergeManager *emerge)
|
MapgenParams *params, EmergeManager *emerge)
|
||||||
|
: Mapgen(mapgenid, params, emerge)
|
||||||
{
|
{
|
||||||
flags = params->flags;
|
flags = params->flags;
|
||||||
|
|
||||||
@ -67,18 +68,18 @@ void MapgenSinglenode::makeChunk(BlockMakeData *data) {
|
|||||||
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
||||||
|
|
||||||
this->generating = true;
|
this->generating = true;
|
||||||
this->vm = data->vmanip;
|
this->vm = data->vmanip;
|
||||||
this->ndef = data->nodedef;
|
this->ndef = data->nodedef;
|
||||||
|
|
||||||
v3s16 blockpos_min = data->blockpos_min;
|
v3s16 blockpos_min = data->blockpos_min;
|
||||||
v3s16 blockpos_max = data->blockpos_max;
|
v3s16 blockpos_max = data->blockpos_max;
|
||||||
|
|
||||||
// Area of central chunk
|
// Area of central chunk
|
||||||
v3s16 node_min = blockpos_min*MAP_BLOCKSIZE;
|
v3s16 node_min = blockpos_min*MAP_BLOCKSIZE;
|
||||||
v3s16 node_max = (blockpos_max+v3s16(1,1,1))*MAP_BLOCKSIZE-v3s16(1,1,1);
|
v3s16 node_max = (blockpos_max+v3s16(1,1,1))*MAP_BLOCKSIZE-v3s16(1,1,1);
|
||||||
|
|
||||||
MapNode n_node(c_node);
|
MapNode n_node(c_node);
|
||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
||||||
u32 i = vm->m_area.index(node_min.X, y, z);
|
u32 i = vm->m_area.index(node_min.X, y, z);
|
||||||
@ -96,7 +97,7 @@ void MapgenSinglenode::makeChunk(BlockMakeData *data) {
|
|||||||
if (flags & MG_LIGHT)
|
if (flags & MG_LIGHT)
|
||||||
calcLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
calcLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
||||||
node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
|
node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
|
||||||
|
|
||||||
this->generating = false;
|
this->generating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,19 +47,12 @@ FlagDesc flagdesc_mapgen_v5[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_) {
|
MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_)
|
||||||
this->generating = false;
|
: Mapgen(mapgenid, params, emerge)
|
||||||
this->id = mapgenid;
|
{
|
||||||
this->emerge = emerge_;
|
this->emerge = emerge_;
|
||||||
this->bmgr = emerge->biomemgr;
|
this->bmgr = emerge->biomemgr;
|
||||||
|
|
||||||
this->seed = (int)params->seed;
|
|
||||||
this->water_level = params->water_level;
|
|
||||||
this->flags = params->flags;
|
|
||||||
this->gennotify = emerge->gennotify;
|
|
||||||
|
|
||||||
this->csize = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE;
|
|
||||||
|
|
||||||
// amount of elements to skip for the next index
|
// amount of elements to skip for the next index
|
||||||
// for noise/height/biome maps (not vmanip)
|
// for noise/height/biome maps (not vmanip)
|
||||||
this->ystride = csize.X;
|
this->ystride = csize.X;
|
||||||
@ -69,8 +62,7 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_) {
|
|||||||
this->heightmap = new s16[csize.X * csize.Z];
|
this->heightmap = new s16[csize.X * csize.Z];
|
||||||
|
|
||||||
MapgenV5Params *sp = (MapgenV5Params *)params->sparams;
|
MapgenV5Params *sp = (MapgenV5Params *)params->sparams;
|
||||||
|
this->spflags = sp->spflags;
|
||||||
this->spflags = sp->spflags;
|
|
||||||
|
|
||||||
// Terrain noise
|
// Terrain noise
|
||||||
noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z);
|
noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z);
|
||||||
@ -129,7 +121,7 @@ MapgenV5::~MapgenV5() {
|
|||||||
|
|
||||||
delete noise_heat;
|
delete noise_heat;
|
||||||
delete noise_humidity;
|
delete noise_humidity;
|
||||||
|
|
||||||
delete[] heightmap;
|
delete[] heightmap;
|
||||||
delete[] biomemap;
|
delete[] biomemap;
|
||||||
}
|
}
|
||||||
@ -234,12 +226,12 @@ void MapgenV5::makeChunk(BlockMakeData *data) {
|
|||||||
assert(data->blockpos_requested.X <= data->blockpos_max.X &&
|
assert(data->blockpos_requested.X <= data->blockpos_max.X &&
|
||||||
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
||||||
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
||||||
|
|
||||||
generating = true;
|
generating = true;
|
||||||
vm = data->vmanip;
|
vm = data->vmanip;
|
||||||
ndef = data->nodedef;
|
ndef = data->nodedef;
|
||||||
//TimeTaker t("makeChunk");
|
//TimeTaker t("makeChunk");
|
||||||
|
|
||||||
v3s16 blockpos_min = data->blockpos_min;
|
v3s16 blockpos_min = data->blockpos_min;
|
||||||
v3s16 blockpos_max = data->blockpos_max;
|
v3s16 blockpos_max = data->blockpos_max;
|
||||||
node_min = blockpos_min * MAP_BLOCKSIZE;
|
node_min = blockpos_min * MAP_BLOCKSIZE;
|
||||||
@ -249,7 +241,7 @@ void MapgenV5::makeChunk(BlockMakeData *data) {
|
|||||||
|
|
||||||
// Create a block-specific seed
|
// Create a block-specific seed
|
||||||
blockseed = emerge->getBlockSeed(full_node_min); //////use getBlockSeed2()!
|
blockseed = emerge->getBlockSeed(full_node_min); //////use getBlockSeed2()!
|
||||||
|
|
||||||
// Make some noise
|
// Make some noise
|
||||||
calculateNoise();
|
calculateNoise();
|
||||||
|
|
||||||
@ -265,7 +257,7 @@ void MapgenV5::makeChunk(BlockMakeData *data) {
|
|||||||
// Calculate biomes
|
// Calculate biomes
|
||||||
bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
|
bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
|
||||||
noise_humidity->result, heightmap, biomemap);
|
noise_humidity->result, heightmap, biomemap);
|
||||||
|
|
||||||
// Actually place the biome-specific nodes
|
// Actually place the biome-specific nodes
|
||||||
generateBiomes();
|
generateBiomes();
|
||||||
|
|
||||||
@ -288,12 +280,12 @@ void MapgenV5::makeChunk(BlockMakeData *data) {
|
|||||||
|
|
||||||
// Add top and bottom side of water to transforming_liquid queue
|
// Add top and bottom side of water to transforming_liquid queue
|
||||||
updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
|
updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
|
||||||
|
|
||||||
// Calculate lighting
|
// Calculate lighting
|
||||||
if (flags & MG_LIGHT)
|
if (flags & MG_LIGHT)
|
||||||
calcLighting(node_min - v3s16(0, 1, 0) - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
calcLighting(node_min - v3s16(0, 1, 0) - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
||||||
node_max + v3s16(0, 1, 0) + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
|
node_max + v3s16(0, 1, 0) + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
|
||||||
|
|
||||||
this->generating = false;
|
this->generating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +295,7 @@ void MapgenV5::calculateNoise() {
|
|||||||
int x = node_min.X;
|
int x = node_min.X;
|
||||||
int y = node_min.Y - 1;
|
int y = node_min.Y - 1;
|
||||||
int z = node_min.Z;
|
int z = node_min.Z;
|
||||||
|
|
||||||
noise_filler_depth->perlinMap2D(x, z);
|
noise_filler_depth->perlinMap2D(x, z);
|
||||||
noise_factor->perlinMap2D(x, z);
|
noise_factor->perlinMap2D(x, z);
|
||||||
noise_height->perlinMap2D(x, z);
|
noise_height->perlinMap2D(x, z);
|
||||||
@ -426,20 +418,20 @@ void MapgenV5::generateBiomes() {
|
|||||||
|
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||||
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
||||||
s16 dfiller = biome->depth_filler + noise_filler_depth->result[index];
|
s16 dfiller = biome->depth_filler + noise_filler_depth->result[index];
|
||||||
s16 y0_top = biome->depth_top;
|
s16 y0_top = biome->depth_top;
|
||||||
s16 y0_filler = biome->depth_top + dfiller;
|
s16 y0_filler = biome->depth_top + dfiller;
|
||||||
|
|
||||||
s16 nplaced = 0;
|
s16 nplaced = 0;
|
||||||
u32 i = vm->m_area.index(x, node_max.Y, z);
|
u32 i = vm->m_area.index(x, node_max.Y, z);
|
||||||
|
|
||||||
content_t c_above = vm->m_data[i + em.X].getContent();
|
content_t c_above = vm->m_data[i + em.X].getContent();
|
||||||
bool have_air = c_above == CONTENT_AIR;
|
bool have_air = c_above == CONTENT_AIR;
|
||||||
|
|
||||||
for (s16 y = node_max.Y; y >= node_min.Y; y--) {
|
for (s16 y = node_max.Y; y >= node_min.Y; y--) {
|
||||||
content_t c = vm->m_data[i].getContent();
|
content_t c = vm->m_data[i].getContent();
|
||||||
bool is_replaceable_content =
|
bool is_replaceable_content =
|
||||||
@ -448,7 +440,7 @@ void MapgenV5::generateBiomes() {
|
|||||||
|
|
||||||
if (is_replaceable_content && have_air) {
|
if (is_replaceable_content && have_air) {
|
||||||
content_t c_below = vm->m_data[i - em.X].getContent();
|
content_t c_below = vm->m_data[i - em.X].getContent();
|
||||||
|
|
||||||
if (c_below != CONTENT_AIR) {
|
if (c_below != CONTENT_AIR) {
|
||||||
if (nplaced < y0_top) {
|
if (nplaced < y0_top) {
|
||||||
if(y < water_level)
|
if(y < water_level)
|
||||||
@ -484,7 +476,7 @@ void MapgenV5::generateBiomes() {
|
|||||||
have_air = true;
|
have_air = true;
|
||||||
nplaced = 0;
|
nplaced = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vm->m_area.add_y(em, i, -1);
|
vm->m_area.add_y(em, i, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -493,14 +485,14 @@ void MapgenV5::generateBiomes() {
|
|||||||
void MapgenV5::dustTopNodes() {
|
void MapgenV5::dustTopNodes() {
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
|
|
||||||
if (water_level > node_max.Y)
|
if (water_level > node_max.Y)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||||
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
||||||
|
|
||||||
if (biome->c_dust == CONTENT_IGNORE)
|
if (biome->c_dust == CONTENT_IGNORE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -512,18 +504,18 @@ void MapgenV5::dustTopNodes() {
|
|||||||
|
|
||||||
vm->m_area.add_y(em, vi, -1);
|
vm->m_area.add_y(em, vi, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
content_t c = vm->m_data[vi].getContent();
|
content_t c = vm->m_data[vi].getContent();
|
||||||
if (c == biome->c_water && biome->c_dust_water != CONTENT_IGNORE) {
|
if (c == biome->c_water && biome->c_dust_water != CONTENT_IGNORE) {
|
||||||
if (y < node_min.Y - 1)
|
if (y < node_min.Y - 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vm->m_data[vi] = MapNode(biome->c_dust_water);
|
vm->m_data[vi] = MapNode(biome->c_dust_water);
|
||||||
} else if (!ndef->get(c).buildable_to && c != CONTENT_IGNORE
|
} else if (!ndef->get(c).buildable_to && c != CONTENT_IGNORE
|
||||||
&& c != biome->c_dust) {
|
&& c != biome->c_dust) {
|
||||||
if (y == node_max.Y + 1)
|
if (y == node_max.Y + 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vm->m_area.add_y(em, vi, 1);
|
vm->m_area.add_y(em, vi, 1);
|
||||||
vm->m_data[vi] = MapNode(biome->c_dust);
|
vm->m_data[vi] = MapNode(biome->c_dust);
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ struct MapgenV5Params : public MapgenSpecificParams {
|
|||||||
|
|
||||||
MapgenV5Params();
|
MapgenV5Params();
|
||||||
~MapgenV5Params() {}
|
~MapgenV5Params() {}
|
||||||
|
|
||||||
void readParams(Settings *settings);
|
void readParams(Settings *settings);
|
||||||
void writeParams(Settings *settings);
|
void writeParams(Settings *settings);
|
||||||
};
|
};
|
||||||
@ -54,7 +54,6 @@ public:
|
|||||||
|
|
||||||
int ystride;
|
int ystride;
|
||||||
int zstride;
|
int zstride;
|
||||||
u32 flags;
|
|
||||||
u32 spflags;
|
u32 spflags;
|
||||||
|
|
||||||
u32 blockseed;
|
u32 blockseed;
|
||||||
@ -62,7 +61,7 @@ public:
|
|||||||
v3s16 node_max;
|
v3s16 node_max;
|
||||||
v3s16 full_node_min;
|
v3s16 full_node_min;
|
||||||
v3s16 full_node_max;
|
v3s16 full_node_max;
|
||||||
|
|
||||||
Noise *noise_filler_depth;
|
Noise *noise_filler_depth;
|
||||||
Noise *noise_factor;
|
Noise *noise_factor;
|
||||||
Noise *noise_height;
|
Noise *noise_height;
|
||||||
@ -92,7 +91,7 @@ public:
|
|||||||
|
|
||||||
MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_);
|
MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_);
|
||||||
~MapgenV5();
|
~MapgenV5();
|
||||||
|
|
||||||
virtual void makeChunk(BlockMakeData *data);
|
virtual void makeChunk(BlockMakeData *data);
|
||||||
int getGroundLevelAtPoint(v2s16 p);
|
int getGroundLevelAtPoint(v2s16 p);
|
||||||
void calculateNoise();
|
void calculateNoise();
|
||||||
@ -107,7 +106,7 @@ struct MapgenFactoryV5 : public MapgenFactory {
|
|||||||
Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
|
Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
|
||||||
return new MapgenV5(mgid, params, emerge);
|
return new MapgenV5(mgid, params, emerge);
|
||||||
};
|
};
|
||||||
|
|
||||||
MapgenSpecificParams *createMapgenParams() {
|
MapgenSpecificParams *createMapgenParams() {
|
||||||
return new MapgenV5Params();
|
return new MapgenV5Params();
|
||||||
};
|
};
|
||||||
|
@ -49,21 +49,13 @@ FlagDesc flagdesc_mapgen_v6[] = {
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge) {
|
MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge)
|
||||||
this->generating = false;
|
: Mapgen(mapgenid, params, emerge)
|
||||||
this->id = mapgenid;
|
{
|
||||||
this->emerge = emerge;
|
this->emerge = emerge;
|
||||||
|
|
||||||
this->seed = (int)params->seed;
|
|
||||||
this->water_level = params->water_level;
|
|
||||||
this->flags = params->flags;
|
|
||||||
this->csize = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE;
|
|
||||||
this->gennotify = emerge->gennotify;
|
|
||||||
|
|
||||||
this->ystride = csize.X; //////fix this
|
this->ystride = csize.X; //////fix this
|
||||||
|
|
||||||
MapgenV6Params *sp = (MapgenV6Params *)params->sparams;
|
|
||||||
|
|
||||||
|
MapgenV6Params *sp = (MapgenV6Params *)params->sparams;
|
||||||
this->spflags = sp->spflags;
|
this->spflags = sp->spflags;
|
||||||
this->freq_desert = sp->freq_desert;
|
this->freq_desert = sp->freq_desert;
|
||||||
this->freq_beach = sp->freq_beach;
|
this->freq_beach = sp->freq_beach;
|
||||||
@ -224,7 +216,7 @@ bool MapgenV6::block_is_underground(u64 seed, v3s16 blockpos)
|
|||||||
//////////////////////// Base terrain height functions
|
//////////////////////// Base terrain height functions
|
||||||
|
|
||||||
float MapgenV6::baseTerrainLevel(float terrain_base, float terrain_higher,
|
float MapgenV6::baseTerrainLevel(float terrain_base, float terrain_higher,
|
||||||
float steepness, float height_select) {
|
float steepness, float height_select) {
|
||||||
float base = 1 + terrain_base;
|
float base = 1 + terrain_base;
|
||||||
float higher = 1 + terrain_higher;
|
float higher = 1 + terrain_higher;
|
||||||
|
|
||||||
@ -245,7 +237,7 @@ float MapgenV6::baseTerrainLevel(float terrain_base, float terrain_higher,
|
|||||||
float a_off = -0.20; // Offset to more low
|
float a_off = -0.20; // Offset to more low
|
||||||
float a = 0.5 + b * (a_off + height_select);
|
float a = 0.5 + b * (a_off + height_select);
|
||||||
a = rangelim(a, 0.0, 1.0); // Limit
|
a = rangelim(a, 0.0, 1.0); // Limit
|
||||||
|
|
||||||
return base * (1.0 - a) + higher * a;
|
return base * (1.0 - a) + higher * a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +245,7 @@ float MapgenV6::baseTerrainLevel(float terrain_base, float terrain_higher,
|
|||||||
float MapgenV6::baseTerrainLevelFromNoise(v2s16 p) {
|
float MapgenV6::baseTerrainLevelFromNoise(v2s16 p) {
|
||||||
if (flags & MG_FLAT)
|
if (flags & MG_FLAT)
|
||||||
return water_level;
|
return water_level;
|
||||||
|
|
||||||
float terrain_base = NoisePerlin2DPosOffset(noise_terrain_base->np,
|
float terrain_base = NoisePerlin2DPosOffset(noise_terrain_base->np,
|
||||||
p.X, 0.5, p.Y, 0.5, seed);
|
p.X, 0.5, p.Y, 0.5, seed);
|
||||||
float terrain_higher = NoisePerlin2DPosOffset(noise_terrain_higher->np,
|
float terrain_higher = NoisePerlin2DPosOffset(noise_terrain_higher->np,
|
||||||
@ -277,12 +269,12 @@ float MapgenV6::baseTerrainLevelFromMap(v2s16 p) {
|
|||||||
float MapgenV6::baseTerrainLevelFromMap(int index) {
|
float MapgenV6::baseTerrainLevelFromMap(int index) {
|
||||||
if (flags & MG_FLAT)
|
if (flags & MG_FLAT)
|
||||||
return water_level;
|
return water_level;
|
||||||
|
|
||||||
float terrain_base = noise_terrain_base->result[index];
|
float terrain_base = noise_terrain_base->result[index];
|
||||||
float terrain_higher = noise_terrain_higher->result[index];
|
float terrain_higher = noise_terrain_higher->result[index];
|
||||||
float steepness = noise_steepness->result[index];
|
float steepness = noise_steepness->result[index];
|
||||||
float height_select = noise_height_select->result[index];
|
float height_select = noise_height_select->result[index];
|
||||||
|
|
||||||
return baseTerrainLevel(terrain_base, terrain_higher,
|
return baseTerrainLevel(terrain_base, terrain_higher,
|
||||||
steepness, height_select);
|
steepness, height_select);
|
||||||
}
|
}
|
||||||
@ -340,7 +332,7 @@ float MapgenV6::getTreeAmount(v2s16 p)
|
|||||||
/*double noise = noise2d_perlin(
|
/*double noise = noise2d_perlin(
|
||||||
0.5+(float)p.X/125, 0.5+(float)p.Y/125,
|
0.5+(float)p.X/125, 0.5+(float)p.Y/125,
|
||||||
seed+2, 4, 0.66);*/
|
seed+2, 4, 0.66);*/
|
||||||
|
|
||||||
float noise = NoisePerlin2D(np_trees, p.X, p.Y, seed);
|
float noise = NoisePerlin2D(np_trees, p.X, p.Y, seed);
|
||||||
float zeroval = -0.39;
|
float zeroval = -0.39;
|
||||||
if (noise < zeroval)
|
if (noise < zeroval)
|
||||||
@ -355,9 +347,9 @@ bool MapgenV6::getHaveAppleTree(v2s16 p)
|
|||||||
/*is_apple_tree = noise2d_perlin(
|
/*is_apple_tree = noise2d_perlin(
|
||||||
0.5+(float)p.X/100, 0.5+(float)p.Z/100,
|
0.5+(float)p.X/100, 0.5+(float)p.Z/100,
|
||||||
data->seed+342902, 3, 0.45) > 0.2;*/
|
data->seed+342902, 3, 0.45) > 0.2;*/
|
||||||
|
|
||||||
float noise = NoisePerlin2D(np_apple_trees, p.X, p.Y, seed);
|
float noise = NoisePerlin2D(np_apple_trees, p.X, p.Y, seed);
|
||||||
|
|
||||||
return noise > 0.2;
|
return noise > 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,11 +358,11 @@ float MapgenV6::getMudAmount(int index)
|
|||||||
{
|
{
|
||||||
if (flags & MG_FLAT)
|
if (flags & MG_FLAT)
|
||||||
return AVERAGE_MUD_AMOUNT;
|
return AVERAGE_MUD_AMOUNT;
|
||||||
|
|
||||||
/*return ((float)AVERAGE_MUD_AMOUNT + 2.0 * noise2d_perlin(
|
/*return ((float)AVERAGE_MUD_AMOUNT + 2.0 * noise2d_perlin(
|
||||||
0.5+(float)p.X/200, 0.5+(float)p.Y/200,
|
0.5+(float)p.X/200, 0.5+(float)p.Y/200,
|
||||||
seed+91013, 3, 0.55));*/
|
seed+91013, 3, 0.55));*/
|
||||||
|
|
||||||
return noise_mud->result[index];
|
return noise_mud->result[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,7 +373,7 @@ bool MapgenV6::getHaveBeach(int index)
|
|||||||
/*double sandnoise = noise2d_perlin(
|
/*double sandnoise = noise2d_perlin(
|
||||||
0.2+(float)p2d.X/250, 0.7+(float)p2d.Y/250,
|
0.2+(float)p2d.X/250, 0.7+(float)p2d.Y/250,
|
||||||
seed+59420, 3, 0.50);*/
|
seed+59420, 3, 0.50);*/
|
||||||
|
|
||||||
float sandnoise = noise_beach->result[index];
|
float sandnoise = noise_beach->result[index];
|
||||||
return (sandnoise > freq_beach);
|
return (sandnoise > freq_beach);
|
||||||
}
|
}
|
||||||
@ -393,16 +385,16 @@ BiomeV6Type MapgenV6::getBiome(int index, v2s16 p)
|
|||||||
/*double d = noise2d_perlin(
|
/*double d = noise2d_perlin(
|
||||||
0.6+(float)p2d.X/250, 0.2+(float)p2d.Y/250,
|
0.6+(float)p2d.X/250, 0.2+(float)p2d.Y/250,
|
||||||
seed+9130, 3, 0.50);*/
|
seed+9130, 3, 0.50);*/
|
||||||
|
|
||||||
float d = noise_biome->result[index];
|
float d = noise_biome->result[index];
|
||||||
if (d > freq_desert)
|
if (d > freq_desert)
|
||||||
return BT_DESERT;
|
return BT_DESERT;
|
||||||
|
|
||||||
if ((spflags & MGV6_BIOMEBLEND) &&
|
if ((spflags & MGV6_BIOMEBLEND) &&
|
||||||
(d > freq_desert - 0.10) &&
|
(d > freq_desert - 0.10) &&
|
||||||
((noise2d(p.X, p.Y, seed) + 1.0) > (freq_desert - d) * 20.0))
|
((noise2d(p.X, p.Y, seed) + 1.0) > (freq_desert - d) * 20.0))
|
||||||
return BT_DESERT;
|
return BT_DESERT;
|
||||||
|
|
||||||
return BT_NORMAL;
|
return BT_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,11 +417,11 @@ void MapgenV6::makeChunk(BlockMakeData *data) {
|
|||||||
assert(data->blockpos_requested.X <= data->blockpos_max.X &&
|
assert(data->blockpos_requested.X <= data->blockpos_max.X &&
|
||||||
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
||||||
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
||||||
|
|
||||||
this->generating = true;
|
this->generating = true;
|
||||||
this->vm = data->vmanip;
|
this->vm = data->vmanip;
|
||||||
this->ndef = data->nodedef;
|
this->ndef = data->nodedef;
|
||||||
|
|
||||||
// Hack: use minimum block coords for old code that assumes a single block
|
// Hack: use minimum block coords for old code that assumes a single block
|
||||||
v3s16 blockpos = data->blockpos_requested;
|
v3s16 blockpos = data->blockpos_requested;
|
||||||
v3s16 blockpos_min = data->blockpos_min;
|
v3s16 blockpos_min = data->blockpos_min;
|
||||||
@ -491,7 +483,7 @@ void MapgenV6::makeChunk(BlockMakeData *data) {
|
|||||||
flowMud(mudflow_minpos, mudflow_maxpos);
|
flowMud(mudflow_minpos, mudflow_maxpos);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add dungeons
|
// Add dungeons
|
||||||
if (flags & MG_DUNGEONS) {
|
if (flags & MG_DUNGEONS) {
|
||||||
DungeonParams dp;
|
DungeonParams dp;
|
||||||
@ -525,7 +517,7 @@ void MapgenV6::makeChunk(BlockMakeData *data) {
|
|||||||
DungeonGen dgen(this, &dp);
|
DungeonGen dgen(this, &dp);
|
||||||
dgen.generate(blockseed, full_node_min, full_node_max);
|
dgen.generate(blockseed, full_node_min, full_node_max);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add top and bottom side of water to transforming_liquid queue
|
// Add top and bottom side of water to transforming_liquid queue
|
||||||
updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
|
updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
|
||||||
|
|
||||||
@ -535,7 +527,7 @@ void MapgenV6::makeChunk(BlockMakeData *data) {
|
|||||||
// Generate some trees, and add grass, if a jungle
|
// Generate some trees, and add grass, if a jungle
|
||||||
if (flags & MG_TREES)
|
if (flags & MG_TREES)
|
||||||
placeTreesAndJungleGrass();
|
placeTreesAndJungleGrass();
|
||||||
|
|
||||||
// Generate the registered decorations
|
// Generate the registered decorations
|
||||||
emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
|
emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
|
||||||
|
|
||||||
@ -546,7 +538,7 @@ void MapgenV6::makeChunk(BlockMakeData *data) {
|
|||||||
if (flags & MG_LIGHT)
|
if (flags & MG_LIGHT)
|
||||||
calcLighting(node_min - v3s16(1, 1, 1) * MAP_BLOCKSIZE,
|
calcLighting(node_min - v3s16(1, 1, 1) * MAP_BLOCKSIZE,
|
||||||
node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
|
node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
|
||||||
|
|
||||||
this->generating = false;
|
this->generating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,25 +590,25 @@ int MapgenV6::generateGround() {
|
|||||||
MapNode n_stone(c_stone), n_desert_stone(c_desert_stone);
|
MapNode n_stone(c_stone), n_desert_stone(c_desert_stone);
|
||||||
int stone_surface_max_y = -MAP_GENERATION_LIMIT;
|
int stone_surface_max_y = -MAP_GENERATION_LIMIT;
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||||
// Surface height
|
// Surface height
|
||||||
s16 surface_y = (s16)baseTerrainLevelFromMap(index);
|
s16 surface_y = (s16)baseTerrainLevelFromMap(index);
|
||||||
|
|
||||||
// Log it
|
// Log it
|
||||||
if (surface_y > stone_surface_max_y)
|
if (surface_y > stone_surface_max_y)
|
||||||
stone_surface_max_y = surface_y;
|
stone_surface_max_y = surface_y;
|
||||||
|
|
||||||
BiomeV6Type bt = getBiome(index, v2s16(x, z));
|
BiomeV6Type bt = getBiome(index, v2s16(x, z));
|
||||||
|
|
||||||
// Fill ground with stone
|
// Fill ground with stone
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
u32 i = vm->m_area.index(x, node_min.Y, z);
|
u32 i = vm->m_area.index(x, node_min.Y, z);
|
||||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
||||||
if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
|
if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
|
||||||
if (y <= surface_y) {
|
if (y <= surface_y) {
|
||||||
vm->m_data[i] = (y > water_level && bt == BT_DESERT) ?
|
vm->m_data[i] = (y > water_level && bt == BT_DESERT) ?
|
||||||
n_desert_stone : n_stone;
|
n_desert_stone : n_stone;
|
||||||
} else if (y <= water_level) {
|
} else if (y <= water_level) {
|
||||||
vm->m_data[i] = n_water_source;
|
vm->m_data[i] = n_water_source;
|
||||||
@ -627,7 +619,7 @@ int MapgenV6::generateGround() {
|
|||||||
vm->m_area.add_y(em, i, 1);
|
vm->m_area.add_y(em, i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return stone_surface_max_y;
|
return stone_surface_max_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,11 +639,11 @@ void MapgenV6::addMud() {
|
|||||||
|
|
||||||
// Find ground level
|
// Find ground level
|
||||||
s16 surface_y = find_stone_level(v2s16(x, z)); /////////////////optimize this!
|
s16 surface_y = find_stone_level(v2s16(x, z)); /////////////////optimize this!
|
||||||
|
|
||||||
// Handle area not found
|
// Handle area not found
|
||||||
if (surface_y == vm->m_area.MinEdge.Y - 1)
|
if (surface_y == vm->m_area.MinEdge.Y - 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
BiomeV6Type bt = getBiome(index, v2s16(x, z));
|
BiomeV6Type bt = getBiome(index, v2s16(x, z));
|
||||||
addnode = (bt == BT_DESERT) ? n_desert_sand : n_dirt;
|
addnode = (bt == BT_DESERT) ? n_desert_sand : n_dirt;
|
||||||
|
|
||||||
@ -830,7 +822,7 @@ void MapgenV6::flowMud(s16 &mudflow_minpos, s16 &mudflow_maxpos) {
|
|||||||
void MapgenV6::addDirtGravelBlobs() {
|
void MapgenV6::addDirtGravelBlobs() {
|
||||||
if (getBiome(v2s16(node_min.X, node_min.Z)) != BT_NORMAL)
|
if (getBiome(v2s16(node_min.X, node_min.Z)) != BT_NORMAL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PseudoRandom pr(blockseed + 983);
|
PseudoRandom pr(blockseed + 983);
|
||||||
for (int i = 0; i < volume_nodes/10/10/10; i++) {
|
for (int i = 0; i < volume_nodes/10/10/10; i++) {
|
||||||
bool only_fill_cave = (myrand_range(0,1) != 0);
|
bool only_fill_cave = (myrand_range(0,1) != 0);
|
||||||
@ -844,7 +836,7 @@ void MapgenV6::addDirtGravelBlobs() {
|
|||||||
pr.range(node_min.Y, node_max.Y) - size.Y / 2,
|
pr.range(node_min.Y, node_max.Y) - size.Y / 2,
|
||||||
pr.range(node_min.Z, node_max.Z) - size.Z / 2
|
pr.range(node_min.Z, node_max.Z) - size.Z / 2
|
||||||
);
|
);
|
||||||
|
|
||||||
MapNode n1((p0.Y > -32 && !pr.range(0, 1)) ? c_dirt : c_gravel);
|
MapNode n1((p0.Y > -32 && !pr.range(0, 1)) ? c_dirt : c_gravel);
|
||||||
for (int z1 = 0; z1 < size.Z; z1++)
|
for (int z1 = 0; z1 < size.Z; z1++)
|
||||||
for (int y1 = 0; y1 < size.Y; y1++)
|
for (int y1 = 0; y1 < size.Y; y1++)
|
||||||
@ -869,7 +861,7 @@ void MapgenV6::placeTreesAndJungleGrass() {
|
|||||||
//TimeTaker t("placeTrees");
|
//TimeTaker t("placeTrees");
|
||||||
if (node_max.Y < water_level)
|
if (node_max.Y < water_level)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PseudoRandom grassrandom(blockseed + 53);
|
PseudoRandom grassrandom(blockseed + 53);
|
||||||
content_t c_junglegrass = ndef->getId("mapgen_junglegrass");
|
content_t c_junglegrass = ndef->getId("mapgen_junglegrass");
|
||||||
// if we don't have junglegrass, don't place cignore... that's bad
|
// if we don't have junglegrass, don't place cignore... that's bad
|
||||||
@ -877,12 +869,12 @@ void MapgenV6::placeTreesAndJungleGrass() {
|
|||||||
c_junglegrass = CONTENT_AIR;
|
c_junglegrass = CONTENT_AIR;
|
||||||
MapNode n_junglegrass(c_junglegrass);
|
MapNode n_junglegrass(c_junglegrass);
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
|
|
||||||
// Divide area into parts
|
// Divide area into parts
|
||||||
s16 div = 8;
|
s16 div = 8;
|
||||||
s16 sidelen = central_area_size.X / div;
|
s16 sidelen = central_area_size.X / div;
|
||||||
double area = sidelen * sidelen;
|
double area = sidelen * sidelen;
|
||||||
|
|
||||||
// N.B. We must add jungle grass first, since tree leaves will
|
// N.B. We must add jungle grass first, since tree leaves will
|
||||||
// obstruct the ground, giving us a false ground level
|
// obstruct the ground, giving us a false ground level
|
||||||
for (s16 z0 = 0; z0 < div; z0++)
|
for (s16 z0 = 0; z0 < div; z0++)
|
||||||
@ -902,10 +894,10 @@ void MapgenV6::placeTreesAndJungleGrass() {
|
|||||||
node_min.X + sidelen + sidelen * x0 - 1,
|
node_min.X + sidelen + sidelen * x0 - 1,
|
||||||
node_min.Z + sidelen + sidelen * z0 - 1
|
node_min.Z + sidelen + sidelen * z0 - 1
|
||||||
);
|
);
|
||||||
|
|
||||||
// Amount of trees, jungle area
|
// Amount of trees, jungle area
|
||||||
u32 tree_count = area * getTreeAmount(p2d_center);
|
u32 tree_count = area * getTreeAmount(p2d_center);
|
||||||
|
|
||||||
float humidity;
|
float humidity;
|
||||||
bool is_jungle = false;
|
bool is_jungle = false;
|
||||||
if (spflags & MGV6_JUNGLES) {
|
if (spflags & MGV6_JUNGLES) {
|
||||||
@ -917,16 +909,16 @@ void MapgenV6::placeTreesAndJungleGrass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add jungle grass
|
// Add jungle grass
|
||||||
if (is_jungle) {
|
if (is_jungle) {
|
||||||
u32 grass_count = 5 * humidity * tree_count;
|
u32 grass_count = 5 * humidity * tree_count;
|
||||||
for (u32 i = 0; i < grass_count; i++) {
|
for (u32 i = 0; i < grass_count; i++) {
|
||||||
s16 x = grassrandom.range(p2d_min.X, p2d_max.X);
|
s16 x = grassrandom.range(p2d_min.X, p2d_max.X);
|
||||||
s16 z = grassrandom.range(p2d_min.Y, p2d_max.Y);
|
s16 z = grassrandom.range(p2d_min.Y, p2d_max.Y);
|
||||||
|
|
||||||
s16 y = findGroundLevelFull(v2s16(x, z)); ////////////////optimize this!
|
s16 y = findGroundLevelFull(v2s16(x, z)); ////////////////optimize this!
|
||||||
if (y < water_level || y < node_min.Y || y > node_max.Y)
|
if (y < water_level || y < node_min.Y || y > node_max.Y)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
u32 vi = vm->m_area.index(x, y, z);
|
u32 vi = vm->m_area.index(x, y, z);
|
||||||
// place on dirt_with_grass, since we know it is exposed to sunlight
|
// place on dirt_with_grass, since we know it is exposed to sunlight
|
||||||
if (vm->m_data[vi].getContent() == c_dirt_with_grass) {
|
if (vm->m_data[vi].getContent() == c_dirt_with_grass) {
|
||||||
@ -935,7 +927,7 @@ void MapgenV6::placeTreesAndJungleGrass() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put trees in random places on part of division
|
// Put trees in random places on part of division
|
||||||
for (u32 i = 0; i < tree_count; i++) {
|
for (u32 i = 0; i < tree_count; i++) {
|
||||||
s16 x = myrand_range(p2d_min.X, p2d_max.X);
|
s16 x = myrand_range(p2d_min.X, p2d_max.X);
|
||||||
@ -945,7 +937,7 @@ void MapgenV6::placeTreesAndJungleGrass() {
|
|||||||
// Don't make a tree so high that it doesn't fit
|
// Don't make a tree so high that it doesn't fit
|
||||||
if(y < water_level || y > node_max.Y - 6)
|
if(y < water_level || y > node_max.Y - 6)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
v3s16 p(x,y,z);
|
v3s16 p(x,y,z);
|
||||||
// Trees grow only on mud and grass
|
// Trees grow only on mud and grass
|
||||||
{
|
{
|
||||||
@ -956,7 +948,7 @@ void MapgenV6::placeTreesAndJungleGrass() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
p.Y++;
|
p.Y++;
|
||||||
|
|
||||||
// Make a tree
|
// Make a tree
|
||||||
if (is_jungle) {
|
if (is_jungle) {
|
||||||
treegen::make_jungletree(*vm, p, ndef, myrand());
|
treegen::make_jungletree(*vm, p, ndef, myrand());
|
||||||
@ -1009,15 +1001,15 @@ void MapgenV6::generateCaves(int max_stone_y) {
|
|||||||
u32 bruises_count = 1;
|
u32 bruises_count = 1;
|
||||||
PseudoRandom ps(blockseed + 21343);
|
PseudoRandom ps(blockseed + 21343);
|
||||||
PseudoRandom ps2(blockseed + 1032);
|
PseudoRandom ps2(blockseed + 1032);
|
||||||
|
|
||||||
if (ps.range(1, 6) == 1)
|
if (ps.range(1, 6) == 1)
|
||||||
bruises_count = ps.range(0, ps.range(0, 2));
|
bruises_count = ps.range(0, ps.range(0, 2));
|
||||||
|
|
||||||
if (getBiome(v2s16(node_min.X, node_min.Z)) == BT_DESERT) {
|
if (getBiome(v2s16(node_min.X, node_min.Z)) == BT_DESERT) {
|
||||||
caves_count /= 3;
|
caves_count /= 3;
|
||||||
bruises_count /= 3;
|
bruises_count /= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 i = 0; i < caves_count + bruises_count; i++) {
|
for (u32 i = 0; i < caves_count + bruises_count; i++) {
|
||||||
bool large_cave = (i >= caves_count);
|
bool large_cave = (i >= caves_count);
|
||||||
CaveV6 cave(this, &ps, &ps2, large_cave);
|
CaveV6 cave(this, &ps, &ps2, large_cave);
|
||||||
|
@ -55,10 +55,10 @@ struct MapgenV6Params : public MapgenSpecificParams {
|
|||||||
NoiseParams np_humidity;
|
NoiseParams np_humidity;
|
||||||
NoiseParams np_trees;
|
NoiseParams np_trees;
|
||||||
NoiseParams np_apple_trees;
|
NoiseParams np_apple_trees;
|
||||||
|
|
||||||
MapgenV6Params();
|
MapgenV6Params();
|
||||||
~MapgenV6Params() {}
|
~MapgenV6Params() {}
|
||||||
|
|
||||||
void readParams(Settings *settings);
|
void readParams(Settings *settings);
|
||||||
void writeParams(Settings *settings);
|
void writeParams(Settings *settings);
|
||||||
};
|
};
|
||||||
@ -68,7 +68,6 @@ public:
|
|||||||
EmergeManager *emerge;
|
EmergeManager *emerge;
|
||||||
|
|
||||||
int ystride;
|
int ystride;
|
||||||
u32 flags;
|
|
||||||
u32 spflags;
|
u32 spflags;
|
||||||
|
|
||||||
u32 blockseed;
|
u32 blockseed;
|
||||||
@ -111,7 +110,7 @@ public:
|
|||||||
|
|
||||||
MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge);
|
MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge);
|
||||||
~MapgenV6();
|
~MapgenV6();
|
||||||
|
|
||||||
void makeChunk(BlockMakeData *data);
|
void makeChunk(BlockMakeData *data);
|
||||||
int getGroundLevelAtPoint(v2s16 p);
|
int getGroundLevelAtPoint(v2s16 p);
|
||||||
|
|
||||||
@ -124,7 +123,7 @@ public:
|
|||||||
s16 find_stone_level(v2s16 p2d);
|
s16 find_stone_level(v2s16 p2d);
|
||||||
bool block_is_underground(u64 seed, v3s16 blockpos);
|
bool block_is_underground(u64 seed, v3s16 blockpos);
|
||||||
s16 find_ground_level_from_noise(u64 seed, v2s16 p2d, s16 precision);
|
s16 find_ground_level_from_noise(u64 seed, v2s16 p2d, s16 precision);
|
||||||
|
|
||||||
float getHumidity(v2s16 p);
|
float getHumidity(v2s16 p);
|
||||||
float getTreeAmount(v2s16 p);
|
float getTreeAmount(v2s16 p);
|
||||||
bool getHaveAppleTree(v2s16 p);
|
bool getHaveAppleTree(v2s16 p);
|
||||||
@ -134,9 +133,9 @@ public:
|
|||||||
bool getHaveBeach(int index);
|
bool getHaveBeach(int index);
|
||||||
BiomeV6Type getBiome(v2s16 p);
|
BiomeV6Type getBiome(v2s16 p);
|
||||||
BiomeV6Type getBiome(int index, v2s16 p);
|
BiomeV6Type getBiome(int index, v2s16 p);
|
||||||
|
|
||||||
u32 get_blockseed(u64 seed, v3s16 p);
|
u32 get_blockseed(u64 seed, v3s16 p);
|
||||||
|
|
||||||
virtual void calculateNoise();
|
virtual void calculateNoise();
|
||||||
int generateGround();
|
int generateGround();
|
||||||
void addMud();
|
void addMud();
|
||||||
@ -152,7 +151,7 @@ struct MapgenFactoryV6 : public MapgenFactory {
|
|||||||
Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
|
Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
|
||||||
return new MapgenV6(mgid, params, emerge);
|
return new MapgenV6(mgid, params, emerge);
|
||||||
};
|
};
|
||||||
|
|
||||||
MapgenSpecificParams *createMapgenParams() {
|
MapgenSpecificParams *createMapgenParams() {
|
||||||
return new MapgenV6Params();
|
return new MapgenV6Params();
|
||||||
};
|
};
|
||||||
|
@ -49,19 +49,12 @@ FlagDesc flagdesc_mapgen_v7[] = {
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) {
|
MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
|
||||||
this->generating = false;
|
: Mapgen(mapgenid, params, emerge)
|
||||||
this->id = mapgenid;
|
{
|
||||||
this->emerge = emerge;
|
this->emerge = emerge;
|
||||||
this->bmgr = emerge->biomemgr;
|
this->bmgr = emerge->biomemgr;
|
||||||
|
|
||||||
this->seed = (int)params->seed;
|
|
||||||
this->water_level = params->water_level;
|
|
||||||
this->flags = params->flags;
|
|
||||||
this->gennotify = emerge->gennotify;
|
|
||||||
|
|
||||||
this->csize = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE;
|
|
||||||
|
|
||||||
//// amount of elements to skip for the next index
|
//// amount of elements to skip for the next index
|
||||||
//// for noise/height/biome maps (not vmanip)
|
//// for noise/height/biome maps (not vmanip)
|
||||||
this->ystride = csize.X;
|
this->ystride = csize.X;
|
||||||
@ -119,7 +112,7 @@ MapgenV7::~MapgenV7() {
|
|||||||
|
|
||||||
delete noise_heat;
|
delete noise_heat;
|
||||||
delete noise_humidity;
|
delete noise_humidity;
|
||||||
|
|
||||||
delete[] ridge_heightmap;
|
delete[] ridge_heightmap;
|
||||||
delete[] heightmap;
|
delete[] heightmap;
|
||||||
delete[] biomemap;
|
delete[] biomemap;
|
||||||
@ -177,7 +170,7 @@ void MapgenV7Params::writeParams(Settings *settings) {
|
|||||||
int MapgenV7::getGroundLevelAtPoint(v2s16 p) {
|
int MapgenV7::getGroundLevelAtPoint(v2s16 p) {
|
||||||
// Base terrain calculation
|
// Base terrain calculation
|
||||||
s16 y = baseTerrainLevelAtPoint(p.X, p.Y);
|
s16 y = baseTerrainLevelAtPoint(p.X, p.Y);
|
||||||
|
|
||||||
// Ridge/river terrain calculation
|
// Ridge/river terrain calculation
|
||||||
float width = 0.3;
|
float width = 0.3;
|
||||||
float uwatern = NoisePerlin2DNoTxfm(noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
|
float uwatern = NoisePerlin2DNoTxfm(noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
|
||||||
@ -185,14 +178,14 @@ int MapgenV7::getGroundLevelAtPoint(v2s16 p) {
|
|||||||
// if inside a river, simply guess
|
// if inside a river, simply guess
|
||||||
if (uwatern >= -width && uwatern <= width)
|
if (uwatern >= -width && uwatern <= width)
|
||||||
return water_level - 10;
|
return water_level - 10;
|
||||||
|
|
||||||
// Mountain terrain calculation
|
// Mountain terrain calculation
|
||||||
int iters = 128; // don't even bother iterating more than 128 times..
|
int iters = 128; // don't even bother iterating more than 128 times..
|
||||||
while (iters--) {
|
while (iters--) {
|
||||||
//current point would have been air
|
//current point would have been air
|
||||||
if (!getMountainTerrainAtPoint(p.X, y, p.Y))
|
if (!getMountainTerrainAtPoint(p.X, y, p.Y))
|
||||||
return y;
|
return y;
|
||||||
|
|
||||||
y++;
|
y++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,12 +202,12 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
|
|||||||
assert(data->blockpos_requested.X <= data->blockpos_max.X &&
|
assert(data->blockpos_requested.X <= data->blockpos_max.X &&
|
||||||
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
||||||
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
||||||
|
|
||||||
this->generating = true;
|
this->generating = true;
|
||||||
this->vm = data->vmanip;
|
this->vm = data->vmanip;
|
||||||
this->ndef = data->nodedef;
|
this->ndef = data->nodedef;
|
||||||
//TimeTaker t("makeChunk");
|
//TimeTaker t("makeChunk");
|
||||||
|
|
||||||
v3s16 blockpos_min = data->blockpos_min;
|
v3s16 blockpos_min = data->blockpos_min;
|
||||||
v3s16 blockpos_max = data->blockpos_max;
|
v3s16 blockpos_max = data->blockpos_max;
|
||||||
node_min = blockpos_min * MAP_BLOCKSIZE;
|
node_min = blockpos_min * MAP_BLOCKSIZE;
|
||||||
@ -223,19 +216,19 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
|
|||||||
full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
|
full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
|
||||||
|
|
||||||
blockseed = emerge->getBlockSeed(full_node_min); //////use getBlockSeed2()!
|
blockseed = emerge->getBlockSeed(full_node_min); //////use getBlockSeed2()!
|
||||||
|
|
||||||
// Make some noise
|
// Make some noise
|
||||||
calculateNoise();
|
calculateNoise();
|
||||||
|
|
||||||
// Generate base terrain, mountains, and ridges with initial heightmaps
|
// Generate base terrain, mountains, and ridges with initial heightmaps
|
||||||
s16 stone_surface_max_y = generateTerrain();
|
s16 stone_surface_max_y = generateTerrain();
|
||||||
|
|
||||||
updateHeightmap(node_min, node_max);
|
updateHeightmap(node_min, node_max);
|
||||||
|
|
||||||
// Calculate biomes
|
// Calculate biomes
|
||||||
bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
|
bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
|
||||||
noise_humidity->result, heightmap, biomemap);
|
noise_humidity->result, heightmap, biomemap);
|
||||||
|
|
||||||
// Actually place the biome-specific nodes and what not
|
// Actually place the biome-specific nodes and what not
|
||||||
generateBiomes();
|
generateBiomes();
|
||||||
|
|
||||||
@ -255,17 +248,17 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
|
|||||||
|
|
||||||
// Sprinkle some dust on top after everything else was generated
|
// Sprinkle some dust on top after everything else was generated
|
||||||
dustTopNodes();
|
dustTopNodes();
|
||||||
|
|
||||||
//printf("makeChunk: %dms\n", t.stop());
|
//printf("makeChunk: %dms\n", t.stop());
|
||||||
|
|
||||||
updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
|
updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
|
||||||
|
|
||||||
if (flags & MG_LIGHT)
|
if (flags & MG_LIGHT)
|
||||||
calcLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
calcLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
||||||
node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
|
node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
|
||||||
//setLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
//setLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
||||||
// node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE, 0xFF);
|
// node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE, 0xFF);
|
||||||
|
|
||||||
this->generating = false;
|
this->generating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,24 +268,24 @@ void MapgenV7::calculateNoise() {
|
|||||||
int x = node_min.X;
|
int x = node_min.X;
|
||||||
int y = node_min.Y;
|
int y = node_min.Y;
|
||||||
int z = node_min.Z;
|
int z = node_min.Z;
|
||||||
|
|
||||||
noise_height_select->perlinMap2D(x, z);
|
noise_height_select->perlinMap2D(x, z);
|
||||||
noise_height_select->transformNoiseMap();
|
noise_height_select->transformNoiseMap();
|
||||||
|
|
||||||
noise_terrain_persist->perlinMap2D(x, z);
|
noise_terrain_persist->perlinMap2D(x, z);
|
||||||
noise_terrain_persist->transformNoiseMap();
|
noise_terrain_persist->transformNoiseMap();
|
||||||
float *persistmap = noise_terrain_persist->result;
|
float *persistmap = noise_terrain_persist->result;
|
||||||
for (int i = 0; i != csize.X * csize.Z; i++)
|
for (int i = 0; i != csize.X * csize.Z; i++)
|
||||||
persistmap[i] = rangelim(persistmap[i], 0.4, 0.9);
|
persistmap[i] = rangelim(persistmap[i], 0.4, 0.9);
|
||||||
|
|
||||||
noise_terrain_base->perlinMap2DModulated(x, z, persistmap);
|
noise_terrain_base->perlinMap2DModulated(x, z, persistmap);
|
||||||
noise_terrain_base->transformNoiseMap();
|
noise_terrain_base->transformNoiseMap();
|
||||||
|
|
||||||
noise_terrain_alt->perlinMap2DModulated(x, z, persistmap);
|
noise_terrain_alt->perlinMap2DModulated(x, z, persistmap);
|
||||||
noise_terrain_alt->transformNoiseMap();
|
noise_terrain_alt->transformNoiseMap();
|
||||||
|
|
||||||
noise_filler_depth->perlinMap2D(x, z);
|
noise_filler_depth->perlinMap2D(x, z);
|
||||||
|
|
||||||
if (spflags & MGV7_MOUNTAINS) {
|
if (spflags & MGV7_MOUNTAINS) {
|
||||||
noise_mountain->perlinMap3D(x, y, z);
|
noise_mountain->perlinMap3D(x, y, z);
|
||||||
noise_mount_height->perlinMap2D(x, z);
|
noise_mount_height->perlinMap2D(x, z);
|
||||||
@ -303,10 +296,10 @@ void MapgenV7::calculateNoise() {
|
|||||||
noise_ridge->perlinMap3D(x, y, z);
|
noise_ridge->perlinMap3D(x, y, z);
|
||||||
noise_ridge_uwater->perlinMap2D(x, z);
|
noise_ridge_uwater->perlinMap2D(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
noise_heat->perlinMap2D(x, z);
|
noise_heat->perlinMap2D(x, z);
|
||||||
noise_humidity->perlinMap2D(x, z);
|
noise_humidity->perlinMap2D(x, z);
|
||||||
|
|
||||||
//printf("calculateNoise: %dus\n", t.stop());
|
//printf("calculateNoise: %dus\n", t.stop());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +308,7 @@ Biome *MapgenV7::getBiomeAtPoint(v3s16 p) {
|
|||||||
float heat = NoisePerlin2D(bmgr->np_heat, p.X, p.Z, seed);
|
float heat = NoisePerlin2D(bmgr->np_heat, p.X, p.Z, seed);
|
||||||
float humidity = NoisePerlin2D(bmgr->np_humidity, p.X, p.Z, seed);
|
float humidity = NoisePerlin2D(bmgr->np_humidity, p.X, p.Z, seed);
|
||||||
s16 groundlevel = baseTerrainLevelAtPoint(p.X, p.Z);
|
s16 groundlevel = baseTerrainLevelAtPoint(p.X, p.Z);
|
||||||
|
|
||||||
return bmgr->getBiome(heat, humidity, groundlevel);
|
return bmgr->getBiome(heat, humidity, groundlevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,7 +316,7 @@ Biome *MapgenV7::getBiomeAtPoint(v3s16 p) {
|
|||||||
float MapgenV7::baseTerrainLevelAtPoint(int x, int z) {
|
float MapgenV7::baseTerrainLevelAtPoint(int x, int z) {
|
||||||
float hselect = NoisePerlin2D(noise_height_select->np, x, z, seed);
|
float hselect = NoisePerlin2D(noise_height_select->np, x, z, seed);
|
||||||
hselect = rangelim(hselect, 0.0, 1.0);
|
hselect = rangelim(hselect, 0.0, 1.0);
|
||||||
|
|
||||||
float persist = NoisePerlin2D(noise_terrain_persist->np, x, z, seed);
|
float persist = NoisePerlin2D(noise_terrain_persist->np, x, z, seed);
|
||||||
persist = rangelim(persist, 0.4, 0.9);
|
persist = rangelim(persist, 0.4, 0.9);
|
||||||
|
|
||||||
@ -335,7 +328,7 @@ float MapgenV7::baseTerrainLevelAtPoint(int x, int z) {
|
|||||||
|
|
||||||
if (height_alt > height_base)
|
if (height_alt > height_base)
|
||||||
return height_alt;
|
return height_alt;
|
||||||
|
|
||||||
return (height_base * hselect) + (height_alt * (1.0 - hselect));
|
return (height_base * hselect) + (height_alt * (1.0 - hselect));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +337,7 @@ float MapgenV7::baseTerrainLevelFromMap(int index) {
|
|||||||
float hselect = rangelim(noise_height_select->result[index], 0.0, 1.0);
|
float hselect = rangelim(noise_height_select->result[index], 0.0, 1.0);
|
||||||
float height_base = noise_terrain_base->result[index];
|
float height_base = noise_terrain_base->result[index];
|
||||||
float height_alt = noise_terrain_alt->result[index];
|
float height_alt = noise_terrain_alt->result[index];
|
||||||
|
|
||||||
if (height_alt > height_base)
|
if (height_alt > height_base)
|
||||||
return height_alt;
|
return height_alt;
|
||||||
|
|
||||||
@ -373,7 +366,7 @@ void MapgenV7::carveRivers() {
|
|||||||
MapNode n_air(CONTENT_AIR), n_water_source(c_water_source);
|
MapNode n_air(CONTENT_AIR), n_water_source(c_water_source);
|
||||||
MapNode n_stone(c_stone);
|
MapNode n_stone(c_stone);
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
|
|
||||||
int river_depth = 4;
|
int river_depth = 4;
|
||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
@ -385,16 +378,16 @@ void MapgenV7::carveRivers() {
|
|||||||
float height = terrain_river * (1 - abs(terrain_mod)) *
|
float height = terrain_river * (1 - abs(terrain_mod)) *
|
||||||
noise_terrain_river->np->scale;
|
noise_terrain_river->np->scale;
|
||||||
height = log(height * height); //log(h^3) is pretty interesting for terrain
|
height = log(height * height); //log(h^3) is pretty interesting for terrain
|
||||||
|
|
||||||
s16 y = heightmap[index];
|
s16 y = heightmap[index];
|
||||||
if (height < 1.0 && y > river_depth &&
|
if (height < 1.0 && y > river_depth &&
|
||||||
y - river_depth >= node_min.Y && y <= node_max.Y) {
|
y - river_depth >= node_min.Y && y <= node_max.Y) {
|
||||||
|
|
||||||
for (s16 ry = y; ry != y - river_depth; ry--) {
|
for (s16 ry = y; ry != y - river_depth; ry--) {
|
||||||
u32 vi = vm->m_area.index(x, ry, z);
|
u32 vi = vm->m_area.index(x, ry, z);
|
||||||
vm->m_data[vi] = n_air;
|
vm->m_data[vi] = n_air;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 vi = vm->m_area.index(x, y - river_depth, z);
|
u32 vi = vm->m_area.index(x, y - river_depth, z);
|
||||||
vm->m_data[vi] = n_water_source;
|
vm->m_data[vi] = n_water_source;
|
||||||
}
|
}
|
||||||
@ -411,7 +404,7 @@ int MapgenV7::generateTerrain() {
|
|||||||
|
|
||||||
if (spflags & MGV7_RIDGES)
|
if (spflags & MGV7_RIDGES)
|
||||||
generateRidgeTerrain();
|
generateRidgeTerrain();
|
||||||
|
|
||||||
return ymax;
|
return ymax;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,23 +413,23 @@ int MapgenV7::generateBaseTerrain() {
|
|||||||
MapNode n_air(CONTENT_AIR);
|
MapNode n_air(CONTENT_AIR);
|
||||||
MapNode n_stone(c_stone);
|
MapNode n_stone(c_stone);
|
||||||
MapNode n_water(c_water_source);
|
MapNode n_water(c_water_source);
|
||||||
|
|
||||||
int stone_surface_max_y = -MAP_GENERATION_LIMIT;
|
int stone_surface_max_y = -MAP_GENERATION_LIMIT;
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||||
float surface_height = baseTerrainLevelFromMap(index);
|
float surface_height = baseTerrainLevelFromMap(index);
|
||||||
s16 surface_y = (s16)surface_height;
|
s16 surface_y = (s16)surface_height;
|
||||||
|
|
||||||
heightmap[index] = surface_y;
|
heightmap[index] = surface_y;
|
||||||
ridge_heightmap[index] = surface_y;
|
ridge_heightmap[index] = surface_y;
|
||||||
|
|
||||||
if (surface_y > stone_surface_max_y)
|
if (surface_y > stone_surface_max_y)
|
||||||
stone_surface_max_y = surface_y;
|
stone_surface_max_y = surface_y;
|
||||||
|
|
||||||
u32 i = vm->m_area.index(x, node_min.Y, z);
|
u32 i = vm->m_area.index(x, node_min.Y, z);
|
||||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
||||||
if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
|
if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
|
||||||
if (y <= surface_y)
|
if (y <= surface_y)
|
||||||
@ -449,7 +442,7 @@ int MapgenV7::generateBaseTerrain() {
|
|||||||
vm->m_area.add_y(em, i, 1);
|
vm->m_area.add_y(em, i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return stone_surface_max_y;
|
return stone_surface_max_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,10 +450,10 @@ int MapgenV7::generateBaseTerrain() {
|
|||||||
void MapgenV7::generateMountainTerrain() {
|
void MapgenV7::generateMountainTerrain() {
|
||||||
if (node_max.Y <= water_level)
|
if (node_max.Y <= water_level)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MapNode n_stone(c_stone);
|
MapNode n_stone(c_stone);
|
||||||
u32 j = 0;
|
u32 j = 0;
|
||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
||||||
u32 vi = vm->m_area.index(node_min.X, y, z);
|
u32 vi = vm->m_area.index(node_min.X, y, z);
|
||||||
@ -469,7 +462,7 @@ void MapgenV7::generateMountainTerrain() {
|
|||||||
|
|
||||||
if (getMountainTerrainFromMap(j, index, y))
|
if (getMountainTerrainFromMap(j, index, y))
|
||||||
vm->m_data[vi] = n_stone;
|
vm->m_data[vi] = n_stone;
|
||||||
|
|
||||||
vi++;
|
vi++;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
@ -481,36 +474,36 @@ void MapgenV7::generateRidgeTerrain() {
|
|||||||
MapNode n_water(c_water_source);
|
MapNode n_water(c_water_source);
|
||||||
MapNode n_air(CONTENT_AIR);
|
MapNode n_air(CONTENT_AIR);
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
||||||
u32 vi = vm->m_area.index(node_min.X, y, z);
|
u32 vi = vm->m_area.index(node_min.X, y, z);
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++, vi++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index++, vi++) {
|
||||||
int j = (z - node_min.Z) * csize.X + (x - node_min.X);
|
int j = (z - node_min.Z) * csize.X + (x - node_min.X);
|
||||||
|
|
||||||
if (heightmap[j] < water_level - 4)
|
if (heightmap[j] < water_level - 4)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float widthn = (noise_terrain_persist->result[j] - 0.6) / 0.1;
|
float widthn = (noise_terrain_persist->result[j] - 0.6) / 0.1;
|
||||||
//widthn = rangelim(widthn, -0.05, 0.5);
|
//widthn = rangelim(widthn, -0.05, 0.5);
|
||||||
|
|
||||||
float width = 0.3; // TODO: figure out acceptable perlin noise values
|
float width = 0.3; // TODO: figure out acceptable perlin noise values
|
||||||
float uwatern = noise_ridge_uwater->result[j] * 2;
|
float uwatern = noise_ridge_uwater->result[j] * 2;
|
||||||
if (uwatern < -width || uwatern > width)
|
if (uwatern < -width || uwatern > width)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float height_mod = (float)(y + 17) / 2.5;
|
float height_mod = (float)(y + 17) / 2.5;
|
||||||
float width_mod = (width - fabs(uwatern));
|
float width_mod = (width - fabs(uwatern));
|
||||||
float nridge = noise_ridge->result[index] * (float)y / 7.0;
|
float nridge = noise_ridge->result[index] * (float)y / 7.0;
|
||||||
|
|
||||||
if (y < water_level)
|
if (y < water_level)
|
||||||
nridge = -fabs(nridge) * 3.0 * widthn * 0.3;
|
nridge = -fabs(nridge) * 3.0 * widthn * 0.3;
|
||||||
|
|
||||||
if (nridge + width_mod * height_mod < 0.6)
|
if (nridge + width_mod * height_mod < 0.6)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (y < ridge_heightmap[j])
|
if (y < ridge_heightmap[j])
|
||||||
ridge_heightmap[j] = y - 1;
|
ridge_heightmap[j] = y - 1;
|
||||||
|
|
||||||
vm->m_data[vi] = (y > water_level) ? n_air : n_water;
|
vm->m_data[vi] = (y > water_level) ? n_air : n_water;
|
||||||
}
|
}
|
||||||
@ -528,7 +521,7 @@ void MapgenV7::generateBiomes() {
|
|||||||
|
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||||
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
||||||
@ -537,14 +530,14 @@ void MapgenV7::generateBiomes() {
|
|||||||
s16 y0_filler = biome->depth_top + dfiller;
|
s16 y0_filler = biome->depth_top + dfiller;
|
||||||
|
|
||||||
s16 nplaced = 0;
|
s16 nplaced = 0;
|
||||||
u32 i = vm->m_area.index(x, node_max.Y, z);
|
u32 i = vm->m_area.index(x, node_max.Y, z);
|
||||||
|
|
||||||
content_t c_above = vm->m_data[i + em.X].getContent();
|
content_t c_above = vm->m_data[i + em.X].getContent();
|
||||||
bool have_air = c_above == CONTENT_AIR;
|
bool have_air = c_above == CONTENT_AIR;
|
||||||
|
|
||||||
for (s16 y = node_max.Y; y >= node_min.Y; y--) {
|
for (s16 y = node_max.Y; y >= node_min.Y; y--) {
|
||||||
content_t c = vm->m_data[i].getContent();
|
content_t c = vm->m_data[i].getContent();
|
||||||
|
|
||||||
// It could be the case that the elevation is equal to the chunk
|
// It could be the case that the elevation is equal to the chunk
|
||||||
// boundary, but the chunk above has not been generated yet
|
// boundary, but the chunk above has not been generated yet
|
||||||
if (y == node_max.Y && c_above == CONTENT_IGNORE &&
|
if (y == node_max.Y && c_above == CONTENT_IGNORE &&
|
||||||
@ -554,10 +547,10 @@ void MapgenV7::generateBiomes() {
|
|||||||
(x - node_min.X);
|
(x - node_min.X);
|
||||||
have_air = !getMountainTerrainFromMap(j, index, y);
|
have_air = !getMountainTerrainFromMap(j, index, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == c_stone && have_air) {
|
if (c == c_stone && have_air) {
|
||||||
content_t c_below = vm->m_data[i - em.X].getContent();
|
content_t c_below = vm->m_data[i - em.X].getContent();
|
||||||
|
|
||||||
if (c_below != CONTENT_AIR) {
|
if (c_below != CONTENT_AIR) {
|
||||||
if (nplaced < y0_top) {
|
if (nplaced < y0_top) {
|
||||||
if(y < water_level)
|
if(y < water_level)
|
||||||
@ -593,7 +586,7 @@ void MapgenV7::generateBiomes() {
|
|||||||
have_air = true;
|
have_air = true;
|
||||||
nplaced = 0;
|
nplaced = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vm->m_area.add_y(em, i, -1);
|
vm->m_area.add_y(em, i, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -603,14 +596,14 @@ void MapgenV7::generateBiomes() {
|
|||||||
void MapgenV7::dustTopNodes() {
|
void MapgenV7::dustTopNodes() {
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
|
|
||||||
if (water_level > node_max.Y)
|
if (water_level > node_max.Y)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||||
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
||||||
|
|
||||||
if (biome->c_dust == CONTENT_IGNORE)
|
if (biome->c_dust == CONTENT_IGNORE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -622,17 +615,17 @@ void MapgenV7::dustTopNodes() {
|
|||||||
|
|
||||||
vm->m_area.add_y(em, vi, -1);
|
vm->m_area.add_y(em, vi, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
content_t c = vm->m_data[vi].getContent();
|
content_t c = vm->m_data[vi].getContent();
|
||||||
if (c == biome->c_water && biome->c_dust_water != CONTENT_IGNORE) {
|
if (c == biome->c_water && biome->c_dust_water != CONTENT_IGNORE) {
|
||||||
if (y < node_min.Y)
|
if (y < node_min.Y)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vm->m_data[vi] = MapNode(biome->c_dust_water);
|
vm->m_data[vi] = MapNode(biome->c_dust_water);
|
||||||
} else if (!ndef->get(c).buildable_to && c != CONTENT_IGNORE) {
|
} else if (!ndef->get(c).buildable_to && c != CONTENT_IGNORE) {
|
||||||
if (y == node_max.Y)
|
if (y == node_max.Y)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vm->m_area.add_y(em, vi, 1);
|
vm->m_area.add_y(em, vi, 1);
|
||||||
vm->m_data[vi] = MapNode(biome->c_dust);
|
vm->m_data[vi] = MapNode(biome->c_dust);
|
||||||
}
|
}
|
||||||
@ -649,10 +642,10 @@ void MapgenV7::addTopNodes() {
|
|||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||||
Biome *biome = bmgr->biomes[biomemap[index]];
|
Biome *biome = bmgr->biomes[biomemap[index]];
|
||||||
|
|
||||||
//////////////////// First, add top nodes below the ridge
|
//////////////////// First, add top nodes below the ridge
|
||||||
s16 y = ridge_heightmap[index];
|
s16 y = ridge_heightmap[index];
|
||||||
|
|
||||||
// This cutoff is good enough, but not perfect.
|
// This cutoff is good enough, but not perfect.
|
||||||
// It will cut off potentially placed top nodes at chunk boundaries
|
// It will cut off potentially placed top nodes at chunk boundaries
|
||||||
if (y < node_min.Y)
|
if (y < node_min.Y)
|
||||||
@ -664,7 +657,7 @@ void MapgenV7::addTopNodes() {
|
|||||||
if (ndef->get(c).walkable)
|
if (ndef->get(c).walkable)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// N.B. It is necessary to search downward since ridge_heightmap[i]
|
// N.B. It is necessary to search downward since ridge_heightmap[i]
|
||||||
// might not be the actual height, just the lowest part in the chunk
|
// might not be the actual height, just the lowest part in the chunk
|
||||||
// where a ridge had been carved
|
// where a ridge had been carved
|
||||||
@ -692,7 +685,7 @@ void MapgenV7::addTopNodes() {
|
|||||||
vm->m_data[i] = MapNode(c_dirt_with_grass);
|
vm->m_data[i] = MapNode(c_dirt_with_grass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////// Now, add top nodes on top of the ridge
|
//////////////////// Now, add top nodes on top of the ridge
|
||||||
y = heightmap[index];
|
y = heightmap[index];
|
||||||
if (y > node_max.Y) {
|
if (y > node_max.Y) {
|
||||||
|
@ -42,10 +42,10 @@ struct MapgenV7Params : public MapgenSpecificParams {
|
|||||||
NoiseParams np_ridge_uwater;
|
NoiseParams np_ridge_uwater;
|
||||||
NoiseParams np_mountain;
|
NoiseParams np_mountain;
|
||||||
NoiseParams np_ridge;
|
NoiseParams np_ridge;
|
||||||
|
|
||||||
MapgenV7Params();
|
MapgenV7Params();
|
||||||
~MapgenV7Params() {}
|
~MapgenV7Params() {}
|
||||||
|
|
||||||
void readParams(Settings *settings);
|
void readParams(Settings *settings);
|
||||||
void writeParams(Settings *settings);
|
void writeParams(Settings *settings);
|
||||||
};
|
};
|
||||||
@ -57,7 +57,6 @@ public:
|
|||||||
|
|
||||||
int ystride;
|
int ystride;
|
||||||
int zstride;
|
int zstride;
|
||||||
u32 flags;
|
|
||||||
u32 spflags;
|
u32 spflags;
|
||||||
|
|
||||||
u32 blockseed;
|
u32 blockseed;
|
||||||
@ -65,9 +64,9 @@ public:
|
|||||||
v3s16 node_max;
|
v3s16 node_max;
|
||||||
v3s16 full_node_min;
|
v3s16 full_node_min;
|
||||||
v3s16 full_node_max;
|
v3s16 full_node_max;
|
||||||
|
|
||||||
s16 *ridge_heightmap;
|
s16 *ridge_heightmap;
|
||||||
|
|
||||||
Noise *noise_terrain_base;
|
Noise *noise_terrain_base;
|
||||||
Noise *noise_terrain_alt;
|
Noise *noise_terrain_alt;
|
||||||
Noise *noise_terrain_persist;
|
Noise *noise_terrain_persist;
|
||||||
@ -77,10 +76,10 @@ public:
|
|||||||
Noise *noise_ridge_uwater;
|
Noise *noise_ridge_uwater;
|
||||||
Noise *noise_mountain;
|
Noise *noise_mountain;
|
||||||
Noise *noise_ridge;
|
Noise *noise_ridge;
|
||||||
|
|
||||||
Noise *noise_heat;
|
Noise *noise_heat;
|
||||||
Noise *noise_humidity;
|
Noise *noise_humidity;
|
||||||
|
|
||||||
content_t c_stone;
|
content_t c_stone;
|
||||||
content_t c_dirt;
|
content_t c_dirt;
|
||||||
content_t c_dirt_with_grass;
|
content_t c_dirt_with_grass;
|
||||||
@ -95,7 +94,7 @@ public:
|
|||||||
|
|
||||||
MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge);
|
MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge);
|
||||||
~MapgenV7();
|
~MapgenV7();
|
||||||
|
|
||||||
virtual void makeChunk(BlockMakeData *data);
|
virtual void makeChunk(BlockMakeData *data);
|
||||||
int getGroundLevelAtPoint(v2s16 p);
|
int getGroundLevelAtPoint(v2s16 p);
|
||||||
Biome *getBiomeAtPoint(v3s16 p);
|
Biome *getBiomeAtPoint(v3s16 p);
|
||||||
@ -104,19 +103,19 @@ public:
|
|||||||
float baseTerrainLevelFromMap(int index);
|
float baseTerrainLevelFromMap(int index);
|
||||||
bool getMountainTerrainAtPoint(int x, int y, int z);
|
bool getMountainTerrainAtPoint(int x, int y, int z);
|
||||||
bool getMountainTerrainFromMap(int idx_xyz, int idx_xz, int y);
|
bool getMountainTerrainFromMap(int idx_xyz, int idx_xz, int y);
|
||||||
|
|
||||||
void calculateNoise();
|
void calculateNoise();
|
||||||
|
|
||||||
virtual int generateTerrain();
|
virtual int generateTerrain();
|
||||||
int generateBaseTerrain();
|
int generateBaseTerrain();
|
||||||
void generateMountainTerrain();
|
void generateMountainTerrain();
|
||||||
void generateRidgeTerrain();
|
void generateRidgeTerrain();
|
||||||
|
|
||||||
void generateBiomes();
|
void generateBiomes();
|
||||||
void dustTopNodes();
|
void dustTopNodes();
|
||||||
|
|
||||||
//void addTopNodes();
|
//void addTopNodes();
|
||||||
|
|
||||||
void generateCaves(int max_stone_y);
|
void generateCaves(int max_stone_y);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -124,7 +123,7 @@ struct MapgenFactoryV7 : public MapgenFactory {
|
|||||||
Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
|
Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
|
||||||
return new MapgenV7(mgid, params, emerge);
|
return new MapgenV7(mgid, params, emerge);
|
||||||
};
|
};
|
||||||
|
|
||||||
MapgenSpecificParams *createMapgenParams() {
|
MapgenSpecificParams *createMapgenParams() {
|
||||||
return new MapgenV7Params();
|
return new MapgenV7Params();
|
||||||
};
|
};
|
||||||
|
@ -144,7 +144,9 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generate(mg, &ps, max_y, v3s16(x, y, z));
|
v3s16 pos(x, y, z);
|
||||||
|
if (generate(mg, &ps, max_y, pos))
|
||||||
|
mg->gennotify.addEvent(GENNOTIFY_DECORATION, pos, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,12 +256,12 @@ bool DecoSimple::canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DecoSimple::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
|
size_t DecoSimple::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
|
||||||
{
|
{
|
||||||
ManualMapVoxelManipulator *vm = mg->vm;
|
ManualMapVoxelManipulator *vm = mg->vm;
|
||||||
|
|
||||||
if (!canPlaceDecoration(vm, p))
|
if (!canPlaceDecoration(vm, p))
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
content_t c_place = c_decos[pr->range(0, c_decos.size() - 1)];
|
content_t c_place = c_decos[pr->range(0, c_decos.size() - 1)];
|
||||||
|
|
||||||
@ -279,6 +281,8 @@ void DecoSimple::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
|
|||||||
|
|
||||||
vm->m_data[vi] = MapNode(c_place);
|
vm->m_data[vi] = MapNode(c_place);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -291,7 +295,7 @@ int DecoSimple::getHeight()
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
void DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
|
size_t DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
|
||||||
{
|
{
|
||||||
ManualMapVoxelManipulator *vm = mg->vm;
|
ManualMapVoxelManipulator *vm = mg->vm;
|
||||||
|
|
||||||
@ -305,12 +309,14 @@ void DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
|
|||||||
u32 vi = vm->m_area.index(p);
|
u32 vi = vm->m_area.index(p);
|
||||||
content_t c = vm->m_data[vi].getContent();
|
content_t c = vm->m_data[vi].getContent();
|
||||||
if (!CONTAINS(c_place_on, c))
|
if (!CONTAINS(c_place_on, c))
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
Rotation rot = (rotation == ROTATE_RAND) ?
|
Rotation rot = (rotation == ROTATE_RAND) ?
|
||||||
(Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation;
|
(Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation;
|
||||||
|
|
||||||
schematic->blitToVManip(p, vm, rot, false, mg->ndef);
|
schematic->blitToVManip(p, vm, rot, false, mg->ndef);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ public:
|
|||||||
size_t placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
|
size_t placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
|
||||||
size_t placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
|
size_t placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
|
||||||
|
|
||||||
virtual void generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) = 0;
|
virtual size_t generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) = 0;
|
||||||
virtual int getHeight() = 0;
|
virtual int getHeight() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ public:
|
|||||||
~DecoSimple() {}
|
~DecoSimple() {}
|
||||||
|
|
||||||
bool canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p);
|
bool canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p);
|
||||||
virtual void generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
|
virtual size_t generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
|
||||||
virtual int getHeight();
|
virtual int getHeight();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ public:
|
|||||||
|
|
||||||
~DecoSchematic() {}
|
~DecoSchematic() {}
|
||||||
|
|
||||||
void generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
|
virtual size_t generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
|
||||||
virtual int getHeight();
|
virtual int getHeight();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ size_t Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
|
|||||||
nmax.Y = ymax;
|
nmax.Y = ymax;
|
||||||
generate(mg->vm, mg->seed, blockseed, nmin, nmax);
|
generate(mg->vm, mg->seed, blockseed, nmin, nmax);
|
||||||
|
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,23 +194,21 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
case MGOBJ_GENNOTIFY: {
|
case MGOBJ_GENNOTIFY: {
|
||||||
|
std::map<std::string, std::vector<v3s16> >event_map;
|
||||||
|
std::map<std::string, std::vector<v3s16> >::iterator it;
|
||||||
|
|
||||||
|
mg->gennotify.getEvents(event_map);
|
||||||
|
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
for (int i = 0; flagdesc_gennotify[i].name; i++) {
|
for (it = event_map.begin(); it != event_map.end(); ++it) {
|
||||||
if (!(emerge->gennotify & flagdesc_gennotify[i].flag))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
std::vector<v3s16> *posvec = mg->gen_notifications[i];
|
|
||||||
if (!posvec)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
for (unsigned int j = 0; j != posvec->size(); j++) {
|
|
||||||
push_v3s16(L, (*posvec)[j]);
|
for (size_t j = 0; j != it->second.size(); j++) {
|
||||||
|
push_v3s16(L, it->second[j]);
|
||||||
lua_rawseti(L, -2, j + 1);
|
lua_rawseti(L, -2, j + 1);
|
||||||
}
|
}
|
||||||
lua_setfield(L, -2, flagdesc_gennotify[i].name);
|
|
||||||
|
|
||||||
posvec->clear();
|
lua_setfield(L, -2, it->first.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -291,14 +289,24 @@ int ModApiMapgen::l_set_noiseparam_defaults(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set_gen_notify(string)
|
// set_gen_notify(flags, {deco_id_table})
|
||||||
int ModApiMapgen::l_set_gen_notify(lua_State *L)
|
int ModApiMapgen::l_set_gen_notify(lua_State *L)
|
||||||
{
|
{
|
||||||
u32 flags = 0, flagmask = 0;
|
u32 flags = 0, flagmask = 0;
|
||||||
|
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||||
|
|
||||||
if (read_flags(L, 1, flagdesc_gennotify, &flags, &flagmask)) {
|
if (read_flags(L, 1, flagdesc_gennotify, &flags, &flagmask)) {
|
||||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
emerge->gen_notify_on &= ~flagmask;
|
||||||
emerge->gennotify = flags;
|
emerge->gen_notify_on |= flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lua_istable(L, 2)) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
while (lua_next(L, 2)) {
|
||||||
|
if (lua_isnumber(L, -1))
|
||||||
|
emerge->gen_notify_on_deco_ids.insert(lua_tonumber(L, -1));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -372,7 +380,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||||||
<< decotype << " not implemented";
|
<< decotype << " not implemented";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
deco->name = getstringfield_default(L, index, "name", "");
|
deco->name = getstringfield_default(L, index, "name", "");
|
||||||
deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02);
|
deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02);
|
||||||
deco->sidelen = getintfield_default(L, index, "sidelen", 8);
|
deco->sidelen = getintfield_default(L, index, "sidelen", 8);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user