Skip to content

Commit

Permalink
Rewrite generate notification mechanism
Browse files Browse the repository at this point in the history
Add support for notify-on-decoration
Clean up mapgen constructors
Clean up mapgen.cpp code style somewhat
Remove trailing whitespace from some files
  • Loading branch information
kwolekr committed Dec 6, 2014
1 parent 2b119e1 commit 5062b99
Show file tree
Hide file tree
Showing 19 changed files with 434 additions and 327 deletions.
11 changes: 7 additions & 4 deletions doc/lua_api.txt
Expand Up @@ -1533,10 +1533,11 @@ minetest.get_perlin(seeddiff, octaves, persistence, scale)
^ Return world-specific perlin noise (int(worldseed)+seeddiff)
minetest.get_voxel_manip()
^ 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
^ flags is a comma-delimited combination of:
^ dungeon, temple, cave_begin, cave_end, large_cave_begin, large_cave_end
^ flags is a flag field with the available flags:
^ 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)
^ Return requested mapgen object if available (see Mapgen objects)
minetest.set_mapgen_params(MapgenParams)
Expand Down Expand Up @@ -2220,7 +2221,9 @@ current mapgen.
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
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
--------------------
Expand Down
106 changes: 53 additions & 53 deletions src/cavegen.cpp
Expand Up @@ -45,7 +45,7 @@ CaveV6::CaveV6(MapgenV6 *mg, PseudoRandom *ps, PseudoRandom *ps2, bool is_large_
max_tunnel_diameter = ps->range(2, 6);
dswitchint = ps->range(1, 14);
flooded = true;

if (large_cave) {
part_max_length_rs = ps->range(2,4);
tunnel_routepoints = ps->range(5, ps->range(15,30));
Expand All @@ -55,7 +55,7 @@ CaveV6::CaveV6(MapgenV6 *mg, PseudoRandom *ps, PseudoRandom *ps2, bool is_large_
part_max_length_rs = ps->range(2,9);
tunnel_routepoints = ps->range(10, ps->range(15,30));
}

large_cave_is_flat = (ps->range(0,1) == 0);
}

Expand Down Expand Up @@ -109,21 +109,21 @@ void CaveV6::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) {
(float)(ps->next() % ar.Z) + 0.5
);

int notifytype = large_cave ? GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
if (mg->gennotify & (1 << notifytype)) {
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype];
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z));
}
// Add generation notify begin event
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
GenNotifyType notifytype = large_cave ?
GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
mg->gennotify.addEvent(notifytype, abs_pos);

// Generate some tunnel starting from orp
for (u16 j = 0; j < tunnel_routepoints; j++)
makeTunnel(j % dswitchint == 0);

notifytype = large_cave ? GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END;
if (mg->gennotify & (1 << notifytype)) {
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype];
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z));
}
// Add generation notify end event
abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
notifytype = large_cave ?
GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
mg->gennotify.addEvent(notifytype, abs_pos);
}


Expand Down Expand Up @@ -179,31 +179,31 @@ void CaveV6::makeTunnel(bool dirswitch) {
rp.X = 0;
else if (rp.X >= ar.X)
rp.X = ar.X - 1;

if (rp.Y < route_y_min)
rp.Y = route_y_min;
else if (rp.Y >= route_y_max)
rp.Y = route_y_max - 1;

if (rp.Z < 0)
rp.Z = 0;
else if (rp.Z >= ar.Z)
rp.Z = ar.Z - 1;

vec = rp - orp;

float veclen = vec.getLength();
// As odd as it sounds, veclen is *exactly* 0.0 sometimes, causing a FPE
if (veclen < 0.05)
veclen = 1.0;

// Every second section is rough
bool randomize_xz = (ps2->range(1, 2) == 1);

// Carve routes
for (float f = 0; f < 1.0; f += 1.0 / veclen)
carveRoute(vec, f, randomize_xz);

orp = rp;
}

Expand All @@ -212,10 +212,10 @@ void CaveV6::carveRoute(v3f vec, float f, bool randomize_xz) {
MapNode airnode(CONTENT_AIR);
MapNode waternode(c_water_source);
MapNode lavanode(c_lava_source);

v3s16 startp(orp.X, orp.Y, orp.Z);
startp += of;

v3f fp = orp + vec * f;
fp.X += 0.1 * ps->range(-10, 10);
fp.Z += 0.1 * ps->range(-10, 10);
Expand All @@ -227,13 +227,13 @@ void CaveV6::carveRoute(v3f vec, float f, bool randomize_xz) {
d0 += ps->range(-1, 1);
d1 += ps->range(-1, 1);
}

for (s16 z0 = d0; z0 <= d1; z0++) {
s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1);
for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) {
s16 maxabsxz = MYMAX(abs(x0), abs(z0));
s16 si2 = rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1);
for (s16 y0 = -si2; y0 <= si2; y0++) {
for (s16 y0 = -si2; y0 <= si2; y0++) {
if (large_cave_is_flat) {
// Make large caves not so tall
if (rs > 7 && abs(y0) >= rs / 3)
Expand Down Expand Up @@ -293,7 +293,7 @@ CaveV7::CaveV7(MapgenV7 *mg, PseudoRandom *ps, bool is_large_cave) {

dswitchint = ps->range(1, 14);
flooded = ps->range(1, 2) == 2;

if (large_cave) {
part_max_length_rs = ps->range(2, 4);
tunnel_routepoints = ps->range(5, ps->range(15, 30));
Expand All @@ -305,7 +305,7 @@ CaveV7::CaveV7(MapgenV7 *mg, PseudoRandom *ps, bool is_large_cave) {
min_tunnel_diameter = 2;
max_tunnel_diameter = ps->range(2, 6);
}

large_cave_is_flat = (ps->range(0, 1) == 0);
}

Expand Down Expand Up @@ -358,21 +358,21 @@ void CaveV7::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) {
(float)(ps->next() % ar.Z) + 0.5
);

int notifytype = large_cave ? GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
if (mg->gennotify & (1 << notifytype)) {
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype];
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z));
}
// Add generation notify begin event
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
GenNotifyType notifytype = large_cave ?
GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
mg->gennotify.addEvent(notifytype, abs_pos);

