Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Schematic decorations: Add 'place_offset_y' placement parameter
For precise control of schematic vertical position relative to the
'place_on' node.
Avoids workarounds that add empty nodes to a schematic and therefore
reduce performance.

Also remove long-unused decoration cutoff code.
  • Loading branch information
paramat committed Sep 10, 2017
1 parent 557bbc6 commit 51002b1
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 83 deletions.
7 changes: 7 additions & 0 deletions doc/lua_api.txt
Expand Up @@ -4743,6 +4743,13 @@ The Biome API is still in an experimental phase and subject to change.
-- ^ Flags for schematic decorations. See 'Schematic attributes'.
rotation = "90" -- rotate schematic 90 degrees on placement
-- ^ Rotation can be "0", "90", "180", "270", or "random".
place_offset_y = 0,
-- ^ Y offset of the schematic base node layer relative to the 'place_on'
-- ^ node.
-- ^ Can be positive or negative. Default is 0.
-- ^ If the flag 'place_center_y' is set this parameter is ignored.
-- ^ If absent or 0 the schematic base node layer will be placed level
-- ^ with the 'place_on' node.
}

### Chat command definition (`register_chatcommand`)
Expand Down
81 changes: 14 additions & 67 deletions src/mg_decoration.cpp
Expand Up @@ -67,6 +67,7 @@ size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 blockseed,

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


void Decoration::resolveNodeNames()
{
getIdsFromNrBacklog(&c_place_on);
Expand Down Expand Up @@ -192,15 +193,8 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed,
if (y < y_min_disp || y > y_max_disp || y < nmin.Y || y > nmax.Y)
continue;

if (y + getHeight() > mg->vm->m_area.MaxEdge.Y) {
if (y + getHeight() > mg->vm->m_area.MaxEdge.Y)
continue;
#if 0
printf("Decoration at (%d %d %d) cut off\n", x, y, z);
//add to queue
MutexAutoLock cutofflock(cutoff_mutex);
cutoffs.push_back(CutoffData(x, y, z, height));
#endif
}

if (mg->biomemap && !biomes.empty()) {
std::unordered_set<u8>::const_iterator iter =
Expand All @@ -219,60 +213,6 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed,
}


#if 0
void Decoration::placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
{
PcgRandom pr(blockseed + 53);
std::vector<CutoffData> handled_cutoffs;

// Copy over the cutoffs we're interested in so we don't needlessly hold a lock
{
MutexAutoLock cutofflock(cutoff_mutex);
for (std::list<CutoffData>::iterator i = cutoffs.begin();
i != cutoffs.end(); ++i) {
CutoffData cutoff = *i;
v3s16 p = cutoff.p;
s16 height = cutoff.height;
if (p.X < nmin.X || p.X > nmax.X ||
p.Z < nmin.Z || p.Z > nmax.Z)
continue;
if (p.Y + height < nmin.Y || p.Y > nmax.Y)
continue;

handled_cutoffs.push_back(cutoff);
}
}

// Generate the cutoffs
for (size_t i = 0; i != handled_cutoffs.size(); i++) {
v3s16 p = handled_cutoffs[i].p;
s16 height = handled_cutoffs[i].height;

if (p.Y + height > nmax.Y) {
//printf("Decoration at (%d %d %d) cut off again!\n", p.X, p.Y, p.Z);
cuttoffs.push_back(v3s16(p.X, p.Y, p.Z));
}

generate(mg, &pr, nmax.Y, nmin.Y - p.Y, v3s16(p.X, nmin.Y, p.Z));
}

// Remove cutoffs that were handled from the cutoff list
{
MutexAutoLock cutofflock(cutoff_mutex);
for (std::list<CutoffData>::iterator i = cutoffs.begin();
i != cutoffs.end(); ++i) {

for (size_t j = 0; j != handled_cutoffs.size(); j++) {
CutoffData coff = *i;
if (coff.p == handled_cutoffs[j].p)
i = cutoffs.erase(i);
}
}
}
}
#endif


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


Expand Down Expand Up @@ -324,6 +264,7 @@ int DecoSimple::getHeight()

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


size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p)
{
// Schematic could have been unloaded but not the decoration
Expand All @@ -336,11 +277,17 @@ size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p)

