From ba8a5184c8a9b7acfb145fe657ebe18541197a00 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sun, 21 Oct 2012 21:15:57 +0000 Subject: Top blocks are now snowed over, either normally, or in deep snow (patch contributed by funmaker, Luksor and Sebi) git-svn-id: http://mc-server.googlecode.com/svn/trunk@1000 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/BlockID.cpp | 1 + source/Chunk.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ source/Chunk.h | 5 ++-- source/World.cpp | 1 + source/World.h | 2 ++ 5 files changed, 91 insertions(+), 2 deletions(-) diff --git a/source/BlockID.cpp b/source/BlockID.cpp index 6553b612e..cb2d16efa 100644 --- a/source/BlockID.cpp +++ b/source/BlockID.cpp @@ -455,6 +455,7 @@ public: g_BlockPistonBreakable[E_BLOCK_YELLOW_FLOWER] = true; // Blocks that can be snowed over: + g_BlockIsSnowable[E_BLOCK_AIR] = false; g_BlockIsSnowable[E_BLOCK_BROWN_MUSHROOM] = false; g_BlockIsSnowable[E_BLOCK_CACTUS] = false; g_BlockIsSnowable[E_BLOCK_CHEST] = false; diff --git a/source/Chunk.cpp b/source/Chunk.cpp index d10aa6dac..e6c2e527a 100644 --- a/source/Chunk.cpp +++ b/source/Chunk.cpp @@ -413,6 +413,8 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom) m_IsDirty = ((cFurnaceEntity *)(*itr))->Tick( a_Dt ) | m_IsDirty; } } + + ApplyWeatherToTop(a_TickRandom); } @@ -522,6 +524,88 @@ void cChunk::TickBlocks(MTRand & a_TickRandom) +void cChunk::ApplyWeatherToTop(MTRand & a_TickRandom) +{ + if ( + (a_TickRandom.randInt(100) != 0) || + ( + (m_World->GetWeather() != eWeather_Rain) && + (m_World->GetWeather() != eWeather_ThunderStorm) + ) + ) + { + // Not the right weather, or not at this tick; bail out + return; + } + + int X = a_TickRandom.randInt(15); + int Z = a_TickRandom.randInt(15); + switch (GetBiomeAt(X, Z)) + { + case biTaiga: + case biFrozenOcean: + case biFrozenRiver: + case biIcePlains: + case biIceMountains: + case biTaigaHills: + { + // TODO: Check light levels, don't snow over when the BlockLight is higher than (7?) + int Height = GetHeight(X, Z); + BLOCKTYPE TopBlock = GetBlock(X, Height, Z); + NIBBLETYPE TopMeta = GetMeta (X, Height, Z); + if (m_World->IsDeepSnowEnabled() && (TopBlock == E_BLOCK_SNOW)) + { + int MaxSize = 7; + BLOCKTYPE BlockType[4]; + NIBBLETYPE BlockMeta[4]; + UnboundedRelGetBlock(X - 1, Height, Z, BlockType[0], BlockMeta[0]); + UnboundedRelGetBlock(X + 1, Height, Z, BlockType[1], BlockMeta[1]); + UnboundedRelGetBlock(X, Height, Z - 1, BlockType[2], BlockMeta[2]); + UnboundedRelGetBlock(X, Height, Z + 1, BlockType[3], BlockMeta[3]); + for (int i = 0; i < 4; i++) + { + switch (BlockType[i]) + { + case E_BLOCK_AIR: + { + MaxSize = 0; + break; + } + case E_BLOCK_SNOW: + { + MaxSize = std::min(BlockMeta[i] + 1, MaxSize); + break; + } + } + } + if (TopMeta < MaxSize) + { + FastSetBlock(X, Height, Z, E_BLOCK_SNOW, TopMeta + 1); + } + else if (TopMeta > MaxSize) + { + FastSetBlock(X, Height, Z, E_BLOCK_SNOW, TopMeta - 1); + } + } + else if (g_BlockIsSnowable[TopBlock]) + { + SetBlock(X, Height + 1, Z, E_BLOCK_SNOW, 0); + } + else if ((TopBlock == E_BLOCK_WATER) || (TopBlock == E_BLOCK_STATIONARY_WATER)) + { + SetBlock(X, Height, Z, E_BLOCK_ICE, 0); + } + break; + } // case (snowy biomes) + + // TODO: Rainy biomes should check for farmland and cauldrons + } // switch (biome) +} + + + + + void cChunk::GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_TickRandom) { // Convert the stem BlockType into produce BlockType diff --git a/source/Chunk.h b/source/Chunk.h index 4bc99b8d2..e21868123 100644 --- a/source/Chunk.h +++ b/source/Chunk.h @@ -290,8 +290,9 @@ private: void CheckBlocks(void); void TickBlocks (MTRand & a_TickRandom); - void TickGrass (int a_RelX, int a_RelY, int a_RelZ, MTRand & a_TickRandom); - void TickFarmland(int a_RelX, int a_RelY, int a_RelZ); + + /// Adds snow to the top of snowy biomes and hydrates farmland / fills cauldrons in rainy biomes + void ApplyWeatherToTop(MTRand & a_TickRandom); /// Grows sugarcane by the specified number of blocks, but no more than 3 blocks high (used by both bonemeal and ticking) void GrowSugarcane (int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks); diff --git a/source/World.cpp b/source/World.cpp index 9ca84156b..1834a49da 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -254,6 +254,7 @@ cWorld::cWorld( const AString & a_WorldName ) m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false); m_IsCactusBonemealable = IniFile.GetValueSetB("Plants", "IsCactusBonemealable", false); m_bEnabledPVP = IniFile.GetValueSetB("PVP", "Enabled", true); + m_IsDeepSnowEnabled = IniFile.GetValueSetB("Physics", "DeepSnow", false); m_GameMode = (eGameMode)IniFile.GetValueSetI("GameMode", "GameMode", m_GameMode ); diff --git a/source/World.h b/source/World.h index f9cc83f31..b54e82662 100644 --- a/source/World.h +++ b/source/World.h @@ -68,6 +68,7 @@ public: eGameMode GetGameMode(void) const { return m_GameMode; } //tolua_export bool IsPVPEnabled(void) const { return m_bEnabledPVP; } //tolua_export + bool IsDeepSnowEnabled(void) const { return m_IsDeepSnowEnabled; } void SetWorldTime(long long a_WorldTime) { m_WorldTime = a_WorldTime; } //tolua_export @@ -425,6 +426,7 @@ private: unsigned long long CurrentTick; eGameMode m_GameMode; bool m_bEnabledPVP; + bool m_IsDeepSnowEnabled; float m_WorldTimeFraction; // When this > 1.f m_WorldTime is incremented by 20 // The cRedstone class simulates redstone and needs access to m_RSList -- cgit v1.2.3