Skip to content
Permalink
Browse files
Ore: Add puff ore type
  • Loading branch information
kwolekr committed Sep 17, 2015
1 parent 6c81be5 commit dcbb95338a9b0e2c5c95fcfc6eeceb9d6d93f320
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 25 deletions.
@@ -714,8 +714,8 @@ a non-equal distribution of ore.

### `sheet`
Creates a sheet of ore in a blob shape according to the 2D perlin noise
described by `noise_params`. This is essentially an improved version of
the so-called "stratus" ore seen in some unofficial mods.
described by `noise_params` and `noise_threshold`. This is essentially an
improved version of the so-called "stratus" ore seen in some unofficial mods.

This sheet consists of vertical columns of uniform randomly distributed height,
varying between the inclusive range `column_height_min` and `column_height_max`.
@@ -731,12 +731,23 @@ the default is 0.5.

The ore parameters `clust_scarcity` and `clust_num_ores` are ignored for this ore type.

### `puff`
Creates a sheet of ore in a cloud-like puff shape.

As with the `sheet` ore type, the size and shape of puffs are described by
`noise_params` and `noise_threshold` and are placed at random vertical positions
within the currently generated chunk.

The vertical top and bottom displacement of each puff are determined by the noise
parameters `np_puff_top` and `np_puff_bottom`, respectively.


### `blob`
Creates a deformed sphere 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 the `scatter` type.

### `vein
### `vein`
Creates veins of ore varying in density by according to the intersection of two
instances of 3d perlin noise with diffferent seeds, both described by
`noise_params`. `random_factor` varies the influence random chance has on
@@ -771,6 +782,17 @@ Also produce this same ore between the height range of `-y_max` and `-y_min`.

Useful for having ore in sky realms without having to duplicate ore entries.

### `puff_cliffs`
If set, puff ore generation will not taper down large differences in displacement
when approaching the edge of a puff. This flag has no effect for ore types other
than `puff`.

### `puff_additive_composition`
By default, when noise described by `np_puff_top` or `np_puff_bottom` results in a
negative displacement, the sub-column at that point is not generated. With this
attribute set, puff ore generation will instead generate the absolute difference in
noise displacement values. This flag has no effect for ore types other than `puff`.

Decoration types
----------------
The varying types of decorations that can be placed.
@@ -25,8 +25,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h"

FlagDesc flagdesc_ore[] = {
{"absheight", OREFLAG_ABSHEIGHT},
{NULL, 0}
{"absheight", OREFLAG_ABSHEIGHT},
{"puff_cliffs", OREFLAG_PUFF_CLIFFS},
{"puff_additive_composition", OREFLAG_PUFF_ADDITIVE},
{NULL, 0}
};


