summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-02-21 17:27:30 +0100
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-02-21 17:27:30 +0100
commitb653e6a01271c05bdbd947ab7120d10d30ecee91 (patch)
tree43d7a6e5ce26b77d1c759a8dc0cc533a13a933e7 /source
parentFixed heightmap optimization from rev 302; removed a few more cChunkPtrs (diff)
downloadcuberite-b653e6a01271c05bdbd947ab7120d10d30ecee91.tar
cuberite-b653e6a01271c05bdbd947ab7120d10d30ecee91.tar.gz
cuberite-b653e6a01271c05bdbd947ab7120d10d30ecee91.tar.bz2
cuberite-b653e6a01271c05bdbd947ab7120d10d30ecee91.tar.lz
cuberite-b653e6a01271c05bdbd947ab7120d10d30ecee91.tar.xz
cuberite-b653e6a01271c05bdbd947ab7120d10d30ecee91.tar.zst
cuberite-b653e6a01271c05bdbd947ab7120d10d30ecee91.zip
Diffstat (limited to 'source')
-rw-r--r--source/Bindings.cpp6
-rw-r--r--source/cChunk.cpp11
-rw-r--r--source/cChunk.h10
-rw-r--r--source/cChunkMap.cpp143
-rw-r--r--source/cChunkMap.h22
-rw-r--r--source/cClientHandle.cpp21
-rw-r--r--source/cPickup.cpp2
-rw-r--r--source/cSignEntity.cpp2
-rw-r--r--source/cWorld.cpp109
-rw-r--r--source/cWorld.h14
10 files changed, 231 insertions, 109 deletions
diff --git a/source/Bindings.cpp b/source/Bindings.cpp
index a8d99330f..21e6ecdb9 100644
--- a/source/Bindings.cpp
+++ b/source/Bindings.cpp
@@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
-** Generated automatically by tolua++-1.0.92 on 02/16/12 18:16:16.
+** Generated automatically by tolua++-1.0.92 on 02/21/12 17:01:49.
*/
#ifndef __cplusplus
@@ -9508,7 +9508,7 @@ static int tolua_AllToLua_cWorld_GetHeight00(lua_State* tolua_S)
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHeight'", NULL);
#endif
{
- char tolua_ret = (char) self->GetHeight(a_X,a_Z);
+ int tolua_ret = (int) self->GetHeight(a_X,a_Z);
tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
}
}
@@ -9984,7 +9984,7 @@ static int tolua_AllToLua_cWorld_GetBlockEntity00(lua_State* tolua_S)
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetBlockEntity'", NULL);
#endif
{
- cBlockEntity* tolua_ret = (cBlockEntity*) self->GetBlockEntity(a_X,a_Y,a_Z);
+ OBSOLETE cBlockEntity* tolua_ret = (OBSOLETE cBlockEntity*) self->GetBlockEntity(a_X,a_Y,a_Z);
tolua_pushusertype(tolua_S,(void*)tolua_ret,"cBlockEntity");
}
}
diff --git a/source/cChunk.cpp b/source/cChunk.cpp
index a783e30b4..c8ba8ba4c 100644
--- a/source/cChunk.cpp
+++ b/source/cChunk.cpp
@@ -67,7 +67,7 @@ sSetBlock::sSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockM
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cChunk:
-cChunk::cChunk(int a_X, int a_Y, int a_Z, cWorld * a_World)
+cChunk::cChunk(int a_X, int a_Y, int a_Z, cChunkMap * a_ChunkMap, cWorld * a_World)
: m_bCalculateLighting( false )
, m_bCalculateHeightmap( false )
, m_PosX( a_X )
@@ -82,6 +82,7 @@ cChunk::cChunk(int a_X, int a_Y, int a_Z, cWorld * a_World)
, m_BlockTickY( 0 )
, m_BlockTickZ( 0 )
, m_World( a_World )
+ , m_ChunkMap(a_ChunkMap)
, m_IsValid(false)
, m_IsDirty(false)
, m_IsSaving(false)
@@ -700,8 +701,8 @@ void cChunk::SpreadLight(char* a_LightBuffer)
bCalcLeft = bCalcRight = bCalcFront = bCalcBack = false;
// Spread to neighbour chunks X-axis
- cChunkPtr LeftChunk = m_World->GetChunkNoGen( m_PosX - 1, m_PosY, m_PosZ );
- cChunkPtr RightChunk = m_World->GetChunkNoGen( m_PosX + 1, m_PosY, m_PosZ );
+ cChunkPtr LeftChunk = m_ChunkMap->GetChunkNoGen( m_PosX - 1, m_PosY, m_PosZ );
+ cChunkPtr RightChunk = m_ChunkMap->GetChunkNoGen( m_PosX + 1, m_PosY, m_PosZ );
char * LeftSky = NULL, *RightSky = NULL;
if (LeftChunk->IsValid())
{
@@ -745,8 +746,8 @@ void cChunk::SpreadLight(char* a_LightBuffer)
}
// Spread to neighbour chunks Z-axis
- cChunkPtr FrontChunk = m_World->GetChunkNoGen( m_PosX, m_PosY, m_PosZ - 1 );
- cChunkPtr BackChunk = m_World->GetChunkNoGen( m_PosX, m_PosY, m_PosZ + 1 );
+ cChunkPtr FrontChunk = m_ChunkMap->GetChunkNoGen( m_PosX, m_PosY, m_PosZ - 1 );
+ cChunkPtr BackChunk = m_ChunkMap->GetChunkNoGen( m_PosX, m_PosY, m_PosZ + 1 );
char * FrontSky = NULL, * BackSky = NULL;
if (FrontChunk->IsValid())
{
diff --git a/source/cChunk.h b/source/cChunk.h
index bbeb2f1b4..2fec4bcbe 100644
--- a/source/cChunk.h
+++ b/source/cChunk.h
@@ -46,10 +46,15 @@ class cClientHandle;
class cServer;
class MTRand;
class cPlayer;
+class cChunkMap;
typedef std::list<cClientHandle *> cClientHandleList;
typedef std::list<cBlockEntity *> cBlockEntityList;
+
+
+
+
/** Interface class used for getting data out of a chunk using the GetAllData() function.
Implementation must use the pointers immediately and NOT store any of them for later use
*/
@@ -108,7 +113,7 @@ public:
static const int c_NumBlocks = 16 * 128 * 16;
static const int c_BlockDataSize = c_NumBlocks * 2 + (c_NumBlocks/2); // 2.5 * numblocks
- cChunk(int a_X, int a_Y, int a_Z, cWorld* a_World);
+ cChunk(int a_X, int a_Y, int a_Z, cChunkMap * a_ChunkMap, cWorld * a_World);
~cChunk();
bool IsValid(void) const {return m_IsValid; } // Returns true if the chunk is valid (loaded / generated)
@@ -248,7 +253,8 @@ private:
bool m_bCalculateHeightmap;
int m_PosX, m_PosY, m_PosZ;
- cWorld * m_World;
+ cWorld * m_World;
+ cChunkMap * m_ChunkMap;
char m_BlockData[c_BlockDataSize]; // Chunk data ready to be compressed and sent
char *m_BlockType; // Pointers to an element in m_BlockData
diff --git a/source/cChunkMap.cpp b/source/cChunkMap.cpp
index 2621e0793..21b99873f 100644
--- a/source/cChunkMap.cpp
+++ b/source/cChunkMap.cpp
@@ -2,11 +2,13 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "cChunkMap.h"
-#include "cChunk.h"
#include "cWorld.h"
#include "cRoot.h"
#include "cMakeDir.h"
#include "cPlayer.h"
+#include "BlockID.h"
+#include "cItem.h"
+#include "cPickup.h"
#ifndef _WIN32
#include <cstdlib> // abs
@@ -19,6 +21,17 @@
+#define RECI_RAND_MAX (1.f/RAND_MAX)
+inline float fRadRand( float a_Radius )
+{
+ MTRand r1;
+ return ((float)r1.rand() * RECI_RAND_MAX)*a_Radius - a_Radius*0.5f;
+}
+
+
+
+
+
////////////////////////////////////////////////////////////////////////////////
// cChunkMap:
@@ -479,6 +492,88 @@ char cChunkMap::GetBlockMeta(int a_X, int a_Y, int a_Z)
+void cChunkMap::SetBlockMeta(int a_X, int a_Y, int a_Z, char a_BlockMeta)
+{
+ int ChunkX, ChunkZ;
+ AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ );
+
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
+ if ((Chunk != NULL) && Chunk->IsValid() )
+ {
+ // Although it is called SetLight(), it actually sets meta when passed the Meta field
+ Chunk->SetLight( Chunk->pGetMeta(), a_X, a_Y, a_Z, a_BlockMeta );
+ Chunk->SendBlockTo( a_X, a_Y, a_Z, NULL );
+ }
+}
+
+
+
+
+
+void cChunkMap::SetBlock(int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta)
+{
+ int ChunkX, ChunkZ, X = a_X, Y = a_Y, Z = a_Z;
+ AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ );
+
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
+ if ((Chunk != NULL) && Chunk->IsValid())
+ {
+ Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta );
+ }
+}
+
+
+
+
+
+bool cChunkMap::DigBlock(int a_X, int a_Y, int a_Z, cItem & a_PickupItem)
+{
+ int PosX = a_X, PosY = a_Y, PosZ = a_Z, ChunkX, ChunkZ;
+
+ AbsoluteToRelative( PosX, PosY, PosZ, ChunkX, ChunkZ );
+
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr DestChunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
+ if ((DestChunk == NULL) || !DestChunk->IsValid())
+ {
+ return false;
+ }
+
+ DestChunk->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, 0 );
+
+ m_World->GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z);
+
+ if ( !a_PickupItem.IsEmpty() )
+ {
+ cPickup * Pickup = new cPickup( a_X * 32 + 16 + (int)fRadRand(16.f), a_Y * 32 + 16 + (int)fRadRand(16.f), a_Z * 32 + 16 + (int)fRadRand(16.f), a_PickupItem );
+ Pickup->Initialize(m_World);
+ }
+ return true;
+}
+
+
+
+
+
+void cChunkMap::SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player)
+{
+ int ChunkX, ChunkZ;
+ AbsoluteToRelative(a_X, a_Y, a_Z, ChunkX, ChunkZ);
+
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ);
+ if (Chunk->IsValid())
+ {
+ Chunk->SendBlockTo(a_X, a_Y, a_Z, a_Player->GetClientHandle());
+ }
+}
+
+
+
+
+
void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback)
{
cCSLock Lock(m_CSLayers);
@@ -552,6 +647,21 @@ bool cChunkMap::AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClient
+void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
+{
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
+ if (Chunk == NULL)
+ {
+ return;
+ }
+ Chunk->RemoveClient(a_Client);
+}
+
+
+
+
+
void cChunkMap::RemoveClientFromChunks(cClientHandle * a_Client, const cChunkCoordsList & a_Chunks)
{
cCSLock Lock(m_CSLayers);
@@ -569,7 +679,7 @@ void cChunkMap::RemoveClientFromChunks(cClientHandle * a_Client, const cChunkCoo
bool cChunkMap::SendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
{
cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
+ cChunkPtr Chunk = GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
if ((Chunk == NULL) || !Chunk->IsValid())
{
return false;
@@ -616,6 +726,33 @@ void cChunkMap::RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_Ch
+void cChunkMap::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
+{
+ cCSLock Lock(m_CSLayers);
+ GetChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
+}
+
+
+
+
+
+void cChunkMap::UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4)
+{
+ cCSLock Lock(m_CSLayers);
+ int ChunkX, ChunkZ;
+ BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ);
+ cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ);
+ if ((Chunk == NULL) || !Chunk->IsValid())
+ {
+ return;
+ }
+ Chunk->UpdateSign(a_X, a_Y, a_Z, a_Line1, a_Line2, a_Line3, a_Line4);
+}
+
+
+
+
+
void cChunkMap::Tick( float a_Dt, MTRand & a_TickRandom )
{
cCSLock Lock(m_CSLayers);
@@ -687,7 +824,7 @@ cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkY, int a_Ch
int Index = LocalX + LocalZ * LAYER_SIZE;
if (m_Chunks[Index].get() == NULL)
{
- m_Chunks[Index].reset(new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent->GetWorld()));
+ m_Chunks[Index].reset(new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld()));
}
return m_Chunks[Index];
}
diff --git a/source/cChunkMap.h b/source/cChunkMap.h
index 026594f11..98698cfe3 100644
--- a/source/cChunkMap.h
+++ b/source/cChunkMap.h
@@ -13,6 +13,7 @@
class cWorld;
class cEntity;
+class cItem;
class MTRand;
@@ -27,10 +28,6 @@ public:
cChunkMap(cWorld* a_World );
~cChunkMap();
- // TODO: Get rid of these (put into Private section) in favor of the direct action methods:
- cChunkPtr GetChunk ( int a_ChunkX, int a_ChunkY, int a_ChunkZ ); // Also queues the chunk for loading / generating if not valid
- cChunkPtr GetChunkNoGen( int a_ChunkX, int a_ChunkY, int a_ChunkZ ); // Also queues the chunk for loading if not valid; doesn't generate
-
// Direct action methods:
/// Broadcast a_Packet to all clients in the chunk specified
void BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cPacket & a_Packet, cClientHandle * a_Exclude = NULL);
@@ -56,6 +53,10 @@ public:
void CollectPickupsByPlayer(cPlayer * a_Player);
char GetBlock (int a_X, int a_Y, int a_Z);
char GetBlockMeta (int a_X, int a_Y, int a_Z);
+ void SetBlockMeta (int a_X, int a_Y, int a_Z, char a_BlockMeta);
+ void SetBlock (int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta);
+ bool DigBlock (int a_X, int a_Y, int a_Z, cItem & a_PickupItem);
+ void SendBlockTo (int a_X, int a_Y, int a_Z, cPlayer * a_Player);
/// Compares clients of two chunks, calls the callback accordingly
void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback);
@@ -63,6 +64,9 @@ public:
/// Adds client to a chunk, if not already present; returns true if added, false if present
bool AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
+ /// Removes the client from the chunk
+ void RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
+
/// Removes the client from all chunks specified
void RemoveClientFromChunks(cClientHandle * a_Client, const cChunkCoordsList & a_Chunks);
@@ -74,6 +78,11 @@ public:
/// Removes the entity from the chunk specified
void RemoveEntityFromChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+
+ /// Touches the chunk, causing it to be loaded or generated
+ void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+
+ void UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4);
void Tick( float a_Dt, MTRand & a_TickRand );
@@ -113,6 +122,8 @@ public:
private:
+ friend class cChunk; // Temporary (until we have a separate Lighting thread), so that cChunk's lighting calc can ask for neighbor chunks
+
class cChunkLayer
{
public:
@@ -153,6 +164,9 @@ private:
cEvent m_evtChunkValid; // Set whenever any chunk becomes valid, via ChunkValidated()
cWorld * m_World;
+
+ cChunkPtr GetChunk ( int a_ChunkX, int a_ChunkY, int a_ChunkZ ); // Also queues the chunk for loading / generating if not valid
+ cChunkPtr GetChunkNoGen( int a_ChunkX, int a_ChunkY, int a_ChunkZ ); // Also queues the chunk for loading if not valid; doesn't generate
};
diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp
index 6db6a2501..91ccb4005 100644
--- a/source/cClientHandle.cpp
+++ b/source/cClientHandle.cpp
@@ -343,7 +343,7 @@ void cClientHandle::StreamChunks(void)
int RelZ = (*itr).m_ChunkZ - ChunkPosZ;
if ((RelX > VIEWDISTANCE) || (RelX < -VIEWDISTANCE) || (RelZ > VIEWDISTANCE) || (RelZ < -VIEWDISTANCE))
{
- World->GetChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ)->RemoveClient(this);
+ World->RemoveChunkClient(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ, this);
itr = m_LoadedChunks.erase(itr);
}
else
@@ -389,13 +389,13 @@ void cClientHandle::StreamChunks(void)
// For each distance touch chunks in a hollow square centered around current position:
for (int i = -d; i <= d; ++i)
{
- World->GetChunk(ChunkPosX + d, ZERO_CHUNK_Y, ChunkPosZ + i);
- World->GetChunk(ChunkPosX - d, ZERO_CHUNK_Y, ChunkPosZ + i);
+ World->TouchChunk(ChunkPosX + d, ZERO_CHUNK_Y, ChunkPosZ + i);
+ World->TouchChunk(ChunkPosX - d, ZERO_CHUNK_Y, ChunkPosZ + i);
} // for i
for (int i = -d + 1; i < d; ++i)
{
- World->GetChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ + d);
- World->GetChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ - d);
+ World->TouchChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ + d);
+ World->TouchChunk(ChunkPosX + i, ZERO_CHUNK_Y, ChunkPosZ - d);
} // for i
} // for d
}
@@ -1510,12 +1510,7 @@ void cClientHandle::HandleWindowClick(cPacket_WindowClick * a_Packet)
void cClientHandle::HandleUpdateSign(cPacket_UpdateSign * a_Packet)
{
cWorld * World = m_Player->GetWorld();
- cChunkPtr Chunk = World->GetChunkOfBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
- if ((Chunk == NULL) || !Chunk->IsValid())
- {
- return;
- }
- Chunk->UpdateSign(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Line1, a_Packet->m_Line2, a_Packet->m_Line3, a_Packet->m_Line4);
+ World->UpdateSign(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Line1, a_Packet->m_Line2, a_Packet->m_Line3, a_Packet->m_Line4);
}
@@ -1664,8 +1659,10 @@ void cClientHandle::Tick(float a_Dt)
// Only send up to 10 chunks per tick, otherwise we'd choke the tick thread
break;
}
- CheckIfWorldDownloaded();
} // for itr - m_ChunksToSend[]
+
+ // Check even if we didn't send anything - a chunk may have sent a notification that we'd miss otherwise
+ CheckIfWorldDownloaded();
}
}
diff --git a/source/cPickup.cpp b/source/cPickup.cpp
index bba9ae518..49dc5b342 100644
--- a/source/cPickup.cpp
+++ b/source/cPickup.cpp
@@ -160,7 +160,7 @@ void cPickup::Tick(float a_Dt)
m_bReplicated = true;
m_bDirtyPosition = false;
cPacket_TeleportEntity TeleportEntity( this );
- GetWorld()->GetChunk( m_ChunkX, m_ChunkY, m_ChunkZ )->Broadcast( &TeleportEntity );
+ GetWorld()->BroadcastToChunk( m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity );
}
}
diff --git a/source/cSignEntity.cpp b/source/cSignEntity.cpp
index 618f5960e..c181deae2 100644
--- a/source/cSignEntity.cpp
+++ b/source/cSignEntity.cpp
@@ -98,7 +98,7 @@ void cSignEntity::SendTo( cClientHandle* a_Client )
}
else // broadcast of a_Client == 0
{
- m_World->GetChunkOfBlock(m_PosX, m_PosY, m_PosZ)->Broadcast( Sign );
+ m_World->BroadcastToChunkOfBlock(m_PosX, m_PosY, m_PosZ, &Sign );
}
}
diff --git a/source/cWorld.cpp b/source/cWorld.cpp
index 84f350495..1b719d031 100644
--- a/source/cWorld.cpp
+++ b/source/cWorld.cpp
@@ -80,17 +80,6 @@ bool g_BlockPistonBreakable[128];
-#define RECI_RAND_MAX (1.f/RAND_MAX)
-inline float fRadRand( float a_Radius )
-{
- MTRand r1;
- return ((float)r1.rand() * RECI_RAND_MAX)*a_Radius - a_Radius*0.5f;
-}
-
-
-
-
-
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cWorldLoadProgress:
@@ -443,7 +432,7 @@ void cWorld::InitializeSpawn()
{
for (int z = 0; z < ViewDist; z++)
{
- GetChunk( x + ChunkX-(ViewDist - 1) / 2, 0, z + ChunkZ-(ViewDist - 1) / 2 ); // Queue the chunk in the generator / loader
+ m_ChunkMap->TouchChunk( x + ChunkX-(ViewDist - 1) / 2, 0, z + ChunkZ-(ViewDist - 1) / 2 ); // Queue the chunk in the generator / loader
}
}
@@ -812,29 +801,11 @@ void cWorld::GrowTree( int a_X, int a_Y, int a_Z )
-cChunkPtr cWorld::GetChunkOfBlock( int a_X, int a_Y, int a_Z )
-{
- int ChunkX, ChunkY, ChunkZ;
- AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkY, ChunkZ );
- return GetChunk( ChunkX, ChunkY, ChunkZ );
-}
-
-
-
-
-
void cWorld::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta )
{
- int ChunkX, ChunkY, ChunkZ, X = a_X, Y = a_Y, Z = a_Z;
- AbsoluteToRelative( X, Y, Z, ChunkX, ChunkY, ChunkZ );
+ m_ChunkMap->SetBlock(a_X, a_Y, a_Z, a_BlockType, a_BlockMeta);
- cChunkPtr Chunk = GetChunk( ChunkX, ChunkY, ChunkZ );
- if ( Chunk->IsValid() )
- {
- Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta );
- this->GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z);
- }
- // The chunk is not yet initialized, so it's probably far away from all players, no need to store this Meta change
+ GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z);
}
@@ -899,17 +870,7 @@ char cWorld::GetBlockMeta( int a_X, int a_Y, int a_Z )
void cWorld::SetBlockMeta( int a_X, int a_Y, int a_Z, char a_MetaData )
{
- int ChunkX, ChunkY, ChunkZ;
-
- AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkY, ChunkZ );
-
- cChunkPtr Chunk = GetChunk( ChunkX, ChunkY, ChunkZ );
- if ( Chunk->IsValid() )
- {
- Chunk->SetLight( Chunk->pGetMeta(), a_X, a_Y, a_Z, a_MetaData );
- Chunk->SendBlockTo( a_X, a_Y, a_Z, NULL );
- }
- // The chunk is not yet initialized, so it's probably far away from all players, no need to store this Meta change
+ m_ChunkMap->SetBlockMeta(a_X, a_Y, a_Z, a_MetaData);
}
@@ -918,24 +879,12 @@ void cWorld::SetBlockMeta( int a_X, int a_Y, int a_Z, char a_MetaData )
bool cWorld::DigBlock( int a_X, int a_Y, int a_Z, cItem & a_PickupItem )
{
- int PosX = a_X, PosY = a_Y, PosZ = a_Z, ChunkX, ChunkY, ChunkZ;
-
- AbsoluteToRelative( PosX, PosY, PosZ, ChunkX, ChunkY, ChunkZ );
-
- cChunkPtr DestChunk = GetChunk( ChunkX, ChunkY, ChunkZ );
- if (DestChunk->IsValid())
+ bool res = m_ChunkMap->DigBlock(a_X, a_Y, a_Z, a_PickupItem);
+ if (res)
{
- DestChunk->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, 0 );
-
GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z);
-
- if ( !a_PickupItem.IsEmpty() )
- {
- cPickup * Pickup = new cPickup( a_X * 32 + 16 + (int)fRadRand(16.f), a_Y * 32 + 16 + (int)fRadRand(16.f), a_Z * 32 + 16 + (int)fRadRand(16.f), a_PickupItem );
- Pickup->Initialize( this );
- }
}
- return true;
+ return res;
}
@@ -944,13 +893,7 @@ bool cWorld::DigBlock( int a_X, int a_Y, int a_Z, cItem & a_PickupItem )
void cWorld::SendBlockTo( int a_X, int a_Y, int a_Z, cPlayer * a_Player )
{
- int ChunkX, ChunkY, ChunkZ;
- AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkY, ChunkZ );
- cChunkPtr Chunk = GetChunk( ChunkX, ChunkY, ChunkZ );
- if (Chunk->IsValid())
- {
- Chunk->SendBlockTo( a_X, a_Y, a_Z, a_Player->GetClientHandle() );
- }
+ m_ChunkMap->SendBlockTo(a_X, a_Y, a_Z, a_Player);
}
@@ -960,15 +903,6 @@ void cWorld::SendBlockTo( int a_X, int a_Y, int a_Z, cPlayer * a_Player )
// TODO: This interface is dangerous!
cBlockEntity * cWorld::GetBlockEntity( int a_X, int a_Y, int a_Z )
{
- int PosX = a_X, PosY = a_Y, PosZ = a_Z, ChunkX, ChunkY, ChunkZ;
-
- AbsoluteToRelative( PosX, PosY, PosZ, ChunkX, ChunkY, ChunkZ );
-
- cChunkPtr Chunk = GetChunk( ChunkX, ChunkY, ChunkZ );
- if (Chunk->IsValid())
- {
- // TODO: return Chunk->GetBlockEntity( a_X, a_Y, a_Z );
- }
return NULL;
}
@@ -1340,6 +1274,15 @@ bool cWorld::AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHan
+void cWorld::RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
+{
+ m_ChunkMap->RemoveChunkClient(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client);
+}
+
+
+
+
+
void cWorld::RemoveClientFromChunks(cClientHandle * a_Client, const cChunkCoordsList & a_Chunks)
{
m_ChunkMap->RemoveClientFromChunks(a_Client, a_Chunks);
@@ -1358,6 +1301,24 @@ bool cWorld::SendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle
+void cWorld::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
+{
+ m_ChunkMap->TouchChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
+}
+
+
+
+
+
+void cWorld::UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4)
+{
+ m_ChunkMap->UpdateSign(a_X, a_Y, a_Z, a_Line1, a_Line2, a_Line3, a_Line4);
+}
+
+
+
+
+
void cWorld::SaveAllChunks()
{
LOG("Saving all chunks...");
diff --git a/source/cWorld.h b/source/cWorld.h
index b181df365..2fc907b3a 100644
--- a/source/cWorld.h
+++ b/source/cWorld.h
@@ -57,9 +57,6 @@ public:
void SetWorldTime(long long a_WorldTime) { m_WorldTime = a_WorldTime; } //tolua_export
- cChunkPtr GetChunk ( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) {return m_ChunkMap->GetChunk (a_ChunkX, a_ChunkY, a_ChunkZ); }
- cChunkPtr GetChunkNoGen ( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) {return m_ChunkMap->GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ); }
- cChunkPtr GetChunkOfBlock( int a_X, int a_Y, int a_Z );
int GetHeight( int a_X, int a_Z ); //tolua_export
//void AddClient( cClientHandle* a_Client );
@@ -124,11 +121,19 @@ public:
/// Adds client to a chunk, if not already present; returns true if added, false if present
bool AddChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
+ /// Removes client from the chunk specified
+ void RemoveChunkClient(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
+
/// Removes the client from all chunks specified
void RemoveClientFromChunks(cClientHandle * a_Client, const cChunkCoordsList & a_Chunks);
/// Sends a chunk to client, returns true if successful, false if not sent
bool SendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client);
+
+ /// Touches the chunk, causing it to be loaded or generated
+ void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
+
+ void UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4);
// TODO: Export to Lua
bool DoWithEntity( int a_UniqueID, cEntityCallback & a_Callback );
@@ -150,7 +155,8 @@ public:
inline cLavaSimulator *GetLavaSimulator() { return m_LavaSimulator; }
// TODO: This interface is dangerous! Export as a set of specific action functions for Lua: GetChestItem, GetFurnaceItem, SetFurnaceItem, SetSignLines etc.
- cBlockEntity * GetBlockEntity( int a_X, int a_Y, int a_Z ); //tolua_export
+ // _X 2012_02_21: This function always returns NULL
+ OBSOLETE cBlockEntity * GetBlockEntity( int a_X, int a_Y, int a_Z ); //tolua_export
/// a_Player is using block entity at [x, y, z], handle that:
void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) {m_ChunkMap->UseBlockEntity(a_Player, a_X, a_Y, a_Z); }