summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Generating/PieceGenerator.cpp11
-rw-r--r--src/Generating/PieceGenerator.h7
-rw-r--r--src/Generating/Prefab.cpp12
-rw-r--r--src/Generating/Prefab.h3
-rw-r--r--src/Generating/VillageGen.cpp41
5 files changed, 67 insertions, 7 deletions
diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp
index ce19c1c95..c12559d3f 100644
--- a/src/Generating/PieceGenerator.cpp
+++ b/src/Generating/PieceGenerator.cpp
@@ -297,6 +297,17 @@ cPlacedPiece::cPlacedPiece(const cPlacedPiece * a_Parent, const cPiece & a_Piece
+cPiece::cConnector cPlacedPiece::GetRotatedConnector(size_t a_Index) const
+{
+ cPiece::cConnectors Connectors = m_Piece->GetConnectors();
+ ASSERT(Connectors.size() >= a_Index);
+ return m_Piece->RotateMoveConnector(Connectors[a_Index], m_NumCCWRotations, m_Coords.x, m_Coords.y, m_Coords.z);
+}
+
+
+
+
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cPieceGenerator:
diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h
index 16bec3bb4..56ce996d2 100644
--- a/src/Generating/PieceGenerator.h
+++ b/src/Generating/PieceGenerator.h
@@ -144,6 +144,13 @@ public:
const cCuboid & GetHitBox (void) const { return m_HitBox; }
int GetDepth (void) const { return m_Depth; }
+ /** Returns the coords as a modifiable object. */
+ Vector3i & GetCoords(void) { return m_Coords; }
+
+ /** Returns the connector at the specified index, rotated in the actual placement.
+ Undefined behavior if a_Index is out of range. */
+ cPiece::cConnector GetRotatedConnector(size_t a_Index) const;
+
protected:
const cPlacedPiece * m_Parent;
const cPiece * m_Piece;
diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp
index 9aef7a94b..506e1c2cc 100644
--- a/src/Generating/Prefab.cpp
+++ b/src/Generating/Prefab.cpp
@@ -192,12 +192,20 @@ void cPrefab::AddRotatedBlockAreas(void)
void cPrefab::Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const
{
+ Draw(a_Dest, a_Placement->GetCoords(), a_Placement->GetNumCCWRotations());
+}
+
+
+
+
+void cPrefab::Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumRotations) const
+{
// Draw the basic image:
- Vector3i Placement = a_Placement->GetCoords();
+ Vector3i Placement(a_Placement);
int ChunkStartX = a_Dest.GetChunkX() * cChunkDef::Width;
int ChunkStartZ = a_Dest.GetChunkZ() * cChunkDef::Width;
Placement.Move(-ChunkStartX, 0, -ChunkStartZ);
- const cBlockArea & Image = m_BlockArea[a_Placement->GetNumCCWRotations()];
+ const cBlockArea & Image = m_BlockArea[a_NumRotations];
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)
diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h
index c08413e87..2b89a204c 100644
--- a/src/Generating/Prefab.h
+++ b/src/Generating/Prefab.h
@@ -94,6 +94,9 @@ public:
/** Draws the prefab into the specified chunk, according to the placement stored in the PlacedPiece. */
void Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const;
+ /** Draws the prefab into the specified chunks, according to the specified placement and rotations. */
+ void Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumRotations) const;
+
/** Returns true if the prefab has any connector of the specified type. */
bool HasConnectorType(int a_ConnectorType) const;
diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp
index b514a90cd..db81fb521 100644
--- a/src/Generating/VillageGen.cpp
+++ b/src/Generating/VillageGen.cpp
@@ -115,7 +115,9 @@ public:
m_HeightGen(a_HeightGen)
{
cBFSPieceGenerator pg(m_Prefabs, a_Seed);
- pg.PlacePieces(a_OriginX, 10, a_OriginZ, a_MaxRoadDepth + 1, m_Pieces);
+ // Generate the pieces at very negative Y coords, so that we can later test
+ // Piece has negative Y coord -> hasn't been height-adjusted yet
+ pg.PlacePieces(a_OriginX, -1000, a_OriginZ, a_MaxRoadDepth + 1, m_Pieces);
}
protected:
@@ -144,16 +146,45 @@ protected:
// cGrdStructGen::cStructure overrides:
virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override
{
- // TODO
// Iterate over all items
- // Each intersecting prefab is placed on ground (if not already placed), then drawn
+ // Each intersecting prefab is placed on ground, then drawn
// Each intersecting road is drawn by replacing top soil blocks with gravel / sandstone blocks
- for (cPlacedPieces::const_iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr)
+ cChunkDef::HeightMap HeightMap; // Heightmap for this chunk, used by roads
+ m_HeightGen.GenHeightMap(a_Chunk.GetChunkX(), a_Chunk.GetChunkZ(), HeightMap);
+ for (cPlacedPieces::iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr)
{
- const cPrefab & Prefab = (const cPrefab &)((*itr)->GetPiece());
+ cPrefab & Prefab = (cPrefab &)((*itr)->GetPiece());
+ if ((*itr)->GetPiece().GetSize().y == 1)
+ {
+ // It's a road, special handling (change top terrain blocks
+ // TODO
+ Prefab.Draw(a_Chunk, (*itr)->GetCoords() + Vector3i(0, 1100, 0), (*itr)->GetNumCCWRotations());
+ continue;
+ }
+ if ((*itr)->GetCoords().y < 0)
+ {
+ PlacePieceOnGround(**itr);
+ }
Prefab.Draw(a_Chunk, *itr);
} // for itr - m_PlacedPieces[]
}
+
+
+ /** Adjusts the Y coord of the given piece so that the piece is on the ground.
+ Ground level is assumed to be represented by the first connector in the piece. */
+ void PlacePieceOnGround(cPlacedPiece & a_Piece)
+ {
+ cPiece::cConnector FirstConnector = a_Piece.GetRotatedConnector(0);
+ int ChunkX, ChunkZ;
+ int BlockX = FirstConnector.m_Pos.x;
+ int BlockZ = FirstConnector.m_Pos.z;
+ int BlockY;
+ cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
+ cChunkDef::HeightMap HeightMap;
+ m_HeightGen.GenHeightMap(ChunkX, ChunkZ, HeightMap);
+ int TerrainHeight = cChunkDef::GetHeight(HeightMap, BlockX, BlockZ);
+ a_Piece.GetCoords().y += TerrainHeight - FirstConnector.m_Pos.y + 1;
+ }
} ;