aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkwolekr <kwolekr@minetest.net>2014-12-06 04:18:04 -0500
committerkwolekr <kwolekr@minetest.net>2014-12-06 13:53:35 -0500
commit5062b99cb0d252d9e377ff4560f7ecc9e66fd558 (patch)
tree3474c0734aac243cabfcf3af763becb4025da35b /src
parent2b119e1e192ead701e69e261fe94ccb7382dbee7 (diff)
downloadminetest-5062b99cb0d252d9e377ff4560f7ecc9e66fd558.tar.gz
minetest-5062b99cb0d252d9e377ff4560f7ecc9e66fd558.tar.bz2
minetest-5062b99cb0d252d9e377ff4560f7ecc9e66fd558.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/cavegen.cpp106
-rw-r--r--src/dungeongen.cpp27
-rw-r--r--src/dungeongen.h10
-rw-r--r--src/emerge.cpp2
-rw-r--r--src/emerge.h3
-rw-r--r--src/mapgen.cpp127
-rw-r--r--src/mapgen.h40
-rw-r--r--src/mapgen_singlenode.cpp13
-rw-r--r--src/mapgen_v5.cpp56
-rw-r--r--src/mapgen_v5.h9
-rw-r--r--src/mapgen_v6.cpp106
-rw-r--r--src/mapgen_v6.h15
-rw-r--r--src/mapgen_v7.cpp147
-rw-r--r--src/mapgen_v7.h27
-rw-r--r--src/mg_decoration.cpp16
-rw-r--r--src/mg_decoration.h6
-rw-r--r--src/mg_ore.cpp2
-rw-r--r--src/script/lua_api/l_mapgen.cpp38
18 files changed, 427 insertions, 323 deletions
diff --git a/src/cavegen.cpp b/src/cavegen.cpp
index d93911f27..02eef72d8 100644
--- a/src/cavegen.cpp
+++ b/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;
}
diff --git a/src/dungeongen.cpp b/src/dungeongen.cpp
index 2027b7f13..2a89c714e 100644
--- a/src/dungeongen.cpp
+++ b/src/dungeongen.cpp
@@ -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);
diff --git a/src/dungeongen.h b/src/dungeongen.h
index 4a0bfcefd..ff1d0bc33 100644
--- a/src/dungeongen.h
+++ b/src/dungeongen.h
@@ -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);
diff --git a/src/emerge.cpp b/src/emerge.cpp
index 6410e56e9..8813a71a9 100644
--- a/src/emerge.cpp
+++ b/src/emerge.cpp
@@ -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
diff --git a/src/emerge.h b/src/emerge.h
index 65b1d6594..7de1c8391 100644
--- a/src/emerge.h
+++ b/src/emerge.h
@@ -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;
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index 60fa842a6..44ce0c615 100644
--- a/src/mapgen.cpp
+++ b/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(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() {
- for (unsigned int i = 0; i != NUM_GEN_NOTIFY; i++)
- delete gen_notifications[i];
+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);
@@ -289,6 +314,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();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
GenElementManager::~GenElementManager()
{
diff --git a/src/mapgen.h b/src/mapgen.h
index cf2120a7a..9cdb157e1 100644
--- a/src/mapgen.h
+++ b/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);
diff --git a/src/mapgen_singlenode.cpp b/src/mapgen_singlenode.cpp
index 9f2e6c122..8558b3b14 100644
--- a/src/mapgen_singlenode.cpp
+++ b/src/mapgen_singlenode.cpp
@@ -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;
}
diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp
index 3867827cc..95cfeeef5 100644
--- a/src/mapgen_v5.cpp
+++ b/src/mapgen_v5.cpp
@@ -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);
}
diff --git a/src/mapgen_v5.h b/src/mapgen_v5.h
index 84e63672b..22a836d64 100644
--- a/src/mapgen_v5.h
+++ b/src/mapgen_v5.h
@@ -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();
};
diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp
index de0c81688..f1ba2a486 100644
--- a/src/mapgen_v6.cpp
+++ b/src/mapgen_v6.cpp
@@ -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);
diff --git a/src/mapgen_v6.h b/src/mapgen_v6.h
index eecfb1fe6..e6d2cdc54 100644
--- a/src/mapgen_v6.h
+++ b/src/mapgen_v6.h
@@ -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();
};
diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp
index bad01bc2a..82bc4aae8 100644
--- a/src/mapgen_v7.cpp
+++ b/src/mapgen_v7.cpp
@@ -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) {
diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h
index bc497309b..1af88ddf5 100644
--- a/src/mapgen_v7.h
+++ b/src/mapgen_v7.h
@@ -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();
};
diff --git a/src/mg_decoration.cpp b/src/mg_decoration.cpp
index 3604b06c0..a8fd9eaad 100644
--- a/src/mg_decoration.cpp
+++ b/src/mg_decoration.cpp
@@ -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;
}
diff --git a/src/mg_decoration.h b/src/mg_decoration.h
index d5c9f0165..c698710b5 100644
--- a/src/mg_decoration.h
+++ b/src/mg_decoration.h
@@ -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();
};
diff --git a/src/mg_ore.cpp b/src/mg_ore.cpp
index edbb224c1..80e86130a 100644
--- a/src/mg_ore.cpp
+++ b/src/mg_ore.cpp
@@ -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;
}
diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp
index bb76bb450..a8f55cd25 100644
--- a/src/script/lua_api/l_mapgen.cpp
+++ b/src/script/lua_api/l_mapgen.cpp
@@ -194,23 +194,21 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L)
return 1;
}
case MGOBJ_GENNOTIFY: {
- lua_newtable(L);
- for (int i = 0; flagdesc_gennotify[i].name; i++) {
- if (!(emerge->gennotify & flagdesc_gennotify[i].flag))
- continue;
+ std::map<std::string, std::vector<v3s16> >event_map;
+ std::map<std::string, std::vector<v3s16> >::iterator it;
- std::vector<v3s16> *posvec = mg->gen_notifications[i];
- if (!posvec)
- return 0;
+ mg->gennotify.getEvents(event_map);
+ lua_newtable(L);
+ 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);