forked from Mirrorlandia_minetest/minetest
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.
This commit is contained in:
parent
557bbc6704
commit
51002b1629
@ -4743,6 +4743,13 @@ The Biome API is still in an experimental phase and subject to change.
|
|||||||
-- ^ Flags for schematic decorations. See 'Schematic attributes'.
|
-- ^ Flags for schematic decorations. See 'Schematic attributes'.
|
||||||
rotation = "90" -- rotate schematic 90 degrees on placement
|
rotation = "90" -- rotate schematic 90 degrees on placement
|
||||||
-- ^ Rotation can be "0", "90", "180", "270", or "random".
|
-- ^ 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`)
|
### Chat command definition (`register_chatcommand`)
|
||||||
|
@ -67,6 +67,7 @@ size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 blockseed,
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
void Decoration::resolveNodeNames()
|
void Decoration::resolveNodeNames()
|
||||||
{
|
{
|
||||||
getIdsFromNrBacklog(&c_place_on);
|
getIdsFromNrBacklog(&c_place_on);
|
||||||
@ -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)
|
if (y < y_min_disp || y > y_max_disp || y < nmin.Y || y > nmax.Y)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (y + getHeight() > mg->vm->m_area.MaxEdge.Y) {
|
if (y + getHeight() > mg->vm->m_area.MaxEdge.Y)
|
||||||
continue;
|
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()) {
|
if (mg->biomemap && !biomes.empty()) {
|
||||||
std::unordered_set<u8>::const_iterator iter =
|
std::unordered_set<u8>::const_iterator iter =
|
||||||
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
@ -324,6 +264,7 @@ int DecoSimple::getHeight()
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p)
|
size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p)
|
||||||
{
|
{
|
||||||
// Schematic could have been unloaded but not the decoration
|
// Schematic could have been unloaded but not the decoration
|
||||||
@ -336,11 +277,17 @@ size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p)
|
|||||||
|
|
||||||
if (flags & DECO_PLACE_CENTER_X)
|
if (flags & DECO_PLACE_CENTER_X)
|
||||||
p.X -= (schematic->size.X - 1) / 2;
|
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)
|
if (flags & DECO_PLACE_CENTER_Z)
|
||||||
p.Z -= (schematic->size.Z - 1) / 2;
|
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 rot = (rotation == ROTATE_RAND) ?
|
||||||
(Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation;
|
(Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation;
|
||||||
|
|
||||||
@ -355,8 +302,8 @@ size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p)
|
|||||||
int DecoSchematic::getHeight()
|
int DecoSchematic::getHeight()
|
||||||
{
|
{
|
||||||
// Account for a schematic being sunk into the ground by flag.
|
// Account for a schematic being sunk into the ground by flag.
|
||||||
// When placed normally account for how a schematic is placed
|
// When placed normally account for how a schematic is by default placed
|
||||||
// sunk 1 node into the ground.
|
// sunk 1 node into the ground or is vertically shifted by 'y_offset'.
|
||||||
return (flags & DECO_PLACE_CENTER_Y) ?
|
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;
|
||||||
}
|
}
|
||||||
|
@ -46,21 +46,6 @@ enum DecorationType {
|
|||||||
extern FlagDesc flagdesc_deco[];
|
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 {
|
class Decoration : public ObjDef, public NodeResolver {
|
||||||
public:
|
public:
|
||||||
Decoration() = default;
|
Decoration() = default;
|
||||||
@ -71,7 +56,6 @@ public:
|
|||||||
bool canPlaceDecoration(MMVManip *vm, v3s16 p);
|
bool canPlaceDecoration(MMVManip *vm, v3s16 p);
|
||||||
size_t placeDeco(Mapgen *mg, u32 blockseed,
|
size_t placeDeco(Mapgen *mg, u32 blockseed,
|
||||||
v3s16 nmin, v3s16 nmax, s16 deco_zero_level);
|
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 size_t generate(MMVManip *vm, PcgRandom *pr, v3s16 p) = 0;
|
||||||
virtual int getHeight() = 0;
|
virtual int getHeight() = 0;
|
||||||
@ -90,6 +74,7 @@ public:
|
|||||||
std::unordered_set<u8> biomes;
|
std::unordered_set<u8> biomes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class DecoSimple : public Decoration {
|
class DecoSimple : public Decoration {
|
||||||
public:
|
public:
|
||||||
virtual void resolveNodeNames();
|
virtual void resolveNodeNames();
|
||||||
@ -102,6 +87,7 @@ public:
|
|||||||
u8 deco_param2;
|
u8 deco_param2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class DecoSchematic : public Decoration {
|
class DecoSchematic : public Decoration {
|
||||||
public:
|
public:
|
||||||
DecoSchematic() = default;
|
DecoSchematic() = default;
|
||||||
@ -110,6 +96,7 @@ public:
|
|||||||
virtual int getHeight();
|
virtual int getHeight();
|
||||||
|
|
||||||
Rotation rotation;
|
Rotation rotation;
|
||||||
|
s16 place_offset_y = 0;
|
||||||
Schematic *schematic = nullptr;
|
Schematic *schematic = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -121,6 +108,7 @@ public:
|
|||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
class DecorationManager : public ObjDefManager {
|
class DecorationManager : public ObjDefManager {
|
||||||
public:
|
public:
|
||||||
DecorationManager(IGameDef *gamedef);
|
DecorationManager(IGameDef *gamedef);
|
||||||
|
@ -1018,6 +1018,8 @@ bool read_deco_schematic(lua_State *L, SchematicManager *schemmgr, DecoSchematic
|
|||||||
deco->rotation = (Rotation)getenumfield(L, index, "rotation",
|
deco->rotation = (Rotation)getenumfield(L, index, "rotation",
|
||||||
ModApiMapgen::es_Rotation, ROTATE_0);
|
ModApiMapgen::es_Rotation, ROTATE_0);
|
||||||
|
|
||||||
|
deco->place_offset_y = getintfield_default(L, index, "place_offset_y", 0);
|
||||||
|
|
||||||
StringMap replace_names;
|
StringMap replace_names;
|
||||||
lua_getfield(L, index, "replacements");
|
lua_getfield(L, index, "replacements");
|
||||||
if (lua_istable(L, -1))
|
if (lua_istable(L, -1))
|
||||||
|
Loading…
Reference in New Issue
Block a user