Skip to content

Commit 900fa26

Browse files
committedDec 28, 2014
Ore: Add Blob ore type
1 parent 8c98f49 commit 900fa26

File tree

4 files changed

+84
-19
lines changed

4 files changed

+84
-19
lines changed
 

‎doc/lua_api.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -562,9 +562,9 @@ All default ores are of the uniformly-distributed scatter type.
562562
The height of the blob is randomly scattered, with a maximum height of clust_size.
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.
565-
- claylike - NOT YET IMPLEMENTED
566-
Places ore if there are no more than clust_scarcity number of specified nodes within a Von Neumann
567-
neighborhood of clust_size radius.
565+
- 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.
568568

569569

570570
Ore attributes

‎src/mg_ore.cpp

+59-2
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,12 @@ void OreSheet::generate(ManualMapVoxelManipulator *vm, int seed,
178178
if (!noise) {
179179
int sx = nmax.X - nmin.X + 1;
180180
int sz = nmax.Z - nmin.Z + 1;
181-
noise = new Noise(&np, seed, sx, sz);
181+
noise = new Noise(&np, 0, sx, sz);
182182
}
183183
noise->seed = seed + y_start;
184184
noise->perlinMap2D(nmin.X, nmin.Z);
185185

186-
int index = 0;
186+
size_t index = 0;
187187
for (int z = nmin.Z; z <= nmax.Z; z++)
188188
for (int x = nmin.X; x <= nmax.X; x++) {
189189
float noiseval = noise->result[index++];
@@ -204,3 +204,60 @@ void OreSheet::generate(ManualMapVoxelManipulator *vm, int seed,
204204
}
205205
}
206206
}
207+
208+
209+
///////////////////////////////////////////////////////////////////////////////
210+
211+
void OreBlob::generate(ManualMapVoxelManipulator *vm, int seed, u32 blockseed,
212+
v3s16 nmin, v3s16 nmax)
213+
{
214+
PseudoRandom pr(blockseed + 2404);
215+
MapNode n_ore(c_ore, 0, ore_param2);
216+
217+
int volume = (nmax.X - nmin.X + 1) *
218+
(nmax.Y - nmin.Y + 1) *
219+
(nmax.Z - nmin.Z + 1);
220+
int csize = clust_size;
221+
int nblobs = volume / clust_scarcity;
222+
223+
if (!noise)
224+
noise = new Noise(&np, seed, csize, csize, csize);
225+
226+
for (int i = 0; i != nblobs; i++) {
227+
int x0 = pr.range(nmin.X, nmax.X - csize + 1);
228+
int y0 = pr.range(nmin.Y, nmax.Y - csize + 1);
229+
int z0 = pr.range(nmin.Z, nmax.Z - csize + 1);
230+
231+
bool noise_generated = false;
232+
noise->seed = blockseed + i;
233+
234+
size_t index = 0;
235+
for (int z1 = 0; z1 != csize; z1++)
236+
for (int y1 = 0; y1 != csize; y1++)
237+
for (int x1 = 0; x1 != csize; x1++, index++) {
238+
u32 i = vm->m_area.index(x0 + x1, y0 + y1, z0 + z1);
239+
if (!CONTAINS(c_wherein, vm->m_data[i].getContent()))
240+
continue;
241+
242+
// Lazily generate noise only if there's a chance of ore being placed
243+
// This simple optimization makes calls 6x faster on average
244+
if (!noise_generated) {
245+
noise_generated = true;
246+
noise->perlinMap3D(x0, y0, z0);
247+
}
248+
249+
float noiseval = noise->result[index];
250+
251+
float xdist = x1 - csize / 2;
252+
float ydist = y1 - csize / 2;
253+
float zdist = z1 - csize / 2;
254+
255+
noiseval -= (sqrt(xdist * xdist + ydist * ydist + zdist * zdist) / csize);
256+
257+
if (noiseval < nthresh)
258+
continue;
259+
260+
vm->m_data[i] = n_ore;
261+
}
262+
}
263+
}

‎src/mg_ore.h

+18-10
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ class ManualMapVoxelManipulator;
4747

4848

4949
enum OreType {
50-
ORE_SCATTER,
51-
ORE_SHEET,
52-
ORE_CLAYLIKE
50+
ORE_TYPE_SCATTER,
51+
ORE_TYPE_SHEET,
52+
ORE_TYPE_BLOB,
5353
};
5454

5555
extern FlagDesc flagdesc_ore[];
@@ -78,23 +78,31 @@ class Ore : public GenElement, public NodeResolver {
7878

7979
size_t placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
8080
virtual void generate(ManualMapVoxelManipulator *vm, int seed,
81-
u32 blockseed, v3s16 nmin, v3s16 nmax) = 0;
81+
u32 blockseed, v3s16 nmin, v3s16 nmax) = 0;
8282
};
8383

8484
class OreScatter : public Ore {
8585
public:
8686
static const bool NEEDS_NOISE = false;
8787

8888
virtual void generate(ManualMapVoxelManipulator *vm, int seed,
89-
u32 blockseed, v3s16 nmin, v3s16 nmax);
89+
u32 blockseed, v3s16 nmin, v3s16 nmax);
9090
};
9191

9292
class OreSheet : public Ore {
9393
public:
9494
static const bool NEEDS_NOISE = true;
9595

9696
virtual void generate(ManualMapVoxelManipulator *vm, int seed,
97-
u32 blockseed, v3s16 nmin, v3s16 nmax);
97+
u32 blockseed, v3s16 nmin, v3s16 nmax);
98+
};
99+
100+
class OreBlob : public Ore {
101+
public:
102+
static const bool NEEDS_NOISE = true;
103+
104+
virtual void generate(ManualMapVoxelManipulator *vm, int seed,
105+
u32 blockseed, v3s16 nmin, v3s16 nmax);
98106
};
99107

100108
class OreManager : public GenElementManager {
@@ -108,12 +116,12 @@ class OreManager : public GenElementManager {
108116
Ore *create(int type)
109117
{
110118
switch (type) {
111-
case ORE_SCATTER:
119+
case ORE_TYPE_SCATTER:
112120
return new OreScatter;
113-
case ORE_SHEET:
121+
case ORE_TYPE_SHEET:
114122
return new OreSheet;
115-
//case ORE_CLAYLIKE: //TODO: implement this!
116-
// return new OreClaylike;
123+
case ORE_TYPE_BLOB:
124+
return new OreBlob;
117125
default:
118126
return NULL;
119127
}

‎src/script/lua_api/l_mapgen.cpp

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

6969
struct EnumString ModApiMapgen::es_OreType[] =
7070
{
71-
{ORE_SCATTER, "scatter"},
72-
{ORE_SHEET, "sheet"},
73-
{ORE_CLAYLIKE, "claylike"},
71+
{ORE_TYPE_SCATTER, "scatter"},
72+
{ORE_TYPE_SHEET, "sheet"},
73+
{ORE_TYPE_BLOB, "blob"},
7474
{0, NULL},
7575
};
7676

@@ -642,7 +642,7 @@ int ModApiMapgen::l_register_ore(lua_State *L)
642642
OreManager *oremgr = getServer(L)->getEmergeManager()->oremgr;
643643

644644
enum OreType oretype = (OreType)getenumfield(L, index,
645-
"ore_type", es_OreType, ORE_SCATTER);
645+
"ore_type", es_OreType, ORE_TYPE_SCATTER);
646646
Ore *ore = oremgr->create(oretype);
647647
if (!ore) {
648648
errorstream << "register_ore: ore_type " << oretype << " not implemented";

0 commit comments

Comments
 (0)