summaryrefslogtreecommitdiffstats
path: root/src/World.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/World.cpp')
-rw-r--r--src/World.cpp70
1 files changed, 65 insertions, 5 deletions
diff --git a/src/World.cpp b/src/World.cpp
index 474f77b81..f3837eb02 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -667,18 +667,23 @@ void cWorld::Start(void)
void cWorld::GenerateRandomSpawn(void)
{
LOGD("Generating random spawnpoint...");
-
+ bool foundSpawnPoint = false;
// Look for a spawn point at most 100 chunks away from map center:
for (int i = 0; i < 100; i++)
{
EMCSBiome biome = GetBiomeAt((int)m_SpawnX, (int)m_SpawnZ);
+
if (
(biome != biOcean) && (biome != biFrozenOcean) && // The biome is acceptable (don't want a small ocean island)
!IsBlockWaterOrIce(GetBlock((int)m_SpawnX, GetHeight((int)m_SpawnX, (int)m_SpawnZ), (int)m_SpawnZ)) // The terrain is acceptable (don't want to spawn inside a lake / river)
)
{
- // A good spawnpoint was found
- break;
+ if (CheckPlayerSpawnPoint((int)m_SpawnX, GetHeight((int)m_SpawnX, (int)m_SpawnZ), (int)m_SpawnZ))
+ {
+ // A good spawnpoint was found
+ foundSpawnPoint = true;
+ break;
+ }
}
// Try a neighboring chunk:
if ((GetTickRandomNumber(4) % 2) == 0) // Randomise whether to increment X or Z coords
@@ -692,8 +697,63 @@ void cWorld::GenerateRandomSpawn(void)
} // for i - 100*
m_SpawnY = (double)GetHeight((int)m_SpawnX, (int)m_SpawnZ) + 1.6f; // 1.6f to accomodate player height
+ if (foundSpawnPoint)
+ {
+ LOGINFO("Generated random spawnpoint position at {%i, %i, %i}", (int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ);
+ }
+ else
+ {
+ LOGINFO("Did not find an acceptable spawnpoint. Generated a random spawnpoint position at {%i, %i, %i}", (int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ);
+ } // Maybe widen the search instead?
+
+}
+
+
+
+
+
+bool cWorld::CheckPlayerSpawnPoint(int a_PosX, int a_PosY, int a_PosZ)
+{
+ static const struct
+ {
+ int x, z;
+ } Coords[] =
+ {
+ { 0, 0 },
+ { -1, 0 },
+ { 1, 0 },
+ { 0, -1 },
+ { 0, 1 },
+ };
+
+ // Checking that spawnblock and surrounding blocks are air and not water/lava
+ for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
+ {
+ BLOCKTYPE BlockType = GetBlock(a_PosX + Coords[i].x, a_PosY, a_PosZ + Coords[i].x);
+
+ if (cBlockInfo::IsSolid(BlockType) || IsBlockLiquid(BlockType))
+ {
+ return false;
+ }
+ } // for i - Coords[]
+
+ // Check if block below is solid
+ BLOCKTYPE BlockType = GetBlock(a_PosX, a_PosY - 1, a_PosZ);
+ if (!cBlockInfo::IsSolid(BlockType))
+ {
+ return false;
+ }
- LOGINFO("Generated random spawnpoint position {%i, %i, %i}", (int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ);
+ // Checking that all the blocks above the spawnpoint is air.
+ for (int i = a_PosY; i < cChunkDef::Height; i++)
+ {
+ BLOCKTYPE BlockType = GetBlock(a_PosX, i, a_PosZ);
+ if (cBlockInfo::IsSolid(BlockType))
+ {
+ return false;
+ }
+ }
+ return true;
}
@@ -3578,7 +3638,7 @@ void cWorld::cTaskUnloadUnusedChunks::Run(cWorld & a_World)
////////////////////////////////////////////////////////////////////////////////
-// cWorld::cTaskSendBlockTo
+// cWorld::cTaskSendBlockToAllPlayers
cWorld::cTaskSendBlockToAllPlayers::cTaskSendBlockToAllPlayers(std::vector<Vector3i> & a_SendQueue) :
m_SendQueue(a_SendQueue)