Skip to content

Commit 61dfa91

Browse files
committedDec 29, 2014
Ore: Add Vein ore type
1 parent 900fa26 commit 61dfa91

File tree

4 files changed

+106
-19
lines changed

4 files changed

+106
-19
lines changed
 

‎doc/lua_api.txt

+25-3
Original file line numberDiff line numberDiff line change
@@ -563,9 +563,27 @@ All default ores are of the uniformly-distributed scatter type.
563563
clust_scarcity and clust_num_ores are ignored.
564564
This is essentially an improved version of the so-called "stratus" ore seen in some unofficial mods.
565565
- blob
566-
Creates a roundish blob of ore according to 3d perlin noise described by noise_params. The maximum
567-
size of the blob is clust_size, and clust_scarcity has the same meaning as with scatter type.
568-
566+
Creates a deformed sphere blobs of ore according to 3d perlin noise described by noise_params. The
567+
maximum size of the blob is clust_size, and clust_scarcity has the same meaning as with scatter type.
568+
- vein
569+
Creates veins of ore varying in density by according to the intersection of two instances 3d perlin
570+
noise with diffferent seeds both described by noise_params. random_factor varies the influence random
571+
chance has on placement of an ore inside the vein, which is 1 by default. Note that modifying this
572+
parameter may require adjusting noise_threshhold. The parameters clust_scarcity, clust_num_ores, and
573+
clust_size are ignored by this ore type. This ore type is difficult to control since it is sensitive
574+
to small changes. The following is a decent set of parameters to work from:
575+
noise_params = {
576+
offset = 0,
577+
scale = 3,
578+
spread = {x=200, y=200, z=200},
579+
seed = 5390,
580+
octaves = 4,
581+
persist = 0.5,
582+
flags = "eased",
583+
},
584+
noise_threshhold = 1.6
585+
WARNING: Use this ore type *very* sparingly since it is ~200x more computationally expensive than
586+
any other ore.
569587

570588
Ore attributes
571589
-------------------
@@ -2717,6 +2735,10 @@ Ore definition (register_ore)
27172735
noise_params = {offset=0, scale=1, spread={x=100, y=100, z=100}, seed=23, octaves=3, persist=0.70}
27182736
^ NoiseParams structure describing the perlin noise used for ore distribution.
27192737
^ Needed for sheet ore_type. Omit from scatter ore_type for a uniform ore distribution
2738+
random_factor = 1.0,
2739+
^ Multiplier of the randomness contribution to the noise value at any given point to
2740+
^ decide if ore should be placed. Set to 0 for solid veins. This parameter is only valid
2741+
^ for ore_type == "vein".
27202742
}
27212743

27222744
Decoration definition (register_decoration)

‎src/mg_ore.cpp

+55-5
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2727
const char *OreManager::ELEMENT_TITLE = "ore";
2828

2929
FlagDesc flagdesc_ore[] = {
30-
{"absheight", OREFLAG_ABSHEIGHT},
31-
{"scatter_noisedensity", OREFLAG_DENSITY},
32-
{"claylike_nodeisnt", OREFLAG_NODEISNT},
33-
{NULL, 0}
30+
{"absheight", OREFLAG_ABSHEIGHT},
31+
{NULL, 0}
3432
};
3533

3634

@@ -217,7 +215,7 @@ void OreBlob::generate(ManualMapVoxelManipulator *vm, int seed, u32 blockseed,
217215
int volume = (nmax.X - nmin.X + 1) *
218216
(nmax.Y - nmin.Y + 1) *
219217
(nmax.Z - nmin.Z + 1);
220-
int csize = clust_size;
218+
int csize = clust_size;
221219
int nblobs = volume / clust_scarcity;
222220

223221
if (!noise)
@@ -261,3 +259,55 @@ void OreBlob::generate(ManualMapVoxelManipulator *vm, int seed, u32 blockseed,
261259
}
262260
}
263261
}
262+
263+
264+
///////////////////////////////////////////////////////////////////////////////
265+
266+
OreVein::~OreVein()
267+
{
268+
delete noise2;
269+
}
270+
271+
272+
void OreVein::generate(ManualMapVoxelManipulator *vm, int seed, u32 blockseed,
273+
v3s16 nmin, v3s16 nmax)
274+
{
275+
PseudoRandom pr(blockseed + 520);
276+
MapNode n_ore(c_ore, 0, ore_param2);
277+
278+
if (!noise) {
279+
int sx = nmax.X - nmin.X + 1;
280+
int sy = nmax.Y - nmin.Y + 1;
281+
int sz = nmax.Z - nmin.Z + 1;
282+
noise = new Noise(&np, seed, sx, sy, sz);
283+
noise2 = new Noise(&np, seed + 436, sx, sy, sz);
284+
}
285+
bool noise_generated = false;
286+
287+
size_t index = 0;
288+
for (int z = nmin.Z; z <= nmax.Z; z++)
289+
for (int y = nmin.Y; y <= nmax.Y; y++)
290+
for (int x = nmin.X; x <= nmax.X; x++, index++) {
291+
u32 i = vm->m_area.index(x, y, z);
292+
if (!vm->m_area.contains(i))
293+
continue;
294+
if (!CONTAINS(c_wherein, vm->m_data[i].getContent()))
295+
continue;
296+
297+
// Same lazy generation optimization as in OreBlob
298+
if (!noise_generated) {
299+
noise_generated = true;
300+
noise->perlinMap3D(nmin.X, nmin.Y, nmin.Z);
301+
noise2->perlinMap3D(nmin.X, nmin.Y, nmin.Z);
302+
}
303+
304+
// randval ranges from -1..1
305+
float randval = (float)pr.next() / (PSEUDORANDOM_MAX / 2) - 1.f;
306+
float noiseval = contour(noise->result[index]);
307+
float noiseval2 = contour(noise2->result[index]);
308+
if (noiseval * noiseval2 + randval * random_factor < nthresh)
309+
continue;
310+
311+
vm->m_data[i] = n_ore;
312+
}
313+
}

