1
0

Made a couple of functions in cChunk inline, this should speed up several block operations on chunks

Players should not spawn in the ground anymore.
When an entity was added to cWorld twice (which shouldn't happen actually), the server would crash when the entity is destroyed, this should be fixed now.

git-svn-id: http://mc-server.googlecode.com/svn/trunk@158 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
faketruth 2011-12-31 21:08:23 +00:00
parent 9d3b2d1335
commit 9af5ed43fd
7 changed files with 152 additions and 124 deletions

View File

@ -526,6 +526,7 @@
</ItemGroup>
<ItemGroup>
<None Include="..\source\AllToLua.pkg" />
<None Include="..\source\cChunk.inl.h" />
<None Include="..\source\cNoise.inc" />
<None Include="icon.ico" />
</ItemGroup>

View File

@ -1362,6 +1362,9 @@
<None Include="..\source\cNoise.inc">
<Filter>cNoise</Filter>
</None>
<None Include="..\source\cChunk.inl.h">
<Filter>cChunk</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="MCServer.rc" />

View File

@ -435,108 +435,6 @@ void cChunk::CreateBlockEntities()
m_pState->BlockListCriticalSection.Unlock();
}
char cChunk::GetLight(char* a_Buffer, int a_BlockIdx)
{
if( a_BlockIdx > -1 && a_BlockIdx < c_NumBlocks )
{
const int cindex = (a_BlockIdx/2);
if( (a_BlockIdx & 1) == 0 )
{ // First half byte
return (a_Buffer[cindex] & 0x0f);
}
else
{
return ((a_Buffer[cindex] & 0xf0) >> 4);
}
}
return 0;
}
char cChunk::GetLight(char* a_Buffer, int x, int y, int z)
{
if( x < 16 && x > -1 && y < 128 && y > -1 && z < 16 && z > -1 )
{
const int cindex = (y/2) + (z * 64) + (x * 64 * 16);
if( (y & 1) == 0 )
{ // First half byte
return (a_Buffer[cindex] & 0x0f);
}
else
{
return ((a_Buffer[cindex] & 0xf0) >> 4);
}
}
return 0;
}
void cChunk::SetLight(char* a_Buffer, int a_BlockIdx, char a_Light)
{
if( a_BlockIdx > -1 && a_BlockIdx < c_NumBlocks )
{
const int cindex = (a_BlockIdx/2);
if( (a_BlockIdx & 1) == 0 )
{ // First half byte
a_Buffer[cindex] &= 0xf0; // Set first half to 0
a_Buffer[cindex] |= (a_Light) & 0x0f;
}
else
{
a_Buffer[cindex] &= 0x0f; // Set second half to 0
a_Buffer[cindex] |= (a_Light << 4) & 0xf0;
}
}
}
void cChunk::SetLight(char* a_Buffer, int x, int y, int z, char light)
{
if( x < 16 && x > -1 && y < 128 && y > -1 && z < 16 && z > -1 )
{
int cindex = (y/2) + (z * 64) + (x * 64 * 16);
if( (y & 1) == 0 )
{ // First half byte
a_Buffer[cindex] &= 0xf0; // Set first half to 0
a_Buffer[cindex] |= (light) & 0x0f;
}
else
{
a_Buffer[cindex] &= 0x0f; // Set second half to 0
a_Buffer[cindex] |= (light << 4) & 0xf0;
}
}
}
inline void cChunk::SpreadLightOfBlock(char* a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff)
{
unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z );
SetLight( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X-1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
SetLight( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X+1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
SetLight( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y-1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
SetLight( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y+1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
SetLight( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z-1 ), MAX(0,CurrentLight-a_Falloff) ) );
SetLight( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z+1 ), MAX(0,CurrentLight-a_Falloff) ) );
}
inline void cChunk::SpreadLightOfBlockX(char* a_LightBuffer, int a_X, int a_Y, int a_Z)
{
unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z );
SetLight( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X-1, a_Y, a_Z ), CurrentLight-1) );
SetLight( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X+1, a_Y, a_Z ), CurrentLight-1) );
}
inline void cChunk::SpreadLightOfBlockY(char* a_LightBuffer, int a_X, int a_Y, int a_Z)
{
unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z );
SetLight( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y-1, a_Z ), CurrentLight-1) );
SetLight( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y+1, a_Z ), CurrentLight-1) );
}
inline void cChunk::SpreadLightOfBlockZ(char* a_LightBuffer, int a_X, int a_Y, int a_Z)
{
unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z );
SetLight( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z-1 ), CurrentLight-1) );
SetLight( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z+1 ), CurrentLight-1) );
}
void cChunk::CalculateHeightmap()
{
m_bCalculateHeightmap = false;
@ -783,8 +681,8 @@ void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block
m_pState->BlockListCriticalSection.Unlock();
}
CalculateHeightmap();
RecalculateLighting();
//RecalculateHeightmap();
//RecalculateLighting();
}
void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta )
@ -1258,4 +1156,9 @@ void cChunk::PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, i
a_Y = a_ChunkY;
a_X = m_PosX * 16 + a_ChunkX;
a_Z = m_PosZ * 16 + a_ChunkZ;
}
}
#if !C_CHUNK_USE_INLINE
# include "cChunk.inc"
#endif

