1
0
Fork 0

BlockArea writing support (BlockTypes with BlockMeta only)

git-svn-id: http://mc-server.googlecode.com/svn/trunk@933 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com 2012-10-06 16:58:31 +00:00
parent 25b163edbd
commit 4c370798d5
11 changed files with 504 additions and 16 deletions

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 10/03/12 10:03:23.
** Generated automatically by tolua++-1.0.92 on 10/06/12 17:42:13.
*/
#ifndef __cplusplus
@ -6124,6 +6124,38 @@ static int tolua_AllToLua_cPlayer_GetInventory00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetEquippedItem of class cPlayer */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetEquippedItem00
static int tolua_AllToLua_cPlayer_GetEquippedItem00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEquippedItem'", NULL);
#endif
{
const cItem& tolua_ret = (const cItem&) self->GetEquippedItem();
tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const cItem");
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'GetEquippedItem'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: TeleportTo of class cPlayer */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_TeleportTo00
static int tolua_AllToLua_cPlayer_TeleportTo00(lua_State* tolua_S)
@ -18853,6 +18885,40 @@ tolua_lerror:
}
#endif //#ifndef TOLUA_DISABLE
/* method: DumpToRawFile of class cBlockArea */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_DumpToRawFile00
static int tolua_AllToLua_cBlockArea_DumpToRawFile00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cBlockArea",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
cBlockArea* self = (cBlockArea*) tolua_tousertype(tolua_S,1,0);
const AString a_FileName = ((const AString) tolua_tocppstring(tolua_S,2,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DumpToRawFile'", NULL);
#endif
{
self->DumpToRawFile(a_FileName);
tolua_pushcppstring(tolua_S,(const char*)a_FileName);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'DumpToRawFile'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: SetRelBlockType of class cBlockArea */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_SetRelBlockType00
static int tolua_AllToLua_cBlockArea_SetRelBlockType00(lua_State* tolua_S)
@ -19469,6 +19535,102 @@ static int tolua_AllToLua_cBlockArea_GetBlockSkyLight00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetSizeX of class cBlockArea */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_GetSizeX00
static int tolua_AllToLua_cBlockArea_GetSizeX00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"const cBlockArea",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const cBlockArea* self = (const cBlockArea*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSizeX'", NULL);
#endif
{
int tolua_ret = (int) self->GetSizeX();
tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'GetSizeX'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetSizeY of class cBlockArea */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_GetSizeY00
static int tolua_AllToLua_cBlockArea_GetSizeY00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"const cBlockArea",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const cBlockArea* self = (const cBlockArea*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSizeY'", NULL);
#endif
{
int tolua_ret = (int) self->GetSizeY();
tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'GetSizeY'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetSizeZ of class cBlockArea */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_GetSizeZ00
static int tolua_AllToLua_cBlockArea_GetSizeZ00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"const cBlockArea",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const cBlockArea* self = (const cBlockArea*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSizeZ'", NULL);
#endif
{
int tolua_ret = (int) self->GetSizeZ();
tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'GetSizeZ'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetDataTypes of class cBlockArea */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_GetDataTypes00
static int tolua_AllToLua_cBlockArea_GetDataTypes00(lua_State* tolua_S)
@ -19501,6 +19663,134 @@ static int tolua_AllToLua_cBlockArea_GetDataTypes00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
/* method: HasBlockTypes of class cBlockArea */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_HasBlockTypes00
static int tolua_AllToLua_cBlockArea_HasBlockTypes00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"const cBlockArea",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const cBlockArea* self = (const cBlockArea*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasBlockTypes'", NULL);
#endif
{
bool tolua_ret = (bool) self->HasBlockTypes();
tolua_pushboolean(tolua_S,(bool)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'HasBlockTypes'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: HasBlockMetas of class cBlockArea */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_HasBlockMetas00
static int tolua_AllToLua_cBlockArea_HasBlockMetas00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"const cBlockArea",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const cBlockArea* self = (const cBlockArea*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasBlockMetas'", NULL);
#endif
{
bool tolua_ret = (bool) self->HasBlockMetas();
tolua_pushboolean(tolua_S,(bool)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'HasBlockMetas'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: HasBlockLights of class cBlockArea */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_HasBlockLights00
static int tolua_AllToLua_cBlockArea_HasBlockLights00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"const cBlockArea",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const cBlockArea* self = (const cBlockArea*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasBlockLights'", NULL);
#endif
{
bool tolua_ret = (bool) self->HasBlockLights();
tolua_pushboolean(tolua_S,(bool)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'HasBlockLights'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: HasBlockSkyLights of class cBlockArea */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cBlockArea_HasBlockSkyLights00
static int tolua_AllToLua_cBlockArea_HasBlockSkyLights00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"const cBlockArea",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const cBlockArea* self = (const cBlockArea*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasBlockSkyLights'", NULL);
#endif
{
bool tolua_ret = (bool) self->HasBlockSkyLights();
tolua_pushboolean(tolua_S,(bool)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'HasBlockSkyLights'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: FillBlocks of class cLuaChunk */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cLuaChunk_FillBlocks00
static int tolua_AllToLua_cLuaChunk_FillBlocks00(lua_State* tolua_S)
@ -21878,6 +22168,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"IsOnGround",tolua_AllToLua_cPlayer_IsOnGround00);
tolua_function(tolua_S,"GetStance",tolua_AllToLua_cPlayer_GetStance00);
tolua_function(tolua_S,"GetInventory",tolua_AllToLua_cPlayer_GetInventory00);
tolua_function(tolua_S,"GetEquippedItem",tolua_AllToLua_cPlayer_GetEquippedItem00);
tolua_function(tolua_S,"TeleportTo",tolua_AllToLua_cPlayer_TeleportTo00);
tolua_function(tolua_S,"GetGameMode",tolua_AllToLua_cPlayer_GetGameMode00);
tolua_function(tolua_S,"GetIP",tolua_AllToLua_cPlayer_GetIP00);
@ -22441,6 +22732,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"Read",tolua_AllToLua_cBlockArea_Read01);
tolua_function(tolua_S,"Write",tolua_AllToLua_cBlockArea_Write00);
tolua_function(tolua_S,"Write",tolua_AllToLua_cBlockArea_Write01);
tolua_function(tolua_S,"DumpToRawFile",tolua_AllToLua_cBlockArea_DumpToRawFile00);
tolua_function(tolua_S,"SetRelBlockType",tolua_AllToLua_cBlockArea_SetRelBlockType00);
tolua_function(tolua_S,"SetBlockType",tolua_AllToLua_cBlockArea_SetBlockType00);
tolua_function(tolua_S,"SetRelBlockMeta",tolua_AllToLua_cBlockArea_SetRelBlockMeta00);
@ -22457,7 +22749,14 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"GetBlockLight",tolua_AllToLua_cBlockArea_GetBlockLight00);
tolua_function(tolua_S,"GetRelBlockSkyLight",tolua_AllToLua_cBlockArea_GetRelBlockSkyLight00);
tolua_function(tolua_S,"GetBlockSkyLight",tolua_AllToLua_cBlockArea_GetBlockSkyLight00);
tolua_function(tolua_S,"GetSizeX",tolua_AllToLua_cBlockArea_GetSizeX00);
tolua_function(tolua_S,"GetSizeY",tolua_AllToLua_cBlockArea_GetSizeY00);
tolua_function(tolua_S,"GetSizeZ",tolua_AllToLua_cBlockArea_GetSizeZ00);
tolua_function(tolua_S,"GetDataTypes",tolua_AllToLua_cBlockArea_GetDataTypes00);
tolua_function(tolua_S,"HasBlockTypes",tolua_AllToLua_cBlockArea_HasBlockTypes00);
tolua_function(tolua_S,"HasBlockMetas",tolua_AllToLua_cBlockArea_HasBlockMetas00);
tolua_function(tolua_S,"HasBlockLights",tolua_AllToLua_cBlockArea_HasBlockLights00);
tolua_function(tolua_S,"HasBlockSkyLights",tolua_AllToLua_cBlockArea_HasBlockSkyLights00);
tolua_endmodule(tolua_S);
tolua_cclass(tolua_S,"cLuaChunk","cLuaChunk","",NULL);
tolua_beginmodule(tolua_S,"cLuaChunk");

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 10/03/12 10:03:23.
** Generated automatically by tolua++-1.0.92 on 10/06/12 17:42:14.
*/
/* Exported function */

View File

@ -50,6 +50,7 @@ void cBlockArea::Clear(void)
bool cBlockArea::Read(cWorld * a_World, int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ, int a_DataTypes)
{
// Normalize the coords:
@ -66,6 +67,11 @@ bool cBlockArea::Read(cWorld * a_World, int a_MinBlockX, int a_MaxBlockX, int a_
std::swap(a_MinBlockZ, a_MaxBlockZ);
}
// Include the Max coords:
a_MaxBlockX += 1;
a_MaxBlockY += 1;
a_MaxBlockZ += 1;
// Check coords validity:
if (a_MinBlockY < 0)
{
@ -111,6 +117,7 @@ bool cBlockArea::Read(cWorld * a_World, int a_MinBlockX, int a_MaxBlockX, int a_
Clear();
return false;
}
return true;
}
@ -120,15 +127,66 @@ bool cBlockArea::Read(cWorld * a_World, int a_MinBlockX, int a_MaxBlockX, int a_
bool cBlockArea::Write(cWorld * a_World, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes)
{
// TODO
ASSERT(!"Not implemented yet");
return false;
ASSERT((a_DataTypes & GetDataTypes()) == a_DataTypes); // Are you requesting only the data that I have?
a_DataTypes = a_DataTypes & GetDataTypes(); // For release builds, silently cut off the datatypes that I don't have
// Check coords validity:
if (a_MinBlockY < 0)
{
LOGWARNING("cBlockArea:Read(): MinBlockY less than zero, adjusting to zero");
a_MinBlockY = 0;
}
else if (a_MinBlockY >= cChunkDef::Height - m_SizeY)
{
LOGWARNING("cBlockArea::Read(): MinBlockY + m_SizeY more than chunk height, adjusting to chunk height");
a_MinBlockY = cChunkDef::Height - m_SizeY - 1;
}
return a_World->WriteBlockArea(*this, a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_DataTypes);
}
void cBlockArea::DumpToRawFile(const AString & a_FileName)
{
cFile f;
if (!f.Open(a_FileName, cFile::fmWrite))
{
LOGWARNING("cBlockArea: Cannot open file \"%s\" for raw dump", a_FileName.c_str());
return;
}
UInt32 SizeX = ntohl(m_SizeX);
UInt32 SizeY = ntohl(m_SizeY);
UInt32 SizeZ = ntohl(m_SizeZ);
f.Write(&SizeX, 4);
f.Write(&SizeY, 4);
f.Write(&SizeZ, 4);
unsigned char DataTypes = GetDataTypes();
f.Write(&DataTypes, 1);
int NumBlocks = GetBlockCount();
if (HasBlockTypes())
{
f.Write(m_BlockTypes, NumBlocks * sizeof(BLOCKTYPE));
}
if (HasBlockMetas())
{
f.Write(m_BlockMetas, NumBlocks);
}
if (HasBlockLights())
{
f.Write(m_BlockLight, NumBlocks);
}
if (HasBlockSkyLights())
{
f.Write(m_BlockSkyLight, NumBlocks);
}
}
void cBlockArea::SetRelBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType)
{
@ -623,4 +681,3 @@ void cBlockArea::cChunkReader::BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight)

View File

@ -4,6 +4,8 @@
// Interfaces to the cBlockArea object representing an area of block data that can be queried from cWorld and then accessed again without further queries
// The object also supports writing the blockdata back into cWorld, even into other coords
// NOTE: All Nibble values (meta, blocklight, skylight) are stored one-nibble-per-byte for faster access / editting!
@ -48,9 +50,12 @@ public:
/// Reads an area of blocks specified. Returns true if successful. All coords are inclusive.
bool Read(cWorld * a_World, int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ, int a_DataTypes = baTypes | baMetas);
/// Writes the area back into cWorld at the coords specified. Returns true if successful.
/// Writes the area back into cWorld at the coords specified. Returns true if successful in all chunks, false if only partially / not at all
bool Write(cWorld * a_World, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes = baTypes | baMetas);
/// For testing purposes only, dumps the area into a file.
void DumpToRawFile(const AString & a_FileName);
// TODO: Write() is not too good an interface: if it fails, there's no way to repeat only for the parts that didn't write
// A better way may be to return a list of cBlockAreas for each part that didn't succeed writing, so that the caller may try again
@ -74,21 +79,30 @@ public:
NIBBLETYPE GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ);
NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ);
int GetSizeX(void) const { return m_SizeX; }
int GetSizeY(void) const { return m_SizeY; }
int GetSizeZ(void) const { return m_SizeZ; }
/// Returns the datatypes that are stored in the object (bitmask of baXXX values)
int GetDataTypes(void) const;
bool HasBlockTypes (void) const { return (m_BlockTypes != NULL); }
bool HasBlockMetas (void) const { return (m_BlockMetas != NULL); }
bool HasBlockLights (void) const { return (m_BlockLight != NULL); }
bool HasBlockSkyLights(void) const { return (m_BlockSkyLight != NULL); }
// tolua_end
// Clients can use these for faster access to all blocktypes. Be careful though!
/// Returns the internal pointer to the block types
BLOCKTYPE * GetBlockTypes(void) { return m_BlockTypes; }
int GetBlockCount(void) const { return m_SizeX * m_SizeY * m_SizeZ; }
// tolua_begin
BLOCKTYPE * GetBlockTypes (void) { return m_BlockTypes; }
NIBBLETYPE * GetBlockMetas (void) { return m_BlockMetas; } // NOTE: one byte per block!
NIBBLETYPE * GetBlockLight (void) { return m_BlockLight; } // NOTE: one byte per block!
NIBBLETYPE * GetBlockSkyLight(void) { return m_BlockSkyLight; } // NOTE: one byte per block!
int GetBlockCount(void) const { return m_SizeX * m_SizeY * m_SizeZ; }
int MakeIndex(int a_RelX, int a_RelY, int a_RelZ);
protected:
// tolua_end
class cChunkReader :
public cChunkDataCallback
@ -114,7 +128,6 @@ protected:
virtual void BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) override;
} ;
// tolua_begin
int m_OriginX;
int m_OriginY;
@ -130,8 +143,6 @@ protected:
bool SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes);
int MakeIndex(int a_RelX, int a_RelY, int a_RelZ);
// Basic Setters:
void SetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array);
void SetNibble (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array);
@ -139,6 +150,8 @@ protected:
// Basic Getters:
NIBBLETYPE GetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE * a_Array);
NIBBLETYPE GetNibble (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE * a_Array);
// tolua_begin
} ;
// tolua_end

View File

@ -317,6 +317,59 @@ void cChunk::GetBlockData(BLOCKTYPE * a_BlockData)
void cChunk::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes)
{
if ((a_DataTypes & (cBlockArea::baTypes | cBlockArea::baMetas)) != (cBlockArea::baTypes | cBlockArea::baMetas))
{
LOGWARNING("cChunk::WriteBlockArea(): unsupported datatype request, can write only types + metas (0x%x), requested 0x%x. Ignoring.",
(cBlockArea::baTypes | cBlockArea::baMetas), a_DataTypes & (cBlockArea::baTypes | cBlockArea::baMetas)
);
return;
}
// SizeX, SizeZ are the dimensions of the block data to copy to the chunk (size of the geometric union)
int BlockStartX = std::max(a_MinBlockX, m_PosX * cChunkDef::Width);
int BlockEndX = std::min(a_MinBlockX + a_Area.GetSizeX(), (m_PosX + 1) * cChunkDef::Width);
int BlockStartZ = std::max(a_MinBlockZ, m_PosZ * cChunkDef::Width);
int BlockEndZ = std::min(a_MinBlockZ + a_Area.GetSizeZ(), (m_PosZ + 1) * cChunkDef::Width);
int SizeX = BlockEndX - BlockStartX;
int SizeZ = BlockEndZ - BlockStartZ;
int OffX = BlockStartX - m_PosX * cChunkDef::Width;
int OffZ = BlockStartZ - m_PosZ * cChunkDef::Width;
int BaseX = BlockStartX - a_MinBlockX;
int BaseZ = BlockStartZ - a_MinBlockZ;
int SizeY = a_Area.GetSizeY();
// TODO: Improve this by not calling FastSetBlock() and doing the processing here
// so that the heightmap is touched only once for each column.
BLOCKTYPE * AreaBlockTypes = a_Area.GetBlockTypes();
NIBBLETYPE * AreaBlockMetas = a_Area.GetBlockMetas();
for (int y = 0; y < SizeY; y++)
{
int ChunkY = a_MinBlockY + y;
int AreaY = y;
for (int z = 0; z < SizeZ; z++)
{
int ChunkZ = OffZ + z;
int AreaZ = BaseZ + z;
for (int x = 0; x < SizeX; x++)
{
int ChunkX = OffX + x;
int AreaX = BaseX + x;
int idx = a_Area.MakeIndex(AreaX, AreaY, AreaZ);
BLOCKTYPE BlockType = AreaBlockTypes[idx];
NIBBLETYPE BlockMeta = AreaBlockMetas[idx];
FastSetBlock(ChunkX, ChunkY, ChunkZ, BlockType, BlockMeta);
} // for x
} // for z
} // for y
}
/// Returns true if there is a block entity at the coords specified
bool cChunk::HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ)
{

View File

@ -43,6 +43,7 @@ class cBlockArea;
class cPawn;
class cPickup;
class cChunkDataSerializer;
class cBlockArea;
typedef std::list<cClientHandle *> cClientHandleList;
typedef cItemCallback<cEntity> cEntityCallback;
@ -108,6 +109,9 @@ public:
/// Copies entire block data into a_BlockData, the entire 4 arrays (Type, Meta, Light, SkyLight)
void GetBlockData(BLOCKTYPE * a_BlockData);
/// Writes the specified cBlockArea at the coords specified. Note that the coords may extend beyond the chunk!
void WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes);
/// Returns true if there is a block entity at the coords specified
bool HasBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ);

View File

@ -10,6 +10,7 @@
#include "Pickup.h"
#include "Chunk.h"
#include "Generating/Trees.h" // used in cChunkMap::ReplaceTreeBlocks() for tree block discrimination
#include "BlockArea.h"
#ifndef _WIN32
#include <cstdlib> // abs
@ -1493,6 +1494,44 @@ bool cChunkMap::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinCh
bool cChunkMap::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes)
{
// Convert block coords to chunks coords:
int MinChunkX, MaxChunkX;
int MinChunkZ, MaxChunkZ;
int MinBlockX = a_MinBlockX;
int MinBlockY = a_MinBlockY;
int MinBlockZ = a_MinBlockZ;
int MaxBlockX = a_MinBlockX + a_Area.GetSizeX();
int MaxBlockY = a_MinBlockY + a_Area.GetSizeY();
int MaxBlockZ = a_MinBlockZ + a_Area.GetSizeZ();
cChunkDef::AbsoluteToRelative(MinBlockX, MinBlockY, MinBlockZ, MinChunkX, MinChunkZ);
cChunkDef::AbsoluteToRelative(MaxBlockX, MaxBlockY, MaxBlockZ, MaxChunkX, MaxChunkZ);
// Iterate over chunks, write data into each:
bool Result = true;
cCSLock Lock(m_CSLayers);
for (int z = MinChunkZ; z <= MaxChunkZ; z++)
{
for (int x = MinChunkX; x <= MaxChunkX; x++)
{
cChunkPtr Chunk = GetChunkNoLoad(x, ZERO_CHUNK_Y, z);
if ((Chunk == NULL) || (!Chunk->IsValid()))
{
// Not present / not valid
Result = false;
continue;
}
Chunk->WriteBlockArea(a_Area, a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_DataTypes);
} // for x
} // for z
return Result;
}
void cChunkMap::GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty)
{
a_NumChunksValid = 0;

View File

@ -22,6 +22,7 @@ class cFurnaceEntity;
class cPawn;
class cPickup;
class cChunkDataSerializer;
class cBlockArea;
typedef std::list<cClientHandle *> cClientHandleList;
typedef cChunk * cChunkPtr;
@ -216,6 +217,9 @@ public:
/// Calls the callback for each chunk in the coords specified (all cords are inclusive). Returns true if all chunks have been processed successfully
bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback);
/// Writes the block area into the specified coords. Returns true if all chunks have been processed. Prefer cBlockArea::Write() instead.
bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes);
/// Returns the number of valid chunks and the number of dirty chunks
void GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty);

View File

@ -70,6 +70,9 @@ typedef long long Int64;
typedef int Int32;
typedef short Int16;
typedef unsigned long long UInt64;
typedef unsigned int UInt32;
typedef unsigned short UInt16;

View File

@ -1135,6 +1135,15 @@ void cWorld::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYP
bool cWorld::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes)
{
return m_ChunkMap->WriteBlockArea(a_Area, a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_DataTypes);
}
void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed)
{
MTRand r1;

View File

@ -252,6 +252,13 @@ public:
// TODO: NIBBLETYPE GetBlockActualLight(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export
void GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); // tolua_export
/** Writes the block area into the specified coords.
Returns true if all chunks have been processed.
Prefer cBlockArea::Write() instead, this is the internal implementation; cBlockArea does error checking, too.
a_DataTypes is a bitmask of cBlockArea::baXXX constants ORed together.
*/
bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes);
/// Spawns item pickups for each item in the list. May compress pickups if too many entities:
void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed = 1.0);