clust_scarcity and clust_num_ores are ignored.
This is essentially an improved version of the so-called "stratus" ore seen in some unofficial mods.
- blob
- Creates a roundish blob of ore according to 3d perlin noise described by noise_params. The maximum
- size of the blob is clust_size, and clust_scarcity has the same meaning as with scatter type.
-
+ Creates a deformed sphere blobs of ore according to 3d perlin noise described by noise_params. The
+ maximum size of the blob is clust_size, and clust_scarcity has the same meaning as with scatter type.
+ - vein
+ Creates veins of ore varying in density by according to the intersection of two instances 3d perlin
+ noise with diffferent seeds both described by noise_params. random_factor varies the influence random
+ chance has on placement of an ore inside the vein, which is 1 by default. Note that modifying this
+ parameter may require adjusting noise_threshhold. The parameters clust_scarcity, clust_num_ores, and
+ clust_size are ignored by this ore type. This ore type is difficult to control since it is sensitive
+ to small changes. The following is a decent set of parameters to work from:
+ noise_params = {
+ offset = 0,
+ scale = 3,
+ spread = {x=200, y=200, z=200},
+ seed = 5390,
+ octaves = 4,
+ persist = 0.5,
+ flags = "eased",
+ },
+ noise_threshhold = 1.6
+ WARNING: Use this ore type *very* sparingly since it is ~200x more computationally expensive than
+ any other ore.
Ore attributes
-------------------
noise_params = {offset=0, scale=1, spread={x=100, y=100, z=100}, seed=23, octaves=3, persist=0.70}
^ NoiseParams structure describing the perlin noise used for ore distribution.
^ Needed for sheet ore_type. Omit from scatter ore_type for a uniform ore distribution
+ random_factor = 1.0,
+ ^ Multiplier of the randomness contribution to the noise value at any given point to
+ ^ decide if ore should be placed. Set to 0 for solid veins. This parameter is only valid
+ ^ for ore_type == "vein".
}
Decoration definition (register_decoration)
const char *OreManager::ELEMENT_TITLE = "ore";
FlagDesc flagdesc_ore[] = {
- {"absheight", OREFLAG_ABSHEIGHT},
- {"scatter_noisedensity", OREFLAG_DENSITY},
- {"claylike_nodeisnt", OREFLAG_NODEISNT},
- {NULL, 0}
+ {"absheight", OREFLAG_ABSHEIGHT},
+ {NULL, 0}
};
int volume = (nmax.X - nmin.X + 1) *
(nmax.Y - nmin.Y + 1) *
(nmax.Z - nmin.Z + 1);
- int csize = clust_size;
+ int csize = clust_size;
int nblobs = volume / clust_scarcity;
if (!noise)
}
}
}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+OreVein::~OreVein()
+{
+ delete noise2;
+}
+
+
+void OreVein::generate(ManualMapVoxelManipulator *vm, int seed, u32 blockseed,
+ v3s16 nmin, v3s16 nmax)
+{
+ PseudoRandom pr(blockseed + 520);
+ MapNode n_ore(c_ore, 0, ore_param2);
+
+ if (!noise) {
+ int sx = nmax.X - nmin.X + 1;
+ int sy = nmax.Y - nmin.Y + 1;
+ int sz = nmax.Z - nmin.Z + 1;
+ noise = new Noise(&np, seed, sx, sy, sz);
+ noise2 = new Noise(&np, seed + 436, sx, sy, sz);
+ }
+ bool noise_generated = false;
+
+ size_t index = 0;
+ for (int z = nmin.Z; z <= nmax.Z; z++)
+ for (int y = nmin.Y; y <= nmax.Y; y++)
+ for (int x = nmin.X; x <= nmax.X; x++, index++) {
+ u32 i = vm->m_area.index(x, y, z);
+ if (!vm->m_area.contains(i))
+ continue;
+ if (!CONTAINS(c_wherein, vm->m_data[i].getContent()))
+ continue;
+
+ // Same lazy generation optimization as in OreBlob
+ if (!noise_generated) {
+ noise_generated = true;
+ noise->perlinMap3D(nmin.X, nmin.Y, nmin.Z);
+ noise2->perlinMap3D(nmin.X, nmin.Y, nmin.Z);
+ }
+
+ // randval ranges from -1..1
+ float randval = (float)pr.next() / (PSEUDORANDOM_MAX / 2) - 1.f;
+ float noiseval = contour(noise->result[index]);
+ float noiseval2 = contour(noise2->result[index]);
+ if (noiseval * noiseval2 + randval * random_factor < nthresh)
+ continue;
+
+ vm->m_data[i] = n_ore;
+ }
+}
// 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
-
#define OREFLAG_USE_NOISE 0x08
#define ORE_RANGE_ACTUAL 1
ORE_TYPE_SCATTER,
ORE_TYPE_SHEET,
ORE_TYPE_BLOB,
+ ORE_TYPE_VEIN,
};
extern FlagDesc flagdesc_ore[];
u32 blockseed, v3s16 nmin, v3s16 nmax);
};
+class OreVein : public Ore {
+public:
+ static const bool NEEDS_NOISE = true;
+
+ float random_factor;
+ Noise *noise2;
+
+ virtual ~OreVein();
+
+ virtual void generate(ManualMapVoxelManipulator *vm, int seed,
+ u32 blockseed, v3s16 nmin, v3s16 nmax);
+};
+
class OreManager : public GenElementManager {
public:
static const char *ELEMENT_TITLE;
return new OreSheet;
case ORE_TYPE_BLOB:
return new OreBlob;
+ case ORE_TYPE_VEIN:
+ return new OreVein;
default:
return NULL;
}
struct EnumString ModApiMapgen::es_OreType[] =
{
- {ORE_TYPE_SCATTER, "scatter"},
- {ORE_TYPE_SHEET, "sheet"},
- {ORE_TYPE_BLOB, "blob"},
+ {ORE_TYPE_SCATTER, "scatter"},
+ {ORE_TYPE_SHEET, "sheet"},
+ {ORE_TYPE_BLOB, "blob"},
+ {ORE_TYPE_VEIN, "vein"},
{0, NULL},
};
}
lua_pop(L, 1);
+ if (oretype == ORE_TYPE_VEIN) {
+ OreVein *orevein = (OreVein *)ore;
+ orevein->random_factor = getfloatfield_default(L, index,
+ "random_factor", 1.f);
+ }
+
u32 id = oremgr->add(ore);
if (id == (u32)-1) {
delete ore;