summaryrefslogtreecommitdiffstats
path: root/src/Generating
diff options
context:
space:
mode:
authorMattes D <github@xoft.cz>2016-11-21 17:12:01 +0100
committerMattes D <github@xoft.cz>2016-11-24 15:51:53 +0100
commit6b70574da96208a9bf855d0db983d27972ad9281 (patch)
treeab87c4a6c9f58fdfe2495c4fef939f4940df7d96 /src/Generating
parentMerge pull request #3442 from Seadragon91/luacheck_config (diff)
downloadcuberite-6b70574da96208a9bf855d0db983d27972ad9281.tar
cuberite-6b70574da96208a9bf855d0db983d27972ad9281.tar.gz
cuberite-6b70574da96208a9bf855d0db983d27972ad9281.tar.bz2
cuberite-6b70574da96208a9bf855d0db983d27972ad9281.tar.lz
cuberite-6b70574da96208a9bf855d0db983d27972ad9281.tar.xz
cuberite-6b70574da96208a9bf855d0db983d27972ad9281.tar.zst
cuberite-6b70574da96208a9bf855d0db983d27972ad9281.zip
Diffstat (limited to 'src/Generating')
-rw-r--r--src/Generating/Prefab.cpp116
-rw-r--r--src/Generating/Prefab.h26
-rw-r--r--src/Generating/PrefabPiecePool.cpp54
3 files changed, 142 insertions, 54 deletions
diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp
index 6805167a9..9af01d6a4 100644
--- a/src/Generating/Prefab.cpp
+++ b/src/Generating/Prefab.cpp
@@ -97,8 +97,8 @@ static const cPrefab::sDef g_TestPrefabDef =
// Merge strategy:
cBlockArea::msImprint,
- // ShouldExtendFloor:
- false,
+ // ExtendFloorStrategy:
+ cPrefab::efsNone,
// DefaultWeight:
10,
@@ -128,7 +128,7 @@ cPrefab::cPrefab(const cPrefab::sDef & a_Def) :
),
m_AllowedRotations(a_Def.m_AllowedRotations),
m_MergeStrategy(a_Def.m_MergeStrategy),
- m_ShouldExtendFloor(a_Def.m_ShouldExtendFloor),
+ m_ExtendFloorStrategy(a_Def.m_ExtendFloorStrategy),
m_DefaultWeight(a_Def.m_DefaultWeight),
m_AddWeightIfSame(a_Def.m_AddWeightIfSame),
m_MoveToGround(a_Def.m_MoveToGround)
@@ -151,7 +151,7 @@ cPrefab::cPrefab(const cBlockArea & a_Image, int a_AllowedRotations) :
m_Size(a_Image.GetSize()),
m_AllowedRotations(a_AllowedRotations),
m_MergeStrategy(cBlockArea::msOverwrite),
- m_ShouldExtendFloor(false),
+ m_ExtendFloorStrategy(efsNone),
m_DefaultWeight(1),
m_AddWeightIfSame(0),
m_MoveToGround(false)
@@ -170,7 +170,7 @@ cPrefab::cPrefab(const cBlockArea & a_Image) :
m_Size(a_Image.GetSize()),
m_AllowedRotations(0),
m_MergeStrategy(cBlockArea::msOverwrite),
- m_ShouldExtendFloor(false),
+ m_ExtendFloorStrategy(efsNone),
m_DefaultWeight(1),
m_AddWeightIfSame(0),
m_MoveToGround(false)
@@ -188,7 +188,7 @@ cPrefab::cPrefab(const AString & a_BlockDefinitions, const AString & a_BlockData
m_Size(a_SizeX, a_SizeY, a_SizeZ),
m_AllowedRotations(0),
m_MergeStrategy(cBlockArea::msOverwrite),
- m_ShouldExtendFloor(false),
+ m_ExtendFloorStrategy(efsNone),
m_DefaultWeight(1),
m_AddWeightIfSame(0),
m_MoveToGround(false)
@@ -264,46 +264,94 @@ void cPrefab::Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumR
a_Dest.WriteBlockArea(Image, Placement.x, Placement.y, Placement.z, m_MergeStrategy);
// If requested, draw the floor (from the bottom of the prefab down to the nearest non-air)
- if (m_ShouldExtendFloor)
+ switch (m_ExtendFloorStrategy)
{
- int MaxX = Image.GetSizeX();
- int MaxZ = Image.GetSizeZ();
- for (int z = 0; z < MaxZ; z++)
+ case efsNone: break; // Nothing needed
+ case efsRepeatBottomTillNonAir:
{
- int RelZ = Placement.z + z;
- if ((RelZ < 0) || (RelZ >= cChunkDef::Width))
- {
- // Z coord outside the chunk
- continue;
- }
- for (int x = 0; x < MaxX; x++)
+ int MaxX = Image.GetSizeX();
+ int MaxZ = Image.GetSizeZ();
+ for (int z = 0; z < MaxZ; z++)
{
- int RelX = Placement.x + x;
- if ((RelX < 0) || (RelX >= cChunkDef::Width))
+ int RelZ = Placement.z + z;
+ if ((RelZ < 0) || (RelZ >= cChunkDef::Width))
{
- // X coord outside the chunk
+ // Z coord outside the chunk
continue;
}
- BLOCKTYPE BlockType;
- NIBBLETYPE BlockMeta;
- Image.GetRelBlockTypeMeta(x, 0, z, BlockType, BlockMeta);
- if ((BlockType == E_BLOCK_AIR) || (BlockType == E_BLOCK_SPONGE))
+ for (int x = 0; x < MaxX; x++)
+ {
+ int RelX = Placement.x + x;
+ if ((RelX < 0) || (RelX >= cChunkDef::Width))
+ {
+ // X coord outside the chunk
+ continue;
+ }
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ Image.GetRelBlockTypeMeta(x, 0, z, BlockType, BlockMeta);
+ if ((BlockType == E_BLOCK_AIR) || (BlockType == E_BLOCK_SPONGE))
+ {
+ // Do not expand air nor sponge blocks
+ continue;
+ }
+ for (int y = Placement.y - 1; y >= 0; y--)
+ {
+ BLOCKTYPE ExistingBlock = a_Dest.GetBlockType(RelX, y, RelZ);
+ if (ExistingBlock != E_BLOCK_AIR)
+ {
+ // End the expansion for this column, reached the end
+ break;
+ }
+ a_Dest.SetBlockTypeMeta(RelX, y, RelZ, BlockType, BlockMeta);
+ } // for y
+ } // for x
+ } // for z
+ break;
+ } // efsRepeatBottomTillNonAir
+
+ case efsRepeatBottomTillSolid:
+ {
+ int MaxX = Image.GetSizeX();
+ int MaxZ = Image.GetSizeZ();
+ for (int z = 0; z < MaxZ; z++)
+ {
+ int RelZ = Placement.z + z;
+ if ((RelZ < 0) || (RelZ >= cChunkDef::Width))
{
- // Do not expand air nor sponge blocks
+ // Z coord outside the chunk
continue;
}
- for (int y = Placement.y - 1; y >= 0; y--)
+ for (int x = 0; x < MaxX; x++)
{
- BLOCKTYPE ExistingBlock = a_Dest.GetBlockType(RelX, y, RelZ);
- if (ExistingBlock != E_BLOCK_AIR)
+ int RelX = Placement.x + x;
+ if ((RelX < 0) || (RelX >= cChunkDef::Width))
{
- // End the expansion for this column, reached the end
- break;
+ // X coord outside the chunk
+ continue;
}
- a_Dest.SetBlockTypeMeta(RelX, y, RelZ, BlockType, BlockMeta);
- } // for y
- } // for x
- } // for z
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ Image.GetRelBlockTypeMeta(x, 0, z, BlockType, BlockMeta);
+ if ((BlockType == E_BLOCK_AIR) || (BlockType == E_BLOCK_SPONGE))
+ {
+ // Do not expand air nor sponge blocks
+ continue;
+ }
+ for (int y = Placement.y - 1; y >= 0; y--)
+ {
+ BLOCKTYPE ExistingBlock = a_Dest.GetBlockType(RelX, y, RelZ);
+ if (cBlockInfo::IsSolid(ExistingBlock))
+ {
+ // End the expansion for this column, reached the end
+ break;
+ }
+ a_Dest.SetBlockTypeMeta(RelX, y, RelZ, BlockType, BlockMeta);
+ } // for y
+ } // for x
+ } // for z
+ break;
+ } // efsRepeatBottomTillSolid
}
}
diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h
index 5f937260d..bb961f2b3 100644
--- a/src/Generating/Prefab.h
+++ b/src/Generating/Prefab.h
@@ -32,6 +32,14 @@ class cPrefab :
public cPiece
{
public:
+ /** How to handle the space between the prefab bottom and the terrain top. */
+ enum eExtendFloorStrategy
+ {
+ efsNone, ///< No processing, the prefab is left "floating in the air"
+ efsRepeatBottomTillNonAir, ///< Repeat the bottom-most block down until the first non-air block
+ efsRepeatBottomTillSolid, ///< Repeat the bottom-most block down until the first solid block; non-solids are overwritten
+ };
+
struct sDef
{
int m_SizeX;
@@ -62,10 +70,9 @@ public:
/** The merge strategy to use while drawing the prefab. */
cBlockArea::eMergeStrategy m_MergeStrategy;
- /** If set to true, the prefab will extend its lowermost blocks until a solid block is found,
- thus creating a foundation for the prefab. This is used for houses to be "on the ground", as well as
- nether fortresses not to float. */
- bool m_ShouldExtendFloor;
+ /** How the prefab should handle not being on top of the ground.
+ This is used for houses to be "on the ground", as well as nether fortresses not to float. */
+ eExtendFloorStrategy m_ExtendFloorStrategy;
/** Chance of this piece being used, if no other modifier is active. */
int m_DefaultWeight;
@@ -143,8 +150,8 @@ public:
/** Sets the flag whether the prefab should be moved to ground level before being drawn. */
void SetMoveToGround(bool a_MoveToGround) { m_MoveToGround = a_MoveToGround; }
- /** Sets the flag whether the lowest layer of the prefab should be repeated downwards until it hits a solid block. */
- void SetExtendFloor(bool a_ShouldExtendFloor) { m_ShouldExtendFloor = a_ShouldExtendFloor; }
+ /** Sets the strategy to use between the bottom of the prefab and the terrain top. */
+ void SetExtendFloorStrategy(eExtendFloorStrategy a_Strategy) { m_ExtendFloorStrategy = a_Strategy; }
/** Sets the internal hitbox to the specified value. */
void SetHitBox(const cCuboid & a_HitBox) { m_HitBox = a_HitBox; }
@@ -183,10 +190,9 @@ protected:
/** The merge strategy to use when drawing the prefab into a block area */
cBlockArea::eMergeStrategy m_MergeStrategy;
- /** If set to true, the prefab will extend its lowermost blocks until a solid block is found,
- thus creating a foundation for the prefab. This is used for houses to be "on the ground", as well as
- nether fortresses not to float. */
- bool m_ShouldExtendFloor;
+ /** How the prefab should handle not being on top of the ground.
+ This is used for houses to be "on the ground", as well as nether fortresses not to float. */
+ eExtendFloorStrategy m_ExtendFloorStrategy;
/** Chance of this piece being used, if no other modifier is active. */
int m_DefaultWeight;
diff --git a/src/Generating/PrefabPiecePool.cpp b/src/Generating/PrefabPiecePool.cpp
index 417f8ce7e..d6c2c8819 100644
--- a/src/Generating/PrefabPiecePool.cpp
+++ b/src/Generating/PrefabPiecePool.cpp
@@ -526,16 +526,15 @@ bool cPrefabPiecePool::ReadPieceMetadataCubesetVer1(
}
// Get the values:
- int AddWeightIfSame = 0, DefaultWeight = 100, MoveToGround = 0, ShouldExpandFloor = 0;
+ int AddWeightIfSame = 0, DefaultWeight = 100, MoveToGround = 0;
AString DepthWeight, MergeStrategy, VerticalLimit, VerticalStrategy;
- a_LuaState.GetNamedValue("AddWeightIfSame", AddWeightIfSame);
- a_LuaState.GetNamedValue("DefaultWeight", DefaultWeight);
- a_LuaState.GetNamedValue("DepthWeight", DepthWeight);
- a_LuaState.GetNamedValue("MergeStrategy", MergeStrategy);
- a_LuaState.GetNamedValue("MoveToGround", MoveToGround);
- a_LuaState.GetNamedValue("ShouldExpandFloor", ShouldExpandFloor);
- a_LuaState.GetNamedValue("VerticalLimit", VerticalLimit);
- a_LuaState.GetNamedValue("VerticalStrategy", VerticalStrategy);
+ a_LuaState.GetNamedValue("AddWeightIfSame", AddWeightIfSame);
+ a_LuaState.GetNamedValue("DefaultWeight", DefaultWeight);
+ a_LuaState.GetNamedValue("DepthWeight", DepthWeight);
+ a_LuaState.GetNamedValue("MergeStrategy", MergeStrategy);
+ a_LuaState.GetNamedValue("MoveToGround", MoveToGround);
+ a_LuaState.GetNamedValue("VerticalLimit", VerticalLimit);
+ a_LuaState.GetNamedValue("VerticalStrategy", VerticalStrategy);
// Apply the values:
a_Prefab->SetAddWeightIfSame(AddWeightIfSame);
@@ -555,7 +554,42 @@ bool cPrefabPiecePool::ReadPieceMetadataCubesetVer1(
a_Prefab->SetMergeStrategy(strategy->second);
}
a_Prefab->SetMoveToGround(MoveToGround != 0);
- a_Prefab->SetExtendFloor(ShouldExpandFloor != 0);
+
+ AString ExpandFloorStrategyStr;
+ if (!a_LuaState.GetNamedValue("ExpandFloorStrategy", ExpandFloorStrategyStr))
+ {
+ // Check the older variant for ExpandFloorStrategy, ShouldExpandFloor:
+ int ShouldExpandFloor;
+ if (a_LuaState.GetNamedValue("ShouldExpandFloor", ShouldExpandFloor))
+ {
+ LOG("Piece \"%s\" in file \"%s\" is using the old \"ShouldExpandFloor\" attribute. Use the new \"ExpandFloorStrategy\" attribute instead for more options.",
+ a_PieceName.c_str(), a_FileName.c_str()
+ );
+ a_Prefab->SetExtendFloorStrategy((ShouldExpandFloor != 0) ? cPrefab::efsRepeatBottomTillNonAir : cPrefab::efsNone);
+ }
+ }
+ else
+ {
+ auto lcExpandFloorStrategyStr = StrToLower(ExpandFloorStrategyStr);
+ if (lcExpandFloorStrategyStr == "repeatbottomtillnonair")
+ {
+ a_Prefab->SetExtendFloorStrategy(cPrefab::efsRepeatBottomTillNonAir);
+ }
+ else if (lcExpandFloorStrategyStr == "repeatbottomtillsolid")
+ {
+ a_Prefab->SetExtendFloorStrategy(cPrefab::efsRepeatBottomTillSolid);
+ }
+ else
+ {
+ if (lcExpandFloorStrategyStr != "none")
+ {
+ LOGWARNING("Piece \"%s\" in file \"%s\" is using an unknown \"ExpandFloorStrategy\" attribute value: \"%s\"",
+ a_PieceName.c_str(), a_FileName.c_str(), ExpandFloorStrategyStr.c_str()
+ );
+ }
+ a_Prefab->SetExtendFloorStrategy(cPrefab::efsNone);
+ }
+ }
if (!VerticalLimit.empty())
{
if (!a_Prefab->SetVerticalLimitFromString(VerticalLimit, a_LogWarnings))