1
0
Fork 0

Village houses are height-adjusted onto the terrain.

This commit is contained in:
madmaxoft 2014-05-17 21:54:04 +02:00
parent fc5c3abcba
commit 7004043c61
5 changed files with 67 additions and 7 deletions

View File

@ -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:

View File

@ -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;

View File

@ -191,13 +191,21 @@ 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)

View File

@ -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;

View File

@ -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;
}
} ;