Add Ore generation flags, implement ore absolute height
authorkwolekr <kwolekr@minetest.net>
Mon, 1 Apr 2013 00:02:03 +0000 (20:02 -0400)
committerkwolekr <kwolekr@minetest.net>
Mon, 1 Apr 2013 00:02:03 +0000 (20:02 -0400)
doc/lua_api.txt
src/mapgen.cpp
src/mapgen.h
src/scriptapi.cpp
src/scriptapi_types.cpp
src/scriptapi_types.h

index beb70db1577a7cbd7b35eb76797150b4792e0782..ca00fc1f972a5ebf05416adad9b3ad58a7c44db1 100644 (file)
@@ -394,6 +394,13 @@ All default ores are of the uniformly-distributed scatter type.
     Places ore if there are no more than clust_scarcity number of specified nodes within a Von Neumann
     neighborhood of clust_size radius.
 
+Ore attributes
+-------------------
+Currently supported flags:  absheight
+ - absheight
+    Also produce this same ore between the height range of -height_max and -height_min.
+    Useful for having ore in sky realms without having to duplicate ore entries.
+
 Representations of simple things
 --------------------------------
 Position/vector:
@@ -1723,6 +1730,8 @@ Ore definition (register_ore)
     ^ In this example, there is a 3x3x3 cluster where 8 out of the 27 nodes are coal ore
     height_min = -31000,
     height_max = 64,
+    flags = "",
+    ^ Attributes for this ore generation
     noise_threshhold = 0.5,
     ^ If noise is above this threshhold, ore is placed.  Not needed for a uniform distribution
     noise_params = {offset=0, scale=1, spread={x=100, y=100, z=100}, seed=23, octaves=3, persist=0.70}
index b5deaae52c5775d4386902686df875be11eb63d8..64c1886b3c1324b5f6923fbc180e0a289a2d6245 100644 (file)
@@ -42,7 +42,14 @@ FlagDesc flagdesc_mapgen[] = {
        {"v6_jungles",     MGV6_JUNGLES},
        {"v6_biome_blend", MGV6_BIOME_BLEND},
        {"flat",           MG_FLAT},
-       {NULL,                     0}
+       {NULL,             0}
+};
+
+FlagDesc flagdesc_ore[] = {
+       {"absheight",            OREFLAG_ABSHEIGHT},
+       {"scatter_noisedensity", OREFLAG_DENSITY},
+       {"claylike_nodeisnt",    OREFLAG_NODEISNT},
+       {NULL,                   0}
 };
 
 
