forked from Mirrorlandia_minetest/minetest
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)
|
||||
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)
|
||||
@ -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
|
||||
--------------------
|
||||
|
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);
|
||||
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));
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
@ -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)
|
||||
@ -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));
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
@ -439,7 +439,7 @@ 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) {
|
||||
@ -447,7 +447,7 @@ void CaveV7::makeTunnel(bool dirswitch) {
|
||||
s16 h = mg->ridge_heightmap[index];
|
||||
if (h < p.Y)
|
||||
return;
|
||||
} else if (p.Y > water_level) {
|
||||
} else if (p.Y > water_level) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
@ -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)
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ DungeonGen::DungeonGen(Mapgen *mapgen, DungeonParams *dparams) {
|
||||
#ifdef DGEN_USE_TORCHES
|
||||
c_torch = ndef->getId("default:torch");
|
||||
#endif
|
||||
|
||||
|
||||
if (dparams) {
|
||||
memcpy(&dp, dparams, sizeof(dp));
|
||||
} else {
|
||||
@ -95,7 +95,7 @@ void DungeonGen::generate(u32 bseed, v3s16 nmin, v3s16 nmax) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add it
|
||||
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());
|
||||
}
|
||||
|
||||
@ -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.Y-roomsize.Y-1-start_padding.Y),
|
||||
random.range(0,areasize.Z-roomsize.Z-1-start_padding.Z));
|
||||
|
||||
|
||||
/*
|
||||
Check that we're not putting the room to an unknown place,
|
||||
otherwise it might end up floating in the air
|
||||
@ -181,10 +181,7 @@ void DungeonGen::makeDungeon(v3s16 start_padding)
|
||||
makeRoom(roomsize, roomplace);
|
||||
|
||||
v3s16 room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2);
|
||||
if (mg->gennotify & (1 << dp.notifytype)) {
|
||||
std::vector <v3s16> *nvec = mg->gen_notifications[dp.notifytype];
|
||||
nvec->push_back(room_center);
|
||||
}
|
||||
mg->gennotify.addEvent(dp.notifytype, room_center);
|
||||
|
||||
#ifdef DGEN_USE_TORCHES
|
||||
// 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
|
||||
v3s16 doorplace;
|
||||
v3s16 doordir;
|
||||
|
||||
|
||||
m_pos = walker_start_place;
|
||||
if (!findPlaceForDoor(doorplace, doordir))
|
||||
return;
|
||||
@ -253,7 +250,7 @@ void DungeonGen::makeRoom(v3s16 roomsize, v3s16 roomplace)
|
||||
{
|
||||
MapNode n_cobble(dp.c_cobble);
|
||||
MapNode n_air(CONTENT_AIR);
|
||||
|
||||
|
||||
// Make +-X walls
|
||||
for (s16 z = 0; z < roomsize.Z; z++)
|
||||
for (s16 y = 0; y < roomsize.Y; y++)
|
||||
@ -393,10 +390,10 @@ void DungeonGen::makeCorridor(v3s16 doorplace,
|
||||
u32 partlength = random.range(1, 13);
|
||||
u32 partcount = 0;
|
||||
s16 make_stairs = 0;
|
||||
|
||||
|
||||
if (random.next() % 2 == 0 && partlength >= 3)
|
||||
make_stairs = random.next() % 2 ? 1 : -1;
|
||||
|
||||
|
||||
for (u32 i = 0; i < length; i++) {
|
||||
v3s16 p = p0 + dir;
|
||||
if (partcount != 0)
|
||||
@ -409,7 +406,7 @@ void DungeonGen::makeCorridor(v3s16 doorplace,
|
||||
VMANIP_FLAG_DUNGEON_UNTOUCHABLE, MapNode(dp.c_cobble), 0);
|
||||
makeHole(p);
|
||||
makeHole(p - dir);
|
||||
|
||||
|
||||
// TODO: fix stairs code so it works 100% (quite difficult)
|
||||
|
||||
// exclude stairs from the bottom step
|
||||
@ -419,11 +416,11 @@ void DungeonGen::makeCorridor(v3s16 doorplace,
|
||||
((make_stairs == -1) && i != length - 1))) {
|
||||
// rotate face 180 deg if making stairs backwards
|
||||
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);
|
||||
if (vm->m_data[vi].getContent() == dp.c_cobble)
|
||||
vm->m_data[vi] = MapNode(dp.c_stair, 0, facedir);
|
||||
|
||||
|
||||
vi = vm->m_area.index(p.X, p.Y, p.Z);
|
||||
if (vm->m_data[vi].getContent() == dp.c_cobble)
|
||||
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 "noise.h"
|
||||
#include "mapgen.h"
|
||||
|
||||
#define VMANIP_FLAG_DUNGEON_INSIDE VOXELFLAG_CHECKED1
|
||||
#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 INodeDefManager;
|
||||
class Mapgen;
|
||||
|
||||
v3s16 rand_ortho_dir(PseudoRandom &random, bool diagonal_dirs);
|
||||
v3s16 turn_xz(v3s16 olddir, int t);
|
||||
@ -44,7 +44,7 @@ struct DungeonParams {
|
||||
content_t c_moss;
|
||||
content_t c_stair;
|
||||
|
||||
int notifytype;
|
||||
GenNotifyType notifytype;
|
||||
bool diagonal_dirs;
|
||||
float mossratio;
|
||||
v3s16 holesize;
|
||||
@ -65,14 +65,14 @@ public:
|
||||
|
||||
content_t c_torch;
|
||||
DungeonParams dp;
|
||||
|
||||
|
||||
//RoomWalker
|
||||
v3s16 m_pos;
|
||||
v3s16 m_dir;
|
||||
|
||||
DungeonGen(Mapgen *mg, DungeonParams *dparams);
|
||||
void generate(u32 bseed, v3s16 full_node_min, v3s16 full_node_max);
|
||||
|
||||
|
||||
void makeDungeon(v3s16 start_padding);
|
||||
void makeRoom(v3s16 roomsize, v3s16 roomplace);
|
||||
void makeCorridor(v3s16 doorplace, v3s16 doordir,
|
||||
@ -84,7 +84,7 @@ public:
|
||||
bool findPlaceForDoor(v3s16 &result_place, v3s16 &result_dir);
|
||||
bool findPlaceForRoomDoor(v3s16 roomsize, v3s16 &result_doorplace,
|
||||
v3s16 &result_doordir, v3s16 &result_roomplace);
|
||||
|
||||
|
||||
void randomizeDir()
|
||||
{
|
||||
m_dir = rand_ortho_dir(random, dp.diagonal_dirs);
|
||||
|
@ -94,7 +94,7 @@ EmergeManager::EmergeManager(IGameDef *gamedef) {
|
||||
this->oremgr = new OreManager(gamedef);
|
||||
this->decomgr = new DecorationManager(gamedef);
|
||||
this->schemmgr = new SchematicManager(gamedef);
|
||||
this->gennotify = 0;
|
||||
this->gen_notify_on = 0;
|
||||
|
||||
// Note that accesses to this variable are not synchronized.
|
||||
// This is because the *only* thread ever starting or stopping
|
||||
|
@ -89,7 +89,8 @@ public:
|
||||
u16 qlimit_diskonly;
|
||||
u16 qlimit_generate;
|
||||
|
||||
u32 gennotify;
|
||||
u32 gen_notify_on;
|
||||
std::set<u32> gen_notify_on_deco_ids;
|
||||
|
||||
//// Block emerge queue data structures
|
||||
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 "content_sao.h"
|
||||
#include "nodedef.h"
|
||||
#include "emerge.h"
|
||||
#include "content_mapnode.h" // For content_mapnode_get_new_name
|
||||
#include "voxelalgorithms.h"
|
||||
#include "profiler.h"
|
||||
@ -55,36 +56,53 @@ FlagDesc flagdesc_gennotify[] = {
|
||||
{"cave_end", 1 << GENNOTIFY_CAVE_END},
|
||||
{"large_cave_begin", 1 << GENNOTIFY_LARGECAVE_BEGIN},
|
||||
{"large_cave_end", 1 << GENNOTIFY_LARGECAVE_END},
|
||||
{"decoration", 1 << GENNOTIFY_DECORATION},
|
||||
{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;
|
||||
ndef = NULL;
|
||||
heightmap = NULL;
|
||||
biomemap = NULL;
|
||||
|
||||
for (unsigned int i = 0; i != NUM_GEN_NOTIFY; i++)
|
||||
gen_notifications[i] = new std::vector<v3s16>;
|
||||
}
|
||||
|
||||
|
||||
Mapgen::~Mapgen() {
|
||||
for (unsigned int i = 0; i != NUM_GEN_NOTIFY; i++)
|
||||
delete gen_notifications[i];
|
||||
Mapgen::Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge) :
|
||||
gennotify(emerge->gen_notify_on, &emerge->gen_notify_on_deco_ids)
|
||||
{
|
||||
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
|
||||
s16 Mapgen::findGroundLevelFull(v2s16 p2d) {
|
||||
s16 Mapgen::findGroundLevelFull(v2s16 p2d)
|
||||
{
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
s16 y_nodes_max = vm->m_area.MaxEdge.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();
|
||||
u32 i = vm->m_area.index(p2d.X, ymax, p2d.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)
|
||||
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;
|
||||
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);
|
||||
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))
|
||||
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);
|
||||
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};
|
||||
VoxelArea a(nmin, nmax);
|
||||
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_LIGHT 0x10
|
||||
|
||||
#define NUM_GEN_NOTIFY 6
|
||||
|
||||
class Settings;
|
||||
class ManualMapVoxelManipulator;
|
||||
class INodeDefManager;
|
||||
@ -61,13 +59,39 @@ enum MapgenObject {
|
||||
MGOBJ_GENNOTIFY
|
||||
};
|
||||
|
||||
enum GenNotify {
|
||||
enum GenNotifyType {
|
||||
GENNOTIFY_DUNGEON,
|
||||
GENNOTIFY_TEMPLE,
|
||||
GENNOTIFY_CAVE_BEGIN,
|
||||
GENNOTIFY_CAVE_END,
|
||||
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 {
|
||||
@ -85,7 +109,8 @@ struct MapgenParams {
|
||||
|
||||
MapgenSpecificParams *sparams;
|
||||
|
||||
MapgenParams() {
|
||||
MapgenParams()
|
||||
{
|
||||
mg_name = DEFAULT_MAPGEN;
|
||||
seed = 0;
|
||||
water_level = 1;
|
||||
@ -99,6 +124,7 @@ class Mapgen {
|
||||
public:
|
||||
int seed;
|
||||
int water_level;
|
||||
u32 flags;
|
||||
bool generating;
|
||||
int id;
|
||||
ManualMapVoxelManipulator *vm;
|
||||
@ -108,10 +134,10 @@ public:
|
||||
u8 *biomemap;
|
||||
v3s16 csize;
|
||||
|
||||
u32 gennotify;
|
||||
std::vector<v3s16> *gen_notifications[NUM_GEN_NOTIFY];
|
||||
GenerateNotifier gennotify;
|
||||
|
||||
Mapgen();
|
||||
Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge);
|
||||
virtual ~Mapgen();
|
||||
|
||||
s16 findGroundLevelFull(v2s16 p2d);
|
||||
|
@ -39,7 +39,8 @@ void MapgenSinglenodeParams::writeParams(Settings *settings) {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MapgenSinglenode::MapgenSinglenode(int mapgenid,
|
||||
MapgenParams *params, EmergeManager *emerge)
|
||||
MapgenParams *params, EmergeManager *emerge)
|
||||
: Mapgen(mapgenid, params, emerge)
|
||||
{
|
||||
flags = params->flags;
|
||||
|
||||
@ -67,18 +68,18 @@ void MapgenSinglenode::makeChunk(BlockMakeData *data) {
|
||||
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
||||
|
||||
this->generating = true;
|
||||
this->vm = data->vmanip;
|
||||
this->vm = data->vmanip;
|
||||
this->ndef = data->nodedef;
|
||||
|
||||
|
||||
v3s16 blockpos_min = data->blockpos_min;
|
||||
v3s16 blockpos_max = data->blockpos_max;
|
||||
|
||||
// Area of central chunk
|
||||
v3s16 node_min = blockpos_min*MAP_BLOCKSIZE;
|
||||
v3s16 node_max = (blockpos_max+v3s16(1,1,1))*MAP_BLOCKSIZE-v3s16(1,1,1);
|
||||
|
||||
|
||||
MapNode n_node(c_node);
|
||||
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
||||
u32 i = vm->m_area.index(node_min.X, y, z);
|
||||
@ -96,7 +97,7 @@ void MapgenSinglenode::makeChunk(BlockMakeData *data) {
|
||||
if (flags & MG_LIGHT)
|
||||
calcLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
||||
node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
|
||||
|
||||
|
||||
this->generating = false;
|
||||
}
|
||||
|
||||
|
@ -47,19 +47,12 @@ FlagDesc flagdesc_mapgen_v5[] = {
|
||||
};
|
||||
|
||||
|
||||
MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_) {
|
||||
this->generating = false;
|
||||
this->id = mapgenid;
|
||||
MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_)
|
||||
: Mapgen(mapgenid, params, emerge)
|
||||
{
|
||||
this->emerge = emerge_;
|
||||
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
|
||||
// for noise/height/biome maps (not vmanip)
|
||||
this->ystride = csize.X;
|
||||
@ -69,8 +62,7 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_) {
|
||||
this->heightmap = new s16[csize.X * csize.Z];
|
||||
|
||||
MapgenV5Params *sp = (MapgenV5Params *)params->sparams;
|
||||
|
||||
this->spflags = sp->spflags;
|
||||
this->spflags = sp->spflags;
|
||||
|
||||
// Terrain noise
|
||||
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_humidity;
|
||||
|
||||
|
||||
delete[] heightmap;
|
||||
delete[] biomemap;
|
||||
}
|
||||
@ -234,12 +226,12 @@ void MapgenV5::makeChunk(BlockMakeData *data) {
|
||||
assert(data->blockpos_requested.X <= data->blockpos_max.X &&
|
||||
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
||||
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
||||
|
||||
|
||||
generating = true;
|
||||
vm = data->vmanip;
|
||||
vm = data->vmanip;
|
||||
ndef = data->nodedef;
|
||||
//TimeTaker t("makeChunk");
|
||||
|
||||
|
||||
v3s16 blockpos_min = data->blockpos_min;
|
||||
v3s16 blockpos_max = data->blockpos_max;
|
||||
node_min = blockpos_min * MAP_BLOCKSIZE;
|
||||
@ -249,7 +241,7 @@ void MapgenV5::makeChunk(BlockMakeData *data) {
|
||||
|
||||
// Create a block-specific seed
|
||||
blockseed = emerge->getBlockSeed(full_node_min); //////use getBlockSeed2()!
|
||||
|
||||
|
||||
// Make some noise
|
||||
calculateNoise();
|
||||
|
||||
@ -265,7 +257,7 @@ void MapgenV5::makeChunk(BlockMakeData *data) {
|
||||
// Calculate biomes
|
||||
bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
|
||||
noise_humidity->result, heightmap, biomemap);
|
||||
|
||||
|
||||
// Actually place the biome-specific nodes
|
||||
generateBiomes();
|
||||
|
||||
@ -288,12 +280,12 @@ void MapgenV5::makeChunk(BlockMakeData *data) {
|
||||
|
||||
// Add top and bottom side of water to transforming_liquid queue
|
||||
updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
|
||||
|
||||
|
||||
// Calculate lighting
|
||||
if (flags & MG_LIGHT)
|
||||
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);
|
||||
|
||||
|
||||
this->generating = false;
|
||||
}
|
||||
|
||||
@ -303,7 +295,7 @@ void MapgenV5::calculateNoise() {
|
||||
int x = node_min.X;
|
||||
int y = node_min.Y - 1;
|
||||
int z = node_min.Z;
|
||||
|
||||
|
||||
noise_filler_depth->perlinMap2D(x, z);
|
||||
noise_factor->perlinMap2D(x, z);
|
||||
noise_height->perlinMap2D(x, z);
|
||||
@ -426,20 +418,20 @@ void MapgenV5::generateBiomes() {
|
||||
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
u32 index = 0;
|
||||
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
||||
s16 dfiller = biome->depth_filler + noise_filler_depth->result[index];
|
||||
s16 y0_top = biome->depth_top;
|
||||
s16 y0_filler = biome->depth_top + dfiller;
|
||||
|
||||
|
||||
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();
|
||||
bool have_air = c_above == CONTENT_AIR;
|
||||
|
||||
|
||||
for (s16 y = node_max.Y; y >= node_min.Y; y--) {
|
||||
content_t c = vm->m_data[i].getContent();
|
||||
bool is_replaceable_content =
|
||||
@ -448,7 +440,7 @@ void MapgenV5::generateBiomes() {
|
||||
|
||||
if (is_replaceable_content && have_air) {
|
||||
content_t c_below = vm->m_data[i - em.X].getContent();
|
||||
|
||||
|
||||
if (c_below != CONTENT_AIR) {
|
||||
if (nplaced < y0_top) {
|
||||
if(y < water_level)
|
||||
@ -484,7 +476,7 @@ void MapgenV5::generateBiomes() {
|
||||
have_air = true;
|
||||
nplaced = 0;
|
||||
}
|
||||
|
||||
|
||||
vm->m_area.add_y(em, i, -1);
|
||||
}
|
||||
}
|
||||
@ -493,14 +485,14 @@ void MapgenV5::generateBiomes() {
|
||||
void MapgenV5::dustTopNodes() {
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
u32 index = 0;
|
||||
|
||||
|
||||
if (water_level > node_max.Y)
|
||||
return;
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
||||
|
||||
|
||||
if (biome->c_dust == CONTENT_IGNORE)
|
||||
continue;
|
||||
|
||||
@ -512,18 +504,18 @@ void MapgenV5::dustTopNodes() {
|
||||
|
||||
vm->m_area.add_y(em, vi, -1);
|
||||
}
|
||||
|
||||
|
||||
content_t c = vm->m_data[vi].getContent();
|
||||
if (c == biome->c_water && biome->c_dust_water != CONTENT_IGNORE) {
|
||||
if (y < node_min.Y - 1)
|
||||
continue;
|
||||
|
||||
|
||||
vm->m_data[vi] = MapNode(biome->c_dust_water);
|
||||
} else if (!ndef->get(c).buildable_to && c != CONTENT_IGNORE
|
||||
&& c != biome->c_dust) {
|
||||
if (y == node_max.Y + 1)
|
||||
continue;
|
||||
|
||||
|
||||
vm->m_area.add_y(em, vi, 1);
|
||||
vm->m_data[vi] = MapNode(biome->c_dust);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ struct MapgenV5Params : public MapgenSpecificParams {
|
||||
|
||||
MapgenV5Params();
|
||||
~MapgenV5Params() {}
|
||||
|
||||
|
||||
void readParams(Settings *settings);
|
||||
void writeParams(Settings *settings);
|
||||
};
|
||||
@ -54,7 +54,6 @@ public:
|
||||
|
||||
int ystride;
|
||||
int zstride;
|
||||
u32 flags;
|
||||
u32 spflags;
|
||||
|
||||
u32 blockseed;
|
||||
@ -62,7 +61,7 @@ public:
|
||||
v3s16 node_max;
|
||||
v3s16 full_node_min;
|
||||
v3s16 full_node_max;
|
||||
|
||||
|
||||
Noise *noise_filler_depth;
|
||||
Noise *noise_factor;
|
||||
Noise *noise_height;
|
||||
@ -92,7 +91,7 @@ public:
|
||||
|
||||
MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_);
|
||||
~MapgenV5();
|
||||
|
||||
|
||||
virtual void makeChunk(BlockMakeData *data);
|
||||
int getGroundLevelAtPoint(v2s16 p);
|
||||
void calculateNoise();
|
||||
@ -107,7 +106,7 @@ struct MapgenFactoryV5 : public MapgenFactory {
|
||||
Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
|
||||
return new MapgenV5(mgid, params, emerge);
|
||||
};
|
||||
|
||||
|
||||
MapgenSpecificParams *createMapgenParams() {
|
||||
return new MapgenV5Params();
|
||||
};
|
||||
|
@ -49,21 +49,13 @@ FlagDesc flagdesc_mapgen_v6[] = {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge) {
|
||||
this->generating = false;
|
||||
this->id = mapgenid;
|
||||
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;
|
||||
|
||||
MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge)
|
||||
: Mapgen(mapgenid, params, emerge)
|
||||
{
|
||||
this->emerge = emerge;
|
||||
this->ystride = csize.X; //////fix this
|
||||
|
||||
MapgenV6Params *sp = (MapgenV6Params *)params->sparams;
|
||||
|
||||
MapgenV6Params *sp = (MapgenV6Params *)params->sparams;
|
||||
this->spflags = sp->spflags;
|
||||
this->freq_desert = sp->freq_desert;
|
||||
this->freq_beach = sp->freq_beach;
|
||||
@ -224,7 +216,7 @@ bool MapgenV6::block_is_underground(u64 seed, v3s16 blockpos)
|
||||
//////////////////////// Base terrain height functions
|
||||
|
||||
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 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 = 0.5 + b * (a_off + height_select);
|
||||
a = rangelim(a, 0.0, 1.0); // Limit
|
||||
|
||||
|
||||
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) {
|
||||
if (flags & MG_FLAT)
|
||||
return water_level;
|
||||
|
||||
|
||||
float terrain_base = NoisePerlin2DPosOffset(noise_terrain_base->np,
|
||||
p.X, 0.5, p.Y, 0.5, seed);
|
||||
float terrain_higher = NoisePerlin2DPosOffset(noise_terrain_higher->np,
|
||||
@ -277,12 +269,12 @@ float MapgenV6::baseTerrainLevelFromMap(v2s16 p) {
|
||||
float MapgenV6::baseTerrainLevelFromMap(int index) {
|
||||
if (flags & MG_FLAT)
|
||||
return water_level;
|
||||
|
||||
|
||||
float terrain_base = noise_terrain_base->result[index];
|
||||
float terrain_higher = noise_terrain_higher->result[index];
|
||||
float steepness = noise_steepness->result[index];
|
||||
float height_select = noise_height_select->result[index];
|
||||
|
||||
|
||||
return baseTerrainLevel(terrain_base, terrain_higher,
|
||||
steepness, height_select);
|
||||
}
|
||||
@ -340,7 +332,7 @@ float MapgenV6::getTreeAmount(v2s16 p)
|
||||
/*double noise = noise2d_perlin(
|
||||
0.5+(float)p.X/125, 0.5+(float)p.Y/125,
|
||||
seed+2, 4, 0.66);*/
|
||||
|
||||
|
||||
float noise = NoisePerlin2D(np_trees, p.X, p.Y, seed);
|
||||
float zeroval = -0.39;
|
||||
if (noise < zeroval)
|
||||
@ -355,9 +347,9 @@ bool MapgenV6::getHaveAppleTree(v2s16 p)
|
||||
/*is_apple_tree = noise2d_perlin(
|
||||
0.5+(float)p.X/100, 0.5+(float)p.Z/100,
|
||||
data->seed+342902, 3, 0.45) > 0.2;*/
|
||||
|
||||
|
||||
float noise = NoisePerlin2D(np_apple_trees, p.X, p.Y, seed);
|
||||
|
||||
|
||||
return noise > 0.2;
|
||||
}
|
||||
|
||||
@ -366,11 +358,11 @@ float MapgenV6::getMudAmount(int index)
|
||||
{
|
||||
if (flags & MG_FLAT)
|
||||
return AVERAGE_MUD_AMOUNT;
|
||||
|
||||
|
||||
/*return ((float)AVERAGE_MUD_AMOUNT + 2.0 * noise2d_perlin(
|
||||
0.5+(float)p.X/200, 0.5+(float)p.Y/200,
|
||||
seed+91013, 3, 0.55));*/
|
||||
|
||||
|
||||
return noise_mud->result[index];
|
||||
}
|
||||
|
||||
@ -381,7 +373,7 @@ bool MapgenV6::getHaveBeach(int index)
|
||||
/*double sandnoise = noise2d_perlin(
|
||||
0.2+(float)p2d.X/250, 0.7+(float)p2d.Y/250,
|
||||
seed+59420, 3, 0.50);*/
|
||||
|
||||
|
||||
float sandnoise = noise_beach->result[index];
|
||||
return (sandnoise > freq_beach);
|
||||
}
|
||||
@ -393,16 +385,16 @@ BiomeV6Type MapgenV6::getBiome(int index, v2s16 p)
|
||||
/*double d = noise2d_perlin(
|
||||
0.6+(float)p2d.X/250, 0.2+(float)p2d.Y/250,
|
||||
seed+9130, 3, 0.50);*/
|
||||
|
||||
|
||||
float d = noise_biome->result[index];
|
||||
if (d > freq_desert)
|
||||
return BT_DESERT;
|
||||
|
||||
|
||||
if ((spflags & MGV6_BIOMEBLEND) &&
|
||||
(d > freq_desert - 0.10) &&
|
||||
((noise2d(p.X, p.Y, seed) + 1.0) > (freq_desert - d) * 20.0))
|
||||
return BT_DESERT;
|
||||
|
||||
|
||||
return BT_NORMAL;
|
||||
}
|
||||
|
||||
@ -425,11 +417,11 @@ void MapgenV6::makeChunk(BlockMakeData *data) {
|
||||
assert(data->blockpos_requested.X <= data->blockpos_max.X &&
|
||||
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
||||
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
||||
|
||||
|
||||
this->generating = true;
|
||||
this->vm = data->vmanip;
|
||||
this->vm = data->vmanip;
|
||||
this->ndef = data->nodedef;
|
||||
|
||||
|
||||
// Hack: use minimum block coords for old code that assumes a single block
|
||||
v3s16 blockpos = data->blockpos_requested;
|
||||
v3s16 blockpos_min = data->blockpos_min;
|
||||
@ -491,7 +483,7 @@ void MapgenV6::makeChunk(BlockMakeData *data) {
|
||||
flowMud(mudflow_minpos, mudflow_maxpos);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Add dungeons
|
||||
if (flags & MG_DUNGEONS) {
|
||||
DungeonParams dp;
|
||||
@ -525,7 +517,7 @@ void MapgenV6::makeChunk(BlockMakeData *data) {
|
||||
DungeonGen dgen(this, &dp);
|
||||
dgen.generate(blockseed, full_node_min, full_node_max);
|
||||
}
|
||||
|
||||
|
||||
// Add top and bottom side of water to transforming_liquid queue
|
||||
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
|
||||
if (flags & MG_TREES)
|
||||
placeTreesAndJungleGrass();
|
||||
|
||||
|
||||
// Generate the registered decorations
|
||||
emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
|
||||
|
||||
@ -546,7 +538,7 @@ void MapgenV6::makeChunk(BlockMakeData *data) {
|
||||
if (flags & MG_LIGHT)
|
||||
calcLighting(node_min - v3s16(1, 1, 1) * MAP_BLOCKSIZE,
|
||||
node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
|
||||
|
||||
|
||||
this->generating = false;
|
||||
}
|
||||
|
||||
@ -598,25 +590,25 @@ int MapgenV6::generateGround() {
|
||||
MapNode n_stone(c_stone), n_desert_stone(c_desert_stone);
|
||||
int stone_surface_max_y = -MAP_GENERATION_LIMIT;
|
||||
u32 index = 0;
|
||||
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||
// Surface height
|
||||
s16 surface_y = (s16)baseTerrainLevelFromMap(index);
|
||||
|
||||
|
||||
// Log it
|
||||
if (surface_y > stone_surface_max_y)
|
||||
stone_surface_max_y = surface_y;
|
||||
|
||||
BiomeV6Type bt = getBiome(index, v2s16(x, z));
|
||||
|
||||
|
||||
// Fill ground with stone
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
u32 i = vm->m_area.index(x, node_min.Y, z);
|
||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
||||
if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
|
||||
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;
|
||||
} else if (y <= water_level) {
|
||||
vm->m_data[i] = n_water_source;
|
||||
@ -627,7 +619,7 @@ int MapgenV6::generateGround() {
|
||||
vm->m_area.add_y(em, i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return stone_surface_max_y;
|
||||
}
|
||||
|
||||
@ -647,11 +639,11 @@ void MapgenV6::addMud() {
|
||||
|
||||
// Find ground level
|
||||
s16 surface_y = find_stone_level(v2s16(x, z)); /////////////////optimize this!
|
||||
|
||||
|
||||
// Handle area not found
|
||||
if (surface_y == vm->m_area.MinEdge.Y - 1)
|
||||
continue;
|
||||
|
||||
|
||||
BiomeV6Type bt = getBiome(index, v2s16(x, z));
|
||||
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() {
|
||||
if (getBiome(v2s16(node_min.X, node_min.Z)) != BT_NORMAL)
|
||||
return;
|
||||
|
||||
|
||||
PseudoRandom pr(blockseed + 983);
|
||||
for (int i = 0; i < volume_nodes/10/10/10; i++) {
|
||||
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.Z, node_max.Z) - size.Z / 2
|
||||
);
|
||||
|
||||
|
||||
MapNode n1((p0.Y > -32 && !pr.range(0, 1)) ? c_dirt : c_gravel);
|
||||
for (int z1 = 0; z1 < size.Z; z1++)
|
||||
for (int y1 = 0; y1 < size.Y; y1++)
|
||||
@ -869,7 +861,7 @@ void MapgenV6::placeTreesAndJungleGrass() {
|
||||
//TimeTaker t("placeTrees");
|
||||
if (node_max.Y < water_level)
|
||||
return;
|
||||
|
||||
|
||||
PseudoRandom grassrandom(blockseed + 53);
|
||||
content_t c_junglegrass = ndef->getId("mapgen_junglegrass");
|
||||
// if we don't have junglegrass, don't place cignore... that's bad
|
||||
@ -877,12 +869,12 @@ void MapgenV6::placeTreesAndJungleGrass() {
|
||||
c_junglegrass = CONTENT_AIR;
|
||||
MapNode n_junglegrass(c_junglegrass);
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
|
||||
|
||||
// Divide area into parts
|
||||
s16 div = 8;
|
||||
s16 sidelen = central_area_size.X / div;
|
||||
double area = sidelen * sidelen;
|
||||
|
||||
|
||||
// N.B. We must add jungle grass first, since tree leaves will
|
||||
// obstruct the ground, giving us a false ground level
|
||||
for (s16 z0 = 0; z0 < div; z0++)
|
||||
@ -902,10 +894,10 @@ void MapgenV6::placeTreesAndJungleGrass() {
|
||||
node_min.X + sidelen + sidelen * x0 - 1,
|
||||
node_min.Z + sidelen + sidelen * z0 - 1
|
||||
);
|
||||
|
||||
|
||||
// Amount of trees, jungle area
|
||||
u32 tree_count = area * getTreeAmount(p2d_center);
|
||||
|
||||
|
||||
float humidity;
|
||||
bool is_jungle = false;
|
||||
if (spflags & MGV6_JUNGLES) {
|
||||
@ -917,16 +909,16 @@ void MapgenV6::placeTreesAndJungleGrass() {
|
||||
}
|
||||
|
||||
// Add jungle grass
|
||||
if (is_jungle) {
|
||||
if (is_jungle) {
|
||||
u32 grass_count = 5 * humidity * tree_count;
|
||||
for (u32 i = 0; i < grass_count; i++) {
|
||||
s16 x = grassrandom.range(p2d_min.X, p2d_max.X);
|
||||
s16 z = grassrandom.range(p2d_min.Y, p2d_max.Y);
|
||||
|
||||
|
||||
s16 y = findGroundLevelFull(v2s16(x, z)); ////////////////optimize this!
|
||||
if (y < water_level || y < node_min.Y || y > node_max.Y)
|
||||
continue;
|
||||
|
||||
|
||||
u32 vi = vm->m_area.index(x, y, z);
|
||||
// place on dirt_with_grass, since we know it is exposed to sunlight
|
||||
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
|
||||
for (u32 i = 0; i < tree_count; i++) {
|
||||
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
|
||||
if(y < water_level || y > node_max.Y - 6)
|
||||
continue;
|
||||
|
||||
|
||||
v3s16 p(x,y,z);
|
||||
// Trees grow only on mud and grass
|
||||
{
|
||||
@ -956,7 +948,7 @@ void MapgenV6::placeTreesAndJungleGrass() {
|
||||
continue;
|
||||
}
|
||||
p.Y++;
|
||||
|
||||
|
||||
// Make a tree
|
||||
if (is_jungle) {
|
||||
treegen::make_jungletree(*vm, p, ndef, myrand());
|
||||
@ -1009,15 +1001,15 @@ void MapgenV6::generateCaves(int max_stone_y) {
|
||||
u32 bruises_count = 1;
|
||||
PseudoRandom ps(blockseed + 21343);
|
||||
PseudoRandom ps2(blockseed + 1032);
|
||||
|
||||
|
||||
if (ps.range(1, 6) == 1)
|
||||
bruises_count = ps.range(0, ps.range(0, 2));
|
||||
|
||||
|
||||
if (getBiome(v2s16(node_min.X, node_min.Z)) == BT_DESERT) {
|
||||
caves_count /= 3;
|
||||
bruises_count /= 3;
|
||||
}
|
||||
|
||||
|
||||
for (u32 i = 0; i < caves_count + bruises_count; i++) {
|
||||
bool large_cave = (i >= caves_count);
|
||||
CaveV6 cave(this, &ps, &ps2, large_cave);
|
||||
|
@ -55,10 +55,10 @@ struct MapgenV6Params : public MapgenSpecificParams {
|
||||
NoiseParams np_humidity;
|
||||
NoiseParams np_trees;
|
||||
NoiseParams np_apple_trees;
|
||||
|
||||
|
||||
MapgenV6Params();
|
||||
~MapgenV6Params() {}
|
||||
|
||||
|
||||
void readParams(Settings *settings);
|
||||
void writeParams(Settings *settings);
|
||||
};
|
||||
@ -68,7 +68,6 @@ public:
|
||||
EmergeManager *emerge;
|
||||
|
||||
int ystride;
|
||||
u32 flags;
|
||||
u32 spflags;
|
||||
|
||||
u32 blockseed;
|
||||
@ -111,7 +110,7 @@ public:
|
||||
|
||||
MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge);
|
||||
~MapgenV6();
|
||||
|
||||
|
||||
void makeChunk(BlockMakeData *data);
|
||||
int getGroundLevelAtPoint(v2s16 p);
|
||||
|
||||
@ -124,7 +123,7 @@ public:
|
||||
s16 find_stone_level(v2s16 p2d);
|
||||
bool block_is_underground(u64 seed, v3s16 blockpos);
|
||||
s16 find_ground_level_from_noise(u64 seed, v2s16 p2d, s16 precision);
|
||||
|
||||
|
||||
float getHumidity(v2s16 p);
|
||||
float getTreeAmount(v2s16 p);
|
||||
bool getHaveAppleTree(v2s16 p);
|
||||
@ -134,9 +133,9 @@ public:
|
||||
bool getHaveBeach(int index);
|
||||
BiomeV6Type getBiome(v2s16 p);
|
||||
BiomeV6Type getBiome(int index, v2s16 p);
|
||||
|
||||
|
||||
u32 get_blockseed(u64 seed, v3s16 p);
|
||||
|
||||
|
||||
virtual void calculateNoise();
|
||||
int generateGround();
|
||||
void addMud();
|
||||
@ -152,7 +151,7 @@ struct MapgenFactoryV6 : public MapgenFactory {
|
||||
Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
|
||||
return new MapgenV6(mgid, params, emerge);
|
||||
};
|
||||
|
||||
|
||||
MapgenSpecificParams *createMapgenParams() {
|
||||
return new MapgenV6Params();
|
||||
};
|
||||
|
@ -49,19 +49,12 @@ FlagDesc flagdesc_mapgen_v7[] = {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) {
|
||||
this->generating = false;
|
||||
this->id = mapgenid;
|
||||
MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
|
||||
: Mapgen(mapgenid, params, emerge)
|
||||
{
|
||||
this->emerge = emerge;
|
||||
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
|
||||
//// for noise/height/biome maps (not vmanip)
|
||||
this->ystride = csize.X;
|
||||
@ -119,7 +112,7 @@ MapgenV7::~MapgenV7() {
|
||||
|
||||
delete noise_heat;
|
||||
delete noise_humidity;
|
||||
|
||||
|
||||
delete[] ridge_heightmap;
|
||||
delete[] heightmap;
|
||||
delete[] biomemap;
|
||||
@ -177,7 +170,7 @@ void MapgenV7Params::writeParams(Settings *settings) {
|
||||
int MapgenV7::getGroundLevelAtPoint(v2s16 p) {
|
||||
// Base terrain calculation
|
||||
s16 y = baseTerrainLevelAtPoint(p.X, p.Y);
|
||||
|
||||
|
||||
// Ridge/river terrain calculation
|
||||
float width = 0.3;
|
||||
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 (uwatern >= -width && uwatern <= width)
|
||||
return water_level - 10;
|
||||
|
||||
|
||||
// Mountain terrain calculation
|
||||
int iters = 128; // don't even bother iterating more than 128 times..
|
||||
while (iters--) {
|
||||
//current point would have been air
|
||||
if (!getMountainTerrainAtPoint(p.X, y, p.Y))
|
||||
return y;
|
||||
|
||||
|
||||
y++;
|
||||
}
|
||||
|
||||
@ -209,12 +202,12 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
|
||||
assert(data->blockpos_requested.X <= data->blockpos_max.X &&
|
||||
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
||||
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
||||
|
||||
|
||||
this->generating = true;
|
||||
this->vm = data->vmanip;
|
||||
this->vm = data->vmanip;
|
||||
this->ndef = data->nodedef;
|
||||
//TimeTaker t("makeChunk");
|
||||
|
||||
|
||||
v3s16 blockpos_min = data->blockpos_min;
|
||||
v3s16 blockpos_max = data->blockpos_max;
|
||||
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);
|
||||
|
||||
blockseed = emerge->getBlockSeed(full_node_min); //////use getBlockSeed2()!
|
||||
|
||||
|
||||
// Make some noise
|
||||
calculateNoise();
|
||||
|
||||
|
||||
// Generate base terrain, mountains, and ridges with initial heightmaps
|
||||
s16 stone_surface_max_y = generateTerrain();
|
||||
|
||||
|
||||
updateHeightmap(node_min, node_max);
|
||||
|
||||
|
||||
// Calculate biomes
|
||||
bmgr->calcBiomes(csize.X, csize.Z, noise_heat->result,
|
||||
noise_humidity->result, heightmap, biomemap);
|
||||
|
||||
|
||||
// Actually place the biome-specific nodes and what not
|
||||
generateBiomes();
|
||||
|
||||
@ -255,17 +248,17 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
|
||||
|
||||
// Sprinkle some dust on top after everything else was generated
|
||||
dustTopNodes();
|
||||
|
||||
|
||||
//printf("makeChunk: %dms\n", t.stop());
|
||||
|
||||
|
||||
updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
|
||||
|
||||
|
||||
if (flags & MG_LIGHT)
|
||||
calcLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
||||
node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
|
||||
//setLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
||||
// node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE, 0xFF);
|
||||
|
||||
|
||||
this->generating = false;
|
||||
}
|
||||
|
||||
@ -275,24 +268,24 @@ void MapgenV7::calculateNoise() {
|
||||
int x = node_min.X;
|
||||
int y = node_min.Y;
|
||||
int z = node_min.Z;
|
||||
|
||||
|
||||
noise_height_select->perlinMap2D(x, z);
|
||||
noise_height_select->transformNoiseMap();
|
||||
|
||||
|
||||
noise_terrain_persist->perlinMap2D(x, z);
|
||||
noise_terrain_persist->transformNoiseMap();
|
||||
float *persistmap = noise_terrain_persist->result;
|
||||
for (int i = 0; i != csize.X * csize.Z; i++)
|
||||
persistmap[i] = rangelim(persistmap[i], 0.4, 0.9);
|
||||
|
||||
|
||||
noise_terrain_base->perlinMap2DModulated(x, z, persistmap);
|
||||
noise_terrain_base->transformNoiseMap();
|
||||
|
||||
|
||||
noise_terrain_alt->perlinMap2DModulated(x, z, persistmap);
|
||||
noise_terrain_alt->transformNoiseMap();
|
||||
|
||||
|
||||
noise_filler_depth->perlinMap2D(x, z);
|
||||
|
||||
|
||||
if (spflags & MGV7_MOUNTAINS) {
|
||||
noise_mountain->perlinMap3D(x, y, z);
|
||||
noise_mount_height->perlinMap2D(x, z);
|
||||
@ -303,10 +296,10 @@ void MapgenV7::calculateNoise() {
|
||||
noise_ridge->perlinMap3D(x, y, z);
|
||||
noise_ridge_uwater->perlinMap2D(x, z);
|
||||
}
|
||||
|
||||
|
||||
noise_heat->perlinMap2D(x, z);
|
||||
noise_humidity->perlinMap2D(x, z);
|
||||
|
||||
|
||||
//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 humidity = NoisePerlin2D(bmgr->np_humidity, p.X, p.Z, seed);
|
||||
s16 groundlevel = baseTerrainLevelAtPoint(p.X, p.Z);
|
||||
|
||||
|
||||
return bmgr->getBiome(heat, humidity, groundlevel);
|
||||
}
|
||||
|
||||
@ -323,7 +316,7 @@ Biome *MapgenV7::getBiomeAtPoint(v3s16 p) {
|
||||
float MapgenV7::baseTerrainLevelAtPoint(int x, int z) {
|
||||
float hselect = NoisePerlin2D(noise_height_select->np, x, z, seed);
|
||||
hselect = rangelim(hselect, 0.0, 1.0);
|
||||
|
||||
|
||||
float persist = NoisePerlin2D(noise_terrain_persist->np, x, z, seed);
|
||||
persist = rangelim(persist, 0.4, 0.9);
|
||||
|
||||
@ -335,7 +328,7 @@ float MapgenV7::baseTerrainLevelAtPoint(int x, int z) {
|
||||
|
||||
if (height_alt > height_base)
|
||||
return height_alt;
|
||||
|
||||
|
||||
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 height_base = noise_terrain_base->result[index];
|
||||
float height_alt = noise_terrain_alt->result[index];
|
||||
|
||||
|
||||
if (height_alt > height_base)
|
||||
return height_alt;
|
||||
|
||||
@ -373,7 +366,7 @@ void MapgenV7::carveRivers() {
|
||||
MapNode n_air(CONTENT_AIR), n_water_source(c_water_source);
|
||||
MapNode n_stone(c_stone);
|
||||
u32 index = 0;
|
||||
|
||||
|
||||
int river_depth = 4;
|
||||
|
||||
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)) *
|
||||
noise_terrain_river->np->scale;
|
||||
height = log(height * height); //log(h^3) is pretty interesting for terrain
|
||||
|
||||
|
||||
s16 y = heightmap[index];
|
||||
if (height < 1.0 && y > river_depth &&
|
||||
y - river_depth >= node_min.Y && y <= node_max.Y) {
|
||||
|
||||
|
||||
for (s16 ry = y; ry != y - river_depth; ry--) {
|
||||
u32 vi = vm->m_area.index(x, ry, z);
|
||||
vm->m_data[vi] = n_air;
|
||||
}
|
||||
|
||||
|
||||
u32 vi = vm->m_area.index(x, y - river_depth, z);
|
||||
vm->m_data[vi] = n_water_source;
|
||||
}
|
||||
@ -411,7 +404,7 @@ int MapgenV7::generateTerrain() {
|
||||
|
||||
if (spflags & MGV7_RIDGES)
|
||||
generateRidgeTerrain();
|
||||
|
||||
|
||||
return ymax;
|
||||
}
|
||||
|
||||
@ -420,23 +413,23 @@ int MapgenV7::generateBaseTerrain() {
|
||||
MapNode n_air(CONTENT_AIR);
|
||||
MapNode n_stone(c_stone);
|
||||
MapNode n_water(c_water_source);
|
||||
|
||||
|
||||
int stone_surface_max_y = -MAP_GENERATION_LIMIT;
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
u32 index = 0;
|
||||
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||
float surface_height = baseTerrainLevelFromMap(index);
|
||||
s16 surface_y = (s16)surface_height;
|
||||
|
||||
heightmap[index] = surface_y;
|
||||
|
||||
heightmap[index] = surface_y;
|
||||
ridge_heightmap[index] = surface_y;
|
||||
|
||||
|
||||
if (surface_y > stone_surface_max_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++) {
|
||||
if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
|
||||
if (y <= surface_y)
|
||||
@ -449,7 +442,7 @@ int MapgenV7::generateBaseTerrain() {
|
||||
vm->m_area.add_y(em, i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return stone_surface_max_y;
|
||||
}
|
||||
|
||||
@ -457,10 +450,10 @@ int MapgenV7::generateBaseTerrain() {
|
||||
void MapgenV7::generateMountainTerrain() {
|
||||
if (node_max.Y <= water_level)
|
||||
return;
|
||||
|
||||
|
||||
MapNode n_stone(c_stone);
|
||||
u32 j = 0;
|
||||
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
||||
u32 vi = vm->m_area.index(node_min.X, y, z);
|
||||
@ -469,7 +462,7 @@ void MapgenV7::generateMountainTerrain() {
|
||||
|
||||
if (getMountainTerrainFromMap(j, index, y))
|
||||
vm->m_data[vi] = n_stone;
|
||||
|
||||
|
||||
vi++;
|
||||
j++;
|
||||
}
|
||||
@ -481,36 +474,36 @@ void MapgenV7::generateRidgeTerrain() {
|
||||
MapNode n_water(c_water_source);
|
||||
MapNode n_air(CONTENT_AIR);
|
||||
u32 index = 0;
|
||||
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
||||
u32 vi = vm->m_area.index(node_min.X, y, z);
|
||||
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);
|
||||
|
||||
|
||||
if (heightmap[j] < water_level - 4)
|
||||
continue;
|
||||
|
||||
|
||||
float widthn = (noise_terrain_persist->result[j] - 0.6) / 0.1;
|
||||
//widthn = rangelim(widthn, -0.05, 0.5);
|
||||
|
||||
|
||||
float width = 0.3; // TODO: figure out acceptable perlin noise values
|
||||
float uwatern = noise_ridge_uwater->result[j] * 2;
|
||||
if (uwatern < -width || uwatern > width)
|
||||
continue;
|
||||
|
||||
|
||||
float height_mod = (float)(y + 17) / 2.5;
|
||||
float width_mod = (width - fabs(uwatern));
|
||||
float nridge = noise_ridge->result[index] * (float)y / 7.0;
|
||||
|
||||
if (y < water_level)
|
||||
nridge = -fabs(nridge) * 3.0 * widthn * 0.3;
|
||||
|
||||
|
||||
if (nridge + width_mod * height_mod < 0.6)
|
||||
continue;
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
@ -528,7 +521,7 @@ void MapgenV7::generateBiomes() {
|
||||
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
u32 index = 0;
|
||||
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
||||
@ -537,14 +530,14 @@ void MapgenV7::generateBiomes() {
|
||||
s16 y0_filler = biome->depth_top + dfiller;
|
||||
|
||||
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();
|
||||
bool have_air = c_above == CONTENT_AIR;
|
||||
|
||||
|
||||
for (s16 y = node_max.Y; y >= node_min.Y; y--) {
|
||||
content_t c = vm->m_data[i].getContent();
|
||||
|
||||
|
||||
// It could be the case that the elevation is equal to the chunk
|
||||
// boundary, but the chunk above has not been generated yet
|
||||
if (y == node_max.Y && c_above == CONTENT_IGNORE &&
|
||||
@ -554,10 +547,10 @@ void MapgenV7::generateBiomes() {
|
||||
(x - node_min.X);
|
||||
have_air = !getMountainTerrainFromMap(j, index, y);
|
||||
}
|
||||
|
||||
|
||||
if (c == c_stone && have_air) {
|
||||
content_t c_below = vm->m_data[i - em.X].getContent();
|
||||
|
||||
|
||||
if (c_below != CONTENT_AIR) {
|
||||
if (nplaced < y0_top) {
|
||||
if(y < water_level)
|
||||
@ -593,7 +586,7 @@ void MapgenV7::generateBiomes() {
|
||||
have_air = true;
|
||||
nplaced = 0;
|
||||
}
|
||||
|
||||
|
||||
vm->m_area.add_y(em, i, -1);
|
||||
}
|
||||
}
|
||||
@ -603,14 +596,14 @@ void MapgenV7::generateBiomes() {
|
||||
void MapgenV7::dustTopNodes() {
|
||||
v3s16 em = vm->m_area.getExtent();
|
||||
u32 index = 0;
|
||||
|
||||
|
||||
if (water_level > node_max.Y)
|
||||
return;
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
||||
|
||||
|
||||
if (biome->c_dust == CONTENT_IGNORE)
|
||||
continue;
|
||||
|
||||
@ -622,17 +615,17 @@ void MapgenV7::dustTopNodes() {
|
||||
|
||||
vm->m_area.add_y(em, vi, -1);
|
||||
}
|
||||
|
||||
|
||||
content_t c = vm->m_data[vi].getContent();
|
||||
if (c == biome->c_water && biome->c_dust_water != CONTENT_IGNORE) {
|
||||
if (y < node_min.Y)
|
||||
continue;
|
||||
|
||||
|
||||
vm->m_data[vi] = MapNode(biome->c_dust_water);
|
||||
} else if (!ndef->get(c).buildable_to && c != CONTENT_IGNORE) {
|
||||
if (y == node_max.Y)
|
||||
continue;
|
||||
|
||||
|
||||
vm->m_area.add_y(em, vi, 1);
|
||||
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 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||
Biome *biome = bmgr->biomes[biomemap[index]];
|
||||
|
||||
|
||||
//////////////////// First, add top nodes below the ridge
|
||||
s16 y = ridge_heightmap[index];
|
||||
|
||||
|
||||
// This cutoff is good enough, but not perfect.
|
||||
// It will cut off potentially placed top nodes at chunk boundaries
|
||||
if (y < node_min.Y)
|
||||
@ -664,7 +657,7 @@ void MapgenV7::addTopNodes() {
|
||||
if (ndef->get(c).walkable)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
// where a ridge had been carved
|
||||
@ -692,7 +685,7 @@ void MapgenV7::addTopNodes() {
|
||||
vm->m_data[i] = MapNode(c_dirt_with_grass);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////// Now, add top nodes on top of the ridge
|
||||
y = heightmap[index];
|
||||
if (y > node_max.Y) {
|
||||
|
@ -42,10 +42,10 @@ struct MapgenV7Params : public MapgenSpecificParams {
|
||||
NoiseParams np_ridge_uwater;
|
||||
NoiseParams np_mountain;
|
||||
NoiseParams np_ridge;
|
||||
|
||||
|
||||
MapgenV7Params();
|
||||
~MapgenV7Params() {}
|
||||
|
||||
|
||||
void readParams(Settings *settings);
|
||||
void writeParams(Settings *settings);
|
||||
};
|
||||
@ -57,7 +57,6 @@ public:
|
||||
|
||||
int ystride;
|
||||
int zstride;
|
||||
u32 flags;
|
||||
u32 spflags;
|
||||
|
||||
u32 blockseed;
|
||||
@ -65,9 +64,9 @@ public:
|
||||
v3s16 node_max;
|
||||
v3s16 full_node_min;
|
||||
v3s16 full_node_max;
|
||||
|
||||
|
||||
s16 *ridge_heightmap;
|
||||
|
||||
|
||||
Noise *noise_terrain_base;
|
||||
Noise *noise_terrain_alt;
|
||||
Noise *noise_terrain_persist;
|
||||
@ -77,10 +76,10 @@ public:
|
||||
Noise *noise_ridge_uwater;
|
||||
Noise *noise_mountain;
|
||||
Noise *noise_ridge;
|
||||
|
||||
|
||||
Noise *noise_heat;
|
||||
Noise *noise_humidity;
|
||||
|
||||
|
||||
content_t c_stone;
|
||||
content_t c_dirt;
|
||||
content_t c_dirt_with_grass;
|
||||
@ -95,7 +94,7 @@ public:
|
||||
|
||||
MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge);
|
||||
~MapgenV7();
|
||||
|
||||
|
||||
virtual void makeChunk(BlockMakeData *data);
|
||||
int getGroundLevelAtPoint(v2s16 p);
|
||||
Biome *getBiomeAtPoint(v3s16 p);
|
||||
@ -104,19 +103,19 @@ public:
|
||||
float baseTerrainLevelFromMap(int index);
|
||||
bool getMountainTerrainAtPoint(int x, int y, int z);
|
||||
bool getMountainTerrainFromMap(int idx_xyz, int idx_xz, int y);
|
||||
|
||||
|
||||
void calculateNoise();
|
||||
|
||||
|
||||
virtual int generateTerrain();
|
||||
int generateBaseTerrain();
|
||||
void generateMountainTerrain();
|
||||
void generateRidgeTerrain();
|
||||
|
||||
|
||||
void generateBiomes();
|
||||
void dustTopNodes();
|
||||
|
||||
|
||||
//void addTopNodes();
|
||||
|
||||
|
||||
void generateCaves(int max_stone_y);
|
||||
};
|
||||
|
||||
@ -124,7 +123,7 @@ struct MapgenFactoryV7 : public MapgenFactory {
|
||||
Mapgen *createMapgen(int mgid, MapgenParams *params, EmergeManager *emerge) {
|
||||
return new MapgenV7(mgid, params, emerge);
|
||||
};
|
||||
|
||||
|
||||
MapgenSpecificParams *createMapgenParams() {
|
||||
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;
|
||||
|
||||
if (!canPlaceDecoration(vm, p))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -305,12 +309,14 @@ void DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
|
||||
u32 vi = vm->m_area.index(p);
|
||||
content_t c = vm->m_data[vi].getContent();
|
||||
if (!CONTAINS(c_place_on, c))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
Rotation rot = (rotation == ROTATE_RAND) ?
|
||||
(Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation;
|
||||
|
||||
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 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;
|
||||
};
|
||||
|
||||
@ -92,7 +92,7 @@ public:
|
||||
~DecoSimple() {}
|
||||
|
||||
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();
|
||||
};
|
||||
|
||||
@ -105,7 +105,7 @@ public:
|
||||
|
||||
~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();
|
||||
};
|
||||
|
||||
|
@ -95,7 +95,7 @@ size_t Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
|
||||
nmax.Y = ymax;
|
||||
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;
|
||||
}
|
||||
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);
|
||||
for (int i = 0; flagdesc_gennotify[i].name; i++) {
|
||||
if (!(emerge->gennotify & flagdesc_gennotify[i].flag))
|
||||
continue;
|
||||
|
||||
std::vector<v3s16> *posvec = mg->gen_notifications[i];
|
||||
if (!posvec)
|
||||
return 0;
|
||||
|
||||
for (it = event_map.begin(); it != event_map.end(); ++it) {
|
||||
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_setfield(L, -2, flagdesc_gennotify[i].name);
|
||||
|
||||
posvec->clear();
|
||||
lua_setfield(L, -2, it->first.c_str());
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -291,14 +289,24 @@ int ModApiMapgen::l_set_noiseparam_defaults(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set_gen_notify(string)
|
||||
// set_gen_notify(flags, {deco_id_table})
|
||||
int ModApiMapgen::l_set_gen_notify(lua_State *L)
|
||||
{
|
||||
u32 flags = 0, flagmask = 0;
|
||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||
|
||||
if (read_flags(L, 1, flagdesc_gennotify, &flags, &flagmask)) {
|
||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||
emerge->gennotify = flags;
|
||||
emerge->gen_notify_on &= ~flagmask;
|
||||
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;
|
||||
@ -372,7 +380,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
||||
<< decotype << " not implemented";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
deco->name = getstringfield_default(L, index, "name", "");
|
||||
deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02);
|
||||
deco->sidelen = getintfield_default(L, index, "sidelen", 8);
|
||||
|
Loading…
Reference in New Issue
Block a user