View File

@ -1,5 +1,14 @@
#pragma once
#define C_CHUNK_USE_INLINE 1
// Do not touch
#if C_CHUNK_USE_INLINE
# define __C_CHUNK_INLINE__ inline
#else
# define __C_CHUNK_INLINE__
#endif
#include <list>
namespace Json
@ -128,4 +137,8 @@ private:
unsigned int m_BlockTickX, m_BlockTickY, m_BlockTickZ;
cCriticalSection* m_EntitiesCriticalSection;
};
};
#if C_CHUNK_USE_INLINE
# include "cChunk.inl.h"
#endif

118
source/cChunk.inl.h Normal file
View File

@ -0,0 +1,118 @@
#ifndef __C_CHUNK_INL_H__
#define __C_CHUNK_INL_H__
#ifndef MAX
# define MAX(a,b) (((a)>(b))?(a):(b))
#endif
__C_CHUNK_INLINE__
char cChunk::GetLight(char* a_Buffer, int a_BlockIdx)
{
if( a_BlockIdx > -1 && a_BlockIdx < c_NumBlocks )
{
const int cindex = (a_BlockIdx/2);
if( (a_BlockIdx & 1) == 0 )
{ // First half byte
return (a_Buffer[cindex] & 0x0f);
}
else
{
return ((a_Buffer[cindex] & 0xf0) >> 4);
}
}
return 0;
}
__C_CHUNK_INLINE__
char cChunk::GetLight(char* a_Buffer, int x, int y, int z)
{
if( x < 16 && x > -1 && y < 128 && y > -1 && z < 16 && z > -1 )
{
const int cindex = (y/2) + (z * 64) + (x * 64 * 16);
if( (y & 1) == 0 )
{ // First half byte
return (a_Buffer[cindex] & 0x0f);
}
else
{
return ((a_Buffer[cindex] & 0xf0) >> 4);
}
}
return 0;
}
__C_CHUNK_INLINE__
void cChunk::SetLight(char* a_Buffer, int a_BlockIdx, char a_Light)
{
if( a_BlockIdx > -1 && a_BlockIdx < c_NumBlocks )
{
const int cindex = (a_BlockIdx/2);
if( (a_BlockIdx & 1) == 0 )
{ // First half byte
a_Buffer[cindex] &= 0xf0; // Set first half to 0
a_Buffer[cindex] |= (a_Light) & 0x0f;
}
else
{
a_Buffer[cindex] &= 0x0f; // Set second half to 0
a_Buffer[cindex] |= (a_Light << 4) & 0xf0;
}
}
}
__C_CHUNK_INLINE__
void cChunk::SetLight(char* a_Buffer, int x, int y, int z, char light)
{
if( x < 16 && x > -1 && y < 128 && y > -1 && z < 16 && z > -1 )
{
int cindex = (y/2) + (z * 64) + (x * 64 * 16);
if( (y & 1) == 0 )
{ // First half byte
a_Buffer[cindex] &= 0xf0; // Set first half to 0
a_Buffer[cindex] |= (light) & 0x0f;
}
else
{
a_Buffer[cindex] &= 0x0f; // Set second half to 0
a_Buffer[cindex] |= (light << 4) & 0xf0;
}
}
}
__C_CHUNK_INLINE__
void cChunk::SpreadLightOfBlock(char* a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff)
{
unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z );
SetLight( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X-1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
SetLight( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X+1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
SetLight( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y-1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
SetLight( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y+1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
SetLight( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z-1 ), MAX(0,CurrentLight-a_Falloff) ) );
SetLight( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z+1 ), MAX(0,CurrentLight-a_Falloff) ) );
}
__C_CHUNK_INLINE__
void cChunk::SpreadLightOfBlockX(char* a_LightBuffer, int a_X, int a_Y, int a_Z)
{
unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z );
SetLight( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X-1, a_Y, a_Z ), CurrentLight-1) );
SetLight( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(GetLight( a_LightBuffer, a_X+1, a_Y, a_Z ), CurrentLight-1) );
}
__C_CHUNK_INLINE__
void cChunk::SpreadLightOfBlockY(char* a_LightBuffer, int a_X, int a_Y, int a_Z)
{
unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z );
SetLight( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y-1, a_Z ), CurrentLight-1) );
SetLight( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(GetLight( a_LightBuffer, a_X, a_Y+1, a_Z ), CurrentLight-1) );
}
__C_CHUNK_INLINE__
void cChunk::SpreadLightOfBlockZ(char* a_LightBuffer, int a_X, int a_Y, int a_Z)
{
unsigned char CurrentLight = GetLight( a_LightBuffer, a_X, a_Y, a_Z );
SetLight( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z-1 ), CurrentLight-1) );
SetLight( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(GetLight( a_LightBuffer, a_X, a_Y, a_Z+1 ), CurrentLight-1) );
}
#endif