@@ -220,6 +222,94 @@ void OreSheet::generate(MMVManip *vm, int mapseed, u32 blockseed,

///////////////////////////////////////////////////////////////////////////////

OrePuff::OrePuff() :
Ore()
{
noise_puff_top = NULL;
noise_puff_bottom = NULL;
}


OrePuff::~OrePuff()
{
delete noise_puff_top;
delete noise_puff_bottom;
}


void OrePuff::generate(MMVManip *vm, int mapseed, u32 blockseed,
v3s16 nmin, v3s16 nmax, u8 *biomemap)
{
PseudoRandom pr(blockseed + 4234);
MapNode n_ore(c_ore, 0, ore_param2);

int y_start = pr.range(nmin.Y, nmax.Y);

if (!noise) {
int sx = nmax.X - nmin.X + 1;
int sz = nmax.Z - nmin.Z + 1;
noise = new Noise(&np, 0, sx, sz);
noise_puff_top = new Noise(&np_puff_top, 0, sx, sz);
noise_puff_bottom = new Noise(&np_puff_bottom, 0, sx, sz);
}

noise->seed = mapseed + y_start;
noise->perlinMap2D(nmin.X, nmin.Z);
bool noise_generated = false;

size_t index = 0;
for (int z = nmin.Z; z <= nmax.Z; z++)
for (int x = nmin.X; x <= nmax.X; x++, index++) {
float noiseval = noise->result[index];
if (noiseval < nthresh)
continue;

if (biomemap && !biomes.empty()) {
std::set<u8>::iterator it = biomes.find(biomemap[index]);
if (it == biomes.end())
continue;
}

if (!noise_generated) {
noise_generated = true;
noise_puff_top->perlinMap2D(nmin.X, nmin.Z);
noise_puff_bottom->perlinMap2D(nmin.X, nmin.Z);
}

float ntop = noise_puff_top->result[index];
float nbottom = noise_puff_bottom->result[index];

if (!(flags & OREFLAG_PUFF_CLIFFS)) {
float ndiff = noiseval - nthresh;
if (ndiff < 1.0f) {
ntop *= ndiff;
nbottom *= ndiff;
}
}

int ymid = y_start;
int y0 = ymid - nbottom;
int y1 = ymid + ntop;

if ((flags & OREFLAG_PUFF_ADDITIVE) && (y0 > y1))
SWAP(int, y0, y1);

for (int y = y0; y <= y1; y++) {
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;

vm->m_data[i] = n_ore;
}
}
}


///////////////////////////////////////////////////////////////////////////////


void OreBlob::generate(MMVManip *vm, int mapseed, u32 blockseed,
v3s16 nmin, v3s16 nmax, u8 *biomemap)
{
@@ -285,7 +375,8 @@ void OreBlob::generate(MMVManip *vm, int mapseed, u32 blockseed,

///////////////////////////////////////////////////////////////////////////////

OreVein::OreVein()
OreVein::OreVein() :
Ore()
{
noise2 = NULL;
}
@@ -30,17 +30,18 @@ class MMVManip;

/////////////////// Ore generation flags

// Use absolute value of height to determine ore placement
#define OREFLAG_ABSHEIGHT 0x01
#define OREFLAG_USE_NOISE 0x08
#define OREFLAG_ABSHEIGHT 0x01
#define OREFLAG_PUFF_CLIFFS 0x02
#define OREFLAG_PUFF_ADDITIVE 0x04
#define OREFLAG_USE_NOISE 0x08

#define ORE_RANGE_ACTUAL 1
#define ORE_RANGE_MIRROR 2


enum OreType {
ORE_SCATTER,
ORE_SHEET,
ORE_PUFF,
ORE_BLOB,
ORE_VEIN,
};
@@ -95,6 +96,22 @@ class OreSheet : public Ore {
v3s16 nmin, v3s16 nmax, u8 *biomemap);
};

class OrePuff : public Ore {
public:
static const bool NEEDS_NOISE = true;

NoiseParams np_puff_top;
NoiseParams np_puff_bottom;
Noise *noise_puff_top;
Noise *noise_puff_bottom;

OrePuff();
virtual ~OrePuff();

virtual void generate(MMVManip *vm, int mapseed, u32 blockseed,
v3s16 nmin, v3s16 nmax, u8 *biomemap);
};

class OreBlob : public Ore {
public:
static const bool NEEDS_NOISE = true;
@@ -134,6 +151,8 @@ class OreManager : public ObjDefManager {
return new OreScatter;
case ORE_SHEET:
return new OreSheet;
case ORE_PUFF:
return new OrePuff;
case ORE_BLOB:
return new OreBlob;
case ORE_VEIN:
@@ -70,6 +70,7 @@ struct EnumString ModApiMapgen::es_OreType[] =
{
{ORE_SCATTER, "scatter"},
{ORE_SHEET, "sheet"},
{ORE_PUFF, "puff"},
{ORE_BLOB, "blob"},
{ORE_VEIN, "vein"},
{0, NULL},
@@ -880,7 +881,7 @@ int ModApiMapgen::l_register_ore(lua_State *L)
"ore_type", es_OreType, ORE_SCATTER);
Ore *ore = oremgr->create(oretype);
if (!ore) {
errorstream << "register_ore: ore_type " << oretype << " not implemented";
errorstream << "register_ore: ore_type " << oretype << " not implemented\n";
return 0;
}

@@ -938,20 +939,42 @@ int ModApiMapgen::l_register_ore(lua_State *L)
lua_pop(L, 1);

//// Get type-specific parameters
if (oretype == ORE_SHEET) {
OreSheet *oresheet = (OreSheet *)ore;

oresheet->column_height_min = getintfield_default(L, index,
"column_height_min", 1);
oresheet->column_height_max = getintfield_default(L, index,
"column_height_max", ore->clust_size);
oresheet->column_midpoint_factor = getfloatfield_default(L, index,
"column_midpoint_factor", 0.5f);
} else if (oretype == ORE_VEIN) {
OreVein *orevein = (OreVein *)ore;

orevein->random_factor = getfloatfield_default(L, index,
"random_factor", 1.f);
switch (oretype) {
case ORE_SHEET: {
OreSheet *oresheet = (OreSheet *)ore;

oresheet->column_height_min = getintfield_default(L, index,
"column_height_min", 1);
oresheet->column_height_max = getintfield_default(L, index,
"column_height_max", ore->clust_size);
oresheet->column_midpoint_factor = getfloatfield_default(L, index,
"column_midpoint_factor", 0.5f);

break;
}
case ORE_PUFF: {
OrePuff *orepuff = (OrePuff *)ore;

lua_getfield(L, index, "np_puff_top");
read_noiseparams(L, -1, &orepuff->np_puff_top);
lua_pop(L, 1);

lua_getfield(L, index, "np_puff_bottom");
read_noiseparams(L, -1, &orepuff->np_puff_bottom);
lua_pop(L, 1);

break;
}
case ORE_VEIN: {
OreVein *orevein = (OreVein *)ore;

orevein->random_factor = getfloatfield_default(L, index,
"random_factor", 1.f);

break;
}
default:
break;
}

ObjDefHandle handle = oremgr->add(ore);

0 comments on commit dcbb953

Please sign in to comment.