@@ -87,17 +94,28 @@ void Ore::resolveNodeNames(INodeDefManager *ndef) {
 
 
 void OreScatter::generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) {
-       if (nmin.Y > height_max || nmax.Y < height_min)
+       int in_range = 0;
+
+       in_range |= (nmin.Y <= height_max && nmax.Y >= height_min);
+       if (flags & OREFLAG_ABSHEIGHT)
+               in_range |= (nmin.Y >= -height_max && nmax.Y <= -height_min) << 1;
+       if (!in_range)
                return;
-       
+
        resolveNodeNames(mg->ndef);
        
        MapNode n_ore(ore);
        ManualMapVoxelManipulator *vm = mg->vm;
        PseudoRandom pr(blockseed);
+       int ymin, ymax;
        
-       int ymin   = MYMAX(nmin.Y, height_min);
-       int ymax   = MYMIN(nmax.Y, height_max);
+       if (in_range & ORE_RANGE_MIRROR) {
+               ymin = MYMAX(nmin.Y, -height_max);
+               ymax = MYMIN(nmax.Y, -height_min);
+       } else {
+               ymin = MYMAX(nmin.Y, height_min);
+               ymax = MYMIN(nmax.Y, height_max);
+       }
        if (clust_size >= ymax - ymin + 1)
                return;
        
@@ -131,17 +149,29 @@ void OreScatter::generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) {
 
 
 void OreSheet::generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) {
-       if (nmin.Y > height_max || nmax.Y < height_min)
-               return;
+       int in_range = 0;
 
+       in_range |= (nmin.Y <= height_max && nmax.Y >= height_min);
+       if (flags & OREFLAG_ABSHEIGHT)
+               in_range |= (nmin.Y >= -height_max && nmax.Y <= -height_min) << 1;
+       if (!in_range)
+               return;
+               
        resolveNodeNames(mg->ndef);
 
        MapNode n_ore(ore);
        ManualMapVoxelManipulator *vm = mg->vm;
        PseudoRandom pr(blockseed + 4234);
+       int ymin, ymax;
        
-       int ymin = MYMAX(nmin.Y, height_min);
-       int ymax = MYMIN(nmax.Y, height_max);
+       if (in_range & ORE_RANGE_MIRROR) {
+               ymin = MYMAX(nmin.Y, -height_max);
+               ymax = MYMIN(nmax.Y, -height_min);
+       } else {
+               ymin = MYMAX(nmin.Y, height_min);
+               ymax = MYMIN(nmax.Y, height_max);
+       }
+
        if (clust_size >= ymax - ymin + 1)
                return;
                
index ee8a8c20c7ef91a960ceaf6a8fad03072e8c2007..e708f23b1e621fb68c262826c760f818c147f0f4 100644 (file)
@@ -36,7 +36,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define MGV6_BIOME_BLEND 0x10
 #define MG_FLAT          0x20
 
+/////////////////// Ore generation flags
+// Use absolute value of height to determine ore placement
+#define OREFLAG_ABSHEIGHT 0x01 
+// Use 3d noise to get density of ore placement, instead of just the position
+#define OREFLAG_DENSITY   0x02 // not yet implemented
+// For claylike ore types, place ore if the number of surrounding
+// nodes isn't the specified node
+#define OREFLAG_NODEISNT  0x04 // not yet implemented
+
 extern FlagDesc flagdesc_mapgen[];
+extern FlagDesc flagdesc_ore[];
 
 class BiomeDefManager;
 class Biome;
@@ -103,6 +113,9 @@ enum OreType {
        ORE_CLAYLIKE
 };
 
+#define ORE_RANGE_ACTUAL 1
+#define ORE_RANGE_MIRROR 2
+
 class Ore {
 public:
        std::string ore_name;
@@ -115,6 +128,7 @@ public:
        s16 clust_size;     // how large (in nodes) a chunk of ore is
        s16 height_min;
        s16 height_max;
+       u32 flags;          // attributes for this ore
        float nthresh;      // threshhold for noise at which an ore is placed 
        NoiseParams *np;    // noise for distribution of clusters (NULL for uniform scattering)
        Noise *noise;
index 81fcc08d3a40f5b1073b4cf62da993d0e5ca8987..c372456d4d599dd73536b1821944c48d5f684e46 100644 (file)
@@ -717,6 +717,7 @@ static int l_register_ore(lua_State *L)
        ore->clust_size     = getintfield_default(L, index, "clust_size", 0);
        ore->height_min     = getintfield_default(L, index, "height_min", 0);
        ore->height_max     = getintfield_default(L, index, "height_max", 0);
+       ore->flags          = getflagsfield(L, index, "flags", flagdesc_ore);
        ore->nthresh        = getfloatfield_default(L, index, "noise_threshhold", 0.);
 
        lua_getfield(L, index, "noise_params");
index 3d06f1623e6776684eb18825e5f14201e241ce21..01a9b3bc3bc9c8d2219151afad83ec5b1719cff5 100644 (file)
@@ -336,6 +336,13 @@ void setboolfield(lua_State *L, int table,
        lua_setfield(L, table, fieldname);
 }
 
+u32 getflagsfield(lua_State *L, int table,
+               const char *fieldname, FlagDesc *flagdesc) {
+       std::string flagstring;
+       
+       flagstring = getstringfield_default(L, table, fieldname, "");
+       return readFlagString(flagstring, flagdesc);
+}
 
 /* minetest specific types */
 MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
index e3a611a9d8d4cd0277fe6f97b3a8568e49cbd0d6..1eeed66df67fc078b45f250b0ed327085cb4e634 100644 (file)
@@ -51,6 +51,8 @@ bool               getboolfield(lua_State *L, int table,
                              const char *fieldname, bool &result);
 bool               getfloatfield(lua_State *L, int table,
                              const char *fieldname, float &result);
+u32                getflagsfield(lua_State *L, int table,
+                             const char *fieldname, FlagDesc *flagdesc);
 
 std::string        checkstringfield(lua_State *L, int table,
                              const char *fieldname);