summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/Bindings.cpp82
-rw-r--r--source/Bindings.h2
-rw-r--r--source/Chunk.cpp36
-rw-r--r--source/Chunk.h24
-rw-r--r--source/ChunkMap.cpp17
-rw-r--r--source/ChunkMap.h1
-rw-r--r--source/World.cpp9
-rw-r--r--source/World.h19
8 files changed, 186 insertions, 4 deletions
diff --git a/source/Bindings.cpp b/source/Bindings.cpp
index d33be08ac..fa5b8f975 100644
--- a/source/Bindings.cpp
+++ b/source/Bindings.cpp
@@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
-** Generated automatically by tolua++-1.0.92 on 08/18/13 13:15:34.
+** Generated automatically by tolua++-1.0.92 on 08/18/13 22:18:01.
*/
#ifndef __cplusplus
@@ -10726,6 +10726,49 @@ static int tolua_AllToLua_cWorld_FastSetBlock00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
+/* method: QueueSetBlock of class cWorld */
+#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_QueueSetBlock00
+static int tolua_AllToLua_cWorld_QueueSetBlock00(lua_State* tolua_S)
+{
+#ifndef TOLUA_RELEASE
+ tolua_Error tolua_err;
+ if (
+ !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) ||
+ !tolua_isnumber(tolua_S,2,0,&tolua_err) ||
+ !tolua_isnumber(tolua_S,3,0,&tolua_err) ||
+ !tolua_isnumber(tolua_S,4,0,&tolua_err) ||
+ !tolua_isnumber(tolua_S,5,0,&tolua_err) ||
+ !tolua_isnumber(tolua_S,6,0,&tolua_err) ||
+ !tolua_isnumber(tolua_S,7,0,&tolua_err) ||
+ !tolua_isnoobj(tolua_S,8,&tolua_err)
+ )
+ goto tolua_lerror;
+ else
+#endif
+ {
+ cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0);
+ int a_BlockX = ((int) tolua_tonumber(tolua_S,2,0));
+ int a_BLockY = ((int) tolua_tonumber(tolua_S,3,0));
+ int a_BlockZ = ((int) tolua_tonumber(tolua_S,4,0));
+ unsigned char a_BlockType = (( unsigned char) tolua_tonumber(tolua_S,5,0));
+ unsigned char a_BlockMeta = (( unsigned char) tolua_tonumber(tolua_S,6,0));
+ int a_TickDelay = ((int) tolua_tonumber(tolua_S,7,0));
+#ifndef TOLUA_RELEASE
+ if (!self) tolua_error(tolua_S,"invalid 'self' in function 'QueueSetBlock'", NULL);
+#endif
+ {
+ self->QueueSetBlock(a_BlockX,a_BLockY,a_BlockZ,a_BlockType,a_BlockMeta,a_TickDelay);
+ }
+ }
+ return 0;
+#ifndef TOLUA_RELEASE
+ tolua_lerror:
+ tolua_error(tolua_S,"#ferror in function 'QueueSetBlock'.",&tolua_err);
+ return 0;
+#endif
+}
+#endif //#ifndef TOLUA_DISABLE
+
/* method: GetBlock of class cWorld */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetBlock00
static int tolua_AllToLua_cWorld_GetBlock00(lua_State* tolua_S)
@@ -27149,7 +27192,11 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_BLOCK_QUARTZ_STAIR",E_BLOCK_QUARTZ_STAIR);
tolua_constant(tolua_S,"E_BLOCK_ACTIVATOR_RAIL",E_BLOCK_ACTIVATOR_RAIL);
tolua_constant(tolua_S,"E_BLOCK_DROPPER",E_BLOCK_DROPPER);
+ tolua_constant(tolua_S,"E_BLOCK_STAINED_CLAY",E_BLOCK_STAINED_CLAY);
+ tolua_constant(tolua_S,"E_BLOCK_HAY_BALE",E_BLOCK_HAY_BALE);
tolua_constant(tolua_S,"E_BLOCK_CARPET",E_BLOCK_CARPET);
+ tolua_constant(tolua_S,"E_BLOCK_HARDENED_CLAY",E_BLOCK_HARDENED_CLAY);
+ tolua_constant(tolua_S,"E_BLOCK_BLOCK_OF_COAL",E_BLOCK_BLOCK_OF_COAL);
tolua_constant(tolua_S,"E_BLOCK_NUMBER_OF_TYPES",E_BLOCK_NUMBER_OF_TYPES);
tolua_constant(tolua_S,"E_BLOCK_MAX_TYPE_ID",E_BLOCK_MAX_TYPE_ID);
tolua_constant(tolua_S,"E_ITEM_EMPTY",E_ITEM_EMPTY);
@@ -27416,6 +27463,38 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_META_WOOL_GREEN",E_META_WOOL_GREEN);
tolua_constant(tolua_S,"E_META_WOOL_RED",E_META_WOOL_RED);
tolua_constant(tolua_S,"E_META_WOOL_BLACK",E_META_WOOL_BLACK);
+ tolua_constant(tolua_S,"E_META_CARPET_WHITE",E_META_CARPET_WHITE);
+ tolua_constant(tolua_S,"E_META_CARPET_ORANGE",E_META_CARPET_ORANGE);
+ tolua_constant(tolua_S,"E_META_CARPET_MAGENTA",E_META_CARPET_MAGENTA);
+ tolua_constant(tolua_S,"E_META_CARPET_LIGHTBLUE",E_META_CARPET_LIGHTBLUE);
+ tolua_constant(tolua_S,"E_META_CARPET_YELLOW",E_META_CARPET_YELLOW);
+ tolua_constant(tolua_S,"E_META_CARPET_LIGHTGREEN",E_META_CARPET_LIGHTGREEN);
+ tolua_constant(tolua_S,"E_META_CARPET_PINK",E_META_CARPET_PINK);
+ tolua_constant(tolua_S,"E_META_CARPET_GRAY",E_META_CARPET_GRAY);
+ tolua_constant(tolua_S,"E_META_CARPET_LIGHTGRAY",E_META_CARPET_LIGHTGRAY);
+ tolua_constant(tolua_S,"E_META_CARPET_CYAN",E_META_CARPET_CYAN);
+ tolua_constant(tolua_S,"E_META_CARPET_PURPLE",E_META_CARPET_PURPLE);
+ tolua_constant(tolua_S,"E_META_CARPET_BLUE",E_META_CARPET_BLUE);
+ tolua_constant(tolua_S,"E_META_CARPET_BROWN",E_META_CARPET_BROWN);
+ tolua_constant(tolua_S,"E_META_CARPET_GREEN",E_META_CARPET_GREEN);
+ tolua_constant(tolua_S,"E_META_CARPET_RED",E_META_CARPET_RED);
+ tolua_constant(tolua_S,"E_META_CARPET_BLACK",E_META_CARPET_BLACK);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_WHITE",E_META_STAINED_CLAY_WHITE);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_ORANGE",E_META_STAINED_CLAY_ORANGE);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_MAGENTA",E_META_STAINED_CLAY_MAGENTA);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_LIGHTBLUE",E_META_STAINED_CLAY_LIGHTBLUE);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_YELLOW",E_META_STAINED_CLAY_YELLOW);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_LIGHTGREEN",E_META_STAINED_CLAY_LIGHTGREEN);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_PINK",E_META_STAINED_CLAY_PINK);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_GRAY",E_META_STAINED_CLAY_GRAY);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_LIGHTGRAY",E_META_STAINED_CLAY_LIGHTGRAY);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_CYAN",E_META_STAINED_CLAY_CYAN);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_PURPLE",E_META_STAINED_CLAY_PURPLE);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_BLUE",E_META_STAINED_CLAY_BLUE);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_BROWN",E_META_STAINED_CLAY_BROWN);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_GREEN",E_META_STAINED_CLAY_GREEN);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_RED",E_META_STAINED_CLAY_RED);
+ tolua_constant(tolua_S,"E_META_STAINED_CLAY_BLACK",E_META_STAINED_CLAY_BLACK);
tolua_constant(tolua_S,"E_META_COAL_NORMAL",E_META_COAL_NORMAL);
tolua_constant(tolua_S,"E_META_COAL_CHARCOAL",E_META_COAL_CHARCOAL);
tolua_constant(tolua_S,"E_META_DYE_BLACK",E_META_DYE_BLACK);
@@ -27955,6 +28034,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"GenerateChunk",tolua_AllToLua_cWorld_GenerateChunk00);
tolua_function(tolua_S,"SetBlock",tolua_AllToLua_cWorld_SetBlock00);
tolua_function(tolua_S,"FastSetBlock",tolua_AllToLua_cWorld_FastSetBlock00);
+ tolua_function(tolua_S,"QueueSetBlock",tolua_AllToLua_cWorld_QueueSetBlock00);
tolua_function(tolua_S,"GetBlock",tolua_AllToLua_cWorld_GetBlock00);
tolua_function(tolua_S,"GetBlockMeta",tolua_AllToLua_cWorld_GetBlockMeta00);
tolua_function(tolua_S,"SetBlockMeta",tolua_AllToLua_cWorld_SetBlockMeta00);
diff --git a/source/Bindings.h b/source/Bindings.h
index a403294a9..5fcd02faa 100644
--- a/source/Bindings.h
+++ b/source/Bindings.h
@@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
-** Generated automatically by tolua++-1.0.92 on 08/18/13 13:15:34.
+** Generated automatically by tolua++-1.0.92 on 08/18/13 22:18:02.
*/
/* Exported function */
diff --git a/source/Chunk.cpp b/source/Chunk.cpp
index 62d411b0c..a2cfb7ead 100644
--- a/source/Chunk.cpp
+++ b/source/Chunk.cpp
@@ -440,6 +440,9 @@ void cChunk::Tick(float a_Dt)
(*itr)->SendUnloadChunk(m_PosX, m_PosZ);
}
m_UnloadQuery.clear();
+
+ // Set all blocks that have been queued for setting later:
+ ProcessQueuedSetBlocks();
CheckBlocks();
@@ -544,6 +547,30 @@ void cChunk::MoveEntityToNewChunk(cEntity * a_Entity)
+void cChunk::ProcessQueuedSetBlocks(void)
+{
+ Int64 CurrTick = m_World->GetWorldAge();
+ for (sSetBlockQueueVector::iterator itr = m_SetBlockQueue.begin(); itr != m_SetBlockQueue.end();)
+ {
+ if (itr->m_Tick < CurrTick)
+ {
+ // Not yet
+ ++itr;
+ continue;
+ }
+ else
+ {
+ // Now is the time to set the block
+ SetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta);
+ itr = m_SetBlockQueue.erase(itr);
+ }
+ } // for itr - m_SetBlockQueue[]
+}
+
+
+
+
+
void cChunk::BroadcastPendingBlockChanges(void)
{
sSetBlockVector Changes;
@@ -1492,6 +1519,15 @@ void cChunk::SetBlock( int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType
+void cChunk::QueueSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Int64 a_Tick)
+{
+ m_SetBlockQueue.push_back(sSetBlockQueueItem(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta, a_Tick));
+}
+
+
+
+
+
void cChunk::QueueTickBlock(int a_RelX, int a_RelY, int a_RelZ)
{
ASSERT (
diff --git a/source/Chunk.h b/source/Chunk.h
index c4eeab6ae..cba39f7ee 100644
--- a/source/Chunk.h
+++ b/source/Chunk.h
@@ -136,6 +136,9 @@ public:
// SetBlock() does a lot of work (heightmap, tickblocks, blockentities) so a BlockIdx version doesn't make sense
void SetBlock( const Vector3i & a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) { SetBlock( a_RelBlockPos.x, a_RelBlockPos.y, a_RelBlockPos.z, a_BlockType, a_BlockMeta ); }
+ /// Queues a block change till the specified world tick
+ void QueueSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Int64 a_Tick);
+
/// Queues block for ticking (m_ToTickQueue)
void QueueTickBlock(int a_RelX, int a_RelY, int a_RelZ);
@@ -319,6 +322,22 @@ private:
friend class cChunkMap;
+ struct sSetBlockQueueItem
+ {
+ int m_RelX, m_RelY, m_RelZ;
+ BLOCKTYPE m_BlockType;
+ NIBBLETYPE m_BlockMeta;
+ Int64 m_Tick;
+
+ sSetBlockQueueItem(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Int64 a_Tick) :
+ m_RelX(a_RelX), m_RelY(a_RelY), m_RelZ(a_RelZ)
+ {
+ }
+ } ;
+
+ typedef std::vector<sSetBlockQueueItem> sSetBlockQueueVector;
+
+
bool m_IsValid; // True if the chunk is loaded / generated
bool m_IsLightValid; // True if the blocklight and skylight are calculated
bool m_IsDirty; // True if the chunk has changed since it was last saved
@@ -329,6 +348,8 @@ private:
std::vector<unsigned int> m_ToTickBlocks;
sSetBlockVector m_PendingSendBlocks; ///< Blocks that have changed and need to be sent to all clients
+ sSetBlockQueueVector m_SetBlockQueue; ///< Block changes that are queued to a specific tick
+
// A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers
cClientHandleList m_LoadedByClient;
cClientHandleList m_UnloadQuery;
@@ -405,6 +426,9 @@ private:
/// Called by Tick() when an entity moves out of this chunk into a neighbor; moves the entity and sends spawn / despawn packet to clients
void MoveEntityToNewChunk(cEntity * a_Entity);
+
+ /// Processes all blocks that have been scheduled for replacement by the QueueSetBlock() function
+ void ProcessQueuedSetBlocks(void);
};
typedef cChunk * cChunkPtr;
diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp
index 5a16495e6..cd4955077 100644
--- a/source/ChunkMap.cpp
+++ b/source/ChunkMap.cpp
@@ -1171,6 +1171,23 @@ void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_B
+void cChunkMap::QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, Int64 a_Tick)
+{
+ int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ;
+ cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ);
+
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ);
+ if ((Chunk != NULL) && Chunk->IsValid())
+ {
+ Chunk->QueueSetBlock(X, Y, Z, a_BlockType, a_BlockMeta, a_Tick);
+ }
+}
+
+
+
+
+
bool cChunkMap::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta)
{
int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ;
diff --git a/source/ChunkMap.h b/source/ChunkMap.h
index 208d2824e..b0af0d779 100644
--- a/source/ChunkMap.h
+++ b/source/ChunkMap.h
@@ -135,6 +135,7 @@ public:
NIBBLETYPE GetBlockBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ);
void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockMeta);
void SetBlock (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta);
+ void QueueSetBlock (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, Int64 a_Tick);
bool GetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta);
bool GetBlockInfo (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight);
diff --git a/source/World.cpp b/source/World.cpp
index e63e45498..70dbb5284 100644
--- a/source/World.cpp
+++ b/source/World.cpp
@@ -1385,6 +1385,15 @@ void cWorld::FastSetBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, NIBB
+void cWorld::QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_TickDelay)
+{
+ m_ChunkMap->QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, GetWorldAge() + a_TickDelay);
+}
+
+
+
+
+
BLOCKTYPE cWorld::GetBlock(int a_X, int a_Y, int a_Z)
{
// First check if it isn't queued in the m_FastSetBlockQueue:
diff --git a/source/World.h b/source/World.h
index 5d3de06d0..8c90b08c4 100644
--- a/source/World.h
+++ b/source/World.h
@@ -311,8 +311,23 @@ public:
bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback);
// tolua_begin
- void SetBlock (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
- void FastSetBlock (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
+
+ /** Sets the block at the specified coords to the specified value.
+ Full processing, incl. updating neighbors, is performed.
+ */
+ void SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
+
+ /** Sets the block at the specified coords to the specified value.
+ The replacement doesn't trigger block updates.
+ The replaced blocks aren't checked for block entities (block entity is leaked if it exists at this block)
+ */
+ void FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
+
+ /** Queues a SetBlock() with the specified parameters after the specified number of ticks.
+ Calls SetBlock(), so performs full processing of the replaced block.
+ */
+ void QueueSetBlock(int a_BlockX, int a_BLockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_TickDelay);
+
BLOCKTYPE GetBlock (int a_BlockX, int a_BlockY, int a_BlockZ);
NIBBLETYPE GetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ);
void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData);