From d06930de7592e731493cbe5f3004ee3d1457a38f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 10 Apr 2021 20:01:01 +0100 Subject: Implement random ticks more faithfully + Make it pick 3 blocks per section, instead of 50 randomly throughout the chunk --- src/Chunk.cpp | 34 +++++++++++++++++++++------------- src/Chunk.h | 2 +- 2 files changed, 22 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/Chunk.cpp b/src/Chunk.cpp index aa2a2887c..aa1544c7d 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -849,27 +849,35 @@ void cChunk::CheckBlocks() void cChunk::TickBlocks(void) { - cChunkInterface ChunkInterface(this->GetWorld()->GetChunkMap()); - cBlockInServerPluginInterface PluginInterface(*this->GetWorld()); + cChunkInterface ChunkInterface(m_World->GetChunkMap()); + cBlockInServerPluginInterface PluginInterface(*m_World); + + // Tick random blocks, but the first one should be m_BlockToTick (so that SetNextBlockToTick() works): + cBlockHandler::For(GetBlock(m_BlockToTick)).OnUpdate(ChunkInterface, *m_World, PluginInterface, *this, m_BlockToTick); - // Tick random blocks, but the first one should be m_BlockToTick (so that SetNextBlockToTick() works) - auto Idx = cChunkDef::MakeIndexNoCheck(m_BlockToTick); auto & Random = GetRandomProvider(); - for (int i = 0; i < 50; ++i) + // Set a new random coord for the next tick: + m_BlockToTick = cChunkDef::IndexToCoordinate(Random.RandInt(cChunkDef::NumBlocks - 1)); + + // Choose a number of blocks for each section to randomly tick. + // http://minecraft.fandom.com/wiki/Tick#Random_tick + for (size_t Y = 0; Y < cChunkDef::NumSections; ++Y) { - auto Pos = cChunkDef::IndexToCoordinate(static_cast(Idx)); - Idx = Random.RandInt(cChunkDef::NumBlocks - 1); - if (Pos.y > cChunkDef::GetHeight(m_HeightMap, Pos.x, Pos.z)) + const auto Section = m_BlockData.GetSection(Y); + if (Section == nullptr) { - continue; // It's all air up here + continue; } - cBlockHandler::For(GetBlock(Pos)).OnUpdate(ChunkInterface, *this->GetWorld(), PluginInterface, *this, Pos); - } // for i + for (int Tick = 0; Tick != 3; Tick++) // TODO: configurability via gamerule randomTickSpeed + { + const auto Index = Random.RandInt(ChunkBlockData::SectionBlockCount - 1); + const auto Position = cChunkDef::IndexToCoordinate(Y * ChunkBlockData::SectionBlockCount + Index); - // Set a new random coord for the next tick: - m_BlockToTick = cChunkDef::IndexToCoordinate(static_cast(Idx)); + cBlockHandler::For((*Section)[Index]).OnUpdate(ChunkInterface, *m_World, PluginInterface, *this, Position); + } + } } diff --git a/src/Chunk.h b/src/Chunk.h index b8c9b75ae..9178c6f1b 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -552,7 +552,7 @@ private: /** Checks the block scheduled for checking in m_ToTickBlocks[] */ void CheckBlocks(); - /** Ticks several random blocks in the chunk */ + /** Ticks several random blocks in the chunk. */ void TickBlocks(void); /** Adds snow to the top of snowy biomes and hydrates farmland / fills cauldrons in rainy biomes */ -- cgit v1.2.3