‎src/mg_ore.h

+16-8
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,6 @@ class ManualMapVoxelManipulator;
3232

3333
// Use absolute value of height to determine ore placement
3434
#define OREFLAG_ABSHEIGHT 0x01
35-
36-
// Use 3d noise to get density of ore placement, instead of just the position
37-
#define OREFLAG_DENSITY 0x02 // not yet implemented
38-
39-
// For claylike ore types, place ore if the number of surrounding
40-
// nodes isn't the specified node
41-
#define OREFLAG_NODEISNT 0x04 // not yet implemented
42-
4335
#define OREFLAG_USE_NOISE 0x08
4436

4537
#define ORE_RANGE_ACTUAL 1
@@ -50,6 +42,7 @@ enum OreType {
5042
ORE_TYPE_SCATTER,
5143
ORE_TYPE_SHEET,
5244
ORE_TYPE_BLOB,
45+
ORE_TYPE_VEIN,
5346
};
5447

5548
extern FlagDesc flagdesc_ore[];
@@ -105,6 +98,19 @@ class OreBlob : public Ore {
10598
u32 blockseed, v3s16 nmin, v3s16 nmax);
10699
};
107100

101+
class OreVein : public Ore {
102+
public:
103+
static const bool NEEDS_NOISE = true;
104+
105+
float random_factor;
106+
Noise *noise2;
107+
108+
virtual ~OreVein();
109+
110+
virtual void generate(ManualMapVoxelManipulator *vm, int seed,
111+
u32 blockseed, v3s16 nmin, v3s16 nmax);
112+
};
113+
108114
class OreManager : public GenElementManager {
109115
public:
110116
static const char *ELEMENT_TITLE;
@@ -122,6 +128,8 @@ class OreManager : public GenElementManager {
122128
return new OreSheet;
123129
case ORE_TYPE_BLOB:
124130
return new OreBlob;
131+
case ORE_TYPE_VEIN:
132+
return new OreVein;
125133
default:
126134
return NULL;
127135
}

‎src/script/lua_api/l_mapgen.cpp

+10-3
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,10 @@ struct EnumString ModApiMapgen::es_MapgenObject[] =
6868

6969
struct EnumString ModApiMapgen::es_OreType[] =
7070
{
71-
{ORE_TYPE_SCATTER, "scatter"},
72-
{ORE_TYPE_SHEET, "sheet"},
73-
{ORE_TYPE_BLOB, "blob"},
71+
{ORE_TYPE_SCATTER, "scatter"},
72+
{ORE_TYPE_SHEET, "sheet"},
73+
{ORE_TYPE_BLOB, "blob"},
74+
{ORE_TYPE_VEIN, "vein"},
7475
{0, NULL},
7576
};
7677

@@ -680,6 +681,12 @@ int ModApiMapgen::l_register_ore(lua_State *L)
680681
}
681682
lua_pop(L, 1);
682683

684+
if (oretype == ORE_TYPE_VEIN) {
685+
OreVein *orevein = (OreVein *)ore;
686+
orevein->random_factor = getfloatfield_default(L, index,
687+
"random_factor", 1.f);
688+
}
689+
683690
u32 id = oremgr->add(ore);
684691
if (id == (u32)-1) {
685692
delete ore;

0 commit comments

Comments
 (0)
Please sign in to comment.