summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MCServer/Plugins/APIDump/APIDump.deproj155
-rw-r--r--Tools/BiomeVisualiser/BiomeCache.cpp5
-rw-r--r--Tools/BiomeVisualiser/BiomeViewWnd.cpp21
-rw-r--r--Tools/BiomeVisualiser/BiomeViewWnd.h19
-rw-r--r--src/Bindings.cpp239
-rw-r--r--src/Bindings.h2
-rw-r--r--src/BlockEntities/DropSpenserEntity.cpp1
-rw-r--r--src/BlockID.h251
-rw-r--r--src/Blocks/BlockCactus.h4
-rw-r--r--src/Blocks/BlockCrops.h12
-rw-r--r--src/Blocks/BlockDirt.h33
-rw-r--r--src/Blocks/BlockFarmland.h23
-rw-r--r--src/Blocks/BlockHandler.cpp2
-rw-r--r--src/Blocks/BlockHandler.h7
-rw-r--r--src/Blocks/BlockLeaves.h25
-rw-r--r--src/Blocks/BlockSapling.h10
-rw-r--r--src/Blocks/BlockStems.h10
-rw-r--r--src/Blocks/BlockSugarcane.h4
-rw-r--r--src/ByteBuffer.cpp2
-rw-r--r--src/Chunk.cpp19
-rw-r--r--src/Chunk.h6
-rw-r--r--src/ChunkMap.cpp19
-rw-r--r--src/ChunkMap.h3
-rw-r--r--src/Defines.h26
-rw-r--r--src/Generating/BioGen.cpp262
-rw-r--r--src/Generating/BioGen.h38
-rw-r--r--src/Generating/CompoGen.cpp90
-rw-r--r--src/Generating/CompoGen.h2
-rw-r--r--src/Generating/ComposableGenerator.cpp49
-rw-r--r--src/Generating/ComposableGenerator.h7
-rw-r--r--src/Generating/DistortedHeightmap.cpp686
-rw-r--r--src/Generating/DistortedHeightmap.h30
-rw-r--r--src/Generating/HeiGen.cpp126
-rw-r--r--src/Generating/HeiGen.h2
-rw-r--r--src/Generating/StructGen.cpp65
-rw-r--r--src/Generating/Trees.cpp50
-rw-r--r--src/LuaState.h16
-rw-r--r--src/Plugin.h2
-rw-r--r--src/PluginLua.cpp4
-rw-r--r--src/PluginLua.h2
-rw-r--r--src/PluginManager.cpp4
-rw-r--r--src/PluginManager.h2
-rw-r--r--src/World.cpp54
-rw-r--r--src/World.h2
-rw-r--r--src/WorldStorage/WSSCompact.h1
-rw-r--r--src/WorldStorage/WorldStorage.h1
46 files changed, 1849 insertions, 544 deletions
diff --git a/MCServer/Plugins/APIDump/APIDump.deproj b/MCServer/Plugins/APIDump/APIDump.deproj
index 9ee9170f2..dffe3eaee 100644
--- a/MCServer/Plugins/APIDump/APIDump.deproj
+++ b/MCServer/Plugins/APIDump/APIDump.deproj
@@ -4,6 +4,159 @@
<filename>APIDesc.lua</filename>
</file>
<file>
- <filename>main.lua</filename>
+ <filename>Classes\BlockEntities.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnBlockToPickups.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnChat.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnChunkAvailable.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnChunkGenerated.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnChunkGenerating.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnChunkUnloaded.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnChunkUnloading.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnCollectingPickup.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnCraftingNoRecipe.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnDisconnect.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnExecuteCommand.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnExploded.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnExploding.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnHandshake.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnHopperPullingItem.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnHopperPushingItem.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnKilling.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnLogin.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerAnimation.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerBreakingBlock.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerBrokenBlock.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerEating.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerJoined.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerLeftClick.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerMoving.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerPlacedBlock.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerPlacingBlock.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerRightClick.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerRightClickingEntity.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerShooting.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerSpawned.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerTossingItem.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerUsedBlock.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerUsedItem.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerUsingBlock.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPlayerUsingItem.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPostCrafting.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnPreCrafting.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnSpawnedEntity.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnSpawnedMonster.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnSpawningEntity.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnSpawningMonster.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnTakeDamage.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnTick.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnUpdatedSign.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnUpdatingSign.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnWeatherChanged.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnWeatherChanging.lua</filename>
+ </file>
+ <file>
+ <filename>Hooks\OnWorldTick.lua</filename>
+ </file>
+ <file>
+ <filename>Classes\Projectiles.lua</filename>
+ </file>
+ <file>
+ <filename>main_APIDump.lua</filename>
</file>
</project>
diff --git a/Tools/BiomeVisualiser/BiomeCache.cpp b/Tools/BiomeVisualiser/BiomeCache.cpp
index b3c308422..7d9301d8f 100644
--- a/Tools/BiomeVisualiser/BiomeCache.cpp
+++ b/Tools/BiomeVisualiser/BiomeCache.cpp
@@ -258,6 +258,11 @@ void cBiomeCache::FilterOutItems(cItems & a_Items, int a_MinChunkX, int a_MaxChu
void cBiomeCache::thrProcessQueueItem(void)
{
+ if (m_Source == NULL)
+ {
+ return;
+ }
+
cItem * Item = NULL;
{
cCSLock Lock(m_CS);
diff --git a/Tools/BiomeVisualiser/BiomeViewWnd.cpp b/Tools/BiomeVisualiser/BiomeViewWnd.cpp
index 0658e3810..5c1240bc7 100644
--- a/Tools/BiomeVisualiser/BiomeViewWnd.cpp
+++ b/Tools/BiomeVisualiser/BiomeViewWnd.cpp
@@ -34,6 +34,8 @@ bool cBiomeViewWnd::Create(HWND a_ParentWnd, LPCTSTR a_Title)
{
ASSERT(m_Wnd == NULL);
+ InitBiomeView();
+
// Create a regular STATIC window, then override its window procedure with our own. No need for obnoxious RegisterWindowClass() stuff.
m_Wnd = CreateWindow("STATIC", a_Title, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 400, 300, a_ParentWnd, NULL, GetModuleHandle(NULL), NULL);
if (m_Wnd == NULL)
@@ -43,11 +45,6 @@ bool cBiomeViewWnd::Create(HWND a_ParentWnd, LPCTSTR a_Title)
}
SetWindowLongPtr(m_Wnd, GWLP_WNDPROC, m_Thunk);
- cIniFile IniFile;
- cBiomeGen * BioGen = new cBioGenMultiStepMap(2);
- BioGen->InitializeBiomeGen(IniFile);
- m_Renderer.SetSource(new cGeneratorBiomeSource(BioGen));
-
return true;
}
@@ -55,6 +52,20 @@ bool cBiomeViewWnd::Create(HWND a_ParentWnd, LPCTSTR a_Title)
+void cBiomeViewWnd::InitBiomeView(void)
+{
+ cIniFile IniFile;
+ IniFile.ReadFile("world.ini");
+ int Seed = IniFile.GetValueSetI("Generator", "Seed", 0);
+ bool CacheOffByDefault = false;
+ m_BiomeGen = cBiomeGen::CreateBiomeGen(IniFile, Seed, CacheOffByDefault);
+ m_Renderer.SetSource(new cGeneratorBiomeSource(m_BiomeGen));
+ IniFile.WriteFile("world.ini");
+}
+
+
+
+
LRESULT cBiomeViewWnd::WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam)
{
diff --git a/Tools/BiomeVisualiser/BiomeViewWnd.h b/Tools/BiomeVisualiser/BiomeViewWnd.h
index 88e808ab3..e3f70c7e6 100644
--- a/Tools/BiomeVisualiser/BiomeViewWnd.h
+++ b/Tools/BiomeVisualiser/BiomeViewWnd.h
@@ -3,6 +3,12 @@
// Declares the cBiomeViewWnd class representing the window that displays biomes
+
+
+
+
+#pragma once
+
#include "WndProcThunk.h"
#include "BiomeRenderer.h"
#include "BiomeCache.h"
@@ -12,6 +18,13 @@
+// fwd:
+class cBiomeGen;
+
+
+
+
+
class cBiomeViewWnd
{
public:
@@ -26,9 +39,15 @@ protected:
cBiomeRenderer m_Renderer;
cPixmap m_Pixmap;
+ /// The generator that is to be visualised
+ cBiomeGen * m_BiomeGen;
+
bool m_IsLButtonDown;
POINT m_MouseDown;
+
+ void InitBiomeView(void);
+
LRESULT WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam);
// Message handlers:
diff --git a/src/Bindings.cpp b/src/Bindings.cpp
index f06fb4c03..6bee7d71d 100644
--- a/src/Bindings.cpp
+++ b/src/Bindings.cpp
@@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
-** Generated automatically by tolua++-1.0.92 on 11/26/13 22:11:10.
+** Generated automatically by tolua++-1.0.92 on 11/30/13 15:42:56.
*/
#ifndef __cplusplus
@@ -16,7 +16,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S);
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "tolua_base.h"
#include "ChunkDef.h"
-#include "inifile/iniFile.h"
+#include "../lib/inifile/iniFile.h"
#include "OSSupport/File.h"
#include "BlockID.h"
#include "StringUtils.h"
@@ -3676,6 +3676,35 @@ static int tolua_AllToLua_ItemCategory_IsArmor00(lua_State* tolua_S)
}
#endif //#ifndef TOLUA_DISABLE
+/* function: IsBiomeNoDownfall */
+#ifndef TOLUA_DISABLE_tolua_AllToLua_IsBiomeNoDownfall00
+static int tolua_AllToLua_IsBiomeNoDownfall00(lua_State* tolua_S)
+{
+#ifndef TOLUA_RELEASE
+ tolua_Error tolua_err;
+ if (
+ !tolua_isnumber(tolua_S,1,0,&tolua_err) ||
+ !tolua_isnoobj(tolua_S,2,&tolua_err)
+ )
+ goto tolua_lerror;
+ else
+#endif
+ {
+ EMCSBiome a_Biome = ((EMCSBiome) (int) tolua_tonumber(tolua_S,1,0));
+ {
+ bool tolua_ret = (bool) IsBiomeNoDownfall(a_Biome);
+ tolua_pushboolean(tolua_S,(bool)tolua_ret);
+ }
+ }
+ return 1;
+#ifndef TOLUA_RELEASE
+ tolua_lerror:
+ tolua_error(tolua_S,"#ferror in function 'IsBiomeNoDownfall'.",&tolua_err);
+ return 0;
+#endif
+}
+#endif //#ifndef TOLUA_DISABLE
+
/* function: GetTime */
#ifndef TOLUA_DISABLE_tolua_AllToLua_GetTime00
static int tolua_AllToLua_GetTime00(lua_State* tolua_S)
@@ -29971,10 +30000,35 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_ITEM_LAST_DISC_PLUS_ONE",E_ITEM_LAST_DISC_PLUS_ONE);
tolua_constant(tolua_S,"E_ITEM_LAST_DISC",E_ITEM_LAST_DISC);
tolua_constant(tolua_S,"E_ITEM_LAST",E_ITEM_LAST);
+ tolua_constant(tolua_S,"E_META_BIG_FLOWER_SUNFLOWER",E_META_BIG_FLOWER_SUNFLOWER);
+ tolua_constant(tolua_S,"E_META_BIG_FLOWER_LILAC",E_META_BIG_FLOWER_LILAC);
+ tolua_constant(tolua_S,"E_META_BIG_FLOWER_DOUBLE_TALL_GRASS",E_META_BIG_FLOWER_DOUBLE_TALL_GRASS);
+ tolua_constant(tolua_S,"E_META_BIG_FLOWER_LARGE_FERN",E_META_BIG_FLOWER_LARGE_FERN);
+ tolua_constant(tolua_S,"E_META_BIG_FLOWER_ROSE_BUSH",E_META_BIG_FLOWER_ROSE_BUSH);
+ tolua_constant(tolua_S,"E_META_BIG_FLOWER_PEONY",E_META_BIG_FLOWER_PEONY);
+ 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_CHEST_FACING_ZM",E_META_CHEST_FACING_ZM);
tolua_constant(tolua_S,"E_META_CHEST_FACING_ZP",E_META_CHEST_FACING_ZP);
tolua_constant(tolua_S,"E_META_CHEST_FACING_XM",E_META_CHEST_FACING_XM);
tolua_constant(tolua_S,"E_META_CHEST_FACING_XP",E_META_CHEST_FACING_XP);
+ tolua_constant(tolua_S,"E_META_DIRT_NORMAL",E_META_DIRT_NORMAL);
+ tolua_constant(tolua_S,"E_META_DIRT_GRASSLESS",E_META_DIRT_GRASSLESS);
+ tolua_constant(tolua_S,"E_META_DIRT_PODZOL",E_META_DIRT_PODZOL);
tolua_constant(tolua_S,"E_META_DROPSPENSER_FACING_YM",E_META_DROPSPENSER_FACING_YM);
tolua_constant(tolua_S,"E_META_DROPSPENSER_FACING_YP",E_META_DROPSPENSER_FACING_YP);
tolua_constant(tolua_S,"E_META_DROPSPENSER_FACING_ZM",E_META_DROPSPENSER_FACING_ZM);
@@ -29989,6 +30043,14 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_META_DOUBLE_STONE_SLAB_STONE_BRICK",E_META_DOUBLE_STONE_SLAB_STONE_BRICK);
tolua_constant(tolua_S,"E_META_DOUBLE_STONE_SLAB_NETHER_BRICK",E_META_DOUBLE_STONE_SLAB_NETHER_BRICK);
tolua_constant(tolua_S,"E_META_DOUBLE_STONE_SLAB_STONE_SECRET",E_META_DOUBLE_STONE_SLAB_STONE_SECRET);
+ tolua_constant(tolua_S,"E_META_FLOWER_POPPY",E_META_FLOWER_POPPY);
+ tolua_constant(tolua_S,"E_META_FLOWER_BLUE_ORCHID",E_META_FLOWER_BLUE_ORCHID);
+ tolua_constant(tolua_S,"E_META_FLOWER_ALLIUM",E_META_FLOWER_ALLIUM);
+ tolua_constant(tolua_S,"E_META_FLOWER_RED_TULIP",E_META_FLOWER_RED_TULIP);
+ tolua_constant(tolua_S,"E_META_FLOWER_ORANGE_TULIP",E_META_FLOWER_ORANGE_TULIP);
+ tolua_constant(tolua_S,"E_META_FLOWER_WHITE_TULIP",E_META_FLOWER_WHITE_TULIP);
+ tolua_constant(tolua_S,"E_META_FLOWER_PINK_TULIP",E_META_FLOWER_PINK_TULIP);
+ tolua_constant(tolua_S,"E_META_FLOWER_OXEYE_DAISY",E_META_FLOWER_OXEYE_DAISY);
tolua_constant(tolua_S,"E_META_HOPPER_FACING_YM",E_META_HOPPER_FACING_YM);
tolua_constant(tolua_S,"E_META_HOPPER_UNATTACHED",E_META_HOPPER_UNATTACHED);
tolua_constant(tolua_S,"E_META_HOPPER_FACING_ZM",E_META_HOPPER_FACING_ZM);
@@ -30003,10 +30065,26 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_META_LOG_CONIFER",E_META_LOG_CONIFER);
tolua_constant(tolua_S,"E_META_LOG_BIRCH",E_META_LOG_BIRCH);
tolua_constant(tolua_S,"E_META_LOG_JUNGLE",E_META_LOG_JUNGLE);
+ tolua_constant(tolua_S,"E_META_NEW_LEAVES_ACACIA_WOOD",E_META_NEW_LEAVES_ACACIA_WOOD);
+ tolua_constant(tolua_S,"E_META_NEW_LEAVES_DARK_OAK_WOOD",E_META_NEW_LEAVES_DARK_OAK_WOOD);
+ tolua_constant(tolua_S,"E_META_NEW_LOG_ACACIA_WOOD",E_META_NEW_LOG_ACACIA_WOOD);
+ tolua_constant(tolua_S,"E_META_NEW_LOG_DARK_OAK_WOOD",E_META_NEW_LOG_DARK_OAK_WOOD);
tolua_constant(tolua_S,"E_META_PLANKS_APPLE",E_META_PLANKS_APPLE);
tolua_constant(tolua_S,"E_META_PLANKS_CONIFER",E_META_PLANKS_CONIFER);
tolua_constant(tolua_S,"E_META_PLANKS_BIRCH",E_META_PLANKS_BIRCH);
tolua_constant(tolua_S,"E_META_PLANKS_JUNGLE",E_META_PLANKS_JUNGLE);
+ tolua_constant(tolua_S,"E_META_RAIL_ZM_ZP",E_META_RAIL_ZM_ZP);
+ tolua_constant(tolua_S,"E_META_RAIL_XM_XP",E_META_RAIL_XM_XP);
+ tolua_constant(tolua_S,"E_META_RAIL_ASCEND_XP",E_META_RAIL_ASCEND_XP);
+ tolua_constant(tolua_S,"E_META_RAIL_ASCEND_XM",E_META_RAIL_ASCEND_XM);
+ tolua_constant(tolua_S,"E_META_RAIL_ASCEND_ZM",E_META_RAIL_ASCEND_ZM);
+ tolua_constant(tolua_S,"E_META_RAIL_ASCEND_ZP",E_META_RAIL_ASCEND_ZP);
+ tolua_constant(tolua_S,"E_META_RAIL_CURVED_ZP_XP",E_META_RAIL_CURVED_ZP_XP);
+ tolua_constant(tolua_S,"E_META_RAIL_CURVED_ZP_XM",E_META_RAIL_CURVED_ZP_XM);
+ tolua_constant(tolua_S,"E_META_RAIL_CURVED_ZM_XM",E_META_RAIL_CURVED_ZM_XM);
+ tolua_constant(tolua_S,"E_META_RAIL_CURVED_ZM_XP",E_META_RAIL_CURVED_ZM_XP);
+ tolua_constant(tolua_S,"E_META_SAND_NORMAL",E_META_SAND_NORMAL);
+ tolua_constant(tolua_S,"E_META_SAND_RED",E_META_SAND_RED);
tolua_constant(tolua_S,"E_META_SANDSTONE_NORMAL",E_META_SANDSTONE_NORMAL);
tolua_constant(tolua_S,"E_META_SANDSTONE_ORNAMENT",E_META_SANDSTONE_ORNAMENT);
tolua_constant(tolua_S,"E_META_SANDSTONE_SMOOTH",E_META_SANDSTONE_SMOOTH);
@@ -30017,6 +30095,62 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_STONE",E_META_SILVERFISH_EGG_STONE);
tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_COBBLESTONE",E_META_SILVERFISH_EGG_COBBLESTONE);
tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_STONE_BRICK",E_META_SILVERFISH_EGG_STONE_BRICK);
+ tolua_constant(tolua_S,"E_META_SNOW_LAYER_ONE",E_META_SNOW_LAYER_ONE);
+ tolua_constant(tolua_S,"E_META_SNOW_LAYER_TWO",E_META_SNOW_LAYER_TWO);
+ tolua_constant(tolua_S,"E_META_SNOW_LAYER_THREE",E_META_SNOW_LAYER_THREE);
+ tolua_constant(tolua_S,"E_META_SNOW_LAYER_FOUR",E_META_SNOW_LAYER_FOUR);
+ tolua_constant(tolua_S,"E_META_SNOW_LAYER_FIVE",E_META_SNOW_LAYER_FIVE);
+ tolua_constant(tolua_S,"E_META_SNOW_LAYER_SIX",E_META_SNOW_LAYER_SIX);
+ tolua_constant(tolua_S,"E_META_SNOW_LAYER_SEVEN",E_META_SNOW_LAYER_SEVEN);
+ tolua_constant(tolua_S,"E_META_SNOW_LAYER_EIGHT",E_META_SNOW_LAYER_EIGHT);
+ 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_STAINED_GLASS_WHITE",E_META_STAINED_GLASS_WHITE);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_ORANGE",E_META_STAINED_GLASS_ORANGE);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_MAGENTA",E_META_STAINED_GLASS_MAGENTA);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_LIGHTBLUE",E_META_STAINED_GLASS_LIGHTBLUE);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_YELLOW",E_META_STAINED_GLASS_YELLOW);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_LIGHTGREEN",E_META_STAINED_GLASS_LIGHTGREEN);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PINK",E_META_STAINED_GLASS_PINK);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_GRAY",E_META_STAINED_GLASS_GRAY);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_LIGHTGRAY",E_META_STAINED_GLASS_LIGHTGRAY);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_CYAN",E_META_STAINED_GLASS_CYAN);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PURPLE",E_META_STAINED_GLASS_PURPLE);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_BLUE",E_META_STAINED_GLASS_BLUE);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_BROWN",E_META_STAINED_GLASS_BROWN);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_GREEN",E_META_STAINED_GLASS_GREEN);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_RED",E_META_STAINED_GLASS_RED);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_BLACK",E_META_STAINED_GLASS_BLACK);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_WHITE",E_META_STAINED_GLASS_PANE_WHITE);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_ORANGE",E_META_STAINED_GLASS_PANE_ORANGE);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_MAGENTA",E_META_STAINED_GLASS_PANE_MAGENTA);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_LIGHTBLUE",E_META_STAINED_GLASS_PANE_LIGHTBLUE);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_YELLOW",E_META_STAINED_GLASS_PANE_YELLOW);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_LIGHTGREEN",E_META_STAINED_GLASS_PANE_LIGHTGREEN);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_PINK",E_META_STAINED_GLASS_PANE_PINK);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_GRAY",E_META_STAINED_GLASS_PANE_GRAY);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_LIGHTGRAY",E_META_STAINED_GLASS_PANE_LIGHTGRAY);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_CYAN",E_META_STAINED_GLASS_PANE_CYAN);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_PURPLE",E_META_STAINED_GLASS_PANE_PURPLE);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_BLUE",E_META_STAINED_GLASS_PANE_BLUE);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_BROWN",E_META_STAINED_GLASS_PANE_BROWN);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_GREEN",E_META_STAINED_GLASS_PANE_GREEN);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_RED",E_META_STAINED_GLASS_PANE_RED);
+ tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_BLACK",E_META_STAINED_GLASS_PANE_BLACK);
tolua_constant(tolua_S,"E_META_STONE_SLAB_STONE",E_META_STONE_SLAB_STONE);
tolua_constant(tolua_S,"E_META_STONE_SLAB_SANDSTONE",E_META_STONE_SLAB_SANDSTONE);
tolua_constant(tolua_S,"E_META_STONE_SLAB_PLANKS",E_META_STONE_SLAB_PLANKS);
@@ -30069,106 +30203,6 @@ 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_STAINED_GLASS_WHITE",E_META_STAINED_GLASS_WHITE);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_ORANGE",E_META_STAINED_GLASS_ORANGE);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_MAGENTA",E_META_STAINED_GLASS_MAGENTA);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_LIGHTBLUE",E_META_STAINED_GLASS_LIGHTBLUE);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_YELLOW",E_META_STAINED_GLASS_YELLOW);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_LIGHTGREEN",E_META_STAINED_GLASS_LIGHTGREEN);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PINK",E_META_STAINED_GLASS_PINK);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_GRAY",E_META_STAINED_GLASS_GRAY);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_LIGHTGRAY",E_META_STAINED_GLASS_LIGHTGRAY);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_CYAN",E_META_STAINED_GLASS_CYAN);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PURPLE",E_META_STAINED_GLASS_PURPLE);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_BLUE",E_META_STAINED_GLASS_BLUE);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_BROWN",E_META_STAINED_GLASS_BROWN);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_GREEN",E_META_STAINED_GLASS_GREEN);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_RED",E_META_STAINED_GLASS_RED);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_BLACK",E_META_STAINED_GLASS_BLACK);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_WHITE",E_META_STAINED_GLASS_PANE_WHITE);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_ORANGE",E_META_STAINED_GLASS_PANE_ORANGE);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_MAGENTA",E_META_STAINED_GLASS_PANE_MAGENTA);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_LIGHTBLUE",E_META_STAINED_GLASS_PANE_LIGHTBLUE);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_YELLOW",E_META_STAINED_GLASS_PANE_YELLOW);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_LIGHTGREEN",E_META_STAINED_GLASS_PANE_LIGHTGREEN);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_PINK",E_META_STAINED_GLASS_PANE_PINK);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_GRAY",E_META_STAINED_GLASS_PANE_GRAY);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_LIGHTGRAY",E_META_STAINED_GLASS_PANE_LIGHTGRAY);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_CYAN",E_META_STAINED_GLASS_PANE_CYAN);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_PURPLE",E_META_STAINED_GLASS_PANE_PURPLE);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_BLUE",E_META_STAINED_GLASS_PANE_BLUE);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_BROWN",E_META_STAINED_GLASS_PANE_BROWN);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_GREEN",E_META_STAINED_GLASS_PANE_GREEN);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_RED",E_META_STAINED_GLASS_PANE_RED);
- tolua_constant(tolua_S,"E_META_STAINED_GLASS_PANE_BLACK",E_META_STAINED_GLASS_PANE_BLACK);
- tolua_constant(tolua_S,"E_META_SNOW_LAYER_ONE",E_META_SNOW_LAYER_ONE);
- tolua_constant(tolua_S,"E_META_SNOW_LAYER_TWO",E_META_SNOW_LAYER_TWO);
- tolua_constant(tolua_S,"E_META_SNOW_LAYER_THREE",E_META_SNOW_LAYER_THREE);
- tolua_constant(tolua_S,"E_META_SNOW_LAYER_FOUR",E_META_SNOW_LAYER_FOUR);
- tolua_constant(tolua_S,"E_META_SNOW_LAYER_FIVE",E_META_SNOW_LAYER_FIVE);
- tolua_constant(tolua_S,"E_META_SNOW_LAYER_SIX",E_META_SNOW_LAYER_SIX);
- tolua_constant(tolua_S,"E_META_SNOW_LAYER_SEVEN",E_META_SNOW_LAYER_SEVEN);
- tolua_constant(tolua_S,"E_META_SNOW_LAYER_EIGHT",E_META_SNOW_LAYER_EIGHT);
- tolua_constant(tolua_S,"E_META_RAIL_ZM_ZP",E_META_RAIL_ZM_ZP);
- tolua_constant(tolua_S,"E_META_RAIL_XM_XP",E_META_RAIL_XM_XP);
- tolua_constant(tolua_S,"E_META_RAIL_ASCEND_XP",E_META_RAIL_ASCEND_XP);
- tolua_constant(tolua_S,"E_META_RAIL_ASCEND_XM",E_META_RAIL_ASCEND_XM);
- tolua_constant(tolua_S,"E_META_RAIL_ASCEND_ZM",E_META_RAIL_ASCEND_ZM);
- tolua_constant(tolua_S,"E_META_RAIL_ASCEND_ZP",E_META_RAIL_ASCEND_ZP);
- tolua_constant(tolua_S,"E_META_RAIL_CURVED_ZP_XP",E_META_RAIL_CURVED_ZP_XP);
- tolua_constant(tolua_S,"E_META_RAIL_CURVED_ZP_XM",E_META_RAIL_CURVED_ZP_XM);
- tolua_constant(tolua_S,"E_META_RAIL_CURVED_ZM_XM",E_META_RAIL_CURVED_ZM_XM);
- tolua_constant(tolua_S,"E_META_RAIL_CURVED_ZM_XP",E_META_RAIL_CURVED_ZM_XP);
- tolua_constant(tolua_S,"E_META_NEW_LEAVES_ACACIA_WOOD",E_META_NEW_LEAVES_ACACIA_WOOD);
- tolua_constant(tolua_S,"E_META_NEW_LEAVES_DARK_OAK_WOOD",E_META_NEW_LEAVES_DARK_OAK_WOOD);
- tolua_constant(tolua_S,"E_META_NEW_LOG_ACACIA_WOOD",E_META_NEW_LOG_ACACIA_WOOD);
- tolua_constant(tolua_S,"E_META_NEW_LOG_DARK_OAK_WOOD",E_META_NEW_LOG_DARK_OAK_WOOD);
- tolua_constant(tolua_S,"E_META_FLOWER_POPPY",E_META_FLOWER_POPPY);
- tolua_constant(tolua_S,"E_META_FLOWER_BLUE_ORCHID",E_META_FLOWER_BLUE_ORCHID);
- tolua_constant(tolua_S,"E_META_FLOWER_ALLIUM",E_META_FLOWER_ALLIUM);
- tolua_constant(tolua_S,"E_META_FLOWER_RED_TULIP",E_META_FLOWER_RED_TULIP);
- tolua_constant(tolua_S,"E_META_FLOWER_ORANGE_TULIP",E_META_FLOWER_ORANGE_TULIP);
- tolua_constant(tolua_S,"E_META_FLOWER_WHITE_TULIP",E_META_FLOWER_WHITE_TULIP);
- tolua_constant(tolua_S,"E_META_FLOWER_PINK_TULIP",E_META_FLOWER_PINK_TULIP);
- tolua_constant(tolua_S,"E_META_FLOWER_OXEYE_DAISY",E_META_FLOWER_OXEYE_DAISY);
- tolua_constant(tolua_S,"E_META_BIG_FLOWER_SUNFLOWER",E_META_BIG_FLOWER_SUNFLOWER);
- tolua_constant(tolua_S,"E_META_BIG_FLOWER_LILAC",E_META_BIG_FLOWER_LILAC);
- tolua_constant(tolua_S,"E_META_BIG_FLOWER_DOUBLE_TALL_GRASS",E_META_BIG_FLOWER_DOUBLE_TALL_GRASS);
- tolua_constant(tolua_S,"E_META_BIG_FLOWER_LARGE_FERN",E_META_BIG_FLOWER_LARGE_FERN);
- tolua_constant(tolua_S,"E_META_BIG_FLOWER_ROSE_BUSH",E_META_BIG_FLOWER_ROSE_BUSH);
- tolua_constant(tolua_S,"E_META_BIG_FLOWER_PEONY",E_META_BIG_FLOWER_PEONY);
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);
@@ -30409,6 +30443,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"IsBoots",tolua_AllToLua_ItemCategory_IsBoots00);
tolua_function(tolua_S,"IsArmor",tolua_AllToLua_ItemCategory_IsArmor00);
tolua_endmodule(tolua_S);
+ tolua_function(tolua_S,"IsBiomeNoDownfall",tolua_AllToLua_IsBiomeNoDownfall00);
tolua_function(tolua_S,"GetTime",tolua_AllToLua_GetTime00);
tolua_function(tolua_S,"GetChar",tolua_AllToLua_GetChar00);
tolua_cclass(tolua_S,"cChatColor","cChatColor","",NULL);
diff --git a/src/Bindings.h b/src/Bindings.h
index d141484db..4b6fbb322 100644
--- a/src/Bindings.h
+++ b/src/Bindings.h
@@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
-** Generated automatically by tolua++-1.0.92 on 11/26/13 22:11:11.
+** Generated automatically by tolua++-1.0.92 on 11/30/13 15:42:57.
*/
/* Exported function */
diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp
index 823ed598f..7c9a40ce6 100644
--- a/src/BlockEntities/DropSpenserEntity.cpp
+++ b/src/BlockEntities/DropSpenserEntity.cpp
@@ -8,6 +8,7 @@
#include "DropSpenserEntity.h"
#include "../Entities/Player.h"
#include "../Chunk.h"
+#include "json/json.h"
diff --git a/src/BlockID.h b/src/BlockID.h
index a4e7dbca9..9742e9745 100644
--- a/src/BlockID.h
+++ b/src/BlockID.h
@@ -401,12 +401,43 @@ enum
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Block metas:
+ // E_BLOCK_BIG_FLOWER metas
+ E_META_BIG_FLOWER_SUNFLOWER = 0,
+ E_META_BIG_FLOWER_LILAC = 1,
+ E_META_BIG_FLOWER_DOUBLE_TALL_GRASS = 2,
+ E_META_BIG_FLOWER_LARGE_FERN = 3,
+ E_META_BIG_FLOWER_ROSE_BUSH = 4,
+ E_META_BIG_FLOWER_PEONY = 5,
+
+ // E_BLOCK_CARPET metas:
+ E_META_CARPET_WHITE = 0,
+ E_META_CARPET_ORANGE = 1,
+ E_META_CARPET_MAGENTA = 2,
+ E_META_CARPET_LIGHTBLUE = 3,
+ E_META_CARPET_YELLOW = 4,
+ E_META_CARPET_LIGHTGREEN = 5,
+ E_META_CARPET_PINK = 6,
+ E_META_CARPET_GRAY = 7,
+ E_META_CARPET_LIGHTGRAY = 8,
+ E_META_CARPET_CYAN = 9,
+ E_META_CARPET_PURPLE = 10,
+ E_META_CARPET_BLUE = 11,
+ E_META_CARPET_BROWN = 12,
+ E_META_CARPET_GREEN = 13,
+ E_META_CARPET_RED = 14,
+ E_META_CARPET_BLACK = 15,
+
// E_BLOCK_CHEST metas:
E_META_CHEST_FACING_ZM = 2,
E_META_CHEST_FACING_ZP = 3,
E_META_CHEST_FACING_XM = 4,
E_META_CHEST_FACING_XP = 5,
+ // E_BLOCK_DIRT metas:
+ E_META_DIRT_NORMAL = 0,
+ E_META_DIRT_GRASSLESS = 1,
+ E_META_DIRT_PODZOL = 2,
+
// E_BLOCK_DISPENSER / E_BLOCK_DROPPER metas:
E_META_DROPSPENSER_FACING_YM = 0,
E_META_DROPSPENSER_FACING_YP = 1,
@@ -424,8 +455,16 @@ enum
E_META_DOUBLE_STONE_SLAB_STONE_BRICK = 5,
E_META_DOUBLE_STONE_SLAB_NETHER_BRICK = 6,
E_META_DOUBLE_STONE_SLAB_STONE_SECRET = 7,
-
-
+
+ // E_BLOCK_FLOWER metas
+ E_META_FLOWER_POPPY = 0,
+ E_META_FLOWER_BLUE_ORCHID = 1,
+ E_META_FLOWER_ALLIUM = 2,
+ E_META_FLOWER_RED_TULIP = 4,
+ E_META_FLOWER_ORANGE_TULIP = 5,
+ E_META_FLOWER_WHITE_TULIP = 6,
+ E_META_FLOWER_PINK_TULIP = 7,
+ E_META_FLOWER_OXEYE_DAISY = 8,
// E_BLOCK_HOPPER metas:
E_META_HOPPER_FACING_YM = 0,
@@ -447,12 +486,36 @@ enum
E_META_LOG_BIRCH = 2,
E_META_LOG_JUNGLE = 3,
+ // E_BLOCK_NEW_LEAVES metas
+ E_META_NEW_LEAVES_ACACIA_WOOD = 0,
+ E_META_NEW_LEAVES_DARK_OAK_WOOD = 1,
+
+ // E_BLOCK_NEW_LOG metas
+ E_META_NEW_LOG_ACACIA_WOOD = 0,
+ E_META_NEW_LOG_DARK_OAK_WOOD = 1,
+
// E_BLOCK_PLANKS metas:
E_META_PLANKS_APPLE = 0,
E_META_PLANKS_CONIFER = 1,
E_META_PLANKS_BIRCH = 2,
E_META_PLANKS_JUNGLE = 3,
+ // E_BLOCK_RAIL metas
+ E_META_RAIL_ZM_ZP = 0,
+ E_META_RAIL_XM_XP = 1,
+ E_META_RAIL_ASCEND_XP = 2,
+ E_META_RAIL_ASCEND_XM = 3,
+ E_META_RAIL_ASCEND_ZM = 4,
+ E_META_RAIL_ASCEND_ZP = 5,
+ E_META_RAIL_CURVED_ZP_XP = 6,
+ E_META_RAIL_CURVED_ZP_XM = 7,
+ E_META_RAIL_CURVED_ZM_XM = 8,
+ E_META_RAIL_CURVED_ZM_XP = 9,
+
+ // E_BLOCK_SAND metas:
+ E_META_SAND_NORMAL = 0,
+ E_META_SAND_RED = 1,
+
// E_BLOCK_SANDSTONE metas:
E_META_SANDSTONE_NORMAL = 0,
E_META_SANDSTONE_ORNAMENT = 1,
@@ -469,6 +532,70 @@ enum
E_META_SILVERFISH_EGG_COBBLESTONE = 1,
E_META_SILVERFISH_EGG_STONE_BRICK = 2,
+ // E_BLOCK_SNOW metas:
+ E_META_SNOW_LAYER_ONE = 0,
+ E_META_SNOW_LAYER_TWO = 1,
+ E_META_SNOW_LAYER_THREE = 2,
+ E_META_SNOW_LAYER_FOUR = 3,
+ E_META_SNOW_LAYER_FIVE = 4,
+ E_META_SNOW_LAYER_SIX = 5,
+ E_META_SNOW_LAYER_SEVEN = 6,
+ E_META_SNOW_LAYER_EIGHT = 7,
+
+ // E_BLOCK_STAINED_CLAY metas
+ E_META_STAINED_CLAY_WHITE = 0,
+ E_META_STAINED_CLAY_ORANGE = 1,
+ E_META_STAINED_CLAY_MAGENTA = 2,
+ E_META_STAINED_CLAY_LIGHTBLUE = 3,
+ E_META_STAINED_CLAY_YELLOW = 4,
+ E_META_STAINED_CLAY_LIGHTGREEN = 5,
+ E_META_STAINED_CLAY_PINK = 6,
+ E_META_STAINED_CLAY_GRAY = 7,
+ E_META_STAINED_CLAY_LIGHTGRAY = 8,
+ E_META_STAINED_CLAY_CYAN = 9,
+ E_META_STAINED_CLAY_PURPLE = 10,
+ E_META_STAINED_CLAY_BLUE = 11,
+ E_META_STAINED_CLAY_BROWN = 12,
+ E_META_STAINED_CLAY_GREEN = 13,
+ E_META_STAINED_CLAY_RED = 14,
+ E_META_STAINED_CLAY_BLACK = 15,
+
+ // E_BLOCK_STAINED_GLASS metas
+ E_META_STAINED_GLASS_WHITE = 0,
+ E_META_STAINED_GLASS_ORANGE = 1,
+ E_META_STAINED_GLASS_MAGENTA = 2,
+ E_META_STAINED_GLASS_LIGHTBLUE = 3,
+ E_META_STAINED_GLASS_YELLOW = 4,
+ E_META_STAINED_GLASS_LIGHTGREEN = 5,
+ E_META_STAINED_GLASS_PINK = 6,
+ E_META_STAINED_GLASS_GRAY = 7,
+ E_META_STAINED_GLASS_LIGHTGRAY = 8,
+ E_META_STAINED_GLASS_CYAN = 9,
+ E_META_STAINED_GLASS_PURPLE = 10,
+ E_META_STAINED_GLASS_BLUE = 11,
+ E_META_STAINED_GLASS_BROWN = 12,
+ E_META_STAINED_GLASS_GREEN = 13,
+ E_META_STAINED_GLASS_RED = 14,
+ E_META_STAINED_GLASS_BLACK = 15,
+
+ // E_BLOCK_STAINED_GLASS_PANE metas
+ E_META_STAINED_GLASS_PANE_WHITE = 0,
+ E_META_STAINED_GLASS_PANE_ORANGE = 1,
+ E_META_STAINED_GLASS_PANE_MAGENTA = 2,
+ E_META_STAINED_GLASS_PANE_LIGHTBLUE = 3,
+ E_META_STAINED_GLASS_PANE_YELLOW = 4,
+ E_META_STAINED_GLASS_PANE_LIGHTGREEN = 5,
+ E_META_STAINED_GLASS_PANE_PINK = 6,
+ E_META_STAINED_GLASS_PANE_GRAY = 7,
+ E_META_STAINED_GLASS_PANE_LIGHTGRAY = 8,
+ E_META_STAINED_GLASS_PANE_CYAN = 9,
+ E_META_STAINED_GLASS_PANE_PURPLE = 10,
+ E_META_STAINED_GLASS_PANE_BLUE = 11,
+ E_META_STAINED_GLASS_PANE_BROWN = 12,
+ E_META_STAINED_GLASS_PANE_GREEN = 13,
+ E_META_STAINED_GLASS_PANE_RED = 14,
+ E_META_STAINED_GLASS_PANE_BLACK = 15,
+
// E_BLOCK_STONE_SLAB metas:
E_META_STONE_SLAB_STONE = 0,
E_META_STONE_SLAB_SANDSTONE = 1,
@@ -535,126 +662,6 @@ enum
E_META_WOOL_RED = 14,
E_META_WOOL_BLACK = 15,
- // E_BLOCK_CARPET metas:
- E_META_CARPET_WHITE = 0,
- E_META_CARPET_ORANGE = 1,
- E_META_CARPET_MAGENTA = 2,
- E_META_CARPET_LIGHTBLUE = 3,
- E_META_CARPET_YELLOW = 4,
- E_META_CARPET_LIGHTGREEN = 5,
- E_META_CARPET_PINK = 6,
- E_META_CARPET_GRAY = 7,
- E_META_CARPET_LIGHTGRAY = 8,
- E_META_CARPET_CYAN = 9,
- E_META_CARPET_PURPLE = 10,
- E_META_CARPET_BLUE = 11,
- E_META_CARPET_BROWN = 12,
- E_META_CARPET_GREEN = 13,
- E_META_CARPET_RED = 14,
- E_META_CARPET_BLACK = 15,
-
- // E_BLOCK_STAINED_CLAY metas
- E_META_STAINED_CLAY_WHITE = 0,
- E_META_STAINED_CLAY_ORANGE = 1,
- E_META_STAINED_CLAY_MAGENTA = 2,
- E_META_STAINED_CLAY_LIGHTBLUE = 3,
- E_META_STAINED_CLAY_YELLOW = 4,
- E_META_STAINED_CLAY_LIGHTGREEN = 5,
- E_META_STAINED_CLAY_PINK = 6,
- E_META_STAINED_CLAY_GRAY = 7,
- E_META_STAINED_CLAY_LIGHTGRAY = 8,
- E_META_STAINED_CLAY_CYAN = 9,
- E_META_STAINED_CLAY_PURPLE = 10,
- E_META_STAINED_CLAY_BLUE = 11,
- E_META_STAINED_CLAY_BROWN = 12,
- E_META_STAINED_CLAY_GREEN = 13,
- E_META_STAINED_CLAY_RED = 14,
- E_META_STAINED_CLAY_BLACK = 15,
-
- // E_BLOCK_STAINED_GLASS metas
- E_META_STAINED_GLASS_WHITE = 0,
- E_META_STAINED_GLASS_ORANGE = 1,
- E_META_STAINED_GLASS_MAGENTA = 2,
- E_META_STAINED_GLASS_LIGHTBLUE = 3,
- E_META_STAINED_GLASS_YELLOW = 4,
- E_META_STAINED_GLASS_LIGHTGREEN = 5,
- E_META_STAINED_GLASS_PINK = 6,
- E_META_STAINED_GLASS_GRAY = 7,
- E_META_STAINED_GLASS_LIGHTGRAY = 8,
- E_META_STAINED_GLASS_CYAN = 9,
- E_META_STAINED_GLASS_PURPLE = 10,
- E_META_STAINED_GLASS_BLUE = 11,
- E_META_STAINED_GLASS_BROWN = 12,
- E_META_STAINED_GLASS_GREEN = 13,
- E_META_STAINED_GLASS_RED = 14,
- E_META_STAINED_GLASS_BLACK = 15,
-
- // E_BLOCK_STAINED_GLASS_PANE metas
- E_META_STAINED_GLASS_PANE_WHITE = 0,
- E_META_STAINED_GLASS_PANE_ORANGE = 1,
- E_META_STAINED_GLASS_PANE_MAGENTA = 2,
- E_META_STAINED_GLASS_PANE_LIGHTBLUE = 3,
- E_META_STAINED_GLASS_PANE_YELLOW = 4,
- E_META_STAINED_GLASS_PANE_LIGHTGREEN = 5,
- E_META_STAINED_GLASS_PANE_PINK = 6,
- E_META_STAINED_GLASS_PANE_GRAY = 7,
- E_META_STAINED_GLASS_PANE_LIGHTGRAY = 8,
- E_META_STAINED_GLASS_PANE_CYAN = 9,
- E_META_STAINED_GLASS_PANE_PURPLE = 10,
- E_META_STAINED_GLASS_PANE_BLUE = 11,
- E_META_STAINED_GLASS_PANE_BROWN = 12,
- E_META_STAINED_GLASS_PANE_GREEN = 13,
- E_META_STAINED_GLASS_PANE_RED = 14,
- E_META_STAINED_GLASS_PANE_BLACK = 15,
-
- // E_BLOCK_SNOW metas:
- E_META_SNOW_LAYER_ONE = 0,
- E_META_SNOW_LAYER_TWO = 1,
- E_META_SNOW_LAYER_THREE = 2,
- E_META_SNOW_LAYER_FOUR = 3,
- E_META_SNOW_LAYER_FIVE = 4,
- E_META_SNOW_LAYER_SIX = 5,
- E_META_SNOW_LAYER_SEVEN = 6,
- E_META_SNOW_LAYER_EIGHT = 7,
-
- // E_BLOCK_RAIL metas
- E_META_RAIL_ZM_ZP = 0,
- E_META_RAIL_XM_XP = 1,
- E_META_RAIL_ASCEND_XP = 2,
- E_META_RAIL_ASCEND_XM = 3,
- E_META_RAIL_ASCEND_ZM = 4,
- E_META_RAIL_ASCEND_ZP = 5,
- E_META_RAIL_CURVED_ZP_XP = 6,
- E_META_RAIL_CURVED_ZP_XM = 7,
- E_META_RAIL_CURVED_ZM_XM = 8,
- E_META_RAIL_CURVED_ZM_XP = 9,
-
- //E_BLOCK_NEW_LEAVES metas
- E_META_NEW_LEAVES_ACACIA_WOOD = 0,
- E_META_NEW_LEAVES_DARK_OAK_WOOD = 1,
-
- //E_BLOCK_NEW_LOG metas
- E_META_NEW_LOG_ACACIA_WOOD = 0,
- E_META_NEW_LOG_DARK_OAK_WOOD = 1,
-
- //E_BLOCK_FLOWER metas
- E_META_FLOWER_POPPY = 0,
- E_META_FLOWER_BLUE_ORCHID = 1,
- E_META_FLOWER_ALLIUM = 2,
- E_META_FLOWER_RED_TULIP = 4,
- E_META_FLOWER_ORANGE_TULIP = 5,
- E_META_FLOWER_WHITE_TULIP = 6,
- E_META_FLOWER_PINK_TULIP = 7,
- E_META_FLOWER_OXEYE_DAISY = 8,
-
- //E_BLOCK_BIG_FLOWER metas
- E_META_BIG_FLOWER_SUNFLOWER = 0,
- E_META_BIG_FLOWER_LILAC = 1,
- E_META_BIG_FLOWER_DOUBLE_TALL_GRASS = 2,
- E_META_BIG_FLOWER_LARGE_FERN = 3,
- E_META_BIG_FLOWER_ROSE_BUSH = 4,
- E_META_BIG_FLOWER_PEONY = 5,
-
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Item metas:
diff --git a/src/Blocks/BlockCactus.h b/src/Blocks/BlockCactus.h
index 4147ad473..7a9088178 100644
--- a/src/Blocks/BlockCactus.h
+++ b/src/Blocks/BlockCactus.h
@@ -65,9 +65,9 @@ public:
}
- void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
- a_World->GrowCactus(a_BlockX, a_BlockY, a_BlockZ, 1);
+ a_Chunk.GetWorld()->GrowCactus(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, 1);
}
diff --git a/src/Blocks/BlockCrops.h b/src/Blocks/BlockCrops.h
index 9dd65aae2..9c4964e02 100644
--- a/src/Blocks/BlockCrops.h
+++ b/src/Blocks/BlockCrops.h
@@ -75,11 +75,11 @@ public:
}
- void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
- NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
- NIBBLETYPE Light = a_World->GetBlockBlockLight(a_BlockX, a_BlockY, a_BlockZ);
- NIBBLETYPE SkyLight = a_World->GetBlockSkyLight(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE Meta = a_Chunk.GetMeta (a_RelX, a_RelY, a_RelZ);
+ NIBBLETYPE Light = a_Chunk.GetBlockLight(a_RelX, a_RelY, a_RelZ);
+ NIBBLETYPE SkyLight = a_Chunk.GetSkyLight (a_RelX, a_RelY, a_RelZ);
if (SkyLight > Light)
{
@@ -88,11 +88,11 @@ public:
if ((Meta < 7) && (Light > 8))
{
- a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_CROPS, ++Meta);
+ a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_CROPS, ++Meta);
}
else if (Light < 9)
{
- a_World->DigBlock(a_BlockX, a_BlockY, a_BlockZ);
+ a_Chunk.GetWorld()->DigBlock(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width);
}
}
diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h
index c694d79f6..a83dab1fd 100644
--- a/src/Blocks/BlockDirt.h
+++ b/src/Blocks/BlockDirt.h
@@ -26,7 +26,7 @@ public:
}
- virtual void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
if (m_BlockType != E_BLOCK_GRASS)
{
@@ -34,18 +34,18 @@ public:
}
// Grass becomes dirt if there is something on top of it:
- if (a_BlockY < cChunkDef::Height - 1)
+ if (a_RelY < cChunkDef::Height - 1)
{
- BLOCKTYPE Above = a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ);
+ BLOCKTYPE Above = a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ);
if ((!g_BlockTransparent[Above] && !g_BlockOneHitDig[Above]) || IsBlockWater(Above))
{
- a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_DIRT, 0);
+ a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, E_META_DIRT_NORMAL);
return;
}
}
- // Grass spreads to adjacent blocks:
- MTRand rand;
+ // Grass spreads to adjacent dirt blocks:
+ MTRand rand; // TODO: Replace with cFastRandom
for (int i = 0; i < 2; i++) // Pick two blocks to grow to
{
int OfsX = rand.randInt(2) - 1; // [-1 .. 1]
@@ -54,24 +54,33 @@ public:
BLOCKTYPE DestBlock;
NIBBLETYPE DestMeta;
- if ((a_BlockY + OfsY < 0) || (a_BlockY + OfsY >= cChunkDef::Height - 1))
+ if ((a_RelY + OfsY < 0) || (a_RelY + OfsY >= cChunkDef::Height - 1))
{
// Y Coord out of range
continue;
}
- bool IsValid = a_World->GetBlockTypeMeta(a_BlockX + OfsX, a_BlockY + OfsY, a_BlockZ + OfsZ, DestBlock, DestMeta);
- if (!IsValid || (DestBlock != E_BLOCK_DIRT))
+ int BlockX = a_RelX + OfsX;
+ int BlockY = a_RelY + OfsY;
+ int BlockZ = a_RelZ + OfsZ;
+ cChunk * Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(BlockX, BlockZ);
+ if (Chunk == NULL)
{
+ // Unloaded chunk
+ continue;
+ }
+ Chunk->GetBlockTypeMeta(BlockX, BlockY, BlockZ, DestBlock, DestMeta);
+ if ((DestBlock != E_BLOCK_DIRT) || (DestMeta != E_META_DIRT_NORMAL))
+ {
+ // Not a regular dirt block
continue;
}
BLOCKTYPE AboveDest;
NIBBLETYPE AboveMeta;
- IsValid = a_World->GetBlockTypeMeta(a_BlockX + OfsX, a_BlockY + OfsY + 1, a_BlockZ + OfsZ, AboveDest, AboveMeta);
- ASSERT(IsValid); // WTF - how did we get the DestBlock if AboveBlock is not valid?
+ Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta);
if ((g_BlockOneHitDig[AboveDest] || g_BlockTransparent[AboveDest]) && !IsBlockWater(AboveDest))
{
- a_World->FastSetBlock(a_BlockX + OfsX, a_BlockY + OfsY, a_BlockZ + OfsZ, E_BLOCK_GRASS, 0);
+ Chunk->FastSetBlock(a_RelX + OfsX, a_RelY + OfsY, a_RelZ + OfsZ, E_BLOCK_GRASS, 0);
}
} // for i - repeat twice
}
diff --git a/src/Blocks/BlockFarmland.h b/src/Blocks/BlockFarmland.h
index 7bc71f7f3..a69d9b775 100644
--- a/src/Blocks/BlockFarmland.h
+++ b/src/Blocks/BlockFarmland.h
@@ -28,12 +28,12 @@ public:
}
- virtual void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
bool Found = false;
- int Biome = a_World->GetBiomeAt(a_BlockX, a_BlockZ);
- if (a_World->IsWeatherWet() && (Biome != biDesert) && (Biome != biDesertHills))
+ EMCSBiome Biome = a_Chunk.GetBiomeAt(a_RelX, a_RelZ);
+ if (a_Chunk.GetWorld()->IsWeatherWet() && !IsBiomeNoDownfall(Biome))
{
// Rain hydrates farmland, too, except in Desert biomes.
Found = true;
@@ -42,10 +42,13 @@ public:
{
// Search for water in a close proximity:
// Ref.: http://www.minecraftwiki.net/wiki/Farmland#Hydrated_Farmland_Tiles
+ // TODO: Rewrite this to use the chunk and its neighbors directly
cBlockArea Area;
- if (!Area.Read(a_World, a_BlockX - 4, a_BlockX + 4, a_BlockY, a_BlockY + 1, a_BlockZ - 4, a_BlockZ + 4))
+ int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
+ int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
+ if (!Area.Read(a_Chunk.GetWorld(), BlockX - 4, BlockX + 4, a_RelY, a_RelY + 1, BlockZ - 4, BlockZ + 4))
{
- // Too close to the world edge, cannot check surroudnings; don't tick at all
+ // Too close to the world edge, cannot check surroundings; don't tick at all
return;
}
@@ -64,14 +67,14 @@ public:
} // for i - BlockTypes[]
}
- NIBBLETYPE BlockMeta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE BlockMeta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
if (Found)
{
// Water was found, hydrate the block until hydration reaches 7:
if (BlockMeta < 7)
{
- a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, ++BlockMeta);
+ a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, ++BlockMeta);
}
return;
}
@@ -79,12 +82,12 @@ public:
// Water wasn't found, de-hydrate block:
if (BlockMeta > 0)
{
- a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FARMLAND, --BlockMeta);
+ a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_FARMLAND, --BlockMeta);
return;
}
// Farmland too dry. If nothing is growing on top, turn back to dirt:
- switch (a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))
+ switch (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ))
{
case E_BLOCK_CROPS:
case E_BLOCK_MELON_STEM:
@@ -95,7 +98,7 @@ public:
}
default:
{
- a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_DIRT, 0);
+ a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, 0);
break;
}
}
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index a4233b883..7bb35efeb 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -254,7 +254,7 @@ bool cBlockHandler::GetPlacementBlockTypeMeta(
-void cBlockHandler::OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+void cBlockHandler::OnUpdate(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ)
{
}
diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h
index 126930dc1..107d36476 100644
--- a/src/Blocks/BlockHandler.h
+++ b/src/Blocks/BlockHandler.h
@@ -22,8 +22,9 @@ class cBlockHandler
public:
cBlockHandler(BLOCKTYPE a_BlockType);
- /// Called when the block gets ticked either by a random tick or by a queued tick
- virtual void OnUpdate(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ);
+ /// Called when the block gets ticked either by a random tick or by a queued tick.
+ /// Note that the coords are chunk-relative!
+ virtual void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ);
/** Called before a block is placed into a world.
The handler should return true to allow placement, false to refuse.
@@ -66,7 +67,7 @@ public:
/// Called if the user right clicks the block and the block is useable
virtual void OnUse(cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ);
- /// Called when the item is mined to convert it into pickups. Pickups may specify multiple items. Appends items to a_Pickups, preserves its original contents
+ /// <summary>Called when the item is mined to convert it into pickups. Pickups may specify multiple items. Appends items to a_Pickups, preserves its original contents</summary>
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta);
/// Handles the dropping of a block based on what ConvertToDrops() returns. This will not destroy the block. a_Digger is the entity causing the drop; it may be NULL
diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h
index 6e015b8fa..539d12a49 100644
--- a/src/Blocks/BlockLeaves.h
+++ b/src/Blocks/BlockLeaves.h
@@ -77,9 +77,9 @@ public:
}
- virtual void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
- NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
if ((Meta & 0x04) != 0)
{
// Player-placed leaves, don't decay
@@ -93,12 +93,14 @@ public:
}
// Get the data around the leaves:
+ int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
+ int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
cBlockArea Area;
if (!Area.Read(
- a_World,
- a_BlockX - LEAVES_CHECK_DISTANCE, a_BlockX + LEAVES_CHECK_DISTANCE,
- a_BlockY - LEAVES_CHECK_DISTANCE, a_BlockY + LEAVES_CHECK_DISTANCE,
- a_BlockZ - LEAVES_CHECK_DISTANCE, a_BlockZ + LEAVES_CHECK_DISTANCE,
+ a_Chunk.GetWorld(),
+ BlockX - LEAVES_CHECK_DISTANCE, BlockX + LEAVES_CHECK_DISTANCE,
+ a_RelY - LEAVES_CHECK_DISTANCE, a_RelY + LEAVES_CHECK_DISTANCE,
+ BlockZ - LEAVES_CHECK_DISTANCE, BlockZ + LEAVES_CHECK_DISTANCE,
cBlockArea::baTypes)
)
{
@@ -106,17 +108,16 @@ public:
return;
}
- if (HasNearLog(Area, a_BlockX, a_BlockY, a_BlockZ))
+ if (HasNearLog(Area, BlockX, a_RelY, BlockZ))
{
// Wood found, the leaves stay; mark them as checked:
- a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x8);
+ a_Chunk.SetMeta(a_RelX, a_RelY, a_RelZ, Meta | 0x8);
return;
}
- // Decay the leaves:
- DropBlock(a_World, NULL, a_BlockX, a_BlockY, a_BlockZ);
- a_World->DigBlock(a_BlockX, a_BlockY, a_BlockZ);
-
+ // Decay the leaves:
+ DropBlock(a_Chunk.GetWorld(), NULL, BlockX, a_RelY, BlockZ);
+ a_Chunk.GetWorld()->DigBlock(BlockX, a_RelY, BlockZ);
}
diff --git a/src/Blocks/BlockSapling.h b/src/Blocks/BlockSapling.h
index fff2fa88b..0dcae1f93 100644
--- a/src/Blocks/BlockSapling.h
+++ b/src/Blocks/BlockSapling.h
@@ -31,17 +31,19 @@ public:
}
- void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
- NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
if ((Meta & 0x08) != 0)
{
- a_World->GrowTree(a_BlockX, a_BlockY, a_BlockZ);
+ int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
+ int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
+ a_Chunk.GetWorld()->GrowTree(BlockX, a_RelY, BlockZ);
}
else
{
- a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x08);
+ a_Chunk.SetMeta(a_RelX, a_RelY, a_RelZ, Meta | 0x08);
}
}
diff --git a/src/Blocks/BlockStems.h b/src/Blocks/BlockStems.h
index 90dd90bbc..c2dff62cf 100644
--- a/src/Blocks/BlockStems.h
+++ b/src/Blocks/BlockStems.h
@@ -24,18 +24,20 @@ public:
}
- void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
- NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
if (Meta >= 7)
{
// Grow the produce:
- a_World->GrowMelonPumpkin(a_BlockX, a_BlockY, a_BlockZ, m_BlockType);
+ int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
+ int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
+ a_Chunk.GetWorld()->GrowMelonPumpkin(BlockX, a_RelY, a_RelZ, m_BlockType);
}
else
{
// Grow the stem:
- a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta + 1);
+ a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, Meta + 1);
}
}
diff --git a/src/Blocks/BlockSugarcane.h b/src/Blocks/BlockSugarcane.h
index 28a60df80..02d7a2fe4 100644
--- a/src/Blocks/BlockSugarcane.h
+++ b/src/Blocks/BlockSugarcane.h
@@ -73,9 +73,9 @@ public:
}
- void OnUpdate(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
- a_World->GrowSugarcane(a_BlockX, a_BlockY, a_BlockZ, 1);
+ a_Chunk.GetWorld()->GrowSugarcane(a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, 1);
}
diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp
index 8f2b76c1f..a6be09ad3 100644
--- a/src/ByteBuffer.cpp
+++ b/src/ByteBuffer.cpp
@@ -818,7 +818,7 @@ void cByteBuffer::AdvanceReadPos(int a_Count)
CHECK_THREAD;
CheckValid();
m_ReadPos += a_Count;
- if (m_ReadPos > m_BufferSize)
+ if (m_ReadPos >= m_BufferSize)
{
m_ReadPos -= m_BufferSize;
}
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index b3b24e339..45825a30f 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -631,6 +631,23 @@ void cChunk::Tick(float a_Dt)
+void cChunk::TickBlock(int a_RelX, int a_RelY, int a_RelZ)
+{
+ unsigned Index = MakeIndex(a_RelX, a_RelY, a_RelZ);
+ if (Index == INDEX_OUT_OF_RANGE)
+ {
+ // An assert has already been made in MakeIndex()
+ return;
+ }
+ cBlockHandler * Handler = BlockHandler(m_BlockTypes[Index]);
+ ASSERT(Handler != NULL); // Happenned on server restart, FS #243
+ Handler->OnUpdate(*this, a_RelX + m_PosX * Width, a_RelY, a_RelZ + m_PosZ * Width);
+}
+
+
+
+
+
void cChunk::MoveEntityToNewChunk(cEntity * a_Entity)
{
cChunk * Neighbor = GetNeighborChunk(a_Entity->GetChunkX() * cChunkDef::Width, a_Entity->GetChunkZ() * cChunkDef::Width);
@@ -777,7 +794,7 @@ void cChunk::TickBlocks(void)
unsigned int Index = MakeIndexNoCheck(m_BlockTickX, m_BlockTickY, m_BlockTickZ);
cBlockHandler * Handler = BlockHandler(m_BlockTypes[Index]);
ASSERT(Handler != NULL); // Happenned on server restart, FS #243
- Handler->OnUpdate(m_World, m_BlockTickX + m_PosX * Width, m_BlockTickY, m_BlockTickZ + m_PosZ * Width);
+ Handler->OnUpdate(*this, m_BlockTickX + m_PosX * Width, m_BlockTickY, m_BlockTickZ + m_PosZ * Width);
} // for i - tickblocks
}
diff --git a/src/Chunk.h b/src/Chunk.h
index 895b407a3..f13eb9a03 100644
--- a/src/Chunk.h
+++ b/src/Chunk.h
@@ -134,6 +134,9 @@ public:
void SpawnMobs(cMobSpawner& a_MobSpawner);
void Tick(float a_Dt);
+
+ /// Ticks a single block. Used by cWorld::TickQueuedBlocks() to tick the queued blocks
+ void TickBlock(int a_RelX, int a_RelY, int a_RelZ);
int GetPosX(void) const { return m_PosX; }
int GetPosY(void) const { return m_PosY; }
@@ -457,9 +460,6 @@ private:
/// Grows a melon or a pumpkin next to the block specified (assumed to be the stem)
void GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_Random);
- /// Checks if a leaves block at the specified coords has a log up to 4 blocks away connected by other leaves blocks (false if no log)
- bool HasNearLog(cBlockArea & a_Area, int a_BlockX, int a_BlockY, int a_BlockZ);
-
/// 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);
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp
index 692f97ddf..a6caa5ef7 100644
--- a/src/ChunkMap.cpp
+++ b/src/ChunkMap.cpp
@@ -2244,7 +2244,24 @@ void cChunkMap::Tick(float a_Dt)
-void cChunkMap::UnloadUnusedChunks()
+void cChunkMap::TickBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
+{
+ cCSLock Lock(m_CSLayers);
+ int ChunkX, ChunkZ;
+ cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ);
+ cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ);
+ if ((Chunk == NULL) || !Chunk->IsValid())
+ {
+ return;
+ }
+ Chunk->TickBlock(a_BlockX, a_BlockY, a_BlockZ);
+}
+
+
+
+
+
+void cChunkMap::UnloadUnusedChunks(void)
{
cCSLock Lock(m_CSLayers);
for (cChunkLayerList::iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr)
diff --git a/src/ChunkMap.h b/src/ChunkMap.h
index 2a1d78ff8..b3fe25393 100644
--- a/src/ChunkMap.h
+++ b/src/ChunkMap.h
@@ -282,6 +282,9 @@ public:
void SpawnMobs(cMobSpawner& a_MobSpawner);
void Tick(float a_Dt);
+
+ /// Ticks a single block. Used by cWorld::TickQueuedBlocks() to tick the queued blocks
+ void TickBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
void UnloadUnusedChunks(void);
void SaveAllChunks(void);
diff --git a/src/Defines.h b/src/Defines.h
index 06410cab4..a338548de 100644
--- a/src/Defines.h
+++ b/src/Defines.h
@@ -546,6 +546,32 @@ namespace ItemCategory
);
}
}
+
+
+
+
+
+/// Returns true if the biome has no downfall - deserts and savannas
+inline bool IsBiomeNoDownfall(EMCSBiome a_Biome)
+{
+ switch (a_Biome)
+ {
+ case biDesert:
+ case biDesertHills:
+ case biDesertM:
+ case biSavanna:
+ case biSavannaM:
+ case biSavannaPlateau:
+ case biSavannaPlateauM:
+ case biNether:
+ case biEnd:
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
// tolua_end
diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp
index 8b2b227a8..a0407a145 100644
--- a/src/Generating/BioGen.cpp
+++ b/src/Generating/BioGen.cpp
@@ -13,6 +13,72 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cBiomeGen:
+
+cBiomeGen * cBiomeGen::CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault)
+{
+ AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", "");
+ if (BiomeGenName.empty())
+ {
+ LOGWARN("[Generator] BiomeGen value not set in world.ini, using \"MultiStepMap\".");
+ BiomeGenName = "MultiStepMap";
+ }
+
+ cBiomeGen * res = NULL;
+ a_CacheOffByDefault = false;
+ if (NoCaseCompare(BiomeGenName, "constant") == 0)
+ {
+ res = new cBioGenConstant;
+ a_CacheOffByDefault = true; // we're generating faster than a cache would retrieve data :)
+ }
+ else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0)
+ {
+ res = new cBioGenCheckerboard;
+ a_CacheOffByDefault = true; // we're (probably) generating faster than a cache would retrieve data
+ }
+ else if (NoCaseCompare(BiomeGenName, "voronoi") == 0)
+ {
+ res = new cBioGenVoronoi(a_Seed);
+ }
+ else if (NoCaseCompare(BiomeGenName, "distortedvoronoi") == 0)
+ {
+ res = new cBioGenDistortedVoronoi(a_Seed);
+ }
+ else if (NoCaseCompare(BiomeGenName, "twolevel") == 0)
+ {
+ res = new cBioGenTwoLevel(a_Seed);
+ }
+ else
+ {
+ if (NoCaseCompare(BiomeGenName, "multistepmap") != 0)
+ {
+ LOGWARNING("Unknown BiomeGen \"%s\", using \"MultiStepMap\" instead.", BiomeGenName.c_str());
+ }
+ res = new cBioGenMultiStepMap(a_Seed);
+
+ /*
+ // Performance-testing:
+ LOGINFO("Measuring performance of cBioGenMultiStepMap...");
+ clock_t BeginTick = clock();
+ for (int x = 0; x < 5000; x++)
+ {
+ cChunkDef::BiomeMap Biomes;
+ res->GenBiomes(x * 5, x * 5, Biomes);
+ }
+ clock_t Duration = clock() - BeginTick;
+ LOGINFO("cBioGenMultiStepMap for 5000 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC);
+ //*/
+ }
+ res->InitializeBiomeGen(a_IniFile);
+
+ return res;
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cBioGenConstant:
void cBioGenConstant::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
@@ -229,11 +295,12 @@ void cBioGenCheckerboard::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::Biome
{
for (int z = 0; z < cChunkDef::Width; z++)
{
- int Base = cChunkDef::Width * a_ChunkZ + z;
+ int Base = (cChunkDef::Width * a_ChunkZ + z) / m_BiomeSize;
for (int x = 0; x < cChunkDef::Width; x++)
{
int Add = cChunkDef::Width * a_ChunkX + x;
- a_BiomeMap[x + cChunkDef::Width * z] = m_Biomes[(Base / m_BiomeSize + Add / m_BiomeSize) % m_BiomesCount];
+ int BiomeIdx = (((Base + Add / m_BiomeSize) % m_BiomesCount) + m_BiomesCount) % m_BiomesCount; // Need to add and modulo twice because of negative numbers
+ a_BiomeMap[x + cChunkDef::Width * z] = m_Biomes[BiomeIdx];
}
}
}
@@ -669,3 +736,194 @@ void cBioGenMultiStepMap::FreezeWaterBiomes(cChunkDef::BiomeMap & a_BiomeMap, co
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cBioGenTwoLevel:
+
+cBioGenTwoLevel::cBioGenTwoLevel(int a_Seed) :
+ m_VoronoiLarge(a_Seed + 1000),
+ m_VoronoiSmall(a_Seed + 2000),
+ m_DistortX(a_Seed + 3000),
+ m_DistortZ(a_Seed + 4000),
+ m_Noise(a_Seed + 5000)
+{
+}
+
+
+
+
+
+void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap)
+{
+ int BaseZ = cChunkDef::Width * a_ChunkZ;
+ int BaseX = cChunkDef::Width * a_ChunkX;
+
+ // Distortions for linear interpolation:
+ int DistortX[cChunkDef::Width + 1][cChunkDef::Width + 1];
+ int DistortZ[cChunkDef::Width + 1][cChunkDef::Width + 1];
+ for (int x = 0; x <= 4; x++) for (int z = 0; z <= 4; z++)
+ {
+ int BlockX = BaseX + x * 4;
+ int BlockZ = BaseZ + z * 4;
+ float BlockXF = (float)(16 * BlockX) / 128;
+ float BlockZF = (float)(16 * BlockZ) / 128;
+ double NoiseX = m_Noise.CubicNoise3D(BlockXF / 16, BlockZF / 16, 1000);
+ NoiseX += 0.5 * m_Noise.CubicNoise3D(BlockXF / 8, BlockZF / 8, 2000);
+ NoiseX += 0.08 * m_Noise.CubicNoise3D(BlockXF, BlockZF, 3000);
+ double NoiseZ = m_Noise.CubicNoise3D(BlockXF / 16, BlockZF / 16, 4000);
+ NoiseZ += 0.5 * m_Noise.CubicNoise3D(BlockXF / 8, BlockZF / 8, 5000);
+ NoiseZ += 0.08 * m_Noise.CubicNoise3D(BlockXF, BlockZF, 6000);
+
+ DistortX[4 * x][4 * z] = BlockX + (int)(64 * NoiseX);
+ DistortZ[4 * x][4 * z] = BlockZ + (int)(64 * NoiseZ);
+ }
+
+ LinearUpscale2DArrayInPlace(&DistortX[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4);
+ LinearUpscale2DArrayInPlace(&DistortZ[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4);
+
+ // Apply distortion to each block coord, then query the voronoi maps for biome group and biome index and choose biome based on that:
+ for (int z = 0; z < cChunkDef::Width; z++)
+ {
+ for (int x = 0; x < cChunkDef::Width; x++)
+ {
+ int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z]) / 7;
+ int MinDist1, MinDist2;
+ int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 11;
+ cChunkDef::SetBiome(a_BiomeMap, x, z, SelectBiome(BiomeGroup, BiomeIdx, (MinDist1 < MinDist2 / 4) ? 0 : 1));
+ }
+ }
+}
+
+
+
+
+
+EMCSBiome cBioGenTwoLevel::SelectBiome(int a_BiomeGroup, int a_BiomeIdx, int a_DistLevel)
+{
+ // TODO: Move this into settings
+ struct BiomeLevels
+ {
+ EMCSBiome InnerBiome;
+ EMCSBiome OuterBiome;
+ } ;
+
+ static BiomeLevels bgOcean[] =
+ {
+ { biOcean, biOcean, },
+ { biOcean, biOcean, },
+ { biOcean, biOcean, },
+ { biOcean, biOcean, },
+ { biOcean, biDeepOcean, },
+ { biOcean, biDeepOcean, },
+ { biDeepOcean, biDeepOcean, },
+ { biDeepOcean, biDeepOcean, },
+ { biDeepOcean, biDeepOcean, },
+ { biDeepOcean, biDeepOcean, },
+ { biMushroomIsland, biMushroomShore, }
+ } ;
+ static BiomeLevels bgFrozen[] =
+ {
+ { biIcePlains, biIcePlains, },
+ { biIceMountains, biIceMountains, },
+ { biFrozenOcean, biFrozenRiver, },
+ { biColdTaiga, biColdTaiga, },
+ { biColdTaigaHills, biColdTaigaHills, },
+ { biColdTaigaM, biColdTaigaM, },
+ { biIcePlainsSpikes, biIcePlainsSpikes, },
+ { biExtremeHills, biExtremeHillsEdge, },
+ { biExtremeHillsPlus, biExtremeHillsEdge, },
+ { biExtremeHillsPlusM, biExtremeHillsPlusM, },
+ } ;
+ static BiomeLevels bgTemperate[] =
+ {
+ { biBirchForestHills, biBirchForest, },
+ { biBirchForest, biBirchForest, },
+ { biBirchForestHillsM, biBirchForestM, },
+ { biBirchForestM, biBirchForestM, },
+ { biForest, biForestHills, },
+ { biFlowerForest, biFlowerForest, },
+ { biRoofedForest, biForest, },
+ { biRoofedForest, biRoofedForest, },
+ { biRoofedForestM, biForest, },
+ { biPlains, biPlains, },
+ { biSunflowerPlains, biSunflowerPlains, },
+ { biSwampland, biSwampland, },
+ { biSwamplandM, biSwamplandM, },
+ } ;
+ static BiomeLevels bgWarm[] =
+ {
+ { biDesertHills, biDesert, },
+ { biDesert, biDesert, },
+ { biDesertM, biDesertM, },
+ { biSavannaPlateau, biSavanna, },
+ { biSavanna, biSavanna, },
+ { biSavannaM, biSavannaM, },
+ } ;
+ static BiomeLevels bgMesa[] =
+ {
+ { biMesaPlateau, biMesa, },
+ { biMesaPlateauF, biMesa, },
+ { biMesaPlateauFM, biMesa, },
+ { biMesaPlateauM, biMesa, },
+ { biMesaBryce, biMesaBryce, },
+ { biSavanna, biSavanna, },
+ { biSavannaPlateau, biSavanna, },
+ } ;
+ static BiomeLevels bgConifers[] =
+ {
+ { biTaiga, biTaiga, },
+ { biTaigaM, biTaigaM, },
+ { biMegaTaiga, biMegaTaiga, },
+ { biMegaSpruceTaiga, biMegaSpruceTaiga, },
+ { biMegaSpruceTaigaHills, biMegaSpruceTaiga, }
+ } ;
+ static BiomeLevels bgDenseTrees[] =
+ {
+ { biJungleHills, biJungle, },
+ { biJungle, biJungleEdge, },
+ { biJungleM, biJungleEdgeM, },
+ } ;
+ static struct
+ {
+ BiomeLevels * Biomes;
+ size_t Count;
+ } BiomeGroups[] =
+ {
+ { bgOcean, ARRAYCOUNT(bgOcean), },
+ { bgOcean, ARRAYCOUNT(bgOcean), },
+ { bgFrozen, ARRAYCOUNT(bgFrozen), },
+ { bgFrozen, ARRAYCOUNT(bgFrozen), },
+ { bgTemperate, ARRAYCOUNT(bgTemperate), },
+ { bgTemperate, ARRAYCOUNT(bgTemperate), },
+ { bgConifers, ARRAYCOUNT(bgConifers), },
+ { bgConifers, ARRAYCOUNT(bgConifers), },
+ { bgWarm, ARRAYCOUNT(bgWarm), },
+ { bgWarm, ARRAYCOUNT(bgWarm), },
+ { bgMesa, ARRAYCOUNT(bgMesa), },
+ { bgDenseTrees, ARRAYCOUNT(bgDenseTrees), },
+ } ;
+ size_t Group = a_BiomeGroup % ARRAYCOUNT(BiomeGroups);
+ size_t Index = a_BiomeIdx % BiomeGroups[Group].Count;
+ return (a_DistLevel > 0) ? BiomeGroups[Group].Biomes[Index].InnerBiome : BiomeGroups[Group].Biomes[Index].OuterBiome;
+}
+
+
+
+
+
+void cBioGenTwoLevel::InitializeBiomeGen(cIniFile & a_IniFile)
+{
+ // TODO: Read these from a file
+ m_VoronoiLarge.SetCellSize(1024);
+ m_VoronoiSmall.SetCellSize(128);
+ m_DistortX.AddOctave(0.01f, 16);
+ m_DistortX.AddOctave(0.005f, 8);
+ m_DistortX.AddOctave(0.0025f, 4);
+ m_DistortZ.AddOctave(0.01f, 16);
+ m_DistortZ.AddOctave(0.005f, 8);
+ m_DistortZ.AddOctave(0.0025f, 4);
+}
+
+
+
+
diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h
index 892168bb6..8bd460d8f 100644
--- a/src/Generating/BioGen.h
+++ b/src/Generating/BioGen.h
@@ -239,3 +239,41 @@ protected:
+
+class cBioGenTwoLevel :
+ public cBiomeGen
+{
+ typedef cBiomeGen super;
+
+public:
+ cBioGenTwoLevel(int a_Seed);
+
+protected:
+ /// The Voronoi map that decides the groups of biomes
+ cVoronoiMap m_VoronoiLarge;
+
+ /// The Voronoi map that decides biomes inside individual biome groups
+ cVoronoiMap m_VoronoiSmall;
+
+ /// The noise used to distort the input X coord
+ cPerlinNoise m_DistortX;
+
+ /// The noise used to distort the inupt Z coord
+ cPerlinNoise m_DistortZ;
+
+ cNoise m_Noise;
+
+
+ // cBiomeGen overrides:
+ virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override;
+ virtual void InitializeBiomeGen(cIniFile & a_IniFile) override;
+
+ /// Selects biome from the specified biome group, based on the specified index.
+ /// Note that both params may overflow
+ /// a_DistLevel is either 0 or 1; zero when it is at the edge of the small Voronoi cell, 1 near the center
+ EMCSBiome SelectBiome(int a_BiomeGroup, int a_BiomeIdx, int a_DistLevel);
+} ;
+
+
+
+
diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp
index 03a65a457..f929ddc2f 100644
--- a/src/Generating/CompoGen.cpp
+++ b/src/Generating/CompoGen.cpp
@@ -250,12 +250,61 @@ void cCompoGenBiomal::ComposeTerrain(cChunkDesc & a_ChunkDesc)
case biExtremeHillsEdge:
case biJungle:
case biJungleHills:
+ case biJungleEdge:
+ case biDeepOcean:
+ case biStoneBeach:
+ case biColdBeach:
+ case biBirchForest:
+ case biBirchForestHills:
+ case biRoofedForest:
+ case biColdTaiga:
+ case biColdTaigaHills:
+ case biExtremeHillsPlus:
+ case biSavanna:
+ case biSavannaPlateau:
+ case biSunflowerPlains:
+ case biExtremeHillsM:
+ case biFlowerForest:
+ case biTaigaM:
+ case biSwamplandM:
+ case biIcePlainsSpikes:
+ case biJungleM:
+ case biJungleEdgeM:
+ case biBirchForestM:
+ case biBirchForestHillsM:
+ case biRoofedForestM:
+ case biColdTaigaM:
+ case biExtremeHillsPlusM:
+ case biSavannaM:
+ case biSavannaPlateauM:
{
FillColumnGrass(x, z, Height, a_ChunkDesc.GetBlockTypes());
break;
}
+
+ case biMesa:
+ case biMesaPlateauF:
+ case biMesaPlateau:
+ case biMesaBryce:
+ case biMesaPlateauFM:
+ case biMesaPlateauM:
+ {
+ FillColumnClay(x, z, Height, a_ChunkDesc.GetBlockTypes());
+ break;
+ }
+
+ case biMegaTaiga:
+ case biMegaTaigaHills:
+ case biMegaSpruceTaiga:
+ case biMegaSpruceTaigaHills:
+ {
+ FillColumnDirt(x, z, Height, a_ChunkDesc.GetBlockTypes());
+ break;
+ }
+
case biDesertHills:
case biDesert:
+ case biDesertM:
case biBeach:
{
FillColumnSand(x, z, Height, a_ChunkDesc.GetBlockTypes());
@@ -341,6 +390,47 @@ void cCompoGenBiomal::FillColumnGrass(int a_RelX, int a_RelZ, int a_Height, cChu
+void cCompoGenBiomal::FillColumnClay(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes)
+{
+ BLOCKTYPE Pattern[] =
+ {
+ E_BLOCK_HARDENED_CLAY,
+ E_BLOCK_HARDENED_CLAY,
+ E_BLOCK_HARDENED_CLAY,
+ E_BLOCK_HARDENED_CLAY,
+ } ;
+ FillColumnPattern(a_RelX, a_RelZ, a_Height, a_BlockTypes, Pattern, ARRAYCOUNT(Pattern));
+
+ for (int y = a_Height - ARRAYCOUNT(Pattern); y > 0; y--)
+ {
+ cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE);
+ }
+}
+
+
+
+
+
+void cCompoGenBiomal::FillColumnDirt(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes)
+{
+ for (int y = 0; y < 4; y++)
+ {
+ if (a_Height - y < 0)
+ {
+ return;
+ }
+ cChunkDef::SetBlock(a_BlockTypes, a_RelX, a_Height - y, a_RelZ, E_BLOCK_DIRT);
+ }
+ for (int y = a_Height - 4; y > 0; y--)
+ {
+ cChunkDef::SetBlock(a_BlockTypes, a_RelX, y, a_RelZ, E_BLOCK_STONE);
+ }
+}
+
+
+
+
+
void cCompoGenBiomal::FillColumnSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes)
{
BLOCKTYPE Pattern[] =
diff --git a/src/Generating/CompoGen.h b/src/Generating/CompoGen.h
index 2ee286b06..096b0fb5a 100644
--- a/src/Generating/CompoGen.h
+++ b/src/Generating/CompoGen.h
@@ -109,6 +109,8 @@ protected:
virtual void InitializeCompoGen(cIniFile & a_IniFile) override;
void FillColumnGrass (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes);
+ void FillColumnClay (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes);
+ void FillColumnDirt (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes);
void FillColumnSand (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes);
void FillColumnMycelium (int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes);
void FillColumnWaterSand(int a_RelX, int a_RelZ, int a_Height, cChunkDef::BlockTypes & a_BlockTypes);
diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp
index 01070963c..c86568c95 100644
--- a/src/Generating/ComposableGenerator.cpp
+++ b/src/Generating/ComposableGenerator.cpp
@@ -147,54 +147,8 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a
void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile)
{
- AString BiomeGenName = a_IniFile.GetValueSet("Generator", "BiomeGen", "");
- if (BiomeGenName.empty())
- {
- LOGWARN("[Generator] BiomeGen value not set in world.ini, using \"MultiStepMap\".");
- BiomeGenName = "MultiStepMap";
- }
-
- int Seed = m_ChunkGenerator.GetSeed();
bool CacheOffByDefault = false;
- if (NoCaseCompare(BiomeGenName, "constant") == 0)
- {
- m_BiomeGen = new cBioGenConstant;
- CacheOffByDefault = true; // we're generating faster than a cache would retrieve data :)
- }
- else if (NoCaseCompare(BiomeGenName, "checkerboard") == 0)
- {
- m_BiomeGen = new cBioGenCheckerboard;
- CacheOffByDefault = true; // we're (probably) generating faster than a cache would retrieve data
- }
- else if (NoCaseCompare(BiomeGenName, "voronoi") == 0)
- {
- m_BiomeGen = new cBioGenVoronoi(Seed);
- }
- else if (NoCaseCompare(BiomeGenName, "distortedvoronoi") == 0)
- {
- m_BiomeGen = new cBioGenDistortedVoronoi(Seed);
- }
- else
- {
- if (NoCaseCompare(BiomeGenName, "multistepmap") != 0)
- {
- LOGWARNING("Unknown BiomeGen \"%s\", using \"MultiStepMap\" instead.", BiomeGenName.c_str());
- }
- m_BiomeGen = new cBioGenMultiStepMap(Seed);
-
- /*
- // Performance-testing:
- LOGINFO("Measuring performance of cBioGenMultiStepMap...");
- clock_t BeginTick = clock();
- for (int x = 0; x < 5000; x++)
- {
- cChunkDef::BiomeMap Biomes;
- m_BiomeGen->GenBiomes(x * 5, x * 5, Biomes);
- }
- clock_t Duration = clock() - BeginTick;
- LOGINFO("cBioGenMultiStepMap for 5000 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC);
- //*/
- }
+ m_BiomeGen = cBiomeGen::CreateBiomeGen(a_IniFile, m_ChunkGenerator.GetSeed(), CacheOffByDefault);
// Add a cache, if requested:
int CacheSize = a_IniFile.GetValueSetI("Generator", "BiomeGenCacheSize", CacheOffByDefault ? 0 : 64);
@@ -211,7 +165,6 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile)
m_UnderlyingBiomeGen = m_BiomeGen;
m_BiomeGen = new cBioGenCache(m_UnderlyingBiomeGen, CacheSize);
}
- m_BiomeGen->InitializeBiomeGen(a_IniFile);
}
diff --git a/src/Generating/ComposableGenerator.h b/src/Generating/ComposableGenerator.h
index d5e33a439..732f64303 100644
--- a/src/Generating/ComposableGenerator.h
+++ b/src/Generating/ComposableGenerator.h
@@ -48,6 +48,13 @@ public:
/// Reads parameters from the ini file, prepares generator for use.
virtual void InitializeBiomeGen(cIniFile & a_IniFile) {}
+
+ /// Creates the correct BiomeGen descendant based on the ini file settings and the seed provided.
+ /// a_CacheOffByDefault gets set to whether the cache should be enabled by default
+ /// Used in BiomeVisualiser, too.
+ /// Implemented in BioGen.cpp!
+ static cBiomeGen * CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault);
+
} ;
diff --git a/src/Generating/DistortedHeightmap.cpp b/src/Generating/DistortedHeightmap.cpp
index 95ea812fa..a61d79bec 100644
--- a/src/Generating/DistortedHeightmap.cpp
+++ b/src/Generating/DistortedHeightmap.cpp
@@ -14,6 +14,150 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cPattern:
+
+/// This class is used to store a column pattern initialized at runtime,
+/// so that the program doesn't need to explicitly set 256 values for each pattern
+/// Each pattern has 256 blocks so that there's no need to check pattern bounds when assigning the
+/// pattern - there will always be enough pattern left, even for the whole chunk height
+class cPattern
+{
+public:
+ cPattern(cDistortedHeightmap::sBlockInfo * a_TopBlocks, size_t a_Count)
+ {
+ // Copy the pattern into the top:
+ for (size_t i = 0; i < a_Count; i++)
+ {
+ m_Pattern[i] = a_TopBlocks[i];
+ }
+
+ // Fill the rest with stone:
+ static cDistortedHeightmap::sBlockInfo Stone = {E_BLOCK_STONE, 0};
+ for (size_t i = a_Count; i < cChunkDef::Height; i++)
+ {
+ m_Pattern[i] = Stone;
+ }
+ }
+
+ const cDistortedHeightmap::sBlockInfo * Get(void) const { return m_Pattern; }
+
+protected:
+ cDistortedHeightmap::sBlockInfo m_Pattern[cChunkDef::Height];
+} ;
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// The arrays to use for the top block pattern definitions:
+
+static cDistortedHeightmap::sBlockInfo tbGrass[] =
+{
+ {E_BLOCK_GRASS, 0},
+ {E_BLOCK_DIRT, E_META_DIRT_NORMAL},
+ {E_BLOCK_DIRT, E_META_DIRT_NORMAL},
+ {E_BLOCK_DIRT, E_META_DIRT_NORMAL},
+} ;
+
+static cDistortedHeightmap::sBlockInfo tbSand[] =
+{
+ { E_BLOCK_SAND, 0},
+ { E_BLOCK_SAND, 0},
+ { E_BLOCK_SAND, 0},
+ { E_BLOCK_SANDSTONE, 0},
+} ;
+
+static cDistortedHeightmap::sBlockInfo tbDirt[] =
+{
+ {E_BLOCK_DIRT, E_META_DIRT_NORMAL},
+ {E_BLOCK_DIRT, E_META_DIRT_NORMAL},
+ {E_BLOCK_DIRT, E_META_DIRT_NORMAL},
+ {E_BLOCK_DIRT, E_META_DIRT_NORMAL},
+} ;
+
+static cDistortedHeightmap::sBlockInfo tbPodzol[] =
+{
+ {E_BLOCK_DIRT, E_META_DIRT_PODZOL},
+ {E_BLOCK_DIRT, E_META_DIRT_NORMAL},
+ {E_BLOCK_DIRT, E_META_DIRT_NORMAL},
+ {E_BLOCK_DIRT, E_META_DIRT_NORMAL},
+} ;
+
+static cDistortedHeightmap::sBlockInfo tbGrassLess[] =
+{
+ {E_BLOCK_DIRT, E_META_DIRT_GRASSLESS},
+ {E_BLOCK_DIRT, E_META_DIRT_NORMAL},
+ {E_BLOCK_DIRT, E_META_DIRT_NORMAL},
+ {E_BLOCK_DIRT, E_META_DIRT_NORMAL},
+} ;
+
+static cDistortedHeightmap::sBlockInfo tbMycelium[] =
+{
+ {E_BLOCK_MYCELIUM, 0},
+ {E_BLOCK_DIRT, 0},
+ {E_BLOCK_DIRT, 0},
+ {E_BLOCK_DIRT, 0},
+} ;
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Ocean floor pattern top-block definitions:
+
+static cDistortedHeightmap::sBlockInfo tbOFSand[] =
+{
+ {E_BLOCK_SAND, 0},
+ {E_BLOCK_SAND, 0},
+ {E_BLOCK_SAND, 0},
+ {E_BLOCK_SANDSTONE, 0}
+} ;
+
+static cDistortedHeightmap::sBlockInfo tbOFClay[] =
+{
+ { E_BLOCK_CLAY, 0},
+ { E_BLOCK_CLAY, 0},
+ { E_BLOCK_SAND, 0},
+ { E_BLOCK_SAND, 0},
+} ;
+
+static cDistortedHeightmap::sBlockInfo tbOFRedSand[] =
+{
+ { E_BLOCK_SAND, E_META_SAND_RED},
+ { E_BLOCK_SAND, E_META_SAND_RED},
+ { E_BLOCK_SAND, E_META_SAND_RED},
+ { E_BLOCK_SANDSTONE, 0},
+} ;
+
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Individual patterns to use:
+
+static cPattern patGrass (tbGrass, ARRAYCOUNT(tbGrass));
+static cPattern patSand (tbSand, ARRAYCOUNT(tbSand));
+static cPattern patDirt (tbDirt, ARRAYCOUNT(tbDirt));
+static cPattern patPodzol (tbPodzol, ARRAYCOUNT(tbPodzol));
+static cPattern patGrassLess(tbGrassLess, ARRAYCOUNT(tbGrassLess));
+static cPattern patMycelium (tbMycelium, ARRAYCOUNT(tbMycelium));
+
+static cPattern patOFSand (tbOFSand, ARRAYCOUNT(tbOFSand));
+static cPattern patOFClay (tbOFClay, ARRAYCOUNT(tbOFClay));
+static cPattern patOFRedSand(tbOFRedSand, ARRAYCOUNT(tbOFRedSand));
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cDistortedHeightmap:
+
/** This table assigns a relative maximum overhang size in each direction to biomes.
Both numbers indicate a number which will multiply the noise value for each coord;
this means that you can have different-sized overhangs in each direction.
@@ -21,7 +165,7 @@ Usually you'd want to keep both numbers the same.
The numbers are "relative", not absolute maximum; overhangs of a slightly larger size are possible
due to the way that noise is calculated.
*/
-const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[biNumBiomes] =
+const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] =
{
/* Biome | AmpX | AmpZ */
/* biOcean */ { 1.5f, 1.5f},
@@ -46,8 +190,70 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[biNumBiomes
/* biForestHills */ { 6.0f, 6.0f},
/* biTaigaHills */ { 8.0f, 8.0f},
/* biExtremeHillsEdge */ { 7.0f, 7.0f},
- /* biJungle */ { 0.0f, 0.0f},
+ /* biJungle */ { 4.0f, 4.0f},
/* biJungleHills */ { 8.0f, 8.0f},
+ /* biJungleEdge */ { 3.0f, 3.0f}, // 23
+ /* biDeepOcean */ { 1.0f, 1.0f}, // 24
+ /* biStoneBeach */ { 1.0f, 1.0f}, // 25
+ /* biColdBeach */ { 1.0f, 1.0f}, // 26
+ /* biBirchForest */ { 3.0f, 3.0f}, // 27
+ /* biBirchForestHills */ { 6.0f, 6.0f}, // 28
+ /* biRoofedForest */ { 3.0f, 3.0f}, // 29
+ /* biColdTaiga */ { 0.5f, 0.5f}, // 30
+ /* biColdTaigaHills */ { 4.0f, 4.0f}, // 31
+ /* biMegaTaiga */ { 1.0f, 1.0f}, // 32
+ /* biMegaTaigaHills */ { 4.0f, 4.0f}, // 33
+ /* biExtremeHillsPlus */ {32.0f, 32.0f}, // 34 - anyone say extreme plus? Make it extreme plus, then :)
+ /* biSavanna */ { 2.0f, 2.0f}, // 35
+ /* biSavannaPlateau */ { 3.0f, 3.0f}, // 36
+ /* biMesa */ { 2.0f, 2.0f}, // 37
+ /* biMesaPlateauF */ { 2.0f, 2.0f}, // 38
+ /* biMesaPlateau */ { 2.0f, 2.0f}, // 39
+
+ // biomes 40 .. 128 are unused, 89 empty placeholders here:
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 40 .. 49
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 50 .. 59
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 60 .. 69
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 70 .. 79
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 80 .. 89
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 90 .. 99
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 100 .. 109
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 110 .. 119
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, // 120 .. 128
+
+ // Release 1.7 /* biome variants:
+ /* biSunflowerPlains */ { 1.0f, 1.0f}, // 129
+ /* biDesertM */ { 1.0f, 1.0f}, // 130
+ /* biExtremeHillsM */ {16.0f, 16.0f}, // 131
+ /* biFlowerForest */ { 4.0f, 4.0f}, // 132
+ /* biTaigaM */ { 3.0f, 3.0f}, // 133
+ /* biSwamplandM */ { 0.0f, 0.0f}, // 134
+
+ // Biomes 135 .. 139 unused, 5 empty placeholders here:
+ {}, {}, {}, {}, {}, // 135 .. 139
+
+ /* biIcePlainsSpikes */ { 1.0f, 1.0f}, // 140
+
+ // Biomes 141 .. 148 unused, 8 empty placeholders here:
+ {}, {}, {}, {}, {}, {}, {}, {}, // 141 .. 148
+
+ /* biJungleM */ { 4.0f, 4.0f}, // 149
+ {}, // 150
+ /* biJungleEdgeM */ { 3.0f, 3.0f}, // 151
+ {}, {}, {}, // 152 .. 154
+ /* biBirchForestM */ { 3.0f, 3.0f}, // 155
+ /* biBirchForestHillsM */ { 5.0f, 5.0f}, // 156
+ /* biRoofedForestM */ { 2.0f, 2.0f}, // 157
+ /* biColdTaigaM */ { 1.0f, 1.0f}, // 158
+ {}, // 159
+ /* biMegaSpruceTaiga */ { 3.0f, 3.0f}, // 160
+ /* biMegaSpruceTaigaHills */ { 3.0f, 3.0f}, // 161
+ /* biExtremeHillsPlusM */ {32.0f, 32.0f}, // 162
+ /* biSavannaM */ { 2.0f, 2.0f}, // 163
+ /* biSavannaPlateauM */ { 3.0f, 3.0f}, // 164
+ /* biMesaBryce */ { 0.5f, 0.5f}, // 165
+ /* biMesaPlateauFM */ { 2.0f, 2.0f}, // 166
+ /* biMesaPlateauM */ { 2.0f, 2.0f}, // 167
} ;
@@ -58,9 +264,11 @@ cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGen & a_BiomeGen) :
m_NoiseDistortX(a_Seed + 1000),
m_NoiseDistortZ(a_Seed + 2000),
m_OceanFloorSelect(a_Seed + 3000),
+ m_MesaFloor(a_Seed + 4000),
m_BiomeGen(a_BiomeGen),
m_UnderlyingHeiGen(a_Seed, a_BiomeGen),
- m_HeightGen(m_UnderlyingHeiGen, 64)
+ m_HeightGen(m_UnderlyingHeiGen, 64),
+ m_IsInitialized(false)
{
m_NoiseDistortX.AddOctave((NOISE_DATATYPE)1, (NOISE_DATATYPE)0.5);
m_NoiseDistortX.AddOctave((NOISE_DATATYPE)0.5, (NOISE_DATATYPE)1);
@@ -69,6 +277,8 @@ cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGen & a_BiomeGen) :
m_NoiseDistortZ.AddOctave((NOISE_DATATYPE)1, (NOISE_DATATYPE)0.5);
m_NoiseDistortZ.AddOctave((NOISE_DATATYPE)0.5, (NOISE_DATATYPE)1);
m_NoiseDistortZ.AddOctave((NOISE_DATATYPE)0.25, (NOISE_DATATYPE)2);
+
+ InitMesaPattern(a_Seed);
}
@@ -95,6 +305,89 @@ void cDistortedHeightmap::Initialize(cIniFile & a_IniFile)
+void cDistortedHeightmap::InitMesaPattern(int a_Seed)
+{
+ // Stone in the bottom half of the pattern:
+ for (int i = cChunkDef::Height; i < 2 * cChunkDef::Height; i++)
+ {
+ m_MesaPattern[i].BlockMeta = 0;
+ m_MesaPattern[i].BlockType = E_BLOCK_STONE;
+ }
+
+ // Stained and hardened clay in the top half of the pattern
+ // In a loop, choose whether to use one or two layers of stained clay, then choose a color and width for each layer
+ // Separate each group with another layer of hardened clay
+ cNoise PatternNoise((unsigned)a_Seed);
+ static NIBBLETYPE AllowedColors[] =
+ {
+ E_META_STAINED_CLAY_YELLOW,
+ E_META_STAINED_CLAY_YELLOW,
+ E_META_STAINED_CLAY_RED,
+ E_META_STAINED_CLAY_RED,
+ E_META_STAINED_CLAY_WHITE,
+ E_META_STAINED_CLAY_BROWN,
+ E_META_STAINED_CLAY_BROWN,
+ E_META_STAINED_CLAY_BROWN,
+ E_META_STAINED_CLAY_ORANGE,
+ E_META_STAINED_CLAY_ORANGE,
+ E_META_STAINED_CLAY_ORANGE,
+ E_META_STAINED_CLAY_ORANGE,
+ E_META_STAINED_CLAY_ORANGE,
+ E_META_STAINED_CLAY_ORANGE,
+ E_META_STAINED_CLAY_LIGHTGRAY,
+ } ;
+ static int LayerSizes[] = // Adjust the chance so that thinner layers occur more commonly
+ {
+ 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2,
+ 3, 3,
+ } ;
+ int Idx = cChunkDef::Height - 1;
+ while (Idx >= 0)
+ {
+ // A layer group of 1 - 2 color stained clay:
+ int Random = PatternNoise.IntNoise1DInt(Idx) / 7;
+ int NumLayers = (Random % 2) + 1;
+ Random /= 2;
+ for (int Lay = 0; Lay < NumLayers; Lay++)
+ {
+ int NumBlocks = LayerSizes[(Random % ARRAYCOUNT(LayerSizes))];
+ NIBBLETYPE Color = AllowedColors[(Random / 4) % ARRAYCOUNT(AllowedColors)];
+ if (
+ ((NumBlocks == 3) && (NumLayers == 2)) || // In two-layer mode disallow the 3-high layers:
+ (Color == E_META_STAINED_CLAY_WHITE)) // White stained clay can ever be only 1 block high
+ {
+ NumBlocks = 1;
+ }
+ NumBlocks = std::min(Idx + 1, NumBlocks); // Limit by Idx so that we don't have to check inside the loop
+ Random /= 32;
+ for (int Block = 0; Block < NumBlocks; Block++, Idx--)
+ {
+ m_MesaPattern[Idx].BlockMeta = Color;
+ m_MesaPattern[Idx].BlockType = E_BLOCK_STAINED_CLAY;
+ } // for Block
+ } // for Lay
+
+ // A layer of hardened clay in between the layer group:
+ int NumBlocks = (Random % 4) + 1; // All heights the same probability
+ if ((NumLayers == 2) && (NumBlocks < 4))
+ {
+ // For two layers of stained clay, add an extra block of hardened clay:
+ NumBlocks++;
+ }
+ NumBlocks = std::min(Idx + 1, NumBlocks); // Limit by Idx so that we don't have to check inside the loop
+ for (int Block = 0; Block < NumBlocks; Block++, Idx--)
+ {
+ m_MesaPattern[Idx].BlockMeta = 0;
+ m_MesaPattern[Idx].BlockType = E_BLOCK_HARDENED_CLAY;
+ } // for Block
+ } // while (Idx >= 0)
+}
+
+
+
+
+
void cDistortedHeightmap::PrepareState(int a_ChunkX, int a_ChunkZ)
{
if ((m_CurChunkX == a_ChunkX) && (m_CurChunkZ == a_ChunkZ))
@@ -202,10 +495,6 @@ void cDistortedHeightmap::InitializeHeightGen(cIniFile & a_IniFile)
void cDistortedHeightmap::ComposeTerrain(cChunkDesc & a_ChunkDesc)
{
- // Frequencies for the ocean floor selecting noise:
- NOISE_DATATYPE FrequencyX = 3;
- NOISE_DATATYPE FrequencyZ = 3;
-
// Prepare the internal state for generating this chunk:
PrepareState(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ());
@@ -215,110 +504,7 @@ void cDistortedHeightmap::ComposeTerrain(cChunkDesc & a_ChunkDesc)
{
for (int x = 0; x < cChunkDef::Width; x++)
{
- int NoiseArrayIdx = x + 17 * 257 * z;
- int LastAir = a_ChunkDesc.GetHeight(x, z) + 1;
- bool HasHadWater = false;
- for (int y = LastAir - 1; y > 0; y--)
- {
- int HeightMapHeight = (int)m_DistortedHeightmap[NoiseArrayIdx + 17 * y];
-
- if (y >= HeightMapHeight)
- {
- // "air" part
- LastAir = y;
- if (y < m_SeaLevel)
- {
- a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STATIONARY_WATER);
- HasHadWater = true;
- }
- continue;
- }
- // "ground" part:
- if (y < LastAir - 4)
- {
- a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_STONE);
- continue;
- }
- if (HasHadWater)
- {
- // Decide between clay, sand and dirt
- NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + x)) / FrequencyX;
- NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + z)) / FrequencyZ;
- NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY);
- if (Val < -0.95)
- {
- // Clay:
- switch (LastAir - y)
- {
- case 0:
- case 1:
- {
- a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_CLAY);
- break;
- }
- case 2:
- case 3:
- {
- a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_SAND);
- break;
- }
- case 4:
- {
- a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_SANDSTONE);
- break;
- }
- } // switch (floor depth)
- }
- else if (Val < 0)
- {
- a_ChunkDesc.SetBlockType(x, y, z, (y < LastAir - 3) ? E_BLOCK_SANDSTONE : E_BLOCK_SAND);
- }
- else
- {
- a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_DIRT);
- }
- }
- else
- {
- switch (a_ChunkDesc.GetBiome(x, z))
- {
- case biOcean:
- case biPlains:
- case biExtremeHills:
- case biForest:
- case biTaiga:
- case biSwampland:
- case biRiver:
- case biFrozenOcean:
- case biFrozenRiver:
- case biIcePlains:
- case biIceMountains:
- case biForestHills:
- case biTaigaHills:
- case biExtremeHillsEdge:
- case biJungle:
- case biJungleHills:
- {
- a_ChunkDesc.SetBlockType(x, y, z, (y == LastAir - 1) ? E_BLOCK_GRASS : E_BLOCK_DIRT);
- break;
- }
- case biDesertHills:
- case biDesert:
- case biBeach:
- {
- a_ChunkDesc.SetBlockType(x, y, z, (y < LastAir - 3) ? E_BLOCK_SANDSTONE : E_BLOCK_SAND);
- break;
- }
- case biMushroomIsland:
- case biMushroomShore:
- {
- a_ChunkDesc.SetBlockType(x, y, z, (y == LastAir - 1) ? E_BLOCK_MYCELIUM : E_BLOCK_DIRT);
- break;
- }
- }
- }
- } // for y
- a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK);
+ ComposeColumn(a_ChunkDesc, x, z);
} // for x
} // for z
}
@@ -394,7 +580,7 @@ void cDistortedHeightmap::UpdateDistortAmps(void)
void cDistortedHeightmap::GetDistortAmpsAt(BiomeNeighbors & a_Neighbors, int a_RelX, int a_RelZ, NOISE_DATATYPE & a_DistortAmpX, NOISE_DATATYPE & a_DistortAmpZ)
{
// Sum up how many biomes of each type there are in the neighborhood:
- int BiomeCounts[biNumBiomes];
+ int BiomeCounts[256];
memset(BiomeCounts, 0, sizeof(BiomeCounts));
int Sum = 0;
for (int z = -8; z <= 8; z++)
@@ -409,10 +595,6 @@ void cDistortedHeightmap::GetDistortAmpsAt(BiomeNeighbors & a_Neighbors, int a_R
int IdxX = FinalX / cChunkDef::Width;
int ModX = FinalX % cChunkDef::Width;
EMCSBiome Biome = cChunkDef::GetBiome(a_Neighbors[IdxX][IdxZ], ModX, ModZ);
- if ((Biome < 0) || (Biome >= ARRAYCOUNT(BiomeCounts)))
- {
- continue;
- }
int WeightX = 9 - abs(x);
BiomeCounts[Biome] += WeightX + WeightZ;
Sum += WeightX + WeightZ;
@@ -432,6 +614,19 @@ void cDistortedHeightmap::GetDistortAmpsAt(BiomeNeighbors & a_Neighbors, int a_R
NOISE_DATATYPE AmpZ = 0;
for (unsigned int i = 0; i < ARRAYCOUNT(BiomeCounts); i++)
{
+ if (BiomeCounts[i] <= 0)
+ {
+ continue;
+ }
+
+ /*
+ // Sanity checks for biome parameters, enable them to check the biome param table in runtime (slow):
+ ASSERT(m_GenParam[i].m_DistortAmpX >= 0);
+ ASSERT(m_GenParam[i].m_DistortAmpX < 100);
+ ASSERT(m_GenParam[i].m_DistortAmpX >= 0);
+ ASSERT(m_GenParam[i].m_DistortAmpX < 100);
+ */
+
AmpX += BiomeCounts[i] * m_GenParam[i].m_DistortAmpX;
AmpZ += BiomeCounts[i] * m_GenParam[i].m_DistortAmpZ;
}
@@ -442,3 +637,262 @@ void cDistortedHeightmap::GetDistortAmpsAt(BiomeNeighbors & a_Neighbors, int a_R
+void cDistortedHeightmap::ComposeColumn(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ)
+{
+ // Frequencies for the podzol floor selecting noise:
+ const NOISE_DATATYPE FrequencyX = 8;
+ const NOISE_DATATYPE FrequencyZ = 8;
+
+ EMCSBiome Biome = a_ChunkDesc.GetBiome(a_RelX, a_RelZ);
+ switch (Biome)
+ {
+ case biOcean:
+ case biPlains:
+ case biExtremeHills:
+ case biForest:
+ case biTaiga:
+ case biSwampland:
+ case biRiver:
+ case biFrozenOcean:
+ case biFrozenRiver:
+ case biIcePlains:
+ case biIceMountains:
+ case biForestHills:
+ case biTaigaHills:
+ case biExtremeHillsEdge:
+ case biJungle:
+ case biJungleHills:
+ case biJungleEdge:
+ case biDeepOcean:
+ case biStoneBeach:
+ case biColdBeach:
+ case biBirchForest:
+ case biBirchForestHills:
+ case biRoofedForest:
+ case biColdTaiga:
+ case biColdTaigaHills:
+ case biExtremeHillsPlus:
+ case biSavanna:
+ case biSavannaPlateau:
+ case biSunflowerPlains:
+ case biExtremeHillsM:
+ case biFlowerForest:
+ case biTaigaM:
+ case biSwamplandM:
+ case biIcePlainsSpikes:
+ case biJungleM:
+ case biJungleEdgeM:
+ case biBirchForestM:
+ case biBirchForestHillsM:
+ case biRoofedForestM:
+ case biColdTaigaM:
+ case biExtremeHillsPlusM:
+ case biSavannaM:
+ case biSavannaPlateauM:
+ {
+ FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patGrass.Get());
+ return;
+ }
+
+ case biMegaTaiga:
+ case biMegaTaigaHills:
+ case biMegaSpruceTaiga:
+ case biMegaSpruceTaigaHills:
+ {
+ // Select the pattern to use - podzol, grass or grassless dirt:
+ NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX;
+ NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ;
+ NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY);
+ const sBlockInfo * Pattern = (Val < -0.9) ? patGrassLess.Get() : ((Val > 0) ? patPodzol.Get() : patGrass.Get());
+ FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern);
+ return;
+ }
+
+ case biDesertHills:
+ case biDesert:
+ case biDesertM:
+ case biBeach:
+ {
+ FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patSand.Get());
+ return;
+ }
+
+ case biMushroomIsland:
+ case biMushroomShore:
+ {
+ FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patMycelium.Get());
+ return;
+ }
+
+ case biMesa:
+ case biMesaPlateauF:
+ case biMesaPlateau:
+ case biMesaBryce:
+ case biMesaPlateauFM:
+ case biMesaPlateauM:
+ {
+ // Mesa biomes need special handling, because they don't follow the usual "4 blocks from top pattern",
+ // instead, they provide a "from bottom" pattern with varying base height,
+ // usually 4 blocks below the ocean level
+ FillColumnMesa(a_ChunkDesc, a_RelX, a_RelZ);
+ return;
+ }
+
+ } // switch (Biome)
+ ASSERT(!"Unhandled biome");
+}
+
+
+
+
+
+void cDistortedHeightmap::FillColumnPattern(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const sBlockInfo * a_Pattern)
+{
+ int NoiseArrayIdx = a_RelX + 17 * 257 * a_RelZ;
+ bool HasHadWater = false;
+ int PatternIdx = 0;
+ for (int y = a_ChunkDesc.GetHeight(a_RelX, a_RelZ); y > 0; y--)
+ {
+ int HeightMapHeight = (int)m_DistortedHeightmap[NoiseArrayIdx + 17 * y];
+
+ if (y < HeightMapHeight)
+ {
+ // "ground" part, use the pattern:
+ a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, a_Pattern[PatternIdx].BlockType, a_Pattern[PatternIdx].BlockMeta);
+ PatternIdx++;
+ continue;
+ }
+
+ // "air" or "water" part:
+ // Reset the pattern index to zero, so that the pattern is repeated from the top again:
+ PatternIdx = 0;
+
+ if (y >= m_SeaLevel)
+ {
+ // "air" part, do nothing
+ continue;
+ }
+
+ a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER);
+ if (HasHadWater)
+ {
+ continue;
+ }
+
+ // Select the ocean-floor pattern to use:
+ a_Pattern = ChooseOceanFloorPattern(a_RelX, a_RelZ);
+ HasHadWater = true;
+ } // for y
+ a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);
+}
+
+
+
+
+
+void cDistortedHeightmap::FillColumnMesa(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ)
+{
+ // Frequencies for the clay floor noise:
+ const NOISE_DATATYPE FrequencyX = 50;
+ const NOISE_DATATYPE FrequencyZ = 50;
+
+ int Top = a_ChunkDesc.GetHeight(a_RelX, a_RelZ);
+ if (Top < m_SeaLevel)
+ {
+ // The terrain is below sealevel, handle as regular ocean:
+ FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patOFRedSand.Get());
+ return;
+ }
+
+ NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX;
+ NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ;
+ int ClayFloor = m_SeaLevel - 6 + (int)(4.f * m_MesaFloor.CubicNoise2D(NoiseX, NoiseY));
+ if (ClayFloor >= Top)
+ {
+ ClayFloor = Top - 1;
+ }
+
+ if (Top - m_SeaLevel < 5)
+ {
+ // Simple case: top is red sand, then hardened clay down to ClayFloor, then stone:
+ a_ChunkDesc.SetBlockTypeMeta(a_RelX, Top, a_RelZ, E_BLOCK_SAND, E_META_SAND_RED);
+ for (int y = Top - 1; y >= ClayFloor; y--)
+ {
+ a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_HARDENED_CLAY);
+ }
+ for (int y = ClayFloor - 1; y > 0; y--)
+ {
+ a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STONE);
+ }
+ a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);
+ return;
+ }
+
+ // Difficult case: use the mesa pattern and watch for overhangs:
+ int NoiseArrayIdx = a_RelX + 17 * 257 * a_RelZ;
+ int PatternIdx = cChunkDef::Height - (Top - ClayFloor); // We want the block at index ClayFloor to be pattern's 256th block (first stone)
+ const sBlockInfo * Pattern = m_MesaPattern;
+ bool HasHadWater = false;
+ for (int y = Top; y > 0; y--)
+ {
+ int HeightMapHeight = (int)m_DistortedHeightmap[NoiseArrayIdx + 17 * y];
+ if (y < HeightMapHeight)
+ {
+ // "ground" part, use the pattern:
+ a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, Pattern[PatternIdx].BlockType, Pattern[PatternIdx].BlockMeta);
+ PatternIdx++;
+ continue;
+ }
+
+ if (y >= m_SeaLevel)
+ {
+ // "air" part, do nothing
+ continue;
+ }
+
+ // "water" part, fill with water and choose new pattern for ocean floor, if not chosen already:
+ PatternIdx = 0;
+ a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER);
+ if (HasHadWater)
+ {
+ continue;
+ }
+
+ // Select the ocean-floor pattern to use:
+ Pattern = ChooseOceanFloorPattern(a_RelX, a_RelZ);
+ HasHadWater = true;
+ } // for y
+ a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);
+}
+
+
+
+
+
+const cDistortedHeightmap::sBlockInfo * cDistortedHeightmap::ChooseOceanFloorPattern(int a_RelX, int a_RelZ)
+{
+ // Frequencies for the ocean floor selecting noise:
+ const NOISE_DATATYPE FrequencyX = 3;
+ const NOISE_DATATYPE FrequencyZ = 3;
+
+ // Select the ocean-floor pattern to use:
+ NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(m_CurChunkX * cChunkDef::Width + a_RelX)) / FrequencyX;
+ NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(m_CurChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ;
+ NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY);
+ if (Val < -0.95)
+ {
+ return patOFClay.Get();
+ }
+ else if (Val < 0)
+ {
+ return patOFSand.Get();
+ }
+ else
+ {
+ return patDirt.Get();
+ }
+}
+
+
+
+
diff --git a/src/Generating/DistortedHeightmap.h b/src/Generating/DistortedHeightmap.h
index 6d7007375..e6b3c9d3f 100644
--- a/src/Generating/DistortedHeightmap.h
+++ b/src/Generating/DistortedHeightmap.h
@@ -28,6 +28,13 @@ class cDistortedHeightmap :
public cTerrainCompositionGen
{
public:
+ /// Structure used for storing block patterns for columns
+ struct sBlockInfo
+ {
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ } ;
+
cDistortedHeightmap(int a_Seed, cBiomeGen & a_BiomeGen);
protected:
@@ -46,6 +53,7 @@ protected:
cPerlinNoise m_NoiseDistortX;
cPerlinNoise m_NoiseDistortZ;
cNoise m_OceanFloorSelect; ///< Used for selecting between dirt and sand on the ocean floor
+ cNoise m_MesaFloor; ///< Used for the floor of the clay blocks in mesa biomes
int m_SeaLevel;
NOISE_DATATYPE m_FrequencyX;
@@ -69,7 +77,7 @@ protected:
NOISE_DATATYPE m_DistortAmpX;
NOISE_DATATYPE m_DistortAmpZ;
} ;
- static const sGenParam m_GenParam[biNumBiomes];
+ static const sGenParam m_GenParam[256];
// Distortion amplitudes for each direction, before linear upscaling
NOISE_DATATYPE m_DistortAmpX[DIM_X * DIM_Z];
@@ -78,7 +86,14 @@ protected:
/// True if Initialize() has been called. Used to initialize-once even with multiple init entrypoints (HeiGen / CompoGen)
bool m_IsInitialized;
+ /// The vertical pattern to be used for mesa biomes. Seed-dependant.
+ /// One Height of pattern and one Height of stone to avoid checking pattern dimensions
+ sBlockInfo m_MesaPattern[2 * cChunkDef::Height];
+
+ /// Initializes m_MesaPattern with a reasonable pattern of stained clay / hardened clay, based on the seed
+ void InitMesaPattern(int a_Seed);
+
/// Unless the LastChunk coords are equal to coords given, prepares the internal state (noise arrays, heightmap)
void PrepareState(int a_ChunkX, int a_ChunkZ);
@@ -97,6 +112,19 @@ protected:
/// Reads the settings from the ini file. Skips reading if already initialized
void Initialize(cIniFile & a_IniFile);
+ /// Composes a single column in a_ChunkDesc. Chooses what to do based on the biome in that column
+ void ComposeColumn(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ);
+
+ /// Fills the specified column with the specified pattern; restarts the pattern when air is reached,
+ /// switches to ocean floor pattern if ocean is reached. Always adds bedrock at the very bottom.
+ void FillColumnPattern(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const sBlockInfo * a_Pattern);
+
+ /// Fills the specified column with mesa pattern, based on the column height
+ void FillColumnMesa(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ);
+
+ /// Returns the pattern to use for an ocean floor in the specified column
+ const sBlockInfo * ChooseOceanFloorPattern(int a_RelX, int a_RelZ);
+
// cTerrainHeightGen overrides:
virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp
index 8aab3fe15..ea6051371 100644
--- a/src/Generating/HeiGen.cpp
+++ b/src/Generating/HeiGen.cpp
@@ -229,33 +229,94 @@ void cHeiGenClassic::InitializeHeightGen(cIniFile & a_IniFile)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cHeiGenBiomal:
-const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[biNumBiomes] =
+const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[256] =
{
/* Fast-changing | Middle-changing | Slow-changing |*/
/* Biome | Freq1 | Amp1 | Freq2 | Amp2 | Freq3 | Amp3 | BaseHeight */
- /* biOcean */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40},
- /* biPlains */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68},
- /* biDesert */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68},
- /* biExtremeHills */ { 0.2f, 4.0f, 0.05f, 20.0f, 0.01f, 16.0f, 100},
- /* biForest */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70},
- /* biTaiga */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70},
- /* biSwampland */ { 0.1f, 1.1f, 0.05f, 1.5f, 0.02f, 2.5f, 61.5},
- /* biRiver */ { 0.2f, 0.1f, 0.05f, 0.1f, 0.01f, 0.1f, 56},
- /* biNether */ { 0.1f, 0.0f, 0.01f, 0.0f, 0.01f, 0.0f, 0}, // Unused, but must be here due to indexing
- /* biSky */ { 0.1f, 0.0f, 0.01f, 0.0f, 0.01f, 0.0f, 0}, // Unused, but must be here due to indexing
- /* biFrozenOcean */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40},
- /* biFrozenRiver */ { 0.2f, 0.1f, 0.05f, 0.1f, 0.01f, 0.1f, 56},
- /* biIcePlains */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68},
- /* biIceMountains */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80},
- /* biMushroomIsland */ { 0.1f, 2.0f, 0.05f, 8.0f, 0.01f, 6.0f, 80},
- /* biMushroomShore */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 64},
- /* biBeach */ { 0.1f, 0.5f, 0.05f, 1.0f, 0.01f, 1.0f, 64},
- /* biDesertHills */ { 0.2f, 2.0f, 0.05f, 5.0f, 0.01f, 4.0f, 75},
- /* biForestHills */ { 0.2f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80},
- /* biTaigaHills */ { 0.2f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80},
- /* biExtremeHillsEdge */ { 0.2f, 3.0f, 0.05f, 16.0f, 0.01f, 12.0f, 80},
- /* biJungle */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70},
- /* biJungleHills */ { 0.2f, 3.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80},
+ /* biOcean */ { 0.1f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 50},
+ /* biPlains */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68},
+ /* biDesert */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68},
+ /* biExtremeHills */ { 0.2f, 4.0f, 0.05f, 20.0f, 0.01f, 16.0f, 100},
+ /* biForest */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70},
+ /* biTaiga */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70},
+ /* biSwampland */ { 0.1f, 1.1f, 0.05f, 1.5f, 0.02f, 2.5f, 61.5},
+ /* biRiver */ { 0.2f, 0.1f, 0.05f, 0.1f, 0.01f, 0.1f, 56},
+ /* biNether */ { 0.1f, 0.0f, 0.01f, 0.0f, 0.01f, 0.0f, 0}, // Unused, but must be here due to indexing
+ /* biSky */ { 0.1f, 0.0f, 0.01f, 0.0f, 0.01f, 0.0f, 0}, // Unused, but must be here due to indexing
+ /* biFrozenOcean */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40},
+ /* biFrozenRiver */ { 0.2f, 0.1f, 0.05f, 0.1f, 0.01f, 0.1f, 56},
+ /* biIcePlains */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68},
+ /* biIceMountains */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80},
+ /* biMushroomIsland */ { 0.1f, 2.0f, 0.05f, 8.0f, 0.01f, 6.0f, 80},
+ /* biMushroomShore */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 64},
+ /* biBeach */ { 0.1f, 0.5f, 0.05f, 1.0f, 0.01f, 1.0f, 64},
+ /* biDesertHills */ { 0.2f, 2.0f, 0.05f, 5.0f, 0.01f, 4.0f, 75},
+ /* biForestHills */ { 0.2f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80},
+ /* biTaigaHills */ { 0.2f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80},
+ /* biExtremeHillsEdge */ { 0.2f, 3.0f, 0.05f, 16.0f, 0.01f, 12.0f, 80},
+ /* biJungle */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70},
+ /* biJungleHills */ { 0.2f, 3.0f, 0.05f, 12.0f, 0.01f, 10.0f, 80},
+ /* biJungleEdge */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70},
+ /* biDeepOcean */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40},
+ /* biStoneBeach */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40},
+ /* biColdBeach */ { 0.1f, 0.5f, 0.05f, 1.0f, 0.01f, 1.0f, 64},
+ /* biBirchForest */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70},
+ /* biBirchForestHills */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80},
+ /* biRoofedForest */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70},
+ /* biColdTaiga */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70},
+ /* biColdTaigaHills */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80},
+ /* biMegaTaiga */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70},
+ /* biMegaTaigaHills */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80},
+ /* biExtremeHillsPlus */ { 0.2f, 4.0f, 0.05f, 20.0f, 0.01f, 16.0f, 120},
+ /* biSavanna */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68},
+ /* biSavannaPlateau */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 80},
+ /* biMesa */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 70}, // 165
+ /* biMesaPlateauF */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 80},
+ /* biMesaPlateau */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 80},
+
+ // biomes 40 .. 128 are unused, 89 empty placeholders here:
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 40 .. 49
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 50 .. 59
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 60 .. 69
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 70 .. 79
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 80 .. 89
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 90 .. 99
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 100 .. 109
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 110 .. 119
+ {}, {}, {}, {}, {}, {}, {}, {}, {}, // 120 .. 128
+
+ /* biSunflowerPlains */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 129
+ /* biDesertM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 130
+ /* biExtremeHillsM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 131
+ /* biFlowerForest */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 132
+ /* biTaigaM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 133
+ /* biSwamplandM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 134
+
+ // Biomes 135 .. 139 unused, 5 empty placeholders here:
+ {}, {}, {}, {}, {}, // 135 .. 139
+
+ /* biIcePlainsSpikes */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 140
+
+ // Biomes 141 .. 148 unused, 8 empty placeholders here:
+ {}, {}, {}, {}, {}, {}, {}, {}, // 141 .. 148
+
+ /* biJungleM */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // 149
+ {}, // 150
+ /* biJungleEdgeM */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // 151
+ {}, {}, {}, // 152 .. 154
+ /* biBirchForestM */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // 155
+ /* biBirchForestHillsM */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80}, // 156
+ /* biRoofedForestM */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // 157
+ /* biColdTaigaM */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // 158
+ {}, // 159
+ /* biMegaSpruceTaiga */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // 160
+ /* biMegaSpruceTaigaHills */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80}, // 161
+ /* biExtremeHillsPlusM */ { 0.2f, 4.0f, 0.05f, 20.0f, 0.01f, 16.0f, 120}, // 162
+ /* biSavannaM */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 68}, // 163
+ /* biSavannaPlateauM */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 80}, // 164
+ /* biMesaBryce */ { 0.2f, 2.0f, 0.1f, 30.0f, 0.01f, 8.0f, 80},
+ /* biMesaPlateauFM */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 80}, // 166
+ /* biMesaPlateauM */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 80}, // 167
} ;
@@ -333,7 +394,7 @@ void cHeiGenBiomal::InitializeHeightGen(cIniFile & a_IniFile)
NOISE_DATATYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, int a_ChunkZ, const cHeiGenBiomal::BiomeNeighbors & a_BiomeNeighbors)
{
// Sum up how many biomes of each type there are in the neighborhood:
- int BiomeCounts[biNumBiomes];
+ int BiomeCounts[256];
memset(BiomeCounts, 0, sizeof(BiomeCounts));
int Sum = 0;
for (int z = -8; z <= 8; z++)
@@ -348,10 +409,6 @@ NOISE_DATATYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX,
int IdxX = FinalX / cChunkDef::Width;
int ModX = FinalX % cChunkDef::Width;
EMCSBiome Biome = cChunkDef::GetBiome(a_BiomeNeighbors[IdxX][IdxZ], ModX, ModZ);
- if ((Biome < 0) || (Biome >= ARRAYCOUNT(BiomeCounts)))
- {
- continue;
- }
int WeightX = 9 - abs(x);
BiomeCounts[Biome] += WeightX + WeightZ;
Sum += WeightX + WeightZ;
@@ -370,6 +427,17 @@ NOISE_DATATYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX,
{
continue;
}
+
+ /*
+ // Sanity checks for biome parameters, enable them to check the biome param table in runtime (slow):
+ ASSERT(m_GenParam[i].m_HeightFreq1 >= 0);
+ ASSERT(m_GenParam[i].m_HeightFreq1 < 1000);
+ ASSERT(m_GenParam[i].m_HeightFreq2 >= 0);
+ ASSERT(m_GenParam[i].m_HeightFreq2 < 1000);
+ ASSERT(m_GenParam[i].m_HeightFreq3 >= 0);
+ ASSERT(m_GenParam[i].m_HeightFreq3 < 1000);
+ */
+
NOISE_DATATYPE oct1 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq1, BlockZ * m_GenParam[i].m_HeightFreq1) * m_GenParam[i].m_HeightAmp1;
NOISE_DATATYPE oct2 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq2, BlockZ * m_GenParam[i].m_HeightFreq2) * m_GenParam[i].m_HeightAmp2;
NOISE_DATATYPE oct3 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq3, BlockZ * m_GenParam[i].m_HeightFreq3) * m_GenParam[i].m_HeightAmp3;
diff --git a/src/Generating/HeiGen.h b/src/Generating/HeiGen.h
index 1b246c70a..1376f2a25 100644
--- a/src/Generating/HeiGen.h
+++ b/src/Generating/HeiGen.h
@@ -131,7 +131,7 @@ protected:
float m_HeightFreq3, m_HeightAmp3;
float m_BaseHeight;
} ;
- static const sGenParam m_GenParam[biNumBiomes];
+ static const sGenParam m_GenParam[256];
// cTerrainHeightGen overrides:
virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp
index 2180261aa..504c26238 100644
--- a/src/Generating/StructGen.cpp
+++ b/src/Generating/StructGen.cpp
@@ -260,20 +260,57 @@ int cStructGenTrees::GetNumTrees(
int Add = 0;
switch (cChunkDef::GetBiome(a_Biomes, x, z))
{
- case biPlains: Add = 1; break;
- case biExtremeHills: Add = 3; break;
- case biForest: Add = 30; break;
- case biTaiga: Add = 30; break;
- case biSwampland: Add = 8; break;
- case biIcePlains: Add = 1; break;
- case biIceMountains: Add = 1; break;
- case biMushroomIsland: Add = 3; break;
- case biMushroomShore: Add = 3; break;
- case biForestHills: Add = 20; break;
- case biTaigaHills: Add = 20; break;
- case biExtremeHillsEdge: Add = 5; break;
- case biJungle: Add = 120; break;
- case biJungleHills: Add = 90; break;
+ case biOcean: Add = 2; break;
+ case biDesert: Add = 0; break;
+ case biPlains: Add = 1; break;
+ case biExtremeHills: Add = 3; break;
+ case biForest: Add = 30; break;
+ case biTaiga: Add = 30; break;
+ case biSwampland: Add = 8; break;
+ case biIcePlains: Add = 1; break;
+ case biIceMountains: Add = 1; break;
+ case biMushroomIsland: Add = 3; break;
+ case biMushroomShore: Add = 3; break;
+ case biForestHills: Add = 20; break;
+ case biTaigaHills: Add = 20; break;
+ case biExtremeHillsEdge: Add = 5; break;
+ case biJungle: Add = 120; break;
+ case biJungleHills: Add = 90; break;
+ case biJungleEdge: Add = 90; break;
+ case biBirchForest: Add = 30; break;
+ case biBirchForestHills: Add = 20; break;
+ case biRoofedForest: Add = 50; break;
+ case biColdTaiga: Add = 20; break;
+ case biColdTaigaHills: Add = 15; break;
+ case biMegaTaiga: Add = 30; break;
+ case biMegaTaigaHills: Add = 25; break;
+ case biExtremeHillsPlus: Add = 3; break;
+ case biSavanna: Add = 8; break;
+ case biSavannaPlateau: Add = 12; break;
+ case biMesa: Add = 2; break;
+ case biMesaPlateauF: Add = 8; break;
+ case biMesaPlateau: Add = 8; break;
+ case biSunflowerPlains: Add = 1; break;
+ case biDesertM: Add = 0; break;
+ case biExtremeHillsM: Add = 4; break;
+ case biFlowerForest: Add = 30; break;
+ case biTaigaM: Add = 30; break;
+ case biSwamplandM: Add = 8; break;
+ case biIcePlainsSpikes: Add = 1; break;
+ case biJungleM: Add = 120; break;
+ case biJungleEdgeM: Add = 90; break;
+ case biBirchForestM: Add = 30; break;
+ case biBirchForestHillsM: Add = 20; break;
+ case biRoofedForestM: Add = 40; break;
+ case biColdTaigaM: Add = 30; break;
+ case biMegaSpruceTaiga: Add = 30; break;
+ case biMegaSpruceTaigaHills: Add = 30; break;
+ case biExtremeHillsPlusM: Add = 4; break;
+ case biSavannaM: Add = 8; break;
+ case biSavannaPlateauM: Add = 12; break;
+ case biMesaBryce: Add = 4; break;
+ case biMesaPlateauFM: Add = 12; break;
+ case biMesaPlateauM: Add = 12; break;
}
NumTrees += Add;
}
diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp
index 7ca30c60f..fbed57cb6 100644
--- a/src/Generating/Trees.cpp
+++ b/src/Generating/Trees.cpp
@@ -161,6 +161,9 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No
case biMushroomIsland:
case biMushroomShore:
case biForestHills:
+ case biDeepOcean:
+ case biStoneBeach:
+ case biColdBeach:
{
// Apple or birch trees:
if (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + 16 * a_Seq, a_BlockZ + 16 * a_Seq) < 0x5fffffff)
@@ -193,6 +196,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No
case biJungle:
case biJungleHills:
+ case biJungleEdge:
{
// Apple bushes, large jungle trees, small jungle trees
if (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + 16 * a_Seq, a_BlockZ + 16 * a_Seq) < 0x6fffffff)
@@ -203,6 +207,52 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No
{
GetJungleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
}
+ break;
+ }
+
+ case biBirchForest:
+ case biBirchForestHills:
+ {
+ GetBirchTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
+ break;
+ }
+
+ case biRoofedForest:
+ case biColdTaiga:
+ case biColdTaigaHills:
+ case biMegaTaiga:
+ case biMegaTaigaHills:
+ case biExtremeHillsPlus:
+ case biSavanna:
+ case biSavannaPlateau:
+ case biMesa:
+ case biMesaPlateauF:
+ case biMesaPlateau:
+ case biSunflowerPlains:
+ case biDesertM:
+ case biExtremeHillsM:
+ case biFlowerForest:
+ case biTaigaM:
+ case biSwamplandM:
+ case biIcePlainsSpikes:
+ case biJungleM:
+ case biJungleEdgeM:
+ case biBirchForestM:
+ case biBirchForestHillsM:
+ case biRoofedForestM:
+ case biColdTaigaM:
+ case biMegaSpruceTaiga:
+ case biMegaSpruceTaigaHills:
+ case biExtremeHillsPlusM:
+ case biSavannaM:
+ case biSavannaPlateauM:
+ case biMesaBryce:
+ case biMesaPlateauFM:
+ case biMesaPlateauM:
+ {
+ // TODO: These need their special trees
+ GetBirchTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
+ break;
}
}
}
diff --git a/src/LuaState.h b/src/LuaState.h
index 5e7f3d180..15b0cdeff 100644
--- a/src/LuaState.h
+++ b/src/LuaState.h
@@ -224,6 +224,22 @@ public:
return CallFunction(0);
}
+ /// Call any 3-param 0-return Lua function in a single line:
+ template<
+ typename FnT, typename ArgT1, typename ArgT2, typename ArgT3
+ >
+ bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3)
+ {
+ if (!PushFunction(a_FnName))
+ {
+ return false;
+ }
+ Push(a_Arg1);
+ Push(a_Arg2);
+ Push(a_Arg3);
+ return CallFunction(0);
+ }
+
/// Call any 1-param 1-return Lua function in a single line:
template<
typename FnT, typename ArgT1, typename RetT1
diff --git a/src/Plugin.h b/src/Plugin.h
index 06e5819df..ec55e256d 100644
--- a/src/Plugin.h
+++ b/src/Plugin.h
@@ -94,7 +94,7 @@ public:
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) = 0;
virtual bool OnWeatherChanged (cWorld & a_World) = 0;
virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) = 0;
- virtual bool OnWorldTick (cWorld & a_World, float a_Dt) = 0;
+ virtual bool OnWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) = 0;
/** Handles the command split into a_Split, issued by player a_Player.
Command permissions have already been checked.
diff --git a/src/PluginLua.cpp b/src/PluginLua.cpp
index 4ddf191ac..110010087 100644
--- a/src/PluginLua.cpp
+++ b/src/PluginLua.cpp
@@ -1143,13 +1143,13 @@ bool cPluginLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather)
-bool cPluginLua::OnWorldTick(cWorld & a_World, float a_Dt)
+bool cPluginLua::OnWorldTick(cWorld & a_World, float a_Dt, int a_LastTickDurationMSec)
{
cCSLock Lock(m_CriticalSection);
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_WORLD_TICK];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{
- m_LuaState.Call((int)(**itr), &a_World, a_Dt);
+ m_LuaState.Call((int)(**itr), &a_World, a_Dt, a_LastTickDurationMSec);
}
return false;
}
diff --git a/src/PluginLua.h b/src/PluginLua.h
index 908466966..6d135ab75 100644
--- a/src/PluginLua.h
+++ b/src/PluginLua.h
@@ -90,7 +90,7 @@ public:
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) override;
virtual bool OnWeatherChanged (cWorld & a_World) override;
virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) override;
- virtual bool OnWorldTick (cWorld & a_World, float a_Dt) override;
+ virtual bool OnWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) override;
virtual bool HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) override;
diff --git a/src/PluginManager.cpp b/src/PluginManager.cpp
index bb6f2a24b..b57a9d7d8 100644
--- a/src/PluginManager.cpp
+++ b/src/PluginManager.cpp
@@ -1210,7 +1210,7 @@ bool cPluginManager::CallHookWeatherChanging(cWorld & a_World, eWeather & a_NewW
-bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt)
+bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt, int a_LastTickDurationMSec)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_WORLD_TICK);
if (Plugins == m_Hooks.end())
@@ -1219,7 +1219,7 @@ bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt)
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
- if ((*itr)->OnWorldTick(a_World, a_Dt))
+ if ((*itr)->OnWorldTick(a_World, a_Dt, a_LastTickDurationMSec))
{
return true;
}
diff --git a/src/PluginManager.h b/src/PluginManager.h
index 4140bffb5..12e4da71b 100644
--- a/src/PluginManager.h
+++ b/src/PluginManager.h
@@ -191,7 +191,7 @@ public: // tolua_export
bool CallHookUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player);
bool CallHookWeatherChanged (cWorld & a_World);
bool CallHookWeatherChanging (cWorld & a_World, eWeather & a_NewWeather);
- bool CallHookWorldTick (cWorld & a_World, float a_Dt);
+ bool CallHookWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec);
bool DisablePlugin(const AString & a_PluginName); // tolua_export
bool LoadPlugin (const AString & a_PluginName); // tolua_export
diff --git a/src/World.cpp b/src/World.cpp
index 8ef4dc0f3..bed5d6701 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -197,20 +197,21 @@ void cWorld::cTickThread::Execute(void)
{
cTimer Timer;
- long long msPerTick = 50;
- long long LastTime = Timer.GetNowTime();
+ const Int64 msPerTick = 50;
+ Int64 LastTime = Timer.GetNowTime();
+ Int64 TickDuration = 50;
while (!m_ShouldTerminate)
{
- long long NowTime = Timer.GetNowTime();
+ Int64 NowTime = Timer.GetNowTime();
float DeltaTime = (float)(NowTime - LastTime);
- m_World.Tick(DeltaTime);
- long long TickTime = Timer.GetNowTime() - NowTime;
+ m_World.Tick(DeltaTime, (int)TickDuration);
+ TickDuration = Timer.GetNowTime() - NowTime;
- if (TickTime < msPerTick)
+ if (TickDuration < msPerTick)
{
// Stretch tick time until it's at least msPerTick
- cSleep::MilliSleep((unsigned int)(msPerTick - TickTime));
+ cSleep::MilliSleep((unsigned int)(msPerTick - TickDuration));
}
LastTime = NowTime;
@@ -485,30 +486,21 @@ void cWorld::Start(void)
}
} // switch (m_Dimension)
- // Try to find the "SpawnPosition" key in the world configuration
- // Set a boolean value if so
+ // Try to find the "SpawnPosition" key and coord values in the world configuration, set the flag if found
int KeyNum = IniFile.FindKey("SpawnPosition");
- unsigned int NumSpawnPositionKeys = ((KeyNum != -1) ? (IniFile.GetNumValues(KeyNum)) : 0);
-
- if (NumSpawnPositionKeys > 0)
- {
- for (unsigned int i = 0; i < NumSpawnPositionKeys; i++)
- {
- AString ValueName = IniFile.GetValueName(KeyNum, i);
- if (
- (ValueName.compare("X") == 0) ||
- (ValueName.compare("Y") == 0) ||
- (ValueName.compare("Z") == 0)
- )
- {
- m_bSpawnExplicitlySet = true;
- LOGD("Spawnpoint explicitly set!");
- }
- }
- }
+ m_bSpawnExplicitlySet =
+ (
+ (KeyNum >= 0) &&
+ (
+ (IniFile.FindValue(KeyNum, "X") >= 0) ||
+ (IniFile.FindValue(KeyNum, "Y") >= 0) ||
+ (IniFile.FindValue(KeyNum, "Z") >= 0)
+ )
+ );
if (m_bSpawnExplicitlySet)
{
+ LOGD("Spawnpoint explicitly set!");
m_SpawnX = IniFile.GetValueF("SpawnPosition", "X", m_SpawnX);
m_SpawnY = IniFile.GetValueF("SpawnPosition", "Y", m_SpawnY);
m_SpawnZ = IniFile.GetValueF("SpawnPosition", "Z", m_SpawnZ);
@@ -660,10 +652,10 @@ void cWorld::Stop(void)
-void cWorld::Tick(float a_Dt)
+void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec)
{
// Call the plugins
- cPluginManager::Get()->CallHookWorldTick(*this, a_Dt);
+ cPluginManager::Get()->CallHookWorldTick(*this, a_Dt, a_LastTickDurationMSec);
// We need sub-tick precision here, that's why we store the time in seconds and calculate ticks off of it
m_WorldAgeSecs += (double)a_Dt / 1000.0;
@@ -2604,12 +2596,12 @@ void cWorld::TickQueuedBlocks(void)
for (std::vector<BlockTickQueueItem *>::iterator itr = m_BlockTickQueueCopy.begin(); itr != m_BlockTickQueueCopy.end(); itr++)
{
- BlockTickQueueItem *Block = (*itr);
+ BlockTickQueueItem * Block = (*itr);
Block->TicksToWait -= 1;
if (Block->TicksToWait <= 0)
{
// TODO: Handle the case when the chunk is already unloaded
- BlockHandler(GetBlock(Block->X, Block->Y, Block->Z))->OnUpdate(this, Block->X, Block->Y, Block->Z);
+ m_ChunkMap->TickBlock(Block->X, Block->Y, Block->Z);
delete Block; // We don't have to remove it from the vector, this will happen automatically on the next tick
}
else
diff --git a/src/World.h b/src/World.h
index 958fc4255..a6b61f2e2 100644
--- a/src/World.h
+++ b/src/World.h
@@ -729,7 +729,7 @@ private:
cWorld(const AString & a_WorldName);
~cWorld();
- void Tick(float a_Dt);
+ void Tick(float a_Dt, int a_LastTickDurationMSec);
/// Handles the weather in each tick
void TickWeather(float a_Dt);
diff --git a/src/WorldStorage/WSSCompact.h b/src/WorldStorage/WSSCompact.h
index e6a013eaf..a75c41ccb 100644
--- a/src/WorldStorage/WSSCompact.h
+++ b/src/WorldStorage/WSSCompact.h
@@ -13,6 +13,7 @@
#include "WorldStorage.h"
#include "../Vector3i.h"
+#include "json/json.h"
diff --git a/src/WorldStorage/WorldStorage.h b/src/WorldStorage/WorldStorage.h
index 98e7e1686..007d37571 100644
--- a/src/WorldStorage/WorldStorage.h
+++ b/src/WorldStorage/WorldStorage.h
@@ -16,7 +16,6 @@
#include "../ChunkDef.h"
#include "../OSSupport/IsThread.h"
-#include "json/json.h"