summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source/BlockID.cpp1
-rw-r--r--source/Chunk.cpp84
-rw-r--r--source/Chunk.h5
-rw-r--r--source/World.cpp1
-rw-r--r--source/World.h2
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