// Generate some tunnel starting from orp
for (u16 j = 0; j < tunnel_routepoints; j++)
makeTunnel(j % dswitchint == 0);

notifytype = large_cave ? GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END;
if (mg->gennotify & (1 << notifytype)) {
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype];
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z));
}
// Add generation notify end event
abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
notifytype = large_cave ?
GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END;
mg->gennotify.addEvent(notifytype, abs_pos);
}


Expand Down Expand Up @@ -428,7 +428,7 @@ void CaveV7::makeTunnel(bool dirswitch) {
v3s16 orpi(orp.X, orp.Y, orp.Z);
v3s16 veci(vec.X, vec.Y, vec.Z);
v3s16 p;

p = orpi + veci + of + rs / 2;
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
p.X >= node_min.X && p.X <= node_max.X) {
Expand All @@ -439,15 +439,15 @@ void CaveV7::makeTunnel(bool dirswitch) {
} else if (p.Y > water_level) {
return; // If it's not in our heightmap, use a simple heuristic
}

p = orpi + of + rs / 2;
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
p.X >= node_min.X && p.X <= node_max.X) {
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
s16 h = mg->ridge_heightmap[index];
if (h < p.Y)
return;
} else if (p.Y > water_level) {
} else if (p.Y > water_level) {
return;
}
}
Expand All @@ -459,23 +459,23 @@ void CaveV7::makeTunnel(bool dirswitch) {
rp.X = 0;
else if (rp.X >= ar.X)
rp.X = ar.X - 1;

if (rp.Y < route_y_min)
rp.Y = route_y_min;
else if (rp.Y >= route_y_max)
rp.Y = route_y_max - 1;

if (rp.Z < 0)
rp.Z = 0;
else if (rp.Z >= ar.Z)
rp.Z = ar.Z - 1;

vec = rp - orp;

float veclen = vec.getLength();
if (veclen < 0.05)
veclen = 1.0;

// Every second section is rough
bool randomize_xz = (ps->range(1, 2) == 1);

Expand All @@ -487,7 +487,7 @@ void CaveV7::makeTunnel(bool dirswitch) {
// Carve routes
for (float f = 0; f < 1.0; f += 1.0 / veclen)
carveRoute(vec, f, randomize_xz, is_ravine);

orp = rp;
}

Expand All @@ -496,14 +496,14 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
MapNode airnode(CONTENT_AIR);
MapNode waternode(c_water_source);
MapNode lavanode(c_lava_source);

v3s16 startp(orp.X, orp.Y, orp.Z);
startp += of;

float nval = NoisePerlin3D(np_caveliquids, startp.X,
startp.Y, startp.Z, mg->seed);
MapNode liquidnode = nval < 0.40 ? lavanode : waternode;

v3f fp = orp + vec * f;
fp.X += 0.1 * ps->range(-10, 10);
fp.Z += 0.1 * ps->range(-10, 10);
Expand All @@ -515,23 +515,23 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
d0 += ps->range(-1, 1);
d1 += ps->range(-1, 1);
}

bool flat_cave_floor = !large_cave && ps->range(0, 2) == 2;
bool should_make_cave_hole = ps->range(1, 10) == 1;

for (s16 z0 = d0; z0 <= d1; z0++) {
s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1);
for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) {
s16 maxabsxz = MYMAX(abs(x0), abs(z0));

s16 si2 = is_ravine ? MYMIN(ps->range(25, 26), ar.Y) :
rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1);

for (s16 y0 = -si2; y0 <= si2; y0++) {
// Make better floors in small caves
if(flat_cave_floor && y0 <= -rs/2 && rs<=7)
continue;

if (large_cave_is_flat) {
// Make large caves not so tall
if (rs > 7 && abs(y0) >= rs / 3)
Expand All @@ -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);
p += of;

if (!is_ravine && mg->heightmap && should_make_cave_hole &&
p.X <= node_max.X && p.Z <= node_max.Z) {
int maplen = node_max.X - node_min.X + 1;
Expand All @@ -553,13 +553,13 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
continue;

u32 i = vm->m_area.index(p);

// Don't replace air, water, lava, or ice
content_t c = vm->m_data[i].getContent();
if (!ndef->get(c).is_ground_content || c == CONTENT_AIR ||
c == c_water_source || c == c_lava_source || c == c_ice)
continue;

if (large_cave) {
int full_ymin = node_min.Y - MAP_BLOCKSIZE;
int full_ymax = node_max.Y + MAP_BLOCKSIZE;
Expand All @@ -573,7 +573,7 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
} else {
if (c == CONTENT_IGNORE)
continue;

vm->m_data[i] = airnode;
vm->m_flags[i] |= VMANIP_FLAG_CAVE;
}
Expand Down

0 comments on commit 5062b99

Please sign in to comment.