diff options
Diffstat (limited to 'source/Generating/MineShafts.cpp')
-rw-r--r-- | source/Generating/MineShafts.cpp | 1423 |
1 files changed, 0 insertions, 1423 deletions
diff --git a/source/Generating/MineShafts.cpp b/source/Generating/MineShafts.cpp deleted file mode 100644 index 159e6b4ea..000000000 --- a/source/Generating/MineShafts.cpp +++ /dev/null @@ -1,1423 +0,0 @@ - -// MineShafts.cpp - -// Implements the cStructGenMineShafts class representing the structure generator for abandoned mineshafts - -/* -Algorithm: -The cStructGenMineShafts::cMineShaftSystem class is the main controller, which knows what mineshaft -classes there are and their random weights. It gets asked to produce a new class everytime a connection is to be made. -The cMineShaft class is a base class for each mineshaft structure. -Each cMineShaft descendant knows how large it is, how to imprint itself into the chunk data and where to connect to -other descendants. Its PivotPoint is always a walkable column. Its Direction determines in which direction the structure -is facing. - -The generation starts with the central dirt room, from there corridors, crossings and staircases are added -in a depth-first processing. Each of the descendants will branch randomly, if not beyond the allowed recursion level -*/ - -#include "Globals.h" -#include "MineShafts.h" -#include "../Cuboid.h" -#include "../BlockEntities/ChestEntity.h" - - - - - -static const int NEIGHBORHOOD_SIZE = 3; - - - - - -class cMineShaft abstract -{ -public: - enum eKind - { - mskDirtRoom, - mskCorridor, - mskCrossing, - mskStaircase, - } ; - - - enum eDirection - { - dirXP, - dirZP, - dirXM, - dirZM, - } ; - - - cStructGenMineShafts::cMineShaftSystem & m_ParentSystem; - eKind m_Kind; - cCuboid m_BoundingBox; - - - cMineShaft(cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, eKind a_Kind) : - m_ParentSystem(a_ParentSystem), - m_Kind(a_Kind) - { - } - - cMineShaft(cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, eKind a_Kind, const cCuboid & a_BoundingBox) : - m_ParentSystem(a_ParentSystem), - m_Kind(a_Kind), - m_BoundingBox(a_BoundingBox) - { - } - - /// Returns true if this mineshaft intersects the specified cuboid - bool DoesIntersect(const cCuboid & a_Other) - { - return m_BoundingBox.DoesIntersect(a_Other); - } - - /** If recursion level is not too large, appends more branches to the parent system, - using exit points specific to this class. - */ - virtual void AppendBranches(int a_RecursionLevel, cNoise & a_Noise) = 0; - - /// Imprints this shape into the specified chunk's data - virtual void ProcessChunk(cChunkDesc & a_ChunkDesc) = 0; -} ; - -typedef std::vector<cMineShaft *> cMineShafts; - - - - - -class cMineShaftDirtRoom : - public cMineShaft -{ - typedef cMineShaft super; - -public: - cMineShaftDirtRoom(cStructGenMineShafts::cMineShaftSystem & a_Parent, cNoise & a_Noise); - - // cMineShaft overrides: - virtual void AppendBranches(int a_RecursionLevel, cNoise & a_Noise) override; - virtual void ProcessChunk(cChunkDesc & a_ChunkDesc) override; -} ; - - - - - -class cMineShaftCorridor : - public cMineShaft -{ - typedef cMineShaft super; - -public: - /** Creates a new Corridor attached to the specified pivot point and direction. - Checks all ParentSystem's objects and disallows intersecting. Initializes the new object to fit. - May return NULL if cannot fit. - */ - static cMineShaft * CreateAndFit( - cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, - int a_PivotX, int a_PivotY, int a_PivotZ, eDirection a_Direction, - cNoise & a_Noise - ); - -protected: - static const int MAX_SEGMENTS = 5; - - int m_NumSegments; - eDirection m_Direction; - bool m_HasFullBeam[MAX_SEGMENTS]; ///< If true, segment at that index has a full beam support (planks in the top center block) - int m_ChestPosition; ///< If <0, no chest; otherwise an offset from m_BoundingBox's p1.x or p1.z, depenging on m_Direction - int m_SpawnerPosition; ///< If <0, no spawner; otherwise an offset from m_BoundingBox's p1.x or p1.z, depenging on m_Direction - bool m_HasTracks; ///< If true, random tracks will be placed on the floor - - cMineShaftCorridor( - cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, - const cCuboid & a_BoundingBox, int a_NumSegments, eDirection a_Direction, - cNoise & a_Noise - ); - - // cMineShaft overrides: - virtual void AppendBranches(int a_RecursionLevel, cNoise & a_Noise) override; - virtual void ProcessChunk(cChunkDesc & a_ChunkDesc) override; - - /// Places a chest, if the corridor has one - void PlaceChest(cChunkDesc & a_ChunkDesc); - - /// If this corridor has tracks, places them randomly - void PlaceTracks(cChunkDesc & a_ChunkDesc); - - /// If this corridor has a spawner, places the spawner - void PlaceSpawner(cChunkDesc & a_ChunkDesc); - - /// Randomly places torches around the central beam block - void PlaceTorches(cChunkDesc & a_ChunkDesc); -} ; - - - - - -class cMineShaftCrossing : - public cMineShaft -{ - typedef cMineShaft super; - -public: - /** Creates a new Crossing attached to the specified pivot point and direction. - Checks all ParentSystem's objects and disallows intersecting. Initializes the new object to fit. - May return NULL if cannot fit. - */ - static cMineShaft * CreateAndFit( - cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, - int a_PivotX, int a_PivotY, int a_PivotZ, eDirection a_Direction, - cNoise & a_Noise - ); - -protected: - cMineShaftCrossing(cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, const cCuboid & a_BoundingBox); - - // cMineShaft overrides: - virtual void AppendBranches(int a_RecursionLevel, cNoise & a_Noise) override; - virtual void ProcessChunk(cChunkDesc & a_ChunkDesc) override; -} ; - - - - - -class cMineShaftStaircase : - public cMineShaft -{ - typedef cMineShaft super; - -public: - enum eSlope - { - sUp, - sDown, - } ; - - /** Creates a new Staircase attached to the specified pivot point and direction. - Checks all ParentSystem's objects and disallows intersecting. Initializes the new object to fit. - May return NULL if cannot fit. - */ - static cMineShaft * CreateAndFit( - cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, - int a_PivotX, int a_PivotY, int a_PivotZ, eDirection a_Direction, - cNoise & a_Noise - ); - -protected: - eDirection m_Direction; - eSlope m_Slope; - - - cMineShaftStaircase( - cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, - const cCuboid & a_BoundingBox, - eDirection a_Direction, - eSlope a_Slope - ); - - // cMineShaft overrides: - virtual void AppendBranches(int a_RecursionLevel, cNoise & a_Noise) override; - virtual void ProcessChunk(cChunkDesc & a_ChunkDesc) override; -} ; - - - - - -class cStructGenMineShafts::cMineShaftSystem -{ -public: - int m_BlockX, m_BlockZ; ///< The pivot point on which the system is generated - int m_GridSize; ///< Maximum offset of the dirtroom from grid center, * 2, in each direction - int m_MaxRecursion; ///< Maximum recursion level (initialized from cStructGenMineShafts::m_MaxRecursion) - int m_ProbLevelCorridor; ///< Probability level of a branch object being the corridor - int m_ProbLevelCrossing; ///< Probability level of a branch object being the crossing, minus Corridor - int m_ProbLevelStaircase; ///< Probability level of a branch object being the staircase, minus Crossing - int m_ChanceChest; ///< Chance [0 .. 250] that a corridor has a chest in it - int m_ChanceSpawner; ///< Chance [0 .. 250] that a corridor has a spawner in it - int m_ChanceTorch; ///< Chance [0 .. 10k] for a torch appearing attached to a corridor's beam - cMineShafts m_MineShafts; ///< List of cMineShaft descendants that comprise this system - cCuboid m_BoundingBox; ///< Bounding box into which all of the components need to fit - - /// Creates and generates the entire system - cMineShaftSystem( - int a_BlockX, int a_BlockZ, int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise, - int a_ProbLevelCorridor, int a_ProbLevelCrossing, int a_ProbLevelStaircase - ); - - ~cMineShaftSystem(); - - /// Carves the system into the chunk data - void ProcessChunk(cChunkDesc & a_Chunk); - - /** Creates new cMineShaft descendant connected at the specified point, heading the specified direction, - if it fits, appends it to the list and calls its AppendBranches() - */ - void AppendBranch( - int a_BlockX, int a_BlockY, int a_BlockZ, - cMineShaft::eDirection a_Direction, cNoise & a_Noise, - int a_RecursionLevel - ); - - /// Returns true if none of the objects in m_MineShafts intersect with the specified bounding box and the bounding box is valid - bool CanAppend(const cCuboid & a_BoundingBox); -} ; - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cStructGenMineShafts::cMineShaftSystem: - -cStructGenMineShafts::cMineShaftSystem::cMineShaftSystem( - int a_BlockX, int a_BlockZ, int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise, - int a_ProbLevelCorridor, int a_ProbLevelCrossing, int a_ProbLevelStaircase -) : - m_BlockX(a_BlockX), - m_BlockZ(a_BlockZ), - m_GridSize(a_GridSize), - m_MaxRecursion(8), // TODO: settable - m_ProbLevelCorridor(a_ProbLevelCorridor), - m_ProbLevelCrossing(a_ProbLevelCrossing), - m_ProbLevelStaircase(a_ProbLevelStaircase + 1), - m_ChanceChest(12), // TODO: settable - m_ChanceSpawner(12), // TODO: settable - m_ChanceTorch(1000) // TODO: settable -{ - m_MineShafts.reserve(100); - - cMineShaft * Start = new cMineShaftDirtRoom(*this, a_Noise); - m_MineShafts.push_back(Start); - - m_BoundingBox.Assign( - Start->m_BoundingBox.p1.x - a_MaxSystemSize / 2, 2, Start->m_BoundingBox.p1.z - a_MaxSystemSize / 2, - Start->m_BoundingBox.p2.x + a_MaxSystemSize / 2, 50, Start->m_BoundingBox.p2.z + a_MaxSystemSize / 2 - ); - - Start->AppendBranches(0, a_Noise); - - for (cMineShafts::const_iterator itr = m_MineShafts.begin(), end = m_MineShafts.end(); itr != end; ++itr) - { - ASSERT((*itr)->m_BoundingBox.IsSorted()); - } // for itr - m_MineShafts[] -} - - - - - -cStructGenMineShafts::cMineShaftSystem::~cMineShaftSystem() -{ - for (cMineShafts::iterator itr = m_MineShafts.begin(), end = m_MineShafts.end(); itr != end; ++itr) - { - delete *itr; - } // for itr - m_MineShafts[] - m_MineShafts.clear(); -} - - - - - -void cStructGenMineShafts::cMineShaftSystem::ProcessChunk(cChunkDesc & a_Chunk) -{ - for (cMineShafts::const_iterator itr = m_MineShafts.begin(), end = m_MineShafts.end(); itr != end; ++itr) - { - (*itr)->ProcessChunk(a_Chunk); - } // for itr - m_MineShafts[] -} - - - - - -void cStructGenMineShafts::cMineShaftSystem::AppendBranch( - int a_PivotX, int a_PivotY, int a_PivotZ, - cMineShaft::eDirection a_Direction, cNoise & a_Noise, - int a_RecursionLevel -) -{ - if (a_RecursionLevel > m_MaxRecursion) - { - return; - } - - cMineShaft * Next = NULL; - int rnd = (a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + a_RecursionLevel * 16, a_PivotZ) / 13) % m_ProbLevelStaircase; - if (rnd < m_ProbLevelCorridor) - { - Next = cMineShaftCorridor::CreateAndFit(*this, a_PivotX, a_PivotY, a_PivotZ, a_Direction, a_Noise); - } - else if (rnd < m_ProbLevelCrossing) - { - Next = cMineShaftCrossing::CreateAndFit(*this, a_PivotX, a_PivotY, a_PivotZ, a_Direction, a_Noise); - } - else - { - Next = cMineShaftStaircase::CreateAndFit(*this, a_PivotX, a_PivotY, a_PivotZ, a_Direction, a_Noise); - } - if (Next == NULL) - { - return; - } - m_MineShafts.push_back(Next); - Next->AppendBranches(a_RecursionLevel + 1, a_Noise); -} - - - - - -bool cStructGenMineShafts::cMineShaftSystem::CanAppend(const cCuboid & a_BoundingBox) -{ - if (!a_BoundingBox.IsCompletelyInside(m_BoundingBox)) - { - // Too far away, or too low / too high - return false; - } - - // Check intersections: - for (cMineShafts::const_iterator itr = m_MineShafts.begin(), end = m_MineShafts.end(); itr != end; ++itr) - { - if ((*itr)->DoesIntersect(a_BoundingBox)) - { - return false; - } - } // for itr - m_MineShafts[] - return true; -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cMineShaftDirtRoom: - -cMineShaftDirtRoom::cMineShaftDirtRoom(cStructGenMineShafts::cMineShaftSystem & a_Parent, cNoise & a_Noise) : - super(a_Parent, mskDirtRoom) -{ - // Make the room of random size, min 10 x 4 x 10; max 18 x 12 x 18: - int rnd = a_Noise.IntNoise3DInt(a_Parent.m_BlockX, 0, a_Parent.m_BlockZ) / 7; - int OfsX = (rnd % a_Parent.m_GridSize) - a_Parent.m_GridSize / 2; - rnd >>= 12; - int OfsZ = (rnd % a_Parent.m_GridSize) - a_Parent.m_GridSize / 2; - rnd = a_Noise.IntNoise3DInt(a_Parent.m_BlockX, 1000, a_Parent.m_BlockZ) / 11; - m_BoundingBox.p1.x = a_Parent.m_BlockX + OfsX; - m_BoundingBox.p2.x = m_BoundingBox.p1.x + 10 + (rnd % 8); - rnd >>= 4; - m_BoundingBox.p1.z = a_Parent.m_BlockZ + OfsZ; - m_BoundingBox.p2.z = m_BoundingBox.p1.z + 10 + (rnd % 8); - rnd >>= 4; - m_BoundingBox.p1.y = 20; - m_BoundingBox.p2.y = 24 + rnd % 8; -} - - - - - -void cMineShaftDirtRoom::AppendBranches(int a_RecursionLevel, cNoise & a_Noise) -{ - int Height = m_BoundingBox.DifY() - 3; - for (int x = m_BoundingBox.p1.x + 1; x < m_BoundingBox.p2.x; x += 4) - { - int rnd = a_Noise.IntNoise3DInt(x, a_RecursionLevel, m_BoundingBox.p1.z) / 7; - m_ParentSystem.AppendBranch(x, m_BoundingBox.p1.y + (rnd % Height), m_BoundingBox.p1.z - 1, dirZM, a_Noise, a_RecursionLevel); - rnd >>= 4; - m_ParentSystem.AppendBranch(x, m_BoundingBox.p1.y + (rnd % Height), m_BoundingBox.p2.z + 1, dirZP, a_Noise, a_RecursionLevel); - } - - for (int z = m_BoundingBox.p1.z + 1; z < m_BoundingBox.p2.z; z += 4) - { - int rnd = a_Noise.IntNoise3DInt(m_BoundingBox.p1.x, a_RecursionLevel, z) / 13; - m_ParentSystem.AppendBranch(m_BoundingBox.p1.x - 1, m_BoundingBox.p1.y + (rnd % Height), z, dirXM, a_Noise, a_RecursionLevel); - rnd >>= 4; - m_ParentSystem.AppendBranch(m_BoundingBox.p2.x + 1, m_BoundingBox.p1.y + (rnd % Height), z, dirXP, a_Noise, a_RecursionLevel); - } -} - - - - - -void cMineShaftDirtRoom::ProcessChunk(cChunkDesc & a_ChunkDesc) -{ - int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; - int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; - if ( - (m_BoundingBox.p1.x > BlockX + cChunkDef::Width) || - (m_BoundingBox.p1.z > BlockZ + cChunkDef::Width) || - (m_BoundingBox.p2.x < BlockX) || - (m_BoundingBox.p2.z < BlockZ) - ) - { - // Early bailout - cannot intersect this chunk - return; - } - - // Chunk-relative coords of the boundaries: - int MinX = std::max(BlockX, m_BoundingBox.p1.x) - BlockX; - int MaxX = std::min(BlockX + cChunkDef::Width, m_BoundingBox.p2.x + 1) - BlockX; - int MinZ = std::max(BlockZ, m_BoundingBox.p1.z) - BlockZ; - int MaxZ = std::min(BlockZ + cChunkDef::Width, m_BoundingBox.p2.z + 1) - BlockZ; - - // Carve the room out: - for (int z = MinZ; z < MaxZ; z++) - { - for (int x = MinX; x < MaxX; x++) - { - for (int y = m_BoundingBox.p1.y + 1; y < m_BoundingBox.p2.y; y++) - { - a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_AIR); - } - if (a_ChunkDesc.GetBlockType(x, m_BoundingBox.p1.y, z) != E_BLOCK_AIR) - { - a_ChunkDesc.SetBlockType(x, m_BoundingBox.p1.y, z, E_BLOCK_DIRT); - } - } // for x - } // for z -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cMineShaftCorridor: - -cMineShaftCorridor::cMineShaftCorridor( - cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, - const cCuboid & a_BoundingBox, int a_NumSegments, eDirection a_Direction, - cNoise & a_Noise -) : - super(a_ParentSystem, mskCorridor, a_BoundingBox), - m_NumSegments(a_NumSegments), - m_Direction(a_Direction), - m_ChestPosition(-1), - m_SpawnerPosition(-1) -{ - int rnd = a_Noise.IntNoise3DInt(a_BoundingBox.p1.x, a_BoundingBox.p1.y, a_BoundingBox.p1.z) / 7; - for (int i = 0; i < a_NumSegments; i++) - { - m_HasFullBeam[i] = (rnd % 4) < 3; // 75 % chance of full beam - rnd >>= 2; - } - m_HasTracks = ((rnd % 4) < 2); // 50 % chance of tracks - - rnd = a_Noise.IntNoise3DInt(a_BoundingBox.p1.z, a_BoundingBox.p1.x, a_BoundingBox.p1.y) / 7; - int ChestCheck = rnd % 250; - rnd >>= 8; - int SpawnerCheck = rnd % 250; - rnd >>= 8; - if (ChestCheck < a_ParentSystem.m_ChanceChest) - { - m_ChestPosition = rnd % (a_NumSegments * 5); - } - if ((a_NumSegments < 4) && (SpawnerCheck < a_ParentSystem.m_ChanceSpawner)) - { - m_SpawnerPosition = rnd % (a_NumSegments * 5); - } -} - - - - - -cMineShaft * cMineShaftCorridor::CreateAndFit( - cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, - int a_PivotX, int a_PivotY, int a_PivotZ, eDirection a_Direction, - cNoise & a_Noise -) -{ - cCuboid BoundingBox(a_PivotX, a_PivotY - 1, a_PivotZ); - BoundingBox.p2.y += 3; - int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7; - int NumSegments = 2 + (rnd) % (MAX_SEGMENTS - 1); // 2 .. MAX_SEGMENTS - switch (a_Direction) - { - case dirXP: BoundingBox.p2.x += NumSegments * 5 - 1; BoundingBox.p1.z -= 1; BoundingBox.p2.z += 1; break; - case dirXM: BoundingBox.p1.x -= NumSegments * 5 - 1; BoundingBox.p1.z -= 1; BoundingBox.p2.z += 1; break; - case dirZP: BoundingBox.p2.z += NumSegments * 5 - 1; BoundingBox.p1.x -= 1; BoundingBox.p2.x += 1; break; - case dirZM: BoundingBox.p1.z -= NumSegments * 5 - 1; BoundingBox.p1.x -= 1; BoundingBox.p2.x += 1; break; - } - if (!a_ParentSystem.CanAppend(BoundingBox)) - { - return NULL; - } - return new cMineShaftCorridor(a_ParentSystem, BoundingBox, NumSegments, a_Direction, a_Noise); -} - - - - - -void cMineShaftCorridor::AppendBranches(int a_RecursionLevel, cNoise & a_Noise) -{ - int rnd = a_Noise.IntNoise3DInt(m_BoundingBox.p1.x, m_BoundingBox.p1.y + a_RecursionLevel, m_BoundingBox.p1.z) / 7; - // Prefer the same height, but allow for up to one block height displacement: - int Height = m_BoundingBox.p1.y + ((rnd % 4) + ((rnd >> 3) % 3)) / 2; - switch (m_Direction) - { - case dirXM: - { - m_ParentSystem.AppendBranch(m_BoundingBox.p1.x - 1, Height, m_BoundingBox.p1.z + 1, dirXM, a_Noise, a_RecursionLevel); - for (int i = m_NumSegments; i >= 0; i--) - { - int rnd = a_Noise.IntNoise3DInt(m_BoundingBox.p1.x + i + 10, m_BoundingBox.p1.y + a_RecursionLevel, m_BoundingBox.p1.z) / 11; - int Height = m_BoundingBox.p1.y + ((rnd % 4) + ((rnd >> 3) % 3)) / 2; - rnd >>= 6; - int Ofs = 1 + rnd % (m_NumSegments * 5 - 2); - m_ParentSystem.AppendBranch(m_BoundingBox.p1.x + Ofs, Height, m_BoundingBox.p1.z - 1, dirZM, a_Noise, a_RecursionLevel); - m_ParentSystem.AppendBranch(m_BoundingBox.p1.x + Ofs, Height, m_BoundingBox.p2.z + 1, dirZP, a_Noise, a_RecursionLevel); - } - break; - } - - case dirXP: - { - m_ParentSystem.AppendBranch(m_BoundingBox.p2.x + 1, Height, m_BoundingBox.p1.z + 1, dirXP, a_Noise, a_RecursionLevel); - for (int i = m_NumSegments; i >= 0; i--) - { - int rnd = a_Noise.IntNoise3DInt(m_BoundingBox.p1.x + i + 10, m_BoundingBox.p1.y + a_RecursionLevel, m_BoundingBox.p1.z) / 11; - int Height = m_BoundingBox.p1.y + ((rnd % 4) + ((rnd >> 3) % 3)) / 2; - rnd >>= 6; - int Ofs = 1 + rnd % (m_NumSegments * 5 - 2); - m_ParentSystem.AppendBranch(m_BoundingBox.p1.x + Ofs, Height, m_BoundingBox.p1.z - 1, dirZM, a_Noise, a_RecursionLevel); - m_ParentSystem.AppendBranch(m_BoundingBox.p1.x + Ofs, Height, m_BoundingBox.p2.z + 1, dirZP, a_Noise, a_RecursionLevel); - } - break; - } - - case dirZM: - { - m_ParentSystem.AppendBranch(m_BoundingBox.p1.x + 1, Height, m_BoundingBox.p1.z - 1, dirZM, a_Noise, a_RecursionLevel); - for (int i = m_NumSegments; i >= 0; i--) - { - int rnd = a_Noise.IntNoise3DInt(m_BoundingBox.p1.x + i + 10, m_BoundingBox.p1.y + a_RecursionLevel, m_BoundingBox.p1.z) / 11; - int Height = m_BoundingBox.p1.y + ((rnd % 4) + ((rnd >> 3) % 3)) / 2; - rnd >>= 6; - int Ofs = 1 + rnd % (m_NumSegments * 5 - 2); - m_ParentSystem.AppendBranch(m_BoundingBox.p1.x - 1, Height, m_BoundingBox.p1.z + Ofs, dirXM, a_Noise, a_RecursionLevel); - m_ParentSystem.AppendBranch(m_BoundingBox.p2.x + 1, Height, m_BoundingBox.p1.z + Ofs, dirXP, a_Noise, a_RecursionLevel); - } - break; - } - - case dirZP: - { - m_ParentSystem.AppendBranch(m_BoundingBox.p1.x + 1, Height, m_BoundingBox.p2.z + 1, dirZP, a_Noise, a_RecursionLevel); - for (int i = m_NumSegments; i >= 0; i--) - { - int rnd = a_Noise.IntNoise3DInt(m_BoundingBox.p1.x + i + 10, m_BoundingBox.p1.y + a_RecursionLevel, m_BoundingBox.p1.z) / 11; - int Height = m_BoundingBox.p1.y + ((rnd % 4) + ((rnd >> 3) % 3)) / 2; - rnd >>= 6; - int Ofs = 1 + rnd % (m_NumSegments * 5 - 2); - m_ParentSystem.AppendBranch(m_BoundingBox.p1.x - 1, Height, m_BoundingBox.p1.z + Ofs, dirXM, a_Noise, a_RecursionLevel); - m_ParentSystem.AppendBranch(m_BoundingBox.p2.x + 1, Height, m_BoundingBox.p1.z + Ofs, dirXP, a_Noise, a_RecursionLevel); - } - break; - } - } // switch (m_Direction) -} - - - - - -void cMineShaftCorridor::ProcessChunk(cChunkDesc & a_ChunkDesc) -{ - int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; - int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; - cCuboid RelBoundingBox(m_BoundingBox); - RelBoundingBox.Move(-BlockX, 0, -BlockZ); - RelBoundingBox.p1.y += 1; - RelBoundingBox.p2.y -= 1; - cCuboid Top(RelBoundingBox); - Top.p2.y += 1; - Top.p1.y = Top.p2.y; - a_ChunkDesc.FillRelCuboid(RelBoundingBox, E_BLOCK_AIR, 0); - a_ChunkDesc.RandomFillRelCuboid(Top, E_BLOCK_AIR, 0, BlockX ^ BlockZ + BlockX, 8000); - if (m_SpawnerPosition >= 0) - { - // Cobwebs around the spider spawner - a_ChunkDesc.RandomFillRelCuboid(RelBoundingBox, E_BLOCK_COBWEB, 0, BlockX ^ BlockZ + BlockZ, 8000); - a_ChunkDesc.RandomFillRelCuboid(Top, E_BLOCK_COBWEB, 0, BlockX ^ BlockZ + BlockX, 5000); - } - a_ChunkDesc.RandomFillRelCuboid(Top, E_BLOCK_COBWEB, 0, BlockX ^ BlockZ + BlockX + 10, 500); - RelBoundingBox.p1.y = m_BoundingBox.p1.y; - RelBoundingBox.p2.y = m_BoundingBox.p1.y; - a_ChunkDesc.FloorRelCuboid(RelBoundingBox, E_BLOCK_PLANKS, 0); - switch (m_Direction) - { - case dirXM: - case dirXP: - { - int y1 = m_BoundingBox.p1.y + 1; - int y2 = m_BoundingBox.p1.y + 2; - int y3 = m_BoundingBox.p1.y + 3; - int z1 = m_BoundingBox.p1.z - BlockZ; - int z2 = m_BoundingBox.p2.z - BlockZ; - for (int i = 0; i < m_NumSegments; i++) - { - int x = m_BoundingBox.p1.x + i * 5 + 2 - BlockX; - if ((x < 0) || (x >= cChunkDef::Width)) - { - continue; - } - if ((z1 >= 0) && (z1 < cChunkDef::Width)) - { - a_ChunkDesc.SetBlockTypeMeta(x, y1, z1, E_BLOCK_FENCE, 0); - a_ChunkDesc.SetBlockTypeMeta(x, y2, z1, E_BLOCK_FENCE, 0); - a_ChunkDesc.SetBlockTypeMeta(x, y3, z1, E_BLOCK_PLANKS, 0); - } - if ((z2 >= 0) && (z2 < cChunkDef::Width)) - { - a_ChunkDesc.SetBlockTypeMeta(x, y1, z2, E_BLOCK_FENCE, 0); - a_ChunkDesc.SetBlockTypeMeta(x, y2, z2, E_BLOCK_FENCE, 0); - a_ChunkDesc.SetBlockTypeMeta(x, y3, z2, E_BLOCK_PLANKS, 0); - } - if ((z1 >= -1) && (z1 < cChunkDef::Width - 1) && m_HasFullBeam[i]) - { - a_ChunkDesc.SetBlockTypeMeta(x, y3, z1 + 1, E_BLOCK_PLANKS, 0); - } - } // for i - NumSegments - break; - } - - case dirZM: - case dirZP: - { - int y1 = m_BoundingBox.p1.y + 1; - int y2 = m_BoundingBox.p1.y + 2; - int y3 = m_BoundingBox.p1.y + 3; - int x1 = m_BoundingBox.p1.x - BlockX; - int x2 = m_BoundingBox.p2.x - BlockX; - for (int i = 0; i < m_NumSegments; i++) - { - int z = m_BoundingBox.p1.z + i * 5 + 2 - BlockZ; - if ((z < 0) || (z >= cChunkDef::Width)) - { - continue; - } - if ((x1 >= 0) && (x1 < cChunkDef::Width)) - { - a_ChunkDesc.SetBlockTypeMeta(x1, y1, z, E_BLOCK_FENCE, 0); - a_ChunkDesc.SetBlockTypeMeta(x1, y2, z, E_BLOCK_FENCE, 0); - a_ChunkDesc.SetBlockTypeMeta(x1, y3, z, E_BLOCK_PLANKS, 0); - } - if ((x2 >= 0) && (x2 < cChunkDef::Width)) - { - a_ChunkDesc.SetBlockTypeMeta(x2, y1, z, E_BLOCK_FENCE, 0); - a_ChunkDesc.SetBlockTypeMeta(x2, y2, z, E_BLOCK_FENCE, 0); - a_ChunkDesc.SetBlockTypeMeta(x2, y3, z, E_BLOCK_PLANKS, 0); - } - if ((x1 >= -1) && (x1 < cChunkDef::Width - 1) && m_HasFullBeam[i]) - { - a_ChunkDesc.SetBlockTypeMeta(x1 + 1, y3, z, E_BLOCK_PLANKS, 0); - } - } // for i - NumSegments - break; - } // case dirZ? - } // for i - - PlaceChest(a_ChunkDesc); - PlaceTracks(a_ChunkDesc); - PlaceSpawner(a_ChunkDesc); // (must be after Tracks!) - PlaceTorches(a_ChunkDesc); -} - - - - - -void cMineShaftCorridor::PlaceChest(cChunkDesc & a_ChunkDesc) -{ - static const cLootProbab LootProbab[] = - { - // Item, MinAmount, MaxAmount, Weight - { cItem(E_ITEM_IRON), 1, 5, 10 }, - { cItem(E_ITEM_GOLD), 1, 3, 5 }, - { cItem(E_ITEM_REDSTONE_DUST), 4, 9, 5 }, - { cItem(E_ITEM_DIAMOND), 1, 2, 3 }, - { cItem(E_ITEM_DYE, 1, 4), 4, 9, 5 }, // lapis lazuli dye - { cItem(E_ITEM_COAL), 3, 8, 10 }, - { cItem(E_ITEM_BREAD), 1, 3, 15 }, - { cItem(E_ITEM_IRON_PICKAXE), 1, 1, 1 }, - { cItem(E_BLOCK_MINECART_TRACKS), 4, 8, 1 }, - { cItem(E_ITEM_MELON_SEEDS), 2, 4, 10 }, - { cItem(E_ITEM_PUMPKIN_SEEDS), 2, 4, 10 }, - } ; - - if (m_ChestPosition < 0) - { - return; - } - - int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; - int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; - int x, z; - NIBBLETYPE Meta = 0; - switch (m_Direction) - { - case dirXM: - case dirXP: - { - x = m_BoundingBox.p1.x + m_ChestPosition - BlockX; - z = m_BoundingBox.p1.z - BlockZ; - Meta = E_META_CHEST_FACING_ZP; - break; - } - - case dirZM: - case dirZP: - { - x = m_BoundingBox.p1.x - BlockX; - z = m_BoundingBox.p1.z + m_ChestPosition - BlockZ; - Meta = E_META_CHEST_FACING_XP; - break; - } - } // switch (Dir) - - if ( - (x >= 0) && (x < cChunkDef::Width) && - (z >= 0) && (z < cChunkDef::Width) - ) - { - a_ChunkDesc.SetBlockTypeMeta(x, m_BoundingBox.p1.y + 1, z, E_BLOCK_CHEST, Meta); - cChestEntity * ChestEntity = (cChestEntity *)a_ChunkDesc.GetBlockEntity(x, m_BoundingBox.p1.y + 1, z); - ASSERT((ChestEntity != NULL) && (ChestEntity->GetBlockType() == E_BLOCK_CHEST)); - cNoise Noise(a_ChunkDesc.GetChunkX() ^ a_ChunkDesc.GetChunkZ()); - int NumSlots = 3 + ((Noise.IntNoise3DInt(x, m_BoundingBox.p1.y, z) / 11) % 4); - int Seed = Noise.IntNoise2DInt(x, z); - ChestEntity->GetContents().GenerateRandomLootWithBooks(LootProbab, ARRAYCOUNT(LootProbab), NumSlots, Seed); - } -} - - - - - -void cMineShaftCorridor::PlaceTracks(cChunkDesc & a_ChunkDesc) -{ - if (!m_HasTracks) - { - return; - } - cCuboid Box(m_BoundingBox); - Box.Move(-a_ChunkDesc.GetChunkX() * cChunkDef::Width, 1, -a_ChunkDesc.GetChunkZ() * cChunkDef::Width); - Box.p2.y = Box.p1.y; - Box.p1.x += 1; - Box.p2.x -= 1; - Box.p1.z += 1; - Box.p2.z -= 1; - NIBBLETYPE Meta = 0; - switch (m_Direction) - { - case dirXM: - case dirXP: - { - Meta = E_META_TRACKS_X; - break; - } - - case dirZM: - case dirZP: - { - Meta = E_META_TRACKS_Z; - break; - } - } // switch (direction) - a_ChunkDesc.RandomFillRelCuboid(Box, E_BLOCK_MINECART_TRACKS, Meta, a_ChunkDesc.GetChunkX() + a_ChunkDesc.GetChunkZ(), 6000); -} - - - - - -void cMineShaftCorridor::PlaceSpawner(cChunkDesc & a_ChunkDesc) -{ - if (m_SpawnerPosition < 0) - { - // No spawner in this corridor - return; - } - int SpawnerRelX = m_BoundingBox.p1.x + 1 - a_ChunkDesc.GetChunkX() * cChunkDef::Width; - int SpawnerRelZ = m_BoundingBox.p1.z + 1 - a_ChunkDesc.GetChunkZ() * cChunkDef::Width; - switch (m_Direction) - { - case dirXM: - case dirXP: - { - SpawnerRelX += m_SpawnerPosition - 1; - break; - } - case dirZM: - case dirZP: - { - SpawnerRelZ += m_SpawnerPosition - 1; - break; - } - } - if ( - (SpawnerRelX >= 0) && (SpawnerRelX < cChunkDef::Width) && - (SpawnerRelZ >= 0) && (SpawnerRelZ < cChunkDef::Width) - ) - { - a_ChunkDesc.SetBlockTypeMeta(SpawnerRelX, m_BoundingBox.p1.y + 1, SpawnerRelZ, E_BLOCK_MOB_SPAWNER, 0); - // TODO: The spawner needs its accompanying cMobSpawnerEntity, when implemented - } -} - - - - - -void cMineShaftCorridor::PlaceTorches(cChunkDesc & a_ChunkDesc) -{ - cNoise Noise(m_BoundingBox.p1.x); - switch (m_Direction) - { - case dirXM: - case dirXP: - { - int z = m_BoundingBox.p1.z + 1 - a_ChunkDesc.GetChunkZ() * cChunkDef::Width; - if ((z < 0) || (z >= cChunkDef::Width)) - { - return; - } - int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; - for (int i = 0; i < m_NumSegments; i++) - { - if (!m_HasFullBeam[i]) - { - continue; - } - int x = m_BoundingBox.p1.x + i * 5 + 1 - BlockX; - if ((x >= 0) && (x < cChunkDef::Width)) - { - if (((Noise.IntNoise2DInt(x, z) / 7) % 10000) < m_ParentSystem.m_ChanceTorch) - { - a_ChunkDesc.SetBlockTypeMeta(x, m_BoundingBox.p2.y, z, E_BLOCK_TORCH, E_META_TORCH_XP); - } - } - x += 2; - if ((x >= 0) && (x < cChunkDef::Width)) - { - if (((Noise.IntNoise2DInt(x, z) / 7) % 10000) < m_ParentSystem.m_ChanceTorch) - { - a_ChunkDesc.SetBlockTypeMeta(x, m_BoundingBox.p2.y, z, E_BLOCK_TORCH, E_META_TORCH_XM); - } - } - } // for i - break; - } - - case dirZM: - case dirZP: - { - int x = m_BoundingBox.p1.x + 1 - a_ChunkDesc.GetChunkX() * cChunkDef::Width; - if ((x < 0) || (x >= cChunkDef::Width)) - { - return; - } - int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; - for (int i = 0; i < m_NumSegments; i++) - { - if (!m_HasFullBeam[i]) - { - continue; - } - int z = m_BoundingBox.p1.z + i * 5 + 1 - BlockZ; - if ((z >= 0) && (z < cChunkDef::Width)) - { - if (((Noise.IntNoise2DInt(x, z) / 7) % 10000) < m_ParentSystem.m_ChanceTorch) - { - a_ChunkDesc.SetBlockTypeMeta(x, m_BoundingBox.p2.y, z, E_BLOCK_TORCH, E_META_TORCH_ZP); - } - } - z += 2; - if ((z >= 0) && (z < cChunkDef::Width)) - { - if (((Noise.IntNoise2DInt(x, z) / 7) % 10000) < m_ParentSystem.m_ChanceTorch) - { - a_ChunkDesc.SetBlockTypeMeta(x, m_BoundingBox.p2.y, z, E_BLOCK_TORCH, E_META_TORCH_ZM); - } - } - } // for i - break; - } - } // switch (direction) -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cMineShaftCrossing: - -cMineShaftCrossing::cMineShaftCrossing(cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, const cCuboid & a_BoundingBox) : - super(a_ParentSystem, mskCrossing, a_BoundingBox) -{ -} - - - - - -cMineShaft * cMineShaftCrossing::CreateAndFit( - cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, - int a_PivotX, int a_PivotY, int a_PivotZ, eDirection a_Direction, - cNoise & a_Noise -) -{ - cCuboid BoundingBox(a_PivotX, a_PivotY - 1, a_PivotZ); - int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7; - BoundingBox.p2.y += 3; - if ((rnd % 4) < 2) - { - // 2-level crossing: - BoundingBox.p2.y += 4; - rnd >>= 2; - if ((rnd % 4) < 2) - { - // This is the higher level: - BoundingBox.p1.y -= 4; - BoundingBox.p2.y -= 4; - } - } - rnd >>= 2; - switch (a_Direction) - { - case dirXP: BoundingBox.p2.x += 4; BoundingBox.p1.z -= 2; BoundingBox.p2.z += 2; break; - case dirXM: BoundingBox.p1.x -= 4; BoundingBox.p1.z -= 2; BoundingBox.p2.z += 2; break; - case dirZP: BoundingBox.p2.z += 4; BoundingBox.p1.x -= 2; BoundingBox.p2.x += 2; break; - case dirZM: BoundingBox.p1.z -= 4; BoundingBox.p1.x -= 2; BoundingBox.p2.x += 2; break; - } - if (!a_ParentSystem.CanAppend(BoundingBox)) - { - return NULL; - } - return new cMineShaftCrossing(a_ParentSystem, BoundingBox); -} - - - - - -void cMineShaftCrossing::AppendBranches(int a_RecursionLevel, cNoise & a_Noise) -{ - struct - { - int x, y, z; - eDirection dir; - } Exits[] = - { - // Bottom level: - {-1, 1, 2, dirXM}, - { 2, 1, -1, dirZM}, - { 5, 1, 2, dirXP}, - { 2, 1, 5, dirZP}, - // Top level: - {-1, 5, 2, dirXM}, - { 2, 5, -1, dirZM}, - { 5, 5, 2, dirXP}, - { 2, 5, 5, dirZP}, - } ; - for (int i = 0; i < ARRAYCOUNT(Exits); i++) - { - if (m_BoundingBox.p1.y + Exits[i].y >= m_BoundingBox.p2.y) - { - // This exit is not available (two-level exit on a one-level crossing) - continue; - } - - int Height = m_BoundingBox.p1.y + Exits[i].y; - m_ParentSystem.AppendBranch(m_BoundingBox.p1.x + Exits[i].x, Height, m_BoundingBox.p1.z + Exits[i].z, Exits[i].dir, a_Noise, a_RecursionLevel); - } // for i -} - - - - - -void cMineShaftCrossing::ProcessChunk(cChunkDesc & a_ChunkDesc) -{ - int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; - int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; - cCuboid box(m_BoundingBox); - box.Move(-BlockX, 0, -BlockZ); - if ((box.p2.x < 0) || (box.p2.z < 0) || (box.p1.x >= cChunkDef::Width) || (box.p1.z > cChunkDef::Width)) - { - // Does not intersect this chunk - return; - } - int Floor = box.p1.y + 1; - int Ceil = box.p2.y; - - // The supports: - a_ChunkDesc.FillRelCuboid(box.p1.x + 1, box.p1.x + 1, Floor, Ceil, box.p1.z + 1, box.p1.z + 1, E_BLOCK_PLANKS, 0); - a_ChunkDesc.FillRelCuboid(box.p2.x - 1, box.p2.x - 1, Floor, Ceil, box.p1.z + 1, box.p1.z + 1, E_BLOCK_PLANKS, 0); - a_ChunkDesc.FillRelCuboid(box.p1.x + 1, box.p1.x + 1, Floor, Ceil, box.p2.z - 1, box.p2.z - 1, E_BLOCK_PLANKS, 0); - a_ChunkDesc.FillRelCuboid(box.p2.x - 1, box.p2.x - 1, Floor, Ceil, box.p2.z - 1, box.p2.z - 1, E_BLOCK_PLANKS, 0); - - // The air in between: - a_ChunkDesc.FillRelCuboid(box.p1.x + 2, box.p1.x + 2, Floor, Ceil, box.p1.z + 1, box.p2.z - 1, E_BLOCK_AIR, 0); - a_ChunkDesc.FillRelCuboid(box.p1.x + 1, box.p2.x - 1, Floor, Ceil, box.p1.z + 2, box.p1.z + 2, E_BLOCK_AIR, 0); - - // The air on the edges: - int Mid = Floor + 2; - a_ChunkDesc.FillRelCuboid(box.p1.x, box.p1.x, Floor, Mid, box.p1.z + 1, box.p2.z - 1, E_BLOCK_AIR, 0); - a_ChunkDesc.FillRelCuboid(box.p2.x, box.p2.x, Floor, Mid, box.p1.z + 1, box.p2.z - 1, E_BLOCK_AIR, 0); - a_ChunkDesc.FillRelCuboid(box.p1.x + 1, box.p2.x - 1, Floor, Mid, box.p1.z, box.p1.z, E_BLOCK_AIR, 0); - a_ChunkDesc.FillRelCuboid(box.p1.x + 1, box.p2.x - 1, Floor, Mid, box.p2.z, box.p2.z, E_BLOCK_AIR, 0); - Mid += 2; - if (Mid < Ceil) - { - a_ChunkDesc.FillRelCuboid(box.p1.x, box.p1.x, Mid, Ceil, box.p1.z + 1, box.p2.z - 1, E_BLOCK_AIR, 0); - a_ChunkDesc.FillRelCuboid(box.p2.x, box.p2.x, Mid, Ceil, box.p1.z + 1, box.p2.z - 1, E_BLOCK_AIR, 0); - a_ChunkDesc.FillRelCuboid(box.p1.x + 1, box.p2.x - 1, Mid, Ceil, box.p1.z, box.p1.z, E_BLOCK_AIR, 0); - a_ChunkDesc.FillRelCuboid(box.p1.x + 1, box.p2.x - 1, Mid, Ceil, box.p2.z, box.p2.z, E_BLOCK_AIR, 0); - } - - // The floor, if needed: - box.p2.y = box.p1.y; - a_ChunkDesc.FloorRelCuboid(box, E_BLOCK_PLANKS, 0); -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cMineShaftStaircase: - -cMineShaftStaircase::cMineShaftStaircase( - cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, - const cCuboid & a_BoundingBox, - eDirection a_Direction, - eSlope a_Slope -) : - super(a_ParentSystem, mskStaircase, a_BoundingBox), - m_Direction(a_Direction), - m_Slope(a_Slope) -{ -} - - - - - -cMineShaft * cMineShaftStaircase::CreateAndFit( - cStructGenMineShafts::cMineShaftSystem & a_ParentSystem, - int a_PivotX, int a_PivotY, int a_PivotZ, eDirection a_Direction, - cNoise & a_Noise -) -{ - int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7; - cCuboid Box; - switch (a_Direction) - { - case dirXM: - { - Box.Assign(a_PivotX - 7, a_PivotY - 1, a_PivotZ - 1, a_PivotX, a_PivotY + 6, a_PivotZ + 1); - break; - } - case dirXP: - { - Box.Assign(a_PivotX, a_PivotY - 1, a_PivotZ - 1, a_PivotX + 7, a_PivotY + 6, a_PivotZ + 1); - break; - } - case dirZM: - { - Box.Assign(a_PivotX - 1, a_PivotY - 1, a_PivotZ - 7, a_PivotX + 1, a_PivotY + 6, a_PivotZ); - break; - } - case dirZP: - { - Box.Assign(a_PivotX - 1, a_PivotY - 1, a_PivotZ, a_PivotX + 1, a_PivotY + 6, a_PivotZ + 7); - break; - } - } - eSlope Slope = sUp; - if ((rnd % 4) < 2) // 50 % - { - Slope = sDown; - Box.Move(0, -4, 0); - } - if (!a_ParentSystem.CanAppend(Box)) - { - return NULL; - } - return new cMineShaftStaircase(a_ParentSystem, Box, a_Direction, Slope); -} - - - - - -void cMineShaftStaircase::AppendBranches(int a_RecursionLevel, cNoise & a_Noise) -{ - int Height = m_BoundingBox.p1.y + ((m_Slope == sDown) ? 1 : 5); - switch (m_Direction) - { - case dirXM: m_ParentSystem.AppendBranch(m_BoundingBox.p1.x - 1, Height, m_BoundingBox.p1.z + 1, dirXM, a_Noise, a_RecursionLevel); break; - case dirXP: m_ParentSystem.AppendBranch(m_BoundingBox.p2.x + 1, Height, m_BoundingBox.p1.z + 1, dirXP, a_Noise, a_RecursionLevel); break; - case dirZM: m_ParentSystem.AppendBranch(m_BoundingBox.p1.x + 1, Height, m_BoundingBox.p1.z - 1, dirZM, a_Noise, a_RecursionLevel); break; - case dirZP: m_ParentSystem.AppendBranch(m_BoundingBox.p1.x + 1, Height, m_BoundingBox.p2.z + 1, dirZP, a_Noise, a_RecursionLevel); break; - } -} - - - - - -void cMineShaftStaircase::ProcessChunk(cChunkDesc & a_ChunkDesc) -{ - int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; - int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; - cCuboid RelB(m_BoundingBox); - RelB.Move(-BlockX, 0, -BlockZ); - if ( - (RelB.p1.x >= cChunkDef::Width) || - (RelB.p1.z >= cChunkDef::Width) || - (RelB.p2.x < 0) || - (RelB.p2.z < 0) - ) - { - // No intersection between this staircase and this chunk - return; - } - - int SFloor = RelB.p1.y + ((m_Slope == sDown) ? 5 : 1); - int DFloor = RelB.p1.y + ((m_Slope == sDown) ? 1 : 5); - int Add = (m_Slope == sDown) ? -1 : 1; - int InitAdd = (m_Slope == sDown) ? -1 : 0; - cCuboid Box; - switch (m_Direction) - { - case dirXM: - { - a_ChunkDesc.FillRelCuboid (RelB.p2.x - 1, RelB.p2.x, SFloor, SFloor + 2, RelB.p1.z, RelB.p2.z, E_BLOCK_AIR, 0); - a_ChunkDesc.FillRelCuboid (RelB.p1.x, RelB.p1.x + 1, DFloor, DFloor + 2, RelB.p1.z, RelB.p2.z, E_BLOCK_AIR, 0); - a_ChunkDesc.FloorRelCuboid(RelB.p2.x - 1, RelB.p2.x, SFloor - 1, SFloor - 1, RelB.p1.z, RelB.p2.z, E_BLOCK_PLANKS, 0); - a_ChunkDesc.FloorRelCuboid(RelB.p1.x, RelB.p1.x + 1, DFloor - 1, DFloor - 1, RelB.p1.z, RelB.p2.z, E_BLOCK_PLANKS, 0); - Box.Assign(RelB.p2.x - 2, SFloor + InitAdd, RelB.p1.z, RelB.p2.x - 2, SFloor + 3 + InitAdd, RelB.p2.z); - for (int i = 0; i < 4; i++) - { - a_ChunkDesc.FillRelCuboid(Box, E_BLOCK_AIR, 0); - a_ChunkDesc.FloorRelCuboid(Box.p1.x, Box.p2.x, Box.p1.y - 1, Box.p1.y - 1, Box.p1.z, Box.p2.z, E_BLOCK_PLANKS, 0); - Box.Move(-1, Add, 0); - } - break; - } - - case dirXP: - { - a_ChunkDesc.FillRelCuboid (RelB.p1.x, RelB.p1.x + 1, SFloor, SFloor + 2, RelB.p1.z, RelB.p2.z, E_BLOCK_AIR, 0); - a_ChunkDesc.FillRelCuboid (RelB.p2.x - 1, RelB.p2.x, DFloor, DFloor + 2, RelB.p1.z, RelB.p2.z, E_BLOCK_AIR, 0); - a_ChunkDesc.FloorRelCuboid(RelB.p1.x, RelB.p1.x + 1, SFloor - 1, SFloor - 1, RelB.p1.z, RelB.p2.z, E_BLOCK_PLANKS, 0); - a_ChunkDesc.FloorRelCuboid(RelB.p2.x - 1, RelB.p2.x, DFloor - 1, DFloor - 1, RelB.p1.z, RelB.p2.z, E_BLOCK_PLANKS, 0); - Box.Assign(RelB.p1.x + 2, SFloor + InitAdd, RelB.p1.z, RelB.p1.x + 2, SFloor + 3 + InitAdd, RelB.p2.z); - for (int i = 0; i < 4; i++) - { - a_ChunkDesc.FillRelCuboid(Box, E_BLOCK_AIR, 0); - a_ChunkDesc.FloorRelCuboid(Box.p1.x, Box.p2.x, Box.p1.y - 1, Box.p1.y - 1, Box.p1.z, Box.p2.z, E_BLOCK_PLANKS, 0); - Box.Move(1, Add, 0); - } - break; - } - - case dirZM: - { - a_ChunkDesc.FillRelCuboid (RelB.p1.x, RelB.p2.x, SFloor, SFloor + 2, RelB.p2.z - 1, RelB.p2.z, E_BLOCK_AIR, 0); - a_ChunkDesc.FillRelCuboid (RelB.p1.x, RelB.p2.x, DFloor, DFloor + 2, RelB.p1.z, RelB.p1.z + 1, E_BLOCK_AIR, 0); - a_ChunkDesc.FloorRelCuboid(RelB.p1.x, RelB.p2.x, SFloor - 1, SFloor - 1, RelB.p2.z - 1, RelB.p2.z, E_BLOCK_PLANKS, 0); - a_ChunkDesc.FloorRelCuboid(RelB.p1.x, RelB.p2.x, DFloor - 1, DFloor - 1, RelB.p1.z, RelB.p1.z + 1, E_BLOCK_PLANKS, 0); - Box.Assign(RelB.p1.x, SFloor + InitAdd, RelB.p2.z - 2, RelB.p2.x, SFloor + 3 + InitAdd, RelB.p2.z - 2); - for (int i = 0; i < 4; i++) - { - a_ChunkDesc.FillRelCuboid(Box, E_BLOCK_AIR, 0); - a_ChunkDesc.FloorRelCuboid(Box.p1.x, Box.p2.x, Box.p1.y - 1, Box.p1.y - 1, Box.p1.z, Box.p2.z, E_BLOCK_PLANKS, 0); - Box.Move(0, Add, -1); - } - break; - } - - case dirZP: - { - a_ChunkDesc.FillRelCuboid (RelB.p1.x, RelB.p2.x, SFloor, SFloor + 2, RelB.p1.z, RelB.p1.z + 1, E_BLOCK_AIR, 0); - a_ChunkDesc.FillRelCuboid (RelB.p1.x, RelB.p2.x, DFloor, DFloor + 2, RelB.p2.z - 1, RelB.p2.z, E_BLOCK_AIR, 0); - a_ChunkDesc.FloorRelCuboid(RelB.p1.x, RelB.p2.x, SFloor - 1, SFloor - 1, RelB.p1.z, RelB.p1.z + 1, E_BLOCK_PLANKS, 0); - a_ChunkDesc.FloorRelCuboid(RelB.p1.x, RelB.p2.x, DFloor - 1, DFloor - 1, RelB.p2.z - 1, RelB.p2.z, E_BLOCK_PLANKS, 0); - Box.Assign(RelB.p1.x, SFloor + InitAdd, RelB.p1.z + 2, RelB.p2.x, SFloor + 3 + InitAdd, RelB.p1.z + 2); - for (int i = 0; i < 4; i++) - { - a_ChunkDesc.FillRelCuboid(Box, E_BLOCK_AIR, 0); - a_ChunkDesc.FloorRelCuboid(Box.p1.x, Box.p2.x, Box.p1.y - 1, Box.p1.y - 1, Box.p1.z, Box.p2.z, E_BLOCK_PLANKS, 0); - Box.Move(0, Add, 1); - } - break; - } - - } // switch (m_Direction) -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cStructGenMineShafts: - -cStructGenMineShafts::cStructGenMineShafts( - int a_Seed, int a_GridSize, int a_MaxSystemSize, - int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase -) : - m_Noise(a_Seed), - m_GridSize(a_GridSize), - m_MaxSystemSize(a_MaxSystemSize), - m_ProbLevelCorridor(std::max(0, a_ChanceCorridor)), - m_ProbLevelCrossing(std::max(0, a_ChanceCorridor + a_ChanceCrossing)), - m_ProbLevelStaircase(std::max(0, a_ChanceCorridor + a_ChanceCrossing + a_ChanceStaircase)) -{ -} - - - - - -cStructGenMineShafts::~cStructGenMineShafts() -{ - ClearCache(); -} - - - - - -void cStructGenMineShafts::ClearCache(void) -{ - for (cMineShaftSystems::const_iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end; ++itr) - { - delete *itr; - } // for itr - m_Cache[] - m_Cache.clear(); -} - - - - - -void cStructGenMineShafts::GetMineShaftSystemsForChunk( - int a_ChunkX, int a_ChunkZ, - cStructGenMineShafts::cMineShaftSystems & a_MineShafts -) -{ - int BaseX = a_ChunkX * cChunkDef::Width / m_GridSize; - int BaseZ = a_ChunkZ * cChunkDef::Width / m_GridSize; - if (BaseX < 0) - { - --BaseX; - } - if (BaseZ < 0) - { - --BaseZ; - } - BaseX -= NEIGHBORHOOD_SIZE / 2; - BaseZ -= NEIGHBORHOOD_SIZE / 2; - - // Walk the cache, move each cave system that we want into a_Caves: - int StartX = BaseX * m_GridSize; - int EndX = (BaseX + NEIGHBORHOOD_SIZE + 1) * m_GridSize; - int StartZ = BaseZ * m_GridSize; - int EndZ = (BaseZ + NEIGHBORHOOD_SIZE + 1) * m_GridSize; - for (cMineShaftSystems::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;) - { - if ( - ((*itr)->m_BlockX >= StartX) && ((*itr)->m_BlockX < EndX) && - ((*itr)->m_BlockZ >= StartZ) && ((*itr)->m_BlockZ < EndZ) - ) - { - // want - a_MineShafts.push_back(*itr); - itr = m_Cache.erase(itr); - } - else - { - // don't want - ++itr; - } - } // for itr - m_Cache[] - - for (int x = 0; x < NEIGHBORHOOD_SIZE; x++) - { - int RealX = (BaseX + x) * m_GridSize; - for (int z = 0; z < NEIGHBORHOOD_SIZE; z++) - { - int RealZ = (BaseZ + z) * m_GridSize; - bool Found = false; - for (cMineShaftSystems::const_iterator itr = a_MineShafts.begin(), end = a_MineShafts.end(); itr != end; ++itr) - { - if (((*itr)->m_BlockX == RealX) && ((*itr)->m_BlockZ == RealZ)) - { - Found = true; - break; - } - } // for itr - a_Mineshafts - if (!Found) - { - a_MineShafts.push_back(new cMineShaftSystem(RealX, RealZ, m_GridSize, m_MaxSystemSize, m_Noise, m_ProbLevelCorridor, m_ProbLevelCrossing, m_ProbLevelStaircase)); - } - } // for z - } // for x - - // Copy a_MineShafts into m_Cache to the beginning: - cMineShaftSystems MineShaftsCopy(a_MineShafts); - m_Cache.splice(m_Cache.begin(), MineShaftsCopy, MineShaftsCopy.begin(), MineShaftsCopy.end()); - - // Trim the cache if it's too long: - if (m_Cache.size() > 100) - { - cMineShaftSystems::iterator itr = m_Cache.begin(); - std::advance(itr, 100); - for (cMineShaftSystems::iterator end = m_Cache.end(); itr != end; ++itr) - { - delete *itr; - } - itr = m_Cache.begin(); - std::advance(itr, 100); - m_Cache.erase(itr, m_Cache.end()); - } -} - - - - - - -void cStructGenMineShafts::GenStructures(cChunkDesc & a_ChunkDesc) -{ - int ChunkX = a_ChunkDesc.GetChunkX(); - int ChunkZ = a_ChunkDesc.GetChunkZ(); - cMineShaftSystems MineShafts; - GetMineShaftSystemsForChunk(ChunkX, ChunkZ, MineShafts); - for (cMineShaftSystems::const_iterator itr = MineShafts.begin(); itr != MineShafts.end(); ++itr) - { - (*itr)->ProcessChunk(a_ChunkDesc); - } // for itr - MineShafts[] -} - - - - |