From eb942797b8a1321f7460cea7763bb6891affd475 Mon Sep 17 00:00:00 2001 From: faketruth Date: Mon, 26 Dec 2011 21:54:08 +0000 Subject: Players can switch worlds on the fly with the command /gotoworld [worldName]. This uses the function cPlayer::MoveToWorld() Changed isValidItem to IsValidItem in Core.lua git-svn-id: http://mc-server.googlecode.com/svn/trunk@126 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Bindings.cpp | 48 ++++++++++++++-- source/Bindings.h | 2 +- source/cChunk.cpp | 144 +++++++++++++++++++++++------------------------ source/cClientHandle.cpp | 14 +++++ source/cClientHandle.h | 1 + source/cEntity.h | 1 + source/cPlayer.cpp | 27 +++++++++ source/cPlayer.h | 2 + source/cServer.cpp | 10 ---- source/cServer.h | 1 - 10 files changed, 160 insertions(+), 90 deletions(-) (limited to 'source') diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 187d9d34b..d6ea00987 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 11/10/11 12:27:03. +** Generated automatically by tolua++-1.0.92 on 12/26/11 15:45:21. */ #ifndef __cplusplus @@ -2467,9 +2467,9 @@ static int tolua_AllToLua_IsValidBlock00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* function: isValidItem */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_isValidItem00 -static int tolua_AllToLua_isValidItem00(lua_State* tolua_S) +/* function: IsValidItem */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_IsValidItem00 +static int tolua_AllToLua_IsValidItem00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; @@ -2490,7 +2490,7 @@ static int tolua_AllToLua_isValidItem00(lua_State* tolua_S) return 1; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'isValidItem'.",&tolua_err); + tolua_error(tolua_S,"#ferror in function 'IsValidItem'.",&tolua_err); return 0; #endif } @@ -5884,6 +5884,40 @@ static int tolua_AllToLua_cPlayer_IsVisible00(lua_State* tolua_S) return 0; #endif } +#endif //#ifndef TOLUA_DISABLE + +/* method: MoveToWorld of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_MoveToWorld00 +static int tolua_AllToLua_cPlayer_MoveToWorld00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const char* a_WorldName = ((const char*) tolua_tostring(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'MoveToWorld'", NULL); +#endif + { + bool tolua_ret = (bool) self->MoveToWorld(a_WorldName); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'MoveToWorld'.",&tolua_err); + return 0; +#endif +} #endif //#ifndef TOLUA_DISABLE class Lua__cPlayer : public cPlayer, public ToluaBase { @@ -15827,6 +15861,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_INVENTORY_PROGRESS",E_INVENTORY_PROGRESS); tolua_constant(tolua_S,"E_CREATE_INVENTORY_ACTION",E_CREATE_INVENTORY_ACTION); tolua_constant(tolua_S,"E_UPDATE_SIGN",E_UPDATE_SIGN); + tolua_constant(tolua_S,"E_PLAYER_LIST_ITEM",E_PLAYER_LIST_ITEM); tolua_constant(tolua_S,"E_PING",E_PING); tolua_constant(tolua_S,"E_DISCONNECT",E_DISCONNECT); tolua_array(tolua_S,"g_BlockLightValue",tolua_get_AllToLua_g_BlockLightValue,tolua_set_AllToLua_g_BlockLightValue); @@ -15834,7 +15869,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_array(tolua_S,"g_BlockTransparent",tolua_get_AllToLua_g_BlockTransparent,tolua_set_AllToLua_g_BlockTransparent); tolua_array(tolua_S,"g_BlockOneHitDig",tolua_get_AllToLua_g_BlockOneHitDig,tolua_set_AllToLua_g_BlockOneHitDig); tolua_function(tolua_S,"IsValidBlock",tolua_AllToLua_IsValidBlock00); - tolua_function(tolua_S,"isValidItem",tolua_AllToLua_isValidItem00); + tolua_function(tolua_S,"IsValidItem",tolua_AllToLua_IsValidItem00); tolua_function(tolua_S,"AddDirection",tolua_AllToLua_AddDirection00); tolua_function(tolua_S,"GetTime",tolua_AllToLua_GetTime00); tolua_function(tolua_S,"GetChar",tolua_AllToLua_GetChar00); @@ -15982,6 +16017,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"Respawn",tolua_AllToLua_cPlayer_Respawn00); tolua_function(tolua_S,"SetVisible",tolua_AllToLua_cPlayer_SetVisible00); tolua_function(tolua_S,"IsVisible",tolua_AllToLua_cPlayer_IsVisible00); + tolua_function(tolua_S,"MoveToWorld",tolua_AllToLua_cPlayer_MoveToWorld00); tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"Lua__cPlayer","Lua__cPlayer","cPlayer",NULL); tolua_beginmodule(tolua_S,"Lua__cPlayer"); diff --git a/source/Bindings.h b/source/Bindings.h index a566558e9..150efff75 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 11/10/11 12:27:03. +** Generated automatically by tolua++-1.0.92 on 12/26/11 15:45:21. */ /* Exported function */ diff --git a/source/cChunk.cpp b/source/cChunk.cpp index e0322dc91..2c915d2ef 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -57,33 +57,33 @@ typedef std::list< cBlockEntity* > BlockEntityList; typedef std::list< cEntity* > EntityList; struct cChunk::sChunkState { - std::map< unsigned int, int > m_ToTickBlocks; - FurnaceEntityList m_TickBlockEntities; - std::vector< unsigned int > m_PendingSendBlocks; - ClientHandleList m_LoadedByClient; - ClientHandleList m_UnloadQuery; - BlockEntityList m_BlockEntities; - EntityList m_Entities; + std::map< unsigned int, int > ToTickBlocks; + FurnaceEntityList TickBlockEntities; + std::vector< unsigned int > PendingSendBlocks; + ClientHandleList LoadedByClient; + ClientHandleList UnloadQuery; + BlockEntityList BlockEntities; + EntityList Entities; }; cChunk::~cChunk() { //LOG("~cChunk() %i %i %i", m_PosX, m_PosY, m_PosZ ); - if( !m_pState->m_LoadedByClient.empty() ) + if( !m_pState->LoadedByClient.empty() ) { - LOGWARN("WARNING: Deleting cChunk while it contains %i clients!", m_pState->m_LoadedByClient.size() ); + LOGWARN("WARNING: Deleting cChunk while it contains %i clients!", m_pState->LoadedByClient.size() ); } - for( std::list::iterator itr = m_pState->m_BlockEntities.begin(); itr != m_pState->m_BlockEntities.end(); ++itr) + for( std::list::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr) { delete *itr; } - m_pState->m_BlockEntities.clear(); + m_pState->BlockEntities.clear(); LockEntities(); - if( m_pState->m_Entities.size() > 0 ) + if( m_pState->Entities.size() > 0 ) { - EntityList Entities = m_pState->m_Entities; // Copy list to a temporary list + EntityList Entities = m_pState->Entities; // Copy list to a temporary list for( EntityList::iterator itr = Entities.begin(); itr != Entities.end(); ++itr) { if( (*itr)->GetEntityType() != cEntity::E_PLAYER ) @@ -92,7 +92,7 @@ cChunk::~cChunk() (*itr)->Destroy(); } } - m_pState->m_Entities.clear(); + m_pState->Entities.clear(); } UnlockEntities(); @@ -143,7 +143,7 @@ void cChunk::Initialize() // During generation, some blocks might have been set by using (Fast)SetBlock() causing this list to fill. // This chunk has not been sent to anybody yet, so there is no need for separately sending block changes when you can send an entire chunk - m_pState->m_PendingSendBlocks.clear(); + m_pState->PendingSendBlocks.clear(); } else { @@ -159,7 +159,7 @@ void cChunk::Tick(float a_Dt) if( m_bCalculateHeightmap ) CalculateHeightmap(); - unsigned int PendingSendBlocks = m_pState->m_PendingSendBlocks.size(); + unsigned int PendingSendBlocks = m_pState->PendingSendBlocks.size(); if( PendingSendBlocks > 1 ) { cPacket_MultiBlock MultiBlock; @@ -172,7 +172,7 @@ void cChunk::Tick(float a_Dt) //LOG("Sending multiblock packet for %i blocks", PendingSendBlocks ); for( unsigned int i = 0; i < PendingSendBlocks; i++) { - unsigned int index = m_pState->m_PendingSendBlocks[i]; + unsigned int index = m_pState->PendingSendBlocks[i]; unsigned int Y = index % 128; unsigned int Z = (index / 128) % 16; unsigned int X = (index / (128*16)); @@ -182,15 +182,15 @@ void cChunk::Tick(float a_Dt) MultiBlock.m_BlockTypes[i] = m_BlockType[index]; MultiBlock.m_BlockMetas[i] = GetLight( m_BlockMeta, index ); } - m_pState->m_PendingSendBlocks.clear(); - PendingSendBlocks = m_pState->m_PendingSendBlocks.size(); + m_pState->PendingSendBlocks.clear(); + PendingSendBlocks = m_pState->PendingSendBlocks.size(); Broadcast( MultiBlock ); } if( PendingSendBlocks > 0 ) { for( unsigned int i = 0; i < PendingSendBlocks; i++) { - unsigned int index = m_pState->m_PendingSendBlocks[i]; + unsigned int index = m_pState->PendingSendBlocks[i]; int Y = index % 128; int Z = (index / 128) % 16; int X = (index / (128*16)); @@ -203,23 +203,23 @@ void cChunk::Tick(float a_Dt) BlockChange.m_BlockMeta = GetLight( m_BlockMeta, index ); Broadcast( BlockChange ); } - m_pState->m_PendingSendBlocks.clear(); + m_pState->PendingSendBlocks.clear(); } - while( !m_pState->m_UnloadQuery.empty() ) + while( !m_pState->UnloadQuery.empty() ) { cPacket_PreChunk UnloadPacket; UnloadPacket.m_PosX = GetPosX(); UnloadPacket.m_PosZ = GetPosZ(); UnloadPacket.m_bLoad = false; // Unload - (*m_pState->m_UnloadQuery.begin())->Send( UnloadPacket ); - m_pState->m_UnloadQuery.remove( *m_pState->m_UnloadQuery.begin() ); + (*m_pState->UnloadQuery.begin())->Send( UnloadPacket ); + m_pState->UnloadQuery.remove( *m_pState->UnloadQuery.begin() ); } - std::map< unsigned int, int > ToTickBlocks = m_pState->m_ToTickBlocks; + std::map< unsigned int, int > ToTickBlocks = m_pState->ToTickBlocks; //unsigned int NumTickBlocks = ToTickBlocks.size(); //if( NumTickBlocks > 0 ) LOG("To tick: %i", NumTickBlocks ); - m_pState->m_ToTickBlocks.clear(); + m_pState->ToTickBlocks.clear(); bool isRedstone = false; for( std::map< unsigned int, int>::iterator itr = ToTickBlocks.begin(); itr != ToTickBlocks.end(); ++itr ) { @@ -369,12 +369,12 @@ void cChunk::Tick(float a_Dt) } // Tick block entities (furnace) - std::list< cFurnaceEntity* > TickBlockEntites = m_pState->m_TickBlockEntities; // Dangerous stuff, better make a copy. + std::list< cFurnaceEntity* > TickBlockEntites = m_pState->TickBlockEntities; // Dangerous stuff, better make a copy. for( std::list< cFurnaceEntity* >::iterator itr = TickBlockEntites.begin(); itr != TickBlockEntites.end(); ++itr ) { if( !(*itr)->Tick( a_Dt ) ) // Remove from list { - m_pState->m_TickBlockEntities.remove( *itr ); + m_pState->TickBlockEntities.remove( *itr ); } } } @@ -399,18 +399,18 @@ void cChunk::CreateBlockEntities() { case E_BLOCK_CHEST: { - m_pState->m_BlockEntities.push_back( new cChestEntity( x + m_PosX*16, y + m_PosY*128, z + m_PosZ*16, this ) ); + m_pState->BlockEntities.push_back( new cChestEntity( x + m_PosX*16, y + m_PosY*128, z + m_PosZ*16, this ) ); } break; case E_BLOCK_FURNACE: { - m_pState->m_BlockEntities.push_back( new cFurnaceEntity( x + m_PosX*16, y + m_PosY*128, z + m_PosZ*16, this ) ); + m_pState->BlockEntities.push_back( new cFurnaceEntity( x + m_PosX*16, y + m_PosY*128, z + m_PosZ*16, this ) ); } break; case E_BLOCK_SIGN_POST: case E_BLOCK_WALLSIGN: { - m_pState->m_BlockEntities.push_back( new cSignEntity( BlockType, x + m_PosX*16, y + m_PosY*128, z + m_PosZ*16, this ) ); + m_pState->BlockEntities.push_back( new cSignEntity( BlockType, x + m_PosX*16, y + m_PosY*128, z + m_PosZ*16, this ) ); } break; default: @@ -695,8 +695,8 @@ void cChunk::SpreadLight(char* a_LightBuffer) void cChunk::AsyncUnload( cClientHandle* a_Client ) { - m_pState->m_UnloadQuery.remove( a_Client ); // Make sure this client is only in the list once - m_pState->m_UnloadQuery.push_back( a_Client ); + m_pState->UnloadQuery.remove( a_Client ); // Make sure this client is only in the list once + m_pState->UnloadQuery.push_back( a_Client ); } void cChunk::Send( cClientHandle* a_Client ) @@ -708,7 +708,7 @@ void cChunk::Send( cClientHandle* a_Client ) a_Client->Send( PreChunk ); a_Client->Send( cPacket_MapChunk( this ) ); - for( BlockEntityList::iterator itr = m_pState->m_BlockEntities.begin(); itr != m_pState->m_BlockEntities.end(); ++itr ) + for( BlockEntityList::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr ) { (*itr)->SendTo( a_Client ); } @@ -732,15 +732,15 @@ void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block if( OldBlockType != a_BlockType || OldBlockMeta != a_BlockMeta ) { //LOG("Old: %i %i New: %i %i", OldBlockType, OldBlockMeta, a_BlockType, a_BlockMeta ); - m_pState->m_PendingSendBlocks.push_back( index ); + m_pState->PendingSendBlocks.push_back( index ); - m_pState->m_ToTickBlocks[ MakeIndex( a_X, a_Y, a_Z ) ]++; - m_pState->m_ToTickBlocks[ MakeIndex( a_X+1, a_Y, a_Z ) ]++; - m_pState->m_ToTickBlocks[ MakeIndex( a_X-1, a_Y, a_Z ) ]++; - m_pState->m_ToTickBlocks[ MakeIndex( a_X, a_Y+1, a_Z ) ]++; - m_pState->m_ToTickBlocks[ MakeIndex( a_X, a_Y-1, a_Z ) ]++; - m_pState->m_ToTickBlocks[ MakeIndex( a_X, a_Y, a_Z+1 ) ]++; - m_pState->m_ToTickBlocks[ MakeIndex( a_X, a_Y, a_Z-1 ) ]++; + m_pState->ToTickBlocks[ MakeIndex( a_X, a_Y, a_Z ) ]++; + m_pState->ToTickBlocks[ MakeIndex( a_X+1, a_Y, a_Z ) ]++; + m_pState->ToTickBlocks[ MakeIndex( a_X-1, a_Y, a_Z ) ]++; + m_pState->ToTickBlocks[ MakeIndex( a_X, a_Y+1, a_Z ) ]++; + m_pState->ToTickBlocks[ MakeIndex( a_X, a_Y-1, a_Z ) ]++; + m_pState->ToTickBlocks[ MakeIndex( a_X, a_Y, a_Z+1 ) ]++; + m_pState->ToTickBlocks[ MakeIndex( a_X, a_Y, a_Z-1 ) ]++; cBlockEntity* BlockEntity = GetBlockEntity( a_X + m_PosX*16, a_Y+m_PosY*128, a_Z+m_PosZ*16 ); if( BlockEntity ) @@ -781,7 +781,7 @@ void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_B const int index = a_Y + (a_Z * 128) + (a_X * 128 * 16); const char OldBlock = m_BlockType[index]; m_BlockType[index] = a_BlockType; - m_pState->m_PendingSendBlocks.push_back( index ); + m_pState->PendingSendBlocks.push_back( index ); SetLight( m_BlockMeta, index, a_BlockMeta ); // ONLY recalculate lighting if it's necessary! @@ -800,11 +800,11 @@ void cChunk::SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client ) { if( a_Client == 0 ) { - m_pState->m_PendingSendBlocks.push_back( MakeIndex( a_X, a_Y, a_Z ) ); + m_pState->PendingSendBlocks.push_back( MakeIndex( a_X, a_Y, a_Z ) ); return; } - for( std::list< cClientHandle* >::iterator itr = m_pState->m_LoadedByClient.begin(); itr != m_pState->m_LoadedByClient.end(); ++itr ) + for( std::list< cClientHandle* >::iterator itr = m_pState->LoadedByClient.begin(); itr != m_pState->LoadedByClient.end(); ++itr ) { if( *itr == a_Client ) { @@ -823,21 +823,21 @@ void cChunk::SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client ) void cChunk::AddBlockEntity( cBlockEntity* a_BlockEntity ) { - m_pState->m_BlockEntities.push_back( a_BlockEntity ); + m_pState->BlockEntities.push_back( a_BlockEntity ); } void cChunk::RemoveBlockEntity( cBlockEntity* a_BlockEntity ) { - m_pState->m_BlockEntities.remove( a_BlockEntity ); + m_pState->BlockEntities.remove( a_BlockEntity ); } void cChunk::AddClient( cClientHandle* a_Client ) { - m_pState->m_LoadedByClient.remove( a_Client ); - m_pState->m_LoadedByClient.push_back( a_Client ); + m_pState->LoadedByClient.remove( a_Client ); + m_pState->LoadedByClient.push_back( a_Client ); LockEntities(); - for( EntityList::iterator itr = m_pState->m_Entities.begin(); itr != m_pState->m_Entities.end(); ++itr ) + for( EntityList::iterator itr = m_pState->Entities.begin(); itr != m_pState->Entities.end(); ++itr ) { LOG("%i %i %i Spawning on %s", m_PosX, m_PosY, m_PosZ, a_Client->GetUsername() ); (*itr)->SpawnOn( a_Client ); @@ -847,12 +847,12 @@ void cChunk::AddClient( cClientHandle* a_Client ) void cChunk::RemoveClient( cClientHandle* a_Client ) { - m_pState->m_LoadedByClient.remove( a_Client ); + m_pState->LoadedByClient.remove( a_Client ); if( !a_Client->IsDestroyed() ) { LockEntities(); - for( EntityList::iterator itr = m_pState->m_Entities.begin(); itr != m_pState->m_Entities.end(); ++itr ) + for( EntityList::iterator itr = m_pState->Entities.begin(); itr != m_pState->Entities.end(); ++itr ) { LOG("%i %i %i Destroying on %s", m_PosX, m_PosY, m_PosZ, a_Client->GetUsername() ); cPacket_DestroyEntity DestroyEntity( *itr ); @@ -865,16 +865,16 @@ void cChunk::RemoveClient( cClientHandle* a_Client ) void cChunk::AddEntity( cEntity & a_Entity ) { LockEntities(); - m_pState->m_Entities.push_back( &a_Entity ); + m_pState->Entities.push_back( &a_Entity ); UnlockEntities(); } bool cChunk::RemoveEntity( cEntity & a_Entity, cChunk* a_CalledFrom /* = 0 */ ) { LockEntities(); - unsigned int SizeBefore = m_pState->m_Entities.size(); - m_pState->m_Entities.remove( &a_Entity ); - if( SizeBefore == m_pState->m_Entities.size() ) + unsigned int SizeBefore = m_pState->Entities.size(); + m_pState->Entities.remove( &a_Entity ); + if( SizeBefore == m_pState->Entities.size() ) { LOG("WARNING: Entity was not in chunk %i %i %i", m_PosX, m_PosY, m_PosZ ); if( !a_CalledFrom ) @@ -915,7 +915,7 @@ char cChunk::GetBlock( int a_BlockIdx ) cBlockEntity* cChunk::GetBlockEntity( int a_X, int a_Y, int a_Z ) { - for( std::list::iterator itr = m_pState->m_BlockEntities.begin(); itr != m_pState->m_BlockEntities.end(); ++itr) + for( std::list::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr) { if( (*itr)->GetPosX() == a_X && (*itr)->GetPosY() == a_Y && @@ -957,7 +957,7 @@ bool cChunk::LoadFromDisk() fclose(f); return false; } - m_pState->m_BlockEntities.push_back( ChestEntity ); + m_pState->BlockEntities.push_back( ChestEntity ); } break; case E_BLOCK_FURNACE: @@ -970,8 +970,8 @@ bool cChunk::LoadFromDisk() fclose(f); return false; } - m_pState->m_BlockEntities.push_back( FurnaceEntity ); - m_pState->m_TickBlockEntities.push_back( FurnaceEntity ); // They need tickin' + m_pState->BlockEntities.push_back( FurnaceEntity ); + m_pState->TickBlockEntities.push_back( FurnaceEntity ); // They need tickin' } break; case E_BLOCK_SIGN_POST: @@ -985,7 +985,7 @@ bool cChunk::LoadFromDisk() fclose(f); return false; } - m_pState->m_BlockEntities.push_back( SignEntity ); + m_pState->BlockEntities.push_back( SignEntity ); } break; default: @@ -1041,7 +1041,7 @@ bool cChunk::SaveToDisk() fwrite( m_BlockData, sizeof(char)*c_BlockDataSize, 1, f ); // Now write Block Entities - for( std::list::iterator itr = m_pState->m_BlockEntities.begin(); itr != m_pState->m_BlockEntities.end(); ++itr) + for( std::list::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr) { cBlockEntity* BlockEntity = *itr; switch( BlockEntity->GetBlockType() ) @@ -1082,7 +1082,7 @@ bool cChunk::SaveToDisk() void cChunk::Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude /* = 0 */ ) const { - for( std::list< cClientHandle* >::const_iterator itr = m_pState->m_LoadedByClient.begin(); itr != m_pState->m_LoadedByClient.end(); ++itr ) + for( std::list< cClientHandle* >::const_iterator itr = m_pState->LoadedByClient.begin(); itr != m_pState->LoadedByClient.end(); ++itr ) { if( *itr == a_Exclude ) continue; (*itr)->Send( a_Packet ); @@ -1105,7 +1105,7 @@ void cChunk::LoadFromJson( const Json::Value & a_Value ) LOGERROR("ERROR READING CHEST FROM JSON!" ); delete ChestEntity; } - else m_pState->m_BlockEntities.push_back( ChestEntity ); + else m_pState->BlockEntities.push_back( ChestEntity ); } } @@ -1122,7 +1122,7 @@ void cChunk::LoadFromJson( const Json::Value & a_Value ) LOGERROR("ERROR READING FURNACE FROM JSON!" ); delete FurnaceEntity; } - else m_pState->m_BlockEntities.push_back( FurnaceEntity ); + else m_pState->BlockEntities.push_back( FurnaceEntity ); } } @@ -1139,7 +1139,7 @@ void cChunk::LoadFromJson( const Json::Value & a_Value ) LOGERROR("ERROR READING SIGN FROM JSON!" ); delete SignEntity; } - else m_pState->m_BlockEntities.push_back( SignEntity ); + else m_pState->BlockEntities.push_back( SignEntity ); } } } @@ -1149,7 +1149,7 @@ void cChunk::SaveToJson( Json::Value & a_Value ) Json::Value AllChests; Json::Value AllFurnaces; Json::Value AllSigns; - for( std::list::iterator itr = m_pState->m_BlockEntities.begin(); itr != m_pState->m_BlockEntities.end(); ++itr) + for( std::list::iterator itr = m_pState->BlockEntities.begin(); itr != m_pState->BlockEntities.end(); ++itr) { cBlockEntity* BlockEntity = *itr; switch( BlockEntity->GetBlockType() ) @@ -1194,24 +1194,24 @@ void cChunk::SaveToJson( Json::Value & a_Value ) EntityList & cChunk::GetEntities() { - return m_pState->m_Entities; + return m_pState->Entities; } const ClientHandleList & cChunk::GetClients() { - return m_pState->m_LoadedByClient; + return m_pState->LoadedByClient; } void cChunk::AddTickBlockEntity( cFurnaceEntity* a_Entity ) { - m_pState->m_TickBlockEntities.remove( a_Entity ); - m_pState->m_TickBlockEntities.push_back( a_Entity ); + m_pState->TickBlockEntities.remove( a_Entity ); + m_pState->TickBlockEntities.push_back( a_Entity ); } void cChunk::RemoveTickBlockEntity( cFurnaceEntity* a_Entity ) { - m_pState->m_TickBlockEntities.remove( a_Entity ); + m_pState->TickBlockEntities.remove( a_Entity ); } diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index 4e71c7169..f7b93ca7e 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -375,6 +375,20 @@ void cClientHandle::StreamChunksSmart( cChunk** a_Chunks, unsigned int a_NumChun } } +// This removes the client from all chunks. Used when switching worlds +void cClientHandle::RemoveFromAllChunks() +{ + for(int i = 0; i < VIEWDISTANCE*VIEWDISTANCE; i++) + { + if( m_LoadedChunks[i] ) + { + m_LoadedChunks[i]->RemoveClient( this ); + m_LoadedChunks[i]->AsyncUnload( this ); + m_LoadedChunks[i] = 0; + } + } +} + void cClientHandle::AddPacket(cPacket * a_Packet) { m_pState->CriticalSection.Lock(); diff --git a/source/cClientHandle.h b/source/cClientHandle.h index 67ef56747..7550e5e05 100644 --- a/source/cClientHandle.h +++ b/source/cClientHandle.h @@ -33,6 +33,7 @@ public: void StreamChunks(); void StreamChunksSmart( cChunk** a_Chunks, unsigned int a_NumChunks ); + void RemoveFromAllChunks(); inline void SetLoggedIn( bool a_bLoggedIn ) { m_bLoggedIn = a_bLoggedIn; } inline bool IsLoggedIn() { return m_bLoggedIn; } diff --git a/source/cEntity.h b/source/cEntity.h index af86c2606..80fc33cf1 100644 --- a/source/cEntity.h +++ b/source/cEntity.h @@ -86,6 +86,7 @@ public: //tolua_export void WrapRotation(); protected: + void SetWorld( cWorld* a_World ) { m_World = a_World; } void MoveToCorrectChunk(bool a_bIgnoreOldChunk = false); friend class cReferenceManager; diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp index 5fe31c8c9..dcc9de177 100644 --- a/source/cPlayer.cpp +++ b/source/cPlayer.cpp @@ -701,6 +701,33 @@ void cPlayer::TossItem( bool a_bDraggingItem, int a_Amount /* = 1 */ ) } } +bool cPlayer::MoveToWorld( const char* a_WorldName ) +{ + cWorld* World = cRoot::Get()->GetWorld( a_WorldName ); + if( World ) + { + /* Remove all links to the old world */ + GetWorld()->RemovePlayer( this ); + GetClientHandle()->RemoveFromAllChunks(); + cChunk* Chunk = GetWorld()->GetChunkUnreliable( m_ChunkX, m_ChunkY, m_ChunkZ ); + if( Chunk ) + { + Chunk->RemoveEntity( *this ); + Chunk->Broadcast( cPacket_DestroyEntity( this ) ); // Remove player entity from all clients in old world + } + + /* Add player to all the necessary parts of the new world */ + SetWorld( World ); + GetWorld()->AddPlayer( this ); + MoveToCorrectChunk(true); + GetClientHandle()->StreamChunks(); + + return true; + } + + return false; +} + bool cPlayer::LoadFromDisk() // TODO - This should also get/set/whatever the correct world for this player { cIniFile IniFile("users.ini"); diff --git a/source/cPlayer.h b/source/cPlayer.h index 6f52b3f1f..17e575e91 100644 --- a/source/cPlayer.h +++ b/source/cPlayer.h @@ -75,6 +75,8 @@ public: void SetVisible( bool a_bVisible ); //tolua_export bool IsVisible() { return m_bVisible; } //tolua_export + bool MoveToWorld( const char* a_WorldName ); //tolua_export + bool SaveToDisk(); bool LoadFromDisk(); diff --git a/source/cServer.cpp b/source/cServer.cpp index ebd91db94..81444f8e1 100644 --- a/source/cServer.cpp +++ b/source/cServer.cpp @@ -258,16 +258,6 @@ void cServer::Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude /* = } } -// TODO - Need to move this to cWorld I think -void cServer::SendAllEntitiesTo(cClientHandle* a_Target) -{ - cWorld* World = cRoot::Get()->GetWorld(); - for( cWorld::EntityList::iterator itr = World->GetEntities().begin(); itr != World->GetEntities().end(); ++itr) - { - (*itr)->SpawnOn( a_Target ); - } -} - void cServer::StartListenClient() { cSocket SClient = m_pState->SListenClient.Accept(); diff --git a/source/cServer.h b/source/cServer.h index c8a669949..718ac4c36 100644 --- a/source/cServer.h +++ b/source/cServer.h @@ -19,7 +19,6 @@ public: //tolua_export int RecClient(cClientHandle *sRecSocket); // receive message for a particular socket void Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude = 0 ); - void SendAllEntitiesTo( cClientHandle* a_Target ); bool Tick(float a_Dt); -- cgit v1.2.3