From d95756c5ccedb9371685356ec0af1ff955b425c7 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Fri, 21 Jun 2013 20:47:58 +0000 Subject: [PATCH] Simulators are woken up after an explosion. Fixes FS #391 git-svn-id: http://mc-server.googlecode.com/svn/trunk@1615 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Bindings.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++++- source/Bindings.h | 2 +- source/ChunkMap.cpp | 66 +++++++++++++++++++++++++++++++++-- source/ChunkMap.h | 3 ++ source/World.cpp | 10 ++++++ source/World.h | 10 ++++-- 6 files changed, 167 insertions(+), 8 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index f8c2f6c66..15e31fbff 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 06/20/13 13:33:05. +** Generated automatically by tolua++-1.0.92 on 06/21/13 22:48:20. */ #ifndef __cplusplus @@ -11822,6 +11822,86 @@ static int tolua_AllToLua_cWorld_GetSpawnZ00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: WakeUpSimulators of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_WakeUpSimulators00 +static int tolua_AllToLua_cWorld_WakeUpSimulators00(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_isnoobj(tolua_S,5,&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)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'WakeUpSimulators'", NULL); +#endif + { + self->WakeUpSimulators(a_BlockX,a_BlockY,a_BlockZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'WakeUpSimulators'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: WakeUpSimulatorsInArea of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_WakeUpSimulatorsInArea00 +static int tolua_AllToLua_cWorld_WakeUpSimulatorsInArea00(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_MinBlockX = ((int) tolua_tonumber(tolua_S,2,0)); + int a_MaxBlockX = ((int) tolua_tonumber(tolua_S,3,0)); + int a_MinBlockY = ((int) tolua_tonumber(tolua_S,4,0)); + int a_MaxBlockY = ((int) tolua_tonumber(tolua_S,5,0)); + int a_MinBlockZ = ((int) tolua_tonumber(tolua_S,6,0)); + int a_MaxBlockZ = ((int) tolua_tonumber(tolua_S,7,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'WakeUpSimulatorsInArea'", NULL); +#endif + { + self->WakeUpSimulatorsInArea(a_MinBlockX,a_MaxBlockX,a_MinBlockY,a_MaxBlockY,a_MinBlockZ,a_MaxBlockZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'WakeUpSimulatorsInArea'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: GetSignLines of class cWorld */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetSignLines00 static int tolua_AllToLua_cWorld_GetSignLines00(lua_State* tolua_S) @@ -28105,6 +28185,8 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetSpawnX",tolua_AllToLua_cWorld_GetSpawnX00); tolua_function(tolua_S,"GetSpawnY",tolua_AllToLua_cWorld_GetSpawnY00); tolua_function(tolua_S,"GetSpawnZ",tolua_AllToLua_cWorld_GetSpawnZ00); + tolua_function(tolua_S,"WakeUpSimulators",tolua_AllToLua_cWorld_WakeUpSimulators00); + tolua_function(tolua_S,"WakeUpSimulatorsInArea",tolua_AllToLua_cWorld_WakeUpSimulatorsInArea00); tolua_function(tolua_S,"GetSignLines",tolua_AllToLua_cWorld_GetSignLines00); tolua_function(tolua_S,"GrowTree",tolua_AllToLua_cWorld_GrowTree00); tolua_function(tolua_S,"GrowTreeFromSapling",tolua_AllToLua_cWorld_GrowTreeFromSapling00); diff --git a/source/Bindings.h b/source/Bindings.h index f7331b277..2de7b3542 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 06/20/13 13:33:06. +** Generated automatically by tolua++-1.0.92 on 06/21/13 22:48:20. */ /* Exported function */ diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp index ca38c8df1..30e8ac06f 100644 --- a/source/ChunkMap.cpp +++ b/source/ChunkMap.cpp @@ -737,6 +737,44 @@ void cChunkMap::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) +/// Wakes up the simulators for the specified area of blocks +void cChunkMap::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ) +{ + cSimulatorManager * SimMgr = m_World->GetSimulatorManager(); + int MinChunkX, MinChunkZ, MaxChunkX, MaxChunkZ; + cChunkDef::BlockToChunk(a_MinBlockX, ZERO_CHUNK_Y, a_MinBlockZ, MinChunkX, MinChunkZ); + cChunkDef::BlockToChunk(a_MaxBlockX, ZERO_CHUNK_Y, a_MaxBlockZ, MaxChunkX, MaxChunkZ); + for (int z = MinChunkZ; z <= MaxChunkZ; z++) + { + int MinZ = std::max(a_MinBlockZ, z * cChunkDef::Width); + int MaxZ = std::min(a_MaxBlockZ, z * cChunkDef::Width + cChunkDef::Width - 1); + for (int x = MinChunkX; x <= MaxChunkX; x++) + { + cChunkPtr Chunk = GetChunkNoGen(x, 0, z); + if ((Chunk == NULL) || !Chunk->IsValid()) + { + continue; + } + int MinX = std::max(a_MinBlockX, x * cChunkDef::Width); + int MaxX = std::min(a_MaxBlockX, x * cChunkDef::Width + cChunkDef::Width - 1); + for (int BlockY = a_MinBlockY; BlockY <= a_MaxBlockY; BlockY++) + { + for (int BlockZ = MinZ; BlockZ <= MaxZ; BlockZ++) + { + for (int BlockX = MinX; BlockX <= MaxX; BlockX++) + { + SimMgr->WakeUp(BlockX, BlockY, BlockZ, Chunk); + } // for BlockX + } // for BlockZ + } // for BlockY + } // for x - chunks + } // for z = chunks +} + + + + + void cChunkMap::MarkChunkDirty (int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); @@ -1515,7 +1553,9 @@ void cChunkMap::DoExplosiontAt(float a_ExplosionSize, int a_BlockX, int a_BlockY int ExplosionSizeInt = (int) ceil(a_ExplosionSize); int ExplosionSizeSq = ExplosionSizeInt * ExplosionSizeInt; a_BlocksAffected.reserve(8 * ExplosionSizeInt * ExplosionSizeInt * ExplosionSizeInt); - area.Read(m_World, a_BlockX - ExplosionSizeInt, a_BlockX + ExplosionSizeInt, a_BlockY - ExplosionSizeInt, a_BlockY + ExplosionSizeInt, a_BlockZ - ExplosionSizeInt,a_BlockZ + ExplosionSizeInt); + int MinY = std::max(a_BlockY - ExplosionSizeInt, 0); + int MaxY = std::min(a_BlockY + ExplosionSizeInt, cChunkDef::Height - 1); + area.Read(m_World, a_BlockX - ExplosionSizeInt, a_BlockX + ExplosionSizeInt, MinY, MaxY, a_BlockZ - ExplosionSizeInt,a_BlockZ + ExplosionSizeInt); for (int x = -ExplosionSizeInt; x < ExplosionSizeInt; x++) { for (int y = -ExplosionSizeInt; y < ExplosionSizeInt; y++) @@ -1546,13 +1586,26 @@ void cChunkMap::DoExplosiontAt(float a_ExplosionSize, int a_BlockX, int a_BlockY case E_BLOCK_OBSIDIAN: case E_BLOCK_BEDROCK: case E_BLOCK_WATER: - case E_BLOCK_STATIONARY_WATER: - case E_BLOCK_STATIONARY_LAVA: case E_BLOCK_LAVA: { // These blocks are not affected by explosions break; } + + case E_BLOCK_STATIONARY_WATER: + { + // Turn into simulated water: + area.SetBlockType(a_BlockX + x, a_BlockY + y, a_BlockZ + z, E_BLOCK_WATER); + break; + } + + case E_BLOCK_STATIONARY_LAVA: + { + // Turn into simulated lava: + area.SetBlockType(a_BlockX + x, a_BlockY + y, a_BlockZ + z, E_BLOCK_LAVA); + break; + } + default: { area.SetBlockType(a_BlockX + x, a_BlockY + y, a_BlockZ + z, E_BLOCK_AIR); @@ -1563,6 +1616,13 @@ void cChunkMap::DoExplosiontAt(float a_ExplosionSize, int a_BlockX, int a_BlockY } // for y } // for x area.Write(m_World, a_BlockX - ExplosionSizeInt, a_BlockY - ExplosionSizeInt, a_BlockZ - ExplosionSizeInt); + + // Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391): + WakeUpSimulatorsInArea( + a_BlockX - ExplosionSizeInt, a_BlockX + ExplosionSizeInt, + MinY, MaxY, + a_BlockZ - ExplosionSizeInt, a_BlockZ + ExplosionSizeInt + ); } diff --git a/source/ChunkMap.h b/source/ChunkMap.h index 4139b0761..1e232deb0 100644 --- a/source/ChunkMap.h +++ b/source/ChunkMap.h @@ -109,6 +109,9 @@ public: /// Wakes up simulators for the specified block void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ); + /// Wakes up the simulators for the specified area of blocks + void WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ); + void MarkChunkDirty (int a_ChunkX, int a_ChunkZ); void MarkChunkSaving (int a_ChunkX, int a_ChunkZ); void MarkChunkSaved (int a_ChunkX, int a_ChunkZ); diff --git a/source/World.cpp b/source/World.cpp index 398077c61..97b5a2b0e 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -689,6 +689,16 @@ void cWorld::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) +/// Wakes up the simulators for the specified area of blocks +void cWorld::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ) +{ + return m_ChunkMap->WakeUpSimulatorsInArea(a_MinBlockX, a_MaxBlockX, a_MinBlockY, a_MaxBlockY, a_MinBlockZ, a_MaxBlockZ); +} + + + + + bool cWorld::ForEachChestInChunk(int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback) { return m_ChunkMap->ForEachChestInChunk(a_ChunkX, a_ChunkZ, a_Callback); diff --git a/source/World.h b/source/World.h index 6bc6cb4c7..46894bbbf 100644 --- a/source/World.h +++ b/source/World.h @@ -348,6 +348,13 @@ public: double GetSpawnX(void) const { return m_SpawnX; } double GetSpawnY(void) const { return m_SpawnY; } double GetSpawnZ(void) const { return m_SpawnZ; } + + /// Wakes up the simulators for the specified block + void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ); + + /// Wakes up the simulators for the specified area of blocks + void WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ); + // tolua_end inline cSimulatorManager * GetSimulatorManager(void) { return m_SimulatorManager; } @@ -355,9 +362,6 @@ public: inline cFluidSimulator * GetWaterSimulator(void) { return m_WaterSimulator; } inline cFluidSimulator * GetLavaSimulator (void) { return m_LavaSimulator; } - /// Wakes up the simulators for the specified block - void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ); - /// Calls the callback for each chest in the specified chunk; returns true if all chests processed, false if the callback aborted by returning true bool ForEachChestInChunk (int a_ChunkX, int a_ChunkZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp