mirror of
https://github.com/moparisthebest/minetest
synced 2024-12-23 08:08:47 -05:00
Refactor decoration-related code
Split up ModApiMapgen::l_register_decoration() Define and make use of CONTAINS() and ARRLEN() macros
This commit is contained in:
parent
7c6da2f384
commit
1cb6ea6346
@ -189,7 +189,7 @@ void Clouds::render()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define GETINDEX(x, z, radius) (((z)+(radius))*(radius)*2 + (x)+(radius))
|
#define GETINDEX(x, z, radius) (((z)+(radius))*(radius)*2 + (x)+(radius))
|
||||||
#define CONTAINS(x, z, radius) \
|
#define INAREA(x, z, radius) \
|
||||||
((x) >= -(radius) && (x) < (radius) && (z) >= -(radius) && (z) < (radius))
|
((x) >= -(radius) && (x) < (radius) && (z) >= -(radius) && (z) < (radius))
|
||||||
|
|
||||||
for(s16 zi0=-cloud_radius_i; zi0<cloud_radius_i; zi0++)
|
for(s16 zi0=-cloud_radius_i; zi0<cloud_radius_i; zi0++)
|
||||||
@ -247,7 +247,7 @@ void Clouds::render()
|
|||||||
v[3].Pos.set( rx, ry,-rz);
|
v[3].Pos.set( rx, ry,-rz);
|
||||||
break;
|
break;
|
||||||
case 1: // back
|
case 1: // back
|
||||||
if(CONTAINS(xi, zi-1, cloud_radius_i)){
|
if(INAREA(xi, zi-1, cloud_radius_i)){
|
||||||
u32 j = GETINDEX(xi, zi-1, cloud_radius_i);
|
u32 j = GETINDEX(xi, zi-1, cloud_radius_i);
|
||||||
if(grid[j])
|
if(grid[j])
|
||||||
continue;
|
continue;
|
||||||
@ -262,7 +262,7 @@ void Clouds::render()
|
|||||||
v[3].Pos.set(-rx,-ry,-rz);
|
v[3].Pos.set(-rx,-ry,-rz);
|
||||||
break;
|
break;
|
||||||
case 2: //right
|
case 2: //right
|
||||||
if(CONTAINS(xi+1, zi, cloud_radius_i)){
|
if(INAREA(xi+1, zi, cloud_radius_i)){
|
||||||
u32 j = GETINDEX(xi+1, zi, cloud_radius_i);
|
u32 j = GETINDEX(xi+1, zi, cloud_radius_i);
|
||||||
if(grid[j])
|
if(grid[j])
|
||||||
continue;
|
continue;
|
||||||
@ -277,7 +277,7 @@ void Clouds::render()
|
|||||||
v[3].Pos.set( rx,-ry,-rz);
|
v[3].Pos.set( rx,-ry,-rz);
|
||||||
break;
|
break;
|
||||||
case 3: // front
|
case 3: // front
|
||||||
if(CONTAINS(xi, zi+1, cloud_radius_i)){
|
if(INAREA(xi, zi+1, cloud_radius_i)){
|
||||||
u32 j = GETINDEX(xi, zi+1, cloud_radius_i);
|
u32 j = GETINDEX(xi, zi+1, cloud_radius_i);
|
||||||
if(grid[j])
|
if(grid[j])
|
||||||
continue;
|
continue;
|
||||||
@ -292,7 +292,7 @@ void Clouds::render()
|
|||||||
v[3].Pos.set( rx,-ry, rz);
|
v[3].Pos.set( rx,-ry, rz);
|
||||||
break;
|
break;
|
||||||
case 4: // left
|
case 4: // left
|
||||||
if(CONTAINS(xi-1, zi, cloud_radius_i)){
|
if(INAREA(xi-1, zi, cloud_radius_i)){
|
||||||
u32 j = GETINDEX(xi-1, zi, cloud_radius_i);
|
u32 j = GETINDEX(xi-1, zi, cloud_radius_i);
|
||||||
if(grid[j])
|
if(grid[j])
|
||||||
continue;
|
continue;
|
||||||
|
@ -149,8 +149,9 @@ void OreScatter::generate(ManualMapVoxelManipulator *vm, int seed,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
u32 i = vm->m_area.index(x0 + x1, y0 + y1, z0 + z1);
|
u32 i = vm->m_area.index(x0 + x1, y0 + y1, z0 + z1);
|
||||||
for (size_t ii = 0; ii < c_wherein.size(); ii++)
|
if (!CONTAINS(c_wherein, vm->m_data[i].getContent()))
|
||||||
if (vm->m_data[i].getContent() == c_wherein[ii])
|
continue;
|
||||||
|
|
||||||
vm->m_data[i] = n_ore;
|
vm->m_data[i] = n_ore;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,13 +188,10 @@ void OreSheet::generate(ManualMapVoxelManipulator *vm, int seed,
|
|||||||
u32 i = vm->m_area.index(x, y, z);
|
u32 i = vm->m_area.index(x, y, z);
|
||||||
if (!vm->m_area.contains(i))
|
if (!vm->m_area.contains(i))
|
||||||
continue;
|
continue;
|
||||||
|
if (!CONTAINS(c_wherein, vm->m_data[i].getContent()))
|
||||||
|
continue;
|
||||||
|
|
||||||
for (size_t ii = 0; ii < c_wherein.size(); ii++) {
|
|
||||||
if (vm->m_data[i].getContent() == c_wherein[ii]) {
|
|
||||||
vm->m_data[i] = n_ore;
|
vm->m_data[i] = n_ore;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -360,23 +358,23 @@ void Decoration::placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool DecoSimple::canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p) {
|
||||||
void DecoSimple::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) {
|
// Don't bother if there aren't any decorations to place
|
||||||
ManualMapVoxelManipulator *vm = mg->vm;
|
if (c_decos.size() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
u32 vi = vm->m_area.index(p);
|
u32 vi = vm->m_area.index(p);
|
||||||
content_t c = vm->m_data[vi].getContent();
|
|
||||||
size_t idx;
|
|
||||||
for (idx = 0; idx != c_place_on.size(); idx++) {
|
|
||||||
if (c == c_place_on[idx])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((idx != 0) && (idx == c_place_on.size()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (nspawnby != -1) {
|
// Check if the decoration can be placed on this node
|
||||||
|
if (!CONTAINS(c_place_on, vm->m_data[vi].getContent()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Don't continue if there are no spawnby constraints
|
||||||
|
if (nspawnby == -1)
|
||||||
|
return true;
|
||||||
|
|
||||||
int nneighs = 0;
|
int nneighs = 0;
|
||||||
v3s16 dirs[8] = { // a Moore neighborhood
|
v3s16 dirs[8] = {
|
||||||
v3s16( 0, 0, 1),
|
v3s16( 0, 0, 1),
|
||||||
v3s16( 0, 0, -1),
|
v3s16( 0, 0, -1),
|
||||||
v3s16( 1, 0, 0),
|
v3s16( 1, 0, 0),
|
||||||
@ -387,26 +385,29 @@ void DecoSimple::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) {
|
|||||||
v3s16( 1, 0, -1)
|
v3s16( 1, 0, -1)
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i != 8; i++) {
|
// Check a Moore neighborhood if there are enough spawnby nodes
|
||||||
|
for (size_t i = 0; i != ARRLEN(dirs); i++) {
|
||||||
u32 index = vm->m_area.index(p + dirs[i]);
|
u32 index = vm->m_area.index(p + dirs[i]);
|
||||||
if (!vm->m_area.contains(index))
|
if (!vm->m_area.contains(index))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
content_t c = vm->m_data[index].getContent();
|
if (CONTAINS(c_spawnby, vm->m_data[index].getContent()))
|
||||||
for (size_t j = 0; j != c_spawnby.size(); j++) {
|
|
||||||
if (c == c_spawnby[j]) {
|
|
||||||
nneighs++;
|
nneighs++;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nneighs < nspawnby)
|
if (nneighs < nspawnby)
|
||||||
return;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (c_decos.size() == 0)
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DecoSimple::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) {
|
||||||
|
ManualMapVoxelManipulator *vm = mg->vm;
|
||||||
|
|
||||||
|
if (!canPlaceDecoration(vm, p))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
content_t c_place = c_decos[pr->range(0, c_decos.size() - 1)];
|
content_t c_place = c_decos[pr->range(0, c_decos.size() - 1)];
|
||||||
|
|
||||||
s16 height = (deco_height_max > 0) ?
|
s16 height = (deco_height_max > 0) ?
|
||||||
@ -415,6 +416,7 @@ void DecoSimple::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) {
|
|||||||
height = MYMIN(height, max_y - p.Y);
|
height = MYMIN(height, max_y - p.Y);
|
||||||
|
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
|
u32 vi = vm->m_area.index(p);
|
||||||
for (int i = 0; i < height; i++) {
|
for (int i = 0; i < height; i++) {
|
||||||
vm->m_area.add_y(em, vi, 1);
|
vm->m_area.add_y(em, vi, 1);
|
||||||
|
|
||||||
@ -477,12 +479,7 @@ void DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) {
|
|||||||
|
|
||||||
u32 vi = vm->m_area.index(p);
|
u32 vi = vm->m_area.index(p);
|
||||||
content_t c = vm->m_data[vi].getContent();
|
content_t c = vm->m_data[vi].getContent();
|
||||||
size_t idx;
|
if (!CONTAINS(c_place_on, c))
|
||||||
for (idx = 0; idx != c_place_on.size(); idx++) {
|
|
||||||
if (c == c_place_on[idx])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((idx != 0) && (idx == c_place_on.size()))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Rotation rot = (rotation == ROTATE_RAND) ?
|
Rotation rot = (rotation == ROTATE_RAND) ?
|
||||||
|
@ -207,7 +207,7 @@ Ore *createOre(OreType type);
|
|||||||
|
|
||||||
|
|
||||||
enum DecorationType {
|
enum DecorationType {
|
||||||
DECO_SIMPLE = 1,
|
DECO_SIMPLE,
|
||||||
DECO_SCHEMATIC,
|
DECO_SCHEMATIC,
|
||||||
DECO_LSYSTEM
|
DECO_LSYSTEM
|
||||||
};
|
};
|
||||||
@ -262,6 +262,7 @@ public:
|
|||||||
|
|
||||||
~DecoSimple() {}
|
~DecoSimple() {}
|
||||||
|
|
||||||
|
bool canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p);
|
||||||
virtual void generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
|
virtual void generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
|
||||||
virtual int getHeight();
|
virtual int getHeight();
|
||||||
virtual std::string getName();
|
virtual std::string getName();
|
||||||
|
@ -354,12 +354,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||||||
NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
|
NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
|
||||||
|
|
||||||
enum DecorationType decotype = (DecorationType)getenumfield(L, index,
|
enum DecorationType decotype = (DecorationType)getenumfield(L, index,
|
||||||
"deco_type", es_DecorationType, 0);
|
"deco_type", es_DecorationType, -1);
|
||||||
if (decotype == 0) {
|
|
||||||
errorstream << "register_decoration: unrecognized "
|
|
||||||
"decoration placement type";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Decoration *deco = createDecoration(decotype);
|
Decoration *deco = createDecoration(decotype);
|
||||||
if (!deco) {
|
if (!deco) {
|
||||||
@ -398,19 +393,44 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//// Handle decoration type-specific parameters
|
//// Handle decoration type-specific parameters
|
||||||
|
bool success = false;
|
||||||
switch (decotype) {
|
switch (decotype) {
|
||||||
case DECO_SIMPLE: {
|
case DECO_SIMPLE:
|
||||||
DecoSimple *dsimple = (DecoSimple *)deco;
|
success = regDecoSimple(L, resolver, (DecoSimple *)deco);
|
||||||
|
break;
|
||||||
|
case DECO_SCHEMATIC:
|
||||||
|
success = regDecoSchematic(L, resolver, (DecoSchematic *)deco);
|
||||||
|
break;
|
||||||
|
case DECO_LSYSTEM:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
dsimple->deco_height = getintfield_default(L, index, "height", 1);
|
if (!success) {
|
||||||
dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0);
|
delete deco;
|
||||||
dsimple->nspawnby = getintfield_default(L, index, "num_spawn_by", -1);
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (dsimple->deco_height <= 0) {
|
emerge->decorations.push_back(deco);
|
||||||
|
|
||||||
|
verbosestream << "register_decoration: decoration '" << deco->getName()
|
||||||
|
<< "' registered" << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ModApiMapgen::regDecoSimple(lua_State *L,
|
||||||
|
NodeResolver *resolver, DecoSimple *deco)
|
||||||
|
{
|
||||||
|
int index = 1;
|
||||||
|
|
||||||
|
deco->deco_height = getintfield_default(L, index, "height", 1);
|
||||||
|
deco->deco_height_max = getintfield_default(L, index, "height_max", 0);
|
||||||
|
deco->nspawnby = getintfield_default(L, index, "num_spawn_by", -1);
|
||||||
|
|
||||||
|
if (deco->deco_height <= 0) {
|
||||||
errorstream << "register_decoration: simple decoration height"
|
errorstream << "register_decoration: simple decoration height"
|
||||||
" must be greater than 0" << std::endl;
|
" must be greater than 0" << std::endl;
|
||||||
delete dsimple;
|
return false;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const char *> deco_names;
|
std::vector<const char *> deco_names;
|
||||||
@ -418,35 +438,35 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||||||
if (deco_names.size() == 0) {
|
if (deco_names.size() == 0) {
|
||||||
errorstream << "register_decoration: no decoration nodes "
|
errorstream << "register_decoration: no decoration nodes "
|
||||||
"defined" << std::endl;
|
"defined" << std::endl;
|
||||||
delete dsimple;
|
return false;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const char *> spawnby_names;
|
std::vector<const char *> spawnby_names;
|
||||||
getstringlistfield(L, index, "spawn_by", spawnby_names);
|
getstringlistfield(L, index, "spawn_by", spawnby_names);
|
||||||
if (dsimple->nspawnby != -1 && spawnby_names.size() == 0) {
|
if (deco->nspawnby != -1 && spawnby_names.size() == 0) {
|
||||||
errorstream << "register_decoration: no spawn_by nodes defined,"
|
errorstream << "register_decoration: no spawn_by nodes defined,"
|
||||||
" but num_spawn_by specified" << std::endl;
|
" but num_spawn_by specified" << std::endl;
|
||||||
delete dsimple;
|
return false;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i != deco_names.size(); i++)
|
for (size_t i = 0; i != deco_names.size(); i++)
|
||||||
resolver->addNodeList(deco_names[i], &dsimple->c_decos);
|
resolver->addNodeList(deco_names[i], &deco->c_decos);
|
||||||
for (size_t i = 0; i != spawnby_names.size(); i++)
|
for (size_t i = 0; i != spawnby_names.size(); i++)
|
||||||
resolver->addNodeList(spawnby_names[i], &dsimple->c_spawnby);
|
resolver->addNodeList(spawnby_names[i], &deco->c_spawnby);
|
||||||
|
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
case DECO_SCHEMATIC: {
|
|
||||||
DecoSchematic *dschem = (DecoSchematic *)deco;
|
|
||||||
|
|
||||||
dschem->flags = 0;
|
bool ModApiMapgen::regDecoSchematic(lua_State *L,
|
||||||
getflagsfield(L, index, "flags", flagdesc_deco_schematic,
|
NodeResolver *resolver, DecoSchematic *deco)
|
||||||
&dschem->flags, NULL);
|
{
|
||||||
|
int index = 1;
|
||||||
|
|
||||||
dschem->rotation = (Rotation)getenumfield(L, index,
|
deco->flags = 0;
|
||||||
"rotation", es_Rotation, ROTATE_0);
|
getflagsfield(L, index, "flags", flagdesc_deco_schematic, &deco->flags, NULL);
|
||||||
|
|
||||||
|
deco->rotation = (Rotation)getenumfield(L, index, "rotation",
|
||||||
|
es_Rotation, ROTATE_0);
|
||||||
|
|
||||||
std::map<std::string, std::string> replace_names;
|
std::map<std::string, std::string> replace_names;
|
||||||
lua_getfield(L, index, "replacements");
|
lua_getfield(L, index, "replacements");
|
||||||
@ -455,33 +475,18 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
lua_getfield(L, index, "schematic");
|
lua_getfield(L, index, "schematic");
|
||||||
if (!read_schematic(L, -1, dschem, getServer(L))) {
|
if (!read_schematic(L, -1, deco, getServer(L)))
|
||||||
delete dschem;
|
return false;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
lua_pop(L, -1);
|
lua_pop(L, -1);
|
||||||
|
|
||||||
if (!dschem->filename.empty() &&
|
if (!deco->filename.empty() &&
|
||||||
!dschem->loadSchematicFile(resolver, replace_names)) {
|
!deco->loadSchematicFile(resolver, replace_names)) {
|
||||||
errorstream << "register_decoration: failed to load schematic"
|
errorstream << "register_decoration: failed to load schematic"
|
||||||
" file '" << dschem->filename << "'" << std::endl;
|
" file '" << deco->filename << "'" << std::endl;
|
||||||
delete dschem;
|
return false;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
return true;
|
||||||
}
|
|
||||||
case DECO_LSYSTEM: {
|
|
||||||
//DecoLSystem *decolsystem = (DecoLSystem *)deco;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
emerge->decorations.push_back(deco);
|
|
||||||
|
|
||||||
verbosestream << "register_decoration: decoration '" << deco->getName()
|
|
||||||
<< "' registered" << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// register_ore({lots of stuff})
|
// register_ore({lots of stuff})
|
||||||
|
@ -22,6 +22,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include "lua_api/l_base.h"
|
#include "lua_api/l_base.h"
|
||||||
|
|
||||||
|
class NodeResolver;
|
||||||
|
class DecoSimple;
|
||||||
|
class DecoSchematic;
|
||||||
|
|
||||||
class ModApiMapgen : public ModApiBase {
|
class ModApiMapgen : public ModApiBase {
|
||||||
private:
|
private:
|
||||||
// get_mapgen_object(objectname)
|
// get_mapgen_object(objectname)
|
||||||
@ -53,6 +57,11 @@ private:
|
|||||||
// place_schematic(p, schematic, rotation, replacement)
|
// place_schematic(p, schematic, rotation, replacement)
|
||||||
static int l_place_schematic(lua_State *L);
|
static int l_place_schematic(lua_State *L);
|
||||||
|
|
||||||
|
static bool regDecoSimple(lua_State *L,
|
||||||
|
NodeResolver *resolver, DecoSimple *deco);
|
||||||
|
static bool regDecoSchematic(lua_State *L,
|
||||||
|
NodeResolver *resolver, DecoSchematic *deco);
|
||||||
|
|
||||||
static struct EnumString es_BiomeTerrainType[];
|
static struct EnumString es_BiomeTerrainType[];
|
||||||
static struct EnumString es_DecorationType[];
|
static struct EnumString es_DecorationType[];
|
||||||
static struct EnumString es_MapgenObject[];
|
static struct EnumString es_MapgenObject[];
|
||||||
|
@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "../irr_v3d.h"
|
#include "../irr_v3d.h"
|
||||||
#include "../irr_aabb3d.h"
|
#include "../irr_aabb3d.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
// Calculate the borders of a "d-radius" cube
|
// Calculate the borders of a "d-radius" cube
|
||||||
void getFacePositions(std::list<v3s16> &list, u16 d);
|
void getFacePositions(std::list<v3s16> &list, u16 d);
|
||||||
@ -139,6 +140,9 @@ inline v3s16 arealim(v3s16 p, s16 d)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ARRLEN(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
#define CONTAINS(c, v) (std::find((c).begin(), (c).end(), (v)) != (c).end())
|
||||||
|
|
||||||
// The naive swap performs better than the xor version
|
// The naive swap performs better than the xor version
|
||||||
#define SWAP(t, x, y) do { \
|
#define SWAP(t, x, y) do { \
|
||||||
t temp = x; \
|
t temp = x; \
|
||||||
|
Loading…
Reference in New Issue
Block a user