if (flags & DECO_PLACE_CENTER_X)
p.X -= (schematic->size.X - 1) / 2;
if (flags & DECO_PLACE_CENTER_Y)
p.Y -= (schematic->size.Y - 1) / 2;
if (flags & DECO_PLACE_CENTER_Z)
p.Z -= (schematic->size.Z - 1) / 2;

if (flags & DECO_PLACE_CENTER_Y)
p.Y -= (schematic->size.Y - 1) / 2;
else
p.Y += place_offset_y;
// Check shifted schematic base is in voxelmanip
if (p.Y < vm->m_area.MinEdge.Y)
return 0;

Rotation rot = (rotation == ROTATE_RAND) ?
(Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation;

Expand All @@ -355,8 +302,8 @@ size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p)
int DecoSchematic::getHeight()
{
// Account for a schematic being sunk into the ground by flag.
// When placed normally account for how a schematic is placed
// sunk 1 node into the ground.
// When placed normally account for how a schematic is by default placed
// sunk 1 node into the ground or is vertically shifted by 'y_offset'.
return (flags & DECO_PLACE_CENTER_Y) ?
(schematic->size.Y - 1) / 2 : schematic->size.Y - 1;
(schematic->size.Y - 1) / 2 : schematic->size.Y - 1 + place_offset_y;
}
20 changes: 4 additions & 16 deletions src/mg_decoration.h
Expand Up @@ -46,21 +46,6 @@ enum DecorationType {
extern FlagDesc flagdesc_deco[];


#if 0
struct CutoffData {
VoxelArea a;
Decoration *deco;
//v3s16 p;
//v3s16 size;
//s16 height;

CutoffData(s16 x, s16 y, s16 z, s16 h) {
p = v3s16(x, y, z);
height = h;
}
};
#endif

class Decoration : public ObjDef, public NodeResolver {
public:
Decoration() = default;
Expand All @@ -71,7 +56,6 @@ class Decoration : public ObjDef, public NodeResolver {
bool canPlaceDecoration(MMVManip *vm, v3s16 p);
size_t placeDeco(Mapgen *mg, u32 blockseed,
v3s16 nmin, v3s16 nmax, s16 deco_zero_level);
//size_t placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);

virtual size_t generate(MMVManip *vm, PcgRandom *pr, v3s16 p) = 0;
virtual int getHeight() = 0;
Expand All @@ -90,6 +74,7 @@ class Decoration : public ObjDef, public NodeResolver {
std::unordered_set<u8> biomes;
};


class DecoSimple : public Decoration {
public:
virtual void resolveNodeNames();
Expand All @@ -102,6 +87,7 @@ class DecoSimple : public Decoration {
u8 deco_param2;
};


class DecoSchematic : public Decoration {
public:
DecoSchematic() = default;
Expand All @@ -110,6 +96,7 @@ class DecoSchematic : public Decoration {
virtual int getHeight();

Rotation rotation;
s16 place_offset_y = 0;
Schematic *schematic = nullptr;
};

Expand All @@ -121,6 +108,7 @@ class DecoLSystem : public Decoration {
};
*/


class DecorationManager : public ObjDefManager {
public:
DecorationManager(IGameDef *gamedef);
Expand Down
2 changes: 2 additions & 0 deletions src/script/lua_api/l_mapgen.cpp
Expand Up @@ -1018,6 +1018,8 @@ bool read_deco_schematic(lua_State *L, SchematicManager *schemmgr, DecoSchematic
deco->rotation = (Rotation)getenumfield(L, index, "rotation",
ModApiMapgen::es_Rotation, ROTATE_0);

deco->place_offset_y = getintfield_default(L, index, "place_offset_y", 0);

StringMap replace_names;
lua_getfield(L, index, "replacements");
if (lua_istable(L, -1))
Expand Down

0 comments on commit 51002b1

Please sign in to comment.