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"
|
AdditionalOptions="/MP"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="../zlib-1.2.5;../jsoncpp-src-0.5.0/include;../lua-5.1.4/src;../tolua++-1.0.93/include"
|
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"
|
MinimalRebuild="false"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@ -289,6 +289,14 @@
|
|||||||
RelativePath="..\source\cHeartBeat.h"
|
RelativePath="..\source\cHeartBeat.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\source\ChunkSender.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\source\ChunkSender.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\source\cInventory.cpp"
|
RelativePath="..\source\cInventory.cpp"
|
||||||
>
|
>
|
||||||
|
@ -329,6 +329,7 @@
|
|||||||
<ClCompile Include="..\Source\cGroup.cpp" />
|
<ClCompile Include="..\Source\cGroup.cpp" />
|
||||||
<ClCompile Include="..\Source\cGroupManager.cpp" />
|
<ClCompile Include="..\Source\cGroupManager.cpp" />
|
||||||
<ClCompile Include="..\Source\cHeartBeat.cpp" />
|
<ClCompile Include="..\Source\cHeartBeat.cpp" />
|
||||||
|
<ClCompile Include="..\source\ChunkSender.cpp" />
|
||||||
<ClCompile Include="..\source\cIsThread.cpp" />
|
<ClCompile Include="..\source\cIsThread.cpp" />
|
||||||
<ClCompile Include="..\source\cItem.cpp" />
|
<ClCompile Include="..\source\cItem.cpp" />
|
||||||
<ClCompile Include="..\source\cLavaSimulator.cpp" />
|
<ClCompile Include="..\source\cLavaSimulator.cpp" />
|
||||||
@ -513,6 +514,7 @@
|
|||||||
<ClInclude Include="..\Source\cGroup.h" />
|
<ClInclude Include="..\Source\cGroup.h" />
|
||||||
<ClInclude Include="..\Source\cGroupManager.h" />
|
<ClInclude Include="..\Source\cGroupManager.h" />
|
||||||
<ClInclude Include="..\Source\cHeartBeat.h" />
|
<ClInclude Include="..\Source\cHeartBeat.h" />
|
||||||
|
<ClInclude Include="..\source\ChunkSender.h" />
|
||||||
<ClInclude Include="..\source\cIsThread.h" />
|
<ClInclude Include="..\source\cIsThread.h" />
|
||||||
<ClInclude Include="..\Source\cLadder.h" />
|
<ClInclude Include="..\Source\cLadder.h" />
|
||||||
<ClInclude Include="..\source\cLavaSimulator.h" />
|
<ClInclude Include="..\source\cLavaSimulator.h" />
|
||||||
|
@ -918,6 +918,7 @@
|
|||||||
<ClCompile Include="..\source\cRedstoneSimulator.cpp">
|
<ClCompile Include="..\source\cRedstoneSimulator.cpp">
|
||||||
<Filter>Simulator\cSimulator\cRedstoneSimulator</Filter>
|
<Filter>Simulator\cSimulator\cRedstoneSimulator</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\source\ChunkSender.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\source\cServer.h">
|
<ClInclude Include="..\source\cServer.h">
|
||||||
@ -1417,6 +1418,7 @@
|
|||||||
<ClInclude Include="..\source\cRedstoneSimulator.h">
|
<ClInclude Include="..\source\cRedstoneSimulator.h">
|
||||||
<Filter>Simulator\cSimulator\cRedstoneSimulator</Filter>
|
<Filter>Simulator\cSimulator\cRedstoneSimulator</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\source\ChunkSender.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\source\AllToLua.pkg">
|
<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
|
#pragma once
|
||||||
|
|
||||||
|
#include "cClientHandle.h"
|
||||||
|
#include "cWorld.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include "BlockID.h"
|
#include "BlockID.h"
|
||||||
#else
|
#else
|
||||||
@ -16,9 +23,9 @@ namespace Json
|
|||||||
class Value;
|
class Value;
|
||||||
};
|
};
|
||||||
|
|
||||||
class cClientHandle;
|
|
||||||
class cPlayer;
|
class cPlayer;
|
||||||
class cWorld;
|
class cWorld;
|
||||||
|
class cPacket;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -49,7 +56,26 @@ public:
|
|||||||
virtual void SaveToJson (Json::Value & a_Value ) = 0;
|
virtual void SaveToJson (Json::Value & a_Value ) = 0;
|
||||||
|
|
||||||
virtual void UsedBy( cPlayer * a_Player ) = 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:
|
protected:
|
||||||
int m_PosX; // Position in block coordinates
|
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
|
/// Returns true if there is a block entity at the coords specified
|
||||||
bool cChunk::HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ)
|
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)
|
#if (MINECRAFT_1_2_2 == 1)
|
||||||
unsigned int Coords = Y | Z << 8 | X << 12;
|
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;
|
MultiBlock.m_Data[i].Data = Coords << 16 | Blocks;
|
||||||
#else
|
#else
|
||||||
MultiBlock.m_BlockCoordinates[i] = (Z&0xf) | (X&0xf)<<4 | (Y&0xff)<<8;
|
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] );
|
//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_BlockTypes[i] = m_BlockType[index];
|
||||||
MultiBlock.m_BlockMetas[i] = GetLight( m_BlockMeta, index );
|
MultiBlock.m_BlockMetas[i] = GetNibble( m_BlockMeta, index );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
m_PendingSendBlocks.clear();
|
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_PosY = (char)(Y + m_PosY*c_ChunkHeight);
|
||||||
BlockChange.m_PosZ = Z + m_PosZ*c_ChunkWidth;
|
BlockChange.m_PosZ = Z + m_PosZ*c_ChunkWidth;
|
||||||
BlockChange.m_BlockType = m_BlockType[index];
|
BlockChange.m_BlockType = m_BlockType[index];
|
||||||
BlockChange.m_BlockMeta = GetLight( m_BlockMeta, index );
|
BlockChange.m_BlockMeta = GetNibble( m_BlockMeta, index );
|
||||||
Broadcast( BlockChange );
|
Broadcast( BlockChange );
|
||||||
}
|
}
|
||||||
m_PendingSendBlocks.clear();
|
m_PendingSendBlocks.clear();
|
||||||
@ -466,7 +476,7 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
isRedstone = true;
|
isRedstone = true;
|
||||||
case E_BLOCK_TORCH:
|
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 );
|
LOG("MetaData: %i", Dir );
|
||||||
int XX = X + m_PosX*c_ChunkWidth;
|
int XX = X + m_PosX*c_ChunkWidth;
|
||||||
int YY = Y + m_PosY*c_ChunkHeight;
|
int YY = Y + m_PosY*c_ChunkHeight;
|
||||||
@ -490,7 +500,7 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
break;
|
break;
|
||||||
case E_BLOCK_LADDER:
|
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 XX = X + m_PosX*c_ChunkWidth;
|
||||||
int YY = Y + m_PosY*c_ChunkHeight;
|
int YY = Y + m_PosY*c_ChunkHeight;
|
||||||
int ZZ = Z + m_PosZ*c_ChunkWidth;
|
int ZZ = Z + m_PosZ*c_ChunkWidth;
|
||||||
@ -534,13 +544,13 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
case E_BLOCK_DIRT:
|
case E_BLOCK_DIRT:
|
||||||
{
|
{
|
||||||
char AboveBlock = GetBlock( Index+1 );
|
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;
|
break;
|
||||||
@ -552,13 +562,13 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom)
|
|||||||
char AboveBlock = GetBlock( Index+1 );
|
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
|
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;
|
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
|
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 );
|
m_World->GrowTree( m_BlockTickX + m_PosX*c_ChunkWidth, m_BlockTickY, m_BlockTickZ + m_PosZ*c_ChunkWidth );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -675,12 +685,12 @@ void cChunk::CalculateLighting()
|
|||||||
{
|
{
|
||||||
// Calculate sunlight
|
// Calculate sunlight
|
||||||
memset(m_BlockSkyLight, 0xff, c_NumBlocks / 2 ); // Set all to fully lit, so everything above HeightMap is lit
|
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;
|
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);
|
int index = y + (z * c_ChunkHeight) + (x * c_ChunkHeight * c_ChunkWidth);
|
||||||
|
|
||||||
@ -688,21 +698,21 @@ void cChunk::CalculateLighting()
|
|||||||
{
|
{
|
||||||
sunlight = 0x0;
|
sunlight = 0x0;
|
||||||
}
|
}
|
||||||
SetLight( m_BlockSkyLight, x, y, z, sunlight );
|
SetNibble( m_BlockSkyLight, x, y, z, sunlight );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate blocklights
|
// 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];
|
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);
|
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_BlockSkyLight);
|
||||||
SpreadLight(m_BlockLight);
|
SpreadLight(m_BlockLight);
|
||||||
|
|
||||||
|
MarkDirty();
|
||||||
|
|
||||||
// Stop it from calculating again :P
|
// Stop it from calculating again :P
|
||||||
m_bCalculateLighting = false;
|
m_bCalculateLighting = false;
|
||||||
}
|
}
|
||||||
@ -762,11 +774,11 @@ void cChunk::SpreadLight(char* a_LightBuffer)
|
|||||||
int index = y + (z * c_ChunkHeight) + (0 * c_ChunkHeight * c_ChunkWidth);
|
int index = y + (z * c_ChunkHeight) + (0 * c_ChunkHeight * c_ChunkWidth);
|
||||||
if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
|
if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
|
||||||
{
|
{
|
||||||
char CurrentLight = GetLight( a_LightBuffer, 0, y, z );
|
char CurrentLight = GetNibble( a_LightBuffer, 0, y, z );
|
||||||
char LeftLight = GetLight( LeftSky, c_ChunkWidth-1, y, z );
|
char LeftLight = GetNibble( LeftSky, c_ChunkWidth-1, y, z );
|
||||||
if( LeftLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ] )
|
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;
|
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);
|
int index = y + (z * c_ChunkHeight) + ((c_ChunkWidth-1) * c_ChunkHeight * c_ChunkWidth);
|
||||||
if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
|
if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
|
||||||
{
|
{
|
||||||
char CurrentLight = GetLight( a_LightBuffer, c_ChunkWidth-1, y, z );
|
char CurrentLight = GetNibble( a_LightBuffer, c_ChunkWidth-1, y, z );
|
||||||
char RightLight = GetLight( RightSky, 0, y, z );
|
char RightLight = GetNibble( RightSky, 0, y, z );
|
||||||
if( RightLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ] )
|
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;
|
bCalcRight = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -806,11 +818,11 @@ void cChunk::SpreadLight(char* a_LightBuffer)
|
|||||||
int index = y + (0 * c_ChunkHeight) + (x * c_ChunkHeight * c_ChunkWidth);
|
int index = y + (0 * c_ChunkHeight) + (x * c_ChunkHeight * c_ChunkWidth);
|
||||||
if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
|
if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
|
||||||
{
|
{
|
||||||
char CurrentLight = GetLight( a_LightBuffer, x, y, 0 );
|
char CurrentLight = GetNibble( a_LightBuffer, x, y, 0 );
|
||||||
char FrontLight = GetLight( FrontSky, x, y, c_ChunkWidth-1 );
|
char FrontLight = GetNibble( FrontSky, x, y, c_ChunkWidth-1 );
|
||||||
if( FrontLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ] )
|
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;
|
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);
|
int index = y + ((c_ChunkWidth-1) * c_ChunkHeight) + (x * c_ChunkHeight * c_ChunkWidth);
|
||||||
if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
|
if( g_BlockSpreadLightFalloff[ m_BlockData[index] ] > 0 )
|
||||||
{
|
{
|
||||||
char CurrentLight = GetLight( a_LightBuffer, x, y, c_ChunkWidth-1 );
|
char CurrentLight = GetNibble( a_LightBuffer, x, y, c_ChunkWidth-1 );
|
||||||
char BackLight = GetLight( BackSky, x, y, 0 );
|
char BackLight = GetNibble( BackSky, x, y, 0 );
|
||||||
if ( BackLight < CurrentLight-g_BlockSpreadLightFalloff[ m_BlockData[index] ] )
|
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;
|
bCalcBack = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( bCalcLeft ) m_World->ReSpreadLighting( m_PosX - 1, m_PosY, m_PosZ );
|
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 ( bCalcRight ) m_World->ReSpreadLighting( m_PosX + 1, m_PosY, m_PosZ );
|
||||||
if( bCalcFront ) m_World->ReSpreadLighting( m_PosX, m_PosY, m_PosZ - 1 );
|
if ( bCalcFront ) m_World->ReSpreadLighting( m_PosX, m_PosY, m_PosZ - 1 );
|
||||||
if( bCalcBack ) 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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?
|
ASSERT(IsValid()); // Is this chunk loaded / generated?
|
||||||
|
|
||||||
int index = a_Y + (a_Z * c_ChunkHeight) + (a_X * c_ChunkHeight * c_ChunkWidth);
|
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];
|
char OldBlockType = m_BlockType[index];
|
||||||
m_BlockType[index] = a_BlockType;
|
m_BlockType[index] = a_BlockType;
|
||||||
|
|
||||||
// It's called SetLight(), but it sets the Meta when passed the BlockMeta workspace
|
SetNibble( m_BlockMeta, index, a_BlockMeta );
|
||||||
SetLight( m_BlockMeta, index, a_BlockMeta );
|
|
||||||
|
|
||||||
if ((OldBlockType == a_BlockType) && (OldBlockMeta == 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 int index = a_Y + (a_Z * c_ChunkHeight) + (a_X * c_ChunkHeight * c_ChunkWidth);
|
||||||
const char OldBlock = m_BlockType[index];
|
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)
|
if (OldBlock == a_BlockType && OldBlockMeta == a_BlockMeta)
|
||||||
{
|
{
|
||||||
return;
|
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 );
|
m_PendingSendBlocks.push_back( index );
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's called SetLight(), but it sets the Meta when passed the BlockMeta workspace
|
SetNibble( m_BlockMeta, index, a_BlockMeta );
|
||||||
SetLight( m_BlockMeta, index, a_BlockMeta );
|
|
||||||
|
|
||||||
// ONLY recalculate lighting if it's necessary!
|
// ONLY recalculate lighting if it's necessary!
|
||||||
if(
|
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 )
|
if( index != INDEX_OUT_OF_RANGE )
|
||||||
{
|
{
|
||||||
BlockChange.m_BlockType = m_BlockType[ index ];
|
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
|
} // else it's both 0
|
||||||
a_Client->Send( BlockChange );
|
a_Client->Send( BlockChange );
|
||||||
break;
|
break;
|
||||||
|
@ -145,7 +145,10 @@ public:
|
|||||||
void SetAllData(const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
void SetAllData(const char * a_BlockData, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities);
|
||||||
|
|
||||||
/// Copies m_BlockData into a_Blocks, only the block types
|
/// 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
|
/// Returns true if there is a block entity at the coords specified
|
||||||
bool HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ);
|
bool HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
@ -160,7 +163,7 @@ public:
|
|||||||
int GetPosZ() { return m_PosZ; }
|
int GetPosZ() { return m_PosZ; }
|
||||||
cWorld * GetWorld() { return m_World; }
|
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 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.
|
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)
|
void CopyBlockDataFrom(const char * a_NewBlockData); // Copies all blockdata, recalculates heightmap (used by chunk loaders)
|
||||||
|
|
||||||
char GetLight(char* a_Buffer, int a_BlockIdx);
|
static char GetNibble(char * a_Buffer, int a_BlockIdx);
|
||||||
char GetLight(char* a_Buffer, int x, int y, int z);
|
static char GetNibble(char * a_Buffer, int x, int y, int z);
|
||||||
void SetLight(char* a_Buffer, int a_BlockIdx, char a_Light);
|
static void SetNibble(char * a_Buffer, int a_BlockIdx, char a_Light);
|
||||||
void SetLight(char* a_Buffer, int x, int y, int z, char 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);
|
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 );
|
Vector3i PositionToWorldPosition( const Vector3i & a_InChunkPos );
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
|
|
||||||
__C_CHUNK_INLINE__
|
__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 )
|
if( a_BlockIdx > -1 && a_BlockIdx < c_NumBlocks )
|
||||||
{
|
{
|
||||||
@ -33,7 +33,7 @@ char cChunk::GetLight(char* a_Buffer, int a_BlockIdx)
|
|||||||
|
|
||||||
|
|
||||||
__C_CHUNK_INLINE__
|
__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 )
|
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__
|
__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 )
|
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] &= 0x0f; // Set second half to 0
|
||||||
a_Buffer[cindex] |= (a_Light << 4) & 0xf0;
|
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__
|
__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 )
|
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] &= 0x0f; // Set second half to 0
|
||||||
a_Buffer[cindex] |= (light << 4) & 0xf0;
|
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__
|
__C_CHUNK_INLINE__
|
||||||
void cChunk::SpreadLightOfBlock(char* a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff)
|
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 );
|
unsigned char CurrentLight = GetNibble( 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) ) );
|
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) ) );
|
||||||
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) ) );
|
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) ) );
|
||||||
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) ) );
|
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) ) );
|
||||||
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) ) );
|
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) ) );
|
||||||
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) ) );
|
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) ) );
|
||||||
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) ) );
|
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__
|
__C_CHUNK_INLINE__
|
||||||
void cChunk::SpreadLightOfBlockX(char* a_LightBuffer, int a_X, int a_Y, int a_Z)
|
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 );
|
unsigned char CurrentLight = GetNibble( 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) );
|
SetNibble( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(GetNibble( 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) );
|
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__
|
__C_CHUNK_INLINE__
|
||||||
void cChunk::SpreadLightOfBlockY(char* a_LightBuffer, int a_X, int a_Y, int a_Z)
|
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 );
|
unsigned char CurrentLight = GetNibble( 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) );
|
SetNibble( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(GetNibble( 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) );
|
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__
|
__C_CHUNK_INLINE__
|
||||||
void cChunk::SpreadLightOfBlockZ(char* a_LightBuffer, int a_X, int a_Y, int a_Z)
|
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 );
|
unsigned char CurrentLight = GetNibble( 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) );
|
SetNibble( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(GetNibble( 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) );
|
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)
|
bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
cCSLock Lock(m_CSLayers);
|
||||||
@ -469,14 +485,17 @@ void cChunkMap::CollectPickupsByPlayer(cPlayer * a_Player)
|
|||||||
int OtherChunkX = ChunkX + ((BlockX > 8) ? 1 : -1);
|
int OtherChunkX = ChunkX + ((BlockX > 8) ? 1 : -1);
|
||||||
int OtherChunkZ = ChunkZ + ((BlockZ > 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);
|
cCSLock Lock(m_CSLayers);
|
||||||
GetChunkNoGen(ChunkX, ChunkY, ChunkZ)->CollectPickupsByPlayer(a_Player);
|
GetChunkNoLoad(ChunkX, ChunkY, ChunkZ)->CollectPickupsByPlayer(a_Player);
|
||||||
|
|
||||||
// Check the neighboring chunks as well:
|
// Check the neighboring chunks as well:
|
||||||
GetChunkNoGen(OtherChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player);
|
GetChunkNoLoad(OtherChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player);
|
||||||
GetChunkNoGen(OtherChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player);
|
GetChunkNoLoad(OtherChunkX, ChunkY, OtherChunkZ)->CollectPickupsByPlayer(a_Player);
|
||||||
GetChunkNoGen(ChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player);
|
GetChunkNoLoad(ChunkX, ChunkY, ChunkZ )->CollectPickupsByPlayer(a_Player);
|
||||||
GetChunkNoGen(ChunkX, ChunkY, OtherChunkZ)->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() )
|
if ((Chunk != NULL) && Chunk->IsValid() )
|
||||||
{
|
{
|
||||||
// Although it is called GetLight(), it actually gets meta when passed the Meta field
|
// 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;
|
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 );
|
cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
|
||||||
if ((Chunk != NULL) && Chunk->IsValid() )
|
if ((Chunk != NULL) && Chunk->IsValid() )
|
||||||
{
|
{
|
||||||
// Although it is called SetLight(), it actually sets meta when passed the Meta field
|
cChunk::SetNibble( Chunk->pGetMeta(), a_X, a_Y, a_Z, a_BlockMeta );
|
||||||
Chunk->SetLight( Chunk->pGetMeta(), a_X, a_Y, a_Z, a_BlockMeta );
|
Chunk->MarkDirty();
|
||||||
Chunk->SendBlockTo( a_X, a_Y, a_Z, NULL );
|
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)
|
void cChunkMap::MoveEntityToChunk(cEntity * a_Entity, int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSLayers);
|
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 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 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);
|
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);
|
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 IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||||
bool HasChunkAnyClients (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);
|
void SpreadChunkLighting(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||||
@ -71,9 +77,6 @@ public:
|
|||||||
/// Removes the client from all chunks specified
|
/// Removes the client from all chunks specified
|
||||||
void RemoveClientFromChunks(cClientHandle * a_Client, const cChunkCoordsList & a_Chunks);
|
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
|
/// 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);
|
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);
|
Send(Ping);
|
||||||
m_LastPingTime = m_PingStartTime;
|
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_PLAYERMOVELOOK:
|
||||||
case E_KEEP_ALIVE:
|
case E_KEEP_ALIVE:
|
||||||
case E_PRE_CHUNK:
|
case E_PRE_CHUNK:
|
||||||
|
case E_MAP_CHUNK:
|
||||||
{
|
{
|
||||||
// Allow
|
// Allow
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case E_MAP_CHUNK:
|
|
||||||
{
|
|
||||||
CheckIfWorldDownloaded();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: return;
|
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);
|
cCSLock Lock(m_CSPackets);
|
||||||
if (a_Priority == E_PRIORITY_NORMAL)
|
if (a_Priority == E_PRIORITY_NORMAL)
|
||||||
{
|
{
|
||||||
|
@ -94,6 +94,8 @@ public:
|
|||||||
|
|
||||||
bool IsDestroyed() { return m_bDestroyed; }
|
bool IsDestroyed() { return m_bDestroyed; }
|
||||||
void Destroy();
|
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) { Send(&a_Packet, a_Priority); }
|
||||||
void Send(const cPacket * a_Packet, ENUM_PRIORITY a_Priority = E_PRIORITY_NORMAL);
|
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)
|
void cPlayer::Tick(float a_Dt)
|
||||||
{
|
{
|
||||||
|
if (!m_ClientHandle->IsPlaying())
|
||||||
|
{
|
||||||
|
// We're not yet in the game, ignore everything
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cPawn::Tick(a_Dt);
|
cPawn::Tick(a_Dt);
|
||||||
|
|
||||||
if (m_bDirtyOrientation && !m_bDirtyPosition)
|
if (m_bDirtyOrientation && !m_bDirtyPosition)
|
||||||
@ -233,7 +239,7 @@ void cPlayer::Tick(float a_Dt)
|
|||||||
m_ClientHandle->StreamChunks();
|
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);
|
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;
|
cPacket_UpdateSign * Sign = new cPacket_UpdateSign;
|
||||||
Sign.m_PosX = m_PosX;
|
Sign->m_PosX = m_PosX;
|
||||||
Sign.m_PosY = (short)m_PosY;
|
Sign->m_PosY = (short)m_PosY;
|
||||||
Sign.m_PosZ = m_PosZ;
|
Sign->m_PosZ = m_PosZ;
|
||||||
Sign.m_Line1 = m_Line[0];
|
Sign->m_Line1 = m_Line[0];
|
||||||
Sign.m_Line2 = m_Line[1];
|
Sign->m_Line2 = m_Line[1];
|
||||||
Sign.m_Line3 = m_Line[2];
|
Sign->m_Line3 = m_Line[2];
|
||||||
Sign.m_Line4 = m_Line[3];
|
Sign->m_Line4 = m_Line[3];
|
||||||
|
return Sign;
|
||||||
if ( a_Client != NULL )
|
|
||||||
{
|
|
||||||
a_Client->Send( Sign );
|
|
||||||
}
|
|
||||||
else // broadcast of a_Client == 0
|
|
||||||
{
|
|
||||||
m_World->BroadcastToChunkOfBlock(m_PosX, m_PosY, m_PosZ, &Sign );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,7 +34,8 @@ public:
|
|||||||
AString GetLine( int a_Index ) const;
|
AString GetLine( int a_Index ) const;
|
||||||
|
|
||||||
virtual void UsedBy( cPlayer * a_Player ) override;
|
virtual void UsedBy( cPlayer * a_Player ) override;
|
||||||
virtual void SendTo( cClientHandle* a_Client ) override;
|
|
||||||
|
virtual cPacket * GetPacket(void) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -238,6 +238,8 @@ cWorld::cWorld( const AString & a_WorldName )
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_ChunkMap = new cChunkMap(this );
|
m_ChunkMap = new cChunkMap(this );
|
||||||
|
|
||||||
|
m_ChunkSender.Start(this);
|
||||||
|
|
||||||
m_Time = 0;
|
m_Time = 0;
|
||||||
m_WorldTimeFraction = 0.f;
|
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)
|
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_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)
|
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_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
|
bool cWorld::IsChunkValid(int a_ChunkX, int a_ChunkY, int a_ChunkZ) const
|
||||||
{
|
{
|
||||||
return m_ChunkMap->IsChunkValid(a_ChunkX, a_ChunkY, a_ChunkZ);
|
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)
|
void cWorld::TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||||
{
|
{
|
||||||
m_ChunkMap->TouchChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
|
m_ChunkMap->TouchChunk(a_ChunkX, a_ChunkY, a_ChunkZ);
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "WorldStorage.h"
|
#include "WorldStorage.h"
|
||||||
#include "cChunkGenerator.h"
|
#include "cChunkGenerator.h"
|
||||||
#include "Vector3i.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 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 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);
|
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);
|
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 IsChunkValid (int a_ChunkX, int a_ChunkY, int a_ChunkZ) const;
|
||||||
bool HasChunkAnyClients(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);
|
void UnloadUnusedChunks(void);
|
||||||
@ -123,9 +130,6 @@ public:
|
|||||||
/// Removes the client from all chunks specified
|
/// Removes the client from all chunks specified
|
||||||
void RemoveClientFromChunks(cClientHandle * a_Client, const cChunkCoordsList & a_Chunks);
|
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
|
/// Touches the chunk, causing it to be loaded or generated
|
||||||
void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
void TouchChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
|
||||||
|
|
||||||
@ -284,6 +288,8 @@ private:
|
|||||||
sSetBlockList m_FastSetBlockQueue;
|
sSetBlockList m_FastSetBlockQueue;
|
||||||
|
|
||||||
cChunkGenerator m_Generator;
|
cChunkGenerator m_Generator;
|
||||||
|
|
||||||
|
cChunkSender m_ChunkSender;
|
||||||
|
|
||||||
AString m_WorldName;
|
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;
|
m_PacketID = E_MAP_CHUNK;
|
||||||
|
|
||||||
#if (MINECRAFT_1_2_2 == 1 )
|
#if (MINECRAFT_1_2_2 == 1 )
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
m_PosX = a_Chunk->GetPosX(); // Chunk coordinates now, instead of block coordinates
|
m_PosX = a_ChunkX; // Chunk coordinates now, instead of block coordinates
|
||||||
m_PosZ = a_Chunk->GetPosZ();
|
m_PosZ = a_ChunkZ;
|
||||||
|
|
||||||
m_bContiguous = false;
|
m_bContiguous = false;
|
||||||
m_BitMap1 = 0;
|
m_BitMap1 = 0;
|
||||||
@ -37,52 +36,59 @@ cPacket_MapChunk::cPacket_MapChunk(cChunk * a_Chunk)
|
|||||||
m_UnusedInt = 0;
|
m_UnusedInt = 0;
|
||||||
|
|
||||||
|
|
||||||
unsigned int DataSize = (cChunk::c_ChunkHeight/16) * (4096 + 2048 + 2048 + 2048);
|
unsigned int DataSize = (cChunk::c_ChunkHeight / 16) * (4096 + 2048 + 2048 + 2048);
|
||||||
char* AllData = new char[ DataSize ];
|
std::auto_ptr<char> AllData(new char[ DataSize ]);
|
||||||
memset( AllData, 0, DataSize );
|
memset( AllData.get(), 0, DataSize );
|
||||||
|
|
||||||
unsigned int iterator = 0;
|
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)
|
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;
|
++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;
|
++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 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->pGetLight(), x*2+0, y+i*16, z ) | a_Chunk->GetLight( a_Chunk->pGetLight(), 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//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;
|
|
||||||
++iterator;
|
++iterator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,17 +97,15 @@ cPacket_MapChunk::cPacket_MapChunk(cChunk * a_Chunk)
|
|||||||
uLongf CompressedSize = compressBound( DataSize );
|
uLongf CompressedSize = compressBound( DataSize );
|
||||||
char * CompressedBlockData = new char[CompressedSize];
|
char * CompressedBlockData = new char[CompressedSize];
|
||||||
|
|
||||||
compress2( (Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)AllData, DataSize, Z_DEFAULT_COMPRESSION);
|
compress2( (Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)AllData.get(), DataSize, Z_DEFAULT_COMPRESSION);
|
||||||
|
|
||||||
delete [] AllData;
|
|
||||||
|
|
||||||
m_CompressedData = CompressedBlockData;
|
m_CompressedData = CompressedBlockData;
|
||||||
m_CompressedSize = CompressedSize;
|
m_CompressedSize = CompressedSize;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
m_PosX = a_Chunk->GetPosX() * cChunk::c_ChunkWidth; // It has to be block coordinates
|
m_PosX = a_ChunkX * cChunk::c_ChunkWidth; // It has to be block coordinates
|
||||||
m_PosY = (short)(a_Chunk->GetPosY() * cChunk::c_ChunkHeight);
|
m_PosY = (short)(a_ChunkY * cChunk::c_ChunkHeight);
|
||||||
m_PosZ = a_Chunk->GetPosZ() * cChunk::c_ChunkWidth;
|
m_PosZ = a_ChunkZ * cChunk::c_ChunkWidth;
|
||||||
|
|
||||||
m_SizeX = 15;
|
m_SizeX = 15;
|
||||||
m_SizeY = 127;
|
m_SizeY = 127;
|
||||||
@ -110,7 +114,7 @@ cPacket_MapChunk::cPacket_MapChunk(cChunk * a_Chunk)
|
|||||||
uLongf CompressedSize = compressBound( cChunk::c_BlockDataSize );
|
uLongf CompressedSize = compressBound( cChunk::c_BlockDataSize );
|
||||||
char * CompressedBlockData = new char[CompressedSize];
|
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_CompressedData = CompressedBlockData;
|
||||||
m_CompressedSize = CompressedSize;
|
m_CompressedSize = CompressedSize;
|
||||||
|
@ -7,12 +7,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cChunk;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class cPacket_MapChunk :
|
class cPacket_MapChunk :
|
||||||
public cPacket
|
public cPacket
|
||||||
{
|
{
|
||||||
@ -39,6 +33,7 @@ public:
|
|||||||
{ m_PacketID = E_MAP_CHUNK; m_CompressedData = 0; }
|
{ m_PacketID = E_MAP_CHUNK; m_CompressedData = 0; }
|
||||||
|
|
||||||
cPacket_MapChunk( const cPacket_MapChunk & a_Copy );
|
cPacket_MapChunk( const cPacket_MapChunk & a_Copy );
|
||||||
|
cPacket_MapChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, char * a_BlockData);
|
||||||
~cPacket_MapChunk();
|
~cPacket_MapChunk();
|
||||||
virtual cPacket* Clone() const { return new cPacket_MapChunk(*this); }
|
virtual cPacket* Clone() const { return new cPacket_MapChunk(*this); }
|
||||||
|
|
||||||
@ -66,12 +61,6 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
char * m_CompressedData;
|
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