ChunkSender: Chunks are now compressed and sent to clients from a separate threads, proper passive waiting between threads. Not much tested, just appears to work :)
git-svn-id: http://mc-server.googlecode.com/svn/trunk@365 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
a655d7fdae
commit
4d65ffffc0
@ -42,7 +42,7 @@
|
||||
AdditionalOptions="/MP"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../zlib-1.2.5;../jsoncpp-src-0.5.0/include;../lua-5.1.4/src;../tolua++-1.0.93/include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;MINECRAFT_1_2_2=1"
|
||||
MinimalRebuild="false"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
@ -289,6 +289,14 @@
|
||||
RelativePath="..\source\cHeartBeat.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\ChunkSender.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\ChunkSender.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\cInventory.cpp"
|
||||
>
|
||||
|
@ -329,6 +329,7 @@
|
||||
<ClCompile Include="..\Source\cGroup.cpp" />
|
||||
<ClCompile Include="..\Source\cGroupManager.cpp" />
|
||||
<ClCompile Include="..\Source\cHeartBeat.cpp" />
|
||||
<ClCompile Include="..\source\ChunkSender.cpp" />
|
||||
<ClCompile Include="..\source\cIsThread.cpp" />
|
||||
<ClCompile Include="..\source\cItem.cpp" />
|
||||
<ClCompile Include="..\source\cLavaSimulator.cpp" />
|
||||
@ -513,6 +514,7 @@
|
||||
<ClInclude Include="..\Source\cGroup.h" />
|
||||
<ClInclude Include="..\Source\cGroupManager.h" />
|
||||
<ClInclude Include="..\Source\cHeartBeat.h" />
|
||||
<ClInclude Include="..\source\ChunkSender.h" />
|
||||
<ClInclude Include="..\source\cIsThread.h" />
|
||||
<ClInclude Include="..\Source\cLadder.h" />
|
||||
<ClInclude Include="..\source\cLavaSimulator.h" />
|
||||
|
@ -918,6 +918,7 @@
|
||||
<ClCompile Include="..\source\cRedstoneSimulator.cpp">
|
||||
<Filter>Simulator\cSimulator\cRedstoneSimulator</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\source\ChunkSender.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\source\cServer.h">
|
||||
@ -1417,6 +1418,7 @@
|
||||
<ClInclude Include="..\source\cRedstoneSimulator.h">
|
||||
<Filter>Simulator\cSimulator\cRedstoneSimulator</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\source\ChunkSender.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\source\AllToLua.pkg">
|
||||
|
133
source/ChunkSender.cpp
Normal file
133
source/ChunkSender.cpp
Normal file
@ -0,0 +1,133 @@
|
||||
|
||||
// ChunkSender.cpp
|
||||
|
||||
// Interfaces to the cChunkSender class representing the thread that waits for chunks becoming ready (loaded / generated) and sends them to clients
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "Globals.h"
|
||||
#include "ChunkSender.h"
|
||||
#include "cWorld.h"
|
||||
#include "packets/cPacket_MapChunk.h"
|
||||
#include "packets/cPacket_PreChunk.h"
|
||||
#include "cBlockEntity.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cChunkSender::cChunkSender(void) :
|
||||
super("ChunkSender"),
|
||||
m_World(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cChunkSender::~cChunkSender()
|
||||
{
|
||||
mShouldTerminate = true;
|
||||
m_Event.Set();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkSender::Start(cWorld * a_World)
|
||||
{
|
||||
m_World = a_World;
|
||||
return super::Start();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||
{
|
||||
// This is probably never gonna be called twice for the same chunk, and if it is, we don't mind, so we don't check
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
m_ChunksReady.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
|
||||
}
|
||||
m_Event.Set();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkSender::Execute(void)
|
||||
{
|
||||
while (!mShouldTerminate)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
while (m_ChunksReady.empty())
|
||||
{
|
||||
cCSUnlock Unlock(Lock);
|
||||
m_Event.Wait();
|
||||
if (mShouldTerminate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
} // while (empty)
|
||||
|
||||
// Take one from the queue:
|
||||
cChunkCoords Coords(m_ChunksReady.front());
|
||||
m_ChunksReady.pop_front();
|
||||
Lock.Unlock();
|
||||
|
||||
ASSERT(m_World != NULL);
|
||||
|
||||
// Send it to anyone waiting:
|
||||
m_World->GetChunkData(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, this);
|
||||
cPacket_PreChunk PreChunk(Coords.m_ChunkX, Coords.m_ChunkZ, true);
|
||||
cPacket_MapChunk MapChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, m_BlockData);
|
||||
m_World->BroadcastToChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, PreChunk);
|
||||
m_World->BroadcastToChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, MapChunk);
|
||||
|
||||
// Send entity creation packets:
|
||||
for (PacketList::iterator itr = m_Packets.begin(); itr != m_Packets.end(); ++itr)
|
||||
{
|
||||
m_World->BroadcastToChunk(Coords.m_ChunkX, Coords.m_ChunkY, Coords.m_ChunkZ, **itr);
|
||||
delete *itr;
|
||||
} // for itr - m_Packets
|
||||
m_Packets.clear();
|
||||
|
||||
} // while (!mShouldTerminate)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkSender::BlockData(const char * a_Data)
|
||||
{
|
||||
memcpy(m_BlockData, a_Data, cChunk::c_BlockDataSize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkSender::BlockEntity(cBlockEntity * a_Entity)
|
||||
{
|
||||
m_Packets.push_back(a_Entity->GetPacket());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkSender::Entity(cEntity * a_Entity)
|
||||
{
|
||||
// Nothing needed yet, perhaps in the future when we save entities into chunks we'd like to send them upon load, too ;)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
63
source/ChunkSender.h
Normal file
63
source/ChunkSender.h
Normal file
@ -0,0 +1,63 @@
|
||||
|
||||
// ChunkSender.h
|
||||
|
||||
// Interfaces to the cChunkSender class representing the thread that waits for chunks becoming ready (loaded / generated) and sends them to clients
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cIsThread.h"
|
||||
#include "cChunk.h"
|
||||
#include "packets/cPacket.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cWorld;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cChunkSender:
|
||||
public cIsThread,
|
||||
public cChunkDataCallback
|
||||
{
|
||||
typedef cIsThread super;
|
||||
public:
|
||||
cChunkSender(void);
|
||||
~cChunkSender();
|
||||
|
||||
bool Start(cWorld * a_World);
|
||||
|
||||
void ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
|
||||
protected:
|
||||
|
||||
cWorld * m_World;
|
||||
|
||||
cCriticalSection m_CS;
|
||||
cChunkCoordsList m_ChunksReady;
|
||||
cEvent m_Event; // Set when anything is added to m_ChunksReady
|
||||
|
||||
// Data about the chunk that is being sent:
|
||||
char m_BlockData[cChunk::c_BlockDataSize];
|
||||
PacketList m_Packets; // Accumulator for the entity-packets to send
|
||||
|
||||
// cIsThread override:
|
||||
virtual void Execute(void) override;
|
||||
|
||||
// cChunkDataCallback overrides:
|
||||
virtual void BlockData(const char * a_Data) override;
|
||||
virtual void Entity(cEntity * a_Entity) override;
|
||||
virtual void BlockEntity(cBlockEntity * a_Entity) override;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -144,4 +144,11 @@ public:
|
||||
|
||||
|
||||
|
||||
#define MINECRAFT_1_2_2 (1)
|
||||
// TODO: Remove this when 1.2 is the major version out there and we're fully compatible
|
||||
#ifndef MINECRAFT_1_2_2
|
||||
#define MINECRAFT_1_2_2 (1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,6 +1,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cClientHandle.h"
|
||||
#include "cWorld.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
#include "BlockID.h"
|
||||
#else
|
||||
@ -16,9 +23,9 @@ namespace Json
|
||||
class Value;
|
||||
};
|
||||
|
||||
class cClientHandle;
|
||||
class cPlayer;
|
||||
class cWorld;
|
||||
class cPacket;
|
||||
|
||||
|
||||
|
||||
@ -49,7 +56,26 @@ public:
|
||||
virtual void SaveToJson (Json::Value & a_Value ) = 0;
|
||||
|
||||
virtual void UsedBy( cPlayer * a_Player ) = 0;
|
||||
virtual void SendTo( cClientHandle* a_Client ) { (void)a_Client; }
|
||||
|
||||
void SendTo( cClientHandle* a_Client )
|
||||
{
|
||||
std::auto_ptr<cPacket> Packet(GetPacket());
|
||||
if (Packet.get() == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( a_Client != NULL )
|
||||
{
|
||||
a_Client->Send(Packet.get());
|
||||
}
|
||||
else // broadcast to all chunk clients
|
||||
{
|
||||
m_World->BroadcastToChunkOfBlock(m_PosX, m_PosY, m_PosZ, Packet.get());
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the packet to send to clients to represent this entity; NULL if no packet needed; caller is supposed to delete the packet
|
||||
virtual cPacket * GetPacket(void) {return NULL; }
|
||||
|
||||
protected:
|
||||
int m_PosX; // Position in block coordinates
|
||||
|
@ -294,6 +294,16 @@ void cChunk::GetBlocks(char * a_Blocks)
|
||||
|
||||
|
||||
|
||||
/// Copies m_BlockData into a_Blocks, only the block types
|
||||
void cChunk::GetBlockData(char * a_BlockData)
|
||||
{
|
||||
memcpy(a_BlockData, m_BlockData, cChunk::c_BlockDataSize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Returns true if there is a block entity at the coords specified
|
||||
bool cChunk::HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
@ -359,13 +369,13 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
||||
|
||||
#if (MINECRAFT_1_2_2 == 1)
|
||||
unsigned int Coords = Y | Z << 8 | X << 12;
|
||||
unsigned int Blocks = GetLight( m_BlockMeta, index ) | (m_BlockType[index]<<4);
|
||||
unsigned int Blocks = GetNibble( m_BlockMeta, index ) | (m_BlockType[index]<<4);
|
||||
MultiBlock.m_Data[i].Data = Coords << 16 | Blocks;
|
||||
#else
|
||||
MultiBlock.m_BlockCoordinates[i] = (Z&0xf) | (X&0xf)<<4 | (Y&0xff)<<8;
|
||||
//LOG("X: %i Y: %i Z: %i Combo: 0x%04x", X, Y, Z, MultiBlock.m_BlockCoordinates[i] );
|
||||
MultiBlock.m_BlockTypes[i] = m_BlockType[index];
|
||||
MultiBlock.m_BlockMetas[i] = GetLight( m_BlockMeta, index );
|
||||
MultiBlock.m_BlockMetas[i] = GetNibble( m_BlockMeta, index );
|
||||
#endif
|
||||
}
|
||||
m_PendingSendBlocks.clear();
|
||||
@ -386,7 +396,7 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
||||
BlockChange.m_PosY = (char)(Y + m_PosY*c_ChunkHeight);
|
||||
BlockChange.m_PosZ = Z + m_PosZ*c_ChunkWidth;
|
||||
BlockChange.m_BlockType = m_BlockType[index];
|
||||
BlockChange.m_BlockMeta = GetLight( m_BlockMeta, index );
|
||||
BlockChange.m_BlockMeta = GetNibble( m_BlockMeta, index );
|
||||
Broadcast( BlockChange );
|
||||
}
|
||||
m_PendingSendBlocks.clear();
|
||||
@ -466,7 +476,7 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
||||
isRedstone = true;
|
||||
case E_BLOCK_TORCH:
|
||||
{
|
||||
char Dir = cTorch::MetaDataToDirection( GetLight( m_BlockMeta, X, Y, Z ) );
|
||||
char Dir = cTorch::MetaDataToDirection( GetNibble( m_BlockMeta, X, Y, Z ) );
|
||||
LOG("MetaData: %i", Dir );
|
||||
int XX = X + m_PosX*c_ChunkWidth;
|
||||
int YY = Y + m_PosY*c_ChunkHeight;
|
||||
@ -490,7 +500,7 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
||||
break;
|
||||
case E_BLOCK_LADDER:
|
||||
{
|
||||
char Dir = cLadder::MetaDataToDirection( GetLight( m_BlockMeta, X, Y, Z ) );
|
||||
char Dir = cLadder::MetaDataToDirection( GetNibble( m_BlockMeta, X, Y, Z ) );
|
||||
int XX = X + m_PosX*c_ChunkWidth;
|
||||
int YY = Y + m_PosY*c_ChunkHeight;
|
||||
int ZZ = Z + m_PosZ*c_ChunkWidth;
|
||||
@ -534,13 +544,13 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
||||
case E_BLOCK_DIRT:
|
||||
{
|
||||
char AboveBlock = GetBlock( Index+1 );
|
||||
if ( (AboveBlock == 0) && GetLight( m_BlockSkyLight, Index ) > 0xf/2 ) // Half lit //changed to not allow grass if any one hit object is on top
|
||||
if ( (AboveBlock == 0) && GetNibble( m_BlockSkyLight, Index ) > 0xf/2 ) // Half lit //changed to not allow grass if any one hit object is on top
|
||||
{
|
||||
FastSetBlock( m_BlockTickX, m_BlockTickY, m_BlockTickZ, E_BLOCK_GRASS, GetLight( m_BlockMeta, Index ) );
|
||||
FastSetBlock( m_BlockTickX, m_BlockTickY, m_BlockTickZ, E_BLOCK_GRASS, GetNibble( m_BlockMeta, Index ) );
|
||||
}
|
||||
if ( (g_BlockOneHitDig[AboveBlock]) && GetLight( m_BlockSkyLight, Index+1 ) > 0xf/2 ) // Half lit //ch$
|
||||
if ( (g_BlockOneHitDig[AboveBlock]) && GetNibble( m_BlockSkyLight, Index+1 ) > 0xf/2 ) // Half lit //ch$
|
||||
{
|
||||
FastSetBlock( m_BlockTickX, m_BlockTickY, m_BlockTickZ, E_BLOCK_GRASS, GetLight( m_BlockMeta, Index ) );
|
||||
FastSetBlock( m_BlockTickX, m_BlockTickY, m_BlockTickZ, E_BLOCK_GRASS, GetNibble( m_BlockMeta, Index ) );
|
||||
}
|
||||
|
||||
break;
|
||||
@ -552,13 +562,13 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
||||
char AboveBlock = GetBlock( Index+1 );
|
||||
if (!( (AboveBlock == 0) || (g_BlockOneHitDig[AboveBlock]) || (g_BlockTransparent[AboveBlock]) ) ) //changed to not allow grass if any one hit object is on top
|
||||
{
|
||||
FastSetBlock( m_BlockTickX, m_BlockTickY, m_BlockTickZ, E_BLOCK_DIRT, GetLight( m_BlockMeta, Index ) );
|
||||
FastSetBlock( m_BlockTickX, m_BlockTickY, m_BlockTickZ, E_BLOCK_DIRT, GetNibble( m_BlockMeta, Index ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case E_BLOCK_SAPLING: //todo: check meta of sapling. change m_World->GrowTree to look change trunk and leaves based on meta of sapling
|
||||
{
|
||||
FastSetBlock( m_BlockTickX, m_BlockTickY, m_BlockTickZ, E_BLOCK_AIR, GetLight( m_BlockMeta, Index ) );
|
||||
FastSetBlock( m_BlockTickX, m_BlockTickY, m_BlockTickZ, E_BLOCK_AIR, GetNibble( m_BlockMeta, Index ) );
|
||||
m_World->GrowTree( m_BlockTickX + m_PosX*c_ChunkWidth, m_BlockTickY, m_BlockTickZ + m_PosZ*c_ChunkWidth );
|
||||
}
|
||||
break;
|
||||
@ -675,12 +685,12 @@ void cChunk::CalculateLighting()
|
||||
{
|
||||
// Calculate sunlight
|
||||
memset(m_BlockSkyLight, 0xff, c_NumBlocks / 2 ); // Set all to fully lit, so everything above HeightMap is lit
|
||||
for(int x = 0; x < c_ChunkWidth; x++)
|
||||
for (int x = 0; x < c_ChunkWidth; x++)
|
||||
{
|
||||
for(int z = 0; z < c_ChunkWidth; z++)
|
||||
for (int z = 0; z < c_ChunkWidth; z++)
|
||||
{
|
||||
char sunlight = 0xf;
|
||||
for(int y = m_HeightMap[x + z*c_ChunkWidth]; y > -1; y--)
|
||||
for (int y = m_HeightMap[x + z*c_ChunkWidth]; y > -1; y--)
|
||||
{
|
||||
int index = y + (z * c_ChunkHeight) + (x * c_ChunkHeight * c_ChunkWidth);
|
||||
|
||||
@ -688,21 +698,21 @@ void cChunk::CalculateLighting()
|
||||
{
|
||||
sunlight = 0x0;
|
||||
}
|
||||
SetLight( m_BlockSkyLight, x, y, z, sunlight );
|
||||
SetNibble( m_BlockSkyLight, x, y, z, sunlight );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate blocklights
|
||||
for(int x = 0; x < c_ChunkWidth; x++)
|
||||
for (int x = 0; x < c_ChunkWidth; x++)
|
||||
{
|
||||
for(int z = 0; z < c_ChunkWidth; z++)
|
||||
for (int z = 0; z < c_ChunkWidth; z++)
|
||||
{
|
||||
int MaxHeight = m_HeightMap[x + z*c_ChunkWidth];
|
||||
for(int y = 0; y < MaxHeight; y++)
|
||||
for (int y = 0; y < MaxHeight; y++)
|
||||
{
|
||||
char BlockID = GetBlock(x, y, z);
|
||||
SetLight( m_BlockLight, x, y, z, g_BlockLightValue[(int)BlockID] );
|
||||
SetNibble( m_BlockLight, x, y, z, g_BlockLightValue[(int)BlockID] );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -710,6 +720,8 @@ void cChunk::CalculateLighting()
|
||||
SpreadLight(m_BlockSkyLight);
|
||||
SpreadLight(m_BlockLight);
|
||||
|
||||
MarkDirty();
|
||||
|
||||
// Stop it from calculating again :P
|
||||
m_bCalculateLighting = false;
|
||||
}
|
||||
@ -762,11 +774,11 @@ void cChunk::SpreadLight(char* a_LightBuffer)
|
||||
int index = y + (z * c_ChunkHeight) + (0 * c_ChunkHeight * c_ChunkWidth);
|
||||
if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
|
||||
{
|
||||
char CurrentLight = GetLight( a_LightBuffer, 0, y, z );
|
||||
char LeftLight = GetLight( LeftSky, c_ChunkWidth-1, y, z );
|
||||
char CurrentLight = GetNibble( a_LightBuffer, 0, y, z );
|
||||
char LeftLight = GetNibble( LeftSky, c_ChunkWidth-1, y, z );
|
||||
if( LeftLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ] )
|
||||
{
|
||||
SetLight( LeftSky, c_ChunkWidth-1, y, z, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ]) );
|
||||
SetNibble( LeftSky, c_ChunkWidth - 1, y, z, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ]) );
|
||||
bCalcLeft = true;
|
||||
}
|
||||
}
|
||||
@ -776,11 +788,11 @@ void cChunk::SpreadLight(char* a_LightBuffer)
|
||||
int index = y + (z * c_ChunkHeight) + ((c_ChunkWidth-1) * c_ChunkHeight * c_ChunkWidth);
|
||||
if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
|
||||
{
|
||||
char CurrentLight = GetLight( a_LightBuffer, c_ChunkWidth-1, y, z );
|
||||
char RightLight = GetLight( RightSky, 0, y, z );
|
||||
char CurrentLight = GetNibble( a_LightBuffer, c_ChunkWidth-1, y, z );
|
||||
char RightLight = GetNibble( RightSky, 0, y, z );
|
||||
if( RightLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ] )
|
||||
{
|
||||
SetLight( RightSky, 0, y, z, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ]) );
|
||||
SetNibble( RightSky, 0, y, z, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ]) );
|
||||
bCalcRight = true;
|
||||
}
|
||||
}
|
||||
@ -806,11 +818,11 @@ void cChunk::SpreadLight(char* a_LightBuffer)
|
||||
int index = y + (0 * c_ChunkHeight) + (x * c_ChunkHeight * c_ChunkWidth);
|
||||
if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
|
||||
{
|
||||
char CurrentLight = GetLight( a_LightBuffer, x, y, 0 );
|
||||
char FrontLight = GetLight( FrontSky, x, y, c_ChunkWidth-1 );
|
||||
char CurrentLight = GetNibble( a_LightBuffer, x, y, 0 );
|
||||
char FrontLight = GetNibble( FrontSky, x, y, c_ChunkWidth-1 );
|
||||
if( FrontLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ] )
|
||||
{
|
||||
SetLight( FrontSky, x, y, c_ChunkWidth-1, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ]) );
|
||||
SetNibble( FrontSky, x, y, c_ChunkWidth-1, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ]) );
|
||||
bCalcFront = true;
|
||||
}
|
||||
}
|
||||
@ -820,41 +832,22 @@ void cChunk::SpreadLight(char* a_LightBuffer)
|
||||
int index = y + ((c_ChunkWidth-1) * c_ChunkHeight) + (x * c_ChunkHeight * c_ChunkWidth);
|
||||
if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
|
||||
{
|
||||
char CurrentLight = GetLight( a_LightBuffer, x, y, c_ChunkWidth-1 );
|
||||
char BackLight = GetLight( BackSky, x, y, 0 );
|
||||
char CurrentLight = GetNibble( a_LightBuffer, x, y, c_ChunkWidth-1 );
|
||||
char BackLight = GetNibble( BackSky, x, y, 0 );
|
||||
if ( BackLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ] )
|
||||
{
|
||||
SetLight( BackSky, x, y, 0, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ]) );
|
||||
SetNibble( BackSky, x, y, 0, MAX(0, CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ]) );
|
||||
bCalcBack = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( bCalcLeft ) m_World->ReSpreadLighting( m_PosX - 1, m_PosY, m_PosZ );
|
||||
if( bCalcRight ) m_World->ReSpreadLighting( m_PosX + 1, m_PosY, m_PosZ );
|
||||
if( bCalcFront ) m_World->ReSpreadLighting( m_PosX, m_PosY, m_PosZ - 1 );
|
||||
if( bCalcBack ) m_World->ReSpreadLighting( m_PosX, m_PosY, m_PosZ + 1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::SendTo(cClientHandle* a_Client)
|
||||
{
|
||||
cPacket_PreChunk PreChunk;
|
||||
PreChunk.m_PosX = m_PosX;
|
||||
PreChunk.m_PosZ = m_PosZ;
|
||||
PreChunk.m_bLoad = true;
|
||||
a_Client->Send( PreChunk );
|
||||
a_Client->Send( cPacket_MapChunk( this ) );
|
||||
|
||||
cCSLock Lock(m_CSBlockLists);
|
||||
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr )
|
||||
{
|
||||
(*itr)->SendTo( a_Client );
|
||||
}
|
||||
if ( bCalcLeft ) m_World->ReSpreadLighting( m_PosX - 1, m_PosY, m_PosZ );
|
||||
if ( bCalcRight ) m_World->ReSpreadLighting( m_PosX + 1, m_PosY, m_PosZ );
|
||||
if ( bCalcFront ) m_World->ReSpreadLighting( m_PosX, m_PosY, m_PosZ - 1 );
|
||||
if ( bCalcBack ) m_World->ReSpreadLighting( m_PosX, m_PosY, m_PosZ + 1 );
|
||||
// No need to set those neighbors dirty, they will recalc their light anyway so they'll get marked dirty there
|
||||
}
|
||||
|
||||
|
||||
@ -871,12 +864,11 @@ void cChunk::SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_Block
|
||||
ASSERT(IsValid()); // Is this chunk loaded / generated?
|
||||
|
||||
int index = a_Y + (a_Z * c_ChunkHeight) + (a_X * c_ChunkHeight * c_ChunkWidth);
|
||||
char OldBlockMeta = GetLight( m_BlockMeta, index );
|
||||
char OldBlockMeta = GetNibble( m_BlockMeta, index );
|
||||
char OldBlockType = m_BlockType[index];
|
||||
m_BlockType[index] = a_BlockType;
|
||||
|
||||
// It's called SetLight(), but it sets the Meta when passed the BlockMeta workspace
|
||||
SetLight( m_BlockMeta, index, a_BlockMeta );
|
||||
SetNibble( m_BlockMeta, index, a_BlockMeta );
|
||||
|
||||
if ((OldBlockType == a_BlockType) && (OldBlockMeta == a_BlockMeta))
|
||||
{
|
||||
@ -968,7 +960,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 * c_ChunkHeight) + (a_X * c_ChunkHeight * c_ChunkWidth);
|
||||
const char OldBlock = m_BlockType[index];
|
||||
const char OldBlockMeta = GetLight( m_BlockMeta, index );
|
||||
const char OldBlockMeta = GetNibble( m_BlockMeta, index );
|
||||
if (OldBlock == a_BlockType && OldBlockMeta == a_BlockMeta)
|
||||
{
|
||||
return;
|
||||
@ -983,8 +975,7 @@ void cChunk::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_B
|
||||
m_PendingSendBlocks.push_back( index );
|
||||
}
|
||||
|
||||
// It's called SetLight(), but it sets the Meta when passed the BlockMeta workspace
|
||||
SetLight( m_BlockMeta, index, a_BlockMeta );
|
||||
SetNibble( m_BlockMeta, index, a_BlockMeta );
|
||||
|
||||
// ONLY recalculate lighting if it's necessary!
|
||||
if(
|
||||
@ -1046,7 +1037,7 @@ void cChunk::SendBlockTo( int a_X, int a_Y, int a_Z, cClientHandle* a_Client )
|
||||
if( index != INDEX_OUT_OF_RANGE )
|
||||
{
|
||||
BlockChange.m_BlockType = m_BlockType[ index ];
|
||||
BlockChange.m_BlockMeta = GetLight( m_BlockMeta, index );
|
||||
BlockChange.m_BlockMeta = GetNibble( m_BlockMeta, index );
|
||||
} // else it's both 0
|
||||
a_Client->Send( BlockChange );
|
||||
break;
|
||||
|
@ -145,7 +145,10 @@ public:
|
||||
void SetAllData(const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
||||
|
||||
/// Copies m_BlockData into a_Blocks, only the block types
|
||||
void GetBlocks(char a_Blocks[cChunk::c_NumBlocks]);
|
||||
void GetBlocks(char * a_Blocks);
|
||||
|
||||
/// Copies m_BlockData into a_Blocks, the entire array
|
||||
void GetBlockData(char * a_BlockData);
|
||||
|
||||
/// Returns true if there is a block entity at the coords specified
|
||||
bool HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
@ -160,7 +163,7 @@ public:
|
||||
int GetPosZ() { return m_PosZ; }
|
||||
cWorld * GetWorld() { return m_World; }
|
||||
|
||||
void SendTo( cClientHandle * a_Client );
|
||||
// OBSOLETE void SendTo( cClientHandle * a_Client );
|
||||
|
||||
void SetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_BlockMeta );
|
||||
void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, char a_BlockType, char a_BlockMeta ); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc.
|
||||
@ -206,10 +209,10 @@ public:
|
||||
|
||||
void CopyBlockDataFrom(const char * a_NewBlockData); // Copies all blockdata, recalculates heightmap (used by chunk loaders)
|
||||
|
||||
char GetLight(char* a_Buffer, int a_BlockIdx);
|
||||
char GetLight(char* a_Buffer, int x, int y, int z);
|
||||
void SetLight(char* a_Buffer, int a_BlockIdx, char a_Light);
|
||||
void SetLight(char* a_Buffer, int x, int y, int z, char light);
|
||||
static char GetNibble(char * a_Buffer, int a_BlockIdx);
|
||||
static char GetNibble(char * a_Buffer, int x, int y, int z);
|
||||
static void SetNibble(char * a_Buffer, int a_BlockIdx, char a_Light);
|
||||
static void SetNibble(char * a_Buffer, int x, int y, int z, char light);
|
||||
|
||||
void PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z);
|
||||
Vector3i PositionToWorldPosition( const Vector3i & a_InChunkPos );
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
|
||||
__C_CHUNK_INLINE__
|
||||
char cChunk::GetLight(char* a_Buffer, int a_BlockIdx)
|
||||
char cChunk::GetNibble(char* a_Buffer, int a_BlockIdx)
|
||||
{
|
||||
if( a_BlockIdx > -1 && a_BlockIdx < c_NumBlocks )
|
||||
{
|
||||
@ -33,7 +33,7 @@ char cChunk::GetLight(char* a_Buffer, int a_BlockIdx)
|
||||
|
||||
|
||||
__C_CHUNK_INLINE__
|
||||
char cChunk::GetLight(char* a_Buffer, int x, int y, int z)
|
||||
char cChunk::GetNibble(char* a_Buffer, int x, int y, int z)
|
||||
{
|
||||
if( x < c_ChunkWidth && x > -1 && y < c_ChunkHeight && y > -1 && z < c_ChunkWidth && z > -1 )
|
||||
{
|
||||
@ -55,7 +55,7 @@ char cChunk::GetLight(char* a_Buffer, int x, int y, int z)
|
||||
|
||||
|
||||
__C_CHUNK_INLINE__
|
||||
void cChunk::SetLight(char* a_Buffer, int a_BlockIdx, char a_Light)
|
||||
void cChunk::SetNibble(char* a_Buffer, int a_BlockIdx, char a_Light)
|
||||
{
|
||||
if( a_BlockIdx > -1 && a_BlockIdx < c_NumBlocks )
|
||||
{
|
||||
@ -70,7 +70,6 @@ void cChunk::SetLight(char* a_Buffer, int a_BlockIdx, char a_Light)
|
||||
a_Buffer[cindex] &= 0x0f; // Set second half to 0
|
||||
a_Buffer[cindex] |= (a_Light << 4) & 0xf0;
|
||||
}
|
||||
MarkDirty();
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +78,7 @@ void cChunk::SetLight(char* a_Buffer, int a_BlockIdx, char a_Light)
|
||||
|
||||
|
||||
__C_CHUNK_INLINE__
|
||||
void cChunk::SetLight(char* a_Buffer, int x, int y, int z, char light)
|
||||
void cChunk::SetNibble(char* a_Buffer, int x, int y, int z, char light)
|
||||
{
|
||||
if( x < c_ChunkWidth && x > -1 && y < c_ChunkHeight && y > -1 && z < c_ChunkWidth && z > -1 )
|
||||
{
|
||||
@ -94,7 +93,6 @@ void cChunk::SetLight(char* a_Buffer, int x, int y, int z, char light)
|
||||
a_Buffer[cindex] &= 0x0f; // Set second half to 0
|
||||
a_Buffer[cindex] |= (light << 4) & 0xf0;
|
||||
}
|
||||
MarkDirty();
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,13 +103,14 @@ void cChunk::SetLight(char* a_Buffer, int x, int y, int z, char light)
|
||||
__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) ) );
|
||||
unsigned char CurrentLight = GetNibble( a_LightBuffer, a_X, a_Y, a_Z );
|
||||
SetNibble( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(GetNibble( a_LightBuffer, a_X-1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
|
||||
SetNibble( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(GetNibble( a_LightBuffer, a_X+1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
|
||||
SetNibble( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(GetNibble( a_LightBuffer, a_X, a_Y-1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
|
||||
SetNibble( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(GetNibble( a_LightBuffer, a_X, a_Y+1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
|
||||
SetNibble( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(GetNibble( a_LightBuffer, a_X, a_Y, a_Z-1 ), MAX(0,CurrentLight-a_Falloff) ) );
|
||||
SetNibble( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(GetNibble( a_LightBuffer, a_X, a_Y, a_Z+1 ), MAX(0,CurrentLight-a_Falloff) ) );
|
||||
MarkDirty();
|
||||
}
|
||||
|
||||
|
||||
@ -121,9 +120,10 @@ void cChunk::SpreadLightOfBlock(char* a_LightBuffer, int a_X, int a_Y, int a_Z,
|
||||
__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) );
|
||||
unsigned char CurrentLight = GetNibble( a_LightBuffer, a_X, a_Y, a_Z );
|
||||
SetNibble( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(GetNibble( a_LightBuffer, a_X-1, a_Y, a_Z ), CurrentLight-1) );
|
||||
SetNibble( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(GetNibble( a_LightBuffer, a_X+1, a_Y, a_Z ), CurrentLight-1) );
|
||||
MarkDirty();
|
||||
}
|
||||
|
||||
|
||||
@ -133,9 +133,10 @@ void cChunk::SpreadLightOfBlockX(char* a_LightBuffer, int a_X, int a_Y, int a_Z)
|
||||
__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) );
|
||||
unsigned char CurrentLight = GetNibble( a_LightBuffer, a_X, a_Y, a_Z );
|
||||
SetNibble( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(GetNibble( a_LightBuffer, a_X, a_Y-1, a_Z ), CurrentLight-1) );
|
||||
SetNibble( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(GetNibble( a_LightBuffer, a_X, a_Y+1, a_Z ), CurrentLight-1) );
|
||||
MarkDirty();
|
||||
}
|
||||
|
||||
|
||||
@ -145,9 +146,10 @@ void cChunk::SpreadLightOfBlockY(char* a_LightBuffer, int a_X, int a_Y, int a_Z)
|
||||
__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) );
|
||||
unsigned char CurrentLight = GetNibble( a_LightBuffer, a_X, a_Y, a_Z );
|
||||
SetNibble( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(GetNibble( a_LightBuffer, a_X, a_Y, a_Z-1 ), CurrentLight-1) );
|
||||
SetNibble( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(GetNibble( a_LightBuffer, a_X, a_Y, a_Z+1 ), CurrentLight-1) );
|
||||
MarkDirty();
|
||||
}
|
||||
|
||||
|
||||
|
@ -343,6 +343,22 @@ bool cChunkMap::GetChunkBlocks(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char *
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::GetChunkBlockData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_BlockData)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_ChunkX, a_ChunkY, a_ChunkZ);
|
||||
if ((Chunk == NULL) || !Chunk->IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Chunk->GetBlockData(a_BlockData);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
@ -469,14 +485,17 @@ void cChunkMap::CollectPickupsByPlayer(cPlayer * a_Player)
|
||||
int OtherChunkX = ChunkX + ((BlockX > 8) ? 1 : -1);
|
||||
int OtherChunkZ = ChunkZ + ((BlockZ > 8) ? 1 : -1);
|
||||
|
||||
// We suppose that each player keeps their chunks in memory, therefore it makes little sense to try to re-load or even generate them.
|
||||
// The only time the chunks are not valid is when the player is downloading the initial world and they should not call this at that moment
|
||||
|
||||
cCSLock Lock(m_CSLayers);
|
||||
GetChunkNoGen(ChunkX, ChunkY, ChunkZ)->CollectPickupsByPlayer(a_Player);
|
||||
GetChunkNoLoad(ChunkX, ChunkY, ChunkZ)->CollectPickupsByPlayer(a_Player);
|
||||
|
||||
// Check the neighboring chunks as well:
|
||||
GetChunkNoGen(OtherChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player);
|
||||
GetChunkNoGen(OtherChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player);
|
||||
GetChunkNoGen(ChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player);
|
||||
GetChunkNoGen(ChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player);
|
||||
GetChunkNoLoad(OtherChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player);
|
||||
GetChunkNoLoad(OtherChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player);
|
||||
GetChunkNoLoad(ChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player);
|
||||
GetChunkNoLoad(ChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player);
|
||||
}
|
||||
|
||||
|
||||
@ -511,7 +530,7 @@ char cChunkMap::GetBlockMeta(int a_X, int a_Y, int a_Z)
|
||||
if ((Chunk != NULL) && Chunk->IsValid() )
|
||||
{
|
||||
// Although it is called GetLight(), it actually gets meta when passed the Meta field
|
||||
return Chunk->GetLight( Chunk->pGetMeta(), a_X, a_Y, a_Z );
|
||||
return cChunk::GetNibble( Chunk->pGetMeta(), a_X, a_Y, a_Z );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -529,8 +548,8 @@ void cChunkMap::SetBlockMeta(int a_X, int a_Y, int a_Z, char a_BlockMeta)
|
||||
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 );
|
||||
cChunk::SetNibble( Chunk->pGetMeta(), a_X, a_Y, a_Z, a_BlockMeta );
|
||||
Chunk->MarkDirty();
|
||||
Chunk->SendBlockTo( a_X, a_Y, a_Z, NULL );
|
||||
}
|
||||
}
|
||||
@ -706,22 +725,6 @@ 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);
|
||||
if ((Chunk == NULL) || !Chunk->IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Chunk->SendTo(a_Client);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunkMap::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
|
@ -45,7 +45,13 @@ public:
|
||||
void ChunkDataLoaded (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
||||
void ChunkDataGenerated (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
||||
void GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback * a_Callback);
|
||||
|
||||
/// Gets the chunk's blocks, only the block types
|
||||
bool GetChunkBlocks (int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_Blocks);
|
||||
|
||||
/// Gets the chunk's blockdata, the entire array
|
||||
bool GetChunkBlockData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_BlockData);
|
||||
|
||||
bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
bool HasChunkAnyClients (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
void SpreadChunkLighting(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
@ -71,9 +77,6 @@ public:
|
||||
/// 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);
|
||||
|
||||
/// Moves the entity from its current chunk to the new chunk specified
|
||||
void MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||
|
||||
|
@ -1681,35 +1681,6 @@ void cClientHandle::Tick(float a_Dt)
|
||||
Send(Ping);
|
||||
m_LastPingTime = m_PingStartTime;
|
||||
}
|
||||
|
||||
if (m_State >= csDownloadingWorld)
|
||||
{
|
||||
cWorld * World = m_Player->GetWorld();
|
||||
|
||||
cCSLock Lock(m_CSChunkLists);
|
||||
|
||||
// Send the chunks:
|
||||
int NumSent = 0;
|
||||
for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end();)
|
||||
{
|
||||
if (!World->SendChunkTo(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ, this))
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
}
|
||||
itr = m_ChunksToSend.erase(itr);
|
||||
NumSent++;
|
||||
if (NumSent > 10)
|
||||
{
|
||||
// Only send up to 10 chunks per tick, otherwise we'd choke the tick thread
|
||||
break;
|
||||
}
|
||||
} // for itr - m_ChunksToSend[]
|
||||
Lock.Unlock();
|
||||
|
||||
// Check even if we didn't send anything - a chunk may have sent a notification that we'd miss otherwise
|
||||
CheckIfWorldDownloaded();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1737,20 +1708,38 @@ void cClientHandle::Send(const cPacket * a_Packet, ENUM_PRIORITY a_Priority /* =
|
||||
case E_PLAYERMOVELOOK:
|
||||
case E_KEEP_ALIVE:
|
||||
case E_PRE_CHUNK:
|
||||
case E_MAP_CHUNK:
|
||||
{
|
||||
// Allow
|
||||
break;
|
||||
}
|
||||
case E_MAP_CHUNK:
|
||||
{
|
||||
CheckIfWorldDownloaded();
|
||||
break;
|
||||
}
|
||||
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check chunks being sent, erase them from m_ChunksToSend:
|
||||
if (a_Packet->m_PacketID == E_MAP_CHUNK)
|
||||
{
|
||||
#if (MINECRAFT_1_2_2 == 1)
|
||||
int ChunkX = ((cPacket_MapChunk *)a_Packet)->m_PosX;
|
||||
int ChunkZ = ((cPacket_MapChunk *)a_Packet)->m_PosZ;
|
||||
#else
|
||||
int ChunkX = ((cPacket_MapChunk *)a_Packet)->m_PosX / cChunk::c_ChunkWidth;
|
||||
int ChunkZ = ((cPacket_MapChunk *)a_Packet)->m_PosZ / cChunk::c_ChunkWidth;
|
||||
#endif
|
||||
cCSLock Lock(m_CSChunkLists);
|
||||
for (cChunkCoordsList::iterator itr = m_ChunksToSend.begin(); itr != m_ChunksToSend.end(); ++itr)
|
||||
{
|
||||
if ((itr->m_ChunkX == ChunkX) && (itr->m_ChunkZ == ChunkZ))
|
||||
{
|
||||
m_ChunksToSend.erase(itr);
|
||||
CheckIfWorldDownloaded();
|
||||
break;
|
||||
}
|
||||
} // for itr - m_ChunksToSend[]
|
||||
}
|
||||
|
||||
// Optimize away multiple queued RelativeEntityMoveLook packets:
|
||||
cCSLock Lock(m_CSPackets);
|
||||
if (a_Priority == E_PRIORITY_NORMAL)
|
||||
{
|
||||
|
@ -94,6 +94,8 @@ public:
|
||||
|
||||
bool IsDestroyed() { return m_bDestroyed; }
|
||||
void Destroy();
|
||||
|
||||
bool IsPlaying(void) const {return (m_State == csPlaying); }
|
||||
|
||||
void Send(const cPacket & a_Packet, ENUM_PRIORITY a_Priority = E_PRIORITY_NORMAL) { Send(&a_Packet, a_Priority); }
|
||||
void Send(const cPacket * a_Packet, ENUM_PRIORITY a_Priority = E_PRIORITY_NORMAL);
|
||||
|
@ -177,6 +177,12 @@ cPacket * cPlayer::GetSpawnPacket(void) const
|
||||
|
||||
void cPlayer::Tick(float a_Dt)
|
||||
{
|
||||
if (!m_ClientHandle->IsPlaying())
|
||||
{
|
||||
// We're not yet in the game, ignore everything
|
||||
return;
|
||||
}
|
||||
|
||||
cPawn::Tick(a_Dt);
|
||||
|
||||
if (m_bDirtyOrientation && !m_bDirtyPosition)
|
||||
@ -233,7 +239,7 @@ void cPlayer::Tick(float a_Dt)
|
||||
m_ClientHandle->StreamChunks();
|
||||
}
|
||||
|
||||
if ( m_Health > 0 ) // make sure player is alive
|
||||
if (m_Health > 0) // make sure player is alive
|
||||
{
|
||||
m_World->CollectPickupsByPlayer(this);
|
||||
}
|
||||
|
@ -81,25 +81,17 @@ AString cSignEntity::GetLine( int a_Index ) const
|
||||
|
||||
|
||||
|
||||
void cSignEntity::SendTo( cClientHandle* a_Client )
|
||||
cPacket * cSignEntity::GetPacket(void)
|
||||
{
|
||||
cPacket_UpdateSign Sign;
|
||||
Sign.m_PosX = m_PosX;
|
||||
Sign.m_PosY = (short)m_PosY;
|
||||
Sign.m_PosZ = m_PosZ;
|
||||
Sign.m_Line1 = m_Line[0];
|
||||
Sign.m_Line2 = m_Line[1];
|
||||
Sign.m_Line3 = m_Line[2];
|
||||
Sign.m_Line4 = m_Line[3];
|
||||
|
||||
if ( a_Client != NULL )
|
||||
{
|
||||
a_Client->Send( Sign );
|
||||
}
|
||||
else // broadcast of a_Client == 0
|
||||
{
|
||||
m_World->BroadcastToChunkOfBlock(m_PosX, m_PosY, m_PosZ, &Sign );
|
||||
}
|
||||
cPacket_UpdateSign * Sign = new cPacket_UpdateSign;
|
||||
Sign->m_PosX = m_PosX;
|
||||
Sign->m_PosY = (short)m_PosY;
|
||||
Sign->m_PosZ = m_PosZ;
|
||||
Sign->m_Line1 = m_Line[0];
|
||||
Sign->m_Line2 = m_Line[1];
|
||||
Sign->m_Line3 = m_Line[2];
|
||||
Sign->m_Line4 = m_Line[3];
|
||||
return Sign;
|
||||
}
|
||||
|
||||
|
||||
|
@ -34,7 +34,8 @@ public:
|
||||
AString GetLine( int a_Index ) const;
|
||||
|
||||
virtual void UsedBy( cPlayer * a_Player ) override;
|
||||
virtual void SendTo( cClientHandle* a_Client ) override;
|
||||
|
||||
virtual cPacket * GetPacket(void) override;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -238,6 +238,8 @@ cWorld::cWorld( const AString & a_WorldName )
|
||||
}
|
||||
|
||||
m_ChunkMap = new cChunkMap(this );
|
||||
|
||||
m_ChunkSender.Start(this);
|
||||
|
||||
m_Time = 0;
|
||||
m_WorldTimeFraction = 0.f;
|
||||
@ -975,6 +977,7 @@ void cWorld::MarkChunkSaved (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||
void cWorld::ChunkDataLoaded(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities)
|
||||
{
|
||||
m_ChunkMap->ChunkDataLoaded(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockData, a_Entities, a_BlockEntities);
|
||||
m_ChunkSender.ChunkReady(a_ChunkX, a_ChunkY, a_ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
@ -984,6 +987,7 @@ void cWorld::ChunkDataLoaded(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const cha
|
||||
void cWorld::ChunkDataGenerated(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities)
|
||||
{
|
||||
m_ChunkMap->ChunkDataGenerated(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockData, a_Entities, a_BlockEntities);
|
||||
m_ChunkSender.ChunkReady(a_ChunkX, a_ChunkY, a_ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
@ -1008,6 +1012,15 @@ bool cWorld::GetChunkBlocks(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_B
|
||||
|
||||
|
||||
|
||||
bool cWorld::GetChunkBlockData(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_BlockData)
|
||||
{
|
||||
return m_ChunkMap->GetChunkBlockData(a_ChunkX, a_ChunkY, a_ChunkZ, a_BlockData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cWorld::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const
|
||||
{
|
||||
return m_ChunkMap->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ);
|
||||
@ -1279,15 +1292,6 @@ void cWorld::RemoveClientFromChunks(cClientHandle * a_Client, const cChunkCoords
|
||||
|
||||
|
||||
|
||||
bool cWorld::SendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cClientHandle * a_Client)
|
||||
{
|
||||
return m_ChunkMap->SendChunkTo(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||
{
|
||||
m_ChunkMap->TouchChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "WorldStorage.h"
|
||||
#include "cChunkGenerator.h"
|
||||
#include "Vector3i.h"
|
||||
#include "ChunkSender.h"
|
||||
|
||||
|
||||
|
||||
@ -71,7 +72,13 @@ public:
|
||||
void ChunkDataLoaded (int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
||||
void ChunkDataGenerated(int a_ChunkX, int a_ChunkY, int a_ChunkZ, const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
||||
void GetChunkData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, cChunkDataCallback * a_Callback);
|
||||
|
||||
/// Gets the chunk's blocks, only the block types
|
||||
bool GetChunkBlocks (int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_Blocks);
|
||||
|
||||
/// Gets the chunk's blockdata, the entire array
|
||||
bool GetChunkBlockData (int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_BlockData);
|
||||
|
||||
bool IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
|
||||
bool HasChunkAnyClients(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
|
||||
void UnloadUnusedChunks(void);
|
||||
@ -123,9 +130,6 @@ public:
|
||||
/// 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);
|
||||
|
||||
@ -284,6 +288,8 @@ private:
|
||||
sSetBlockList m_FastSetBlockQueue;
|
||||
|
||||
cChunkGenerator m_Generator;
|
||||
|
||||
cChunkSender m_ChunkSender;
|
||||
|
||||
AString m_WorldName;
|
||||
|
||||
|
@ -19,16 +19,15 @@ cPacket_MapChunk::~cPacket_MapChunk()
|
||||
|
||||
|
||||
|
||||
cPacket_MapChunk::cPacket_MapChunk(cChunk * a_Chunk)
|
||||
cPacket_MapChunk::cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_BlockData)
|
||||
{
|
||||
ASSERT(a_Chunk->IsValid());
|
||||
m_PacketID = E_MAP_CHUNK;
|
||||
|
||||
#if (MINECRAFT_1_2_2 == 1 )
|
||||
|
||||
// ...
|
||||
m_PosX = a_Chunk->GetPosX(); // Chunk coordinates now, instead of block coordinates
|
||||
m_PosZ = a_Chunk->GetPosZ();
|
||||
m_PosX = a_ChunkX; // Chunk coordinates now, instead of block coordinates
|
||||
m_PosZ = a_ChunkZ;
|
||||
|
||||
m_bContiguous = false;
|
||||
m_BitMap1 = 0;
|
||||
@ -37,52 +36,59 @@ cPacket_MapChunk::cPacket_MapChunk(cChunk * a_Chunk)
|
||||
m_UnusedInt = 0;
|
||||
|
||||
|
||||
unsigned int DataSize = (cChunk::c_ChunkHeight/16) * (4096 + 2048 + 2048 + 2048);
|
||||
char* AllData = new char[ DataSize ];
|
||||
memset( AllData, 0, DataSize );
|
||||
unsigned int DataSize = (cChunk::c_ChunkHeight / 16) * (4096 + 2048 + 2048 + 2048);
|
||||
std::auto_ptr<char> AllData(new char[ DataSize ]);
|
||||
memset( AllData.get(), 0, DataSize );
|
||||
|
||||
unsigned int iterator = 0;
|
||||
for( int i = 0; i < (cChunk::c_ChunkHeight/16); ++i ) // Old world is only 8*16 high (should be 16*16)
|
||||
for ( int i = 0; i < (cChunk::c_ChunkHeight / 16); ++i )
|
||||
{
|
||||
m_BitMap1 |= (1 << i); // This tells what chunks are sent. Use this to NOT send air only chunks (right now everything is sent)
|
||||
for( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) for( int x = 0; x < 16; ++x )
|
||||
for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z ) for( int x = 0; x < 16; ++x )
|
||||
{
|
||||
AllData[iterator] = a_Chunk->GetBlock( x, y+i*16, z );
|
||||
int idx = cChunk::MakeIndex(x, y + i * 16, z);
|
||||
AllData.get()[iterator] = a_BlockData[idx];
|
||||
++iterator;
|
||||
}
|
||||
} // for y, z, x
|
||||
}
|
||||
//Send block metadata
|
||||
for( int i = 0; i < (cChunk::c_ChunkHeight/16); ++i )
|
||||
|
||||
// Send block metadata:
|
||||
char * Meta = a_BlockData + cChunk::c_NumBlocks;
|
||||
for ( int i = 0; i < (cChunk::c_ChunkHeight / 16); ++i )
|
||||
{
|
||||
for( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z )
|
||||
for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z )
|
||||
{
|
||||
for( int x = 0; x < 8; ++x )
|
||||
for ( int x = 0; x < 8; ++x )
|
||||
{
|
||||
AllData[iterator] = a_Chunk->GetLight( a_Chunk->pGetMeta(), x*2+0, y+i*16, z ) | a_Chunk->GetLight( a_Chunk->pGetMeta(), x*2+1, y+i*16, z ) << 4;
|
||||
AllData.get()[iterator] = cChunk::GetNibble(Meta, x * 2 + 0, y + i * 16, z) | (cChunk::GetNibble(Meta, x * 2 + 1, y + i * 16, z ) << 4);
|
||||
++iterator;
|
||||
} // for x
|
||||
} // for y, z
|
||||
}
|
||||
|
||||
// Send block light:
|
||||
char * Light = Meta + cChunk::c_NumBlocks / 2;
|
||||
for ( int i = 0; i < (cChunk::c_ChunkHeight / 16); ++i )
|
||||
{
|
||||
for ( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z )
|
||||
{
|
||||
for ( int x = 0; x < 8; ++x )
|
||||
{
|
||||
AllData.get()[iterator] = cChunk::GetNibble(Light, x * 2 + 0, y + i * 16, z ) | (cChunk::GetNibble(Light, x * 2 + 1, y + i * 16, z ) << 4);
|
||||
++iterator;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Send block light
|
||||
|
||||
// Send sky light:
|
||||
char * SkyLight = Light + cChunk::c_NumBlocks / 2;
|
||||
for( int i = 0; i < (cChunk::c_ChunkHeight/16); ++i )
|
||||
{
|
||||
for( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z )
|
||||
{
|
||||
for( int x = 0; x < 8; ++x )
|
||||
{
|
||||
AllData[iterator] = a_Chunk->GetLight( a_Chunk->pGetLight(), x*2+0, y+i*16, z ) | a_Chunk->GetLight( a_Chunk->pGetLight(), x*2+1, y+i*16, z ) << 4;
|
||||
++iterator;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Send sky light
|
||||
for( int i = 0; i < (cChunk::c_ChunkHeight/16); ++i )
|
||||
{
|
||||
for( int y = 0; y < 16; ++y ) for( int z = 0; z < 16; ++z )
|
||||
{
|
||||
for( int x = 0; x < 8; ++x )
|
||||
{
|
||||
AllData[iterator] = a_Chunk->GetLight( a_Chunk->pGetSkyLight(), x*2+0, y+i*16, z ) | a_Chunk->GetLight( a_Chunk->pGetSkyLight(), x*2+1, y+i*16, z ) << 4;
|
||||
AllData.get()[iterator] = cChunk::GetNibble(SkyLight, x * 2 + 0, y + i * 16, z ) | (cChunk::GetNibble(SkyLight, x * 2 + 1, y + i * 16, z ) << 4);
|
||||
++iterator;
|
||||
}
|
||||
}
|
||||
@ -91,17 +97,15 @@ cPacket_MapChunk::cPacket_MapChunk(cChunk * a_Chunk)
|
||||
uLongf CompressedSize = compressBound( DataSize );
|
||||
char * CompressedBlockData = new char[CompressedSize];
|
||||
|
||||
compress2( (Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)AllData, DataSize, Z_DEFAULT_COMPRESSION);
|
||||
|
||||
delete [] AllData;
|
||||
compress2( (Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)AllData.get(), DataSize, Z_DEFAULT_COMPRESSION);
|
||||
|
||||
m_CompressedData = CompressedBlockData;
|
||||
m_CompressedSize = CompressedSize;
|
||||
|
||||
#else
|
||||
m_PosX = a_Chunk->GetPosX() * cChunk::c_ChunkWidth; // It has to be block coordinates
|
||||
m_PosY = (short)(a_Chunk->GetPosY() * cChunk::c_ChunkHeight);
|
||||
m_PosZ = a_Chunk->GetPosZ() * cChunk::c_ChunkWidth;
|
||||
m_PosX = a_ChunkX * cChunk::c_ChunkWidth; // It has to be block coordinates
|
||||
m_PosY = (short)(a_ChunkY * cChunk::c_ChunkHeight);
|
||||
m_PosZ = a_ChunkZ * cChunk::c_ChunkWidth;
|
||||
|
||||
m_SizeX = 15;
|
||||
m_SizeY = 127;
|
||||
@ -110,7 +114,7 @@ cPacket_MapChunk::cPacket_MapChunk(cChunk * a_Chunk)
|
||||
uLongf CompressedSize = compressBound( cChunk::c_BlockDataSize );
|
||||
char * CompressedBlockData = new char[CompressedSize];
|
||||
|
||||
compress2( (Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)a_Chunk->pGetBlockData(), cChunk::c_BlockDataSize, Z_DEFAULT_COMPRESSION);
|
||||
compress2( (Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)a_BlockData, cChunk::c_BlockDataSize, Z_DEFAULT_COMPRESSION);
|
||||
|
||||
m_CompressedData = CompressedBlockData;
|
||||
m_CompressedSize = CompressedSize;
|
||||
|
@ -7,12 +7,6 @@
|
||||
|
||||
|
||||
|
||||
class cChunk;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cPacket_MapChunk :
|
||||
public cPacket
|
||||
{
|
||||
@ -39,6 +33,7 @@ public:
|
||||
{ m_PacketID = E_MAP_CHUNK; m_CompressedData = 0; }
|
||||
|
||||
cPacket_MapChunk( const cPacket_MapChunk & a_Copy );
|
||||
cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_BlockData);
|
||||
~cPacket_MapChunk();
|
||||
virtual cPacket* Clone() const { return new cPacket_MapChunk(*this); }
|
||||
|
||||
@ -66,12 +61,6 @@ public:
|
||||
|
||||
|
||||
char * m_CompressedData;
|
||||
|
||||
protected:
|
||||
friend class cChunk;
|
||||
|
||||
cPacket_MapChunk(cChunk * a_Chunk); // Called only from within cChunk, therefore it CAN receive a direct pointer
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user