Rewrite generate notification mechanism
authorkwolekr <kwolekr@minetest.net>
Sat, 6 Dec 2014 09:18:04 +0000 (04:18 -0500)
committerkwolekr <kwolekr@minetest.net>
Sat, 6 Dec 2014 18:53:35 +0000 (13:53 -0500)
Add support for notify-on-decoration
Clean up mapgen constructors
Clean up mapgen.cpp code style somewhat
Remove trailing whitespace from some files

19 files changed:
doc/lua_api.txt
src/cavegen.cpp
src/dungeongen.cpp
src/dungeongen.h
src/emerge.cpp
src/emerge.h
src/mapgen.cpp
src/mapgen.h
src/mapgen_singlenode.cpp
src/mapgen_v5.cpp
src/mapgen_v5.h
src/mapgen_v6.cpp
src/mapgen_v6.h
src/mapgen_v7.cpp
src/mapgen_v7.h
src/mg_decoration.cpp
src/mg_decoration.h
src/mg_ore.cpp
src/script/lua_api/l_mapgen.cpp

index 6c33d92d4677aa25f51657bf1e8b97c3b58b2cbb..df4b59a054a13ecc80cddf1606f15992e4b10929 100644 (file)
@@ -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
 --------------------
index d93911f277bdda6fab4c3bdf581426b6e7a37260..02eef72d8f449ce86099675bab7a39cf233956c3 100644 (file)
@@ -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;
                                }
index 2027b7f1381c0fac9aca3a45e8d7c1f31b7b5c85..2a89c714e37936eed0828170dfc178dd82d05514 100644 (file)
@@ -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);
index 4a0bfcefd85c2eb2552f9c2d6918cbba50ffffa9..ff1d0bc33eb77a17f3b79c4c0c404e483e330283 100644 (file)
@@ -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);
index 6410e56e955ae70ee4eb901eb58f4301908e36b7..8813a71a96dc2d6a449ce19ed091fa917b7f19bb 100644 (file)
@@ -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
index 65b1d6594ebe9e33544e436c8c88d5597ed26fe5..7de1c8391d9c309b21f2b503107bc91d41c94c00 100644 (file)
@@ -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;
index 60fa842a6635b3e6bb8c9e4ae77324cfc775054f..44ce0c6151fcc9221be6d61a885ef1daf7c082bc 100644 (file)
@@ -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);
@@ -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();
+}
+
+
 ///////////////////////////////////////////////////////////////////////////////
 
 
index cf2120a7a2843f98398b7effc213feee79b1cae3..9cdb157e11184ec6682cfb24cc277af454fda20c 100644 (file)
@@ -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);
index 9f2e6c122df9516d53a7a1242b8d9375bb2b580d..8558b3b1427e9e06795ae11f185f45c40e2a5760 100644 (file)
@@ -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;
 }
 
index 3867827cc96c17d7a6b894e3401accf74ba0b44b..95cfeeef5afce01b2ba1da1693b1501d9dac5e28 100644 (file)
@@ -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);
                }
index 84e63672b9be64ed717de602f2ecb2aca17d3f42..22a836d64afe6deef5af297e4e331783699c5346 100644 (file)
@@ -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();
        };
index de0c8168821f0589980aaa88ed910198f4574d31..f1ba2a486205dbe75764579a4e717e8ee2d0bdd3 100644 (file)
@@ -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);
index eecfb1fe6d91bd477f49a59004478ebd29b4abf1..e6d2cdc544bfc0ace08dc2ea77f9fadebf9be7bd 100644 (file)
@@ -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();
        };
index bad01bc2a649091c9e9c30b3ba0b9671df8141a1..82bc4aae825cb16faf0cc03e3fef6c4b6f7c0c46 100644 (file)
@@ -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) {
index bc497309bfa0b7367d4f237c6870033472b6e52a..1af88ddf5b0a67b2996dd4d43f3fe214d5560327 100644 (file)
@@ -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();
        };
index 3604b06c0cecb0ef84f1c404158803187c9680f3..a8fd9eaadf0b87fe362d9bd588a42f263e0bc7c6 100644 (file)
@@ -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;
 }
 
 
index d5c9f016561124b12506d9cf2c054b21b22039b5..c698710b5343d38c383c0b8bf1970f7257c33aef 100644 (file)
@@ -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();
 };
 
index edbb224c147005e352489f97621914a126939997..80e86130a1fa61510e5bd6f5dfabb3861f9314b9 100644 (file)
@@ -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;
 }
 
 
index bb76bb450b8ebd72b33a135d820b7d189535f4a8..a8f55cd2536593913aca2049253655391c2732a2 100644 (file)
@@ -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);