Slight cleanup - removed old code, some additional comments on dangerous functions
git-svn-id: http://mc-server.googlecode.com/svn/trunk@261 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
e7ea352f41
commit
19e711a1e3
@ -225,14 +225,6 @@
|
||||
RelativePath="..\source\cChunkGenerator.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\cChunkLoader.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\cChunkLoader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\cChunkMap.cpp"
|
||||
>
|
||||
|
@ -308,7 +308,6 @@
|
||||
<ClCompile Include="..\source\cCavespider.cpp" />
|
||||
<ClCompile Include="..\Source\cChicken.cpp" />
|
||||
<ClCompile Include="..\source\cChunkGenerator.cpp" />
|
||||
<ClCompile Include="..\source\cChunkLoader.cpp" />
|
||||
<ClCompile Include="..\Source\cChunkMap.cpp" />
|
||||
<ClCompile Include="..\source\cCow.cpp" />
|
||||
<ClCompile Include="..\source\cCraftingWindow.cpp" />
|
||||
@ -492,7 +491,6 @@
|
||||
<ClInclude Include="..\source\cCavespider.h" />
|
||||
<ClInclude Include="..\Source\cChicken.h" />
|
||||
<ClInclude Include="..\source\cChunkGenerator.h" />
|
||||
<ClInclude Include="..\source\cChunkLoader.h" />
|
||||
<ClInclude Include="..\Source\cChunkMap.h" />
|
||||
<ClInclude Include="..\source\cCow.h" />
|
||||
<ClInclude Include="..\source\cCraftingWindow.h" />
|
||||
|
@ -217,9 +217,6 @@
|
||||
<Filter Include="Packets\cPacket_WindowClick">
|
||||
<UniqueIdentifier>{378afb88-8909-455c-aaf9-4d41387b2bea}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="cChunkLoader">
|
||||
<UniqueIdentifier>{177e25ee-63e6-4382-8560-4f309ae8242d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="cNoise">
|
||||
<UniqueIdentifier>{58d6aa00-beab-4654-bbbd-c3b0397a9549}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@ -670,9 +667,6 @@
|
||||
<ClCompile Include="..\source\packets\cPacket_WindowClick.cpp">
|
||||
<Filter>Packets\cPacket_WindowClick</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\source\cChunkLoader.cpp">
|
||||
<Filter>cChunkLoader</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\source\cCuboid.cpp">
|
||||
<Filter>Vector3f</Filter>
|
||||
</ClCompile>
|
||||
@ -1161,9 +1155,6 @@
|
||||
<ClInclude Include="..\source\packets\cPacket_WindowClick.h">
|
||||
<Filter>Packets\cPacket_WindowClick</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\source\cChunkLoader.h">
|
||||
<Filter>cChunkLoader</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\source\cCuboid.h">
|
||||
<Filter>Vector3f</Filter>
|
||||
</ClInclude>
|
||||
|
@ -52,7 +52,6 @@ public:
|
||||
cChunk(int a_X, int a_Y, int a_Z, cWorld* a_World);
|
||||
~cChunk();
|
||||
|
||||
void Initialize();
|
||||
bool IsValid(void) const {return m_IsValid; } // Returns true if the chunk is valid (loaded / generated)
|
||||
void SetValid(bool a_SendToClients = true); // Also wakes up all clients attached to this chunk to let them finish logging in
|
||||
bool CanUnload(void);
|
||||
@ -87,9 +86,6 @@ public:
|
||||
void AddEntity( cEntity * a_Entity );
|
||||
void RemoveEntity( cEntity * a_Entity);
|
||||
|
||||
// TODO: This interface is dangerous
|
||||
OBSOLETE const std::list< cClientHandle* > & GetClients();// { return m_LoadedByClient; }
|
||||
|
||||
inline void RecalculateLighting() { m_bCalculateLighting = true; } // Recalculate lighting next tick
|
||||
inline void RecalculateHeightmap() { m_bCalculateHeightmap = true; } // Recalculate heightmap next tick
|
||||
void SpreadLight(char* a_LightBuffer);
|
||||
@ -102,6 +98,10 @@ public:
|
||||
void Broadcast( const cPacket & a_Packet, cClientHandle * a_Exclude = NULL) {Broadcast(&a_Packet, a_Exclude); }
|
||||
void Broadcast( const cPacket * a_Packet, cClientHandle * a_Exclude = NULL);
|
||||
|
||||
// TODO: These functions are dangerous - rewrite to:
|
||||
// Loaded(blockdata, lightdata, blockentities, entities),
|
||||
// Generated(blockdata, lightdata, blockentities, entities),
|
||||
// GetBlockData(blockdatadest) etc.
|
||||
char* pGetBlockData() { return m_BlockData; }
|
||||
char* pGetType() { return m_BlockType; }
|
||||
char* pGetMeta() { return m_BlockMeta; }
|
||||
@ -109,6 +109,8 @@ public:
|
||||
char* pGetSkyLight() { return m_BlockSkyLight; }
|
||||
|
||||
void CopyBlockDataFrom(const char * a_NewBlockData); // Copies all blockdata, recalculates heightmap (used by chunk loaders)
|
||||
|
||||
// TODO: Move this into the specific WSSchema:
|
||||
void LoadFromJson( const Json::Value & a_Value );
|
||||
void SaveToJson( Json::Value & a_Value );
|
||||
|
||||
@ -122,18 +124,15 @@ public:
|
||||
inline static unsigned int MakeIndex(int x, int y, int z )
|
||||
{
|
||||
if( x < 16 && x > -1 && y < 128 && y > -1 && z < 16 && z > -1 )
|
||||
{
|
||||
return y + (z * 128) + (x * 128 * 16);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const int c_NumBlocks = 16*128*16;
|
||||
static const int c_BlockDataSize = c_NumBlocks * 2 + (c_NumBlocks/2); // 2.5 * numblocks
|
||||
|
||||
// Reference counting
|
||||
void AddReference();
|
||||
void RemoveReference();
|
||||
int GetReferenceCount();
|
||||
|
||||
private:
|
||||
|
||||
bool m_IsValid; // True if the chunk is loaded / generated
|
||||
|
@ -1,359 +0,0 @@
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#if 0 // ignore all contents of this file
|
||||
#include "cChunkLoader.h"
|
||||
#include "cChunk.h"
|
||||
#include "cMCLogger.h"
|
||||
#include "BlockID.h"
|
||||
#include "cCriticalSection.h"
|
||||
#include "cEvent.h"
|
||||
#include "cThread.h"
|
||||
#include "cSleep.h"
|
||||
|
||||
#include "cChestEntity.h"
|
||||
#include "cFurnaceEntity.h"
|
||||
#include "cSignEntity.h"
|
||||
|
||||
#include <iostream>
|
||||
#ifndef _WIN32
|
||||
#include <cstdlib>
|
||||
#endif
|
||||
|
||||
struct ChunkData
|
||||
{
|
||||
ChunkData()
|
||||
: x( 0 )
|
||||
, z( 0 )
|
||||
, Data( 0 )
|
||||
, LiveChunk( 0 )
|
||||
{}
|
||||
int x, z;
|
||||
unsigned int DataSize;
|
||||
unsigned int ChunkStart;
|
||||
char* Data;
|
||||
cChunk* LiveChunk;
|
||||
};
|
||||
|
||||
typedef std::list< ChunkData > ChunkDataList;
|
||||
struct cChunkLoader::ChunkPack
|
||||
{
|
||||
ChunkDataList AllChunks;
|
||||
int x, y, z;
|
||||
};
|
||||
|
||||
typedef std::list< cChunkLoader::ChunkPack > ChunkPackList;
|
||||
struct cChunkLoader::ChunkPacks
|
||||
{
|
||||
ChunkPackList AllPacks;
|
||||
};
|
||||
|
||||
cChunkLoader::cChunkLoader()
|
||||
: m_bStop( false )
|
||||
, m_CriticalSection( new cCriticalSection() )
|
||||
, m_Event( new cEvent() )
|
||||
, m_ChunkPacks( new ChunkPacks )
|
||||
{
|
||||
cThread( SaveThread, this );
|
||||
}
|
||||
|
||||
cChunkLoader::~cChunkLoader()
|
||||
{
|
||||
m_bStop = true;
|
||||
m_Event->Wait();
|
||||
delete m_CriticalSection;
|
||||
}
|
||||
|
||||
void cChunkLoader::SaveThread( void* a_Param )
|
||||
{
|
||||
cChunkLoader* self = (cChunkLoader*)a_Param;
|
||||
while( !self->m_bStop )
|
||||
{
|
||||
cSleep::MilliSleep( 1000 ); // Only check for saving once a second
|
||||
}
|
||||
self->m_Event->Set();
|
||||
}
|
||||
|
||||
cChunk* cChunkLoader::LoadChunk( int a_X, int a_Y, int a_Z )
|
||||
{
|
||||
m_CriticalSection->Lock();
|
||||
cChunk* Chunk = 0;
|
||||
|
||||
Chunk = LoadOldFormat( a_X, a_Y, a_Z );
|
||||
if( Chunk ) { Chunk->CalculateHeightmap(); }
|
||||
else
|
||||
{
|
||||
1; // load new format()
|
||||
}
|
||||
|
||||
m_CriticalSection->Unlock();
|
||||
return Chunk;
|
||||
}
|
||||
|
||||
bool cChunkLoader::SaveChunk( const cChunk & a_Chunk )
|
||||
{
|
||||
m_CriticalSection->Lock();
|
||||
bool Success = SaveOldFormat( a_Chunk );
|
||||
m_CriticalSection->Unlock();
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Old format stuffs
|
||||
**/
|
||||
|
||||
cChunk* cChunkLoader::LoadOldFormat( int a_X, int a_Y, int a_Z )
|
||||
{
|
||||
AString SourceFile;
|
||||
Printf(SourceFile, "world/X%i_Y%i_Z%i.bin", a_X, a_Y, a_Z );
|
||||
|
||||
FILE* f = 0;
|
||||
#ifdef _WIN32
|
||||
if( fopen_s(&f, SourceFile, "rb" ) == 0 ) // no error
|
||||
#else
|
||||
if( (f = fopen(SourceFile, "rb" )) != 0 ) // no error
|
||||
#endif
|
||||
{
|
||||
cChunk* Chunk = new cChunk( a_X, a_Y, a_Z );
|
||||
if( fread( Chunk->m_BlockData, sizeof(char)*cChunk::c_BlockDataSize, 1, f) != 1 ) { LOGERROR("ERROR READING FROM FILE %s", SourceFile); fclose(f); return false; }
|
||||
|
||||
// Now load Block Entities
|
||||
ENUM_BLOCK_ID BlockType;
|
||||
while( fread( &BlockType, sizeof(ENUM_BLOCK_ID), 1, f) == 1 )
|
||||
{
|
||||
switch( BlockType )
|
||||
{
|
||||
case E_BLOCK_CHEST:
|
||||
{
|
||||
cChestEntity* ChestEntity = new cChestEntity( 0, 0, 0 );
|
||||
if( !ChestEntity->LoadFromFile( f ) )
|
||||
{
|
||||
LOGERROR("ERROR READING CHEST FROM FILE %s", SourceFile );
|
||||
delete ChestEntity;
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
Chunk->m_BlockEntities.push_back( ChestEntity );
|
||||
}
|
||||
break;
|
||||
case E_BLOCK_FURNACE:
|
||||
{
|
||||
cFurnaceEntity* FurnaceEntity = new cFurnaceEntity( 0, 0, 0 );
|
||||
if( !FurnaceEntity->LoadFromFile( f ) )
|
||||
{
|
||||
LOGERROR("ERROR READING FURNACE FROM FILE %s", SourceFile );
|
||||
delete FurnaceEntity;
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
Chunk->m_BlockEntities.push_back( FurnaceEntity );
|
||||
Chunk->m_TickBlockEntities.push_back( FurnaceEntity ); // They need tickin'
|
||||
}
|
||||
break;
|
||||
case E_BLOCK_SIGN_POST:
|
||||
case E_BLOCK_WALLSIGN:
|
||||
{
|
||||
cSignEntity* SignEntity = new cSignEntity(BlockType, 0, 0, 0 );
|
||||
if( !SignEntity->LoadFromFile( f ) )
|
||||
{
|
||||
LOGERROR("ERROR READING SIGN FROM FILE %s", SourceFile );
|
||||
delete SignEntity;
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
Chunk->m_BlockEntities.push_back( SignEntity );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return Chunk;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool cChunkLoader::SaveOldFormat( const cChunk & a_Chunk )
|
||||
{
|
||||
AString SourceFile;
|
||||
Printf(SourceFile, "world/X%i_Y%i_Z%i.bin", a_Chunk.m_PosX, a_Chunk.m_PosY, a_Chunk.m_PosZ );
|
||||
|
||||
#ifdef _WIN32
|
||||
{
|
||||
SECURITY_ATTRIBUTES Attrib;
|
||||
Attrib.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
Attrib.lpSecurityDescriptor = NULL;
|
||||
Attrib.bInheritHandle = false;
|
||||
::CreateDirectory("world", &Attrib);
|
||||
}
|
||||
#else
|
||||
{
|
||||
mkdir("world", S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
}
|
||||
#endif
|
||||
|
||||
FILE* f = 0;
|
||||
#ifdef _WIN32
|
||||
if( fopen_s(&f, SourceFile, "wb" ) == 0 ) // no error
|
||||
#else
|
||||
if( (f = fopen(SourceFile, "wb" )) != 0 ) // no error
|
||||
#endif
|
||||
{
|
||||
fwrite( a_Chunk.m_BlockData, sizeof(char)*cChunk::c_BlockDataSize, 1, f );
|
||||
|
||||
// Now write Block Entities
|
||||
for( std::list<cBlockEntity*>::const_iterator itr = a_Chunk.m_BlockEntities.begin(); itr != a_Chunk.m_BlockEntities.end(); ++itr)
|
||||
{
|
||||
cBlockEntity* BlockEntity = *itr;
|
||||
switch( BlockEntity->GetBlockType() )
|
||||
{
|
||||
case E_BLOCK_CHEST:
|
||||
{
|
||||
cChestEntity* ChestEntity = reinterpret_cast< cChestEntity* >( BlockEntity );
|
||||
ChestEntity->WriteToFile( f );
|
||||
}
|
||||
break;
|
||||
case E_BLOCK_FURNACE:
|
||||
{
|
||||
cFurnaceEntity* FurnaceEntity = reinterpret_cast< cFurnaceEntity* >( BlockEntity );
|
||||
FurnaceEntity->WriteToFile( f );
|
||||
}
|
||||
break;
|
||||
case E_BLOCK_SIGN_POST:
|
||||
case E_BLOCK_WALLSIGN:
|
||||
{
|
||||
cSignEntity* SignEntity = reinterpret_cast< cSignEntity* >( BlockEntity );
|
||||
SignEntity->WriteToFile( f );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR("ERROR WRITING TO FILE %s", SourceFile);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************
|
||||
* New format
|
||||
**/
|
||||
|
||||
cChunk* cChunkLoader::LoadFormat1( int a_X, int a_Y, int a_Z )
|
||||
{
|
||||
int PakX = (int)(floorf((float)a_X / 16.f));
|
||||
int PakY = (int)(floorf((float)a_Y / 16.f));
|
||||
int PakZ = (int)(floorf((float)a_Z / 16.f));
|
||||
|
||||
ChunkPack * Pack = 0;
|
||||
ChunkPackList & PackList = m_ChunkPacks->AllPacks;
|
||||
for( ChunkPackList::iterator itr = PackList.begin(); itr != PackList.end(); ++itr )
|
||||
{
|
||||
if( itr->x == PakX && itr->y == PakY && itr->z == PakZ )
|
||||
{
|
||||
Pack = &(*itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !Pack ) // The pack was not in memory, so try to load it from disk
|
||||
{
|
||||
Pack = LoadPak1( PakX, PakY, PakZ ); // Load .pak file from disk
|
||||
if( Pack )
|
||||
{
|
||||
PackList.push_back( *Pack ); // Add it to the loaded list
|
||||
}
|
||||
}
|
||||
|
||||
if( Pack ) // Allright, the pack is in memory
|
||||
{
|
||||
ChunkData * Data = 0;
|
||||
ChunkDataList & ChunkList = Pack->AllChunks;
|
||||
for( ChunkDataList::iterator itr = ChunkList.begin(); itr != ChunkList.end(); ++itr )
|
||||
{
|
||||
if( itr->x == a_X && itr->z == a_Z )
|
||||
{
|
||||
Data = &(*itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !Data ) // Sorry, chunk does not exist (yet)
|
||||
return 0;
|
||||
|
||||
if( Data->LiveChunk ) // This chunk is already loaded and decoded (this should actually never happen)
|
||||
return Data->LiveChunk;
|
||||
|
||||
// Decompress chunk, and return brand new chunk
|
||||
|
||||
// doing it...
|
||||
|
||||
return 0; // actually return the chunk
|
||||
}
|
||||
|
||||
return 0; // .pak file didn't exist
|
||||
}
|
||||
|
||||
cChunkLoader::ChunkPack* cChunkLoader::LoadPak1( int PakX, int PakY, int PakZ )
|
||||
{
|
||||
AString SourceFile;
|
||||
Printf(SourceFile, "world/X%i_Y%i_Z%i.pak", PakX, PakY, PakZ );
|
||||
|
||||
FILE* f = 0;
|
||||
#ifdef _WIN32
|
||||
if( fopen_s(&f, SourceFile, "rb" ) == 0 ) // no error
|
||||
#else
|
||||
if( (f = fopen(SourceFile, "rb" )) != 0 ) // no error
|
||||
#endif
|
||||
{
|
||||
cChunkLoader::ChunkPack * Pack = new cChunkLoader::ChunkPack;
|
||||
Pack->x = PakX;
|
||||
Pack->y = PakY;
|
||||
Pack->z = PakZ;
|
||||
|
||||
short Version = 0;
|
||||
if( fread( &Version, sizeof( short ), 1, f ) != 1 ) { LOGERROR("Error reading file %s", SourceFile ); return 0; }
|
||||
if( Version != 1 ) { LOGERROR("Wrong pak version! %s", SourceFile ); return 0; }
|
||||
short NumChunks = 0;
|
||||
if( fread( &NumChunks, sizeof( short ), 1, f ) != 1 ) { LOGERROR("Error reading file %s", SourceFile ); return 0; }
|
||||
|
||||
// Load all the headers
|
||||
for( short i = 0; i < NumChunks; ++i )
|
||||
{
|
||||
ChunkData Data;
|
||||
if( fread( &Data.x, sizeof( int ), 1, f ) != 1 ) { LOGERROR("Error reading file %s", SourceFile ); return 0; }
|
||||
if( fread( &Data.z, sizeof( int ), 1, f ) != 1 ) { LOGERROR("Error reading file %s", SourceFile ); return 0; }
|
||||
if( fread( &Data.DataSize, sizeof( unsigned int ), 1, f ) != 1 ) { LOGERROR("Error reading file %s", SourceFile ); return 0; }
|
||||
if( fread( &Data.ChunkStart, sizeof( unsigned int ), 1, f ) != 1 ) { LOGERROR("Error reading file %s", SourceFile ); return 0; }
|
||||
Pack->AllChunks.push_back( Data );
|
||||
}
|
||||
|
||||
// Load all compressed chunk data in the order the headers were loaded
|
||||
ChunkDataList::iterator itr = Pack->AllChunks.begin();
|
||||
for( short i = 0; i < NumChunks; ++i )
|
||||
{
|
||||
itr->Data = new char[ itr->DataSize ];
|
||||
if( fread( itr->Data, sizeof( char ) * itr->DataSize, 1, f ) != 1 ) { LOGERROR("Error reading file %s", SourceFile ); return 0; }
|
||||
++itr;
|
||||
}
|
||||
|
||||
// And we're done :)
|
||||
return Pack;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@ -1,30 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
class cChunk;
|
||||
class cChunkLoader
|
||||
{
|
||||
public:
|
||||
cChunkLoader();
|
||||
~cChunkLoader();
|
||||
|
||||
cChunk* LoadChunk( int a_X, int a_Y, int a_Z );
|
||||
bool SaveChunk( const cChunk & a_Chunk );
|
||||
|
||||
struct ChunkPack;
|
||||
private:
|
||||
cChunk* LoadFormat1( int a_X, int a_Y, int a_Z );
|
||||
ChunkPack* LoadPak1( int PakX, int PakY, int PakZ ); // This loads a .pak file from disk and returns it, nothing more
|
||||
|
||||
// Old stuffs
|
||||
cChunk* LoadOldFormat( int a_X, int a_Y, int a_Z );
|
||||
bool SaveOldFormat( const cChunk & a_Chunk );
|
||||
|
||||
static void SaveThread( void* a_Param );
|
||||
|
||||
bool m_bStop;
|
||||
cCriticalSection* m_CriticalSection;
|
||||
cEvent* m_Event;
|
||||
|
||||
struct ChunkPacks; // Defined in .cpp
|
||||
ChunkPacks* m_ChunkPacks;
|
||||
};
|
@ -27,8 +27,8 @@ public:
|
||||
cChunkMap(cWorld* a_World );
|
||||
~cChunkMap();
|
||||
|
||||
cChunkPtr GetChunk ( int a_X, int a_Y, int a_Z ); // Also queues the chunk for loading / generating if not valid
|
||||
cChunkPtr GetChunkNoGen( int a_X, int a_Y, int a_Z ); // Also queues the chunk for loading if not valid; doesn't generate
|
||||
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
|
||||
|
||||
void Tick( float a_Dt, MTRand & a_TickRand );
|
||||
|
||||
|
@ -82,9 +82,10 @@ public:
|
||||
// >> EXPORTED IN MANUALBINDINGS <<
|
||||
unsigned int GetNumPlayers(); //tolua_export
|
||||
|
||||
// TODO: This interface is dangerous
|
||||
// TODO: This interface is dangerous - rewrite to DoWithPlayer(playername, action)
|
||||
cPlayer * GetPlayer( const char * a_PlayerName ); //tolua_export
|
||||
|
||||
// TODO: This interface is dangerous - rewrite to DoWithClosestPlayer(pos, sight, action)
|
||||
cPlayer * FindClosestPlayer(const Vector3f & a_Pos, float a_SightLimit);
|
||||
|
||||
void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player
|
||||
|
Loading…
Reference in New Issue
Block a user