Terrain generation is synchronous again, async generation has bugs.
Made some funky smart pointer things for chunks. Fixed a bug where the client would override the player position on the server and back again, resulting in sending too many chunks to the client which it doesn't even need. Fixed some compiler warnings in cPickup.cpp git-svn-id: http://mc-server.googlecode.com/svn/trunk@164 0a769ca7-a7f5-676a-18bf-c427514a06d6master
parent
f47c852186
commit
50a7722242
|
@ -522,6 +522,7 @@
|
|||
<ClInclude Include="..\source\packets\cPacket_WindowClick.h" />
|
||||
<ClInclude Include="..\source\packets\cPacket_WindowClose.h" />
|
||||
<ClInclude Include="..\source\packets\cPacket_WindowOpen.h" />
|
||||
<ClInclude Include="..\source\ptr_cChunk.h" />
|
||||
<ClInclude Include="..\source\SquirrelBindings.h" />
|
||||
<ClInclude Include="..\source\Vector3d.h" />
|
||||
<ClInclude Include="..\source\Vector3f.h" />
|
||||
|
|
|
@ -448,6 +448,9 @@
|
|||
<Filter Include="cInventory\cCreativeInventory">
|
||||
<UniqueIdentifier>{69e6a927-8e49-4d39-af88-f587d17bb8a3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="!Smart_Pointers">
|
||||
<UniqueIdentifier>{9bd7a65c-b60f-4905-ae2b-7c3c7586eaef}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\source\cServer.cpp">
|
||||
|
@ -1371,6 +1374,9 @@
|
|||
<ClInclude Include="..\source\cSurvivalInventory.h">
|
||||
<Filter>cInventory\cSurvivalInventory</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\source\ptr_cChunk.h">
|
||||
<Filter>!Smart_Pointers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\source\AllToLua.pkg">
|
||||
|
|
|
@ -22,6 +22,8 @@ public: //tolua_export
|
|||
inline double Dot( const Vector3d & a_V ) const { return x * a_V.x + y * a_V.y + z * a_V.z; } //tolua_export
|
||||
inline Vector3d Cross( const Vector3d & v ) const { return Vector3d( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); } //tolua_export
|
||||
|
||||
inline bool Equals( const Vector3d & v ) const { return (x == v.x && y == v.y && z == v.z ); } //tolua_export
|
||||
|
||||
void operator += ( const Vector3d& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; }
|
||||
void operator += ( Vector3d* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; }
|
||||
void operator -= ( const Vector3d& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; }
|
||||
|
|
|
@ -62,6 +62,7 @@ struct cChunk::sChunkState
|
|||
sChunkState()
|
||||
: TotalReferencesEver( 0 )
|
||||
, MinusReferences( 0 )
|
||||
, NumRefs( 0 )
|
||||
{}
|
||||
|
||||
FurnaceEntityList TickBlockEntities;
|
||||
|
@ -79,6 +80,7 @@ struct cChunk::sChunkState
|
|||
ReferenceMap References;
|
||||
int MinusReferences; // References.size() - MinusReferences = Actual amount of references. This is due to removal of reference without an ID (don't know which to remove, so remove none)
|
||||
int TotalReferencesEver; // For creating a unique reference ID
|
||||
int NumRefs;
|
||||
};
|
||||
|
||||
cChunk::~cChunk()
|
||||
|
@ -541,8 +543,8 @@ void cChunk::SpreadLight(char* a_LightBuffer)
|
|||
bool bCalcLeft, bCalcRight, bCalcFront, bCalcBack;
|
||||
bCalcLeft = bCalcRight = bCalcFront = bCalcBack = false;
|
||||
// Spread to neighbour chunks X-axis
|
||||
cChunk* LeftChunk = m_World->GetChunkUnreliable( m_PosX-1, m_PosY, m_PosZ );
|
||||
cChunk* RightChunk = m_World->GetChunkUnreliable( m_PosX+1, m_PosY, m_PosZ );
|
||||
ptr_cChunk LeftChunk = m_World->GetChunkUnreliable( m_PosX-1, m_PosY, m_PosZ );
|
||||
ptr_cChunk RightChunk = m_World->GetChunkUnreliable( m_PosX+1, m_PosY, m_PosZ );
|
||||
char* LeftSky = 0, *RightSky = 0;
|
||||
if(LeftChunk) LeftSky = (a_LightBuffer==m_BlockSkyLight)?LeftChunk->pGetSkyLight():LeftChunk->pGetLight();
|
||||
if(RightChunk) RightSky = (a_LightBuffer==m_BlockSkyLight)?RightChunk->pGetSkyLight():RightChunk->pGetLight();
|
||||
|
@ -579,8 +581,8 @@ void cChunk::SpreadLight(char* a_LightBuffer)
|
|||
}
|
||||
|
||||
// Spread to neighbour chunks Z-axis
|
||||
cChunk* FrontChunk = m_World->GetChunkUnreliable( m_PosX, m_PosY, m_PosZ-1 );
|
||||
cChunk* BackChunk = m_World->GetChunkUnreliable( m_PosX, m_PosY, m_PosZ+1 );
|
||||
ptr_cChunk FrontChunk = m_World->GetChunkUnreliable( m_PosX, m_PosY, m_PosZ-1 );
|
||||
ptr_cChunk BackChunk = m_World->GetChunkUnreliable( m_PosX, m_PosY, m_PosZ+1 );
|
||||
char* FrontSky = 0, *BackSky = 0;
|
||||
if(FrontChunk) FrontSky = (a_LightBuffer==m_BlockSkyLight)?FrontChunk->pGetSkyLight():FrontChunk->pGetLight();
|
||||
if(BackChunk) BackSky = (a_LightBuffer==m_BlockSkyLight)?BackChunk->pGetSkyLight():BackChunk->pGetLight();
|
||||
|
@ -1177,60 +1179,28 @@ void cChunk::PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, i
|
|||
a_Z = m_PosZ * 16 + a_ChunkZ;
|
||||
}
|
||||
|
||||
int cChunk::AddReference( const char* a_Info /* = 0 */ )
|
||||
void cChunk::AddReference()
|
||||
{
|
||||
m_pState->ReferenceCriticalSection.Lock();
|
||||
|
||||
m_pState->TotalReferencesEver++;
|
||||
|
||||
std::string Info;
|
||||
if( a_Info ) Info = a_Info;
|
||||
|
||||
m_pState->References[ m_pState->TotalReferencesEver ] = Info;
|
||||
|
||||
int ID = m_pState->TotalReferencesEver;
|
||||
m_pState->NumRefs++;
|
||||
m_pState->ReferenceCriticalSection.Unlock();
|
||||
return ID;
|
||||
}
|
||||
|
||||
void cChunk::RemoveReference( int a_ID )
|
||||
void cChunk::RemoveReference()
|
||||
{
|
||||
m_pState->ReferenceCriticalSection.Lock();
|
||||
|
||||
if( a_ID > -1 ) // Remove reference with an ID
|
||||
m_pState->NumRefs--;
|
||||
if( m_pState->NumRefs < 0 )
|
||||
{
|
||||
bool bFound = false;
|
||||
for( ReferenceMap::iterator itr = m_pState->References.begin(); itr != m_pState->References.end(); ++itr )
|
||||
{
|
||||
if( itr->first == a_ID )
|
||||
{
|
||||
bFound = true;
|
||||
m_pState->References.erase( itr );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !bFound )
|
||||
{
|
||||
LOGWARN("WARNING: cChunk: Tried to remove reference %i but it could not be found! May cause memory leak", a_ID );
|
||||
}
|
||||
LOGWARN("WARNING: cChunk: Tried to remove reference, but the chunk is not referenced!");
|
||||
}
|
||||
else // No ID so add one to MinusReferences
|
||||
{
|
||||
m_pState->MinusReferences++;
|
||||
if( (int)m_pState->References.size() - m_pState->MinusReferences < 0 )
|
||||
{
|
||||
LOGWARN("WARNING: cChunk: Tried to remove reference %i, but the chunk is not referenced!", a_ID);
|
||||
}
|
||||
}
|
||||
|
||||
m_pState->ReferenceCriticalSection.Unlock();
|
||||
}
|
||||
|
||||
int cChunk::GetReferenceCount()
|
||||
{
|
||||
m_pState->ReferenceCriticalSection.Unlock();
|
||||
int Refs = (int)m_pState->References.size() - m_pState->MinusReferences;
|
||||
int Refs = m_pState->NumRefs;
|
||||
m_pState->ReferenceCriticalSection.Lock();
|
||||
return Refs;
|
||||
}
|
||||
|
|
|
@ -102,8 +102,8 @@ public:
|
|||
static const int c_BlockDataSize = c_NumBlocks * 2 + (c_NumBlocks/2); // 2.5 * numblocks
|
||||
|
||||
// Reference counting
|
||||
int AddReference( const char* a_Info = 0 ); // a_Info is for debugging
|
||||
void RemoveReference( int a_ID = -1 );
|
||||
void AddReference();
|
||||
void RemoveReference();
|
||||
int GetReferenceCount();
|
||||
private:
|
||||
struct sChunkState;
|
||||
|
|
|
@ -465,7 +465,7 @@ void cChunkMap::UnloadUnusedChunks()
|
|||
if( Chunk && Chunk->GetClients().size() == 0 && Chunk->GetReferenceCount() <= 0 )
|
||||
{
|
||||
Chunk->SaveToDisk();
|
||||
World->RemoveSpread( Chunk );
|
||||
World->RemoveSpread( ptr_cChunk( Chunk ) );
|
||||
RemoveChunk( Chunk );
|
||||
delete Chunk;
|
||||
}
|
||||
|
|
|
@ -113,6 +113,8 @@ struct cClientHandle::sClientHandleState
|
|||
cCriticalSection SocketCriticalSection;
|
||||
cSemaphore* pSemaphore;
|
||||
|
||||
Vector3d ConfirmPosition;
|
||||
|
||||
cPacket* PacketMap[256];
|
||||
};
|
||||
|
||||
|
@ -126,6 +128,7 @@ cClientHandle::cClientHandle(const cSocket & a_Socket)
|
|||
, m_bSendLoginResponse( false )
|
||||
, m_pState( new sClientHandleState )
|
||||
, m_Ping(1000)
|
||||
, m_bPositionConfirmed( false )
|
||||
{
|
||||
LOG("cClientHandle::cClientHandle");
|
||||
|
||||
|
@ -382,6 +385,7 @@ void cClientHandle::StreamChunksSmart( cChunk** a_Chunks, unsigned int a_NumChun
|
|||
{
|
||||
a_Chunks[ClosestIdx]->Send( this );
|
||||
a_Chunks[ClosestIdx]->AddClient( this );
|
||||
//LOGINFO("CCC: Sending chunk %i %i", a_Chunks[ClosestIdx]->GetPosX(), a_Chunks[ClosestIdx]->GetPosZ() );
|
||||
a_Chunks[ClosestIdx] = 0;
|
||||
}
|
||||
}
|
||||
|
@ -526,6 +530,7 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
|
|||
StreamChunks();
|
||||
|
||||
// Send position
|
||||
m_pState->ConfirmPosition = m_Player->GetPosition();
|
||||
Send( cPacket_PlayerMoveLook( m_Player ) );
|
||||
}
|
||||
break;
|
||||
|
@ -539,7 +544,32 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
|
|||
break;
|
||||
}
|
||||
}
|
||||
else // m_bLoggedIn == true
|
||||
else if( !m_bPositionConfirmed ) // m_bLoggedIn == true
|
||||
{
|
||||
switch( a_Packet->m_PacketID )
|
||||
{
|
||||
case E_PLAYERMOVELOOK:
|
||||
{
|
||||
cPacket_PlayerMoveLook* PacketData = reinterpret_cast<cPacket_PlayerMoveLook*>(a_Packet);
|
||||
Vector3d ReceivedPosition = Vector3d( PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ );
|
||||
|
||||
// Test the distance between points with a small/large enough value instead of comparing directly. Floating point inaccuracies might screw stuff up
|
||||
if( ( ReceivedPosition - m_pState->ConfirmPosition ).SqrLength() < 1.0 )
|
||||
{
|
||||
// Test
|
||||
if( ReceivedPosition.Equals( m_pState->ConfirmPosition ) )
|
||||
{
|
||||
LOGINFO("Exact position confirmed by client!");
|
||||
}
|
||||
m_bPositionConfirmed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( m_bPositionConfirmed )
|
||||
{
|
||||
switch( a_Packet->m_PacketID )
|
||||
{
|
||||
|
@ -1434,6 +1464,7 @@ void cClientHandle::SendThread( void *lpParam )
|
|||
m_pState->SocketCriticalSection.Unlock();
|
||||
break;
|
||||
}
|
||||
//LOG("Send packet: 0x%2x", Packet->m_PacketID );
|
||||
bool bSuccess = Packet->Send( m_pState->Socket );
|
||||
m_pState->SocketCriticalSection.Unlock();
|
||||
if( !bSuccess )
|
||||
|
@ -1481,6 +1512,7 @@ void cClientHandle::ReceiveThread( void *lpParam )
|
|||
}
|
||||
else
|
||||
{
|
||||
//LOG("Recv packet: 0x%2x", (unsigned char)temp );
|
||||
cPacket* pPacket = self->m_pState->PacketMap[ (unsigned char)temp ];
|
||||
if( pPacket )
|
||||
{
|
||||
|
|
|
@ -78,6 +78,7 @@ private:
|
|||
static const unsigned short PING_TIME_MS = 1000; //minecraft sends 1 per 20 ticks (1 second or every 1000 ms)
|
||||
|
||||
bool m_bLoggedIn;
|
||||
bool m_bPositionConfirmed;
|
||||
bool m_bSendLoginResponse;
|
||||
|
||||
bool m_bKeepThreadGoing;
|
||||
|
|
|
@ -148,7 +148,7 @@ void cEntity::RemoveFromChunk( cChunk* a_Chunk )
|
|||
{
|
||||
if( m_World )
|
||||
{
|
||||
cChunk* Chunk = ( a_Chunk ? a_Chunk : m_World->GetChunkUnreliable( m_ChunkX, m_ChunkY, m_ChunkZ ) );
|
||||
cChunk* Chunk = ( a_Chunk ? a_Chunk : (cChunk*)m_World->GetChunkUnreliable( m_ChunkX, m_ChunkY, m_ChunkZ ) );
|
||||
if( Chunk )
|
||||
{
|
||||
cPacket_DestroyEntity DestroyEntity( this );
|
||||
|
|
|
@ -197,7 +197,7 @@ void cPickup::HandlePhysics(float a_Dt)
|
|||
Direction WaterDir = World->GetWaterSimulator()->GetFlowingDirection((int) m_Pos->x - 1, (int) m_Pos->y, (int) m_Pos->z - 1);
|
||||
|
||||
|
||||
*m_WaterSpeed *= 0.9; //Keep old speed but lower it
|
||||
*m_WaterSpeed *= 0.9f; //Keep old speed but lower it
|
||||
|
||||
switch(WaterDir)
|
||||
{
|
||||
|
@ -256,7 +256,7 @@ void cPickup::HandlePhysics(float a_Dt)
|
|||
}
|
||||
}
|
||||
*m_Pos = Tracer.RealHit;
|
||||
*m_Pos += *Tracer.HitNormal * 0.2;
|
||||
*m_Pos += *Tracer.HitNormal * 0.2f;
|
||||
|
||||
}
|
||||
else
|
||||
|
|
|
@ -277,7 +277,7 @@ void cServer::StartListenClient()
|
|||
|
||||
bool cServer::Tick(float a_Dt)
|
||||
{
|
||||
//LOG("Tick");
|
||||
//LOG("1. Tick");
|
||||
if( a_Dt > 100.f ) a_Dt = 100.f; // Don't go over 1/10 second
|
||||
|
||||
cSleep::MilliSleep( 50 ); // Don't tick too much
|
||||
|
@ -289,7 +289,6 @@ bool cServer::Tick(float a_Dt)
|
|||
m_Millisecondsf = m_Millisecondsf - (int)m_Millisecondsf;
|
||||
}
|
||||
|
||||
|
||||
cRoot::Get()->TickWorlds( a_Dt ); // TODO - Maybe give all worlds their own thread?
|
||||
|
||||
//World->LockClientHandle(); // TODO - Lock client list
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include "packets/cPacket_NewInvalidState.h"
|
||||
#include "packets/cPacket_Thunderbolt.h"
|
||||
|
||||
#include "ptr_cChunk.h"
|
||||
|
||||
#include "Vector3d.h"
|
||||
|
||||
#include <time.h>
|
||||
|
@ -430,12 +432,11 @@ void cWorld::Tick(float a_Dt)
|
|||
int TimesSpreaded = 0;
|
||||
while( !m_pState->SpreadQueue.empty() && TimesSpreaded < 50 ) // Spread a max of 50 times each tick, otherwise server will hang
|
||||
{
|
||||
cChunk* Chunk = (*m_pState->SpreadQueue.begin());
|
||||
ptr_cChunk& Chunk = *m_pState->SpreadQueue.begin();
|
||||
//LOG("Spreading: %p", Chunk );
|
||||
Chunk->SpreadLight( Chunk->pGetSkyLight() );
|
||||
Chunk->SpreadLight( Chunk->pGetLight() );
|
||||
m_pState->SpreadQueue.remove( Chunk );
|
||||
Chunk->RemoveReference();
|
||||
TimesSpreaded++;
|
||||
}
|
||||
if( TimesSpreaded >= 50 )
|
||||
|
@ -494,7 +495,7 @@ void cWorld::Tick(float a_Dt)
|
|||
FastSetBlock( SetBlockData.x, SetBlockData.y, SetBlockData.z, SetBlockData.BlockID, SetBlockData.BlockMeta ); // If unable to set block, it's added to FastSetBlockQueue again
|
||||
}
|
||||
if( FastSetBlockQueueCopy.size() != m_pState->FastSetBlockQueue.size() )
|
||||
LOG(" Before: %i, after %i" , FastSetBlockQueueCopy.size(), m_pState->FastSetBlockQueue.size() );
|
||||
LOG(" Before: %i, after %i" , FastSetBlockQueueCopy.size(), m_pState->FastSetBlockQueue.size() );
|
||||
|
||||
if( m_Time - m_LastSave > 60*5 ) // Save each 5 minutes
|
||||
{
|
||||
|
@ -712,20 +713,36 @@ cChunk* cWorld::GetChunk( int a_X, int a_Y, int a_Z )
|
|||
cChunk* Chunk = GetChunkUnreliable( a_X, a_Y, a_Z );
|
||||
if( Chunk ) return Chunk;
|
||||
|
||||
#if 1 // Current thread chunk generation
|
||||
|
||||
// Found nothing, create a chunk
|
||||
Chunk = new cChunk( a_X, a_Y, a_Z, this );
|
||||
if(Chunk)
|
||||
{
|
||||
LOGWARN("Created new chunk! %i %i", a_X, a_Z);
|
||||
LockChunks();
|
||||
m_ChunkMap->AddChunk( Chunk );
|
||||
UnlockChunks();
|
||||
Chunk->Initialize();
|
||||
return Chunk;
|
||||
}
|
||||
return 0;
|
||||
#else // Async thread generation
|
||||
|
||||
// Generate new chunk asynchronously
|
||||
m_pState->pChunkGenerator->GenerateChunk( a_X, a_Z );
|
||||
|
||||
// Could not find chunk, it's being generated, so return 0
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
cChunk* cWorld::GetChunkUnreliable( int a_X, int a_Y, int a_Z )
|
||||
ptr_cChunk cWorld::GetChunkUnreliable( int a_X, int a_Y, int a_Z )
|
||||
{
|
||||
LockChunks();
|
||||
cChunk* Chunk = m_ChunkMap->GetChunk( a_X, a_Y, a_Z );
|
||||
ptr_cChunk Chunk( m_ChunkMap->GetChunk( a_X, a_Y, a_Z ) );
|
||||
UnlockChunks();
|
||||
if( Chunk ) return Chunk;
|
||||
return 0;
|
||||
return Chunk;
|
||||
}
|
||||
|
||||
cChunk* cWorld::GetChunkOfBlock( int a_X, int a_Y, int a_Z )
|
||||
|
@ -761,18 +778,6 @@ void cWorld::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_B
|
|||
return;
|
||||
}
|
||||
|
||||
// Could not find chunk, so it has been pushed into the generate chunks queue
|
||||
// Check if currently generating the target chunk
|
||||
m_pState->pChunkGenerator->Lock();
|
||||
Chunk = m_pState->pChunkGenerator->GetCurrentlyGenerating();
|
||||
if( Chunk && Chunk->GetPosX() == ChunkX && Chunk->GetPosZ() == ChunkZ )
|
||||
{
|
||||
Chunk->FastSetBlock(X, Y, Z, a_BlockType, a_BlockMeta );
|
||||
m_pState->pChunkGenerator->Unlock();
|
||||
return;
|
||||
}
|
||||
m_pState->pChunkGenerator->Unlock();
|
||||
|
||||
// Unable to set block right now, try again later
|
||||
m_pState->FastSetBlockQueue.push_back( sSetBlockData( a_X, a_Y, a_Z, a_BlockType, a_BlockMeta ) );
|
||||
}
|
||||
|
@ -1052,23 +1057,20 @@ void cWorld::UnlockChunks()
|
|||
m_ChunksCriticalSection->Unlock();
|
||||
}
|
||||
|
||||
void cWorld::ReSpreadLighting( cChunk* a_Chunk )
|
||||
void cWorld::ReSpreadLighting( const ptr_cChunk& a_Chunk )
|
||||
{
|
||||
LockChunks();
|
||||
m_pState->SpreadQueue.remove( a_Chunk );
|
||||
m_pState->SpreadQueue.remove( a_Chunk );
|
||||
m_pState->SpreadQueue.push_back( a_Chunk );
|
||||
#define STRINGIZE(x) #x
|
||||
a_Chunk->AddReference( __FILE__ ": " STRINGIZE(__LINE__) );
|
||||
//#define STRINGIZE(x) #x
|
||||
//a_Chunk->AddReference( __FILE__ ": " STRINGIZE(__LINE__) );
|
||||
UnlockChunks();
|
||||
}
|
||||
|
||||
void cWorld::RemoveSpread( cChunk* a_Chunk )
|
||||
void cWorld::RemoveSpread( const ptr_cChunk& a_Chunk )
|
||||
{
|
||||
LockChunks();
|
||||
size_t SizeBefore = m_pState->SpreadQueue.size();
|
||||
m_pState->SpreadQueue.remove( a_Chunk );
|
||||
if( SizeBefore != m_pState->SpreadQueue.size() )
|
||||
a_Chunk->RemoveReference();
|
||||
UnlockChunks();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ enum ENUM_ITEM_ID;
|
|||
#include <string>
|
||||
|
||||
#include "cSimulatorManager.h"
|
||||
#include "ptr_cChunk.h"
|
||||
|
||||
class cPacket;
|
||||
class cRedstone;
|
||||
|
@ -36,7 +37,7 @@ class cWorld //tolua_export
|
|||
public:
|
||||
typedef std::list< cClientHandle* > ClientList;
|
||||
typedef std::list< cEntity* > EntityList;
|
||||
typedef std::list< cChunk* > ChunkList;
|
||||
typedef std::list< ptr_cChunk > ChunkList;
|
||||
typedef std::list< cPlayer* > PlayerList;
|
||||
std::vector<int> m_RSList;
|
||||
|
||||
|
@ -56,7 +57,7 @@ public:
|
|||
|
||||
cChunk* GetChunk( int a_X, int a_Y, int a_Z );
|
||||
cChunk* GetChunkReliable( int a_X, int a_Y, int a_Z );
|
||||
cChunk* GetChunkUnreliable( int a_X, int a_Y, int a_Z );
|
||||
ptr_cChunk GetChunkUnreliable( int a_X, int a_Y, int a_Z );
|
||||
cChunk* GetChunkOfBlock( int a_X, int a_Y, int a_Z );
|
||||
char GetHeight( int a_X, int a_Z ); //tolua_export
|
||||
|
||||
|
@ -148,14 +149,14 @@ public:
|
|||
void LockChunks();
|
||||
void UnlockChunks();
|
||||
|
||||
void ReSpreadLighting( cChunk* a_Chunk );
|
||||
void RemoveSpread( cChunk* a_Chunk );
|
||||
void ReSpreadLighting( const ptr_cChunk& a_Chunk );
|
||||
void RemoveSpread( const ptr_cChunk& a_Chunk );
|
||||
|
||||
void InitializeSpawn();
|
||||
|
||||
void CastThunderbolt ( int, int, int ); //tolua_export
|
||||
void CastThunderbolt ( int, int, int ); //tolua_export
|
||||
void SetWeather ( int ); //tolua_export
|
||||
int GetWeather() { return m_Weather; }; //tolua_export
|
||||
int GetWeather() { return m_Weather; }; //tolua_export
|
||||
|
||||
cWorldGenerator* GetWorldGenerator() { return m_WorldGenerator; }
|
||||
private:
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include "cChunk.h"
|
||||
|
||||
class ptr_cChunk
|
||||
{
|
||||
public:
|
||||
ptr_cChunk( cChunk* a_Ptr )
|
||||
: m_Ptr( a_Ptr )
|
||||
{
|
||||
if( m_Ptr ) m_Ptr->AddReference();
|
||||
}
|
||||
|
||||
ptr_cChunk( const ptr_cChunk& a_Clone )
|
||||
: m_Ptr( a_Clone.m_Ptr )
|
||||
{
|
||||
if( m_Ptr ) m_Ptr->AddReference();
|
||||
}
|
||||
|
||||
~ptr_cChunk()
|
||||
{
|
||||
if( m_Ptr ) m_Ptr->RemoveReference();
|
||||
}
|
||||
|
||||
cChunk* operator-> ()
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
cChunk& operator* () { return *m_Ptr; }
|
||||
bool operator!() { return !m_Ptr; }
|
||||
bool operator==( const ptr_cChunk& a_Other ) { return m_Ptr == a_Other.m_Ptr; }
|
||||
operator bool() { return m_Ptr != 0; }
|
||||
operator cChunk*() { return m_Ptr; }
|
||||
private:
|
||||
cChunk* m_Ptr;
|
||||
};
|
Loading…
Reference in New Issue