diff options
-rw-r--r-- | source/Bindings.cpp | 301 | ||||
-rw-r--r-- | source/Bindings.h | 2 | ||||
-rw-r--r-- | source/BlockArea.cpp | 65 | ||||
-rw-r--r-- | source/BlockArea.h | 33 | ||||
-rw-r--r-- | source/Chunk.cpp | 53 | ||||
-rw-r--r-- | source/Chunk.h | 4 | ||||
-rw-r--r-- | source/ChunkMap.cpp | 39 | ||||
-rw-r--r-- | source/ChunkMap.h | 4 | ||||
-rw-r--r-- | source/Globals.h | 3 | ||||
-rw-r--r-- | source/World.cpp | 9 | ||||
-rw-r--r-- | source/World.h | 7 |
11 files changed, 504 insertions, 16 deletions
diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 27ed6a0a3..3c93ed6f0 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -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"); diff --git a/source/Bindings.h b/source/Bindings.h index 56b73ab50..d006609b1 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -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 */ diff --git a/source/BlockArea.cpp b/source/BlockArea.cpp index caeaf609e..8c3888782 100644 --- a/source/BlockArea.cpp +++ b/source/BlockArea.cpp @@ -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) -
diff --git a/source/BlockArea.h b/source/BlockArea.h index 5abdab3bb..8d374eaad 100644 --- a/source/BlockArea.h +++ b/source/BlockArea.h @@ -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
diff --git a/source/Chunk.cpp b/source/Chunk.cpp index 149adaa62..72b065bdd 100644 --- a/source/Chunk.cpp +++ b/source/Chunk.cpp @@ -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) { diff --git a/source/Chunk.h b/source/Chunk.h index 480dea796..0a51e99d2 100644 --- a/source/Chunk.h +++ b/source/Chunk.h @@ -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); diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp index af8f09820..671eac708 100644 --- a/source/ChunkMap.cpp +++ b/source/ChunkMap.cpp @@ -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; diff --git a/source/ChunkMap.h b/source/ChunkMap.h index 165e41f10..bfdbc889b 100644 --- a/source/ChunkMap.h +++ b/source/ChunkMap.h @@ -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); diff --git a/source/Globals.h b/source/Globals.h index b9892c933..01b118cf8 100644 --- a/source/Globals.h +++ b/source/Globals.h @@ -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; diff --git a/source/World.cpp b/source/World.cpp index 7acbf8a39..961d99d7c 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -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; diff --git a/source/World.h b/source/World.h index 16c80bd82..0fb2bac7c 100644 --- a/source/World.h +++ b/source/World.h @@ -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); |