View File

@ -516,25 +516,19 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
cPacket_Chat Joined( m_pState->Username + " joined the game!");
cRoot::Get()->GetServer()->Broadcast( Joined, this );
}
int posx = (int) m_Player->GetPosX();
int posy = (int) m_Player->GetPosY();
int posz = (int) m_Player->GetPosZ();
// Now initialize player (adds to entity list etc.)
cWorld* PlayerWorld = cRoot::Get()->GetWorld( m_Player->GetLoadedWorldName() );
if( !PlayerWorld ) PlayerWorld = cRoot::Get()->GetDefaultWorld();
m_Player->Initialize( PlayerWorld ); // TODO - Get correct world for player
// Broadcasts to all but this ( this is actually handled in cChunk.cpp, after entity is added to the chunk )
//m_Player->SpawnOn( 0 );
// Send all already connected players to new player
//cRoot::Get()->GetServer()->SendAllEntitiesTo( this );
m_Player->Initialize( PlayerWorld );
// Then we can start doing more stuffs! :D
m_bLoggedIn = true;
LOG("%s completely logged in", GetUsername() );
m_Player->TeleportTo( posx, posy, posz );
StreamChunks();
// Send position
Send( cPacket_PlayerMoveLook( m_Player ) );
}
break;
case E_KEEP_ALIVE:
@ -1268,7 +1262,7 @@ void cClientHandle::Tick(float a_Dt)
// Spawn player (only serversided, so data is loaded)
m_Player = new cPlayer( this, GetUsername() ); // !!DO NOT INITIALIZE!! <- is done after receiving MoveLook Packet
cWorld* World = cRoot::Get()->GetWorld( m_Player->GetLoadedWorldName() ); // TODO - Get the correct world or better yet, move this to the main thread so we don't have to lock anything
cWorld* World = cRoot::Get()->GetWorld( m_Player->GetLoadedWorldName() );
if( !World ) World = cRoot::Get()->GetDefaultWorld();
World->LockEntities();
m_Player->LoginSetGameMode ( World->GetGameMode() ); //set player's gamemode to server's gamemode at login. TODO: set to last player's gamemode at logout
@ -1295,9 +1289,6 @@ void cClientHandle::Tick(float a_Dt)
Send( RainPacket );
}
// Send position
Send( cPacket_PlayerMoveLook( m_Player ) );
// Send time
Send( cPacket_TimeUpdate( World->GetWorldTime() ) );
@ -1310,7 +1301,6 @@ void cClientHandle::Tick(float a_Dt)
Health.m_Food = m_Player->GetFood();
Health.m_Saturation = m_Player->GetFoodSaturation();
Send(Health);
//Send( cPacket_UpdateHealth( (short)m_Player->GetHealth() ) );
World->UnlockEntities();
}

View File

@ -415,8 +415,8 @@ void cWorld::Tick(float a_Dt)
{
LOG("Destroy that entity! %i", (*itr)->GetUniqueID() );
cEntity* RemoveMe = *itr;
itr++;
AddToRemoveEntityQueue( *RemoveMe );
itr = m_pState->AllEntities.erase( itr );
m_pState->RemoveEntityQueue.push_back( RemoveMe );
continue;
}
(*itr)->Tick(a_Dt);