summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Bindings/LuaChunkStay.cpp2
-rw-r--r--src/Bindings/LuaFunctions.h4
-rw-r--r--src/Bindings/ManualBindings.cpp40
-rw-r--r--src/Bindings/Plugin.h2
-rw-r--r--src/Bindings/PluginLua.cpp4
-rw-r--r--src/Bindings/PluginLua.h2
-rw-r--r--src/Bindings/PluginManager.cpp13
-rw-r--r--src/Bindings/PluginManager.h4
-rw-r--r--src/BlockArea.cpp14
-rw-r--r--src/BlockInfo.cpp10
-rw-r--r--src/Blocks/BlockAnvil.h7
-rw-r--r--src/Blocks/BlockBed.h7
-rw-r--r--src/Blocks/BlockDirt.h8
-rw-r--r--src/Blocks/BlockFarmland.h4
-rw-r--r--src/Blocks/BlockFire.h19
-rw-r--r--src/Blocks/BlockFluid.h6
-rw-r--r--src/Blocks/BlockHandler.cpp9
-rw-r--r--src/Blocks/BlockHandler.h3
-rw-r--r--src/Blocks/BlockLeaves.h6
-rw-r--r--src/Blocks/BlockPortal.h14
-rw-r--r--src/Blocks/BlockSlab.h6
-rw-r--r--src/Blocks/BlockStairs.h5
-rw-r--r--src/Chunk.cpp24
-rw-r--r--src/Chunk.h9
-rw-r--r--src/ChunkMap.cpp2
-rw-r--r--src/ClientHandle.cpp37
-rw-r--r--src/ClientHandle.h3
-rw-r--r--src/CraftingRecipes.cpp4
-rw-r--r--src/DeadlockDetect.cpp2
-rw-r--r--src/Enchantments.cpp9
-rw-r--r--src/Enchantments.h3
-rw-r--r--src/Entities/ArrowEntity.cpp1
-rw-r--r--src/Entities/Entity.cpp183
-rw-r--r--src/Entities/Entity.h35
-rw-r--r--src/Entities/ExpOrb.cpp2
-rw-r--r--src/Entities/FallingBlock.cpp5
-rw-r--r--src/Entities/Player.cpp30
-rw-r--r--src/Entities/Player.h3
-rw-r--r--src/Entities/TNTEntity.cpp2
-rw-r--r--src/Generating/Caves.cpp247
-rw-r--r--src/Generating/Caves.h22
-rw-r--r--src/Generating/GridStructGen.cpp126
-rw-r--r--src/Generating/GridStructGen.h124
-rw-r--r--src/Generating/MineShafts.cpp167
-rw-r--r--src/Generating/MineShafts.h34
-rw-r--r--src/Generating/NetherFortGen.cpp229
-rw-r--r--src/Generating/NetherFortGen.h61
-rw-r--r--src/Generating/PieceGenerator.cpp9
-rw-r--r--src/Generating/PieceGenerator.h3
-rw-r--r--src/Generating/Prefab.cpp63
-rw-r--r--src/Generating/PrefabPiecePool.cpp121
-rw-r--r--src/Generating/PrefabPiecePool.h79
-rw-r--r--src/Generating/Prefabs/NetherFortPrefabs.cpp153
-rw-r--r--src/Generating/Ravines.cpp211
-rw-r--r--src/Generating/Ravines.h24
-rw-r--r--src/Generating/Trees.cpp2
-rw-r--r--src/GroupManager.cpp35
-rw-r--r--src/HTTPServer/NameValueParser.cpp2
-rw-r--r--src/Inventory.cpp1
-rw-r--r--src/Item.cpp4
-rw-r--r--src/Item.h22
-rw-r--r--src/Items/ItemArmor.h43
-rw-r--r--src/Items/ItemHandler.cpp10
-rw-r--r--src/Items/ItemHandler.h3
-rw-r--r--src/Items/ItemLilypad.h14
-rw-r--r--src/Items/ItemMinecart.h2
-rw-r--r--src/Items/ItemPickaxe.h14
-rw-r--r--src/Items/ItemShovel.h14
-rw-r--r--src/Items/ItemSpawnEgg.h40
-rw-r--r--src/Items/ItemSword.h13
-rw-r--r--src/Items/ItemThrowable.h17
-rw-r--r--src/LightingThread.cpp2
-rw-r--r--src/Map.cpp2
-rw-r--r--src/Map.h2
-rw-r--r--src/MapManager.cpp6
-rw-r--r--src/MapManager.h2
-rw-r--r--src/MobCensus.cpp2
-rw-r--r--src/MobFamilyCollecter.cpp2
-rw-r--r--src/MobSpawner.cpp6
-rw-r--r--src/Mobs/AggressiveMonster.cpp5
-rw-r--r--src/Mobs/Monster.cpp4
-rw-r--r--src/Noise.cpp2
-rw-r--r--src/OSSupport/File.cpp4
-rw-r--r--src/OSSupport/ListenThread.cpp2
-rw-r--r--src/OSSupport/Socket.cpp8
-rw-r--r--src/OSSupport/Socket.h4
-rw-r--r--src/OSSupport/SocketThreads.cpp2
-rw-r--r--src/ProbabDistrib.cpp2
-rw-r--r--src/Protocol/Authenticator.cpp2
-rw-r--r--src/Protocol/Protocol17x.cpp29
-rw-r--r--src/Protocol/Protocol17x.h2
-rw-r--r--src/Protocol/ProtocolRecognizer.cpp4
-rw-r--r--src/RCONServer.cpp2
-rw-r--r--src/Root.cpp14
-rw-r--r--src/Scoreboard.cpp6
-rw-r--r--src/Scoreboard.h6
-rw-r--r--src/Simulator/DelayedFluidSimulator.cpp2
-rw-r--r--src/Simulator/FloodyFluidSimulator.cpp4
-rw-r--r--src/Simulator/FloodyFluidSimulator.h13
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator.cpp969
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator.h68
-rw-r--r--src/Simulator/SandSimulator.cpp6
-rw-r--r--src/Simulator/VanillaFluidSimulator.cpp10
-rw-r--r--src/Simulator/VanillaFluidSimulator.h2
-rw-r--r--src/StringCompression.cpp14
-rw-r--r--src/StringCompression.h4
-rw-r--r--src/StringUtils.cpp24
-rw-r--r--src/StringUtils.h4
-rw-r--r--src/Tracer.cpp6
-rw-r--r--src/UI/SlotArea.cpp407
-rw-r--r--src/UI/SlotArea.h38
-rw-r--r--src/UI/Window.cpp47
-rw-r--r--src/UI/Window.h29
-rw-r--r--src/Vector3.h55
-rw-r--r--src/World.cpp15
-rw-r--r--src/World.h6
-rw-r--r--src/WorldStorage/FastNBT.cpp42
-rw-r--r--src/WorldStorage/FastNBT.h22
-rw-r--r--src/WorldStorage/FireworksSerializer.cpp8
-rw-r--r--src/WorldStorage/MapSerializer.cpp8
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp39
-rw-r--r--src/WorldStorage/SchematicFileSerializer.cpp10
-rw-r--r--src/WorldStorage/WSSAnvil.cpp64
-rw-r--r--src/WorldStorage/WSSAnvil.h4
-rw-r--r--src/WorldStorage/WSSCompact.cpp24
125 files changed, 2692 insertions, 1826 deletions
diff --git a/src/Bindings/LuaChunkStay.cpp b/src/Bindings/LuaChunkStay.cpp
index db865cfa4..985a18a95 100644
--- a/src/Bindings/LuaChunkStay.cpp
+++ b/src/Bindings/LuaChunkStay.cpp
@@ -42,7 +42,7 @@ bool cLuaChunkStay::AddChunks(int a_ChunkCoordTableStackPos)
// Add each set of coords:
int NumChunks = luaL_getn(L, a_ChunkCoordTableStackPos);
- m_Chunks.reserve(NumChunks);
+ m_Chunks.reserve((size_t)NumChunks);
for (int idx = 1; idx <= NumChunks; idx++)
{
// Push the idx-th element of the array onto stack top, check that it's a table:
diff --git a/src/Bindings/LuaFunctions.h b/src/Bindings/LuaFunctions.h
index 4f9eab86d..629e2d77d 100644
--- a/src/Bindings/LuaFunctions.h
+++ b/src/Bindings/LuaFunctions.h
@@ -4,12 +4,12 @@
#include <time.h>
// tolua_begin
-unsigned int GetTime()
+inline unsigned int GetTime()
{
return (unsigned int)time(0);
}
-std::string GetChar( std::string & a_Str, unsigned int a_Idx )
+inline std::string GetChar( std::string & a_Str, unsigned int a_Idx )
{
return std::string(1, a_Str[ a_Idx ]);
}
diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp
index b3f75aff1..10e560ac0 100644
--- a/src/Bindings/ManualBindings.cpp
+++ b/src/Bindings/ManualBindings.cpp
@@ -37,7 +37,7 @@
/****************************
* Better error reporting for Lua
**/
-int tolua_do_error(lua_State* L, const char * a_pMsg, tolua_Error * a_pToLuaError)
+static int tolua_do_error(lua_State* L, const char * a_pMsg, tolua_Error * a_pToLuaError)
{
// Retrieve current function name
lua_Debug entry;
@@ -57,7 +57,7 @@ int tolua_do_error(lua_State* L, const char * a_pMsg, tolua_Error * a_pToLuaErro
-int lua_do_error(lua_State* L, const char * a_pFormat, ...)
+static int lua_do_error(lua_State* L, const char * a_pFormat, ...)
{
// Retrieve current function name
lua_Debug entry;
@@ -235,7 +235,7 @@ static int tolua_Base64Decode(lua_State * tolua_S)
-cPluginLua * GetLuaPlugin(lua_State * L)
+static cPluginLua * GetLuaPlugin(lua_State * L)
{
// Get the plugin identification out of LuaState:
lua_getglobal(L, LUA_PLUGIN_INSTANCE_VAR_NAME);
@@ -1776,20 +1776,20 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S)
-static int tolua_cPlayer_GetGroups(lua_State* tolua_S)
+static int tolua_cPlayer_GetGroups(lua_State * tolua_S)
{
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S, 1, NULL);
+ cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, NULL);
const cPlayer::GroupList & AllGroups = self->GetGroups();
- lua_createtable(tolua_S, AllGroups.size(), 0);
+ lua_createtable(tolua_S, (int)AllGroups.size(), 0);
int newTable = lua_gettop(tolua_S);
int index = 1;
cPlayer::GroupList::const_iterator iter = AllGroups.begin();
- while(iter != AllGroups.end())
+ while (iter != AllGroups.end())
{
- const cGroup* Group = *iter;
- tolua_pushusertype( tolua_S, (void*)Group, "const cGroup" );
+ const cGroup * Group = *iter;
+ tolua_pushusertype(tolua_S, (void *)Group, "const cGroup");
lua_rawseti(tolua_S, newTable, index);
++iter;
++index;
@@ -1801,20 +1801,20 @@ static int tolua_cPlayer_GetGroups(lua_State* tolua_S)
-static int tolua_cPlayer_GetResolvedPermissions(lua_State* tolua_S)
+static int tolua_cPlayer_GetResolvedPermissions(lua_State * tolua_S)
{
- cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S, 1, NULL);
+ cPlayer * self = (cPlayer*) tolua_tousertype(tolua_S, 1, NULL);
cPlayer::StringList AllPermissions = self->GetResolvedPermissions();
- lua_createtable(tolua_S, AllPermissions.size(), 0);
+ lua_createtable(tolua_S, (int)AllPermissions.size(), 0);
int newTable = lua_gettop(tolua_S);
int index = 1;
cPlayer::StringList::iterator iter = AllPermissions.begin();
- while(iter != AllPermissions.end())
+ while (iter != AllPermissions.end())
{
- std::string& Permission = *iter;
- tolua_pushstring( tolua_S, Permission.c_str() );
+ std::string & Permission = *iter;
+ lua_pushlstring(tolua_S, Permission.c_str(), Permission.length());
lua_rawseti(tolua_S, newTable, index);
++iter;
++index;
@@ -2076,18 +2076,18 @@ static int tolua_get_HTTPRequest_FormData(lua_State* tolua_S)
static int tolua_cWebAdmin_GetPlugins(lua_State * tolua_S)
{
- cWebAdmin* self = (cWebAdmin*) tolua_tousertype(tolua_S, 1, NULL);
+ cWebAdmin * self = (cWebAdmin *)tolua_tousertype(tolua_S, 1, NULL);
const cWebAdmin::PluginList & AllPlugins = self->GetPlugins();
- lua_createtable(tolua_S, AllPlugins.size(), 0);
+ lua_createtable(tolua_S, (int)AllPlugins.size(), 0);
int newTable = lua_gettop(tolua_S);
int index = 1;
cWebAdmin::PluginList::const_iterator iter = AllPlugins.begin();
- while(iter != AllPlugins.end())
+ while (iter != AllPlugins.end())
{
- const cWebPlugin* Plugin = *iter;
- tolua_pushusertype( tolua_S, (void*)Plugin, "const cWebPlugin" );
+ const cWebPlugin * Plugin = *iter;
+ tolua_pushusertype(tolua_S, (void *)Plugin, "const cWebPlugin");
lua_rawseti(tolua_S, newTable, index);
++iter;
++index;
diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h
index df0bd4dcc..0bd9270c4 100644
--- a/src/Bindings/Plugin.h
+++ b/src/Bindings/Plugin.h
@@ -56,7 +56,7 @@ public:
virtual bool OnChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ) = 0;
virtual bool OnCollectingPickup (cPlayer * a_Player, cPickup * a_Pickup) = 0;
virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0;
- virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason) = 0;
+ virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) = 0;
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) = 0;
virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0;
virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0;
diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp
index cb55715a6..59708bf59 100644
--- a/src/Bindings/PluginLua.cpp
+++ b/src/Bindings/PluginLua.cpp
@@ -400,14 +400,14 @@ bool cPluginLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGri
-bool cPluginLua::OnDisconnect(cPlayer * a_Player, const AString & a_Reason)
+bool cPluginLua::OnDisconnect(cClientHandle & a_Client, const AString & a_Reason)
{
cCSLock Lock(m_CriticalSection);
bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_DISCONNECT];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{
- m_LuaState.Call((int)(**itr), a_Player, a_Reason, cLuaState::Return, res);
+ m_LuaState.Call((int)(**itr), &a_Client, a_Reason, cLuaState::Return, res);
if (res)
{
return true;
diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h
index 59542d23a..3357dd87b 100644
--- a/src/Bindings/PluginLua.h
+++ b/src/Bindings/PluginLua.h
@@ -79,7 +79,7 @@ public:
virtual bool OnChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override;
virtual bool OnCollectingPickup (cPlayer * a_Player, cPickup * a_Pickup) override;
virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
- virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason) override;
+ virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) override;
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) override;
virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override;
virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override;
diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp
index 6a5356c0b..fc690d4de 100644
--- a/src/Bindings/PluginManager.cpp
+++ b/src/Bindings/PluginManager.cpp
@@ -143,13 +143,14 @@ void cPluginManager::ReloadPluginsNow(cIniFile & a_SettingsIni)
}
}
- if (GetNumPlugins() == 0)
+ size_t NumLoadedPlugins = GetNumPlugins();
+ if (NumLoadedPlugins == 0)
{
LOG("-- No Plugins Loaded --");
}
- else if (GetNumPlugins() > 1)
+ else if (NumLoadedPlugins > 1)
{
- LOG("-- Loaded %i Plugins --", GetNumPlugins());
+ LOG("-- Loaded %i Plugins --", (int)NumLoadedPlugins);
}
else
{
@@ -442,7 +443,7 @@ bool cPluginManager::CallHookCraftingNoRecipe(const cPlayer * a_Player, const cC
-bool cPluginManager::CallHookDisconnect(cPlayer * a_Player, const AString & a_Reason)
+bool cPluginManager::CallHookDisconnect(cClientHandle & a_Client, const AString & a_Reason)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_DISCONNECT);
if (Plugins == m_Hooks.end())
@@ -451,7 +452,7 @@ bool cPluginManager::CallHookDisconnect(cPlayer * a_Player, const AString & a_Re
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
- if ((*itr)->OnDisconnect(a_Player, a_Reason))
+ if ((*itr)->OnDisconnect(a_Client, a_Reason))
{
return true;
}
@@ -1869,7 +1870,7 @@ void cPluginManager::AddHook(cPlugin * a_Plugin, int a_Hook)
-unsigned int cPluginManager::GetNumPlugins() const
+size_t cPluginManager::GetNumPlugins() const
{
return m_Plugins.size();
}
diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h
index 512bc1351..3b3091957 100644
--- a/src/Bindings/PluginManager.h
+++ b/src/Bindings/PluginManager.h
@@ -159,7 +159,7 @@ public: // tolua_export
/** Adds the plugin to the list of plugins called for the specified hook type. Handles multiple adds as a single add */
void AddHook(cPlugin * a_Plugin, int a_HookType);
- unsigned int GetNumPlugins() const; // tolua_export
+ size_t GetNumPlugins() const; // tolua_export
// Calls for individual hooks. Each returns false if the action is to continue or true if the plugin wants to abort
bool CallHookBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source);
@@ -172,7 +172,7 @@ public: // tolua_export
bool CallHookChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ);
bool CallHookCollectingPickup (cPlayer * a_Player, cPickup & a_Pickup);
bool CallHookCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
- bool CallHookDisconnect (cPlayer * a_Player, const AString & a_Reason);
+ bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason);
bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split); // If a_Player == NULL, it is a console cmd
bool CallHookExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData);
bool CallHookExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData);
diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp
index e0ae2c5b6..9e20a0983 100644
--- a/src/BlockArea.cpp
+++ b/src/BlockArea.cpp
@@ -707,11 +707,11 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R
if (IsDummyMetas)
{
- MergeByStrategy<true>(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas);
+ MergeByStrategy<false>(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas);
}
else
{
- MergeByStrategy<false>(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas);
+ MergeByStrategy<true>(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas);
}
}
@@ -738,31 +738,31 @@ void cBlockArea::Fill(int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_Block
a_DataTypes = a_DataTypes & GetDataTypes();
}
- int BlockCount = GetBlockCount();
+ size_t BlockCount = GetBlockCount();
if ((a_DataTypes & baTypes) != 0)
{
- for (int i = 0; i < BlockCount; i++)
+ for (size_t i = 0; i < BlockCount; i++)
{
m_BlockTypes[i] = a_BlockType;
}
}
if ((a_DataTypes & baMetas) != 0)
{
- for (int i = 0; i < BlockCount; i++)
+ for (size_t i = 0; i < BlockCount; i++)
{
m_BlockMetas[i] = a_BlockMeta;
}
}
if ((a_DataTypes & baLight) != 0)
{
- for (int i = 0; i < BlockCount; i++)
+ for (size_t i = 0; i < BlockCount; i++)
{
m_BlockLight[i] = a_BlockLight;
}
}
if ((a_DataTypes & baSkyLight) != 0)
{
- for (int i = 0; i < BlockCount; i++)
+ for (size_t i = 0; i < BlockCount; i++)
{
m_BlockSkyLight[i] = a_BlockSkyLight;
}
diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp
index def98fdf5..e8d9a7ec4 100644
--- a/src/BlockInfo.cpp
+++ b/src/BlockInfo.cpp
@@ -110,10 +110,13 @@ void cBlockInfo::Initialize(void)
// Transparent blocks
ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_Transparent = true;
ms_Info[E_BLOCK_AIR ].m_Transparent = true;
+ ms_Info[E_BLOCK_ANVIL ].m_Transparent = true;
ms_Info[E_BLOCK_BIG_FLOWER ].m_Transparent = true;
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_Transparent = true;
+ ms_Info[E_BLOCK_CAKE ].m_Transparent = true;
ms_Info[E_BLOCK_CARROTS ].m_Transparent = true;
ms_Info[E_BLOCK_CHEST ].m_Transparent = true;
+ ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_Transparent = true;
ms_Info[E_BLOCK_COBWEB ].m_Transparent = true;
ms_Info[E_BLOCK_CROPS ].m_Transparent = true;
ms_Info[E_BLOCK_DANDELION ].m_Transparent = true;
@@ -126,6 +129,7 @@ void cBlockInfo::Initialize(void)
ms_Info[E_BLOCK_FLOWER_POT ].m_Transparent = true;
ms_Info[E_BLOCK_GLASS ].m_Transparent = true;
ms_Info[E_BLOCK_GLASS_PANE ].m_Transparent = true;
+ ms_Info[E_BLOCK_HEAD ].m_Transparent = true;
ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_Transparent = true;
ms_Info[E_BLOCK_ICE ].m_Transparent = true;
ms_Info[E_BLOCK_IRON_DOOR ].m_Transparent = true;
@@ -196,12 +200,14 @@ void cBlockInfo::Initialize(void)
ms_Info[E_BLOCK_BED ].m_PistonBreakable = true;
ms_Info[E_BLOCK_BIG_FLOWER ].m_PistonBreakable = true;
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_PistonBreakable = true;
+ ms_Info[E_BLOCK_CAKE ].m_PistonBreakable = true;
ms_Info[E_BLOCK_COBWEB ].m_PistonBreakable = true;
ms_Info[E_BLOCK_CROPS ].m_PistonBreakable = true;
ms_Info[E_BLOCK_DANDELION ].m_PistonBreakable = true;
ms_Info[E_BLOCK_DEAD_BUSH ].m_PistonBreakable = true;
ms_Info[E_BLOCK_FIRE ].m_PistonBreakable = true;
ms_Info[E_BLOCK_FLOWER ].m_PistonBreakable = true;
+ ms_Info[E_BLOCK_HEAD ].m_PistonBreakable = true;
ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true;
ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PistonBreakable = true;
ms_Info[E_BLOCK_IRON_DOOR ].m_PistonBreakable = true;
@@ -243,6 +249,7 @@ void cBlockInfo::Initialize(void)
ms_Info[E_BLOCK_CACTUS ].m_IsSnowable = false;
ms_Info[E_BLOCK_CHEST ].m_IsSnowable = false;
ms_Info[E_BLOCK_CROPS ].m_IsSnowable = false;
+ ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_IsSnowable = false;
ms_Info[E_BLOCK_DANDELION ].m_IsSnowable = false;
ms_Info[E_BLOCK_FIRE ].m_IsSnowable = false;
ms_Info[E_BLOCK_FLOWER ].m_IsSnowable = false;
@@ -276,6 +283,7 @@ void cBlockInfo::Initialize(void)
ms_Info[E_BLOCK_POWERED_RAIL ].m_IsSnowable = false;
ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSnowable = false;
ms_Info[E_BLOCK_COBWEB ].m_IsSnowable = false;
+ ms_Info[E_BLOCK_HEAD ].m_IsSnowable = false;
// Blocks that don't drop without a special tool:
@@ -283,6 +291,7 @@ void cBlockInfo::Initialize(void)
ms_Info[E_BLOCK_CAULDRON ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_COAL_ORE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_COBBLESTONE ].m_RequiresSpecialTool = true;
+ ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_COBBLESTONE_STAIRS ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_COBWEB ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_DIAMOND_BLOCK ].m_RequiresSpecialTool = true;
@@ -325,6 +334,7 @@ void cBlockInfo::Initialize(void)
ms_Info[E_BLOCK_AIR ].m_IsSolid = false;
ms_Info[E_BLOCK_BIG_FLOWER ].m_IsSolid = false;
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSolid = false;
+ ms_Info[E_BLOCK_CAKE ].m_IsSolid = false;
ms_Info[E_BLOCK_CARROTS ].m_IsSolid = false;
ms_Info[E_BLOCK_COBWEB ].m_IsSolid = false;
ms_Info[E_BLOCK_CROPS ].m_IsSolid = false;
diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h
index 93a796ef7..35a356678 100644
--- a/src/Blocks/BlockAnvil.h
+++ b/src/Blocks/BlockAnvil.h
@@ -23,6 +23,13 @@ public:
{
a_Pickups.push_back(cItem(E_BLOCK_ANVIL, 1, a_BlockMeta >> 2));
}
+
+
+ virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
+ {
+ cWindow * Window = new cAnvilWindow(a_BlockX, a_BlockY, a_BlockZ);
+ a_Player->OpenWindow(Window);
+ }
virtual bool GetPlacementBlockTypeMeta(
diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h
index 92804aaac..51e79b888 100644
--- a/src/Blocks/BlockBed.h
+++ b/src/Blocks/BlockBed.h
@@ -39,6 +39,13 @@ public:
}
+ virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override
+ {
+ return true;
+ }
+
+
+
// Bed specific helper functions
static NIBBLETYPE RotationToMetaData(double a_Rotation)
{
diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h
index aa24b8668..2d4fccbac 100644
--- a/src/Blocks/BlockDirt.h
+++ b/src/Blocks/BlockDirt.h
@@ -35,8 +35,10 @@ public:
// Grass becomes dirt if there is something on top of it:
if (a_RelY < cChunkDef::Height - 1)
{
- BLOCKTYPE Above = a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ);
- if ((!cBlockInfo::IsTransparent(Above) && !cBlockInfo::IsOneHitDig(Above)) || IsBlockWater(Above))
+ BLOCKTYPE Above;
+ NIBBLETYPE AboveMeta;
+ a_Chunk.GetBlockTypeMeta(a_RelX, a_RelY + 1, a_RelZ, Above, AboveMeta);
+ if (!cBlockInfo::GetHandler(Above)->CanDirtGrowGrass(AboveMeta))
{
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, E_META_DIRT_NORMAL);
return;
@@ -77,7 +79,7 @@ public:
BLOCKTYPE AboveDest;
NIBBLETYPE AboveMeta;
Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta);
- if ((cBlockInfo::IsOneHitDig(AboveDest) || cBlockInfo::IsTransparent(AboveDest)) && !IsBlockWater(AboveDest))
+ if (cBlockInfo::GetHandler(AboveDest)->CanDirtGrowGrass(AboveMeta))
{
if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, BlockX * cChunkDef::Width, BlockY, BlockZ * cChunkDef::Width, ssGrassSpread))
{
diff --git a/src/Blocks/BlockFarmland.h b/src/Blocks/BlockFarmland.h
index b720ccd14..3dd5bcd1d 100644
--- a/src/Blocks/BlockFarmland.h
+++ b/src/Blocks/BlockFarmland.h
@@ -52,9 +52,9 @@ public:
return;
}
- int NumBlocks = Area.GetBlockCount();
+ size_t NumBlocks = Area.GetBlockCount();
BLOCKTYPE * BlockTypes = Area.GetBlockTypes();
- for (int i = 0; i < NumBlocks; i++)
+ for (size_t i = 0; i < NumBlocks; i++)
{
if (
(BlockTypes[i] == E_BLOCK_WATER) ||
diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h
index c8f158e7e..f9f32eb50 100644
--- a/src/Blocks/BlockFire.h
+++ b/src/Blocks/BlockFire.h
@@ -68,7 +68,6 @@ public:
{
return 0;
}
-
for (int newY = Y + 1; newY < cChunkDef::Height; newY++)
{
@@ -84,7 +83,7 @@ public:
// This is because the frame is a solid obsidian pillar
if ((MaxY != 0) && (newY == Y + 1))
{
- return EvaluatePortalBorder(X, newY, Z, MaxY, a_ChunkInterface);
+ return EvaluatePortalBorder(X, newY, Z, MaxY, a_ChunkInterface) ? -1 /* -1 = found a frame */ : 0;
}
else
{
@@ -99,18 +98,18 @@ public:
}
/// Evaluates if coords have a valid border on top, based on MaxY
- int EvaluatePortalBorder(int X, int FoundObsidianY, int Z, int MaxY, cChunkInterface & a_ChunkInterface)
+ bool EvaluatePortalBorder(int X, int FoundObsidianY, int Z, int MaxY, cChunkInterface & a_ChunkInterface)
{
for (int checkBorder = FoundObsidianY + 1; checkBorder <= MaxY - 1; checkBorder++) // FoundObsidianY + 1: FoundObsidianY has already been checked in FindObsidianCeiling; MaxY - 1: portal doesn't need corners
{
if (a_ChunkInterface.GetBlock(X, checkBorder, Z) != E_BLOCK_OBSIDIAN)
{
// Base obsidian, base + 1 obsidian, base + x NOT obsidian -> not complete portal
- return 0;
+ return false;
}
}
// Everything was obsidian, found a border!
- return -1; // Return -1 for a frame border
+ return true;
}
/// Finds entire frame in any direction with the coordinates of a base block and fills hole with nether portal (START HERE)
@@ -169,7 +168,7 @@ public:
{
return false; // Not valid slice, no portal can be formed
}
- } XZP = X1 - 1; // Set boundary of frame interior, note that for some reason, the loop of X and the loop of Z go to different numbers, hence -1 here and -2 there
+ } XZP = X1 - 1; // Set boundary of frame interior
for (; ((a_ChunkInterface.GetBlock(X2, Y, Z) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock(X2, Y + 1, Z) == E_BLOCK_OBSIDIAN)); X2--) // Go the other direction (XM)
{
int Value = FindObsidianCeiling(X2, Y, Z, a_ChunkInterface, MaxY);
@@ -199,13 +198,13 @@ public:
if ((Value == -1) || (ValueTwo == -1))
{
FoundFrameZP = true;
- continue;
+ break;
}
else if ((Value != MaxY) && (ValueTwo != MaxY))
{
return false;
}
- } XZP = Z1 - 2;
+ } XZP = Z1 - 1;
for (; ((a_ChunkInterface.GetBlock(X, Y, Z2) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock(X, Y + 1, Z2) == E_BLOCK_OBSIDIAN)); Z2--)
{
int Value = FindObsidianCeiling(X, Y, Z2, a_ChunkInterface, MaxY);
@@ -213,13 +212,13 @@ public:
if ((Value == -1) || (ValueTwo == -1))
{
FoundFrameZM = true;
- continue;
+ break;
}
else if ((Value != MaxY) && (ValueTwo != MaxY))
{
return false;
}
- } XZM = Z2 + 2;
+ } XZM = Z2 + 1;
return (FoundFrameZP && FoundFrameZM);
}
};
diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h
index d486d642d..d0c4ea55b 100644
--- a/src/Blocks/BlockFluid.h
+++ b/src/Blocks/BlockFluid.h
@@ -49,6 +49,12 @@ public:
}
super::Check(a_ChunkInterface, a_PluginInterface, a_RelX, a_RelY, a_RelZ, a_Chunk);
}
+
+
+ virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override
+ {
+ return false;
+ }
} ;
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index a764c6f44..304e35e84 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -400,6 +400,15 @@ bool cBlockHandler::CanBeAt(cChunkInterface & a_ChunkInterface, int a_BlockX, in
+bool cBlockHandler::CanDirtGrowGrass(NIBBLETYPE a_Meta)
+{
+ return ((cBlockInfo::IsTransparent(m_BlockType)) || (cBlockInfo::IsOneHitDig(m_BlockType)));
+}
+
+
+
+
+
bool cBlockHandler::IsUseable()
{
return false;
diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h
index 3a3efb3cc..fb6cae729 100644
--- a/src/Blocks/BlockHandler.h
+++ b/src/Blocks/BlockHandler.h
@@ -85,6 +85,9 @@ public:
/// Checks if the block can stay at the specified relative coords in the chunk
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk);
+
+ /** Can the dirt under this block grow to grass? */
+ virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta);
/** Checks if the block can be placed at this point.
Default: CanBeAt(...)
diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h
index d21227b07..495e849fa 100644
--- a/src/Blocks/BlockLeaves.h
+++ b/src/Blocks/BlockLeaves.h
@@ -138,14 +138,14 @@ bool HasNearLog(cBlockArea & a_Area, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Filter the blocks into a {leaves, log, other (air)} set:
BLOCKTYPE * Types = a_Area.GetBlockTypes();
- for (int i = a_Area.GetBlockCount() - 1; i > 0; i--)
+ for (size_t i = a_Area.GetBlockCount() - 1; i > 0; i--)
{
switch (Types[i])
{
- case E_BLOCK_NEW_LEAVES:
- case E_BLOCK_NEW_LOG:
case E_BLOCK_LEAVES:
case E_BLOCK_LOG:
+ case E_BLOCK_NEW_LEAVES:
+ case E_BLOCK_NEW_LOG:
{
break;
}
diff --git a/src/Blocks/BlockPortal.h b/src/Blocks/BlockPortal.h
index 21bcbdeea..3b8030028 100644
--- a/src/Blocks/BlockPortal.h
+++ b/src/Blocks/BlockPortal.h
@@ -2,6 +2,7 @@
#pragma once
#include "BlockHandler.h"
+#include "../Mobs/Monster.h"
@@ -38,6 +39,19 @@ public:
return; // No pickups
}
+ virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
+ {
+ cFastRandom Random;
+ if (Random.NextInt(2000) != 0)
+ {
+ return;
+ }
+
+ int PosX = a_Chunk.GetPosX() * 16 + a_RelX;
+ int PosZ = a_Chunk.GetPosZ() * 16 + a_RelZ;
+
+ a_WorldInterface.SpawnMob(PosX, a_RelY, PosZ, cMonster::mtZombiePigman);
+ }
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h
index 76f5ed0e7..80841b094 100644
--- a/src/Blocks/BlockSlab.h
+++ b/src/Blocks/BlockSlab.h
@@ -97,6 +97,12 @@ public:
return "";
}
+
+ virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override
+ {
+ return ((a_Meta & 0x8) != 0);
+ }
+
/// Returns true if the specified blocktype is one of the slabs handled by this handler
static bool IsAnySlabType(BLOCKTYPE a_BlockType)
diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h
index 09ff254a6..a49fda5ae 100644
--- a/src/Blocks/BlockStairs.h
+++ b/src/Blocks/BlockStairs.h
@@ -77,6 +77,11 @@ public:
// Reset meta to 0
a_Pickups.push_back(cItem(m_BlockType, 1, 0));
}
+
+ virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override
+ {
+ return true;
+ }
static NIBBLETYPE RotationToMetaData(double a_Rotation)
{
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index cd3bceda2..ca536e89a 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -380,12 +380,12 @@ void cChunk::SetLight(
{ // Compress blocklight
m_BlockLight.clear();
- m_BlockLight.insert(m_BlockLight.end(), &a_BlockLight[0], &a_BlockLight[m_BlockTypes.size()]);
+ m_BlockLight.insert(m_BlockLight.end(), &a_BlockLight[0], &a_BlockLight[m_BlockTypes.size() / 2]);
}
{ // Compress skylight
m_BlockSkyLight.clear();
- m_BlockSkyLight.insert(m_BlockSkyLight.end(), &a_SkyLight[0], &a_SkyLight[m_BlockTypes.size()]);
+ m_BlockSkyLight.insert(m_BlockSkyLight.end(), &a_SkyLight[0], &a_SkyLight[m_BlockTypes.size() / 2]);
}
m_IsLightValid = true;
@@ -749,7 +749,7 @@ void cChunk::ProcessQueuedSetBlocks(void)
{
if (itr->m_Tick <= CurrTick)
{
- if (itr->m_PreviousType != E_BLOCK_AIR) // PreviousType defaults to -1 if not specified
+ if (itr->m_PreviousType != E_BLOCK_AIR) // PreviousType defaults to 0 if not specified
{
if (GetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ) == itr->m_PreviousType)
{
@@ -1638,6 +1638,24 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT
+void cChunk::SetMeta(int a_BlockIdx, NIBBLETYPE a_Meta)
+{
+ if (GetNibble(m_BlockMeta, a_BlockIdx) == a_Meta)
+ {
+ return;
+ }
+
+ MarkDirty();
+ SetNibble(m_BlockMeta, a_BlockIdx, a_Meta);
+ Vector3i Coords(IndexToCoordinate(a_BlockIdx));
+
+ m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, Coords.x, Coords.y, Coords.z, GetBlock(a_BlockIdx), a_Meta));
+}
+
+
+
+
+
void cChunk::SendBlockTo(int a_RelX, int a_RelY, int a_RelZ, cClientHandle * a_Client)
{
// The coords must be valid, because the upper level already does chunk lookup. No need to check them again.
diff --git a/src/Chunk.h b/src/Chunk.h
index a15d43e00..84ec35496 100644
--- a/src/Chunk.h
+++ b/src/Chunk.h
@@ -320,10 +320,10 @@ public:
m_BlockTickZ = a_RelZ;
}
- inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const {return cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ); }
- inline NIBBLETYPE GetMeta(int a_BlockIdx) const {return cChunkDef::GetNibble(m_BlockMeta, a_BlockIdx); }
- inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta) { cChunkDef::SetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ, a_Meta); }
- inline void SetMeta(int a_BlockIdx, NIBBLETYPE a_Meta) { cChunkDef::SetNibble(m_BlockMeta, a_BlockIdx, a_Meta); }
+ inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const { return cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ); }
+ inline NIBBLETYPE GetMeta(int a_BlockIdx) const { return cChunkDef::GetNibble(m_BlockMeta, a_BlockIdx); }
+ inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta) { SetMeta(MakeIndex(a_RelX, a_RelY, a_RelZ), a_Meta); }
+ void SetMeta(int a_BlockIdx, NIBBLETYPE a_Meta);
inline NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const {return cChunkDef::GetNibble(m_BlockLight, a_RelX, a_RelY, a_RelZ); }
inline NIBBLETYPE GetSkyLight (int a_RelX, int a_RelY, int a_RelZ) const {return cChunkDef::GetNibble(m_BlockSkyLight, a_RelX, a_RelY, a_RelZ, true); }
@@ -420,7 +420,6 @@ private:
cWorld * m_World;
cChunkMap * m_ChunkMap;
- // TODO: Make these pointers and don't allocate what isn't needed
COMPRESSED_BLOCKTYPE m_BlockTypes;
COMPRESSED_NIBBLETYPE m_BlockMeta;
COMPRESSED_NIBBLETYPE m_BlockLight;
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp
index 537d491c9..d7164a6a5 100644
--- a/src/ChunkMap.cpp
+++ b/src/ChunkMap.cpp
@@ -1248,8 +1248,6 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP
if ((Chunk != NULL) && Chunk->IsValid())
{
Chunk->SetMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta);
- Chunk->MarkDirty();
- Chunk->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, NULL);
}
}
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index f168a092f..caff15cd0 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -202,7 +202,7 @@ AString cClientHandle::FormatMessageType(bool ShouldAppendChatPrefixes, eMessage
{
switch (a_ChatPrefix)
{
- case mtCustom: return AString();
+ case mtCustom: return "";
case mtFailure: return FormatChatPrefix(ShouldAppendChatPrefixes, "INFO", cChatColor::Rose, cChatColor::White);
case mtInformation: return FormatChatPrefix(ShouldAppendChatPrefixes, "INFO", cChatColor::Yellow, cChatColor::White);
case mtSuccess: return FormatChatPrefix(ShouldAppendChatPrefixes, "INFO", cChatColor::Green, cChatColor::White);
@@ -224,7 +224,7 @@ AString cClientHandle::FormatMessageType(bool ShouldAppendChatPrefixes, eMessage
}
}
ASSERT(!"Unhandled chat prefix type!");
- return AString();
+ return "";
}
@@ -633,6 +633,10 @@ void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString
// Client <-> Server branding exchange
SendPluginMessage("MC|Brand", "MCServer");
}
+ else if (a_Channel == "MC|ItemName")
+ {
+ HandleAnvilItemName(a_Message.c_str(), a_Message.size());
+ }
else if (a_Channel == "REGISTER")
{
if (HasPluginChannel(a_Channel))
@@ -774,6 +778,29 @@ void cClientHandle::HandleCommandBlockMessage(const char * a_Data, size_t a_Leng
+void cClientHandle::HandleAnvilItemName(const char * a_Data, size_t a_Length)
+{
+ if (a_Length < 1)
+ {
+ return;
+ }
+
+ if ((m_Player->GetWindow() == NULL) || (m_Player->GetWindow()->GetWindowType() != cWindow::wtAnvil))
+ {
+ return;
+ }
+
+ AString Name(a_Data, a_Length);
+ if (Name.length() <= 30)
+ {
+ ((cAnvilWindow *)m_Player->GetWindow())->SetRepairedItemName(Name, m_Player);
+ }
+}
+
+
+
+
+
void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, char a_Status)
{
LOGD("HandleLeftClick: {%i, %i, %i}; Face: %i; Stat: %i",
@@ -1510,7 +1537,7 @@ void cClientHandle::HandleDisconnect(const AString & a_Reason)
{
LOGD("Received d/c packet from %s with reason \"%s\"", m_Username.c_str(), a_Reason.c_str());
- cRoot::Get()->GetPluginManager()->CallHookDisconnect(m_Player, a_Reason);
+ cRoot::Get()->GetPluginManager()->CallHookDisconnect(*this, a_Reason);
m_HasSentDC = true;
Destroy();
@@ -2690,9 +2717,9 @@ void cClientHandle::SocketClosed(void)
LOGD("Player %s @ %s disconnected", m_Username.c_str(), m_IPString.c_str());
- if (m_Username != "") // Ignore client pings
+ if (!m_Username.empty()) // Ignore client pings
{
- cRoot::Get()->GetPluginManager()->CallHookDisconnect(m_Player, "Player disconnected");
+ cRoot::Get()->GetPluginManager()->CallHookDisconnect(*this, "Player disconnected");
}
Destroy();
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index bddc1dd5e..b6bba4eae 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -385,6 +385,9 @@ private:
/** Handles the "MC|AdvCdm" plugin message */
void HandleCommandBlockMessage(const char * a_Data, size_t a_Length);
+
+ /** Handles the "MC|ItemName" plugin message */
+ void HandleAnvilItemName(const char * a_Data, size_t a_Length);
// cSocketThreads::cCallback overrides:
virtual bool DataReceived (const char * a_Data, size_t a_Size) override; // Data is received from the client
diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp
index b0af8f271..53a638ee5 100644
--- a/src/CraftingRecipes.cpp
+++ b/src/CraftingRecipes.cpp
@@ -802,7 +802,7 @@ void cCraftingRecipes::HandleFireworks(const cItem * a_CraftingGrid, cCraftingRe
break;
}
case E_ITEM_PAPER: break;
- default: LOG("Unexpected item in firework rocket a_Recipe, was the crafting file fireworks section changed?"); break;
+ default: LOG("Unexpected item in firework rocket recipe, was the crafting file's fireworks section changed?"); break;
}
}
}
@@ -837,7 +837,7 @@ void cCraftingRecipes::HandleFireworks(const cItem * a_CraftingGrid, cCraftingRe
case E_ITEM_GOLD_NUGGET: a_Recipe->m_Result.m_FireworkItem.m_Type = 2; break;
case E_ITEM_FEATHER: a_Recipe->m_Result.m_FireworkItem.m_Type = 4; break;
case E_ITEM_HEAD: a_Recipe->m_Result.m_FireworkItem.m_Type = 3; break;
- default: LOG("Unexpected item in firework star a_Recipe, was the crafting file fireworks section changed?"); break; // ermahgerd BARD ardmins
+ default: LOG("Unexpected item in firework star recipe, was the crafting file's fireworks section changed?"); break; // ermahgerd BARD ardmins
}
}
diff --git a/src/DeadlockDetect.cpp b/src/DeadlockDetect.cpp
index 38a3c369e..f73a45555 100644
--- a/src/DeadlockDetect.cpp
+++ b/src/DeadlockDetect.cpp
@@ -109,7 +109,7 @@ void cDeadlockDetect::CheckWorldAge(const AString & a_WorldName, Int64 a_Age)
WorldAges::iterator itr = m_WorldAges.find(a_WorldName);
if (itr == m_WorldAges.end())
{
- ASSERT(!"Unknown world in cDeadlockDetect");
+ SetWorldAge(a_WorldName, a_Age);
return;
}
diff --git a/src/Enchantments.cpp b/src/Enchantments.cpp
index 64f89815b..264878c22 100644
--- a/src/Enchantments.cpp
+++ b/src/Enchantments.cpp
@@ -83,6 +83,15 @@ void cEnchantments::AddFromString(const AString & a_StringSpec)
+size_t cEnchantments::Count(void)
+{
+ return m_Enchantments.size();
+}
+
+
+
+
+
AString cEnchantments::ToString(void) const
{
// Serialize all the enchantments into a string
diff --git a/src/Enchantments.h b/src/Enchantments.h
index ec42257c8..85a316414 100644
--- a/src/Enchantments.h
+++ b/src/Enchantments.h
@@ -84,6 +84,9 @@ public:
/** Adds enchantments in the stringspec; if a specified enchantment already exists, overwrites it */
void AddFromString(const AString & a_StringSpec);
+ /** Get the count of enchantments */
+ size_t Count(void);
+
/** Serializes all the enchantments into a string */
AString ToString(void) const;
diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp
index 847b39bbc..8d2569125 100644
--- a/src/Entities/ArrowEntity.cpp
+++ b/src/Entities/ArrowEntity.cpp
@@ -15,6 +15,7 @@ cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a
m_IsCritical(false),
m_Timer(0),
m_HitGroundTimer(0),
+ m_HasTeleported(false),
m_bIsCollected(false),
m_HitBlockPos(Vector3i(0, 0, 0))
{
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 5c675a387..4cf10a219 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -1,3 +1,4 @@
+
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Entity.h"
@@ -10,7 +11,6 @@
#include "../Simulator/FluidSimulator.h"
#include "../Bindings/PluginManager.h"
#include "../Tracer.h"
-#include "Minecart.h"
#include "Player.h"
@@ -32,16 +32,10 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d
, m_Attachee(NULL)
, m_bDirtyHead(true)
, m_bDirtyOrientation(true)
- , m_bDirtyPosition(true)
- , m_bDirtySpeed(true)
- , m_bOnGround( false )
- , m_Gravity( -9.81f )
- , m_LastPosX( 0.0 )
- , m_LastPosY( 0.0 )
- , m_LastPosZ( 0.0 )
- , m_TimeLastTeleportPacket(0)
- , m_TimeLastMoveReltPacket(0)
- , m_TimeLastSpeedPacket(0)
+ , m_bHasSentNoSpeed(true)
+ , m_bOnGround(false)
+ , m_Gravity(-9.81f)
+ , m_LastPos(a_X, a_Y, a_Z)
, m_IsInitialized(false)
, m_EntityType(a_EntityType)
, m_World(NULL)
@@ -55,7 +49,7 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d
, m_IsSubmerged(false)
, m_AirLevel(0)
, m_AirTickTimer(0)
- , m_HeadYaw( 0.0 )
+ , m_HeadYaw(0.0)
, m_Rot(0.0, 0.0, 0.0)
, m_Pos(a_X, a_Y, a_Z)
, m_WaterSpeed(0, 0, 0)
@@ -794,30 +788,43 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
NextSpeed += m_WaterSpeed;
- if( NextSpeed.SqrLength() > 0.f )
+ if (NextSpeed.SqrLength() > 0.f)
{
- cTracer Tracer( GetWorld() );
- bool HasHit = Tracer.Trace( NextPos, NextSpeed, 2 );
- if (HasHit) // Oh noez! we hit something
+ cTracer Tracer(GetWorld());
+ // Distance traced is an integer, so we round up from the distance we should go (Speed * Delta), else we will encounter collision detection failurse
+ int DistanceToTrace = (int)(ceil((NextSpeed * a_Dt).SqrLength()) * 2);
+ bool HasHit = Tracer.Trace(NextPos, NextSpeed, DistanceToTrace);
+
+ if (HasHit)
{
- // Set to hit position
+ // Oh noez! We hit something: verify that the (hit position - current) was smaller or equal to the (position that we should travel without obstacles - current)
+ // This is because previously, we traced with a length that was rounded up (due to integer limitations), and in the case that something was hit, we don't want to overshoot our projected movement
if ((Tracer.RealHit - NextPos).SqrLength() <= (NextSpeed * a_Dt).SqrLength())
{
+ // Block hit was within our projected path
+ // Begin by stopping movement in the direction that we hit something. The Normal is the line perpendicular to a 2D face and in this case, stores what block face was hit through either -1 or 1.
+ // For example: HitNormal.y = -1 : BLOCK_FACE_YM; HitNormal.y = 1 : BLOCK_FACE_YP
if (Tracer.HitNormal.x != 0.f) NextSpeed.x = 0.f;
if (Tracer.HitNormal.y != 0.f) NextSpeed.y = 0.f;
if (Tracer.HitNormal.z != 0.f) NextSpeed.z = 0.f;
- if (Tracer.HitNormal.y > 0) // means on ground
+ if (Tracer.HitNormal.y == 1) // Hit BLOCK_FACE_YP, we are on the ground
{
m_bOnGround = true;
}
- NextPos.Set(Tracer.RealHit.x,Tracer.RealHit.y,Tracer.RealHit.z);
- NextPos.x += Tracer.HitNormal.x * 0.3f;
- NextPos.y += Tracer.HitNormal.y * 0.05f; // Any larger produces entity vibration-upon-the-spot
- NextPos.z += Tracer.HitNormal.z * 0.3f;
+
+ // Now, set our position to the hit block (i.e. move part way along our intended trajectory)
+ NextPos.Set(Tracer.RealHit.x, Tracer.RealHit.y, Tracer.RealHit.z);
+ NextPos.x += Tracer.HitNormal.x * 0.1;
+ NextPos.y += Tracer.HitNormal.y * 0.05;
+ NextPos.z += Tracer.HitNormal.z * 0.1;
}
else
{
+ // We have hit a block but overshot our intended trajectory, move normally, safe in the warm cocoon of knowledge that we won't appear to teleport forwards on clients,
+ // and that this piece of software will come to be hailed as the epitome of performance and functionality in C++, never before seen, and of such a like that will never
+ // be henceforth seen again in the time of programmers and man alike
+ // </&sensationalist>
NextPos += (NextSpeed * a_Dt);
}
}
@@ -1010,9 +1017,9 @@ void cEntity::SetSwimState(cChunk & a_Chunk)
{
// This sometimes happens on Linux machines
// Ref.: http://forum.mc-server.org/showthread.php?tid=1244
- LOGD("SetSwimState failure: RelX = %d, RelZ = %d, LastPos = {%.02f, %.02f}, Pos = %.02f, %.02f}",
- RelX, RelY, m_LastPosX, m_LastPosZ, GetPosX(), GetPosZ()
- );
+ LOGD("SetSwimState failure: RelX = %d, RelZ = %d, Pos = %.02f, %.02f}",
+ RelX, RelY, GetPosX(), GetPosZ()
+ );
m_IsSwimming = false;
m_IsSubmerged = false;
return;
@@ -1178,72 +1185,70 @@ void cEntity::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ)
void cEntity::BroadcastMovementUpdate(const cClientHandle * a_Exclude)
{
- // Send velocity packet every two ticks if: speed is not negligible or speed was set (as indicated by the DirtySpeed flag)
- if (((m_Speed.SqrLength() > 0.0004f) || m_bDirtySpeed) && ((m_World->GetWorldAge() - m_TimeLastSpeedPacket) >= 2))
+ // Process packet sending every two ticks
+ if (GetWorld()->GetWorldAge() % 2 == 0)
{
- m_World->BroadcastEntityVelocity(*this,a_Exclude);
- m_bDirtySpeed = false;
- m_TimeLastSpeedPacket = m_World->GetWorldAge();
- }
-
- // Have to process position related packets this every two ticks
- if (m_World->GetWorldAge() % 2 == 0)
- {
- int DiffX = (int) (floor(GetPosX() * 32.0) - floor(m_LastPosX * 32.0));
- int DiffY = (int) (floor(GetPosY() * 32.0) - floor(m_LastPosY * 32.0));
- int DiffZ = (int) (floor(GetPosZ() * 32.0) - floor(m_LastPosZ * 32.0));
- Int64 DiffTeleportPacket = m_World->GetWorldAge() - m_TimeLastTeleportPacket;
- // 4 blocks is max Relative So if the Diff is greater than 127 or. Send an absolute position every 20 seconds
- if (DiffTeleportPacket >= 400 ||
- ((DiffX > 127) || (DiffX < -128) ||
- (DiffY > 127) || (DiffY < -128) ||
- (DiffZ > 127) || (DiffZ < -128)))
+ double SpeedSqr = GetSpeed().SqrLength();
+ if (SpeedSqr == 0.0)
{
- //
- m_World->BroadcastTeleportEntity(*this,a_Exclude);
- m_TimeLastTeleportPacket = m_World->GetWorldAge();
- m_TimeLastMoveReltPacket = m_TimeLastTeleportPacket; //Must synchronize.
- m_LastPosX = GetPosX();
- m_LastPosY = GetPosY();
- m_LastPosZ = GetPosZ();
- m_bDirtyPosition = false;
- m_bDirtyOrientation = false;
+ // Speed is zero, send this to clients once only as well as an absolute position
+ if (!m_bHasSentNoSpeed)
+ {
+ m_World->BroadcastEntityVelocity(*this, a_Exclude);
+ m_World->BroadcastTeleportEntity(*this, a_Exclude);
+ m_bHasSentNoSpeed = true;
+ }
}
else
{
- Int64 DiffMoveRelPacket = m_World->GetWorldAge() - m_TimeLastMoveReltPacket;
- //if the change is big enough.
- if ((abs(DiffX) >= 4 || abs(DiffY) >= 4 || abs(DiffZ) >= 4 || DiffMoveRelPacket >= 60) && m_bDirtyPosition)
+ // Movin'
+ m_World->BroadcastEntityVelocity(*this, a_Exclude);
+ m_bHasSentNoSpeed = false;
+ }
+
+ // TODO: Pickups move disgracefully if relative move packets are sent as opposed to just velocity. Have a system to send relmove only when SetPosXXX() is called with a large difference in position
+ int DiffX = (int)(floor(GetPosX() * 32.0) - floor(m_LastPos.x * 32.0));
+ int DiffY = (int)(floor(GetPosY() * 32.0) - floor(m_LastPos.y * 32.0));
+ int DiffZ = (int)(floor(GetPosZ() * 32.0) - floor(m_LastPos.z * 32.0));
+
+ if ((DiffX != 0) || (DiffY != 0) || (DiffZ != 0)) // Have we moved?
+ {
+ if ((abs(DiffX) <= 127) && (abs(DiffY) <= 127) && (abs(DiffZ) <= 127)) // Limitations of a Byte
{
+ // Difference within Byte limitations, use a relative move packet
if (m_bDirtyOrientation)
{
- m_World->BroadcastEntityRelMoveLook(*this, (char)DiffX, (char)DiffY, (char)DiffZ,a_Exclude);
+ m_World->BroadcastEntityRelMoveLook(*this, (char)DiffX, (char)DiffY, (char)DiffZ, a_Exclude);
m_bDirtyOrientation = false;
}
else
{
- m_World->BroadcastEntityRelMove(*this, (char)DiffX, (char)DiffY, (char)DiffZ,a_Exclude);
+ m_World->BroadcastEntityRelMove(*this, (char)DiffX, (char)DiffY, (char)DiffZ, a_Exclude);
}
- m_LastPosX = GetPosX();
- m_LastPosY = GetPosY();
- m_LastPosZ = GetPosZ();
- m_bDirtyPosition = false;
- m_TimeLastMoveReltPacket = m_World->GetWorldAge();
+ // Clients seem to store two positions, one for the velocity packet and one for the teleport/relmove packet
+ // The latter is only changed with a relmove/teleport, and m_LastPos stores this position
+ m_LastPos = GetPosition();
}
else
{
- if (m_bDirtyOrientation)
- {
- m_World->BroadcastEntityLook(*this,a_Exclude);
- m_bDirtyOrientation = false;
- }
- }
+ // Too big a movement, do a teleport
+ m_World->BroadcastTeleportEntity(*this, a_Exclude);
+ m_LastPos = GetPosition(); // See above
+ m_bDirtyOrientation = false;
+ }
}
+
if (m_bDirtyHead)
{
- m_World->BroadcastEntityHeadLook(*this,a_Exclude);
+ m_World->BroadcastEntityHeadLook(*this, a_Exclude);
m_bDirtyHead = false;
}
+ if (m_bDirtyOrientation)
+ {
+ // Send individual update in case above (sending with rel-move packet) wasn't done
+ GetWorld()->BroadcastEntityLook(*this, a_Exclude);
+ m_bDirtyOrientation = false;
+ }
}
}
@@ -1383,7 +1388,7 @@ void cEntity::SetRoll(double a_Roll)
void cEntity::SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
{
m_Speed.Set(a_SpeedX, a_SpeedY, a_SpeedZ);
- m_bDirtySpeed = true;
+
WrapSpeed();
}
@@ -1393,7 +1398,7 @@ void cEntity::SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
void cEntity::SetSpeedX(double a_SpeedX)
{
m_Speed.x = a_SpeedX;
- m_bDirtySpeed = true;
+
WrapSpeed();
}
@@ -1403,7 +1408,7 @@ void cEntity::SetSpeedX(double a_SpeedX)
void cEntity::SetSpeedY(double a_SpeedY)
{
m_Speed.y = a_SpeedY;
- m_bDirtySpeed = true;
+
WrapSpeed();
}
@@ -1413,7 +1418,7 @@ void cEntity::SetSpeedY(double a_SpeedY)
void cEntity::SetSpeedZ(double a_SpeedZ)
{
m_Speed.z = a_SpeedZ;
- m_bDirtySpeed = true;
+
WrapSpeed();
}
@@ -1433,7 +1438,7 @@ void cEntity::SetWidth(double a_Width)
void cEntity::AddPosX(double a_AddPosX)
{
m_Pos.x += a_AddPosX;
- m_bDirtyPosition = true;
+
}
@@ -1442,7 +1447,7 @@ void cEntity::AddPosX(double a_AddPosX)
void cEntity::AddPosY(double a_AddPosY)
{
m_Pos.y += a_AddPosY;
- m_bDirtyPosition = true;
+
}
@@ -1451,7 +1456,7 @@ void cEntity::AddPosY(double a_AddPosY)
void cEntity::AddPosZ(double a_AddPosZ)
{
m_Pos.z += a_AddPosZ;
- m_bDirtyPosition = true;
+
}
@@ -1462,7 +1467,7 @@ void cEntity::AddPosition(double a_AddPosX, double a_AddPosY, double a_AddPosZ)
m_Pos.x += a_AddPosX;
m_Pos.y += a_AddPosY;
m_Pos.z += a_AddPosZ;
- m_bDirtyPosition = true;
+
}
@@ -1472,8 +1477,7 @@ void cEntity::AddSpeed(double a_AddSpeedX, double a_AddSpeedY, double a_AddSpeed
{
m_Speed.x += a_AddSpeedX;
m_Speed.y += a_AddSpeedY;
- m_Speed.z += a_AddSpeedZ;
- m_bDirtySpeed = true;
+ m_Speed.z += a_AddSpeedZ;
WrapSpeed();
}
@@ -1483,8 +1487,7 @@ void cEntity::AddSpeed(double a_AddSpeedX, double a_AddSpeedY, double a_AddSpeed
void cEntity::AddSpeedX(double a_AddSpeedX)
{
- m_Speed.x += a_AddSpeedX;
- m_bDirtySpeed = true;
+ m_Speed.x += a_AddSpeedX;
WrapSpeed();
}
@@ -1494,8 +1497,7 @@ void cEntity::AddSpeedX(double a_AddSpeedX)
void cEntity::AddSpeedY(double a_AddSpeedY)
{
- m_Speed.y += a_AddSpeedY;
- m_bDirtySpeed = true;
+ m_Speed.y += a_AddSpeedY;
WrapSpeed();
}
@@ -1505,8 +1507,7 @@ void cEntity::AddSpeedY(double a_AddSpeedY)
void cEntity::AddSpeedZ(double a_AddSpeedZ)
{
- m_Speed.z += a_AddSpeedZ;
- m_bDirtySpeed = true;
+ m_Speed.z += a_AddSpeedZ;
WrapSpeed();
}
@@ -1561,8 +1562,7 @@ Vector3d cEntity::GetLookVector(void) const
// Set position
void cEntity::SetPosition(double a_PosX, double a_PosY, double a_PosZ)
{
- m_Pos.Set(a_PosX, a_PosY, a_PosZ);
- m_bDirtyPosition = true;
+ m_Pos.Set(a_PosX, a_PosY, a_PosZ);
}
@@ -1571,8 +1571,7 @@ void cEntity::SetPosition(double a_PosX, double a_PosY, double a_PosZ)
void cEntity::SetPosX(double a_PosX)
{
- m_Pos.x = a_PosX;
- m_bDirtyPosition = true;
+ m_Pos.x = a_PosX;
}
@@ -1581,8 +1580,7 @@ void cEntity::SetPosX(double a_PosX)
void cEntity::SetPosY(double a_PosY)
{
- m_Pos.y = a_PosY;
- m_bDirtyPosition = true;
+ m_Pos.y = a_PosY;
}
@@ -1592,7 +1590,6 @@ void cEntity::SetPosY(double a_PosY)
void cEntity::SetPosZ(double a_PosZ)
{
m_Pos.z = a_PosZ;
- m_bDirtyPosition = true;
}
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index a682701de..df03d635b 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -430,22 +430,29 @@ protected:
/// The entity which is attached to this entity (rider), NULL if none
cEntity * m_Attachee;
- // Flags that signal that we haven't updated the clients with the latest.
- bool m_bDirtyHead;
- bool m_bDirtyOrientation;
- bool m_bDirtyPosition;
- bool m_bDirtySpeed;
-
- bool m_bOnGround;
- float m_Gravity;
+ /** Stores whether head yaw has been set manually */
+ bool m_bDirtyHead;
+
+ /** Stores whether our yaw/pitch/roll (body orientation) has been set manually */
+ bool m_bDirtyOrientation;
- // Last Position.
- double m_LastPosX, m_LastPosY, m_LastPosZ;
+ /** Stores whether we have sent a Velocity packet with a speed of zero (no speed) to the client
+ Ensures that said packet is sent only once */
+ bool m_bHasSentNoSpeed;
- // This variables keep track of the last time a packet was sent
- Int64 m_TimeLastTeleportPacket, m_TimeLastMoveReltPacket, m_TimeLastSpeedPacket; // In ticks
+ /** Stores if the entity is on the ground */
+ bool m_bOnGround;
+
+ /** Stores gravity that is applied to an entity every tick
+ For realistic effects, this should be negative. For spaaaaaaace, this can be zero or even positive */
+ float m_Gravity;
+
+ /** Last position sent to client via the Relative Move or Teleport packets (not Velocity)
+ Only updated if cEntity::BroadcastMovementUpdate() is called! */
+ Vector3d m_LastPos;
- bool m_IsInitialized; // Is set to true when it's initialized, until it's destroyed (Initialize() till Destroy() )
+ /** True when entity is initialised (Initialize()) and false when destroyed pending deletion (Destroy()) */
+ bool m_IsInitialized;
eEntityType m_EntityType;
@@ -469,12 +476,14 @@ protected:
/// Time, in ticks, since the last damage dealt by the void. Reset to zero when moving out of the void.
int m_TicksSinceLastVoidDamage;
+
virtual void Destroyed(void) {} // Called after the entity has been destroyed
void SetWorld(cWorld * a_World) { m_World = a_World; }
/** Called in each tick to handle air-related processing i.e. drowning */
virtual void HandleAir();
+
/** Called once per tick to set IsSwimming and IsSubmerged */
virtual void SetSwimState(cChunk & a_Chunk);
diff --git a/src/Entities/ExpOrb.cpp b/src/Entities/ExpOrb.cpp
index 3623c869a..10f79aedc 100644
--- a/src/Entities/ExpOrb.cpp
+++ b/src/Entities/ExpOrb.cpp
@@ -34,8 +34,6 @@ cExpOrb::cExpOrb(const Vector3d & a_Pos, int a_Reward)
void cExpOrb::SpawnOn(cClientHandle & a_Client)
{
a_Client.SendExperienceOrb(*this);
- m_bDirtyPosition = false;
- m_bDirtySpeed = false;
m_bDirtyOrientation = false;
m_bDirtyHead = false;
}
diff --git a/src/Entities/FallingBlock.cpp b/src/Entities/FallingBlock.cpp
index 99bff1100..beb58f207 100644
--- a/src/Entities/FallingBlock.cpp
+++ b/src/Entities/FallingBlock.cpp
@@ -87,9 +87,8 @@ void cFallingBlock::Tick(float a_Dt, cChunk & a_Chunk)
AddSpeedY(MilliDt * -9.8f);
AddPosition(GetSpeed() * MilliDt);
- // If not static (One billionth precision) broadcast movement.
- static const float epsilon = 0.000000001f;
- if ((fabs(GetSpeedX()) > epsilon) || (fabs(GetSpeedZ()) > epsilon))
+ // If not static (one billionth precision) broadcast movement
+ if ((fabs(GetSpeedX()) > std::numeric_limits<double>::epsilon()) || (fabs(GetSpeedZ()) > std::numeric_limits<double>::epsilon()))
{
BroadcastMovementUpdate();
}
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 08b7d3984..6ac11c270 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -76,11 +76,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
cTimer t1;
m_LastPlayerListTime = t1.GetNowTime();
-
- m_TimeLastTeleportPacket = 0;
m_PlayerName = a_PlayerName;
- m_bDirtyPosition = true; // So chunks are streamed to player at spawn
if (!LoadFromDisk())
{
@@ -209,25 +206,22 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
m_BowCharge += 1;
}
- //handle updating experience
+ // Handle updating experience
if (m_bDirtyExperience)
{
SendExperience();
}
- if (m_bDirtyPosition)
+ if (GetPosition() != m_LastPos) // Change in position from last tick?
{
// Apply food exhaustion from movement:
ApplyFoodExhaustionFromMovement();
cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*this);
- BroadcastMovementUpdate(m_ClientHandle);
m_ClientHandle->StreamChunks();
}
- else
- {
- BroadcastMovementUpdate(m_ClientHandle);
- }
+
+ BroadcastMovementUpdate(m_ClientHandle);
if (m_Health > 0) // make sure player is alive
{
@@ -1596,10 +1590,7 @@ bool cPlayer::LoadFromDisk()
SetPosX(JSON_PlayerPosition[(unsigned int)0].asDouble());
SetPosY(JSON_PlayerPosition[(unsigned int)1].asDouble());
SetPosZ(JSON_PlayerPosition[(unsigned int)2].asDouble());
- m_LastPosX = GetPosX();
- m_LastPosY = GetPosY();
- m_LastPosZ = GetPosZ();
- m_LastFoodPos = GetPosition();
+ m_LastPos = GetPosition();
}
Json::Value & JSON_PlayerRotation = root["rotation"];
@@ -1860,17 +1851,16 @@ void cPlayer::ApplyFoodExhaustionFromMovement()
{
return;
}
-
- // Calculate the distance travelled, update the last pos:
- Vector3d Movement(GetPosition() - m_LastFoodPos);
- Movement.y = 0; // Only take XZ movement into account
- m_LastFoodPos = GetPosition();
-
+
// If riding anything, apply no food exhaustion
if (m_AttachedTo != NULL)
{
return;
}
+
+ // Calculate the distance travelled, update the last pos:
+ Vector3d Movement(GetPosition() - m_LastPos);
+ Movement.y = 0; // Only take XZ movement into account
// Apply the exhaustion based on distance travelled:
double BaseExhaustion = Movement.Length();
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index 3029abfe0..6fc7e2875 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -423,9 +423,6 @@ protected:
/** Number of ticks remaining for the foodpoisoning effect; zero if not foodpoisoned */
int m_FoodPoisonedTicksRemaining;
- /** Last position that has been recorded for food-related processing: */
- Vector3d m_LastFoodPos;
-
float m_LastJumpHeight;
float m_LastGroundHeight;
bool m_bTouchGround;
diff --git a/src/Entities/TNTEntity.cpp b/src/Entities/TNTEntity.cpp
index 02f31f5bb..fd9a4e7ac 100644
--- a/src/Entities/TNTEntity.cpp
+++ b/src/Entities/TNTEntity.cpp
@@ -30,8 +30,6 @@ cTNTEntity::cTNTEntity(const Vector3d & a_Pos, int a_FuseTicks) :
void cTNTEntity::SpawnOn(cClientHandle & a_ClientHandle)
{
a_ClientHandle.SendSpawnObject(*this, 50, 1, 0, 0); // 50 means TNT
- m_bDirtyPosition = false;
- m_bDirtySpeed = false;
m_bDirtyOrientation = false;
m_bDirtyHead = false;
}
diff --git a/src/Generating/Caves.cpp b/src/Generating/Caves.cpp
index 5cad11d2a..872e3341d 100644
--- a/src/Generating/Caves.cpp
+++ b/src/Generating/Caves.cpp
@@ -35,13 +35,6 @@ reduced in complexity in order for this generator to be useful, so the caves' sh
-/// How many nests in each direction are generated for a given chunk. Must be an even number
-#define NEIGHBORHOOD_SIZE 8
-
-
-
-
-
const int MIN_RADIUS = 3;
const int MAX_RADIUS = 8;
@@ -122,27 +115,19 @@ typedef std::vector<cCaveTunnel *> cCaveTunnels;
/// A collection of connected tunnels, possibly branching.
-class cStructGenWormNestCaves::cCaveSystem
+class cStructGenWormNestCaves::cCaveSystem :
+ public cGridStructGen::cStructure
{
+ typedef cGridStructGen::cStructure super;
+
public:
// The generating block position; is read directly in cStructGenWormNestCaves::GetCavesForChunk()
int m_BlockX;
int m_BlockZ;
- cCaveSystem(int a_BlockX, int a_BlockZ, int a_MaxOffset, int a_Size, cNoise & a_Noise);
+ cCaveSystem(int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise);
~cCaveSystem();
- /// Carves the cave system into the chunk specified
- void ProcessChunk(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes,
- cChunkDef::HeightMap & a_HeightMap
- );
-
- #ifdef _DEBUG
- AString ExportAsSVG(int a_Color, int a_OffsetX, int a_OffsetZ) const;
- #endif // _DEBUG
-
protected:
int m_Size;
cCaveTunnels m_Tunnels;
@@ -157,6 +142,9 @@ protected:
/// Returns a radius based on the location provided.
int GetRadius(cNoise & a_Noise, int a_OriginX, int a_OriginY, int a_OriginZ);
+
+ // cGridStructGen::cStructure overrides:
+ virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override;
} ;
@@ -239,9 +227,15 @@ void cCaveTunnel::Randomize(cNoise & a_Noise)
bool cCaveTunnel::RefineDefPoints(const cCaveDefPoints & a_Src, cCaveDefPoints & a_Dst)
{
+ if (a_Src.size() < 2)
+ {
+ // There are no midpoints, nothing to smooth
+ return true;
+ }
+
// Smoothing: for each line segment, add points on its 1/4 lengths
bool res = false;
- int Num = a_Src.size() - 2; // this many intermediary points
+ size_t Num = a_Src.size() - 2; // this many intermediary points
a_Dst.clear();
a_Dst.reserve(Num * 2 + 2);
cCaveDefPoints::const_iterator itr = a_Src.begin() + 1;
@@ -251,7 +245,7 @@ bool cCaveTunnel::RefineDefPoints(const cCaveDefPoints & a_Src, cCaveDefPoints &
int PrevY = Source.m_BlockY;
int PrevZ = Source.m_BlockZ;
int PrevR = Source.m_Radius;
- for (int i = 0; i <= Num; ++i, ++itr)
+ for (size_t i = 0; i <= Num; ++i, ++itr)
{
int dx = itr->m_BlockX - PrevX;
int dy = itr->m_BlockY - PrevY;
@@ -580,17 +574,16 @@ AString cCaveTunnel::ExportAsSVG(int a_Color, int a_OffsetX, int a_OffsetZ) cons
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cStructGenWormNestCaves::cCaveSystem:
-cStructGenWormNestCaves::cCaveSystem::cCaveSystem(int a_BlockX, int a_BlockZ, int a_MaxOffset, int a_Size, cNoise & a_Noise) :
- m_BlockX(a_BlockX),
- m_BlockZ(a_BlockZ),
+cStructGenWormNestCaves::cCaveSystem::cCaveSystem(int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise) :
+ super(a_OriginX, a_OriginZ),
m_Size(a_Size)
{
- int Num = 1 + a_Noise.IntNoise2DInt(a_BlockX, a_BlockZ) % 3;
+ int Num = 1 + a_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) % 3;
for (int i = 0; i < Num; i++)
{
- int OriginX = a_BlockX + (a_Noise.IntNoise3DInt(13 * a_BlockX, 17 * a_BlockZ, 11 * i) / 19) % a_MaxOffset;
- int OriginZ = a_BlockZ + (a_Noise.IntNoise3DInt(17 * a_BlockX, 13 * a_BlockZ, 11 * i) / 23) % a_MaxOffset;
- int OriginY = 20 + (a_Noise.IntNoise3DInt(19 * a_BlockX, 13 * a_BlockZ, 11 * i) / 17) % 20;
+ int OriginX = a_OriginX + (a_Noise.IntNoise3DInt(13 * a_OriginX, 17 * a_OriginZ, 11 * i) / 19) % a_MaxOffset;
+ int OriginZ = a_OriginZ + (a_Noise.IntNoise3DInt(17 * a_OriginX, 13 * a_OriginZ, 11 * i) / 23) % a_MaxOffset;
+ int OriginY = 20 + (a_Noise.IntNoise3DInt(19 * a_OriginX, 13 * a_OriginZ, 11 * i) / 17) % 20;
// Generate three branches from the origin point:
// The tunnels generated depend on X, Y, Z and Branches,
@@ -616,64 +609,17 @@ cStructGenWormNestCaves::cCaveSystem::~cCaveSystem()
-void cStructGenWormNestCaves::cCaveSystem::ProcessChunk(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes,
- cChunkDef::HeightMap & a_HeightMap
-)
-{
- for (cCaveTunnels::const_iterator itr = m_Tunnels.begin(), end = m_Tunnels.end(); itr != end; ++itr)
- {
- (*itr)->ProcessChunk(a_ChunkX, a_ChunkZ, a_BlockTypes, a_HeightMap);
- } // for itr - m_Tunnels[]
-}
-
-
-
-
-
-#ifdef _DEBUG
-AString cStructGenWormNestCaves::cCaveSystem::ExportAsSVG(int a_Color, int a_OffsetX, int a_OffsetZ) const
+void cStructGenWormNestCaves::cCaveSystem::DrawIntoChunk(cChunkDesc & a_ChunkDesc)
{
- AString SVG;
- SVG.reserve(512 * 1024);
+ int ChunkX = a_ChunkDesc.GetChunkX();
+ int ChunkZ = a_ChunkDesc.GetChunkZ();
+ cChunkDef::BlockTypes & BlockTypes = a_ChunkDesc.GetBlockTypes();
+ cChunkDef::HeightMap & HeightMap = a_ChunkDesc.GetHeightMap();
for (cCaveTunnels::const_iterator itr = m_Tunnels.begin(), end = m_Tunnels.end(); itr != end; ++itr)
{
- SVG.append((*itr)->ExportAsSVG(a_Color, a_OffsetX, a_OffsetZ));
+ (*itr)->ProcessChunk(ChunkX, ChunkZ, BlockTypes, HeightMap);
} // for itr - m_Tunnels[]
-
- // Base point highlight:
- AppendPrintf(SVG, "<path style=\"fill:none;stroke:#ff0000;stroke-width:1px;\"\nd=\"M %d,%d L %d,%d\"/>\n",
- a_OffsetX + m_BlockX - 5, a_OffsetZ + m_BlockZ, a_OffsetX + m_BlockX + 5, a_OffsetZ + m_BlockZ
- );
- AppendPrintf(SVG, "<path style=\"fill:none;stroke:#ff0000;stroke-width:1px;\"\nd=\"M %d,%d L %d,%d\"/>\n",
- a_OffsetX + m_BlockX, a_OffsetZ + m_BlockZ - 5, a_OffsetX + m_BlockX, a_OffsetZ + m_BlockZ + 5
- );
-
- // A gray line from the base point to the first point of the ravine, for identification:
- AppendPrintf(SVG, "<path style=\"fill:none;stroke:#cfcfcf;stroke-width:1px;\"\nd=\"M %d,%d L %d,%d\"/>\n",
- a_OffsetX + m_BlockX, a_OffsetZ + m_BlockZ,
- a_OffsetX + m_Tunnels.front()->m_Points.front().m_BlockX,
- a_OffsetZ + m_Tunnels.front()->m_Points.front().m_BlockZ
- );
-
- // Offset guides:
- if (a_OffsetX > 0)
- {
- AppendPrintf(SVG, "<path style=\"fill:none;stroke:#0000ff;stroke-width:1px;\"\nd=\"M %d,0 L %d,1024\"/>\n",
- a_OffsetX, a_OffsetX
- );
- }
- if (a_OffsetZ > 0)
- {
- AppendPrintf(SVG, "<path style=\"fill:none;stroke:#0000ff;stroke-width:1px;\"\nd=\"M 0,%d L 1024,%d\"/>\n",
- a_OffsetZ, a_OffsetZ
- );
- }
-
- return SVG;
}
-#endif // _DEBUG
@@ -744,142 +690,9 @@ int cStructGenWormNestCaves::cCaveSystem::GetRadius(cNoise & a_Noise, int a_Orig
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cStructGenWormNestCaves:
-cStructGenWormNestCaves::~cStructGenWormNestCaves()
-{
- ClearCache();
-}
-
-
-
-
-
-void cStructGenWormNestCaves::ClearCache(void)
+cGridStructGen::cStructurePtr cStructGenWormNestCaves::CreateStructure(int a_OriginX, int a_OriginZ)
{
- for (cCaveSystems::const_iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end; ++itr)
- {
- delete *itr;
- } // for itr - m_Cache[]
- m_Cache.clear();
-}
-
-
-
-
-
-void cStructGenWormNestCaves::GenFinish(cChunkDesc & a_ChunkDesc)
-{
- int ChunkX = a_ChunkDesc.GetChunkX();
- int ChunkZ = a_ChunkDesc.GetChunkZ();
- cCaveSystems Caves;
- GetCavesForChunk(ChunkX, ChunkZ, Caves);
- for (cCaveSystems::const_iterator itr = Caves.begin(); itr != Caves.end(); ++itr)
- {
- (*itr)->ProcessChunk(ChunkX, ChunkZ, a_ChunkDesc.GetBlockTypes(), a_ChunkDesc.GetHeightMap());
- } // for itr - Caves[]
-}
-
-
-
-
-
-void cStructGenWormNestCaves::GetCavesForChunk(int a_ChunkX, int a_ChunkZ, cStructGenWormNestCaves::cCaveSystems & a_Caves)
-{
- int BaseX = a_ChunkX * cChunkDef::Width / m_Grid;
- int BaseZ = a_ChunkZ * cChunkDef::Width / m_Grid;
- if (BaseX < 0)
- {
- --BaseX;
- }
- if (BaseZ < 0)
- {
- --BaseZ;
- }
- BaseX -= NEIGHBORHOOD_SIZE / 2;
- BaseZ -= NEIGHBORHOOD_SIZE / 2;
-
- // Walk the cache, move each cave system that we want into a_Caves:
- int StartX = BaseX * m_Grid;
- int EndX = (BaseX + NEIGHBORHOOD_SIZE + 1) * m_Grid;
- int StartZ = BaseZ * m_Grid;
- int EndZ = (BaseZ + NEIGHBORHOOD_SIZE + 1) * m_Grid;
- for (cCaveSystems::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;)
- {
- if (
- ((*itr)->m_BlockX >= StartX) && ((*itr)->m_BlockX < EndX) &&
- ((*itr)->m_BlockZ >= StartZ) && ((*itr)->m_BlockZ < EndZ)
- )
- {
- // want
- a_Caves.push_back(*itr);
- itr = m_Cache.erase(itr);
- }
- else
- {
- // don't want
- ++itr;
- }
- } // for itr - m_Cache[]
-
- for (int x = 0; x < NEIGHBORHOOD_SIZE; x++)
- {
- int RealX = (BaseX + x) * m_Grid;
- for (int z = 0; z < NEIGHBORHOOD_SIZE; z++)
- {
- int RealZ = (BaseZ + z) * m_Grid;
- bool Found = false;
- for (cCaveSystems::const_iterator itr = a_Caves.begin(), end = a_Caves.end(); itr != end; ++itr)
- {
- if (((*itr)->m_BlockX == RealX) && ((*itr)->m_BlockZ == RealZ))
- {
- Found = true;
- break;
- }
- }
- if (!Found)
- {
- a_Caves.push_back(new cCaveSystem(RealX, RealZ, m_MaxOffset, m_Size, m_Noise));
- }
- }
- }
-
- // Copy a_Caves into m_Cache to the beginning:
- cCaveSystems CavesCopy(a_Caves);
- m_Cache.splice(m_Cache.begin(), CavesCopy, CavesCopy.begin(), CavesCopy.end());
-
- // Trim the cache if it's too long:
- if (m_Cache.size() > 100)
- {
- cCaveSystems::iterator itr = m_Cache.begin();
- std::advance(itr, 100);
- for (cCaveSystems::iterator end = m_Cache.end(); itr != end; ++itr)
- {
- delete *itr;
- }
- itr = m_Cache.begin();
- std::advance(itr, 100);
- m_Cache.erase(itr, m_Cache.end());
- }
-
- /*
- // Uncomment this block for debugging the caves' shapes in 2D using an SVG export
- #ifdef _DEBUG
- AString SVG;
- SVG.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1024\" height = \"1024\">\n");
- SVG.reserve(2 * 1024 * 1024);
- for (cCaveSystems::const_iterator itr = a_Caves.begin(), end = a_Caves.end(); itr != end; ++itr)
- {
- int Color = 0x10 * abs((*itr)->m_BlockX / m_Grid);
- Color |= 0x1000 * abs((*itr)->m_BlockZ / m_Grid);
- SVG.append((*itr)->ExportAsSVG(Color, 512, 512));
- }
- SVG.append("</svg>\n");
-
- AString fnam;
- Printf(fnam, "wnc\\%03d_%03d.svg", a_ChunkX, a_ChunkZ);
- cFile File(fnam, cFile::fmWrite);
- File.Write(SVG.c_str(), SVG.size());
- #endif // _DEBUG
- //*/
+ return cStructurePtr(new cCaveSystem(a_OriginX, a_OriginZ, m_MaxOffset, m_Size, m_Noise));
}
diff --git a/src/Generating/Caves.h b/src/Generating/Caves.h
index 7c45c056b..254dcddbd 100644
--- a/src/Generating/Caves.h
+++ b/src/Generating/Caves.h
@@ -12,7 +12,7 @@
#pragma once
-#include "ComposableGenerator.h"
+#include "GridStructGen.h"
#include "../Noise.h"
@@ -64,10 +64,12 @@ protected:
class cStructGenWormNestCaves :
- public cFinishGen
+ public cGridStructGen
{
+ typedef cGridStructGen super;
public:
cStructGenWormNestCaves(int a_Seed, int a_Size = 64, int a_Grid = 96, int a_MaxOffset = 128) :
+ super(a_Seed, a_Grid, a_Grid, a_Size + a_MaxOffset, a_Size + a_MaxOffset, 100),
m_Noise(a_Seed),
m_Size(a_Size),
m_MaxOffset(a_MaxOffset),
@@ -75,26 +77,16 @@ public:
{
}
- ~cStructGenWormNestCaves();
-
protected:
class cCaveSystem; // fwd: Caves.cpp
- typedef std::list<cCaveSystem *> cCaveSystems;
cNoise m_Noise;
int m_Size; // relative size of the cave systems' caves. Average number of blocks of each initial tunnel
int m_MaxOffset; // maximum offset of the cave nest origin from the grid cell the nest belongs to
int m_Grid; // average spacing of the nests
- cCaveSystems m_Cache;
-
- /// Clears everything from the cache
- void ClearCache(void);
-
- /// Returns all caves that *may* intersect the given chunk. All the caves are valid until the next call to this function.
- void GetCavesForChunk(int a_ChunkX, int a_ChunkZ, cCaveSystems & a_Caves);
-
- // cStructGen override:
- virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
+
+ // cGridStructGen override:
+ virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
} ;
diff --git a/src/Generating/GridStructGen.cpp b/src/Generating/GridStructGen.cpp
new file mode 100644
index 000000000..3bbc89054
--- /dev/null
+++ b/src/Generating/GridStructGen.cpp
@@ -0,0 +1,126 @@
+
+// GridStructGen.cpp
+
+// Implements the cGridStructGen class representing a common base class for structure generators that place structures in a semi-random grid
+
+#include "Globals.h"
+#include "GridStructGen.h"
+
+
+
+
+cGridStructGen::cGridStructGen(
+ int a_Seed,
+ int a_GridSizeX, int a_GridSizeZ,
+ int a_MaxStructureSizeX, int a_MaxStructureSizeZ,
+ size_t a_MaxCacheSize
+) :
+ m_Seed(a_Seed),
+ m_GridSizeX(a_GridSizeX),
+ m_GridSizeZ(a_GridSizeZ),
+ m_MaxStructureSizeX(a_MaxStructureSizeX),
+ m_MaxStructureSizeZ(a_MaxStructureSizeZ),
+ m_MaxCacheSize(a_MaxCacheSize)
+{
+}
+
+
+
+
+
+void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructurePtrs & a_Structures)
+{
+ // Calculate the min and max grid coords of the structures to be returned:
+ int MinBlockX = a_ChunkX * cChunkDef::Width - m_MaxStructureSizeX;
+ int MinBlockZ = a_ChunkZ * cChunkDef::Width - m_MaxStructureSizeZ;
+ int MaxBlockX = a_ChunkX * cChunkDef::Width + m_MaxStructureSizeX + cChunkDef::Width - 1;
+ int MaxBlockZ = a_ChunkZ * cChunkDef::Width + m_MaxStructureSizeZ + cChunkDef::Width - 1;
+ int MinGridX = MinBlockX / m_GridSizeX;
+ int MinGridZ = MinBlockZ / m_GridSizeZ;
+ int MaxGridX = (MaxBlockX + m_GridSizeX - 1) / m_GridSizeX;
+ int MaxGridZ = (MaxBlockZ + m_GridSizeZ - 1) / m_GridSizeZ;
+ int MinX = MinGridX * m_GridSizeX;
+ int MaxX = MaxGridX * m_GridSizeX;
+ int MinZ = MinGridZ * m_GridSizeZ;
+ int MaxZ = MaxGridZ * m_GridSizeZ;
+
+ // Walk the cache, move each structure that we want into a_Structures:
+ for (cStructurePtrs::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;)
+ {
+ if (
+ ((*itr)->m_OriginX >= MinX) && ((*itr)->m_OriginX < MaxX) &&
+ ((*itr)->m_OriginZ >= MinZ) && ((*itr)->m_OriginZ < MaxZ)
+ )
+ {
+ // want
+ a_Structures.push_back(*itr);
+ itr = m_Cache.erase(itr);
+ }
+ else
+ {
+ // don't want
+ ++itr;
+ }
+ } // for itr - m_Cache[]
+
+ // Create those structures that haven't been in the cache:
+ for (int x = MinGridX; x < MaxGridX; x++)
+ {
+ int OriginX = x * m_GridSizeX;
+ for (int z = MinGridZ; z < MaxGridZ; z++)
+ {
+ int OriginZ = z * m_GridSizeZ;
+ bool Found = false;
+ for (cStructurePtrs::const_iterator itr = a_Structures.begin(), end = a_Structures.end(); itr != end; ++itr)
+ {
+ if (((*itr)->m_OriginX == OriginX) && ((*itr)->m_OriginZ == OriginZ))
+ {
+ Found = true;
+ break;
+ }
+ } // for itr - a_Structures[]
+ if (!Found)
+ {
+ a_Structures.push_back(CreateStructure(OriginX, OriginZ));
+ }
+ } // for z
+ } // for x
+
+ // Copy a_Forts into m_Cache to the beginning:
+ cStructurePtrs StructuresCopy (a_Structures);
+ m_Cache.splice(m_Cache.begin(), StructuresCopy, StructuresCopy.begin(), StructuresCopy.end());
+
+ // Trim the cache if it's too long:
+ size_t CacheSize = 0;
+ for (cStructurePtrs::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end; ++itr)
+ {
+ CacheSize += (*itr)->GetCacheCost();
+ if (CacheSize > m_MaxCacheSize)
+ {
+ // Erase all items from this one till the cache end
+ m_Cache.erase(itr, m_Cache.end());
+ break;
+ }
+ }
+}
+
+
+
+
+
+void cGridStructGen::GenFinish(cChunkDesc & a_ChunkDesc)
+{
+ int ChunkX = a_ChunkDesc.GetChunkX();
+ int ChunkZ = a_ChunkDesc.GetChunkZ();
+ cStructurePtrs Structures;
+ GetStructuresForChunk(ChunkX, ChunkZ, Structures);
+ for (cStructurePtrs::const_iterator itr = Structures.begin(); itr != Structures.end(); ++itr)
+ {
+ (*itr)->DrawIntoChunk(a_ChunkDesc);
+ } // for itr - Structures[]
+}
+
+
+
+
+
diff --git a/src/Generating/GridStructGen.h b/src/Generating/GridStructGen.h
new file mode 100644
index 000000000..234cc75c5
--- /dev/null
+++ b/src/Generating/GridStructGen.h
@@ -0,0 +1,124 @@
+
+// GridStructGen.h
+
+// Declares the cGridStructGen class representing a common base class for structure generators that place structures in a semi-random grid
+
+
+
+
+
+#pragma once
+
+#include "ComposableGenerator.h"
+
+
+
+
+
+/** Generates structures in a semi-random grid.
+Defines a grid in the XZ space with predefined cell size in each direction. Each cell then receives exactly
+one structure (provided by the descendant class). The structure is placed within the cell, but doesn't need
+to be bounded by the cell, it can be well outside the cell; the generator uses the MaxStructureSize parameter
+to determine how far away from the cell the structure can be at most.
+This class provides a cache for the structures generated for successive chunks and manages that cache. It
+also provides the cFinishGen override that uses the cache to actually generate the structure into chunk data.
+
+After generating each chunk the cache is checked for size, each item in the cache has a cost associated with
+it and the cache is trimmed (from its least-recently-used end) so that the sum of the cost in the cache is
+less than m_MaxCacheSize
+
+To use this class, declare a descendant class that implements the overridable methods, then create an
+instance of that class. The descendant must provide the CreateStructure() function that is called to generate
+a structure at the specific grid cell.
+
+The descendant must use a specific cStructure descendant to provide the actual structure that gets generated.
+The structure must provide the DrawIntoChunk() function that generates the structure into the chunk data, and
+can override the GetCacheCost() function that returns the cost of that structure in the cache.
+*/
+class cGridStructGen :
+ public cFinishGen
+{
+public:
+ cGridStructGen(
+ int a_Seed,
+ int a_GridSizeX, int a_GridSizeZ,
+ int a_MaxStructureSizeX, int a_MaxStructureSizeZ,
+ size_t a_MaxCacheSize
+ );
+
+protected:
+ /** Represents a single structure that occupies the grid point. Knows how to draw itself into a chunk. */
+ class cStructure
+ {
+ public:
+ /** The origin (the coords of the gridpoint for which the structure is generated) */
+ int m_OriginX, m_OriginZ;
+
+
+ /** Creates a structure that has its originset at the specified coords. */
+ cStructure (int a_OriginX, int a_OriginZ) :
+ m_OriginX(a_OriginX),
+ m_OriginZ(a_OriginZ)
+ {
+ }
+
+ // Force a virtual destructor in descendants:
+ virtual ~cStructure() {}
+
+ /** Draws self into the specified chunk */
+ virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) = 0;
+
+ /** Returns the cost of keeping this structure in the cache */
+ virtual size_t GetCacheCost(void) const { return 1; }
+ } ;
+ typedef SharedPtr<cStructure> cStructurePtr;
+ typedef std::list<cStructurePtr> cStructurePtrs;
+
+
+ /** Seed for generating the semi-random grid. */
+ int m_Seed;
+
+ /** The size of each grid's cell in the X axis */
+ int m_GridSizeX;
+
+ /** The size of each grid's cell in the Z axis */
+ int m_GridSizeZ;
+
+ /** Maximum theoretical size of the structure in the X axis.
+ This limits the structures considered for a single chunk, so the lesser the number, the better performance.
+ Structures large than this may get cropped. */
+ int m_MaxStructureSizeX;
+
+ /** Maximum theoretical size of the structure in the Z axis.
+ This limits the structures considered for a single chunk, so the lesser the number, the better performance.
+ Structures large than this may get cropped. */
+ int m_MaxStructureSizeZ;
+
+ /** Maximum allowed sum of costs for items in the cache. Items that are over this cost are removed from the
+ cache, oldest-first */
+ size_t m_MaxCacheSize;
+
+ /** Cache for the most recently generated structures, ordered by the recentness. */
+ cStructurePtrs m_Cache;
+
+
+ /** Clears everything from the cache */
+ void ClearCache(void);
+
+ /** Returns all structures that may intersect the given chunk.
+ The structures are considered as intersecting iff their bounding box (defined by m_MaxStructureSize)
+ around their gridpoint intersects the chunk. */
+ void GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructurePtrs & a_Structures);
+
+ // cFinishGen overrides:
+ virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
+
+ // Functions for the descendants to override:
+ /** Create a new structure at the specified gridpoint */
+ virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) = 0;
+} ;
+
+
+
+
+
diff --git a/src/Generating/MineShafts.cpp b/src/Generating/MineShafts.cpp
index 231295c3f..391e4c04f 100644
--- a/src/Generating/MineShafts.cpp
+++ b/src/Generating/MineShafts.cpp
@@ -25,12 +25,6 @@ in a depth-first processing. Each of the descendants will branch randomly, if no
-static const int NEIGHBORHOOD_SIZE = 3;
-
-
-
-
-
class cMineShaft abstract
{
public:
@@ -234,10 +228,12 @@ protected:
-class cStructGenMineShafts::cMineShaftSystem
+class cStructGenMineShafts::cMineShaftSystem :
+ public cGridStructGen::cStructure
{
+ typedef cGridStructGen::cStructure super;
+
public:
- int m_BlockX, m_BlockZ; ///< The pivot point on which the system is generated
int m_GridSize; ///< Maximum offset of the dirtroom from grid center, * 2, in each direction
int m_MaxRecursion; ///< Maximum recursion level (initialized from cStructGenMineShafts::m_MaxRecursion)
int m_ProbLevelCorridor; ///< Probability level of a branch object being the corridor
@@ -249,17 +245,15 @@ public:
cMineShafts m_MineShafts; ///< List of cMineShaft descendants that comprise this system
cCuboid m_BoundingBox; ///< Bounding box into which all of the components need to fit
- /// Creates and generates the entire system
+
+ /** Creates and generates the entire system */
cMineShaftSystem(
- int a_BlockX, int a_BlockZ, int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise,
+ int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise,
int a_ProbLevelCorridor, int a_ProbLevelCrossing, int a_ProbLevelStaircase
);
~cMineShaftSystem();
- /// Carves the system into the chunk data
- void ProcessChunk(cChunkDesc & a_Chunk);
-
/** Creates new cMineShaft descendant connected at the specified point, heading the specified direction,
if it fits, appends it to the list and calls its AppendBranches()
*/
@@ -269,8 +263,11 @@ public:
int a_RecursionLevel
);
- /// Returns true if none of the objects in m_MineShafts intersect with the specified bounding box and the bounding box is valid
+ /** Returns true if none of the objects in m_MineShafts intersect with the specified bounding box and the bounding box is valid */
bool CanAppend(const cCuboid & a_BoundingBox);
+
+ // cGridStructGen::cStructure overrides:
+ virtual void DrawIntoChunk(cChunkDesc & a_Chunk);
} ;
@@ -281,11 +278,10 @@ public:
// cStructGenMineShafts::cMineShaftSystem:
cStructGenMineShafts::cMineShaftSystem::cMineShaftSystem(
- int a_BlockX, int a_BlockZ, int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise,
+ int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise,
int a_ProbLevelCorridor, int a_ProbLevelCrossing, int a_ProbLevelStaircase
) :
- m_BlockX(a_BlockX),
- m_BlockZ(a_BlockZ),
+ super(a_OriginX, a_OriginZ),
m_GridSize(a_GridSize),
m_MaxRecursion(8), // TODO: settable
m_ProbLevelCorridor(a_ProbLevelCorridor),
@@ -330,7 +326,7 @@ cStructGenMineShafts::cMineShaftSystem::~cMineShaftSystem()
-void cStructGenMineShafts::cMineShaftSystem::ProcessChunk(cChunkDesc & a_Chunk)
+void cStructGenMineShafts::cMineShaftSystem::DrawIntoChunk(cChunkDesc & a_Chunk)
{
for (cMineShafts::const_iterator itr = m_MineShafts.begin(), end = m_MineShafts.end(); itr != end; ++itr)
{
@@ -409,15 +405,15 @@ cMineShaftDirtRoom::cMineShaftDirtRoom(cStructGenMineShafts::cMineShaftSystem &
super(a_Parent, mskDirtRoom)
{
// Make the room of random size, min 10 x 4 x 10; max 18 x 12 x 18:
- int rnd = a_Noise.IntNoise3DInt(a_Parent.m_BlockX, 0, a_Parent.m_BlockZ) / 7;
+ int rnd = a_Noise.IntNoise3DInt(a_Parent.m_OriginX, 0, a_Parent.m_OriginZ) / 7;
int OfsX = (rnd % a_Parent.m_GridSize) - a_Parent.m_GridSize / 2;
rnd >>= 12;
int OfsZ = (rnd % a_Parent.m_GridSize) - a_Parent.m_GridSize / 2;
- rnd = a_Noise.IntNoise3DInt(a_Parent.m_BlockX, 1000, a_Parent.m_BlockZ) / 11;
- m_BoundingBox.p1.x = a_Parent.m_BlockX + OfsX;
+ rnd = a_Noise.IntNoise3DInt(a_Parent.m_OriginX, 1000, a_Parent.m_OriginZ) / 11;
+ m_BoundingBox.p1.x = a_Parent.m_OriginX + OfsX;
m_BoundingBox.p2.x = m_BoundingBox.p1.x + 10 + (rnd % 8);
rnd >>= 4;
- m_BoundingBox.p1.z = a_Parent.m_BlockZ + OfsZ;
+ m_BoundingBox.p1.z = a_Parent.m_OriginZ + OfsZ;
m_BoundingBox.p2.z = m_BoundingBox.p1.z + 10 + (rnd % 8);
rnd >>= 4;
m_BoundingBox.p1.y = 20;
@@ -543,7 +539,7 @@ cMineShaft * cMineShaftCorridor::CreateAndFit(
{
cCuboid BoundingBox(a_PivotX, a_PivotY - 1, a_PivotZ);
BoundingBox.p2.y += 3;
- int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7;
+ int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + (int)a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7;
int NumSegments = 2 + (rnd) % (MAX_SEGMENTS - 1); // 2 .. MAX_SEGMENTS
switch (a_Direction)
{
@@ -985,7 +981,7 @@ cMineShaft * cMineShaftCrossing::CreateAndFit(
)
{
cCuboid BoundingBox(a_PivotX, a_PivotY - 1, a_PivotZ);
- int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7;
+ int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + (int)a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7;
BoundingBox.p2.y += 3;
if ((rnd % 4) < 2)
{
@@ -1127,7 +1123,7 @@ cMineShaft * cMineShaftStaircase::CreateAndFit(
cNoise & a_Noise
)
{
- int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7;
+ int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + (int)a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7;
cCuboid Box;
switch (a_Direction)
{
@@ -1287,6 +1283,7 @@ cStructGenMineShafts::cStructGenMineShafts(
int a_Seed, int a_GridSize, int a_MaxSystemSize,
int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase
) :
+ super(a_Seed, a_GridSize, a_GridSize, 120 + a_MaxSystemSize * 10, 120 + a_MaxSystemSize * 10, 100),
m_Noise(a_Seed),
m_GridSize(a_GridSize),
m_MaxSystemSize(a_MaxSystemSize),
@@ -1300,125 +1297,9 @@ cStructGenMineShafts::cStructGenMineShafts(
-cStructGenMineShafts::~cStructGenMineShafts()
-{
- ClearCache();
-}
-
-
-
-
-
-void cStructGenMineShafts::ClearCache(void)
-{
- for (cMineShaftSystems::const_iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end; ++itr)
- {
- delete *itr;
- } // for itr - m_Cache[]
- m_Cache.clear();
-}
-
-
-
-
-
-void cStructGenMineShafts::GetMineShaftSystemsForChunk(
- int a_ChunkX, int a_ChunkZ,
- cStructGenMineShafts::cMineShaftSystems & a_MineShafts
-)
-{
- int BaseX = a_ChunkX * cChunkDef::Width / m_GridSize;
- int BaseZ = a_ChunkZ * cChunkDef::Width / m_GridSize;
- if (BaseX < 0)
- {
- --BaseX;
- }
- if (BaseZ < 0)
- {
- --BaseZ;
- }
- BaseX -= NEIGHBORHOOD_SIZE / 2;
- BaseZ -= NEIGHBORHOOD_SIZE / 2;
-
- // Walk the cache, move each cave system that we want into a_Mineshafts:
- int StartX = BaseX * m_GridSize;
- int EndX = (BaseX + NEIGHBORHOOD_SIZE + 1) * m_GridSize;
- int StartZ = BaseZ * m_GridSize;
- int EndZ = (BaseZ + NEIGHBORHOOD_SIZE + 1) * m_GridSize;
- for (cMineShaftSystems::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;)
- {
- if (
- ((*itr)->m_BlockX >= StartX) && ((*itr)->m_BlockX < EndX) &&
- ((*itr)->m_BlockZ >= StartZ) && ((*itr)->m_BlockZ < EndZ)
- )
- {
- // want
- a_MineShafts.push_back(*itr);
- itr = m_Cache.erase(itr);
- }
- else
- {
- // don't want
- ++itr;
- }
- } // for itr - m_Cache[]
-
- for (int x = 0; x < NEIGHBORHOOD_SIZE; x++)
- {
- int RealX = (BaseX + x) * m_GridSize;
- for (int z = 0; z < NEIGHBORHOOD_SIZE; z++)
- {
- int RealZ = (BaseZ + z) * m_GridSize;
- bool Found = false;
- for (cMineShaftSystems::const_iterator itr = a_MineShafts.begin(), end = a_MineShafts.end(); itr != end; ++itr)
- {
- if (((*itr)->m_BlockX == RealX) && ((*itr)->m_BlockZ == RealZ))
- {
- Found = true;
- break;
- }
- } // for itr - a_Mineshafts
- if (!Found)
- {
- a_MineShafts.push_back(new cMineShaftSystem(RealX, RealZ, m_GridSize, m_MaxSystemSize, m_Noise, m_ProbLevelCorridor, m_ProbLevelCrossing, m_ProbLevelStaircase));
- }
- } // for z
- } // for x
-
- // Copy a_MineShafts into m_Cache to the beginning:
- cMineShaftSystems MineShaftsCopy(a_MineShafts);
- m_Cache.splice(m_Cache.begin(), MineShaftsCopy, MineShaftsCopy.begin(), MineShaftsCopy.end());
-
- // Trim the cache if it's too long:
- if (m_Cache.size() > 100)
- {
- cMineShaftSystems::iterator itr = m_Cache.begin();
- std::advance(itr, 100);
- for (cMineShaftSystems::iterator end = m_Cache.end(); itr != end; ++itr)
- {
- delete *itr;
- }
- itr = m_Cache.begin();
- std::advance(itr, 100);
- m_Cache.erase(itr, m_Cache.end());
- }
-}
-
-
-
-
-
-
-void cStructGenMineShafts::GenFinish(cChunkDesc & a_ChunkDesc)
+cGridStructGen::cStructurePtr cStructGenMineShafts::CreateStructure(int a_OriginX, int a_OriginZ)
{
- int ChunkX = a_ChunkDesc.GetChunkX();
- int ChunkZ = a_ChunkDesc.GetChunkZ();
- cMineShaftSystems MineShafts;
- GetMineShaftSystemsForChunk(ChunkX, ChunkZ, MineShafts);
- for (cMineShaftSystems::const_iterator itr = MineShafts.begin(); itr != MineShafts.end(); ++itr)
- {
- (*itr)->ProcessChunk(a_ChunkDesc);
- } // for itr - MineShafts[]
+ return cStructurePtr(new cMineShaftSystem(a_OriginX, a_OriginZ, m_GridSize, m_MaxSystemSize, m_Noise, m_ProbLevelCorridor, m_ProbLevelCrossing, m_ProbLevelStaircase));
}
diff --git a/src/Generating/MineShafts.h b/src/Generating/MineShafts.h
index ba32e75ad..c29b6cdac 100644
--- a/src/Generating/MineShafts.h
+++ b/src/Generating/MineShafts.h
@@ -9,7 +9,7 @@
#pragma once
-#include "ComposableGenerator.h"
+#include "GridStructGen.h"
#include "../Noise.h"
@@ -17,16 +17,16 @@
class cStructGenMineShafts :
- public cFinishGen
+ public cGridStructGen
{
+ typedef cGridStructGen super;
+
public:
cStructGenMineShafts(
int a_Seed, int a_GridSize, int a_MaxSystemSize,
int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase
);
- virtual ~cStructGenMineShafts();
-
protected:
friend class cMineShaft;
friend class cMineShaftDirtRoom;
@@ -34,26 +34,16 @@ protected:
friend class cMineShaftCrossing;
friend class cMineShaftStaircase;
class cMineShaftSystem; // fwd: MineShafts.cpp
- typedef std::list<cMineShaftSystem *> cMineShaftSystems;
- cNoise m_Noise;
- int m_GridSize; ///< Average spacing of the systems
- int m_MaxSystemSize; ///< Maximum blcok size of a mineshaft system
- int m_ProbLevelCorridor; ///< Probability level of a branch object being the corridor
- int m_ProbLevelCrossing; ///< Probability level of a branch object being the crossing, minus Corridor
- int m_ProbLevelStaircase; ///< Probability level of a branch object being the staircase, minus Crossing
- cMineShaftSystems m_Cache; ///< Cache of the most recently used systems. MoveToFront used.
+ cNoise m_Noise;
+ int m_GridSize; ///< Average spacing of the systems
+ int m_MaxSystemSize; ///< Maximum blcok size of a mineshaft system
+ int m_ProbLevelCorridor; ///< Probability level of a branch object being the corridor
+ int m_ProbLevelCrossing; ///< Probability level of a branch object being the crossing, minus Corridor
+ int m_ProbLevelStaircase; ///< Probability level of a branch object being the staircase, minus Crossing
- /// Clears everything from the cache
- void ClearCache(void);
-
- /** Returns all systems that *may* intersect the given chunk.
- All the systems are valid until the next call to this function (which may delete some of the pointers).
- */
- void GetMineShaftSystemsForChunk(int a_ChunkX, int a_ChunkZ, cMineShaftSystems & a_MineShaftSystems);
-
- // cFinishGen overrides:
- virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
+ // cGridStructGen overrides:
+ virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
} ;
diff --git a/src/Generating/NetherFortGen.cpp b/src/Generating/NetherFortGen.cpp
index d90fdeb0a..3867ec80c 100644
--- a/src/Generating/NetherFortGen.cpp
+++ b/src/Generating/NetherFortGen.cpp
@@ -11,29 +11,24 @@
-static const int NEIGHBORHOOD_SIZE = 3;
-
-
-
-
-
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cNetherFortGen::cNetherFort:
-class cNetherFortGen::cNetherFort
+class cNetherFortGen::cNetherFort :
+ public cGridStructGen::cStructure
{
+ typedef cGridStructGen::cStructure super;
+
public:
cNetherFortGen & m_ParentGen;
- int m_BlockX, m_BlockZ;
int m_GridSize;
int m_Seed;
cPlacedPieces m_Pieces;
- cNetherFort(cNetherFortGen & a_ParentGen, int a_BlockX, int a_BlockZ, int a_GridSize, int a_MaxDepth, int a_Seed) :
+ cNetherFort(cNetherFortGen & a_ParentGen, int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxDepth, int a_Seed) :
+ super(a_OriginX, a_OriginZ),
m_ParentGen(a_ParentGen),
- m_BlockX(a_BlockX),
- m_BlockZ(a_BlockZ),
m_GridSize(a_GridSize),
m_Seed(a_Seed)
{
@@ -43,8 +38,8 @@ public:
// Generate pieces:
for (int i = 0; m_Pieces.size() < (size_t)(a_MaxDepth * a_MaxDepth / 8 + a_MaxDepth); i++)
{
- cBFSPieceGenerator pg(m_ParentGen, a_Seed + i);
- pg.PlacePieces(a_BlockX, BlockY, a_BlockZ, a_MaxDepth, m_Pieces);
+ cBFSPieceGenerator pg(cNetherFortGen::m_PiecePool, a_Seed + i);
+ pg.PlacePieces(a_OriginX, BlockY, a_OriginZ, a_MaxDepth, m_Pieces);
}
}
@@ -56,7 +51,7 @@ public:
/** Carves the system into the chunk data */
- void ProcessChunk(cChunkDesc & a_Chunk)
+ virtual void DrawIntoChunk(cChunkDesc & a_Chunk)
{
for (cPlacedPieces::const_iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr)
{
@@ -107,214 +102,30 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cNetherFortGen:
+cPrefabPiecePool cNetherFortGen::m_PiecePool(g_NetherFortPrefabs, g_NetherFortPrefabsCount, g_NetherFortStartingPrefabs, g_NetherFortStartingPrefabsCount);
+
+
+
+
+
cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth) :
- m_Seed(a_Seed),
- m_Noise(a_Seed),
- m_GridSize(a_GridSize),
+ super(a_Seed, a_GridSize, a_GridSize, a_MaxDepth * 10, a_MaxDepth * 10, 200),
m_MaxDepth(a_MaxDepth)
{
- // Initialize the prefabs:
- for (size_t i = 0; i < g_NetherFortPrefabsCount; i++)
- {
- cPrefab * Prefab = new cPrefab(g_NetherFortPrefabs[i]);
- m_AllPieces.push_back(Prefab);
- if (Prefab->HasConnectorType(0))
- {
- m_OuterPieces.push_back(Prefab);
- }
- if (Prefab->HasConnectorType(1))
- {
- m_InnerPieces.push_back(Prefab);
- }
- }
-
- // Initialize the starting piece prefabs:
- for (size_t i = 0; i < g_NetherFortStartingPrefabsCount; i++)
- {
- m_StartingPieces.push_back(new cPrefab(g_NetherFortStartingPrefabs[i]));
- }
-
/*
// DEBUG: Try one round of placement:
cPlacedPieces Pieces;
- cBFSPieceGenerator pg(*this, a_Seed);
+ cBFSPieceGenerator pg(m_PiecePool, a_Seed);
pg.PlacePieces(0, 64, 0, a_MaxDepth, Pieces);
- */
-}
-
-
-
-
-
-cNetherFortGen::~cNetherFortGen()
-{
- ClearCache();
- for (cPieces::iterator itr = m_AllPieces.begin(), end = m_AllPieces.end(); itr != end; ++itr)
- {
- delete *itr;
- } // for itr - m_AllPieces[]
- m_AllPieces.clear();
-}
-
-
-
-
-
-void cNetherFortGen::ClearCache(void)
-{
- // TODO
-}
-
-
-
-
-
-void cNetherFortGen::GetFortsForChunk(int a_ChunkX, int a_ChunkZ, cNetherForts & a_Forts)
-{
- int BaseX = a_ChunkX * cChunkDef::Width / m_GridSize;
- int BaseZ = a_ChunkZ * cChunkDef::Width / m_GridSize;
- if (BaseX < 0)
- {
- --BaseX;
- }
- if (BaseZ < 0)
- {
- --BaseZ;
- }
- BaseX -= NEIGHBORHOOD_SIZE / 2;
- BaseZ -= NEIGHBORHOOD_SIZE / 2;
-
- // Walk the cache, move each cave system that we want into a_Forts:
- int StartX = BaseX * m_GridSize;
- int EndX = (BaseX + NEIGHBORHOOD_SIZE + 1) * m_GridSize;
- int StartZ = BaseZ * m_GridSize;
- int EndZ = (BaseZ + NEIGHBORHOOD_SIZE + 1) * m_GridSize;
- for (cNetherForts::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;)
- {
- if (
- ((*itr)->m_BlockX >= StartX) && ((*itr)->m_BlockX < EndX) &&
- ((*itr)->m_BlockZ >= StartZ) && ((*itr)->m_BlockZ < EndZ)
- )
- {
- // want
- a_Forts.push_back(*itr);
- itr = m_Cache.erase(itr);
- }
- else
- {
- // don't want
- ++itr;
- }
- } // for itr - m_Cache[]
-
- // Create those forts that haven't been in the cache:
- for (int x = 0; x < NEIGHBORHOOD_SIZE; x++)
- {
- int RealX = (BaseX + x) * m_GridSize;
- for (int z = 0; z < NEIGHBORHOOD_SIZE; z++)
- {
- int RealZ = (BaseZ + z) * m_GridSize;
- bool Found = false;
- for (cNetherForts::const_iterator itr = a_Forts.begin(), end = a_Forts.end(); itr != end; ++itr)
- {
- if (((*itr)->m_BlockX == RealX) && ((*itr)->m_BlockZ == RealZ))
- {
- Found = true;
- break;
- }
- } // for itr - a_Mineshafts
- if (!Found)
- {
- a_Forts.push_back(new cNetherFort(*this, RealX, RealZ, m_GridSize, m_MaxDepth, m_Seed));
- }
- } // for z
- } // for x
-
- // Copy a_Forts into m_Cache to the beginning:
- cNetherForts FortsCopy (a_Forts);
- m_Cache.splice(m_Cache.begin(), FortsCopy, FortsCopy.begin(), FortsCopy.end());
-
- // Trim the cache if it's too long:
- if (m_Cache.size() > 100)
- {
- cNetherForts::iterator itr = m_Cache.begin();
- std::advance(itr, 100);
- for (cNetherForts::iterator end = m_Cache.end(); itr != end; ++itr)
- {
- delete *itr;
- }
- itr = m_Cache.begin();
- std::advance(itr, 100);
- m_Cache.erase(itr, m_Cache.end());
- }
-}
-
-
-
-
-
-void cNetherFortGen::GenFinish(cChunkDesc & a_ChunkDesc)
-{
- int ChunkX = a_ChunkDesc.GetChunkX();
- int ChunkZ = a_ChunkDesc.GetChunkZ();
- cNetherForts Forts;
- GetFortsForChunk(ChunkX, ChunkZ, Forts);
- for (cNetherForts::const_iterator itr = Forts.begin(); itr != Forts.end(); ++itr)
- {
- (*itr)->ProcessChunk(a_ChunkDesc);
- } // for itr - Forts[]
-}
-
-
-
-
-
-cPieces cNetherFortGen::GetPiecesWithConnector(int a_ConnectorType)
-{
- switch (a_ConnectorType)
- {
- case 0: return m_OuterPieces;
- case 1: return m_InnerPieces;
- default: return cPieces();
- }
+ //*/
}
-cPieces cNetherFortGen::GetStartingPieces(void)
+cGridStructGen::cStructurePtr cNetherFortGen::CreateStructure(int a_OriginX, int a_OriginZ)
{
- return m_StartingPieces;
+ return cStructurePtr(new cNetherFort(*this, a_OriginX, a_OriginZ, m_GridSizeX, m_MaxDepth, m_Seed));
}
-
-
-
-
-int cNetherFortGen::GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, const cPiece & a_NewPiece)
-{
- return ((const cPrefab &)a_NewPiece).GetPieceWeight(a_PlacedPiece, a_ExistingConnector);
-}
-
-
-
-
-
-void cNetherFortGen::PiecePlaced(const cPiece & a_Piece)
-{
- UNUSED(a_Piece);
-}
-
-
-
-
-
-void cNetherFortGen::Reset(void)
-{
- // Nothing needed
-}
-
-
-
-
diff --git a/src/Generating/NetherFortGen.h b/src/Generating/NetherFortGen.h
index d51596b9e..f35801a3c 100644
--- a/src/Generating/NetherFortGen.h
+++ b/src/Generating/NetherFortGen.h
@@ -10,77 +10,34 @@
#pragma once
#include "ComposableGenerator.h"
-#include "PieceGenerator.h"
+#include "PrefabPiecePool.h"
+#include "GridStructGen.h"
class cNetherFortGen :
- public cFinishGen,
- public cPiecePool
+ public cGridStructGen
{
+ typedef cGridStructGen super;
+
public:
cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth);
- virtual ~cNetherFortGen();
-
protected:
friend class cNetherFortPerfTest; // fwd: NetherFortGen.cpp
class cNetherFort; // fwd: NetherFortGen.cpp
- typedef std::list<cNetherFort *> cNetherForts;
-
-
- /** The seed used for generating*/
- int m_Seed;
-
- /** The noise used for generating */
- cNoise m_Noise;
-
- /** Average spacing between the fortresses*/
- int m_GridSize;
/** Maximum depth of the piece-generator tree */
int m_MaxDepth;
-
- /** Cache of the most recently used systems. MoveToFront used. */
- cNetherForts m_Cache;
- /** All the pieces that are allowed for building.
- This is the list that's used for memory allocation and deallocation for the pieces. */
- cPieces m_AllPieces;
+ /** The pool of pieces to use for generating. Static, so that it's shared by multiple generators. */
+ static cPrefabPiecePool m_PiecePool;
- /** The pieces that are used as starting pieces.
- This list is not shared and the pieces need deallocation. */
- cPieces m_StartingPieces;
-
- /** The pieces that have an "outer" connector.
- The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */
- cPieces m_OuterPieces;
-
- /** The pieces that have an "inner" connector.
- The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */
- cPieces m_InnerPieces;
-
- /** Clears everything from the cache.
- Also invalidates the forst returned by GetFortsForChunk(). */
- void ClearCache(void);
-
- /** Returns all forts that *may* intersect the given chunk.
- The returned forts live within m_Cache.They are valid until the next call
- to this function (which may delete some of the pointers). */
- void GetFortsForChunk(int a_ChunkX, int a_ChunkZ, cNetherForts & a_Forts);
-
- // cFinishGen overrides:
- virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
-
- // cPiecePool overrides:
- virtual cPieces GetPiecesWithConnector(int a_ConnectorType) override;
- virtual cPieces GetStartingPieces(void) override;
- virtual int GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, const cPiece & a_NewPiece) override;
- virtual void PiecePlaced(const cPiece & a_Piece) override;
- virtual void Reset(void) override;
+ // cGridStructGen overrides:
+ virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
} ;
diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp
index 8e9a48be6..ce19c1c95 100644
--- a/src/Generating/PieceGenerator.cpp
+++ b/src/Generating/PieceGenerator.cpp
@@ -339,9 +339,9 @@ cPlacedPiece * cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockY, i
int NumRotations = 1;
for (size_t i = 1; i < ARRAYCOUNT(Rotations); i++)
{
- if (StartingPiece->CanRotateCCW(i))
+ if (StartingPiece->CanRotateCCW((int)i))
{
- Rotations[NumRotations] = i;
+ Rotations[NumRotations] = (int)i;
NumRotations += 1;
}
}
@@ -388,7 +388,8 @@ bool cPieceGenerator::TryPlacePieceAtConnector(
// Get a list of available connections:
const int * RotTable = DirectionRotationTable[a_Connector.m_Direction];
cConnections Connections;
- cPieces AvailablePieces = m_PiecePool.GetPiecesWithConnector(a_Connector.m_Type);
+ int WantedConnectorType = -a_Connector.m_Type;
+ cPieces AvailablePieces = m_PiecePool.GetPiecesWithConnector(WantedConnectorType);
Connections.reserve(AvailablePieces.size());
Vector3i ConnPos = a_Connector.m_Pos; // The position at which the new connector should be placed - 1 block away from the connector
AddFaceDirection(ConnPos.x, ConnPos.y, ConnPos.z, a_Connector.m_Direction);
@@ -406,7 +407,7 @@ bool cPieceGenerator::TryPlacePieceAtConnector(
cPiece::cConnectors Connectors = (*itrP)->GetConnectors();
for (cPiece::cConnectors::iterator itrC = Connectors.begin(), endC = Connectors.end(); itrC != endC; ++itrC)
{
- if (itrC->m_Type != a_Connector.m_Type)
+ if (itrC->m_Type != WantedConnectorType)
{
continue;
}
diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h
index f4433b947..16bec3bb4 100644
--- a/src/Generating/PieceGenerator.h
+++ b/src/Generating/PieceGenerator.h
@@ -38,7 +38,8 @@ public:
/** Position relative to the piece */
Vector3i m_Pos;
- /** Type of the connector. Any arbitrary number; the generator connects only connectors of the same type. */
+ /** Type of the connector. Any arbitrary number; the generator connects only connectors of opposite
+ (negative) types. */
int m_Type;
/** Direction in which the connector is facing.
diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp
index 44d5097de..0f20603be 100644
--- a/src/Generating/Prefab.cpp
+++ b/src/Generating/Prefab.cpp
@@ -174,44 +174,47 @@ void cPrefab::Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const
a_Dest.WriteBlockArea(Image, Placement.x, Placement.y, Placement.z, m_MergeStrategy);
// If requested, draw the floor (from the bottom of the prefab down to the nearest non-air)
- int MaxX = Image.GetSizeX();
- int MaxZ = Image.GetSizeZ();
- for (int z = 0; z < MaxZ; z++)
+ if (m_ShouldExtendFloor)
{
- int RelZ = Placement.z + z;
- if ((RelZ < 0) || (RelZ >= cChunkDef::Width))
+ int MaxX = Image.GetSizeX();
+ int MaxZ = Image.GetSizeZ();
+ for (int z = 0; z < MaxZ; z++)
{
- // Z coord outside the chunk
- continue;
- }
- for (int x = 0; x < MaxX; x++)
- {
- int RelX = Placement.x + x;
- if ((RelX < 0) || (RelX >= cChunkDef::Width))
- {
- // X coord outside the chunk
- continue;
- }
- BLOCKTYPE BlockType;
- NIBBLETYPE BlockMeta;
- Image.GetRelBlockTypeMeta(x, 0, z, BlockType, BlockMeta);
- if ((BlockType == E_BLOCK_AIR) || (BlockType == E_BLOCK_SPONGE))
+ int RelZ = Placement.z + z;
+ if ((RelZ < 0) || (RelZ >= cChunkDef::Width))
{
- // Do not expand air nor sponge blocks
+ // Z coord outside the chunk
continue;
}
- for (int y = Placement.y - 1; y >= 0; y--)
+ for (int x = 0; x < MaxX; x++)
{
- BLOCKTYPE ExistingBlock = a_Dest.GetBlockType(RelX, y, RelZ);
- if (ExistingBlock != E_BLOCK_AIR)
+ int RelX = Placement.x + x;
+ if ((RelX < 0) || (RelX >= cChunkDef::Width))
+ {
+ // X coord outside the chunk
+ continue;
+ }
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ Image.GetRelBlockTypeMeta(x, 0, z, BlockType, BlockMeta);
+ if ((BlockType == E_BLOCK_AIR) || (BlockType == E_BLOCK_SPONGE))
{
- // End the expansion for this column, reached the end
- break;
+ // Do not expand air nor sponge blocks
+ continue;
}
- a_Dest.SetBlockTypeMeta(RelX, y, RelZ, BlockType, BlockMeta);
- } // for y
- } // for x
- } // for z
+ for (int y = Placement.y - 1; y >= 0; y--)
+ {
+ BLOCKTYPE ExistingBlock = a_Dest.GetBlockType(RelX, y, RelZ);
+ if (ExistingBlock != E_BLOCK_AIR)
+ {
+ // End the expansion for this column, reached the end
+ break;
+ }
+ a_Dest.SetBlockTypeMeta(RelX, y, RelZ, BlockType, BlockMeta);
+ } // for y
+ } // for x
+ } // for z
+ }
}
diff --git a/src/Generating/PrefabPiecePool.cpp b/src/Generating/PrefabPiecePool.cpp
new file mode 100644
index 000000000..ed9340815
--- /dev/null
+++ b/src/Generating/PrefabPiecePool.cpp
@@ -0,0 +1,121 @@
+
+// PrefabPiecePool.cpp
+
+// Implements the cPrefabPiecePool class that represents a cPiecePool descendant that uses cPrefab instances as the pieces
+
+#include "Globals.h"
+#include "PrefabPiecePool.h"
+
+
+
+
+
+cPrefabPiecePool::cPrefabPiecePool(
+ const cPrefab::sDef * a_PieceDefs, size_t a_NumPieceDefs,
+ const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs
+)
+{
+ AddPieceDefs(a_PieceDefs, a_NumPieceDefs);
+ if (a_StartingPieceDefs != NULL)
+ {
+ AddStartingPieceDefs(a_StartingPieceDefs, a_NumStartingPieceDefs);
+ }
+}
+
+
+
+
+
+void cPrefabPiecePool::AddPieceDefs(const cPrefab::sDef * a_PieceDefs, size_t a_NumPieceDefs)
+{
+ ASSERT(a_PieceDefs != NULL);
+ for (size_t i = 0; i < a_NumPieceDefs; i++)
+ {
+ cPrefab * Prefab = new cPrefab(a_PieceDefs[i]);
+ m_AllPieces.push_back(Prefab);
+ AddToPerConnectorMap(Prefab);
+ }
+}
+
+
+
+
+
+void cPrefabPiecePool::AddStartingPieceDefs(const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs)
+{
+ ASSERT(a_StartingPieceDefs != NULL);
+ for (size_t i = 0; i < a_NumStartingPieceDefs; i++)
+ {
+ cPrefab * Prefab = new cPrefab(a_StartingPieceDefs[i]);
+ m_StartingPieces.push_back(Prefab);
+ }
+}
+
+
+
+
+
+void cPrefabPiecePool::AddToPerConnectorMap(cPrefab * a_Prefab)
+{
+ cPiece::cConnectors Connectors = ((const cPiece *)a_Prefab)->GetConnectors();
+ for (cPiece::cConnectors::const_iterator itr = Connectors.begin(), end = Connectors.end(); itr != end; ++itr)
+ {
+ m_PiecesByConnector[itr->m_Type].push_back(a_Prefab);
+ }
+}
+
+
+
+
+cPieces cPrefabPiecePool::GetPiecesWithConnector(int a_ConnectorType)
+{
+ return m_PiecesByConnector[a_ConnectorType];
+}
+
+
+
+
+
+cPieces cPrefabPiecePool::GetStartingPieces(void)
+{
+ if (m_StartingPieces.empty())
+ {
+ return m_AllPieces;
+ }
+ else
+ {
+ return m_StartingPieces;
+ }
+}
+
+
+
+
+
+int cPrefabPiecePool::GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, const cPiece & a_NewPiece)
+{
+ return ((const cPrefab &)a_NewPiece).GetPieceWeight(a_PlacedPiece, a_ExistingConnector);
+}
+
+
+
+
+
+void cPrefabPiecePool::PiecePlaced(const cPiece & a_Piece)
+{
+ // Do nothing
+ UNUSED(a_Piece);
+}
+
+
+
+
+
+void cPrefabPiecePool::Reset(void)
+{
+ // Do nothing
+}
+
+
+
+
diff --git a/src/Generating/PrefabPiecePool.h b/src/Generating/PrefabPiecePool.h
new file mode 100644
index 000000000..c6a5ad360
--- /dev/null
+++ b/src/Generating/PrefabPiecePool.h
@@ -0,0 +1,79 @@
+
+// PrefabPiecePool.h
+
+// Declares the cPrefabPiecePool class that represents a cPiecePool descendant that uses cPrefab instances as the pieces
+
+
+
+
+
+#pragma once
+
+#include "PieceGenerator.h"
+#include "Prefab.h"
+
+
+
+
+
+class cPrefabPiecePool :
+ public cPiecePool
+{
+public:
+ /** Creates an empty instance. Prefabs can be added by calling AddPieceDefs() and AddStartingPieceDefs(). */
+ cPrefabPiecePool(void);
+
+ /** Creates a piece pool with prefabs from the specified definitions.
+ If both a_PieceDefs and a_StartingPieceDefs are given, only the a_StartingPieceDefs are used as starting
+ pieces for the pool, and they do not participate in the generation any further.
+ If only a_PieceDefs is given, any such piece can be chosen as a starting piece, and all the pieces are used
+ for generating.
+ More pieces can be added to the instance afterwards by calling AddPieceDefs() and AddStartingPieceDefs(). */
+ cPrefabPiecePool(
+ const cPrefab::sDef * a_PieceDefs, size_t a_NumPieceDefs,
+ const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs
+ );
+
+ /** Adds pieces from the specified definitions into m_AllPieces. Also adds the pieces into
+ the m_PiecesByConnector map.
+ May be called multiple times with different PieceDefs, will add all such pieces. */
+ void AddPieceDefs(const cPrefab::sDef * a_PieceDefs, size_t a_NumPieceDefs);
+
+ /** Adds pieces from the specified definitions into m_StartingPieces. Doesn't add them to
+ the m_PiecesByConnector map.
+ May be called multiple times with different PieceDefs, will add all such pieces. */
+ void AddStartingPieceDefs(const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs);
+
+
+protected:
+
+ /** The type used to map a connector type to the list of pieces with that connector */
+ typedef std::map<int, cPieces> cPiecesMap;
+
+ /** All the pieces that are allowed for building.
+ This is the list that's used for memory allocation and deallocation for the pieces. */
+ cPieces m_AllPieces;
+
+ /** The pieces that are used as starting pieces.
+ This list is not shared and the pieces need deallocation. */
+ cPieces m_StartingPieces;
+
+ /** The map that has all pieces by their connector types
+ The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */
+ cPiecesMap m_PiecesByConnector;
+
+
+ /** Adds the prefab to the m_PiecesByConnector map for all its connectors. */
+ void AddToPerConnectorMap(cPrefab * a_Prefab);
+
+ // cPiecePool overrides:
+ virtual cPieces GetPiecesWithConnector(int a_ConnectorType) override;
+ virtual cPieces GetStartingPieces(void) override;
+ virtual int GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, const cPiece & a_NewPiece) override;
+ virtual void PiecePlaced(const cPiece & a_Piece) override;
+ virtual void Reset(void) override;
+} ;
+
+
+
+
diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp
index d2ef5663d..088340391 100644
--- a/src/Generating/Prefabs/NetherFortPrefabs.cpp
+++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp
@@ -134,7 +134,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 12, 2, 2: 5\n" /* Type 1, direction X+ */
- "1: 0, 2, 2: 4\n" /* Type 1, direction X- */,
+ "1: 0, 2, 2: 4\n" /* Type 1, direction X- */
+ "-1: 12, 2, 2: 5\n" /* Type -1, direction X+ */
+ "-1: 0, 2, 2: 4\n" /* Type -1, direction X- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -143,7 +145,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
20,
@@ -291,7 +293,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 12, 2, 4: 5\n" /* Type 1, direction X+ */
"1: 6, 2, 0: 2\n" /* Type 1, direction Z- */
- "1: 0, 2, 4: 4\n" /* Type 1, direction X- */,
+ "1: 0, 2, 4: 4\n" /* Type 1, direction X- */
+ "-1: 12, 2, 4: 5\n" /* Type -1, direction X+ */
+ "-1: 6, 2, 0: 2\n" /* Type -1, direction Z- */
+ "-1: 0, 2, 4: 4\n" /* Type -1, direction X- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -300,7 +305,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
20,
@@ -420,7 +425,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -590,7 +595,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -790,7 +795,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
5,
@@ -991,7 +996,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
10,
@@ -1085,7 +1090,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -1185,7 +1190,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -1208,7 +1213,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ
- 4, 6, 15, // MaxX, MaxY, MaxZ
+ 4, 16, 15, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
@@ -1364,7 +1369,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
10,
@@ -1604,7 +1609,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
5,
@@ -1933,7 +1938,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
20,
@@ -2052,7 +2057,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
500,
@@ -2212,7 +2217,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
10,
@@ -2302,7 +2307,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 10, 1, 2: 5\n" /* Type 1, direction X+ */
- "1: 0, 1, 2: 4\n" /* Type 1, direction X- */,
+ "1: 0, 1, 2: 4\n" /* Type 1, direction X- */
+ "-1: 10, 1, 2: 5\n" /* Type -1, direction X+ */
+ "-1: 0, 1, 2: 4\n" /* Type -1, direction X- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -2311,7 +2318,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
300,
@@ -2401,7 +2408,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 12, 1, 2: 5\n" /* Type 1, direction X+ */
- "1: 0, 1, 2: 4\n" /* Type 1, direction X- */,
+ "1: 0, 1, 2: 4\n" /* Type 1, direction X- */
+ "-1: 12, 1, 2: 5\n" /* Type -1, direction X+ */
+ "-1: 0, 1, 2: 4\n" /* Type -1, direction X- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -2410,7 +2419,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
300,
@@ -2494,7 +2503,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 4, 1, 2: 5\n" /* Type 1, direction X+ */
- "1: 0, 1, 2: 4\n" /* Type 1, direction X- */,
+ "1: 0, 1, 2: 4\n" /* Type 1, direction X- */
+ "-1: 4, 1, 2: 5\n" /* Type -1, direction X+ */
+ "-1: 0, 1, 2: 4\n" /* Type -1, direction X- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -2503,7 +2514,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
500,
@@ -2631,7 +2642,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 2, 1, 10: 3\n" /* Type 1, direction Z+ */
- "1: 10, 1, 2: 5\n" /* Type 1, direction X+ */,
+ "1: 10, 1, 2: 5\n" /* Type 1, direction X+ */
+ "-1: 2, 1, 10: 3\n" /* Type -1, direction Z+ */
+ "-1: 10, 1, 2: 5\n" /* Type -1, direction X+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -2640,7 +2653,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -2769,7 +2782,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 10, 1, 2: 5\n" /* Type 1, direction X+ */
- "1: 2, 1, 10: 3\n" /* Type 1, direction Z+ */,
+ "1: 2, 1, 10: 3\n" /* Type 1, direction Z+ */
+ "-1: 2, 1, 10: 3\n" /* Type -1, direction Z+ */
+ "-1: 10, 1, 2: 5\n" /* Type -1, direction X+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -2778,7 +2793,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -2890,7 +2905,11 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
"1: 8, 1, 4: 5\n" /* Type 1, direction X+ */
"1: 4, 1, 0: 2\n" /* Type 1, direction Z- */
"1: 4, 1, 8: 3\n" /* Type 1, direction Z+ */
- "1: 0, 1, 4: 4\n" /* Type 1, direction X- */,
+ "1: 0, 1, 4: 4\n" /* Type 1, direction X- */
+ "-1: 8, 1, 4: 5\n" /* Type -1, direction X+ */
+ "-1: 4, 1, 8: 3\n" /* Type -1, direction Z+ */
+ "-1: 0, 1, 4: 4\n" /* Type -1, direction X- */
+ "-1: 4, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -2899,7 +2918,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -3040,7 +3059,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */
- "1: 8, 8, 2: 5\n" /* Type 1, direction X+ */,
+ "1: 8, 8, 2: 5\n" /* Type 1, direction X+ */
+ "-1: 0, 1, 2: 4\n" /* Type -1, direction X- */
+ "-1: 8, 8, 2: 5\n" /* Type -1, direction X+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -3049,7 +3070,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
1000,
@@ -3139,7 +3160,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */
- "1: 13, 1, 2: 5\n" /* Type 1, direction X+ */,
+ "1: 13, 1, 2: 5\n" /* Type 1, direction X+ */
+ "-1: 0, 1, 2: 4\n" /* Type -1, direction X- */
+ "-1: 13, 1, 2: 5\n" /* Type -1, direction X+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -3148,7 +3171,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -3393,7 +3416,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 0, 6, 7: 4\n" /* Type 1, direction X- */
"1: 9, 1, 14: 3\n" /* Type 1, direction Z+ */
- "1: 9, 1, 0: 2\n" /* Type 1, direction Z- */,
+ "1: 9, 1, 0: 2\n" /* Type 1, direction Z- */
+ "-1: 0, 6, 7: 4\n" /* Type -1, direction X- */
+ "-1: 9, 1, 14: 3\n" /* Type -1, direction Z+ */
+ "-1: 9, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -3402,7 +3428,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
10,
@@ -3722,7 +3748,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 11, 1, 7: 5\n" /* Type 1, direction X+ */
- "1: 0, 9, 7: 4\n" /* Type 1, direction X- */,
+ "1: 0, 9, 7: 4\n" /* Type 1, direction X- */
+ "-1: 11, 1, 7: 5\n" /* Type -1, direction X+ */
+ "-1: 0, 9, 7: 4\n" /* Type -1, direction X- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -3731,7 +3759,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
10,
@@ -4009,7 +4037,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
10,
@@ -4186,7 +4214,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 12, 1, 6: 5\n" /* Type 1, direction X+ */
- "1: 0, 1, 6: 4\n" /* Type 1, direction X- */,
+ "1: 0, 1, 6: 4\n" /* Type 1, direction X- */
+ "-1: 12, 1, 6: 5\n" /* Type -1, direction X+ */
+ "-1: 0, 1, 6: 4\n" /* Type -1, direction X- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -4195,7 +4225,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -4338,7 +4368,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -4481,7 +4511,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -4586,7 +4616,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 0, 1, 4: 4\n" /* Type 1, direction X- */
"1: 6, 1, 0: 2\n" /* Type 1, direction Z- */
- "1: 12, 1, 4: 5\n" /* Type 1, direction X+ */,
+ "1: 12, 1, 4: 5\n" /* Type 1, direction X+ */
+ "-1: 0, 1, 4: 4\n" /* Type -1, direction X- */
+ "-1: 12, 1, 4: 5\n" /* Type -1, direction X+ */
+ "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -4595,7 +4628,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -4712,7 +4745,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 0, 1, 6: 4\n" /* Type 1, direction X- */
"1: 6, 1, 0: 2\n" /* Type 1, direction Z- */
- "1: 12, 1, 6: 5\n" /* Type 1, direction X+ */,
+ "1: 12, 1, 6: 5\n" /* Type 1, direction X+ */
+ "-1: 0, 1, 6: 4\n" /* Type -1, direction X- */
+ "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */
+ "-1: 12, 1, 6: 5\n" /* Type -1, direction X+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -4721,7 +4757,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -4806,7 +4842,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 2, 1, 4: 3\n" /* Type 1, direction Z+ */
- "1: 0, 1, 2: 4\n" /* Type 1, direction X- */,
+ "1: 0, 1, 2: 4\n" /* Type 1, direction X- */
+ "-1: 2, 1, 4: 3\n" /* Type -1, direction Z+ */
+ "-1: 0, 1, 2: 4\n" /* Type -1, direction X- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -4815,7 +4853,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -4901,7 +4939,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// Connectors:
"1: 2, 1, 4: 3\n" /* Type 1, direction Z+ */
- "1: 0, 1, 2: 4\n" /* Type 1, direction X- */,
+ "1: 0, 1, 2: 4\n" /* Type 1, direction X- */
+ "-1: 2, 1, 4: 3\n" /* Type -1, direction Z+ */
+ "-1: 0, 1, 2: 4\n" /* Type -1, direction X- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -4910,7 +4950,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -4996,7 +5036,11 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
"1: 4, 1, 2: 5\n" /* Type 1, direction X+ */
"1: 2, 1, 4: 3\n" /* Type 1, direction Z+ */
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */
- "1: 2, 1, 0: 2\n" /* Type 1, direction Z- */,
+ "1: 2, 1, 0: 2\n" /* Type 1, direction Z- */
+ "-1: 4, 1, 2: 5\n" /* Type -1, direction X+ */
+ "-1: 2, 1, 4: 3\n" /* Type -1, direction Z+ */
+ "-1: 0, 1, 2: 4\n" /* Type -1, direction X- */
+ "-1: 2, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -5005,7 +5049,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -5120,7 +5164,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
@@ -5314,7 +5358,8 @@ const cPrefab::sDef g_NetherFortStartingPrefabs[] =
// Connectors:
"0: 6, 1, 0: 2\n" /* Type 0, direction Z- */
- "1: 6, 1, 12: 3\n" /* Type 1, direction Z+ */,
+ "1: 6, 1, 12: 3\n" /* Type 1, direction Z+ */
+ "-1: 6, 1, 12: 3\n" /* Type -1, direction Z+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -5323,7 +5368,7 @@ const cPrefab::sDef g_NetherFortStartingPrefabs[] =
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
- false,
+ true,
// DefaultWeight:
100,
diff --git a/src/Generating/Ravines.cpp b/src/Generating/Ravines.cpp
index 267dcbbf9..2722e4ca3 100644
--- a/src/Generating/Ravines.cpp
+++ b/src/Generating/Ravines.cpp
@@ -9,9 +9,6 @@
-/// How many ravines in each direction are generated for a given chunk. Must be an even number
-static const int NEIGHBORHOOD_SIZE = 8;
-
static const int NUM_RAVINE_POINTS = 4;
@@ -42,40 +39,38 @@ typedef std::vector<cRavDefPoint> cRavDefPoints;
-class cStructGenRavines::cRavine
+class cStructGenRavines::cRavine :
+ public cGridStructGen::cStructure
{
+ typedef cGridStructGen::cStructure super;
+
cRavDefPoints m_Points;
+
- /// Generates the shaping defpoints for the ravine, based on the ravine block coords and noise
+ /** Generates the shaping defpoints for the ravine, based on the ravine block coords and noise */
void GenerateBaseDefPoints(int a_BlockX, int a_BlockZ, int a_Size, cNoise & a_Noise);
- /// Refines (adds and smooths) defpoints from a_Src into a_Dst
+ /** Refines (adds and smooths) defpoints from a_Src into a_Dst */
void RefineDefPoints(const cRavDefPoints & a_Src, cRavDefPoints & a_Dst);
- /// Does one round of smoothing, two passes of RefineDefPoints()
+ /** Does one round of smoothing, two passes of RefineDefPoints() */
void Smooth(void);
- /// Linearly interpolates the points so that the maximum distance between two neighbors is max 1 block
+ /** Linearly interpolates the points so that the maximum distance between two neighbors is max 1 block */
void FinishLinear(void);
public:
- // Coords for which the ravine was generated (not necessarily the center)
- int m_BlockX;
- int m_BlockZ;
cRavine(int a_BlockX, int a_BlockZ, int a_Size, cNoise & a_Noise);
- /// Carves the ravine into the chunk specified
- void ProcessChunk(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes,
- cChunkDef::HeightMap & a_HeightMap
- );
-
#ifdef _DEBUG
/// Exports itself as a SVG line definition
AString ExportAsSVG(int a_Color, int a_OffsetX = 0, int a_OffsetZ = 0) const;
#endif // _DEBUG
+
+protected:
+ // cGridStructGen::cStructure overrides:
+ virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override;
} ;
@@ -86,6 +81,7 @@ public:
// cStructGenRavines:
cStructGenRavines::cStructGenRavines(int a_Seed, int a_Size) :
+ super(a_Seed, a_Size, a_Size, a_Size * 2, a_Size * 2, 100),
m_Noise(a_Seed),
m_Size(a_Size)
{
@@ -95,139 +91,9 @@ cStructGenRavines::cStructGenRavines(int a_Seed, int a_Size) :
-cStructGenRavines::~cStructGenRavines()
-{
- ClearCache();
-}
-
-
-
-
-
-void cStructGenRavines::ClearCache(void)
+cGridStructGen::cStructurePtr cStructGenRavines::CreateStructure(int a_OriginX, int a_OriginZ)
{
- for (cRavines::const_iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end; ++itr)
- {
- delete *itr;
- } // for itr - m_Cache[]
- m_Cache.clear();
-}
-
-
-
-
-
-void cStructGenRavines::GenFinish(cChunkDesc & a_ChunkDesc)
-{
- int ChunkX = a_ChunkDesc.GetChunkX();
- int ChunkZ = a_ChunkDesc.GetChunkZ();
- cRavines Ravines;
- GetRavinesForChunk(ChunkX, ChunkZ, Ravines);
- for (cRavines::const_iterator itr = Ravines.begin(), end = Ravines.end(); itr != end; ++itr)
- {
- (*itr)->ProcessChunk(ChunkX, ChunkZ, a_ChunkDesc.GetBlockTypes(), a_ChunkDesc.GetHeightMap());
- } // for itr - Ravines[]
-}
-
-
-
-
-
-void cStructGenRavines::GetRavinesForChunk(int a_ChunkX, int a_ChunkZ, cStructGenRavines::cRavines & a_Ravines)
-{
- int BaseX = a_ChunkX * cChunkDef::Width / m_Size;
- int BaseZ = a_ChunkZ * cChunkDef::Width / m_Size;
- if (BaseX < 0)
- {
- --BaseX;
- }
- if (BaseZ < 0)
- {
- --BaseZ;
- }
- BaseX -= 4;
- BaseZ -= 4;
-
- // Walk the cache, move each ravine that we want into a_Ravines:
- int StartX = BaseX * m_Size;
- int EndX = (BaseX + NEIGHBORHOOD_SIZE + 1) * m_Size;
- int StartZ = BaseZ * m_Size;
- int EndZ = (BaseZ + NEIGHBORHOOD_SIZE + 1) * m_Size;
- for (cRavines::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;)
- {
- if (
- ((*itr)->m_BlockX >= StartX) && ((*itr)->m_BlockX < EndX) &&
- ((*itr)->m_BlockZ >= StartZ) && ((*itr)->m_BlockZ < EndZ)
- )
- {
- // want
- a_Ravines.push_back(*itr);
- itr = m_Cache.erase(itr);
- }
- else
- {
- // don't want
- ++itr;
- }
- } // for itr - m_Cache[]
-
- for (int x = 0; x < NEIGHBORHOOD_SIZE; x++)
- {
- int RealX = (BaseX + x) * m_Size;
- for (int z = 0; z < NEIGHBORHOOD_SIZE; z++)
- {
- int RealZ = (BaseZ + z) * m_Size;
- bool Found = false;
- for (cRavines::const_iterator itr = a_Ravines.begin(), end = a_Ravines.end(); itr != end; ++itr)
- {
- if (((*itr)->m_BlockX == RealX) && ((*itr)->m_BlockZ == RealZ))
- {
- Found = true;
- break;
- }
- }
- if (!Found)
- {
- a_Ravines.push_back(new cRavine(RealX, RealZ, m_Size, m_Noise));
- }
- }
- }
-
- // Copy a_Ravines into m_Cache to the beginning:
- cRavines RavinesCopy(a_Ravines);
- m_Cache.splice(m_Cache.begin(), RavinesCopy, RavinesCopy.begin(), RavinesCopy.end());
-
- // Trim the cache if it's too long:
- if (m_Cache.size() > 100)
- {
- cRavines::iterator itr = m_Cache.begin();
- std::advance(itr, 100);
- for (cRavines::iterator end = m_Cache.end(); itr != end; ++itr)
- {
- delete *itr;
- }
- itr = m_Cache.begin();
- std::advance(itr, 100);
- m_Cache.erase(itr, m_Cache.end());
- }
-
- /*
- #ifdef _DEBUG
- // DEBUG: Export as SVG into a file specific for the chunk, for visual verification:
- AString SVG;
- SVG.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1024\" height = \"1024\">\n");
- for (cRavines::const_iterator itr = a_Ravines.begin(), end = a_Ravines.end(); itr != end; ++itr)
- {
- SVG.append((*itr)->ExportAsSVG(0, 512, 512));
- }
- SVG.append("</svg>\n");
-
- AString fnam;
- Printf(fnam, "ravines\\%03d_%03d.svg", a_ChunkX, a_ChunkZ);
- cFile File(fnam, cFile::fmWrite);
- File.Write(SVG.c_str(), SVG.size());
- #endif // _DEBUG
- //*/
+ return cStructurePtr(new cRavine(a_OriginX, a_OriginZ, m_Size, m_Noise));
}
@@ -238,14 +104,13 @@ void cStructGenRavines::GetRavinesForChunk(int a_ChunkX, int a_ChunkZ, cStructGe
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cStructGenRavines::cRavine
-cStructGenRavines::cRavine::cRavine(int a_BlockX, int a_BlockZ, int a_Size, cNoise & a_Noise) :
- m_BlockX(a_BlockX),
- m_BlockZ(a_BlockZ)
+cStructGenRavines::cRavine::cRavine(int a_OriginX, int a_OriginZ, int a_Size, cNoise & a_Noise) :
+ super(a_OriginX, a_OriginZ)
{
// Calculate the ravine shape-defining points:
- GenerateBaseDefPoints(a_BlockX, a_BlockZ, a_Size, a_Noise);
+ GenerateBaseDefPoints(a_OriginX, a_OriginZ, a_Size, a_Noise);
- // Smooth the ravine. A two passes are needed:
+ // Smooth the ravine. Two passes are needed:
Smooth();
Smooth();
@@ -263,8 +128,8 @@ void cStructGenRavines::cRavine::GenerateBaseDefPoints(int a_BlockX, int a_Block
a_Size = (512 + ((a_Noise.IntNoise3DInt(19 * a_BlockX, 11 * a_BlockZ, a_BlockX + a_BlockZ) / 17) % 512)) * a_Size / 1024;
// The complete offset of the ravine from its cellpoint, up to 2 * a_Size in each direction
- int OffsetX = (((a_Noise.IntNoise3DInt(50 * a_BlockX, 30 * a_BlockZ, 0) / 9) % (2 * a_Size)) + ((a_Noise.IntNoise3DInt(30 * a_BlockX, 50 * m_BlockZ, 1000) / 7) % (2 * a_Size)) - 2 * a_Size) / 2;
- int OffsetZ = (((a_Noise.IntNoise3DInt(50 * a_BlockX, 30 * a_BlockZ, 2000) / 7) % (2 * a_Size)) + ((a_Noise.IntNoise3DInt(30 * a_BlockX, 50 * m_BlockZ, 3000) / 9) % (2 * a_Size)) - 2 * a_Size) / 2;
+ int OffsetX = (((a_Noise.IntNoise3DInt(50 * a_BlockX, 30 * a_BlockZ, 0) / 9) % (2 * a_Size)) + ((a_Noise.IntNoise3DInt(30 * a_BlockX, 50 * a_BlockZ, 1000) / 7) % (2 * a_Size)) - 2 * a_Size) / 2;
+ int OffsetZ = (((a_Noise.IntNoise3DInt(50 * a_BlockX, 30 * a_BlockZ, 2000) / 7) % (2 * a_Size)) + ((a_Noise.IntNoise3DInt(30 * a_BlockX, 50 * a_BlockZ, 3000) / 9) % (2 * a_Size)) - 2 * a_Size) / 2;
int CenterX = a_BlockX + OffsetX;
int CenterZ = a_BlockZ + OffsetZ;
@@ -306,8 +171,14 @@ void cStructGenRavines::cRavine::GenerateBaseDefPoints(int a_BlockX, int a_Block
void cStructGenRavines::cRavine::RefineDefPoints(const cRavDefPoints & a_Src, cRavDefPoints & a_Dst)
{
+ if (a_Src.size() < 2)
+ {
+ // No midpoints, nothing to refine
+ return;
+ }
+
// Smoothing: for each line segment, add points on its 1/4 lengths
- int Num = a_Src.size() - 2; // this many intermediary points
+ size_t Num = a_Src.size() - 2; // this many intermediary points
a_Dst.clear();
a_Dst.reserve(Num * 2 + 2);
cRavDefPoints::const_iterator itr = a_Src.begin() + 1;
@@ -318,7 +189,7 @@ void cStructGenRavines::cRavine::RefineDefPoints(const cRavDefPoints & a_Src, cR
int PrevR = Source.m_Radius;
int PrevT = Source.m_Top;
int PrevB = Source.m_Bottom;
- for (int i = 0; i <= Num; ++i, ++itr)
+ for (size_t i = 0; i <= Num; ++i, ++itr)
{
int dx = itr->m_BlockX - PrevX;
int dz = itr->m_BlockZ - PrevZ;
@@ -423,15 +294,15 @@ AString cStructGenRavines::cRavine::ExportAsSVG(int a_Color, int a_OffsetX, int
// Base point highlight:
AppendPrintf(SVG, "<path style=\"fill:none;stroke:#ff0000;stroke-width:1px;\"\nd=\"M %d,%d L %d,%d\"/>\n",
- a_OffsetX + m_BlockX - 5, a_OffsetZ + m_BlockZ, a_OffsetX + m_BlockX + 5, a_OffsetZ + m_BlockZ
+ a_OffsetX + m_OriginX - 5, a_OffsetZ + m_OriginZ, a_OffsetX + m_OriginX + 5, a_OffsetZ + m_OriginZ
);
AppendPrintf(SVG, "<path style=\"fill:none;stroke:#ff0000;stroke-width:1px;\"\nd=\"M %d,%d L %d,%d\"/>\n",
- a_OffsetX + m_BlockX, a_OffsetZ + m_BlockZ - 5, a_OffsetX + m_BlockX, a_OffsetZ + m_BlockZ + 5
+ a_OffsetX + m_OriginX, a_OffsetZ + m_OriginZ - 5, a_OffsetX + m_OriginX, a_OffsetZ + m_OriginZ + 5
);
// A gray line from the base point to the first point of the ravine, for identification:
AppendPrintf(SVG, "<path style=\"fill:none;stroke:#cfcfcf;stroke-width:1px;\"\nd=\"M %d,%d L %d,%d\"/>\n",
- a_OffsetX + m_BlockX, a_OffsetZ + m_BlockZ, a_OffsetX + m_Points.front().m_BlockX, a_OffsetZ + m_Points.front().m_BlockZ
+ a_OffsetX + m_OriginX, a_OffsetZ + m_OriginZ, a_OffsetX + m_Points.front().m_BlockX, a_OffsetZ + m_Points.front().m_BlockZ
);
// Offset guides:
@@ -455,14 +326,10 @@ AString cStructGenRavines::cRavine::ExportAsSVG(int a_Color, int a_OffsetX, int
-void cStructGenRavines::cRavine::ProcessChunk(
- int a_ChunkX, int a_ChunkZ,
- cChunkDef::BlockTypes & a_BlockTypes,
- cChunkDef::HeightMap & a_HeightMap
-)
+void cStructGenRavines::cRavine::DrawIntoChunk(cChunkDesc & a_ChunkDesc)
{
- int BlockStartX = a_ChunkX * cChunkDef::Width;
- int BlockStartZ = a_ChunkZ * cChunkDef::Width;
+ int BlockStartX = a_ChunkDesc.GetChunkX() * cChunkDef::Width;
+ int BlockStartZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
int BlockEndX = BlockStartX + cChunkDef::Width;
int BlockEndZ = BlockStartZ + cChunkDef::Width;
for (cRavDefPoints::const_iterator itr = m_Points.begin(), end = m_Points.end(); itr != end; ++itr)
@@ -488,7 +355,7 @@ void cStructGenRavines::cRavine::ProcessChunk(
// DEBUG: Make the ravine shapepoints visible on a single layer (so that we can see with Minutor what's going on)
if ((DifX + x == 0) && (DifZ + z == 0))
{
- cChunkDef::SetBlock(a_BlockTypes, x, 4, z, E_BLOCK_LAPIS_ORE);
+ a_ChunkDesc.SetBlockType(x, 4, z, E_BLOCK_LAPIS_ORE);
}
#endif // _DEBUG
@@ -498,7 +365,7 @@ void cStructGenRavines::cRavine::ProcessChunk(
int Top = std::min(itr->m_Top, (int)(cChunkDef::Height)); // Stupid gcc needs int cast
for (int y = std::max(itr->m_Bottom, 1); y <= Top; y++)
{
- switch (cChunkDef::GetBlock(a_BlockTypes, x, y, z))
+ switch (a_ChunkDesc.GetBlockType(x, y, z))
{
// Only carve out these specific block types
case E_BLOCK_DIRT:
@@ -516,7 +383,7 @@ void cStructGenRavines::cRavine::ProcessChunk(
case E_BLOCK_REDSTONE_ORE:
case E_BLOCK_REDSTONE_ORE_GLOWING:
{
- cChunkDef::SetBlock(a_BlockTypes, x, y, z, E_BLOCK_AIR);
+ a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_AIR);
break;
}
default: break;
diff --git a/src/Generating/Ravines.h b/src/Generating/Ravines.h
index c76b9f19f..30b47e9ec 100644
--- a/src/Generating/Ravines.h
+++ b/src/Generating/Ravines.h
@@ -9,7 +9,7 @@
#pragma once
-#include "ComposableGenerator.h"
+#include "GridStructGen.h"
#include "../Noise.h"
@@ -17,28 +17,22 @@
class cStructGenRavines :
- public cFinishGen
+ public cGridStructGen
{
+ typedef cGridStructGen super;
+
public:
cStructGenRavines(int a_Seed, int a_Size);
- ~cStructGenRavines();
protected:
class cRavine; // fwd: Ravines.cpp
- typedef std::list<cRavine *> cRavines;
-
- cNoise m_Noise;
- int m_Size; // Max size, in blocks, of the ravines generated
- cRavines m_Cache;
- /// Clears everything from the cache
- void ClearCache(void);
+ cNoise m_Noise;
+ int m_Size; // Max size, in blocks, of the ravines generated
- /// Returns all ravines that *may* intersect the given chunk. All the ravines are valid until the next call to this function.
- void GetRavinesForChunk(int a_ChunkX, int a_ChunkZ, cRavines & a_Ravines);
-
- // cFinishGen override:
- virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
+
+ // cGridStructGen overrides:
+ virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
} ;
diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp
index 4909587b1..4f1553c36 100644
--- a/src/Generating/Trees.cpp
+++ b/src/Generating/Trees.cpp
@@ -136,7 +136,7 @@ inline void PushSomeColumns(int a_BlockX, int a_Height, int a_BlockZ, int a_Colu
{
int x = a_BlockX + a_Coords[i].x;
int z = a_BlockZ + a_Coords[i].z;
- if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height + i, z + 64 * a_Seq) <= a_Chance)
+ if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height + (int)i, z + 64 * a_Seq) <= a_Chance)
{
for (int j = 0; j < a_ColumnHeight; j++)
{
diff --git a/src/GroupManager.cpp b/src/GroupManager.cpp
index 33b601e82..3586560bf 100644
--- a/src/GroupManager.cpp
+++ b/src/GroupManager.cpp
@@ -79,23 +79,24 @@ void cGroupManager::CheckUsers(void)
return;
}
- unsigned int NumKeys = IniFile.GetNumKeys();
- for (size_t i = 0; i < NumKeys; i++)
+ int NumKeys = IniFile.GetNumKeys();
+ for (int i = 0; i < NumKeys; i++)
{
- AString Player = IniFile.GetKeyName( i );
+ AString Player = IniFile.GetKeyName(i);
AString Groups = IniFile.GetValue(Player, "Groups", "");
- if (!Groups.empty())
+ if (Groups.empty())
+ {
+ continue;
+ }
+ AStringVector Split = StringSplitAndTrim(Groups, ",");
+ for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr)
{
- AStringVector Split = StringSplit( Groups, "," );
- for( unsigned int i = 0; i < Split.size(); i++ )
+ if (!ExistsGroup(*itr))
{
- if (!ExistsGroup(Split[i]))
- {
- LOGWARNING("The group %s for player %s was not found!", Split[i].c_str(), Player.c_str());
- }
+ LOGWARNING("The group %s for player %s was not found!", Split[i].c_str(), Player.c_str());
}
- }
- }
+ } // for itr - Split[]
+ } // for i - ini file keys
}
@@ -128,15 +129,15 @@ void cGroupManager::LoadGroups()
IniFile.WriteFile("groups.ini");
}
- unsigned int NumKeys = IniFile.GetNumKeys();
- for (size_t i = 0; i < NumKeys; i++)
+ int NumKeys = IniFile.GetNumKeys();
+ for (int i = 0; i < NumKeys; i++)
{
- AString KeyName = IniFile.GetKeyName( i );
- cGroup* Group = GetGroup( KeyName.c_str() );
+ AString KeyName = IniFile.GetKeyName(i);
+ cGroup * Group = GetGroup(KeyName.c_str());
Group->ClearPermission(); // Needed in case the groups are reloaded.
- LOGD("Loading group: %s", KeyName.c_str() );
+ LOGD("Loading group %s", KeyName.c_str());
Group->SetName(KeyName);
AString Color = IniFile.GetValue(KeyName, "Color", "-");
diff --git a/src/HTTPServer/NameValueParser.cpp b/src/HTTPServer/NameValueParser.cpp
index 3f6c17dda..f16ea1915 100644
--- a/src/HTTPServer/NameValueParser.cpp
+++ b/src/HTTPServer/NameValueParser.cpp
@@ -97,7 +97,7 @@ void cNameValueParser::Parse(const char * a_Data, size_t a_Size)
{
ASSERT(m_State != psFinished); // Calling Parse() after Finish() is wrong!
- int Last = 0;
+ size_t Last = 0;
for (size_t i = 0; i < a_Size;)
{
switch (m_State)
diff --git a/src/Inventory.cpp b/src/Inventory.cpp
index c7c089d5f..a365e4ed4 100644
--- a/src/Inventory.cpp
+++ b/src/Inventory.cpp
@@ -376,6 +376,7 @@ bool cInventory::DamageItem(int a_SlotNum, short a_Amount)
if (!Grid->DamageItem(GridSlotNum, a_Amount))
{
// The item has been damaged, but did not break yet
+ SendSlot(a_SlotNum);
return false;
}
diff --git a/src/Item.cpp b/src/Item.cpp
index 7e472f6d8..d6e8b224a 100644
--- a/src/Item.cpp
+++ b/src/Item.cpp
@@ -151,6 +151,8 @@ void cItem::GetJson(Json::Value & a_OutValue) const
a_OutValue["Colours"] = m_FireworkItem.ColoursToString(m_FireworkItem);
a_OutValue["FadeColours"] = m_FireworkItem.FadeColoursToString(m_FireworkItem);
}
+
+ a_OutValue["RepairCost"] = m_RepairCost;
}
}
@@ -179,6 +181,8 @@ void cItem::FromJson(const Json::Value & a_Value)
m_FireworkItem.ColoursFromString(a_Value.get("Colours", "").asString(), m_FireworkItem);
m_FireworkItem.FadeColoursFromString(a_Value.get("FadeColours", "").asString(), m_FireworkItem);
}
+
+ m_RepairCost = a_Value.get("RepairCost", 0).asInt();
}
}
diff --git a/src/Item.h b/src/Item.h
index 8eb0a1f4e..2f65d5344 100644
--- a/src/Item.h
+++ b/src/Item.h
@@ -40,6 +40,7 @@ public:
m_ItemDamage(0),
m_CustomName(""),
m_Lore(""),
+ m_RepairCost(0),
m_FireworkItem()
{
}
@@ -60,6 +61,7 @@ public:
m_Enchantments(a_Enchantments),
m_CustomName (a_CustomName),
m_Lore (a_Lore),
+ m_RepairCost (0),
m_FireworkItem()
{
if (!IsValidItem(m_ItemType))
@@ -85,6 +87,7 @@ public:
m_Enchantments(a_CopyFrom.m_Enchantments),
m_CustomName (a_CopyFrom.m_CustomName),
m_Lore (a_CopyFrom.m_Lore),
+ m_RepairCost (a_CopyFrom.m_RepairCost),
m_FireworkItem(a_CopyFrom.m_FireworkItem)
{
}
@@ -100,6 +103,7 @@ public:
m_Enchantments.Clear();
m_CustomName = "";
m_Lore = "";
+ m_RepairCost = 0;
m_FireworkItem.EmptyData();
}
@@ -109,6 +113,7 @@ public:
m_ItemType = E_ITEM_EMPTY;
m_ItemCount = 0;
m_ItemDamage = 0;
+ m_RepairCost = 0;
}
@@ -190,14 +195,15 @@ public:
// tolua_begin
- short m_ItemType;
- char m_ItemCount;
- short m_ItemDamage;
- cEnchantments m_Enchantments;
- AString m_CustomName;
- AString m_Lore;
-
- cFireworkItem m_FireworkItem;
+ short m_ItemType;
+ char m_ItemCount;
+ short m_ItemDamage;
+ cEnchantments m_Enchantments;
+ AString m_CustomName;
+ AString m_Lore;
+
+ int m_RepairCost;
+ cFireworkItem m_FireworkItem;
};
// tolua_end
diff --git a/src/Items/ItemArmor.h b/src/Items/ItemArmor.h
index 08cddb1ad..2436df5bd 100644
--- a/src/Items/ItemArmor.h
+++ b/src/Items/ItemArmor.h
@@ -60,6 +60,49 @@ public:
return true;
}
+ virtual bool CanRepairWithRawMaterial(short a_ItemType) override
+ {
+ switch (m_ItemType)
+ {
+ case E_ITEM_CHAIN_BOOTS:
+ case E_ITEM_CHAIN_CHESTPLATE:
+ case E_ITEM_CHAIN_HELMET:
+ case E_ITEM_CHAIN_LEGGINGS:
+ {
+ return (a_ItemType == E_ITEM_IRON);
+ }
+ case E_ITEM_DIAMOND_BOOTS:
+ case E_ITEM_DIAMOND_CHESTPLATE:
+ case E_ITEM_DIAMOND_HELMET:
+ case E_ITEM_DIAMOND_LEGGINGS:
+ {
+ return (a_ItemType == E_ITEM_DIAMOND);
+ }
+ case E_ITEM_IRON_BOOTS:
+ case E_ITEM_IRON_CHESTPLATE:
+ case E_ITEM_IRON_HELMET:
+ case E_ITEM_IRON_LEGGINGS:
+ {
+ return (a_ItemType == E_ITEM_IRON);
+ }
+ case E_ITEM_GOLD_BOOTS:
+ case E_ITEM_GOLD_CHESTPLATE:
+ case E_ITEM_GOLD_HELMET:
+ case E_ITEM_GOLD_LEGGINGS:
+ {
+ return (a_ItemType == E_ITEM_GOLD);
+ }
+ case E_ITEM_LEATHER_BOOTS:
+ case E_ITEM_LEATHER_CAP:
+ case E_ITEM_LEATHER_PANTS:
+ case E_ITEM_LEATHER_TUNIC:
+ {
+ return (a_ItemType == E_ITEM_LEATHER);
+ }
+ }
+ return false;
+ }
+
} ;
diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp
index ce9593a70..d97f986ba 100644
--- a/src/Items/ItemHandler.cpp
+++ b/src/Items/ItemHandler.cpp
@@ -511,6 +511,16 @@ bool cItemHandler::IsPlaceable(void)
+
+bool cItemHandler::CanRepairWithRawMaterial(short a_ItemType)
+{
+ return false;
+}
+
+
+
+
+
bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType)
{
UNUSED(a_BlockType);
diff --git a/src/Items/ItemHandler.h b/src/Items/ItemHandler.h
index 4993eac85..e13198cd7 100644
--- a/src/Items/ItemHandler.h
+++ b/src/Items/ItemHandler.h
@@ -85,6 +85,9 @@ public:
/** Blocks simply get placed */
virtual bool IsPlaceable(void);
+ /** Can the anvil repair this item, when a_Item is the second input? */
+ virtual bool CanRepairWithRawMaterial(short a_ItemType);
+
/** Called before a block is placed into a world.
The handler should return true to allow placement, false to refuse.
Also, the handler should set a_BlockType and a_BlockMeta to correct values for the newly placed block.
diff --git a/src/Items/ItemLilypad.h b/src/Items/ItemLilypad.h
index 8fc1d8543..bc650cdbd 100644
--- a/src/Items/ItemLilypad.h
+++ b/src/Items/ItemLilypad.h
@@ -47,9 +47,9 @@ public:
public cBlockTracer::cCallbacks
{
public:
- cCallbacks(cWorld * a_CBWorld) :
- m_HasHitFluid(false),
- m_World(a_CBWorld)
+
+ cCallbacks(void) :
+ m_HasHitFluid(false)
{
}
@@ -62,10 +62,9 @@ public:
return false;
}
AddFaceDirection(a_CBBlockX, a_CBBlockY, a_CBBlockZ, BLOCK_FACE_YP); // Always place pad at top of water block
- BLOCKTYPE Block = m_World->GetBlock(a_CBBlockX, a_CBBlockY, a_CBBlockZ);
if (
- !IsBlockWater(Block) &&
- cBlockInfo::FullyOccupiesVoxel(Block)
+ !IsBlockWater(a_CBBlockType) &&
+ cBlockInfo::FullyOccupiesVoxel(a_CBBlockType)
)
{
// Can't place lilypad on air/in another block!
@@ -80,11 +79,10 @@ public:
Vector3i m_Pos;
bool m_HasHitFluid;
- cWorld * m_World;
};
- cCallbacks Callbacks(a_World);
+ cCallbacks Callbacks;
cLineBlockTracer Tracer(*a_Player->GetWorld(), Callbacks);
Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector());
Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5);
diff --git a/src/Items/ItemMinecart.h b/src/Items/ItemMinecart.h
index 25500aeb9..4e7d8fcff 100644
--- a/src/Items/ItemMinecart.h
+++ b/src/Items/ItemMinecart.h
@@ -78,7 +78,7 @@ public:
}
return true;
}
-
+
} ;
diff --git a/src/Items/ItemPickaxe.h b/src/Items/ItemPickaxe.h
index 2a8e40daa..82bec52d4 100644
--- a/src/Items/ItemPickaxe.h
+++ b/src/Items/ItemPickaxe.h
@@ -76,6 +76,7 @@ public:
case E_BLOCK_STONE_PRESSURE_PLATE:
case E_BLOCK_BRICK:
case E_BLOCK_COBBLESTONE_STAIRS:
+ case E_BLOCK_COBBLESTONE_WALL:
case E_BLOCK_STONE_BRICK_STAIRS:
case E_BLOCK_NETHER_BRICK_STAIRS:
case E_BLOCK_CAULDRON:
@@ -85,6 +86,19 @@ public:
}
return false;
}
+
+ virtual bool CanRepairWithRawMaterial(short a_ItemType) override
+ {
+ switch (m_ItemType)
+ {
+ case E_ITEM_WOODEN_PICKAXE: return (a_ItemType == E_BLOCK_PLANKS);
+ case E_ITEM_STONE_PICKAXE: return (a_ItemType == E_BLOCK_COBBLESTONE);
+ case E_ITEM_IRON_PICKAXE: return (a_ItemType == E_ITEM_IRON);
+ case E_ITEM_GOLD_PICKAXE: return (a_ItemType == E_ITEM_GOLD);
+ case E_ITEM_DIAMOND_PICKAXE: return (a_ItemType == E_ITEM_DIAMOND);
+ }
+ return false;
+ }
} ;
diff --git a/src/Items/ItemShovel.h b/src/Items/ItemShovel.h
index 873d5ae25..333ba46e8 100644
--- a/src/Items/ItemShovel.h
+++ b/src/Items/ItemShovel.h
@@ -41,4 +41,18 @@ public:
{
return (a_BlockType == E_BLOCK_SNOW);
}
+
+ virtual bool CanRepairWithRawMaterial(short a_ItemType) override
+ {
+ switch (m_ItemType)
+ {
+ case E_ITEM_WOODEN_SHOVEL: return (a_ItemType == E_BLOCK_PLANKS);
+ case E_ITEM_STONE_SHOVEL: return (a_ItemType == E_BLOCK_COBBLESTONE);
+ case E_ITEM_IRON_SHOVEL: return (a_ItemType == E_ITEM_IRON);
+ case E_ITEM_GOLD_SHOVEL: return (a_ItemType == E_ITEM_GOLD);
+ case E_ITEM_DIAMOND_SHOVEL: return (a_ItemType == E_ITEM_DIAMOND);
+ }
+ return false;
+ }
+
};
diff --git a/src/Items/ItemSpawnEgg.h b/src/Items/ItemSpawnEgg.h
index 0d6019398..bba97afa1 100644
--- a/src/Items/ItemSpawnEgg.h
+++ b/src/Items/ItemSpawnEgg.h
@@ -33,7 +33,10 @@ public:
a_BlockY--;
}
- if (a_World->SpawnMob(a_BlockX + 0.5, a_BlockY, a_BlockZ + 0.5, (cMonster::eType)(a_Item.m_ItemDamage)) >= 0)
+ cMonster::eType MonsterType = ItemDamageToMonsterType(a_Item.m_ItemDamage);
+ if (
+ (MonsterType != cMonster::mtInvalidType) && // Valid monster type
+ (a_World->SpawnMob(a_BlockX + 0.5, a_BlockY, a_BlockZ + 0.5, MonsterType) >= 0)) // Spawning succeeded
{
if (!a_Player->IsGameModeCreative())
{
@@ -45,6 +48,41 @@ public:
return false;
}
+
+
+ /** Converts the Spawn egg item damage to the monster type to spawn.
+ Returns mtInvalidType for invalid damage values. */
+ static cMonster::eType ItemDamageToMonsterType(short a_ItemDamage)
+ {
+ switch (a_ItemDamage)
+ {
+ case E_META_SPAWN_EGG_BAT: return cMonster::mtBat;
+ case E_META_SPAWN_EGG_BLAZE: return cMonster::mtBlaze;
+ case E_META_SPAWN_EGG_CAVE_SPIDER: return cMonster::mtCaveSpider;
+ case E_META_SPAWN_EGG_CHICKEN: return cMonster::mtChicken;
+ case E_META_SPAWN_EGG_COW: return cMonster::mtCow;
+ case E_META_SPAWN_EGG_CREEPER: return cMonster::mtCreeper;
+ case E_META_SPAWN_EGG_ENDERMAN: return cMonster::mtEnderman;
+ case E_META_SPAWN_EGG_GHAST: return cMonster::mtGhast;
+ case E_META_SPAWN_EGG_HORSE: return cMonster::mtHorse;
+ case E_META_SPAWN_EGG_MAGMA_CUBE: return cMonster::mtMagmaCube;
+ case E_META_SPAWN_EGG_MOOSHROOM: return cMonster::mtMooshroom;
+ case E_META_SPAWN_EGG_OCELOT: return cMonster::mtOcelot;
+ case E_META_SPAWN_EGG_PIG: return cMonster::mtPig;
+ case E_META_SPAWN_EGG_SHEEP: return cMonster::mtSheep;
+ case E_META_SPAWN_EGG_SILVERFISH: return cMonster::mtSilverfish;
+ case E_META_SPAWN_EGG_SKELETON: return cMonster::mtSkeleton;
+ case E_META_SPAWN_EGG_SLIME: return cMonster::mtSlime;
+ case E_META_SPAWN_EGG_SPIDER: return cMonster::mtSpider;
+ case E_META_SPAWN_EGG_SQUID: return cMonster::mtSquid;
+ case E_META_SPAWN_EGG_VILLAGER: return cMonster::mtVillager;
+ case E_META_SPAWN_EGG_WITCH: return cMonster::mtWitch;
+ case E_META_SPAWN_EGG_WOLF: return cMonster::mtWolf;
+ case E_META_SPAWN_EGG_ZOMBIE: return cMonster::mtZombie;
+ case E_META_SPAWN_EGG_ZOMBIE_PIGMAN: return cMonster::mtZombiePigman;
+ }
+ return cMonster::mtInvalidType;
+ }
} ;
diff --git a/src/Items/ItemSword.h b/src/Items/ItemSword.h
index a7c1d2432..44feb2d83 100644
--- a/src/Items/ItemSword.h
+++ b/src/Items/ItemSword.h
@@ -23,6 +23,19 @@ public:
{
return (a_BlockType == E_BLOCK_COBWEB);
}
+
+ virtual bool CanRepairWithRawMaterial(short a_ItemType) override
+ {
+ switch (m_ItemType)
+ {
+ case E_ITEM_WOODEN_SWORD: return (a_ItemType == E_BLOCK_PLANKS);
+ case E_ITEM_STONE_SWORD: return (a_ItemType == E_BLOCK_COBBLESTONE);
+ case E_ITEM_IRON_SWORD: return (a_ItemType == E_ITEM_IRON);
+ case E_ITEM_GOLD_SWORD: return (a_ItemType == E_ITEM_GOLD);
+ case E_ITEM_DIAMOND_SWORD: return (a_ItemType == E_ITEM_DIAMOND);
+ }
+ return false;
+ }
} ;
diff --git a/src/Items/ItemThrowable.h b/src/Items/ItemThrowable.h
index c6a4e714e..35c2b8731 100644
--- a/src/Items/ItemThrowable.h
+++ b/src/Items/ItemThrowable.h
@@ -28,15 +28,19 @@ public:
virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override
{
+ Vector3d Pos = a_Player->GetThrowStartPos();
+ Vector3d Speed = a_Player->GetLookVector() * m_SpeedCoeff;
+
+ if (a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, a_Player->GetEquippedItem(), &Speed) < 0)
+ {
+ return false;
+ }
+
if (!a_Player->IsGameModeCreative())
{
a_Player->GetInventory().RemoveOneEquippedItem();
}
- Vector3d Pos = a_Player->GetThrowStartPos();
- Vector3d Speed = a_Player->GetLookVector() * m_SpeedCoeff;
- a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, a_Player->GetEquippedItem(), &Speed);
-
return true;
}
@@ -127,7 +131,10 @@ public:
return false;
}
- a_World->CreateProjectile(a_BlockX + 0.5, a_BlockY + 1, a_BlockZ + 0.5, m_ProjectileKind, a_Player, a_Player->GetEquippedItem());
+ if (a_World->CreateProjectile(a_BlockX + 0.5, a_BlockY + 1, a_BlockZ + 0.5, m_ProjectileKind, a_Player, a_Player->GetEquippedItem()) < 0)
+ {
+ return false;
+ }
if (!a_Player->IsGameModeCreative())
{
diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp
index 5ba2940d2..5459644af 100644
--- a/src/LightingThread.cpp
+++ b/src/LightingThread.cpp
@@ -106,11 +106,13 @@ void cLightingThread::Stop(void)
cCSLock Lock(m_CS);
for (cChunkStays::iterator itr = m_PendingQueue.begin(), end = m_PendingQueue.end(); itr != end; ++itr)
{
+ (*itr)->Disable();
delete *itr;
}
m_PendingQueue.clear();
for (cChunkStays::iterator itr = m_Queue.begin(), end = m_Queue.end(); itr != end; ++itr)
{
+ (*itr)->Disable();
delete *itr;
}
m_Queue.clear();
diff --git a/src/Map.cpp b/src/Map.cpp
index 79370b097..7721baa70 100644
--- a/src/Map.cpp
+++ b/src/Map.cpp
@@ -614,7 +614,7 @@ unsigned int cMap::GetNumPixels(void) const
-unsigned int cMap::GetNumDecorators(void) const
+size_t cMap::GetNumDecorators(void) const
{
return m_Decorators.size();
}
diff --git a/src/Map.h b/src/Map.h
index ee7c537b1..e23ca2c92 100644
--- a/src/Map.h
+++ b/src/Map.h
@@ -181,7 +181,7 @@ public:
// tolua_end
- unsigned int GetNumDecorators(void) const;
+ size_t GetNumDecorators(void) const;
const cColorList & GetData(void) const { return m_Data; }
diff --git a/src/MapManager.cpp b/src/MapManager.cpp
index 9d02eafb4..e7df75118 100644
--- a/src/MapManager.cpp
+++ b/src/MapManager.cpp
@@ -86,7 +86,7 @@ cMap * cMapManager::CreateMap(int a_CenterX, int a_CenterY, int a_Scale)
return NULL;
}
- cMap Map(m_MapData.size(), a_CenterX, a_CenterY, m_World, a_Scale);
+ cMap Map((unsigned)m_MapData.size(), a_CenterX, a_CenterY, m_World, a_Scale);
m_MapData.push_back(Map);
@@ -97,7 +97,7 @@ cMap * cMapManager::CreateMap(int a_CenterX, int a_CenterY, int a_Scale)
-unsigned int cMapManager::GetNumMaps(void) const
+size_t cMapManager::GetNumMaps(void) const
{
return m_MapData.size();
}
@@ -151,7 +151,7 @@ void cMapManager::SaveMapData(void)
cIDCountSerializer IDSerializer(m_World->GetName());
- IDSerializer.SetMapCount(m_MapData.size());
+ IDSerializer.SetMapCount((unsigned)m_MapData.size());
if (!IDSerializer.Save())
{
diff --git a/src/MapManager.h b/src/MapManager.h
index 80e6d16d1..ceab8f126 100644
--- a/src/MapManager.h
+++ b/src/MapManager.h
@@ -53,7 +53,7 @@ public:
*/
bool ForEachMap(cMapCallback & a_Callback);
- unsigned int GetNumMaps(void) const; // tolua_export
+ size_t GetNumMaps(void) const; // tolua_export
/** Loads the map data from the disk */
void LoadMapData(void);
diff --git a/src/MobCensus.cpp b/src/MobCensus.cpp
index 9c32bf695..23f74b59e 100644
--- a/src/MobCensus.cpp
+++ b/src/MobCensus.cpp
@@ -64,7 +64,7 @@ void cMobCensus::CollectSpawnableChunk(cChunk & a_Chunk)
int cMobCensus::GetNumChunks(void)
{
- return m_EligibleForSpawnChunks.size();
+ return (int)m_EligibleForSpawnChunks.size();
}
diff --git a/src/MobFamilyCollecter.cpp b/src/MobFamilyCollecter.cpp
index e9c69e078..6da330c83 100644
--- a/src/MobFamilyCollecter.cpp
+++ b/src/MobFamilyCollecter.cpp
@@ -18,7 +18,7 @@ void cMobFamilyCollecter::CollectMob(cMonster & a_Monster)
int cMobFamilyCollecter::GetNumberOfCollectedMobs(cMonster::eFamily a_Family)
{
- return m_Mobs[a_Family].size();
+ return (int)m_Mobs[a_Family].size();
}
diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp
index ce8e06777..de8e01b8a 100644
--- a/src/MobSpawner.cpp
+++ b/src/MobSpawner.cpp
@@ -104,13 +104,13 @@ cMonster::eType cMobSpawner::ChooseMobType(EMCSBiome a_Biome)
}
}
- int allowedMobsSize = allowedMobs.size();
+ size_t allowedMobsSize = allowedMobs.size();
if (allowedMobsSize > 0)
{
std::set<cMonster::eType>::iterator itr = allowedMobs.begin();
- int iRandom = m_Random.NextInt(allowedMobsSize,a_Biome);
+ int iRandom = m_Random.NextInt((int)allowedMobsSize, a_Biome);
- for(int i = 0; i < iRandom; i++)
+ for (int i = 0; i < iRandom; i++)
{
++itr;
}
diff --git a/src/Mobs/AggressiveMonster.cpp b/src/Mobs/AggressiveMonster.cpp
index 447bf3549..85b122034 100644
--- a/src/Mobs/AggressiveMonster.cpp
+++ b/src/Mobs/AggressiveMonster.cpp
@@ -108,14 +108,13 @@ void cAggressiveMonster::Attack(float a_Dt)
bool cAggressiveMonster::IsMovingToTargetPosition()
{
- static const float epsilon = 0.000000000001f;
// Difference between destination x and target x is negligible (to 10^-12 precision)
- if (fabsf((float)m_FinalDestination.x - (float)m_Target->GetPosX()) < epsilon)
+ if (fabsf((float)m_FinalDestination.x - (float)m_Target->GetPosX()) < std::numeric_limits<float>::epsilon())
{
return false;
}
// Difference between destination z and target z is negligible (to 10^-12 precision)
- else if (fabsf((float)m_FinalDestination.z - (float)m_Target->GetPosZ()) > epsilon)
+ else if (fabsf((float)m_FinalDestination.z - (float)m_Target->GetPosZ()) > std::numeric_limits<float>::epsilon())
{
return false;
}
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index c66ab4e04..62670907f 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -827,6 +827,10 @@ cMonster * cMonster::NewMonsterFromType(cMonster::eType a_MobType)
switch (a_MobType)
{
case mtMagmaCube:
+ {
+ toReturn = new cMagmaCube(Random.NextInt(2) + 1);
+ break;
+ }
case mtSlime:
{
toReturn = new cSlime(Random.NextInt(2) + 1);
diff --git a/src/Noise.cpp b/src/Noise.cpp
index 13a194938..89115d992 100644
--- a/src/Noise.cpp
+++ b/src/Noise.cpp
@@ -814,7 +814,7 @@ void cPerlinNoise::SetSeed(int a_Seed)
void cPerlinNoise::AddOctave(float a_Frequency, float a_Amplitude)
{
- m_Octaves.push_back(cOctave(m_Seed * (m_Octaves.size() + 4) * 4 + 1024, a_Frequency, a_Amplitude));
+ m_Octaves.push_back(cOctave(m_Seed * ((int)m_Octaves.size() + 4) * 4 + 1024, a_Frequency, a_Amplitude));
}
diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp
index 33b9cfc3f..8c24fa541 100644
--- a/src/OSSupport/File.cpp
+++ b/src/OSSupport/File.cpp
@@ -75,7 +75,7 @@ bool cFile::Open(const AString & iFileName, eMode iMode)
}
#ifdef _WIN32
- fopen_s(&m_File, (FILE_IO_PREFIX + iFileName).c_str(), Mode);
+ m_File = _fsopen((FILE_IO_PREFIX + iFileName).c_str(), Mode, _SH_DENYWR);
#else
m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), Mode);
#endif // _WIN32
@@ -88,7 +88,7 @@ bool cFile::Open(const AString & iFileName, eMode iMode)
// Simply re-open for read-writing, erasing existing contents:
#ifdef _WIN32
- fopen_s(&m_File, (FILE_IO_PREFIX + iFileName).c_str(), "wb+");
+ m_File = _fsopen((FILE_IO_PREFIX + iFileName).c_str(), "wb+", _SH_DENYWR);
#else
m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), "wb+");
#endif // _WIN32
diff --git a/src/OSSupport/ListenThread.cpp b/src/OSSupport/ListenThread.cpp
index ba3198764..02e98acfc 100644
--- a/src/OSSupport/ListenThread.cpp
+++ b/src/OSSupport/ListenThread.cpp
@@ -214,7 +214,7 @@ void cListenThread::Execute(void)
timeval tv; // On Linux select() doesn't seem to wake up when socket is closed, so let's kinda busy-wait:
tv.tv_sec = 1;
tv.tv_usec = 0;
- if (select(Highest + 1, &fdRead, NULL, NULL, &tv) == -1)
+ if (select((int)Highest + 1, &fdRead, NULL, NULL, &tv) == -1)
{
LOG("select(R) call failed in cListenThread: \"%s\"", cSocket::GetLastErrorString().c_str());
continue;
diff --git a/src/OSSupport/Socket.cpp b/src/OSSupport/Socket.cpp
index 98f694a79..56835b518 100644
--- a/src/OSSupport/Socket.cpp
+++ b/src/OSSupport/Socket.cpp
@@ -328,18 +328,18 @@ bool cSocket::ConnectIPv4(const AString & a_HostNameOrAddr, unsigned short a_Por
-int cSocket::Receive(char * a_Buffer, unsigned int a_Length, unsigned int a_Flags)
+int cSocket::Receive(char * a_Buffer, size_t a_Length, unsigned int a_Flags)
{
- return recv(m_Socket, a_Buffer, a_Length, a_Flags);
+ return recv(m_Socket, a_Buffer, (int)a_Length, a_Flags);
}
-int cSocket::Send(const char * a_Buffer, unsigned int a_Length)
+int cSocket::Send(const char * a_Buffer, size_t a_Length)
{
- return send(m_Socket, a_Buffer, a_Length, MSG_NOSIGNAL);
+ return send(m_Socket, a_Buffer, (int)a_Length, MSG_NOSIGNAL);
}
diff --git a/src/OSSupport/Socket.h b/src/OSSupport/Socket.h
index bdc2babf5..35ecadfa0 100644
--- a/src/OSSupport/Socket.h
+++ b/src/OSSupport/Socket.h
@@ -110,8 +110,8 @@ public:
/// Connects to the specified host or string IP address and port, using IPv4. Returns true if successful.
bool ConnectIPv4(const AString & a_HostNameOrAddr, unsigned short a_Port);
- int Receive(char * a_Buffer, unsigned int a_Length, unsigned int a_Flags);
- int Send (const char * a_Buffer, unsigned int a_Length);
+ int Receive(char * a_Buffer, size_t a_Length, unsigned int a_Flags);
+ int Send (const char * a_Buffer, size_t a_Length);
unsigned short GetPort(void) const; // Returns 0 on failure
diff --git a/src/OSSupport/SocketThreads.cpp b/src/OSSupport/SocketThreads.cpp
index 0bc1d6b55..0ab5b6298 100644
--- a/src/OSSupport/SocketThreads.cpp
+++ b/src/OSSupport/SocketThreads.cpp
@@ -406,7 +406,7 @@ void cSocketThreads::cSocketThread::Execute(void)
timeval Timeout;
Timeout.tv_sec = 5;
Timeout.tv_usec = 0;
- if (select(Highest + 1, &fdRead, &fdWrite, NULL, &Timeout) == -1)
+ if (select((int)Highest + 1, &fdRead, &fdWrite, NULL, &Timeout) == -1)
{
LOG("select() call failed in cSocketThread: \"%s\"", cSocket::GetLastErrorString().c_str());
continue;
diff --git a/src/ProbabDistrib.cpp b/src/ProbabDistrib.cpp
index 5fa17c276..7a5869dcc 100644
--- a/src/ProbabDistrib.cpp
+++ b/src/ProbabDistrib.cpp
@@ -118,7 +118,7 @@ int cProbabDistrib::MapValue(int a_OrigValue) const
size_t Hi = m_Cumulative.size() - 1;
while (Hi - Lo > 1)
{
- int Mid = (Lo + Hi) / 2;
+ size_t Mid = (Lo + Hi) / 2;
int MidProbab = m_Cumulative[Mid].m_Probability;
if (MidProbab < a_OrigValue)
{
diff --git a/src/Protocol/Authenticator.cpp b/src/Protocol/Authenticator.cpp
index 41d614e58..2050393c2 100644
--- a/src/Protocol/Authenticator.cpp
+++ b/src/Protocol/Authenticator.cpp
@@ -214,7 +214,7 @@ bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_S
ReplaceString(ActualAddress, "%SERVERID%", a_ServerId);
AString Request;
- Request += "GET " + ActualAddress + " HTTP/1.1\r\n";
+ Request += "GET " + ActualAddress + " HTTP/1.0\r\n";
Request += "Host: " + m_Server + "\r\n";
Request += "User-Agent: MCServer\r\n";
Request += "Connection: close\r\n";
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index bc9aff0c0..443723e40 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -197,7 +197,7 @@ void cProtocol172::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV
Pkt.WriteInt(a_ChunkX);
Pkt.WriteInt(a_ChunkZ);
Pkt.WriteShort((short)a_Changes.size());
- Pkt.WriteInt(a_Changes.size() * 4);
+ Pkt.WriteInt((int)a_Changes.size() * 4);
for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr)
{
unsigned int Coords = itr->y | (itr->z << 8) | (itr->x << 12);
@@ -532,7 +532,7 @@ void cProtocol172::SendExplosion(double a_BlockX, double a_BlockY, double a_Bloc
Pkt.WriteFloat((float)a_BlockY);
Pkt.WriteFloat((float)a_BlockZ);
Pkt.WriteFloat((float)a_Radius);
- Pkt.WriteInt(a_BlocksAffected.size());
+ Pkt.WriteInt((int)a_BlocksAffected.size());
for (cVector3iArray::const_iterator itr = a_BlocksAffected.begin(), end = a_BlocksAffected.end(); itr != end; ++itr)
{
Pkt.WriteChar((char)itr->x);
@@ -698,7 +698,7 @@ void cProtocol172::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decor
cPacketizer Pkt(*this, 0x34);
Pkt.WriteVarInt(a_ID);
- Pkt.WriteShort (1 + (3 * a_Decorators.size()));
+ Pkt.WriteShort ((short)(1 + (3 * a_Decorators.size())));
Pkt.WriteByte(1);
@@ -1174,7 +1174,7 @@ void cProtocol172::SendTabCompletionResults(const AStringVector & a_Results)
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x3a); // Tab-Complete packet
- Pkt.WriteVarInt(a_Results.size());
+ Pkt.WriteVarInt((int)a_Results.size());
for (AStringVector::const_iterator itr = a_Results.begin(), end = a_Results.end(); itr != end; ++itr)
{
@@ -1743,7 +1743,7 @@ void cProtocol172::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer)
cPacketizer Pkt(*this, 0x01);
Pkt.WriteString(Server->GetServerID());
const AString & PubKeyDer = Server->GetPublicKeyDER();
- Pkt.WriteShort(PubKeyDer.size());
+ Pkt.WriteShort((short)PubKeyDer.size());
Pkt.WriteBuf(PubKeyDer.data(), PubKeyDer.size());
Pkt.WriteShort(4);
Pkt.WriteInt((int)(intptr_t)this); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :)
@@ -2138,7 +2138,7 @@ void cProtocol172::WritePacket(cByteBuffer & a_Packet)
cCSLock Lock(m_CSPacket);
AString Pkt;
a_Packet.ReadAll(Pkt);
- WriteVarInt(Pkt.size());
+ WriteVarInt((UInt32)Pkt.size());
SendData(Pkt.data(), Pkt.size());
Flush();
}
@@ -2278,6 +2278,13 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
}
break;
}
+ case TAG_Int:
+ {
+ if (TagName == "RepairCost")
+ {
+ a_Item.m_RepairCost = NBT.GetInt(tag);
+ }
+ }
default: LOGD("Unimplemented NBT data when parsing!"); break;
}
}
@@ -2396,7 +2403,7 @@ cProtocol172::cPacketizer::~cPacketizer()
AString DataToSend;
// Send the packet length
- UInt32 PacketLen = m_Out.GetUsedSpace();
+ UInt32 PacketLen = (UInt32)m_Out.GetUsedSpace();
m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen);
m_Protocol.m_OutPacketLenBuffer.ReadAll(DataToSend);
m_Protocol.SendData(DataToSend.data(), DataToSend.size());
@@ -2451,6 +2458,10 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item)
// Send the enchantments and custom names:
cFastNBTWriter Writer;
+ if (a_Item.m_RepairCost != 0)
+ {
+ Writer.AddInt("RepairCost", a_Item.m_RepairCost);
+ }
if (!a_Item.m_Enchantments.IsEmpty())
{
const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
@@ -2489,7 +2500,7 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item)
Writer.Finish();
AString Compressed;
CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed);
- WriteShort(Compressed.size());
+ WriteShort((short)Compressed.size());
WriteBuf(Compressed.data(), Compressed.size());
}
@@ -2559,7 +2570,7 @@ void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt
AString Compressed;
CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed);
- WriteShort(Compressed.size());
+ WriteShort((short)Compressed.size());
WriteBuf(Compressed.data(), Compressed.size());
}
diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h
index eed761a4a..dc111e737 100644
--- a/src/Protocol/Protocol17x.h
+++ b/src/Protocol/Protocol17x.h
@@ -238,7 +238,7 @@ protected:
bool m_IsEncrypted;
cAesCfb128Decryptor m_Decryptor;
- cAesCfb128Decryptor m_Encryptor;
+ cAesCfb128Encryptor m_Encryptor;
/** The logfile where the comm is logged, when g_ShouldLogComm is true */
cFile m_CommLogFile;
diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp
index 22dfe7c88..667fb5cef 100644
--- a/src/Protocol/ProtocolRecognizer.cpp
+++ b/src/Protocol/ProtocolRecognizer.cpp
@@ -871,7 +871,7 @@ bool cProtocolRecognizer::TryRecognizeProtocol(void)
// Not enough bytes for the packet length, keep waiting
return false;
}
- ReadSoFar -= m_Buffer.GetReadableSpace();
+ ReadSoFar -= (UInt32)m_Buffer.GetReadableSpace();
if (!m_Buffer.CanReadBytes(PacketLen))
{
// Not enough bytes for the packet, keep waiting
@@ -961,7 +961,7 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema
{
return false;
}
- NumBytesRead -= m_Buffer.GetReadableSpace();
+ NumBytesRead -= (UInt32)m_Buffer.GetReadableSpace();
switch (ProtocolVersion)
{
case PROTO_VERSION_1_7_2:
diff --git a/src/RCONServer.cpp b/src/RCONServer.cpp
index cd5292ac3..c511968be 100644
--- a/src/RCONServer.cpp
+++ b/src/RCONServer.cpp
@@ -59,7 +59,7 @@ public:
virtual void Finished(void) override
{
- m_Connection.SendResponse(m_RequestID, RCON_PACKET_RESPONSE, m_Buffer.size(), m_Buffer.c_str());
+ m_Connection.SendResponse(m_RequestID, RCON_PACKET_RESPONSE, (int)m_Buffer.size(), m_Buffer.c_str());
delete this;
}
diff --git a/src/Root.cpp b/src/Root.cpp
index 5d32bdd87..c82b05a66 100644
--- a/src/Root.cpp
+++ b/src/Root.cpp
@@ -590,13 +590,13 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac
{
class cCallback : public cPlayerListCallback
{
- unsigned m_BestRating;
- unsigned m_NameLength;
+ size_t m_BestRating;
+ size_t m_NameLength;
const AString m_PlayerName;
virtual bool Item (cPlayer * a_pPlayer)
{
- unsigned int Rating = RateCompareString (m_PlayerName, a_pPlayer->GetName());
+ size_t Rating = RateCompareString (m_PlayerName, a_pPlayer->GetName());
if ((Rating > 0) && (Rating >= m_BestRating))
{
m_BestMatch = a_pPlayer;
@@ -626,7 +626,7 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac
cPlayer * m_BestMatch;
unsigned m_NumMatches;
} Callback (a_PlayerName);
- ForEachPlayer( Callback );
+ ForEachPlayer(Callback);
if (Callback.m_NumMatches == 1)
{
@@ -763,8 +763,8 @@ void cRoot::LogChunkStats(cCommandOutputCallback & a_Output)
{
cWorld * World = itr->second;
int NumInGenerator = World->GetGeneratorQueueLength();
- int NumInSaveQueue = World->GetStorageSaveQueueLength();
- int NumInLoadQueue = World->GetStorageLoadQueueLength();
+ int NumInSaveQueue = (int)World->GetStorageSaveQueueLength();
+ int NumInLoadQueue = (int)World->GetStorageLoadQueueLength();
int NumValid = 0;
int NumDirty = 0;
int NumInLighting = 0;
@@ -784,8 +784,6 @@ void cRoot::LogChunkStats(cCommandOutputCallback & a_Output)
a_Output.Out(" block lighting: " SIZE_T_FMT_PRECISION(6) " bytes (" SIZE_T_FMT_PRECISION(3) " KiB)", 2 * sizeof(cChunkDef::BlockNibbles), (2 * sizeof(cChunkDef::BlockNibbles) + 1023) / 1024);
a_Output.Out(" heightmap: " SIZE_T_FMT_PRECISION(6) " bytes (" SIZE_T_FMT_PRECISION(3) " KiB)", sizeof(cChunkDef::HeightMap), (sizeof(cChunkDef::HeightMap) + 1023) / 1024);
a_Output.Out(" biomemap: " SIZE_T_FMT_PRECISION(6) " bytes (" SIZE_T_FMT_PRECISION(3) " KiB)", sizeof(cChunkDef::BiomeMap), (sizeof(cChunkDef::BiomeMap) + 1023) / 1024);
- int Rest = sizeof(cChunk) - sizeof(cChunkDef::BlockTypes) - 3 * sizeof(cChunkDef::BlockNibbles) - sizeof(cChunkDef::HeightMap) - sizeof(cChunkDef::BiomeMap);
- a_Output.Out(" other: %6d bytes (%3d KiB)", Rest, (Rest + 1023) / 1024);
SumNumValid += NumValid;
SumNumDirty += NumDirty;
SumNumInLighting += NumInLighting;
diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp
index 4c89ce265..250f63aa9 100644
--- a/src/Scoreboard.cpp
+++ b/src/Scoreboard.cpp
@@ -261,7 +261,7 @@ void cTeam::SetDisplayName(const AString & a_Name)
-unsigned int cTeam::GetNumPlayers(void) const
+size_t cTeam::GetNumPlayers(void) const
{
return m_Players.size();
}
@@ -569,7 +569,7 @@ void cScoreboard::SendTo(cClientHandle & a_Client)
-unsigned int cScoreboard::GetNumObjectives(void) const
+size_t cScoreboard::GetNumObjectives(void) const
{
return m_Objectives.size();
}
@@ -578,7 +578,7 @@ unsigned int cScoreboard::GetNumObjectives(void) const
-unsigned int cScoreboard::GetNumTeams(void) const
+size_t cScoreboard::GetNumTeams(void) const
{
return m_Teams.size();
}
diff --git a/src/Scoreboard.h b/src/Scoreboard.h
index 2fae5e499..1e1973a10 100644
--- a/src/Scoreboard.h
+++ b/src/Scoreboard.h
@@ -153,7 +153,7 @@ public:
// tolua_begin
/** Returns the number of registered players */
- unsigned int GetNumPlayers(void) const;
+ size_t GetNumPlayers(void) const;
bool AllowsFriendlyFire(void) const { return m_AllowsFriendlyFire; }
bool CanSeeFriendlyInvisible(void) const { return m_CanSeeFriendlyInvisible; }
@@ -248,9 +248,9 @@ public:
cObjective * GetObjectiveIn(eDisplaySlot a_Slot);
- unsigned int GetNumObjectives(void) const;
+ size_t GetNumObjectives(void) const;
- unsigned int GetNumTeams(void) const;
+ size_t GetNumTeams(void) const;
void AddPlayerScore(const AString & a_Name, cObjective::eType a_Type, cObjective::Score a_Value = 1);
diff --git a/src/Simulator/DelayedFluidSimulator.cpp b/src/Simulator/DelayedFluidSimulator.cpp
index bc5158d95..5ff736231 100644
--- a/src/Simulator/DelayedFluidSimulator.cpp
+++ b/src/Simulator/DelayedFluidSimulator.cpp
@@ -148,7 +148,7 @@ void cDelayedFluidSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_Chunk
{
SimulateBlock(a_Chunk, itr->x, itr->y, itr->z);
}
- m_TotalBlocks -= Blocks.size();
+ m_TotalBlocks -= (int)Blocks.size();
Blocks.clear();
}
}
diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp
index 03e94e791..e95af3a1c 100644
--- a/src/Simulator/FloodyFluidSimulator.cpp
+++ b/src/Simulator/FloodyFluidSimulator.cpp
@@ -119,7 +119,7 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re
if (SpreadFurther && (NewMeta < 8))
{
// Spread to the neighbors:
- Spread(a_Chunk, a_RelX, a_RelY, a_RelZ, NewMeta);
+ SpreadXZ(a_Chunk, a_RelX, a_RelY, a_RelZ, NewMeta);
}
// Mark as processed:
@@ -130,7 +130,7 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re
-void cFloodyFluidSimulator::Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta)
+void cFloodyFluidSimulator::SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta)
{
SpreadToNeighbor(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, a_NewMeta);
SpreadToNeighbor(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, a_NewMeta);
diff --git a/src/Simulator/FloodyFluidSimulator.h b/src/Simulator/FloodyFluidSimulator.h
index 632de3bb2..8e1be5e6b 100644
--- a/src/Simulator/FloodyFluidSimulator.h
+++ b/src/Simulator/FloodyFluidSimulator.h
@@ -48,16 +48,13 @@ protected:
bool CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ);
/** Checks if the specified block should harden (Water/Lava interaction) and if so, converts it to a suitable block.
- *
- * Returns whether the block was changed or not.
- */
+ Returns whether the block was changed or not. */
bool HardenBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta);
- /** Spread water to neighbors.
- *
- * May be overridden to provide more sophisticated algorithms.
- */
- virtual void Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta);
+ /** Spread fluid to XZ neighbors.
+ The coords are of the block currently being processed; a_NewMeta is the new meta for the new fluid block.
+ Descendants may overridde to provide more sophisticated algorithms. */
+ virtual void SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta);
} ;
diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp
index d37d2eecf..074063add 100644
--- a/src/Simulator/IncrementalRedstoneSimulator.cpp
+++ b/src/Simulator/IncrementalRedstoneSimulator.cpp
@@ -9,6 +9,8 @@
#include "../Entities/Pickup.h"
#include "../Blocks/BlockTorch.h"
#include "../Blocks/BlockDoor.h"
+#include "../Blocks/BlockButton.h"
+#include "../Blocks/BlockLever.h"
#include "../Piston.h"
@@ -116,7 +118,9 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
// Things that can send power through a block but which depends on meta
((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) ||
((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) ||
- (((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta)))
+ (((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) ||
+ (((Block == E_BLOCK_STONE_PRESSURE_PLATE) || (Block == E_BLOCK_WOODEN_PRESSURE_PLATE)) && (Meta == 0)) ||
+ (((Block == E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE) || (Block == E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE)) && (Meta == 0))
)
{
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
@@ -139,14 +143,14 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
SimulatedPlayerToggleableList * SimulatedPlayerToggleableBlocks = a_Chunk->GetRedstoneSimulatorSimulatedPlayerToggleableList();
for (SimulatedPlayerToggleableList::iterator itr = SimulatedPlayerToggleableBlocks->begin(); itr != SimulatedPlayerToggleableBlocks->end(); ++itr)
{
- if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
+ if (!itr->a_RelBlockPos.Equals(Vector3i(RelX, a_BlockY, RelZ)))
{
continue;
}
if (!IsAllowedBlock(Block))
{
- LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from toggleable simulated list as it is no longer redstone", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
+ LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from toggleable simulated list as it is no longer redstone", itr->a_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z);
SimulatedPlayerToggleableBlocks->erase(itr);
break;
}
@@ -155,7 +159,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
RepeatersDelayList * RepeatersDelayList = a_Chunk->GetRedstoneSimulatorRepeatersDelayList();
for (RepeatersDelayList::iterator itr = RepeatersDelayList->begin(); itr != RepeatersDelayList->end(); ++itr)
{
- if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
+ if (!itr->a_RelBlockPos.Equals(Vector3i(RelX, a_BlockY, RelZ)))
{
continue;
}
@@ -221,9 +225,6 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
m_LinkedPoweredBlocks = a_Chunk->GetRedstoneSimulatorLinkedBlocksList();
m_Chunk = a_Chunk;
- int BaseX = a_Chunk->GetPosX() * cChunkDef::Width;
- int BaseZ = a_Chunk->GetPosZ() * cChunkDef::Width;
-
for (cRedstoneSimulatorChunkData::iterator dataitr = m_RedstoneSimulatorChunkData->begin(); dataitr != m_RedstoneSimulatorChunkData->end();)
{
if (dataitr->DataTwo)
@@ -232,67 +233,65 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
continue;
}
- int a_X = BaseX + dataitr->x;
- int a_Z = BaseZ + dataitr->z;
switch (dataitr->Data)
{
- case E_BLOCK_BLOCK_OF_REDSTONE: HandleRedstoneBlock(a_X, dataitr->y, a_Z); break;
- case E_BLOCK_LEVER: HandleRedstoneLever(a_X, dataitr->y, a_Z); break;
- case E_BLOCK_FENCE_GATE: HandleFenceGate(a_X, dataitr->y, a_Z); break;
- case E_BLOCK_TNT: HandleTNT(a_X, dataitr->y, a_Z); break;
- case E_BLOCK_TRAPDOOR: HandleTrapdoor(a_X, dataitr->y, a_Z); break;
- case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(a_X, dataitr->y, a_Z); break;
- case E_BLOCK_NOTE_BLOCK: HandleNoteBlock(a_X, dataitr->y, a_Z); break;
- case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(a_X, dataitr->y, a_Z); break;
- case E_BLOCK_COMMAND_BLOCK: HandleCommandBlock(a_X, dataitr->y, a_Z); break;
+ case E_BLOCK_BLOCK_OF_REDSTONE: HandleRedstoneBlock(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_LEVER: HandleRedstoneLever(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_FENCE_GATE: HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_TNT: HandleTNT(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_TRAPDOOR: HandleTrapdoor(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_NOTE_BLOCK: HandleNoteBlock(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_COMMAND_BLOCK: HandleCommandBlock(dataitr->x, dataitr->y, dataitr->z); break;
case E_BLOCK_REDSTONE_TORCH_OFF:
case E_BLOCK_REDSTONE_TORCH_ON:
{
- HandleRedstoneTorch(a_X, dataitr->y, a_Z, dataitr->Data);
+ HandleRedstoneTorch(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
break;
}
case E_BLOCK_STONE_BUTTON:
case E_BLOCK_WOODEN_BUTTON:
{
- HandleRedstoneButton(a_X, dataitr->y, a_Z, dataitr->Data);
+ HandleRedstoneButton(dataitr->x, dataitr->y, dataitr->z);
break;
}
case E_BLOCK_REDSTONE_REPEATER_OFF:
case E_BLOCK_REDSTONE_REPEATER_ON:
{
- HandleRedstoneRepeater(a_X, dataitr->y, a_Z, dataitr->Data);
+ HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
break;
}
case E_BLOCK_PISTON:
case E_BLOCK_STICKY_PISTON:
{
- HandlePiston(a_X, dataitr->y, a_Z);
+ HandlePiston(dataitr->x, dataitr->y, dataitr->z);
break;
}
case E_BLOCK_REDSTONE_LAMP_OFF:
case E_BLOCK_REDSTONE_LAMP_ON:
{
- HandleRedstoneLamp(a_X, dataitr->y, a_Z, dataitr->Data);
+ HandleRedstoneLamp(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
break;
}
case E_BLOCK_DISPENSER:
case E_BLOCK_DROPPER:
{
- HandleDropSpenser(a_X, dataitr->y, a_Z);
+ HandleDropSpenser(dataitr->x, dataitr->y, dataitr->z);
break;
}
case E_BLOCK_WOODEN_DOOR:
case E_BLOCK_IRON_DOOR:
{
- HandleDoor(a_X, dataitr->y, a_Z);
+ HandleDoor(dataitr->x, dataitr->y, dataitr->z);
break;
}
case E_BLOCK_ACTIVATOR_RAIL:
case E_BLOCK_DETECTOR_RAIL:
case E_BLOCK_POWERED_RAIL:
{
- HandleRail(a_X, dataitr->y, a_Z, dataitr->Data);
+ HandleRail(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
break;
}
case E_BLOCK_WOODEN_PRESSURE_PLATE:
@@ -300,7 +299,7 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
{
- HandlePressurePlate(a_X, dataitr->y, a_Z, dataitr->Data);
+ HandlePressurePlate(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
break;
}
default: LOGD("Unhandled block (!) or unimplemented redstone block: %s", ItemToString(dataitr->Data).c_str()); break;
@@ -342,7 +341,7 @@ void cIncrementalRedstoneSimulator::WakeUp(int a_BlockX, int a_BlockY, int a_Blo
-void cIncrementalRedstoneSimulator::HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState)
+void cIncrementalRedstoneSimulator::HandleRedstoneTorch(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState)
{
static const struct // Define which directions the torch can power
{
@@ -359,54 +358,58 @@ void cIncrementalRedstoneSimulator::HandleRedstoneTorch(int a_BlockX, int a_Bloc
if (a_MyState == E_BLOCK_REDSTONE_TORCH_ON)
{
// Check if the block the torch is on is powered
- int X = a_BlockX; int Y = a_BlockY; int Z = a_BlockZ;
- AddFaceDirection(X, Y, Z, cBlockTorchHandler::MetaDataToDirection(m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)), true); // Inverse true to get the block torch is on
+ int X = a_RelBlockX; int Y = a_RelBlockY; int Z = a_RelBlockZ;
+ AddFaceDirection(X, Y, Z, cBlockTorchHandler::MetaDataToDirection(m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ)), true); // Inverse true to get the block torch is on
if (AreCoordsDirectlyPowered(X, Y, Z))
{
// There was a match, torch goes off
- m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_TORCH_OFF, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ));
+ m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_TORCH_OFF, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ));
return;
}
// Torch still on, make all 4(X, Z) + 1(Y) sides powered
for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++)
{
- BLOCKTYPE Type = m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z);
+ BLOCKTYPE Type = 0;
+ if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, Type))
+ {
+ continue;
+ }
if (i + 1 < ARRAYCOUNT(gCrossCoords)) // Sides of torch, not top (top is last)
{
if (
((IsMechanism(Type)) || (Type == E_BLOCK_REDSTONE_WIRE)) && // Is it a mechanism or wire? Not block/other torch etc.
- (!Vector3i(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z).Equals(Vector3i(X, Y, Z))) // CAN'T power block is that it is on
+ (!Vector3i(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z).Equals(Vector3i(X, Y, Z))) // CAN'T power block is that it is on
)
{
- SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_TORCH_ON);
+ SetBlockPowered(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
}
}
else
{
// Top side, power whatever is there, including blocks
- SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_TORCH_ON);
+ SetBlockPowered(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
// Power all blocks surrounding block above torch
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YP, E_BLOCK_REDSTONE_TORCH_ON);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YP);
}
}
- if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0x5) // Is torch standing on ground? If NOT (i.e. on wall), power block beneath
+ if (m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) != 0x5) // Is torch standing on ground? If NOT (i.e. on wall), power block beneath
{
- BLOCKTYPE Type = m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ);
+ BLOCKTYPE Type = m_Chunk->GetBlock(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ);
if ((IsMechanism(Type)) || (Type == E_BLOCK_REDSTONE_WIRE)) // Still can't make a normal block powered though!
{
- SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_TORCH_ON);
+ SetBlockPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
}
}
}
else
{
// Check if the block the torch is on is powered
- int X = a_BlockX; int Y = a_BlockY; int Z = a_BlockZ;
- AddFaceDirection(X, Y, Z, cBlockTorchHandler::MetaDataToDirection(m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)), true); // Inverse true to get the block torch is on
+ int X = a_RelBlockX; int Y = a_RelBlockY; int Z = a_RelBlockZ;
+ AddFaceDirection(X, Y, Z, cBlockTorchHandler::MetaDataToDirection(m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ)), true); // Inverse true to get the block torch is on
// See if off state torch can be turned on again
if (AreCoordsDirectlyPowered(X, Y, Z))
@@ -415,7 +418,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneTorch(int a_BlockX, int a_Bloc
}
// Block torch on not powered, can be turned on again!
- m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_TORCH_ON, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ));
+ m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_TORCH_ON, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ));
}
}
@@ -423,28 +426,47 @@ void cIncrementalRedstoneSimulator::HandleRedstoneTorch(int a_BlockX, int a_Bloc
-void cIncrementalRedstoneSimulator::HandleRedstoneBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cIncrementalRedstoneSimulator::HandleRedstoneBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
- SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BLOCK_OF_REDSTONE);
- SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BLOCK_OF_REDSTONE); // Set self as powered
+ SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ); // Set self as powered
}
-void cIncrementalRedstoneSimulator::HandleRedstoneLever(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cIncrementalRedstoneSimulator::HandleRedstoneLever(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
- if (IsLeverOn(m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)))
+ NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ if (IsLeverOn(Meta))
{
- SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LEVER);
+ SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_LEVER);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_LEVER);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_LEVER);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YP, E_BLOCK_LEVER);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_LEVER);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_LEVER);
+ NIBBLETYPE Dir = cBlockLeverHandler::BlockMetaDataToBlockFace(Meta);
+ switch (Dir) // Now, flip the direction into the type used by SetBlockLinkedPowered()
+ {
+ case BLOCK_FACE_YP:
+ case BLOCK_FACE_XP:
+ case BLOCK_FACE_ZP:
+ {
+ Dir--;
+ break;
+ }
+ case BLOCK_FACE_XM:
+ case BLOCK_FACE_ZM:
+ case BLOCK_FACE_YM:
+ {
+ Dir++;
+ break;
+ }
+ default:
+ {
+ ASSERT(!"Unhandled lever metadata!");
+ return;
+ }
+ }
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir);
}
}
@@ -452,27 +474,29 @@ void cIncrementalRedstoneSimulator::HandleRedstoneLever(int a_BlockX, int a_Bloc
-void cIncrementalRedstoneSimulator::HandleFenceGate(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cIncrementalRedstoneSimulator::HandleFenceGate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
cChunkInterface ChunkInterface(m_World.GetChunkMap());
- NIBBLETYPE MetaData = ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE MetaData = ChunkInterface.GetBlockMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
- if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
+ if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ))
{
- if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, true))
+ if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true))
{
- m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, MetaData | 0x4);
- m_World.BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0);
- SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, true);
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData | 0x4);
+ m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0);
+ SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true);
}
}
else
{
- if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, false))
+ if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false))
{
- m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, MetaData & 0xFFFFFFFB);
- m_World.BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0);
- SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, false);
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData & 0xFFFFFFFB);
+ m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0);
+ SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false);
}
}
}
@@ -481,18 +505,35 @@ void cIncrementalRedstoneSimulator::HandleFenceGate(int a_BlockX, int a_BlockY,
-void cIncrementalRedstoneSimulator::HandleRedstoneButton(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType)
+void cIncrementalRedstoneSimulator::HandleRedstoneButton(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
- if (IsButtonOn(m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)))
+ NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ if (IsButtonOn(Meta))
{
- SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, a_BlockType);
-
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, a_BlockType);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, a_BlockType);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, a_BlockType);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YP, a_BlockType);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, a_BlockType);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, a_BlockType);
+ SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+
+ NIBBLETYPE Dir = cBlockButtonHandler::BlockMetaDataToBlockFace(Meta);
+ switch (Dir) // Now, flip the direction into the type used by SetBlockLinkedPowered()
+ {
+ case BLOCK_FACE_XP:
+ case BLOCK_FACE_ZP:
+ {
+ Dir--;
+ break;
+ }
+ case BLOCK_FACE_XM:
+ case BLOCK_FACE_ZM:
+ {
+ Dir++;
+ break;
+ }
+ default:
+ {
+ ASSERT(!"Unhandled button metadata!");
+ return;
+ }
+ }
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir);
}
}
@@ -500,7 +541,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneButton(int a_BlockX, int a_Blo
-void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
static const struct // Define which directions the wire can receive power from
{
@@ -535,14 +576,16 @@ void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_Block
// Check to see if directly beside a power source
unsigned char MyPower;
- if (!IsWirePowered(a_BlockX, a_BlockY, a_BlockZ, MyPower))
+ if (!IsWirePowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower))
{
- m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0);
- m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0);
+ m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ);
return;
}
- m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, MyPower);
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower);
if (MyPower < 1)
{
@@ -555,74 +598,98 @@ void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_Block
{
if ((i >= 4) && (i <= 7)) // If we are currently checking for wire surrounding ourself one block above...
{
- if (cBlockInfo::IsSolid(m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))) // If there is something solid above us (wire cut off)...
+ BLOCKTYPE Type = 0;
+ if (a_RelBlockY + 1 >= cChunkDef::Height)
+ {
+ continue;
+ }
+ if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, Type))
+ {
+ continue;
+ }
+ if (cBlockInfo::IsSolid(Type)) // If there is something solid above us (wire cut off)...
{
continue; // We don't receive power from that wire
}
}
else if ((i >= 8) && (i <= 11)) // See above, but this is for wire below us
{
- if (cBlockInfo::IsSolid(m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)))
+ BLOCKTYPE Type = 0;
+ if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY, a_RelBlockZ + gCrossCoords[i].z, Type))
+ {
+ continue;
+ }
+ if (cBlockInfo::IsSolid(Type))
{
continue;
}
}
- if (m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z) == E_BLOCK_REDSTONE_WIRE)
+ BLOCKTYPE Type = 0;
+ if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, Type))
{
- SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
+ continue;
+ }
+ if (Type == E_BLOCK_REDSTONE_WIRE)
+ {
+ SetBlockPowered(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower);
}
}
for (size_t i = 0; i < ARRAYCOUNT(gSideCoords); i++) // Look for repeaters immediately surrounding self and try to power them
{
- if (m_World.GetBlock(a_BlockX + gSideCoords[i].x, a_BlockY + gSideCoords[i].y, a_BlockZ + gSideCoords[i].z) == E_BLOCK_REDSTONE_REPEATER_OFF)
+ BLOCKTYPE Type = 0;
+ if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + gSideCoords[i].x, a_RelBlockY + gSideCoords[i].y, a_RelBlockZ + gSideCoords[i].z, Type))
{
- SetBlockPowered(a_BlockX + gSideCoords[i].x, a_BlockY + gSideCoords[i].y, a_BlockZ + gSideCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
+ continue;
+ }
+ if (Type == E_BLOCK_REDSTONE_REPEATER_OFF)
+ {
+ SetBlockPowered(a_RelBlockX + gSideCoords[i].x, a_RelBlockY + gSideCoords[i].y, a_RelBlockZ + gSideCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower);
}
}
// Wire still powered, power blocks beneath
- SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_REDSTONE_WIRE, MyPower);
+ SetBlockPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, MyPower);
- switch (GetWireDirection(a_BlockX, a_BlockY, a_BlockZ))
+ switch (GetWireDirection(a_RelBlockX, a_RelBlockY, a_RelBlockZ))
{
case REDSTONE_NONE:
{
- SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
- SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
- SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
- SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
+ SetBlockPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower);
+ SetBlockPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower);
+ SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower);
+ SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_WIRE, MyPower);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_WIRE, MyPower);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_WIRE, MyPower);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_WIRE, MyPower);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XM, MyPower);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XP, MyPower);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZM, MyPower);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZP, MyPower);
break;
}
case REDSTONE_X_POS:
{
- SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_WIRE, MyPower);
+ SetBlockPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XP, MyPower);
break;
}
case REDSTONE_X_NEG:
{
- SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_WIRE, MyPower);
+ SetBlockPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XM, MyPower);
break;
}
case REDSTONE_Z_POS:
{
- SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_WIRE, MyPower);
+ SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZP, MyPower);
break;
}
case REDSTONE_Z_NEG:
{
- SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE, MyPower);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_WIRE, MyPower);
+ SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MyPower);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZM, MyPower);
break;
}
}
@@ -632,7 +699,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_Block
-void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState)
+void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState)
{
/* Repeater Orientation Mini Guide:
===================================
@@ -643,7 +710,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_B
X Axis ---->
- Repeater directions, values from a cWorld::GetBlockMeta(a_BlockX , a_BlockY, a_BlockZ) lookup:
+ Repeater directions, values from a cWorld::GetBlockMeta(a_RelBlockX , a_RelBlockY, a_RelBlockZ) lookup:
East (Right) (X+): 0x1
West (Left) (X-): 0x3
@@ -656,25 +723,25 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_B
*/
// Create a variable holding my meta to avoid multiple lookups.
- NIBBLETYPE a_Meta = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE a_Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
bool IsOn = (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON);
- if (!IsRepeaterLocked(a_BlockX, a_BlockY, a_BlockZ, a_Meta)) // If we're locked, change nothing. Otherwise:
+ if (!IsRepeaterLocked(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta)) // If we're locked, change nothing. Otherwise:
{
- bool IsSelfPowered = IsRepeaterPowered(a_BlockX, a_BlockY, a_BlockZ, a_Meta);
+ bool IsSelfPowered = IsRepeaterPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta);
if (IsSelfPowered && !IsOn) // Queue a power change if powered, but not on and not locked.
{
- QueueRepeaterPowerChange(a_BlockX, a_BlockY, a_BlockZ, a_Meta, true);
+ QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, true);
}
else if (!IsSelfPowered && IsOn) // Queue a power change if unpowered, on, and not locked.
{
- QueueRepeaterPowerChange(a_BlockX, a_BlockY, a_BlockZ, a_Meta, false);
+ QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false);
}
}
for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end(); ++itr)
{
- if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
+ if (!itr->a_RelBlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ)))
{
continue;
}
@@ -685,33 +752,33 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_B
{
if (!IsOn)
{
- m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); // For performance
+ m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); // For performance
}
switch (a_Meta & 0x3) // We only want the direction (bottom) bits
{
case 0x0:
{
- SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_REPEATER_ON);
+ SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZM);
break;
}
case 0x1:
{
- SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_REPEATER_ON);
+ SetBlockPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XP);
break;
}
case 0x2:
{
- SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_REPEATER_ON);
+ SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZP);
break;
}
case 0x3:
{
- SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON);
- SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_REPEATER_ON);
+ SetBlockPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XM);
break;
}
}
@@ -724,7 +791,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_B
{
if (IsOn)
{
- m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta);
+ m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta);
}
m_RepeatersDelayList->erase(itr); // We can remove off repeaters which don't need further updating
return;
@@ -735,7 +802,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_B
// Apparently, incrementing ticks only works reliably here, and not in SimChunk;
// With a world with lots of redstone, the repeaters simply do not delay
// I am confounded to say why. Perhaps optimisation failure.
- LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks);
+ LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", itr->a_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks);
itr->a_ElapsedTicks++;
}
}
@@ -745,16 +812,19 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_B
-void cIncrementalRedstoneSimulator::HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cIncrementalRedstoneSimulator::HandlePiston(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
cPiston Piston(&m_World);
- if (IsPistonPowered(a_BlockX, a_BlockY, a_BlockZ, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x7)) // We only want the bottom three bits (4th controls extended-ness)
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+
+ if (IsPistonPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x7)) // We only want the bottom three bits (4th controls extended-ness)
{
- Piston.ExtendPiston(a_BlockX, a_BlockY, a_BlockZ);
+ Piston.ExtendPiston(BlockX, a_RelBlockY, BlockZ);
}
else
{
- Piston.RetractPiston(a_BlockX, a_BlockY, a_BlockZ);
+ Piston.RetractPiston(BlockX, a_RelBlockY, BlockZ);
}
}
@@ -762,7 +832,7 @@ void cIncrementalRedstoneSimulator::HandlePiston(int a_BlockX, int a_BlockY, int
-void cIncrementalRedstoneSimulator::HandleDropSpenser(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cIncrementalRedstoneSimulator::HandleDropSpenser(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
class cSetPowerToDropSpenser :
public cDropSpenserCallback
@@ -776,29 +846,31 @@ void cIncrementalRedstoneSimulator::HandleDropSpenser(int a_BlockX, int a_BlockY
a_DropSpenser->SetRedstonePower(m_IsPowered);
return false;
}
- } DrSpSP (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ));
+ } DrSpSP (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ));
- m_World.DoWithDropSpenserAt(a_BlockX, a_BlockY, a_BlockZ, DrSpSP);
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+ m_Chunk->DoWithDropSpenserAt(BlockX, a_RelBlockY, BlockZ, DrSpSP);
}
-void cIncrementalRedstoneSimulator::HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState)
+void cIncrementalRedstoneSimulator::HandleRedstoneLamp(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState)
{
if (a_MyState == E_BLOCK_REDSTONE_LAMP_OFF)
{
- if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
+ if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ))
{
- m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_LAMP_ON, 0);
+ m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_LAMP_ON, 0);
}
}
else
{
- if (!AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
+ if (!AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ))
{
- m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_LAMP_OFF, 0);
+ m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_LAMP_OFF, 0);
}
}
}
@@ -807,13 +879,16 @@ void cIncrementalRedstoneSimulator::HandleRedstoneLamp(int a_BlockX, int a_Block
-void cIncrementalRedstoneSimulator::HandleTNT(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cIncrementalRedstoneSimulator::HandleTNT(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
- if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+
+ if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ))
{
- m_World.BroadcastSoundEffect("game.tnt.primed", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f);
- m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
- m_World.SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5); // 80 ticks to boom
+ m_Chunk->BroadcastSoundEffect("game.tnt.primed", BlockX * 8, a_RelBlockY * 8, BlockZ * 8, 0.5f, 0.6f);
+ m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_AIR, 0);
+ m_World.SpawnPrimedTNT(BlockX + 0.5, a_RelBlockY + 0.5, BlockZ + 0.5); // 80 ticks to boom
}
}
@@ -821,26 +896,29 @@ void cIncrementalRedstoneSimulator::HandleTNT(int a_BlockX, int a_BlockY, int a_
-void cIncrementalRedstoneSimulator::HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cIncrementalRedstoneSimulator::HandleDoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
- if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+
+ if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ))
{
- if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, true))
+ if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true))
{
cChunkInterface ChunkInterface(m_World.GetChunkMap());
- cBlockDoorHandler::ChangeDoor(ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
- m_World.BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0);
- SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, true);
+ cBlockDoorHandler::ChangeDoor(ChunkInterface, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0);
+ SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true);
}
}
else
{
- if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, false))
+ if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false))
{
cChunkInterface ChunkInterface(m_World.GetChunkMap());
- cBlockDoorHandler::ChangeDoor(ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
- m_World.BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0);
- SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, false);
+ cBlockDoorHandler::ChangeDoor(ChunkInterface, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0);
+ SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false);
}
}
}
@@ -849,7 +927,7 @@ void cIncrementalRedstoneSimulator::HandleDoor(int a_BlockX, int a_BlockY, int a
-void cIncrementalRedstoneSimulator::HandleCommandBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cIncrementalRedstoneSimulator::HandleCommandBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
class cSetPowerToCommandBlock :
public cCommandBlockCallback
@@ -863,37 +941,39 @@ void cIncrementalRedstoneSimulator::HandleCommandBlock(int a_BlockX, int a_Block
a_CommandBlock->SetRedstonePower(m_IsPowered);
return false;
}
- } CmdBlockSP (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ));
+ } CmdBlockSP (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ));
- m_World.DoWithCommandBlockAt(a_BlockX, a_BlockY, a_BlockZ, CmdBlockSP);
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+ m_Chunk->DoWithCommandBlockAt(BlockX, a_RelBlockY, BlockZ, CmdBlockSP);
}
-void cIncrementalRedstoneSimulator::HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType)
+void cIncrementalRedstoneSimulator::HandleRail(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType)
{
switch (a_MyType)
{
case E_BLOCK_DETECTOR_RAIL:
{
- if ((m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x08) == 0x08)
+ if ((m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x08) == 0x08)
{
- SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, a_MyType);
+ SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_MyType);
}
break;
}
case E_BLOCK_ACTIVATOR_RAIL:
case E_BLOCK_POWERED_RAIL:
{
- if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
+ if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ))
{
- m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) | 0x08);
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) | 0x08);
}
else
{
- m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x07);
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x07);
}
break;
}
@@ -905,22 +985,25 @@ void cIncrementalRedstoneSimulator::HandleRail(int a_BlockX, int a_BlockY, int a
-void cIncrementalRedstoneSimulator::HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cIncrementalRedstoneSimulator::HandleTrapdoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
- if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+
+ if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ))
{
- if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, true))
+ if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true))
{
- m_World.SetTrapdoorOpen(a_BlockX, a_BlockY, a_BlockZ, true);
- SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, true);
+ m_World.SetTrapdoorOpen(BlockX, a_RelBlockY, BlockZ, true);
+ SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true);
}
}
else
{
- if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, false))
+ if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false))
{
- m_World.SetTrapdoorOpen(a_BlockX, a_BlockY, a_BlockZ, false);
- SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, false);
+ m_World.SetTrapdoorOpen(BlockX, a_RelBlockY, BlockZ, false);
+ SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false);
}
}
}
@@ -929,13 +1012,13 @@ void cIncrementalRedstoneSimulator::HandleTrapdoor(int a_BlockX, int a_BlockY, i
-void cIncrementalRedstoneSimulator::HandleNoteBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cIncrementalRedstoneSimulator::HandleNoteBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
- bool m_bAreCoordsPowered = AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ);
+ bool m_bAreCoordsPowered = AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
if (m_bAreCoordsPowered)
{
- if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, true))
+ if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true))
{
class cSetPowerToNoteBlock :
public cNoteBlockCallback
@@ -954,15 +1037,17 @@ void cIncrementalRedstoneSimulator::HandleNoteBlock(int a_BlockX, int a_BlockY,
}
} NoteBlockSP(m_bAreCoordsPowered);
- m_World.DoWithNoteBlockAt(a_BlockX, a_BlockY, a_BlockZ, NoteBlockSP);
- SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, true);
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+ m_Chunk->DoWithNoteBlockAt(BlockX, a_RelBlockY, BlockZ, NoteBlockSP);
+ SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true);
}
}
else
{
- if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, false))
+ if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false))
{
- SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, false);
+ SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false);
}
}
}
@@ -971,10 +1056,10 @@ void cIncrementalRedstoneSimulator::HandleNoteBlock(int a_BlockX, int a_BlockY,
-void cIncrementalRedstoneSimulator::HandleDaylightSensor(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cIncrementalRedstoneSimulator::HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
int a_ChunkX, a_ChunkZ;
- cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, a_ChunkX, a_ChunkZ);
+ cChunkDef::BlockToChunk(a_RelBlockX, a_RelBlockZ, a_ChunkX, a_ChunkZ);
if (!m_World.IsChunkLighted(a_ChunkX, a_ChunkZ))
{
@@ -982,10 +1067,12 @@ void cIncrementalRedstoneSimulator::HandleDaylightSensor(int a_BlockX, int a_Blo
}
else
{
- NIBBLETYPE SkyLight = m_World.GetBlockSkyLight(a_BlockX, a_BlockY + 1, a_BlockZ) - m_World.GetSkyDarkness();
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+ NIBBLETYPE SkyLight = m_Chunk->GetTimeAlteredLight(m_World.GetBlockSkyLight(BlockX, a_RelBlockY + 1, BlockZ));
if (SkyLight > 8)
{
- SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_DAYLIGHT_SENSOR);
+ SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
}
}
}
@@ -994,24 +1081,28 @@ void cIncrementalRedstoneSimulator::HandleDaylightSensor(int a_BlockX, int a_Blo
-void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType)
+void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType)
{
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+
switch (a_MyType)
{
case E_BLOCK_STONE_PRESSURE_PLATE:
{
// MCS feature - stone pressure plates can only be triggered by players :D
- cPlayer * a_Player = m_World.FindClosestPlayer(Vector3f(a_BlockX + 0.5f, (float)a_BlockY, a_BlockZ + 0.5f), 0.5f, false);
+ cPlayer * a_Player = m_World.FindClosestPlayer(Vector3f(BlockX + 0.5f, (float)a_RelBlockY, BlockZ + 0.5f), 0.7f, false);
if (a_Player != NULL)
{
- m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0x1);
- SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_STONE_PRESSURE_PLATE);
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x1);
+ SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, a_MyType);
}
else
{
- m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0x0);
- m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0);
+ m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ);
}
break;
}
@@ -1056,95 +1147,98 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_Bloc
int m_Z;
};
- cPressurePlateCallback PressurePlateCallback(a_BlockX, a_BlockY, a_BlockZ);
+ cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ);
m_World.ForEachEntity(PressurePlateCallback);
unsigned char Power;
- NIBBLETYPE Meta = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
if (PressurePlateCallback.GetPowerLevel(Power))
{
if (Meta == E_META_PRESSURE_PLATE_RAISED)
{
- m_World.BroadcastSoundEffect("random.click", (int)((a_BlockX + 0.5) * 8.0), (int)((a_BlockY + 0.1) * 8.0), (int)((a_BlockZ + 0.5) * 8.0), 0.3F, 0.5F);
+ m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.5F);
}
- m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_DEPRESSED);
- SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, a_MyType, Power);
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_DEPRESSED);
+ SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Power);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, a_MyType);
}
else
{
if (Meta == E_META_PRESSURE_PLATE_DEPRESSED)
{
- m_World.BroadcastSoundEffect("random.click", (int)((a_BlockX + 0.5) * 8.0), (int)((a_BlockY + 0.1) * 8.0), (int)((a_BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
+ m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
}
- m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_RAISED);
- m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED);
+ m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ);
}
break;
}
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
- {class cPressurePlateCallback :
- public cEntityCallback
{
- public:
- cPressurePlateCallback(int a_BlockX, int a_BlockY, int a_BlockZ) :
- m_NumberOfEntities(0),
- m_X(a_BlockX),
- m_Y(a_BlockY),
- m_Z(a_BlockZ)
- {
- }
-
- virtual bool Item(cEntity * a_Entity) override
+ class cPressurePlateCallback :
+ public cEntityCallback
{
- Vector3f EntityPos = a_Entity->GetPosition();
- Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f);
- double Distance = (EntityPos - BlockPos).Length();
+ public:
+ cPressurePlateCallback(int a_BlockX, int a_BlockY, int a_BlockZ) :
+ m_NumberOfEntities(0),
+ m_X(a_BlockX),
+ m_Y(a_BlockY),
+ m_Z(a_BlockZ)
+ {
+ }
- if (Distance <= 0.7)
+ virtual bool Item(cEntity * a_Entity) override
{
- m_NumberOfEntities++;
+ Vector3f EntityPos = a_Entity->GetPosition();
+ Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f);
+ double Distance = (EntityPos - BlockPos).Length();
+
+ if (Distance <= 0.7)
+ {
+ m_NumberOfEntities++;
+ }
+ return false;
}
- return false;
- }
- bool GetPowerLevel(unsigned char & a_PowerLevel) const
- {
- a_PowerLevel = std::min((int)ceil(m_NumberOfEntities / (float)10), MAX_POWER_LEVEL);
- return (a_PowerLevel > 0);
- }
+ bool GetPowerLevel(unsigned char & a_PowerLevel) const
+ {
+ a_PowerLevel = std::min((int)ceil(m_NumberOfEntities / (float)10), MAX_POWER_LEVEL);
+ return (a_PowerLevel > 0);
+ }
- protected:
- int m_NumberOfEntities;
+ protected:
+ int m_NumberOfEntities;
- int m_X;
- int m_Y;
- int m_Z;
- };
+ int m_X;
+ int m_Y;
+ int m_Z;
+ };
- cPressurePlateCallback PressurePlateCallback(a_BlockX, a_BlockY, a_BlockZ);
- m_World.ForEachEntity(PressurePlateCallback);
+ cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ);
+ m_World.ForEachEntity(PressurePlateCallback);
- unsigned char Power;
- NIBBLETYPE Meta = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
- if (PressurePlateCallback.GetPowerLevel(Power))
- {
- if (Meta == E_META_PRESSURE_PLATE_RAISED)
+ unsigned char Power;
+ NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ if (PressurePlateCallback.GetPowerLevel(Power))
{
- m_World.BroadcastSoundEffect("random.click", (int)((a_BlockX + 0.5) * 8.0), (int)((a_BlockY + 0.1) * 8.0), (int)((a_BlockZ + 0.5) * 8.0), 0.3F, 0.5F);
+ if (Meta == E_META_PRESSURE_PLATE_RAISED)
+ {
+ m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.5F);
+ }
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_DEPRESSED);
+ SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Power);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, a_MyType);
}
- m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_DEPRESSED);
- SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, a_MyType, Power);
- }
- else
- {
- if (Meta == E_META_PRESSURE_PLATE_DEPRESSED)
+ else
{
- m_World.BroadcastSoundEffect("random.click", (int)((a_BlockX + 0.5) * 8.0), (int)((a_BlockY + 0.1) * 8.0), (int)((a_BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
+ if (Meta == E_META_PRESSURE_PLATE_DEPRESSED)
+ {
+ m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
+ }
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED);
+ m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ);
}
- m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_RAISED);
- m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
- }
break;
}
@@ -1189,27 +1283,28 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_Bloc
int m_Z;
} ;
- cPressurePlateCallback PressurePlateCallback(a_BlockX, a_BlockY, a_BlockZ);
+ cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ);
m_World.ForEachEntity(PressurePlateCallback);
- NIBBLETYPE Meta = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
+ NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
if (PressurePlateCallback.FoundEntity())
{
if (Meta == E_META_PRESSURE_PLATE_RAISED)
{
- m_World.BroadcastSoundEffect("random.click", (int) ((a_BlockX + 0.5) * 8.0), (int) ((a_BlockY + 0.1) * 8.0), (int) ((a_BlockZ + 0.5) * 8.0), 0.3F, 0.5F);
+ m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.5F);
}
- m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_DEPRESSED);
- SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, a_MyType);
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_DEPRESSED);
+ SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_YM, a_MyType);
}
else
{
if (Meta == E_META_PRESSURE_PLATE_DEPRESSED)
{
- m_World.BroadcastSoundEffect("random.click", (int) ((a_BlockX + 0.5) * 8.0), (int) ((a_BlockY + 0.1) * 8.0), (int) ((a_BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
+ m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F);
}
- m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, E_META_PRESSURE_PLATE_RAISED);
- m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED);
+ m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ);
}
break;
}
@@ -1225,11 +1320,15 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_Bloc
-bool cIncrementalRedstoneSimulator::AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ)
+bool cIncrementalRedstoneSimulator::AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
- for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr) // Check powered list
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+
+ PoweredBlocksList * Powered = m_Chunk->GetNeighborChunk(BlockX, BlockZ)->GetRedstoneSimulatorPoweredBlocksList(); // Torches want to access neighbour's data when on a wall
+ for (PoweredBlocksList::const_iterator itr = Powered->begin(); itr != Powered->end(); ++itr) // Check powered list
{
- if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
+ if (itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)))
{
return true;
}
@@ -1241,11 +1340,14 @@ bool cIncrementalRedstoneSimulator::AreCoordsDirectlyPowered(int a_BlockX, int a
-bool cIncrementalRedstoneSimulator::AreCoordsLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ)
+bool cIncrementalRedstoneSimulator::AreCoordsLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) // Check linked powered list
{
- if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
+ if (itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)))
{
return true;
}
@@ -1258,35 +1360,37 @@ bool cIncrementalRedstoneSimulator::AreCoordsLinkedPowered(int a_BlockX, int a_B
// IsRepeaterPowered tests if a repeater should be powered by testing for power sources behind the repeater.
// It takes the coordinates of the repeater the the meta value.
-bool cIncrementalRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta)
+bool cIncrementalRedstoneSimulator::IsRepeaterPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta)
{
// Repeaters cannot be powered by any face except their back; verify that this is true for a source
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr)
{
- if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
+ if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { continue; }
switch (a_Meta & 0x3)
{
case 0x0:
{
// Flip the coords to check the back of the repeater
- if (itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; }
+ if (itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ + 1))) { return true; }
break;
}
case 0x1:
{
- if (itr->a_SourcePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; }
+ if (itr->a_SourcePos.Equals(Vector3i(BlockX - 1, a_RelBlockY, BlockZ))) { return true; }
break;
}
case 0x2:
{
- if (itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; }
+ if (itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ - 1))) { return true; }
break;
}
case 0x3:
{
- if (itr->a_SourcePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; }
+ if (itr->a_SourcePos.Equals(Vector3i(BlockX + 1, a_RelBlockY, BlockZ))) { return true; }
break;
}
}
@@ -1294,28 +1398,28 @@ bool cIncrementalRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr)
{
- if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
+ if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { continue; }
switch (a_Meta & 0x3)
{
case 0x0:
{
- if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; }
+ if (itr->a_MiddlePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ + 1))) { return true; }
break;
}
case 0x1:
{
- if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; }
+ if (itr->a_MiddlePos.Equals(Vector3i(BlockX - 1, a_RelBlockY, BlockZ))) { return true; }
break;
}
case 0x2:
{
- if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; }
+ if (itr->a_MiddlePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ - 1))) { return true; }
break;
}
case 0x3:
{
- if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; }
+ if (itr->a_MiddlePos.Equals(Vector3i(BlockX + 1, a_RelBlockY, BlockZ))) { return true; }
break;
}
}
@@ -1327,7 +1431,7 @@ bool cIncrementalRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY
-bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta)
+bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta)
{
switch (a_Meta & 0x3) // We only want the 'direction' part of our metadata
{
@@ -1336,16 +1440,17 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_BlockX, int a_BlockY,
case 0x2:
{
// Check if eastern(right) neighbor is a powered on repeater who is facing us.
- if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) == E_BLOCK_REDSTONE_REPEATER_ON) // Is right neighbor a powered repeater?
+ BLOCKTYPE Block = 0;
+ if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) // Is right neighbor a powered repeater?
{
- NIBBLETYPE OtherRepeaterDir = m_World.GetBlockMeta(a_BlockX + 1, a_BlockY, a_BlockZ) & 0x3;
+ NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ) & 0x3;
if (OtherRepeaterDir == 0x3) { return true; } // If so, I am latched/locked.
}
// Check if western(left) neighbor is a powered on repeater who is facing us.
- if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) == E_BLOCK_REDSTONE_REPEATER_ON)
+ if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON))
{
- NIBBLETYPE OtherRepeaterDir = m_World.GetBlockMeta(a_BlockX -1, a_BlockY, a_BlockZ) & 0x3;
+ NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX -1, a_RelBlockY, a_RelBlockZ) & 0x3;
if (OtherRepeaterDir == 0x1) { return true; } // If so, I am latched/locked.
}
@@ -1357,16 +1462,17 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_BlockX, int a_BlockY,
case 0x3:
{
// Check if southern(down) neighbor is a powered on repeater who is facing us.
- if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) == E_BLOCK_REDSTONE_REPEATER_ON)
+ BLOCKTYPE Block = 0;
+ if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON))
{
- NIBBLETYPE OtherRepeaterDir = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ + 1) & 0x3;
+ NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1) & 0x3;
if (OtherRepeaterDir == 0x0) { return true; } // If so, am latched/locked.
}
// Check if northern(up) neighbor is a powered on repeater who is facing us.
- if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ -1) == E_BLOCK_REDSTONE_REPEATER_ON)
+ if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON))
{
- NIBBLETYPE OtherRepeaterDir = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ - 1) & 0x3;
+ NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1) & 0x3;
if (OtherRepeaterDir == 0x2) { return true; } // If so, I am latched/locked.
}
@@ -1380,43 +1486,45 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_BlockX, int a_BlockY,
-bool cIncrementalRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta)
+bool cIncrementalRedstoneSimulator::IsPistonPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta)
{
// Pistons cannot be powered through their front face; this function verifies that a source meets this requirement
- int OldX = a_BlockX, OldY = a_BlockY, OldZ = a_BlockZ;
+ int OldX = a_RelBlockX, OldY = a_RelBlockY, OldZ = a_RelBlockZ;
eBlockFace Face = cPiston::MetaDataToDirection(a_Meta);
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr)
{
- if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
+ if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { continue; }
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, Face);
+ AddFaceDirection(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Face);
- if (!itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
+ if (!itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)))
{
return true;
}
- a_BlockX = OldX;
- a_BlockY = OldY;
- a_BlockZ = OldZ;
+ a_RelBlockX = OldX;
+ a_RelBlockY = OldY;
+ a_RelBlockZ = OldZ;
}
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr)
{
- if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
+ if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { continue; }
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, Face);
+ AddFaceDirection(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Face);
- if (!itr->a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
+ if (!itr->a_MiddlePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)))
{
return true;
}
- a_BlockX = OldX;
- a_BlockY = OldY;
- a_BlockZ = OldZ;
+ a_RelBlockX = OldX;
+ a_RelBlockY = OldY;
+ a_RelBlockZ = OldZ;
}
return false; // Source was in front of the piston's front face
}
@@ -1424,13 +1532,15 @@ bool cIncrementalRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY,
-bool cIncrementalRedstoneSimulator::IsWirePowered(int a_BlockX, int a_BlockY, int a_BlockZ, unsigned char & a_PowerLevel)
+bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char & a_PowerLevel)
{
a_PowerLevel = 0;
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr) // Check powered list
{
- if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
+ if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)))
{
continue;
}
@@ -1439,7 +1549,7 @@ bool cIncrementalRedstoneSimulator::IsWirePowered(int a_BlockX, int a_BlockY, in
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) // Check linked powered list
{
- if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
+ if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)))
{
continue;
}
@@ -1453,11 +1563,11 @@ bool cIncrementalRedstoneSimulator::IsWirePowered(int a_BlockX, int a_BlockY, in
-bool cIncrementalRedstoneSimulator::AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered)
+bool cIncrementalRedstoneSimulator::AreCoordsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool IsCurrentStatePowered)
{
for (SimulatedPlayerToggleableList::const_iterator itr = m_SimulatedPlayerToggleableBlocks->begin(); itr != m_SimulatedPlayerToggleableBlocks->end(); ++itr)
{
- if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
+ if (itr->a_RelBlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ)))
{
if (itr->WasLastStatePowered != IsCurrentStatePowered) // Was the last power state different to the current?
{
@@ -1476,79 +1586,98 @@ bool cIncrementalRedstoneSimulator::AreCoordsSimulated(int a_BlockX, int a_Block
-void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceType, unsigned char a_PowerLevel)
+void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, char a_Direction, unsigned char a_PowerLevel)
{
+ BLOCKTYPE MiddleBlock = 0;
switch (a_Direction)
{
case BLOCK_FACE_XM:
{
- BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ);
+ if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, MiddleBlock))
+ {
+ return;
+ }
- SetBlockLinkedPowered(a_BlockX - 2, a_BlockY, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX - 2, a_RelBlockY, a_RelBlockZ, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
break;
}
case BLOCK_FACE_XP:
{
- BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ);
+ if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, MiddleBlock))
+ {
+ return;
+ }
- SetBlockLinkedPowered(a_BlockX + 2, a_BlockY, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX + 2, a_RelBlockY, a_RelBlockZ, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
break;
}
case BLOCK_FACE_YM:
{
- BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ);
+ if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, MiddleBlock))
+ {
+ return;
+ }
- SetBlockLinkedPowered(a_BlockX, a_BlockY - 2, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 2, a_RelBlockZ, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
break;
}
case BLOCK_FACE_YP:
{
- BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ);
+ if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, MiddleBlock))
+ {
+ return;
+ }
- SetBlockLinkedPowered(a_BlockX, a_BlockY + 2, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 2, a_RelBlockZ, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
break;
}
case BLOCK_FACE_ZM:
{
- BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1);
+ if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, MiddleBlock))
+ {
+ return;
+ }
- SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ - 2, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 2, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
break;
}
case BLOCK_FACE_ZP:
{
- BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1);
+ if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, MiddleBlock))
+ {
+ return;
+ }
- SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ + 2, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
- SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 2, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY + 1, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
+ SetBlockLinkedPowered(a_RelBlockX, a_RelBlockY - 1, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ, MiddleBlock, a_PowerLevel);
break;
}
@@ -1564,7 +1693,7 @@ void cIncrementalRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int
-void cIncrementalRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock, unsigned char a_PowerLevel)
+void cIncrementalRedstoneSimulator::SetAllDirsAsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char a_PowerLevel)
{
static const struct
{
@@ -1572,16 +1701,16 @@ void cIncrementalRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_Bloc
} gCrossCoords[] =
{
{ 1, 0, 0 },
- {-1, 0, 0 },
+ { -1, 0, 0 },
{ 0, 0, 1 },
- { 0, 0,-1 },
+ { 0, 0, -1 },
{ 0, 1, 0 },
- { 0,-1, 0 }
+ { 0, -1, 0 }
};
for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) // Loop through struct to power all directions
{
- SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, a_SourceBlock, a_PowerLevel);
+ SetBlockPowered(a_RelBlockX + gCrossCoords[i].x, a_RelBlockY + gCrossCoords[i].y, a_RelBlockZ + gCrossCoords[i].z, a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_PowerLevel);
}
}
@@ -1589,39 +1718,45 @@ void cIncrementalRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_Bloc
-void cIncrementalRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, unsigned char a_PowerLevel)
+void cIncrementalRedstoneSimulator::SetBlockPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, unsigned char a_PowerLevel)
{
- BLOCKTYPE Block = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ);
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+ int SourceX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelSourceX;
+ int SourceZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelSourceZ;
+
+ BLOCKTYPE Block = 0;
+ if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Block))
+ {
+ return;
+ }
if (Block == E_BLOCK_AIR)
{
// Don't set air, fixes some bugs (wires powering themselves)
return;
}
- PoweredBlocksList * Powered = m_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ)->GetRedstoneSimulatorPoweredBlocksList();
+ PoweredBlocksList * Powered = m_Chunk->GetNeighborChunk(BlockX, BlockZ)->GetRedstoneSimulatorPoweredBlocksList();
for (PoweredBlocksList::iterator itr = Powered->begin(); itr != Powered->end(); ++itr) // Check powered list
{
if (
- itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) &&
- itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))
- )
+ itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) &&
+ itr->a_SourcePos.Equals(Vector3i(SourceX, a_RelSourceY, SourceZ))
+ )
{
- // Check for duplicates, update power level if everything else the same but either way, don't add a new listing
- if (itr->a_PowerLevel != a_PowerLevel)
- {
- itr->a_PowerLevel = a_PowerLevel;
- }
+ // Check for duplicates, update power level, don't add a new listing
+ itr->a_PowerLevel = a_PowerLevel;
return;
}
}
- PoweredBlocksList * OtherPowered = m_Chunk->GetNeighborChunk(a_SourceX, a_SourceZ)->GetRedstoneSimulatorPoweredBlocksList();
+ PoweredBlocksList * OtherPowered = m_Chunk->GetNeighborChunk(SourceX, SourceZ)->GetRedstoneSimulatorPoweredBlocksList();
for (PoweredBlocksList::const_iterator itr = OtherPowered->begin(); itr != OtherPowered->end(); ++itr) // Check powered list
{
if (
- itr->a_BlockPos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ)) &&
- itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))
- )
+ itr->a_BlockPos.Equals(Vector3i(SourceX, a_RelSourceY, SourceZ)) &&
+ itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))
+ )
{
// Powered wires try to power their source - don't let them!
return;
@@ -1629,8 +1764,8 @@ void cIncrementalRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY,
}
sPoweredBlocks RC;
- RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
- RC.a_SourcePos = Vector3i(a_SourceX, a_SourceY, a_SourceZ);
+ RC.a_BlockPos = Vector3i(BlockX, a_RelBlockY, BlockZ);
+ RC.a_SourcePos = Vector3i(SourceX, a_RelSourceY, SourceZ);
RC.a_PowerLevel = a_PowerLevel;
Powered->push_back(RC);
}
@@ -1640,45 +1775,57 @@ void cIncrementalRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY,
void cIncrementalRedstoneSimulator::SetBlockLinkedPowered(
- int a_BlockX, int a_BlockY, int a_BlockZ,
- int a_MiddleX, int a_MiddleY, int a_MiddleZ,
- int a_SourceX, int a_SourceY, int a_SourceZ,
- BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddleBlock, unsigned char a_PowerLevel
-)
+ int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ,
+ int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ,
+ int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ,
+ BLOCKTYPE a_MiddleBlock, unsigned char a_PowerLevel
+ )
{
- BLOCKTYPE DestBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ);
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
+ int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+ int MiddleX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelMiddleX;
+ int MiddleZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelMiddleZ;
+ int SourceX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelSourceX;
+ int SourceZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelSourceZ;
+
+ BLOCKTYPE DestBlock = 0;
+ if (!m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ, DestBlock))
+ {
+ return;
+ }
if (DestBlock == E_BLOCK_AIR)
{
// Don't set air, fixes some bugs (wires powering themselves)
return;
}
+ if ((DestBlock == E_BLOCK_REDSTONE_WIRE) && (m_Chunk->GetBlock(a_RelSourceX, a_RelSourceY, a_RelSourceZ) == E_BLOCK_REDSTONE_WIRE))
+ {
+ return;
+ }
if (!IsViableMiddleBlock(a_MiddleBlock))
{
return;
}
- LinkedBlocksList * Linked = m_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ)->GetRedstoneSimulatorLinkedBlocksList();
+ LinkedBlocksList * Linked = m_Chunk->GetNeighborChunk(BlockX, BlockZ)->GetRedstoneSimulatorLinkedBlocksList();
for (LinkedBlocksList::iterator itr = Linked->begin(); itr != Linked->end(); ++itr) // Check linked powered list
{
if (
- itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) &&
- itr->a_MiddlePos.Equals(Vector3i(a_MiddleX, a_MiddleY, a_MiddleZ)) &&
- itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))
+ itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)) &&
+ itr->a_MiddlePos.Equals(Vector3i(MiddleX, a_RelMiddleY, MiddleZ)) &&
+ itr->a_SourcePos.Equals(Vector3i(SourceX, a_RelSourceY, SourceZ))
)
{
- // Check for duplicates, update power level if everything else the same but either way, don't add a new listing
- if (itr->a_PowerLevel != a_PowerLevel)
- {
- itr->a_PowerLevel = a_PowerLevel;
- }
+ // Check for duplicates, update power level, don't add a new listing
+ itr->a_PowerLevel = a_PowerLevel;
return;
}
}
sLinkedPoweredBlocks RC;
- RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
- RC.a_MiddlePos = Vector3i(a_MiddleX, a_MiddleY, a_MiddleZ);
- RC.a_SourcePos = Vector3i(a_SourceX, a_SourceY, a_SourceZ);
+ RC.a_BlockPos = Vector3i(BlockX, a_RelBlockY, BlockZ);
+ RC.a_MiddlePos = Vector3i(MiddleX, a_RelMiddleY, MiddleZ);
+ RC.a_SourcePos = Vector3i(SourceX, a_RelSourceY, SourceZ);
RC.a_PowerLevel = a_PowerLevel;
Linked->push_back(RC);
}
@@ -1687,11 +1834,11 @@ void cIncrementalRedstoneSimulator::SetBlockLinkedPowered(
-void cIncrementalRedstoneSimulator::SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool WasLastStatePowered)
+void cIncrementalRedstoneSimulator::SetPlayerToggleableBlockAsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool WasLastStatePowered)
{
for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks->begin(); itr != m_SimulatedPlayerToggleableBlocks->end(); ++itr)
{
- if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
+ if (!itr->a_RelBlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ)))
{
continue;
}
@@ -1711,7 +1858,7 @@ void cIncrementalRedstoneSimulator::SetPlayerToggleableBlockAsSimulated(int a_Bl
// We have arrive here; no block must be in list - add one
sSimulatedPlayerToggleableList RC;
- RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
+ RC.a_RelBlockPos = Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
RC.WasLastStatePowered = WasLastStatePowered;
m_SimulatedPlayerToggleableBlocks->push_back(RC);
}
@@ -1720,11 +1867,11 @@ void cIncrementalRedstoneSimulator::SetPlayerToggleableBlockAsSimulated(int a_Bl
-void cIncrementalRedstoneSimulator::QueueRepeaterPowerChange(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn)
+void cIncrementalRedstoneSimulator::QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn)
{
for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end(); ++itr)
{
- if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
+ if (itr->a_RelBlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ)))
{
if (ShouldPowerOn == itr->ShouldPowerOn) // We are queued already for the same thing, don't replace entry
{
@@ -1741,7 +1888,7 @@ void cIncrementalRedstoneSimulator::QueueRepeaterPowerChange(int a_BlockX, int a
// Self not in list, add self to list
sRepeatersDelayList RC;
- RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
+ RC.a_RelBlockPos = Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
// Gets the top two bits (delay time), shifts them into the lower two bits, and adds one (meta 0 = 1 tick; 1 = 2 etc.)
// * 2 because in MCS, 1 redstone tick = 1 world tick, but in Vanilla, 1 redstone tick = 2 world ticks, and we need to maintain compatibility
@@ -1757,52 +1904,64 @@ void cIncrementalRedstoneSimulator::QueueRepeaterPowerChange(int a_BlockX, int a
-cIncrementalRedstoneSimulator::eRedstoneDirection cIncrementalRedstoneSimulator::GetWireDirection(int a_BlockX, int a_BlockY, int a_BlockZ)
+cIncrementalRedstoneSimulator::eRedstoneDirection cIncrementalRedstoneSimulator::GetWireDirection(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
int Dir = REDSTONE_NONE;
- BLOCKTYPE NegX = m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ);
- if (IsPotentialSource(NegX))
+ BLOCKTYPE NegX = 0;
+ if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, NegX))
{
- Dir |= (REDSTONE_X_POS);
+ if (IsPotentialSource(NegX))
+ {
+ Dir |= (REDSTONE_X_POS);
+ }
}
- BLOCKTYPE PosX = m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ);
- if (IsPotentialSource(PosX))
+ BLOCKTYPE PosX = 0;
+ if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, PosX))
{
- Dir |= (REDSTONE_X_NEG);
+ if (IsPotentialSource(PosX))
+ {
+ Dir |= (REDSTONE_X_NEG);
+ }
}
- BLOCKTYPE NegZ = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1);
- if (IsPotentialSource(NegZ))
+ BLOCKTYPE NegZ = 0;
+ if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, NegZ))
{
- if ((Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG)) // corner
+ if (IsPotentialSource(NegZ))
{
- Dir ^= REDSTONE_X_POS;
- Dir |= REDSTONE_X_NEG;
- }
- if ((Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS)) // corner
- {
- Dir ^= REDSTONE_X_NEG;
- Dir |= REDSTONE_X_POS;
+ if ((Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG)) // corner
+ {
+ Dir ^= REDSTONE_X_POS;
+ Dir |= REDSTONE_X_NEG;
+ }
+ if ((Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS)) // corner
+ {
+ Dir ^= REDSTONE_X_NEG;
+ Dir |= REDSTONE_X_POS;
+ }
+ Dir |= REDSTONE_Z_POS;
}
- Dir |= REDSTONE_Z_POS;
}
- BLOCKTYPE PosZ = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1);
- if (IsPotentialSource(PosZ))
+ BLOCKTYPE PosZ = 0;
+ if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, PosZ))
{
- if ((Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG)) // corner
- {
- Dir ^= REDSTONE_X_POS;
- Dir |= REDSTONE_X_NEG;
- }
- if ((Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS)) // corner
+ if (IsPotentialSource(PosZ))
{
- Dir ^= REDSTONE_X_NEG;
- Dir |= REDSTONE_X_POS;
+ if ((Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG)) // corner
+ {
+ Dir ^= REDSTONE_X_POS;
+ Dir |= REDSTONE_X_NEG;
+ }
+ if ((Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS)) // corner
+ {
+ Dir ^= REDSTONE_X_NEG;
+ Dir |= REDSTONE_X_POS;
+ }
+ Dir |= REDSTONE_Z_NEG;
}
- Dir |= REDSTONE_Z_NEG;
}
return (eRedstoneDirection)Dir;
}
diff --git a/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h
index a42cce79a..233a3d408 100644
--- a/src/Simulator/IncrementalRedstoneSimulator.h
+++ b/src/Simulator/IncrementalRedstoneSimulator.h
@@ -55,13 +55,13 @@ private:
struct sSimulatedPlayerToggleableList // Define structure of the list containing simulate-on-update blocks (such as trapdoors that respond once to a block update, and can be toggled by a player)
{
- Vector3i a_BlockPos;
+ Vector3i a_RelBlockPos;
bool WasLastStatePowered; // Was the last state powered or not? Determines whether a source update has happened and if I should resimulate
};
struct sRepeatersDelayList // Define structure of list containing repeaters' delay states
{
- Vector3i a_BlockPos;
+ Vector3i a_RelBlockPos;
unsigned char a_DelayTicks; // For how many ticks should the repeater delay
unsigned char a_ElapsedTicks; // How much of the previous has been elapsed?
bool ShouldPowerOn; // What happens when the delay time is fulfilled?
@@ -91,80 +91,80 @@ private:
/* ====== SOURCES ====== */
/** Handles the redstone torch */
- void HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
+ void HandleRedstoneTorch(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
/** Handles the redstone block */
- void HandleRedstoneBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
+ void HandleRedstoneBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles levers */
- void HandleRedstoneLever(int a_BlockX, int a_BlockY, int a_BlockZ);
+ void HandleRedstoneLever(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles buttons */
- void HandleRedstoneButton(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType);
+ void HandleRedstoneButton(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles daylight sensors */
- void HandleDaylightSensor(int a_BlockX, int a_BlockY, int a_BlockZ);
+ void HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles pressure plates */
- void HandlePressurePlate(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
+ void HandlePressurePlate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType);
/* ==================== */
/* ====== CARRIERS ====== */
/** Handles redstone wire */
- void HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_BlockZ);
+ void HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles repeaters */
- void HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
+ void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
/* ====================== */
/* ====== DEVICES ====== */
/** Handles pistons */
- void HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ);
+ void HandlePiston(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles dispensers and droppers */
- void HandleDropSpenser(int a_BlockX, int a_BlockY, int a_BlockZ);
+ void HandleDropSpenser(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles TNT (exploding) */
- void HandleTNT(int a_BlockX, int a_BlockY, int a_BlockZ);
+ void HandleTNT(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles redstone lamps */
- void HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
+ void HandleRedstoneLamp(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
/** Handles doords */
- void HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ);
+ void HandleDoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles command blocks */
- void HandleCommandBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
+ void HandleCommandBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles activator, detector, and powered rails */
- void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
+ void HandleRail(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType);
/** Handles trapdoors */
- void HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ);
+ void HandleTrapdoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles fence gates */
- void HandleFenceGate(int a_BlockX, int a_BlockY, int a_BlockZ);
+ void HandleFenceGate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles noteblocks */
- void HandleNoteBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
+ void HandleNoteBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/* ===================== */
/* ====== Helper functions ====== */
/** Marks a block as powered */
- void SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
+ void SetBlockPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
/** Marks a block as being powered through another block */
- void SetBlockLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_MiddleX, int a_MiddleY, int a_MiddleZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddeBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
+ void SetBlockLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, BLOCKTYPE a_MiddeBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
/** Marks a block as simulated, who should not be simulated further unless their power state changes, to accomodate a player manually toggling the block without triggering the simulator toggling it back */
- void SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool WasLastStatePowered);
+ void SetPlayerToggleableBlockAsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool WasLastStatePowered);
/** Marks the second block in a direction as linked powered */
- void SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
+ void SetDirectionLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, char a_Direction, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
/** Marks all blocks immediately surrounding a coordinate as powered */
- void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
+ void SetAllDirsAsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
/** Queues a repeater to be powered or unpowered */
- void QueueRepeaterPowerChange(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn);
+ void QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn);
/** Returns if a coordinate is powered or linked powered */
- bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ) { return AreCoordsDirectlyPowered(a_BlockX, a_BlockY, a_BlockZ) || AreCoordsLinkedPowered(a_BlockX, a_BlockY, a_BlockZ); }
+ bool AreCoordsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { return AreCoordsDirectlyPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ) || AreCoordsLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); }
/** Returns if a coordinate is in the directly powered blocks list */
- bool AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
+ bool AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Returns if a coordinate is in the indirectly powered blocks list */
- bool AreCoordsLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
+ bool AreCoordsLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */
- bool AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered);
+ bool AreCoordsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool IsCurrentStatePowered);
/** Returns if a repeater is powered */
- bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
+ bool IsRepeaterPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta);
/** Returns if a repeater is locked */
- bool IsRepeaterLocked(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
+ bool IsRepeaterLocked(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta);
/** Returns if a piston is powered */
- bool IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
+ bool IsPistonPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta);
/** Returns if a wire is powered
The only diffence between this and a normal AreCoordsPowered is that this function checks for a wire powering another wire */
- bool IsWirePowered(int a_BlockX, int a_BlockY, int a_BlockZ, unsigned char & a_PowerLevel);
+ bool IsWirePowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char & a_PowerLevel);
/** Returns if lever metadata marks it as emitting power */
diff --git a/src/Simulator/SandSimulator.cpp b/src/Simulator/SandSimulator.cpp
index f305ba61a..b8f34559f 100644
--- a/src/Simulator/SandSimulator.cpp
+++ b/src/Simulator/SandSimulator.cpp
@@ -64,7 +64,7 @@ void cSandSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChun
a_Chunk->SetBlock(itr->x, itr->y, itr->z, E_BLOCK_AIR, 0);
}
}
- m_TotalBlocks -= ChunkData.size();
+ m_TotalBlocks -= (int)ChunkData.size();
ChunkData.clear();
}
@@ -254,6 +254,10 @@ void cSandSimulator::FinishFalling(
{
// Rematerialize the material here:
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_FallingBlockType, a_FallingBlockMeta);
+ if (a_FallingBlockType == E_BLOCK_ANVIL)
+ {
+ a_World->BroadcastSoundParticleEffect(1022, a_BlockX, a_BlockY, a_BlockZ, 0);
+ }
return;
}
diff --git a/src/Simulator/VanillaFluidSimulator.cpp b/src/Simulator/VanillaFluidSimulator.cpp
index 78aff9d68..18d9b07e1 100644
--- a/src/Simulator/VanillaFluidSimulator.cpp
+++ b/src/Simulator/VanillaFluidSimulator.cpp
@@ -35,14 +35,16 @@ cVanillaFluidSimulator::cVanillaFluidSimulator(
-void cVanillaFluidSimulator::Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta)
+void cVanillaFluidSimulator::SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta)
{
+ // Calculate the distance to the nearest "hole" in each direction:
int Cost[4];
Cost[0] = CalculateFlowCost(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, X_PLUS);
Cost[1] = CalculateFlowCost(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, X_MINUS);
Cost[2] = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, Z_PLUS);
Cost[3] = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, Z_MINUS);
+ // Find the minimum distance:
int MinCost = InfiniteCost;
for (unsigned int i = 0; i < ARRAYCOUNT(Cost); ++i)
{
@@ -52,6 +54,7 @@ void cVanillaFluidSimulator::Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, in
}
}
+ // Spread in all directions where the distance matches the minimum:
if (Cost[0] == MinCost)
{
SpreadToNeighbor(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, a_NewMeta);
@@ -86,7 +89,10 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int
{
return Cost;
}
- if (!IsPassableForFluid(BlockType) && !IsBlockLiquid(BlockType))
+ if (
+ !IsPassableForFluid(BlockType) || // The block cannot be passed by the liquid ...
+ (IsAllowedBlock(BlockType) && (BlockMeta == 0)) // ... or if it is liquid, it is a source block
+ )
{
return Cost;
}
diff --git a/src/Simulator/VanillaFluidSimulator.h b/src/Simulator/VanillaFluidSimulator.h
index a9ea98b5a..89a56ca14 100644
--- a/src/Simulator/VanillaFluidSimulator.h
+++ b/src/Simulator/VanillaFluidSimulator.h
@@ -30,7 +30,7 @@ public:
protected:
// cFloodyFluidSimulator overrides:
- virtual void Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) override;
+ virtual void SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) override;
/** Recursively calculates the minimum number of blocks needed to descend a level. */
int CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, Direction a_Dir, unsigned a_Iteration = 0);
diff --git a/src/StringCompression.cpp b/src/StringCompression.cpp
index 2a85649a1..71d64e71e 100644
--- a/src/StringCompression.cpp
+++ b/src/StringCompression.cpp
@@ -11,15 +11,15 @@
/// Compresses a_Data into a_Compressed; returns Z_XXX error constants same as zlib's compress2()
-int CompressString(const char * a_Data, int a_Length, AString & a_Compressed, int a_Factor)
+int CompressString(const char * a_Data, size_t a_Length, AString & a_Compressed, int a_Factor)
{
- uLongf CompressedSize = compressBound(a_Length);
+ uLongf CompressedSize = compressBound((uLong)a_Length);
// HACK: We're assuming that AString returns its internal buffer in its data() call and we're overwriting that buffer!
// It saves us one allocation and one memcpy of the entire compressed data
// It may not work on some STL implementations! (Confirmed working on MSVC 2008 & 2010)
a_Compressed.resize(CompressedSize);
- int errorcode = compress2( (Bytef*)a_Compressed.data(), &CompressedSize, (const Bytef*)a_Data, a_Length, a_Factor);
+ int errorcode = compress2((Bytef*)a_Compressed.data(), &CompressedSize, (const Bytef *)a_Data, (uLong)a_Length, a_Factor);
if (errorcode != Z_OK)
{
return errorcode;
@@ -33,14 +33,14 @@ int CompressString(const char * a_Data, int a_Length, AString & a_Compressed, in
/// Uncompresses a_Data into a_Decompressed; returns Z_XXX error constants same as zlib's uncompress()
-int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed, int a_UncompressedSize)
+int UncompressString(const char * a_Data, size_t a_Length, AString & a_Uncompressed, size_t a_UncompressedSize)
{
// HACK: We're assuming that AString returns its internal buffer in its data() call and we're overwriting that buffer!
// It saves us one allocation and one memcpy of the entire compressed data
// It may not work on some STL implementations! (Confirmed working on MSVC 2008 & 2010)
a_Uncompressed.resize(a_UncompressedSize);
uLongf UncompressedSize = (uLongf)a_UncompressedSize; // On some architectures the uLongf is different in size to int, that may be the cause of the -5 error
- int errorcode = uncompress((Bytef*)a_Uncompressed.data(), &UncompressedSize, (const Bytef*)a_Data, a_Length);
+ int errorcode = uncompress((Bytef*)a_Uncompressed.data(), &UncompressedSize, (const Bytef*)a_Data, (uLong)a_Length);
if (errorcode != Z_OK)
{
return errorcode;
@@ -63,7 +63,7 @@ int CompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Compres
z_stream strm;
memset(&strm, 0, sizeof(strm));
strm.next_in = (Bytef *)a_Data;
- strm.avail_in = a_Length;
+ strm.avail_in = (uInt)a_Length;
strm.next_out = (Bytef *)Buffer;
strm.avail_out = sizeof(Buffer);
@@ -127,7 +127,7 @@ extern int UncompressStringGZIP(const char * a_Data, size_t a_Length, AString &
z_stream strm;
memset(&strm, 0, sizeof(strm));
strm.next_in = (Bytef *)a_Data;
- strm.avail_in = a_Length;
+ strm.avail_in = (uInt)a_Length;
strm.next_out = (Bytef *)Buffer;
strm.avail_out = sizeof(Buffer);
diff --git a/src/StringCompression.h b/src/StringCompression.h
index c3a9eca91..038240797 100644
--- a/src/StringCompression.h
+++ b/src/StringCompression.h
@@ -10,10 +10,10 @@
/// Compresses a_Data into a_Compressed using ZLIB; returns Z_XXX error constants same as zlib's compress2()
-extern int CompressString(const char * a_Data, int a_Length, AString & a_Compressed, int a_Factor);
+extern int CompressString(const char * a_Data, size_t a_Length, AString & a_Compressed, int a_Factor);
/// Uncompresses a_Data into a_Uncompressed; returns Z_XXX error constants same as zlib's decompress()
-extern int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed, int a_UncompressedSize);
+extern int UncompressString(const char * a_Data, size_t a_Length, AString & a_Uncompressed, size_t a_UncompressedSize);
/// Compresses a_Data into a_Compressed using GZIP; returns Z_OK for success or Z_XXX error constants same as zlib
extern int CompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Compressed);
diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp
index 33b04505f..7488a3073 100644
--- a/src/StringUtils.cpp
+++ b/src/StringUtils.cpp
@@ -247,18 +247,22 @@ int NoCaseCompare(const AString & s1, const AString & s2)
-unsigned int RateCompareString(const AString & s1, const AString & s2 )
+size_t RateCompareString(const AString & s1, const AString & s2)
{
- unsigned int MatchedLetters = 0;
- unsigned int s1Length = s1.length();
+ size_t MatchedLetters = 0;
+ size_t s1Length = s1.length();
- if( s1Length > s2.length() ) return 0; // Definitely not a match
+ if (s1Length > s2.length())
+ {
+ // Definitely not a match
+ return 0;
+ }
- for (unsigned int i = 0; i < s1Length; i++)
+ for (size_t i = 0; i < s1Length; i++)
{
- char c1 = (char)toupper( s1[i] );
- char c2 = (char)toupper( s2[i] );
- if( c1 == c2 )
+ char c1 = (char)toupper(s1[i]);
+ char c2 = (char)toupper(s2[i]);
+ if (c1 == c2)
{
++MatchedLetters;
}
@@ -288,11 +292,11 @@ void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString &
// Converts a stream of BE shorts into UTF-8 string; returns a ref to a_UTF8
-AString & RawBEToUTF8(const char * a_RawData, int a_NumShorts, AString & a_UTF8)
+AString & RawBEToUTF8(const char * a_RawData, size_t a_NumShorts, AString & a_UTF8)
{
a_UTF8.clear();
a_UTF8.reserve(3 * a_NumShorts / 2); // a quick guess of the resulting size
- for (int i = 0; i < a_NumShorts; i++)
+ for (size_t i = 0; i < a_NumShorts; i++)
{
int c = GetBEShort(&a_RawData[i * 2]);
if (c < 0x80)
diff --git a/src/StringUtils.h b/src/StringUtils.h
index b69e47d3c..caad85aef 100644
--- a/src/StringUtils.h
+++ b/src/StringUtils.h
@@ -52,13 +52,13 @@ extern AString & StrToLower(AString & s);
extern int NoCaseCompare(const AString & s1, const AString & s2); // tolua_export
/// Case-insensitive string comparison that returns a rating of equal-ness between [0 - s1.length()]
-extern unsigned int RateCompareString(const AString & s1, const AString & s2 );
+extern size_t RateCompareString(const AString & s1, const AString & s2);
/// Replaces *each* occurence of iNeedle in iHayStack with iReplaceWith
extern void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & iReplaceWith); // tolua_export
/// Converts a stream of BE shorts into UTF-8 string; returns a ref to a_UTF8
-extern AString & RawBEToUTF8(const char * a_RawData, int a_NumShorts, AString & a_UTF8);
+extern AString & RawBEToUTF8(const char * a_RawData, size_t a_NumShorts, AString & a_UTF8);
/// Converts a UTF-8 string into a UTF-16 BE string, packing that back into AString; return a ref to a_UTF16
extern AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a_UTF16);
diff --git a/src/Tracer.cpp b/src/Tracer.cpp
index 6da6b2ad7..be42430a5 100644
--- a/src/Tracer.cpp
+++ b/src/Tracer.cpp
@@ -219,6 +219,10 @@ bool cTracer::Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int
return false;
}
+ if ((pos.y < 0) || (pos.y >= cChunkDef::Height))
+ {
+ return false;
+ }
BLOCKTYPE BlockID = m_World->GetBlock(pos.x, pos.y, pos.z);
// Block is counted as a collision if we are not doing a line of sight and it is solid,
// or if the block is not air and not water. That way mobs can still see underwater.
@@ -226,7 +230,7 @@ bool cTracer::Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int
{
BlockHitPosition = pos;
int Normal = GetHitNormal(a_Start, End, pos );
- if(Normal > 0)
+ if (Normal > 0)
{
HitNormal = m_NormalTable[Normal-1];
}
diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp
index 87b4032e0..788974f9c 100644
--- a/src/UI/SlotArea.cpp
+++ b/src/UI/SlotArea.cpp
@@ -244,7 +244,7 @@ void cSlotArea::OnPlayerRemoved(cPlayer & a_Player)
-void cSlotArea::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_Apply, bool a_KeepEmptySlots)
+void cSlotArea::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots)
{
for (int i = 0; i < m_NumSlots; i++)
{
@@ -264,7 +264,7 @@ void cSlotArea::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_
{
NumFit = a_ItemStack.m_ItemCount;
}
- if (a_Apply)
+ if (a_ShouldApply)
{
cItem NewSlot(a_ItemStack);
NewSlot.m_ItemCount = Slot->m_ItemCount + NumFit;
@@ -596,6 +596,409 @@ cCraftingRecipe & cSlotAreaCrafting::GetRecipeForPlayer(cPlayer & a_Player)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cSlotAreaAnvil:
+
+cSlotAreaAnvil::cSlotAreaAnvil(cAnvilWindow & a_ParentWindow) :
+ cSlotAreaTemporary(3, a_ParentWindow),
+ m_MaximumCost(0)
+{
+}
+
+
+
+
+
+void cSlotAreaAnvil::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem)
+{
+ ASSERT((a_SlotNum >= 0) && (a_SlotNum < GetNumSlots()));
+ if (a_SlotNum != 2)
+ {
+ super::Clicked(a_Player, a_SlotNum, a_ClickAction, a_ClickedItem);
+ UpdateResult(a_Player);
+ return;
+ }
+
+ bool bAsync = false;
+ if (GetSlot(a_SlotNum, a_Player) == NULL)
+ {
+ LOGWARNING("GetSlot(%d) returned NULL! Ignoring click", a_SlotNum);
+ return;
+ }
+
+ if (a_ClickAction == caDblClick)
+ {
+ return;
+ }
+
+ if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick))
+ {
+ ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
+ return;
+ }
+
+ cItem Slot(*GetSlot(a_SlotNum, a_Player));
+ if (!Slot.IsSameType(a_ClickedItem))
+ {
+ LOGWARNING("*** Window lost sync at item %d in SlotArea with %d items ***", a_SlotNum, m_NumSlots);
+ LOGWARNING("My item: %s", ItemToFullString(Slot).c_str());
+ LOGWARNING("Their item: %s", ItemToFullString(a_ClickedItem).c_str());
+ bAsync = true;
+ }
+ cItem & DraggingItem = a_Player.GetDraggingItem();
+
+ if (Slot.IsEmpty())
+ {
+ return;
+ }
+ if (!DraggingItem.IsEmpty())
+ {
+ if (!(DraggingItem.IsEqual(Slot) && ((DraggingItem.m_ItemCount + Slot.m_ItemCount) <= cItemHandler::GetItemHandler(Slot)->GetMaxStackSize())))
+ {
+ return;
+ }
+ }
+
+ if (!CanTakeResultItem(a_Player))
+ {
+ return;
+ }
+
+ cItem NewItem = cItem(Slot);
+ NewItem.m_ItemCount += DraggingItem.m_ItemCount;
+
+ Slot.Empty();
+ DraggingItem.Empty();
+ SetSlot(a_SlotNum, a_Player, Slot);
+
+ DraggingItem = NewItem;
+ OnTakeResult(a_Player);
+
+ if (bAsync)
+ {
+ m_ParentWindow.BroadcastWholeWindow();
+ }
+}
+
+
+
+
+
+void cSlotAreaAnvil::ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem & a_ClickedItem)
+{
+ if (a_SlotNum != 2)
+ {
+ super::ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
+ UpdateResult(a_Player);
+ return;
+ }
+
+ // Make a copy of the slot, distribute it among the other areas, then update the slot to contain the leftover:
+ cItem Slot(*GetSlot(a_SlotNum, a_Player));
+
+ if (Slot.IsEmpty() || !CanTakeResultItem(a_Player))
+ {
+ return;
+ }
+
+ m_ParentWindow.DistributeStack(Slot, a_Player, this, true);
+ if (Slot.IsEmpty())
+ {
+ Slot.Empty();
+ OnTakeResult(a_Player);
+ }
+ SetSlot(a_SlotNum, a_Player, Slot);
+
+ // Some clients try to guess our actions and not always right (armor slots in 1.2.5), so we fix them:
+ m_ParentWindow.BroadcastWholeWindow();
+}
+
+
+
+
+
+void cSlotAreaAnvil::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots)
+{
+ for (int i = 0; i < 2; i++)
+ {
+ const cItem * Slot = GetSlot(i, a_Player);
+ if (!Slot->IsEqual(a_ItemStack) && (!Slot->IsEmpty() || a_KeepEmptySlots))
+ {
+ // Different items
+ continue;
+ }
+ int NumFit = ItemHandler(Slot->m_ItemType)->GetMaxStackSize() - Slot->m_ItemCount;
+ if (NumFit <= 0)
+ {
+ // Full stack already
+ continue;
+ }
+ if (NumFit > a_ItemStack.m_ItemCount)
+ {
+ NumFit = a_ItemStack.m_ItemCount;
+ }
+ if (a_ShouldApply)
+ {
+ cItem NewSlot(a_ItemStack);
+ NewSlot.m_ItemCount = Slot->m_ItemCount + NumFit;
+ SetSlot(i, a_Player, NewSlot);
+ }
+ a_ItemStack.m_ItemCount -= NumFit;
+ if (a_ItemStack.IsEmpty())
+ {
+ UpdateResult(a_Player);
+ return;
+ }
+ } // for i - Slots
+ UpdateResult(a_Player);
+}
+
+
+
+
+
+void cSlotAreaAnvil::OnTakeResult(cPlayer & a_Player)
+{
+ if (!a_Player.IsGameModeCreative())
+ {
+ a_Player.DeltaExperience(cPlayer::XpForLevel(m_MaximumCost));
+ }
+ SetSlot(0, a_Player, cItem());
+
+ if (m_StackSizeToBeUsedInRepair > 0)
+ {
+ const cItem * Item = GetSlot(1, a_Player);
+ if (!Item->IsEmpty() && (Item->m_ItemCount > m_StackSizeToBeUsedInRepair))
+ {
+ cItem NewSecondItem(*Item);
+ NewSecondItem.m_ItemCount -= m_StackSizeToBeUsedInRepair;
+ SetSlot(1, a_Player, NewSecondItem);
+ }
+ else
+ {
+ SetSlot(1, a_Player, cItem());
+ }
+ }
+ else
+ {
+ SetSlot(1, a_Player, cItem());
+ }
+ m_ParentWindow.SetProperty(0, m_MaximumCost, a_Player);
+
+ m_MaximumCost = 0;
+ ((cAnvilWindow*)&m_ParentWindow)->SetRepairedItemName("", NULL);
+
+ int PosX, PosY, PosZ;
+ ((cAnvilWindow*)&m_ParentWindow)->GetBlockPos(PosX, PosY, PosZ);
+
+ BLOCKTYPE Block;
+ NIBBLETYPE BlockMeta;
+ a_Player.GetWorld()->GetBlockTypeMeta(PosX, PosY, PosZ, Block, BlockMeta);
+
+ cFastRandom Random;
+ if (!a_Player.IsGameModeCreative() && (Block == E_BLOCK_ANVIL) && (Random.NextFloat(1.0F) < 0.12F))
+ {
+ NIBBLETYPE Orientation = BlockMeta & 0x3;
+ NIBBLETYPE AnvilDamage = BlockMeta >> 2;
+ ++AnvilDamage;
+
+ if (AnvilDamage > 2)
+ {
+ // Anvil will break
+ a_Player.GetWorld()->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, (NIBBLETYPE)0);
+ a_Player.GetWorld()->BroadcastSoundParticleEffect(1020, PosX, PosY, PosZ, 0);
+ a_Player.CloseWindow(false);
+ }
+ else
+ {
+ a_Player.GetWorld()->SetBlockMeta(PosX, PosY, PosZ, Orientation | (AnvilDamage << 2));
+ a_Player.GetWorld()->BroadcastSoundParticleEffect(1021, PosX, PosY, PosZ, 0);
+ }
+ }
+ else
+ {
+ a_Player.GetWorld()->BroadcastSoundParticleEffect(1021, PosX, PosY, PosZ, 0);
+ }
+}
+
+
+
+
+
+bool cSlotAreaAnvil::CanTakeResultItem(cPlayer & a_Player)
+{
+ return (
+ (
+ a_Player.IsGameModeCreative() || // Is the player in gamemode?
+ (a_Player.GetXpLevel() >= m_MaximumCost) // or the player have enough exp?
+ ) &&
+ (!GetSlot(2, a_Player)->IsEmpty()) && // Is a item in the result slot?
+ (m_MaximumCost > 0) // When no maximum cost is set, the item isn't set from the UpdateResult() method and can't be a valid enchanting result.
+ );
+}
+
+
+
+
+
+void cSlotAreaAnvil::OnPlayerRemoved(cPlayer & a_Player)
+{
+ TossItems(a_Player, 0, 2);
+ super::OnPlayerRemoved(a_Player);
+}
+
+
+
+
+
+void cSlotAreaAnvil::UpdateResult(cPlayer & a_Player)
+{
+ cItem Input(*GetSlot(0, a_Player));
+ cItem SecondInput(*GetSlot(1, a_Player));
+ cItem Output(*GetSlot(2, a_Player));
+
+ if (Input.IsEmpty() && !Output.IsEmpty())
+ {
+ Output.Empty();
+ SetSlot(2, a_Player, Output);
+ m_ParentWindow.SetProperty(0, 0, a_Player);
+ return;
+ }
+
+ m_MaximumCost = 0;
+ m_StackSizeToBeUsedInRepair = 0;
+ int RepairCost = Input.m_RepairCost;
+ int NeedExp = 0;
+ bool IsEnchantBook = false;
+ if (!SecondInput.IsEmpty())
+ {
+ IsEnchantBook = (SecondInput.m_ItemType == E_ITEM_ENCHANTED_BOOK);
+
+ RepairCost += SecondInput.m_RepairCost;
+ if (Input.IsDamageable() && cItemHandler::GetItemHandler(Input)->CanRepairWithRawMaterial(SecondInput.m_ItemType))
+ {
+ // Tool and armor repair with special item (iron / gold / diamond / ...)
+ int DamageDiff = std::min((int)Input.m_ItemDamage, (int)Input.GetMaxDamage() / 4);
+ if (DamageDiff <= 0)
+ {
+ // No enchantment
+ Output.Empty();
+ SetSlot(2, a_Player, Output);
+ m_ParentWindow.SetProperty(0, 0, a_Player);
+ return;
+ }
+
+ int x = 0;
+ while ((DamageDiff > 0) && (x < SecondInput.m_ItemCount))
+ {
+ Input.m_ItemDamage -= DamageDiff;
+ NeedExp += std::max(1, DamageDiff / 100) + (int)Input.m_Enchantments.Count();
+ DamageDiff = std::min((int)Input.m_ItemDamage, (int)Input.GetMaxDamage() / 4);
+
+ ++x;
+ }
+ m_StackSizeToBeUsedInRepair = x;
+ }
+ else
+ {
+ // Tool and armor repair with two tools / armors
+ if (!IsEnchantBook && (!Input.IsSameType(SecondInput) || !Input.IsDamageable()))
+ {
+ // No enchantment
+ Output.Empty();
+ SetSlot(2, a_Player, Output);
+ m_ParentWindow.SetProperty(0, 0, a_Player);
+ return;
+ }
+
+ if ((Input.GetMaxDamage() > 0) && !IsEnchantBook)
+ {
+ int FirstDamageDiff = Input.GetMaxDamage() - Input.m_ItemDamage;
+ int SecondDamageDiff = SecondInput.GetMaxDamage() - SecondInput.m_ItemDamage;
+ int Damage = SecondDamageDiff + Input.GetMaxDamage() * 12 / 100;
+
+ int NewItemDamage = Input.GetMaxDamage() - (FirstDamageDiff + Damage);
+ if (NewItemDamage > 0)
+ {
+ NewItemDamage = 0;
+ }
+
+ if (NewItemDamage < Input.m_ItemDamage)
+ {
+ Input.m_ItemDamage = NewItemDamage;
+ NeedExp += std::max(1, Damage / 100);
+ }
+ }
+
+ // TODO: Add enchantments.
+ }
+ }
+
+ int NameChangeExp = 0;
+ const AString & RepairedItemName = ((cAnvilWindow*)&m_ParentWindow)->GetRepairedItemName();
+ if (RepairedItemName.empty())
+ {
+ // Remove custom name
+ if (!Input.m_CustomName.empty())
+ {
+ NameChangeExp = (Input.IsDamageable()) ? 7 : (Input.m_ItemCount * 5);
+ NeedExp += NameChangeExp;
+ Input.m_CustomName = "";
+ }
+ }
+ else if (RepairedItemName != Input.m_CustomName)
+ {
+ // Change custom name
+ NameChangeExp = (Input.IsDamageable()) ? 7 : (Input.m_ItemCount * 5);
+ NeedExp += NameChangeExp;
+
+ if (!Input.m_CustomName.empty())
+ {
+ RepairCost += NameChangeExp / 2;
+ }
+
+ Input.m_CustomName = RepairedItemName;
+ }
+
+ // TODO: Add enchantment exp cost.
+
+ m_MaximumCost = RepairCost + NeedExp;
+
+ if (NeedExp < 0)
+ {
+ Input.Empty();
+ }
+
+ if ((NameChangeExp == NeedExp) && (NameChangeExp > 0) && (m_MaximumCost >= 40))
+ {
+ m_MaximumCost = 39;
+ }
+ if (m_MaximumCost >= 40 && !a_Player.IsGameModeCreative())
+ {
+ Input.Empty();
+ }
+
+ if (!Input.IsEmpty())
+ {
+ RepairCost = std::max(Input.m_RepairCost, SecondInput.m_RepairCost);
+ if (!Input.m_CustomName.empty())
+ {
+ RepairCost -= 9;
+ }
+ RepairCost = std::max(RepairCost, 0);
+ RepairCost += 2;
+ Input.m_RepairCost = RepairCost;
+ }
+
+ SetSlot(2, a_Player, Input);
+ m_ParentWindow.SetProperty(0, m_MaximumCost, a_Player);
+}
+
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cSlotAreaEnchanting:
cSlotAreaEnchanting::cSlotAreaEnchanting(cEnchantingWindow & a_ParentWindow) :
diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h
index 254722822..4da6a672f 100644
--- a/src/UI/SlotArea.h
+++ b/src/UI/SlotArea.h
@@ -9,6 +9,7 @@
#pragma once
#include "../Inventory.h"
+#include "Window.h"
@@ -259,6 +260,43 @@ protected:
+class cSlotAreaAnvil :
+ public cSlotAreaTemporary
+{
+ typedef cSlotAreaTemporary super;
+
+public:
+ cSlotAreaAnvil(cAnvilWindow & a_ParentWindow);
+
+ // cSlotArea overrides:
+ virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
+ virtual void ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem & a_ClickedItem) override;
+ virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) override;
+
+ // cSlotAreaTemporary overrides:
+ virtual void OnPlayerRemoved(cPlayer & a_Player) override;
+
+ /** Can the player take the item from the slot? */
+ bool CanTakeResultItem(cPlayer & a_Player);
+
+ /** This function will call, when the player take the item from the slot. */
+ void OnTakeResult(cPlayer & a_Player);
+
+ /** Handles a click in the item slot. */
+ void UpdateResult(cPlayer & a_Player);
+
+protected:
+ /** The maximum cost of repairing/renaming in the anvil. */
+ int m_MaximumCost;
+
+ /** The stack size of the second item where was used for repair */
+ char m_StackSizeToBeUsedInRepair;
+} ;
+
+
+
+
+
class cSlotAreaEnchanting :
public cSlotAreaTemporary
{
diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp
index 0a78578fc..46885390b 100644
--- a/src/UI/Window.cpp
+++ b/src/UI/Window.cpp
@@ -591,7 +591,7 @@ void cWindow::OnLeftPaintEnd(cPlayer & a_Player)
const cSlotNums & SlotNums = a_Player.GetInventoryPaintSlots();
cItem ToDistribute(a_Player.GetDraggingItem());
- int ToEachSlot = (int)ToDistribute.m_ItemCount / SlotNums.size();
+ int ToEachSlot = (int)ToDistribute.m_ItemCount / (int)SlotNums.size();
int NumDistributed = DistributeItemToSlots(a_Player, ToDistribute, ToEachSlot, SlotNums);
@@ -805,6 +805,51 @@ cCraftingWindow::cCraftingWindow(int a_BlockX, int a_BlockY, int a_BlockZ) :
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cAnvilWindow:
+
+cAnvilWindow::cAnvilWindow(int a_BlockX, int a_BlockY, int a_BlockZ) :
+ cWindow(wtAnvil, "Repair"),
+ m_RepairedItemName(""),
+ m_BlockX(a_BlockX),
+ m_BlockY(a_BlockY),
+ m_BlockZ(a_BlockZ)
+{
+ m_AnvilSlotArea = new cSlotAreaAnvil(*this);
+ m_SlotAreas.push_back(m_AnvilSlotArea);
+ m_SlotAreas.push_back(new cSlotAreaInventory(*this));
+ m_SlotAreas.push_back(new cSlotAreaHotBar(*this));
+}
+
+
+
+
+
+void cAnvilWindow::SetRepairedItemName(const AString & a_Name, cPlayer * a_Player)
+{
+ m_RepairedItemName = a_Name;
+
+ if (a_Player != NULL)
+ {
+ m_AnvilSlotArea->UpdateResult(*a_Player);
+ }
+}
+
+
+
+
+
+void cAnvilWindow::GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ)
+{
+ a_PosX = m_BlockX;
+ a_PosY = m_BlockY;
+ a_PosZ = m_BlockZ;
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cEnchantingWindow:
cEnchantingWindow::cEnchantingWindow(int a_BlockX, int a_BlockY, int a_BlockZ) :
diff --git a/src/UI/Window.h b/src/UI/Window.h
index 1ca67bfd8..542dccb88 100644
--- a/src/UI/Window.h
+++ b/src/UI/Window.h
@@ -24,6 +24,7 @@ class cEnderChestEntity;
class cFurnaceEntity;
class cHopperEntity;
class cSlotArea;
+class cSlotAreaAnvil;
class cWorld;
typedef std::list<cPlayer *> cPlayerList;
@@ -231,6 +232,32 @@ public:
+class cAnvilWindow :
+ public cWindow
+{
+ typedef cWindow super;
+public:
+ cAnvilWindow(int a_BlockX, int a_BlockY, int a_BlockZ);
+
+ /** Gets the repaired item name. */
+ AString GetRepairedItemName(void) const { return m_RepairedItemName; }
+
+ /** Set the repaired item name. */
+ void SetRepairedItemName(const AString & a_Name, cPlayer * a_Player);
+
+ /** Gets the Position from the Anvil */
+ void GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ);
+
+protected:
+ cSlotAreaAnvil * m_AnvilSlotArea;
+ AString m_RepairedItemName;
+ int m_BlockX, m_BlockY, m_BlockZ;
+} ;
+
+
+
+
+
class cEnchantingWindow :
public cWindow
{
@@ -243,7 +270,7 @@ public:
/** Return the Value of a Property */
int GetPropertyValue(int a_Property);
- /** Set the Position Values to the Position of the Enchantment Table */
+ /** Get the Position from the Enchantment Table */
void GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ);
cSlotArea * m_SlotArea;
diff --git a/src/Vector3.h b/src/Vector3.h
index 2c79f9ff1..fed776018 100644
--- a/src/Vector3.h
+++ b/src/Vector3.h
@@ -40,7 +40,6 @@ public:
Vector3(const Vector3<_T> * a_Rhs) : x(a_Rhs->x), y(a_Rhs->y), z(a_Rhs->z) {}
// tolua_begin
-
inline void Set(T a_x, T a_y, T a_z)
{
x = a_x;
@@ -105,18 +104,18 @@ public:
inline bool Equals(const Vector3<T> & a_Rhs) const
{
- return x == a_Rhs.x && y == a_Rhs.y && z == a_Rhs.z;
- }
-
- inline bool operator == (const Vector3<T> & a_Rhs) const
- {
- return Equals(a_Rhs);
+ // Perform a bitwise comparison of the contents - we want to know whether this object is exactly equal
+ // To perform EPS-based comparison, use the EqualsEps() function
+ return (
+ (memcmp(&x, &a_Rhs.x, sizeof(x)) == 0) &&
+ (memcmp(&y, &a_Rhs.y, sizeof(y)) == 0) &&
+ (memcmp(&z, &a_Rhs.z, sizeof(z)) == 0)
+ );
}
-
- inline bool operator < (const Vector3<T> & a_Rhs)
+
+ inline bool EqualsEps(const Vector3<T> & a_Rhs, T a_Eps) const
{
- // return (x < a_Rhs.x) && (y < a_Rhs.y) && (z < a_Rhs.z); ?
- return (x < a_Rhs.x) || (x == a_Rhs.x && y < a_Rhs.y) || (x == a_Rhs.x && y == a_Rhs.y && z < a_Rhs.z);
+ return (Abs(x - a_Rhs.x) < a_Eps) && (Abs(y - a_Rhs.y) < a_Eps) && (Abs(z - a_Rhs.z) < a_Eps);
}
inline void Move(T a_X, T a_Y, T a_Z)
@@ -135,6 +134,16 @@ public:
// tolua_end
+ inline bool operator != (const Vector3<T> & a_Rhs) const
+ {
+ return !Equals(a_Rhs);
+ }
+
+ inline bool operator == (const Vector3<T> & a_Rhs) const
+ {
+ return Equals(a_Rhs);
+ }
+
inline void operator += (const Vector3<T> & a_Rhs)
{
x += a_Rhs.x;
@@ -163,8 +172,16 @@ public:
z *= a_v;
}
- // tolua_begin
+ inline Vector3<T> & operator = (const Vector3<T> & a_Rhs)
+ {
+ x = a_Rhs.x;
+ y = a_Rhs.y;
+ z = a_Rhs.z;
+ return *this;
+ }
+ // tolua_begin
+
inline Vector3<T> operator + (const Vector3<T>& a_Rhs) const
{
return Vector3<T>(
@@ -217,7 +234,7 @@ public:
*/
inline double LineCoeffToXYPlane(const Vector3<T> & a_OtherEnd, T a_Z) const
{
- if (abs(z - a_OtherEnd.z) < EPS)
+ if (Abs(z - a_OtherEnd.z) < EPS)
{
return NO_INTERSECTION;
}
@@ -232,7 +249,7 @@ public:
*/
inline double LineCoeffToXZPlane(const Vector3<T> & a_OtherEnd, T a_Y) const
{
- if (abs(y - a_OtherEnd.y) < EPS)
+ if (Abs(y - a_OtherEnd.y) < EPS)
{
return NO_INTERSECTION;
}
@@ -247,7 +264,7 @@ public:
*/
inline double LineCoeffToYZPlane(const Vector3<T> & a_OtherEnd, T a_X) const
{
- if (abs(x - a_OtherEnd.x) < EPS)
+ if (Abs(x - a_OtherEnd.x) < EPS)
{
return NO_INTERSECTION;
}
@@ -260,7 +277,15 @@ public:
/** Return value of LineCoeffToPlane() if the line is parallel to the plane. */
static const double NO_INTERSECTION;
+
+protected:
+ /** Returns the absolute value of the given argument.
+ Templatized because the standard library differentiates between abs() and fabs(). */
+ static T Abs(T a_Value)
+ {
+ return (a_Value < 0) ? -a_Value : a_Value;
+ }
};
// tolua_end
diff --git a/src/World.cpp b/src/World.cpp
index 5ac8e0a6e..807065bfa 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -394,10 +394,14 @@ void cWorld::InitializeSpawn(void)
// For the debugging builds, don't make the server build too much world upon start:
#if defined(_DEBUG) || defined(ANDROID_NDK)
- int ViewDist = 9;
+ const int DefaultViewDist = 9;
#else
- int ViewDist = 20; // Always prepare an area 20 chunks across, no matter what the actual cClientHandle::VIEWDISTANCE is
+ const int DefaultViewDist = 20; // Always prepare an area 20 chunks across, no matter what the actual cClientHandle::VIEWDISTANCE is
#endif // _DEBUG
+ cIniFile IniFile;
+ IniFile.ReadFile(m_IniFileName);
+ int ViewDist = IniFile.GetValueSetI("SpawnPosition", "PregenerateDistance", DefaultViewDist);
+ IniFile.WriteFile(m_IniFileName);
LOG("Preparing spawn area in world \"%s\"...", m_WorldName.c_str());
for (int x = 0; x < ViewDist; x++)
@@ -2402,13 +2406,13 @@ bool cWorld::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_
bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCallback & a_Callback)
{
cPlayer * BestMatch = NULL;
- unsigned int BestRating = 0;
- unsigned int NameLength = a_PlayerNameHint.length();
+ size_t BestRating = 0;
+ size_t NameLength = a_PlayerNameHint.length();
cCSLock Lock(m_CSPlayers);
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
- unsigned int Rating = RateCompareString (a_PlayerNameHint, (*itr)->GetName());
+ size_t Rating = RateCompareString (a_PlayerNameHint, (*itr)->GetName());
if (Rating >= BestRating)
{
BestMatch = *itr;
@@ -2422,7 +2426,6 @@ bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCa
if (BestMatch != NULL)
{
- LOG("Compared %s and %s with rating %i", a_PlayerNameHint.c_str(), BestMatch->GetName().c_str(), BestRating);
return a_Callback.Item (BestMatch);
}
return false;
diff --git a/src/World.h b/src/World.h
index f789916df..86cbb3e7e 100644
--- a/src/World.h
+++ b/src/World.h
@@ -351,7 +351,7 @@ public:
/** Is the trapdoor open? Returns false if there is no trapdoor at the specified coords. */
bool IsTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export
- /** Set the state of a trapdoor. Returns true if the trapdoor was update, false if there was no trapdoor at those coords. */
+ /** Set the state of a trapdoor. Returns true if the trapdoor was updated, false if there was no trapdoor at those coords. */
bool SetTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open); // tolua_export
/** Regenerate the given chunk: */
@@ -710,7 +710,9 @@ public:
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) override; // tolua_export
int SpawnMobFinalize(cMonster* a_Monster);
- /** Creates a projectile of the specified type. Returns the projectile's EntityID if successful, <0 otherwise */
+ /** Creates a projectile of the specified type. Returns the projectile's EntityID if successful, <0 otherwise
+ Item parameter used currently for Fireworks to correctly set entity metadata based on item metadata
+ */
int CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem & a_Item, const Vector3d * a_Speed = NULL); // tolua_export
/** Returns a random number from the m_TickRand in range [0 .. a_Range]. To be used only in the tick thread! */
diff --git a/src/WorldStorage/FastNBT.cpp b/src/WorldStorage/FastNBT.cpp
index ac9a21205..a047d67c7 100644
--- a/src/WorldStorage/FastNBT.cpp
+++ b/src/WorldStorage/FastNBT.cpp
@@ -29,7 +29,7 @@
// cParsedNBT:
#define NEEDBYTES(N) \
- if (m_Length - m_Pos < N) \
+ if (m_Length - m_Pos < (size_t)N) \
{ \
return false; \
}
@@ -38,7 +38,7 @@
-cParsedNBT::cParsedNBT(const char * a_Data, int a_Length) :
+cParsedNBT::cParsedNBT(const char * a_Data, size_t a_Length) :
m_Data(a_Data),
m_Length(a_Length),
m_Pos(0)
@@ -79,14 +79,14 @@ bool cParsedNBT::Parse(void)
-bool cParsedNBT::ReadString(int & a_StringStart, int & a_StringLen)
+bool cParsedNBT::ReadString(size_t & a_StringStart, size_t & a_StringLen)
{
NEEDBYTES(2);
a_StringStart = m_Pos + 2;
- a_StringLen = GetBEShort(m_Data + m_Pos);
- if (a_StringLen < 0)
+ a_StringLen = (size_t)GetBEShort(m_Data + m_Pos);
+ if (a_StringLen > 0xffff)
{
- // Invalid string length
+ // Suspicious string length
return false;
}
m_Pos += 2 + a_StringLen;
@@ -99,8 +99,10 @@ bool cParsedNBT::ReadString(int & a_StringStart, int & a_StringLen)
bool cParsedNBT::ReadCompound(void)
{
+ ASSERT(m_Tags.size() > 0);
+
// Reads the latest tag as a compound
- int ParentIdx = m_Tags.size() - 1;
+ int ParentIdx = (int)m_Tags.size() - 1;
int PrevSibling = -1;
for (;;)
{
@@ -114,13 +116,13 @@ bool cParsedNBT::ReadCompound(void)
m_Tags.push_back(cFastNBTTag(TagType, ParentIdx, PrevSibling));
if (PrevSibling >= 0)
{
- m_Tags[PrevSibling].m_NextSibling = m_Tags.size() - 1;
+ m_Tags[PrevSibling].m_NextSibling = (int)m_Tags.size() - 1;
}
else
{
- m_Tags[ParentIdx].m_FirstChild = m_Tags.size() - 1;
+ m_Tags[ParentIdx].m_FirstChild = (int)m_Tags.size() - 1;
}
- PrevSibling = m_Tags.size() - 1;
+ PrevSibling = (int)m_Tags.size() - 1;
RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength));
RETURN_FALSE_IF_FALSE(ReadTag());
} // while (true)
@@ -146,20 +148,20 @@ bool cParsedNBT::ReadList(eTagType a_ChildrenType)
}
// Read items:
- int ParentIdx = m_Tags.size() - 1;
+ int ParentIdx = (int)m_Tags.size() - 1;
int PrevSibling = -1;
for (int i = 0; i < Count; i++)
{
m_Tags.push_back(cFastNBTTag(a_ChildrenType, ParentIdx, PrevSibling));
if (PrevSibling >= 0)
{
- m_Tags[PrevSibling].m_NextSibling = m_Tags.size() - 1;
+ m_Tags[PrevSibling].m_NextSibling = (int)m_Tags.size() - 1;
}
else
{
- m_Tags[ParentIdx].m_FirstChild = m_Tags.size() - 1;
+ m_Tags[ParentIdx].m_FirstChild = (int)m_Tags.size() - 1;
}
- PrevSibling = m_Tags.size() - 1;
+ PrevSibling = (int)m_Tags.size() - 1;
RETURN_FALSE_IF_FALSE(ReadTag());
} // for (i)
m_Tags[ParentIdx].m_LastChild = PrevSibling;
@@ -279,7 +281,7 @@ int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLen
for (int Child = m_Tags[a_Tag].m_FirstChild; Child != -1; Child = m_Tags[Child].m_NextSibling)
{
if (
- (m_Tags[Child].m_NameLength == (int)a_NameLength) &&
+ (m_Tags[Child].m_NameLength == a_NameLength) &&
(memcmp(m_Data + m_Tags[Child].m_NameStart, a_Name, a_NameLength) == 0)
)
{
@@ -336,7 +338,7 @@ cFastNBTWriter::cFastNBTWriter(const AString & a_RootTagName) :
m_Stack[0].m_Type = TAG_Compound;
m_Result.reserve(100 * 1024);
m_Result.push_back(TAG_Compound);
- WriteString(a_RootTagName.data(), a_RootTagName.size());
+ WriteString(a_RootTagName.data(), (UInt16)a_RootTagName.size());
}
@@ -389,7 +391,7 @@ void cFastNBTWriter::BeginList(const AString & a_Name, eTagType a_ChildrenType)
++m_CurrentStack;
m_Stack[m_CurrentStack].m_Type = TAG_List;
- m_Stack[m_CurrentStack].m_Pos = m_Result.size() - 4;
+ m_Stack[m_CurrentStack].m_Pos = (int)m_Result.size() - 4;
m_Stack[m_CurrentStack].m_Count = 0;
m_Stack[m_CurrentStack].m_ItemType = a_ChildrenType;
}
@@ -493,7 +495,7 @@ void cFastNBTWriter::AddString(const AString & a_Name, const AString & a_Value)
void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements)
{
TagCommon(a_Name, TAG_ByteArray);
- Int32 len = htonl(a_NumElements);
+ u_long len = htonl((u_long)a_NumElements);
m_Result.append((const char *)&len, 4);
m_Result.append(a_Value, a_NumElements);
}
@@ -505,7 +507,7 @@ void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value,
void cFastNBTWriter::AddIntArray(const AString & a_Name, const int * a_Value, size_t a_NumElements)
{
TagCommon(a_Name, TAG_IntArray);
- Int32 len = htonl(a_NumElements);
+ u_long len = htonl((u_long)a_NumElements);
size_t cap = m_Result.capacity();
size_t size = m_Result.length();
if ((cap - size) < (4 + a_NumElements * 4))
@@ -534,7 +536,7 @@ void cFastNBTWriter::Finish(void)
-void cFastNBTWriter::WriteString(const char * a_Data, short a_Length)
+void cFastNBTWriter::WriteString(const char * a_Data, UInt16 a_Length)
{
Int16 Len = htons(a_Length);
m_Result.append((const char *)&Len, 2);
diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h
index bcf93228f..fe28005ac 100644
--- a/src/WorldStorage/FastNBT.h
+++ b/src/WorldStorage/FastNBT.h
@@ -61,10 +61,10 @@ public:
// The following members are indices into the data stream. m_DataLength == 0 if no data available
// They must not be pointers, because the datastream may be copied into another AString object in the meantime.
- int m_NameStart;
- int m_NameLength;
- int m_DataStart;
- int m_DataLength;
+ size_t m_NameStart;
+ size_t m_NameLength;
+ size_t m_DataStart;
+ size_t m_DataLength;
// The following members are indices into the array returned; -1 if not valid
// They must not be pointers, because pointers would not survive std::vector reallocation
@@ -114,7 +114,7 @@ Each primitive tag also stores the length of the contained data, in bytes.
class cParsedNBT
{
public:
- cParsedNBT(const char * a_Data, int a_Length);
+ cParsedNBT(const char * a_Data, size_t a_Length);
bool IsValid(void) const {return m_IsValid; }
@@ -135,7 +135,7 @@ public:
/** Returns the length of the tag's data, in bytes.
Not valid for Compound or List tags! */
- int GetDataLength (int a_Tag) const
+ size_t GetDataLength (int a_Tag) const
{
ASSERT(m_Tags[(size_t)a_Tag].m_Type != TAG_List);
ASSERT(m_Tags[(size_t)a_Tag].m_Type != TAG_Compound);
@@ -251,15 +251,15 @@ public:
protected:
const char * m_Data;
- int m_Length;
+ size_t m_Length;
std::vector<cFastNBTTag> m_Tags;
bool m_IsValid; // True if parsing succeeded
// Used while parsing:
- int m_Pos;
+ size_t m_Pos;
bool Parse(void);
- bool ReadString(int & a_StringStart, int & a_StringLen); // Reads a simple string (2 bytes length + data), sets the string descriptors
+ bool ReadString(size_t & a_StringStart, size_t & a_StringLen); // Reads a simple string (2 bytes length + data), sets the string descriptors
bool ReadCompound(void); // Reads the latest tag as a compound
bool ReadList(eTagType a_ChildrenType); // Reads the latest tag as a list of items of type a_ChildrenType
bool ReadTag(void); // Reads the latest tag, depending on its m_Type setting
@@ -319,7 +319,7 @@ protected:
bool IsStackTopCompound(void) const { return (m_Stack[m_CurrentStack].m_Type == TAG_Compound); }
- void WriteString(const char * a_Data, short a_Length);
+ void WriteString(const char * a_Data, UInt16 a_Length);
inline void TagCommon(const AString & a_Name, eTagType a_Type)
{
@@ -330,7 +330,7 @@ protected:
{
// Compound: add the type and name:
m_Result.push_back((char)a_Type);
- WriteString(a_Name.c_str(), (short)a_Name.length());
+ WriteString(a_Name.c_str(), (UInt16)a_Name.length());
}
else
{
diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp
index e0cd69634..181cfde0d 100644
--- a/src/WorldStorage/FireworksSerializer.cpp
+++ b/src/WorldStorage/FireworksSerializer.cpp
@@ -96,7 +96,7 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB
if (ExplosionName == "Colors")
{
// Divide by four as data length returned in bytes
- int DataLength = a_NBT.GetDataLength(explosiontag);
+ size_t DataLength = a_NBT.GetDataLength(explosiontag);
// round to the next highest multiple of four
DataLength -= DataLength % 4;
if (DataLength == 0)
@@ -105,14 +105,14 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB
}
const char * ColourData = (a_NBT.GetData(explosiontag));
- for (int i = 0; i < DataLength; i += 4 /* Size of network int*/)
+ for (size_t i = 0; i < DataLength; i += 4)
{
a_FireworkItem.m_Colours.push_back(GetBEInt(ColourData + i));
}
}
else if (ExplosionName == "FadeColors")
{
- int DataLength = a_NBT.GetDataLength(explosiontag) / 4;
+ size_t DataLength = a_NBT.GetDataLength(explosiontag) / 4;
// round to the next highest multiple of four
DataLength -= DataLength % 4;
if (DataLength == 0)
@@ -121,7 +121,7 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB
}
const char * FadeColourData = (a_NBT.GetData(explosiontag));
- for (int i = 0; i < DataLength; i += 4 /* Size of network int*/)
+ for (size_t i = 0; i < DataLength; i += 4)
{
a_FireworkItem.m_FadeColours.push_back(GetBEInt(FadeColourData + i));
}
diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp
index df72d1cc9..012fc52f3 100644
--- a/src/WorldStorage/MapSerializer.cpp
+++ b/src/WorldStorage/MapSerializer.cpp
@@ -152,6 +152,10 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT)
if (CurrLine >= 0)
{
unsigned int Width = a_NBT.GetShort(CurrLine);
+ if (Width != 128)
+ {
+ return false;
+ }
m_Map->m_Width = Width;
}
@@ -159,6 +163,10 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT)
if (CurrLine >= 0)
{
unsigned int Height = a_NBT.GetShort(CurrLine);
+ if (Height >= 256)
+ {
+ return false;
+ }
m_Map->m_Height = Height;
}
diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp
index fd356c7de..2ac1d7962 100644
--- a/src/WorldStorage/NBTChunkSerializer.cpp
+++ b/src/WorldStorage/NBTChunkSerializer.cpp
@@ -88,23 +88,48 @@ void cNBTChunkSerializer::Finish(void)
void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AString & a_CompoundName)
{
m_Writer.BeginCompound(a_CompoundName);
- m_Writer.AddShort("id", (short)(a_Item.m_ItemType));
- m_Writer.AddShort("Damage", a_Item.m_ItemDamage);
- m_Writer.AddByte ("Count", a_Item.m_ItemCount);
+ m_Writer.AddShort("id", (short)(a_Item.m_ItemType));
+ m_Writer.AddShort("Damage", a_Item.m_ItemDamage);
+ m_Writer.AddByte ("Count", a_Item.m_ItemCount);
if (a_Slot >= 0)
{
m_Writer.AddByte ("Slot", (unsigned char)a_Slot);
}
- // Write the enchantments:
- if (!a_Item.m_Enchantments.IsEmpty() || ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR)))
+ // Write the tag compound (for enchantment, firework, custom name and repair cost):
+ if (
+ (!a_Item.m_Enchantments.IsEmpty()) ||
+ ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR)) ||
+ (a_Item.m_RepairCost > 0) ||
+ (a_Item.m_CustomName != "") ||
+ (a_Item.m_Lore != "")
+ )
{
m_Writer.BeginCompound("tag");
+ if (a_Item.m_RepairCost > 0)
+ {
+ m_Writer.AddInt("RepairCost", a_Item.m_RepairCost);
+ }
+
+ if ((a_Item.m_CustomName != "") || (a_Item.m_Lore != ""))
+ {
+ m_Writer.BeginCompound("display");
+ if (a_Item.m_CustomName != "")
+ {
+ m_Writer.AddString("Name", a_Item.m_CustomName);
+ }
+ if (a_Item.m_Lore != "")
+ {
+ m_Writer.AddString("Lore", a_Item.m_Lore);
+ }
+ m_Writer.EndCompound();
+ }
+
if ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR))
{
cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, m_Writer, (ENUM_ITEM_ID)a_Item.m_ItemType);
}
-
+
if (!a_Item.m_Enchantments.IsEmpty())
{
const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
@@ -490,7 +515,7 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
}
case cMonster::mtMagmaCube:
{
- m_Writer.AddByte("Size", ((const cMagmaCube *)a_Monster)->GetSize());
+ m_Writer.AddInt("Size", ((const cMagmaCube *)a_Monster)->GetSize());
break;
}
case cMonster::mtSheep:
diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp
index 9d594a084..1cf99efd9 100644
--- a/src/WorldStorage/SchematicFileSerializer.cpp
+++ b/src/WorldStorage/SchematicFileSerializer.cpp
@@ -192,7 +192,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP
int SizeX = a_NBT.GetShort(TSizeX);
int SizeY = a_NBT.GetShort(TSizeY);
int SizeZ = a_NBT.GetShort(TSizeZ);
- if ((SizeX < 1) || (SizeY < 1) || (SizeZ < 1))
+ if ((SizeX < 1) || (SizeX > 65535) || (SizeY < 1) || (SizeY > 256) || (SizeZ < 1) || (SizeZ > 65535))
{
LOG("Dimensions are invalid in the schematic file: %d, %d, %d", SizeX, SizeY, SizeZ);
return false;
@@ -230,11 +230,11 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP
}
// Copy the block types and metas:
- int NumBytes = a_BlockArea.GetBlockCount();
+ size_t NumBytes = a_BlockArea.GetBlockCount();
if (a_NBT.GetDataLength(TBlockTypes) < NumBytes)
{
LOG("BlockTypes truncated in the schematic file (exp %d, got %d bytes). Loading partial.",
- NumBytes, a_NBT.GetDataLength(TBlockTypes)
+ (int)NumBytes, (int)a_NBT.GetDataLength(TBlockTypes)
);
NumBytes = a_NBT.GetDataLength(TBlockTypes);
}
@@ -242,11 +242,11 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP
if (AreMetasPresent)
{
- int NumBytes = a_BlockArea.GetBlockCount();
+ size_t NumBytes = a_BlockArea.GetBlockCount();
if (a_NBT.GetDataLength(TBlockMetas) < NumBytes)
{
LOG("BlockMetas truncated in the schematic file (exp %d, got %d bytes). Loading partial.",
- NumBytes, a_NBT.GetDataLength(TBlockMetas)
+ (int)NumBytes, (int)a_NBT.GetDataLength(TBlockMetas)
);
NumBytes = a_NBT.GetDataLength(TBlockMetas);
}
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index f33178173..d310c9124 100644
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -96,7 +96,7 @@ cWSSAnvil::cWSSAnvil(cWorld * a_World, int a_CompressionFactor) :
gzFile gz = gzopen((FILE_IO_PREFIX + fnam).c_str(), "wb");
if (gz != NULL)
{
- gzwrite(gz, Writer.GetResult().data(), Writer.GetResult().size());
+ gzwrite(gz, Writer.GetResult().data(), (unsigned)Writer.GetResult().size());
}
gzclose(gz);
}
@@ -252,7 +252,7 @@ bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString &
strm.next_out = (Bytef *)Uncompressed;
strm.avail_out = sizeof(Uncompressed);
strm.next_in = (Bytef *)a_Data.data();
- strm.avail_in = a_Data.size();
+ strm.avail_in = (uInt)a_Data.size();
int res = inflate(&strm, Z_FINISH);
inflateEnd(&strm);
if (res != Z_STREAM_END)
@@ -405,7 +405,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT
-void cWSSAnvil::CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, int a_Length)
+void cWSSAnvil::CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, size_t a_Length)
{
int Child = a_NBT.FindChildByName(a_Tag, a_ChildName);
if ((Child >= 0) && (a_NBT.GetType(Child) == TAG_ByteArray) && (a_NBT.GetDataLength(Child) == a_Length))
@@ -440,8 +440,8 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_
// Save blockdata:
a_Writer.BeginList("Sections", TAG_Compound);
- int SliceSizeBlock = cChunkDef::Width * cChunkDef::Width * 16;
- int SliceSizeNibble = SliceSizeBlock / 2;
+ size_t SliceSizeBlock = cChunkDef::Width * cChunkDef::Width * 16;
+ size_t SliceSizeNibble = SliceSizeBlock / 2;
const char * BlockTypes = (const char *)(Serializer.m_BlockTypes);
const char * BlockMetas = (const char *)(Serializer.m_BlockMetas);
#ifdef DEBUG_SKYLIGHT
@@ -645,18 +645,16 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_
}
int Damage = a_NBT.FindChildByName(a_TagIdx, "Damage");
- if ((Damage < 0) || (a_NBT.GetType(Damage) != TAG_Short))
+ if ((Damage > 0) && (a_NBT.GetType(Damage) == TAG_Short))
{
- return false;
+ a_Item.m_ItemDamage = a_NBT.GetShort(Damage);
}
- a_Item.m_ItemDamage = a_NBT.GetShort(Damage);
int Count = a_NBT.FindChildByName(a_TagIdx, "Count");
- if ((Count < 0) || (a_NBT.GetType(Count) != TAG_Byte))
+ if ((Count > 0) && (a_NBT.GetType(Count) == TAG_Byte))
{
- return false;
+ a_Item.m_ItemCount = a_NBT.GetByte(Count);
}
- a_Item.m_ItemCount = a_NBT.GetByte(Count);
// Find the "tag" tag, used for enchantments and other extra data
int TagTag = a_NBT.FindChildByName(a_TagIdx, "tag");
@@ -666,6 +664,29 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_
return true;
}
+ // Load repair cost:
+ int RepairCost = a_NBT.FindChildByName(TagTag, "RepairCost");
+ if ((RepairCost > 0) && (a_NBT.GetType(RepairCost) == TAG_Int))
+ {
+ a_Item.m_RepairCost = a_NBT.GetInt(RepairCost);
+ }
+
+ // Load display name:
+ int DisplayTag = a_NBT.FindChildByName(TagTag, "display");
+ if (DisplayTag > 0)
+ {
+ int DisplayName = a_NBT.FindChildByName(DisplayTag, "Name");
+ if ((DisplayName > 0) && (a_NBT.GetType(DisplayName) == TAG_String))
+ {
+ a_Item.m_CustomName = a_NBT.GetString(DisplayName);
+ }
+ int Lore = a_NBT.FindChildByName(DisplayTag, "Lore");
+ if ((Lore > 0) && (a_NBT.GetType(Lore) == TAG_String))
+ {
+ a_Item.m_Lore = a_NBT.GetString(Lore);
+ }
+ }
+
// Load enchantments:
const char * EnchName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
int EnchTag = a_NBT.FindChildByName(TagTag, EnchName);
@@ -674,6 +695,7 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_
EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, a_NBT, EnchTag);
}
+ // Load firework data:
int FireworksTag = a_NBT.FindChildByName(TagTag, ((a_Item.m_ItemType == E_ITEM_FIREWORK_STAR) ? "Fireworks" : "Explosion"));
if (EnchTag > 0)
{
@@ -1056,7 +1078,7 @@ void cWSSAnvil::LoadCommandBlockFromNBT(cBlockEntityList & a_BlockEntities, cons
-void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength)
+void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, size_t a_IDTagLength)
{
if (strncmp(a_IDTag, "Boat", a_IDTagLength) == 0)
{
@@ -1974,7 +1996,10 @@ void cWSSAnvil::LoadMagmaCubeFromNBT(cEntityList & a_Entities, const cParsedNBT
{
int SizeIdx = a_NBT.FindChildByName(a_TagIdx, "Size");
- if (SizeIdx < 0) { return; }
+ if (SizeIdx < 0)
+ {
+ return;
+ }
int Size = a_NBT.GetInt(SizeIdx);
@@ -2132,7 +2157,10 @@ void cWSSAnvil::LoadSlimeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
{
int SizeIdx = a_NBT.FindChildByName(a_TagIdx, "Size");
- if (SizeIdx < 0) { return; }
+ if (SizeIdx < 0)
+ {
+ return;
+ }
int Size = a_NBT.GetInt(SizeIdx);
@@ -2602,14 +2630,14 @@ bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a
unsigned ChunkLocation = ntohl(m_Header[LocalX + 32 * LocalZ]);
unsigned ChunkOffset = ChunkLocation >> 8;
- m_File.Seek(ChunkOffset * 4096);
+ m_File.Seek((int)ChunkOffset * 4096);
int ChunkSize = 0;
if (m_File.Read(&ChunkSize, 4) != 4)
{
return false;
}
- ChunkSize = ntohl(ChunkSize);
+ ChunkSize = ntohl((u_long)ChunkSize);
char CompressionType = 0;
if (m_File.Read(&CompressionType, 1) != 1)
{
@@ -2654,7 +2682,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri
// Store the chunk data:
m_File.Seek(ChunkSector * 4096);
- unsigned ChunkSize = htonl(a_Data.size() + 1);
+ u_long ChunkSize = htonl((u_long)a_Data.size() + 1);
if (m_File.Write(&ChunkSize, 4) != 4)
{
LOGWARNING("Cannot save chunk [%d, %d], writing(1) data to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str());
@@ -2678,7 +2706,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri
m_File.Write(Padding, 4096 - (BytesWritten % 4096));
// Store the header:
- ChunkSize = (a_Data.size() + MCA_CHUNK_HEADER_LENGTH + 4095) / 4096; // Round data size *up* to nearest 4KB sector, make it a sector number
+ ChunkSize = ((u_long)a_Data.size() + MCA_CHUNK_HEADER_LENGTH + 4095) / 4096; // Round data size *up* to nearest 4KB sector, make it a sector number
ASSERT(ChunkSize < 256);
m_Header[LocalX + 32 * LocalZ] = htonl((ChunkSector << 8) | ChunkSize);
if (m_File.Seek(0) < 0)
diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h
index 1773ee882..7542a828a 100644
--- a/src/WorldStorage/WSSAnvil.h
+++ b/src/WorldStorage/WSSAnvil.h
@@ -145,7 +145,7 @@ protected:
void LoadMobHeadFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadCommandBlockFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx);
- void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength);
+ void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, size_t a_IDTagLength);
void LoadBoatFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadEnderCrystalFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
@@ -221,7 +221,7 @@ protected:
cMCAFile * LoadMCAFile(const cChunkCoords & a_Chunk);
/// Copies a_Length bytes of data from the specified NBT Tag's Child into the a_Destination buffer
- void CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, int a_Length);
+ void CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, size_t a_Length);
// cWSSchema overrides:
virtual bool LoadChunk(const cChunkCoords & a_Chunk) override;
diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp
index 359bac4a8..6d06b8fe3 100644
--- a/src/WorldStorage/WSSCompact.cpp
+++ b/src/WorldStorage/WSSCompact.cpp
@@ -601,7 +601,7 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2()
// Decompress the data:
AString UncompressedData;
{
- int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, UncompressedSize);
+ int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, (size_t)UncompressedSize);
if (errorcode != Z_OK)
{
LOGERROR("Error %d decompressing data for chunk [%d, %d]",
@@ -681,7 +681,7 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2()
// Re-compress data
AString CompressedData;
{
- int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData,m_CompressionFactor);
+ int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData, m_CompressionFactor);
if (errorcode != Z_OK)
{
LOGERROR("Error %d compressing data for chunk [%d, %d]",
@@ -693,9 +693,9 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2()
}
// Save into file's cache
- Header->m_UncompressedSize = Converted.size();
- Header->m_CompressedSize = CompressedData.size();
- NewDataContents.append( CompressedData );
+ Header->m_UncompressedSize = (int)Converted.size();
+ Header->m_CompressedSize = (int)CompressedData.size();
+ NewDataContents.append(CompressedData);
}
// Done converting
@@ -731,7 +731,7 @@ void cWSSCompact::cPAKFile::UpdateChunk2To3()
Offset += Header->m_CompressedSize;
// Crude data integrity check:
- const int ExpectedSize = (16*256*16)*2 + (16*256*16)/2; // For version 2
+ const int ExpectedSize = (16 * 256 * 16) * 2 + (16 * 256 * 16) / 2; // For version 2
if (UncompressedSize < ExpectedSize)
{
LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing",
@@ -745,7 +745,7 @@ void cWSSCompact::cPAKFile::UpdateChunk2To3()
// Decompress the data:
AString UncompressedData;
{
- int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, UncompressedSize);
+ int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, (size_t)UncompressedSize);
if (errorcode != Z_OK)
{
LOGERROR("Error %d decompressing data for chunk [%d, %d]",
@@ -829,9 +829,9 @@ void cWSSCompact::cPAKFile::UpdateChunk2To3()
}
// Save into file's cache
- Header->m_UncompressedSize = Converted.size();
- Header->m_CompressedSize = CompressedData.size();
- NewDataContents.append( CompressedData );
+ Header->m_UncompressedSize = (int)Converted.size();
+ Header->m_CompressedSize = (int)CompressedData.size();
+ NewDataContents.append(CompressedData);
}
// Done converting
@@ -861,7 +861,7 @@ bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int a_Uncompre
// Decompress the data:
AString UncompressedData;
- int errorcode = UncompressString(a_Data.data(), a_Data.size(), UncompressedData, a_UncompressedSize);
+ int errorcode = UncompressString(a_Data.data(), a_Data.size(), UncompressedData, (size_t)a_UncompressedSize);
if (errorcode != Z_OK)
{
LOGERROR("Error %d decompressing data for chunk [%d, %d]",
@@ -873,7 +873,7 @@ bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int a_Uncompre
if (a_UncompressedSize != (int)UncompressedData.size())
{
- LOGWARNING("Uncompressed data size differs (exp %d bytes, got " SIZE_T_FMT ") for chunk [%d, %d]",
+ LOGWARNING("Uncompressed data size differs (exp %d bytes, got " SIZE_T_FMT ") for chunk [%d, %d]",
a_UncompressedSize, UncompressedData.size(),
a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ
);