summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorarchshift <admin@archshift.com>2014-07-10 08:28:27 +0200
committerarchshift <admin@archshift.com>2014-07-10 08:28:27 +0200
commite824cd09b369c47a7f316fccc7577cd923164466 (patch)
treed8efa178a29955525458a38b1351ea0b609a2a09 /src
parentEntityEffects.x -> EntityEffect.x, Object-Oriented effects (diff)
parentMerge pull request #1157 from Howaner/Window (diff)
downloadcuberite-e824cd09b369c47a7f316fccc7577cd923164466.tar
cuberite-e824cd09b369c47a7f316fccc7577cd923164466.tar.gz
cuberite-e824cd09b369c47a7f316fccc7577cd923164466.tar.bz2
cuberite-e824cd09b369c47a7f316fccc7577cd923164466.tar.lz
cuberite-e824cd09b369c47a7f316fccc7577cd923164466.tar.xz
cuberite-e824cd09b369c47a7f316fccc7577cd923164466.tar.zst
cuberite-e824cd09b369c47a7f316fccc7577cd923164466.zip
Diffstat (limited to '')
-rw-r--r--src/Bindings/.gitignore1
-rw-r--r--src/Bindings/LuaState.cpp12
-rw-r--r--src/Bindings/LuaState.h634
-rw-r--r--src/Bindings/ManualBindings.cpp12
-rw-r--r--src/Bindings/Plugin.h1
-rw-r--r--src/Bindings/PluginLua.cpp28
-rw-r--r--src/Bindings/PluginLua.h1
-rw-r--r--src/Bindings/PluginManager.cpp87
-rw-r--r--src/Bindings/PluginManager.h30
-rw-r--r--src/Bindings/gen_LuaState_Call.lua196
-rw-r--r--src/Bindings/virtual_method_hooks.lua14
-rw-r--r--src/BlockArea.cpp28
-rw-r--r--src/BlockEntities/ChestEntity.cpp13
-rw-r--r--src/BlockEntities/EnderChestEntity.cpp93
-rw-r--r--src/BlockEntities/EnderChestEntity.h44
-rw-r--r--src/BlockEntities/HopperEntity.cpp77
-rw-r--r--src/BlockEntities/MobHeadEntity.cpp2
-rw-r--r--src/BlockInfo.cpp754
-rw-r--r--src/BlockInfo.h23
-rw-r--r--src/Blocks/BlockButton.h3
-rw-r--r--src/Blocks/BlockDoor.cpp7
-rw-r--r--src/Blocks/BlockFenceGate.h1
-rw-r--r--src/Blocks/BlockFire.h4
-rw-r--r--src/Blocks/BlockHandler.cpp96
-rw-r--r--src/Blocks/BlockHayBale.h29
-rw-r--r--src/Blocks/BlockLever.h16
-rw-r--r--src/Blocks/BlockMobHead.h108
-rw-r--r--src/Blocks/BlockSign.h6
-rw-r--r--src/Blocks/BlockSlab.h16
-rw-r--r--src/Blocks/BlockStone.h2
-rw-r--r--src/Blocks/BlockTorch.h4
-rw-r--r--src/Blocks/BlockTripwire.h32
-rw-r--r--src/Blocks/BlockTripwireHook.h82
-rw-r--r--src/Blocks/WorldInterface.h12
-rw-r--r--src/ByteBuffer.cpp1
-rw-r--r--src/CMakeLists.txt26
-rw-r--r--src/Chunk.cpp14
-rw-r--r--src/Chunk.h2
-rw-r--r--src/ChunkMap.cpp6
-rw-r--r--src/ChunkMap.h5
-rw-r--r--src/ClientHandle.cpp109
-rw-r--r--src/ClientHandle.h15
-rw-r--r--src/CraftingRecipes.cpp1
-rw-r--r--src/Defines.h15
-rw-r--r--src/Entities/ArrowEntity.cpp73
-rw-r--r--src/Entities/ArrowEntity.h6
-rw-r--r--src/Entities/Entity.cpp17
-rw-r--r--src/Entities/Entity.h4
-rw-r--r--src/Entities/Pickup.cpp35
-rw-r--r--src/Entities/Player.cpp102
-rw-r--r--src/Entities/Player.h18
-rw-r--r--src/Entities/ProjectileEntity.cpp71
-rw-r--r--src/Entities/ProjectileEntity.h34
-rw-r--r--src/Entities/ThrownEggEntity.cpp7
-rw-r--r--src/Entities/ThrownEggEntity.h21
-rw-r--r--src/Entities/ThrownEnderPearlEntity.cpp40
-rw-r--r--src/Entities/ThrownEnderPearlEntity.h25
-rw-r--r--src/Entities/ThrownSnowballEntity.cpp11
-rw-r--r--src/Entities/ThrownSnowballEntity.h21
-rw-r--r--src/FurnaceRecipe.cpp272
-rw-r--r--src/FurnaceRecipe.h30
-rw-r--r--src/Generating/BioGen.cpp23
-rw-r--r--src/Generating/BioGen.h7
-rw-r--r--src/Generating/CompoGen.cpp2
-rw-r--r--src/Generating/ComposableGenerator.cpp5
-rw-r--r--src/Generating/GridStructGen.cpp4
-rw-r--r--src/Generating/HeiGen.cpp2
-rw-r--r--src/Generating/Prefab.cpp11
-rw-r--r--src/Generating/Prefabs/AlchemistVillagePrefabs.cpp3698
-rw-r--r--src/Generating/Prefabs/JapaneseVillagePrefabs.cpp384
-rw-r--r--src/Generating/Prefabs/PlainsVillagePrefabs.cpp434
-rw-r--r--src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp180
-rw-r--r--src/Generating/Prefabs/SandVillagePrefabs.cpp1472
-rw-r--r--src/Generating/Prefabs/TestRailsPrefabs.cpp484
-rw-r--r--src/Generating/Prefabs/TestRailsPrefabs.h15
-rw-r--r--src/Generating/Prefabs/UnderwaterBasePrefabs.cpp2
-rw-r--r--src/Generating/TestRailsGen.cpp116
-rw-r--r--src/Generating/TestRailsGen.h47
-rw-r--r--src/Globals.h21
-rw-r--r--src/GroupManager.cpp2
-rw-r--r--src/HTTPServer/HTTPConnection.cpp1
-rw-r--r--src/HTTPServer/HTTPServer.cpp2
-rw-r--r--src/Item.cpp2
-rw-r--r--src/ItemGrid.cpp1
-rw-r--r--src/Items/ItemBow.h17
-rw-r--r--src/Items/ItemHandler.cpp5
-rw-r--r--src/Items/ItemItemFrame.h1
-rw-r--r--src/Items/ItemString.h39
-rw-r--r--src/Items/ItemThrowable.h11
-rw-r--r--src/MCLogger.cpp1
-rw-r--r--src/Mobs/Blaze.cpp1
-rw-r--r--src/Mobs/Creeper.cpp22
-rw-r--r--src/Mobs/Ghast.cpp1
-rw-r--r--src/Mobs/Monster.cpp2
-rw-r--r--src/Mobs/Pig.cpp20
-rw-r--r--src/Mobs/Pig.h1
-rw-r--r--src/Mobs/Skeleton.cpp6
-rw-r--r--src/Mobs/Zombie.cpp5
-rw-r--r--src/MonsterConfig.cpp1
-rw-r--r--src/Noise.cpp4
-rw-r--r--src/OSSupport/Event.cpp7
-rw-r--r--src/OSSupport/File.cpp3
-rw-r--r--src/OSSupport/IsThread.cpp2
-rw-r--r--src/OSSupport/SocketThreads.cpp1
-rw-r--r--src/OSSupport/Thread.cpp2
-rw-r--r--src/Protocol/Protocol.h4
-rw-r--r--src/Protocol/Protocol125.cpp10
-rw-r--r--src/Protocol/Protocol125.h4
-rw-r--r--src/Protocol/Protocol132.cpp8
-rw-r--r--src/Protocol/Protocol132.h2
-rw-r--r--src/Protocol/Protocol16x.cpp4
-rw-r--r--src/Protocol/Protocol16x.h2
-rw-r--r--src/Protocol/Protocol17x.cpp15
-rw-r--r--src/Protocol/Protocol17x.h4
-rw-r--r--src/Protocol/ProtocolRecognizer.cpp9
-rw-r--r--src/Protocol/ProtocolRecognizer.h4
-rw-r--r--src/Server.cpp1
-rw-r--r--src/Simulator/FloodyFluidSimulator.cpp54
-rw-r--r--src/Simulator/FluidSimulator.cpp4
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator.cpp424
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator.h12
-rw-r--r--src/UI/SlotArea.cpp264
-rw-r--r--src/UI/SlotArea.h20
-rw-r--r--src/UI/Window.cpp28
-rw-r--r--src/Vector3.h21
-rw-r--r--src/VoronoiMap.cpp53
-rw-r--r--src/VoronoiMap.h25
-rw-r--r--src/WebAdmin.cpp1
-rw-r--r--src/World.cpp21
-rw-r--r--src/World.h7
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp39
-rw-r--r--src/WorldStorage/WSSAnvil.cpp35
-rw-r--r--src/WorldStorage/WSSCompact.cpp1
-rw-r--r--src/WorldStorage/WorldStorage.cpp35
-rw-r--r--src/WorldStorage/WorldStorage.h3
135 files changed, 6956 insertions, 4674 deletions
diff --git a/src/Bindings/.gitignore b/src/Bindings/.gitignore
index af8aa76fa..0d00dd578 100644
--- a/src/Bindings/.gitignore
+++ b/src/Bindings/.gitignore
@@ -1 +1,2 @@
lua51.dll
+LuaState_Call.inc
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp
index 7a5ed1425..32638df96 100644
--- a/src/Bindings/LuaState.cpp
+++ b/src/Bindings/LuaState.cpp
@@ -811,6 +811,18 @@ void cLuaState::GetStackValue(int a_StackPos, double & a_ReturnedVal)
+void cLuaState::GetStackValue(int a_StackPos, eWeather & a_ReturnedVal)
+{
+ if (lua_isnumber(m_LuaState, a_StackPos))
+ {
+ a_ReturnedVal = (eWeather)Clamp((int)tolua_tonumber(m_LuaState, a_StackPos, a_ReturnedVal), (int)wSunny, (int)wThunderstorm);
+ }
+}
+
+
+
+
+
bool cLuaState::CallFunction(int a_NumResults)
{
ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first
diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h
index 066390e39..b1ac3578a 100644
--- a/src/Bindings/LuaState.h
+++ b/src/Bindings/LuaState.h
@@ -9,10 +9,11 @@ Owned lua_State is created by calling Create() and the cLuaState automatically c
Or, lua_State can be attached by calling Attach(), the cLuaState doesn't close such a state
Attaching a state will automatically close an owned state.
-Calling a Lua function is done by pushing the function, either by PushFunction() or PushFunctionFromRegistry(),
-then pushing the arguments (PushString(), PushNumber(), PushUserData() etc.) and finally
-executing CallFunction(). cLuaState automatically keeps track of the number of arguments and the name of the
-function (for logging purposes), which makes the call less error-prone.
+Calling a Lua function is done internally by pushing the function using PushFunction(), then pushing the
+arguments and finally executing CallFunction(). cLuaState automatically keeps track of the number of
+arguments and the name of the function (for logging purposes). After the call the return values are read from
+the stack using GetStackValue(). All of this is wrapped in a templated function overloads cLuaState::Call(),
+which is generated automatically by gen_LuaState_Call.lua script file into the LuaState_Call.inc file.
Reference management is provided by the cLuaState::cRef class. This is used when you need to hold a reference to
any Lua object across several function calls; usually this is used for callbacks. The class is RAII-like, with
@@ -30,6 +31,7 @@ extern "C"
}
#include "../Vector3.h"
+#include "../Defines.h"
@@ -222,625 +224,13 @@ public:
/** Retrieve value at a_StackPos, if it is a valid number. If not, a_Value is unchanged */
void GetStackValue(int a_StackPos, double & a_Value);
+ /** Retrieve value at a_StackPos, if it is a valid number, converting and clamping it to eWeather.
+ If not, a_Value is unchanged. */
+ void GetStackValue(int a_StackPos, eWeather & a_Value);
+
- /** Call any 0-param 0-return Lua function in a single line: */
- template <typename FnT>
- bool Call(FnT a_FnName)
- {
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- return CallFunction(0);
- }
-
- /** Call any 1-param 0-return Lua function in a single line: */
- template<
- typename FnT,
- typename ArgT1
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1)
- {
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- return CallFunction(0);
- }
-
- /** Call any 2-param 0-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2)
- {
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- return CallFunction(0);
- }
-
- /** Call any 3-param 0-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3)
- {
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- return CallFunction(0);
- }
-
- /** Call any 0-param 1-return Lua function in a single line: */
- template<
- typename FnT, typename RetT1
- >
- bool Call(FnT a_FnName, const cRet & a_Mark, RetT1 & a_Ret1)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- if (!CallFunction(1))
- {
- return false;
- }
- GetStackValue(-1, a_Ret1);
- lua_pop(m_LuaState, 1);
- return true;
- }
-
- /** Call any 1-param 1-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename RetT1
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, const cRet & a_Mark, RetT1 & a_Ret1)
- {
- int InitialTop = lua_gettop(m_LuaState);
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- if (!CallFunction(1))
- {
- return false;
- }
- GetStackValue(-1, a_Ret1);
- lua_pop(m_LuaState, 1);
- ASSERT(InitialTop == lua_gettop(m_LuaState));
- return true;
- }
-
- /** Call any 2-param 1-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename RetT1
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, const cRet & a_Mark, RetT1 & a_Ret1)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- if (!CallFunction(1))
- {
- return false;
- }
- GetStackValue(-1, a_Ret1);
- lua_pop(m_LuaState, 1);
- return true;
- }
-
- /** Call any 3-param 1-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename RetT1
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, const cRet & a_Mark, RetT1 & a_Ret1)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- if (!CallFunction(1))
- {
- return false;
- }
- GetStackValue(-1, a_Ret1);
- lua_pop(m_LuaState, 1);
- return true;
- }
-
- /** Call any 4-param 1-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename RetT1
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, const cRet & a_Mark, RetT1 & a_Ret1)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- Push(a_Arg4);
- if (!CallFunction(1))
- {
- return false;
- }
- GetStackValue(-1, a_Ret1);
- lua_pop(m_LuaState, 1);
- return true;
- }
-
- /** Call any 5-param 1-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename RetT1
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, const cRet & a_Mark, RetT1 & a_Ret1)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- Push(a_Arg4);
- Push(a_Arg5);
- if (!CallFunction(1))
- {
- return false;
- }
- GetStackValue(-1, a_Ret1);
- lua_pop(m_LuaState, 1);
- return true;
- }
-
- /** Call any 6-param 1-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
- typename RetT1
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, const cRet & a_Mark, RetT1 & a_Ret1)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- Push(a_Arg4);
- Push(a_Arg5);
- Push(a_Arg6);
- if (!CallFunction(1))
- {
- return false;
- }
- GetStackValue(-1, a_Ret1);
- lua_pop(m_LuaState, 1);
- return true;
- }
-
- /** Call any 7-param 1-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
- typename ArgT7, typename RetT1
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, const cRet & a_Mark, RetT1 & a_Ret1)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- Push(a_Arg4);
- Push(a_Arg5);
- Push(a_Arg6);
- Push(a_Arg7);
- if (!CallFunction(1))
- {
- return false;
- }
- GetStackValue(-1, a_Ret1);
- lua_pop(m_LuaState, 1);
- return true;
- }
-
- /** Call any 8-param 1-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
- typename ArgT7, typename ArgT8, typename RetT1
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, const cRet & a_Mark, RetT1 & a_Ret1)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- Push(a_Arg4);
- Push(a_Arg5);
- Push(a_Arg6);
- Push(a_Arg7);
- Push(a_Arg8);
- if (!CallFunction(1))
- {
- return false;
- }
- GetStackValue(-1, a_Ret1);
- lua_pop(m_LuaState, 1);
- return true;
- }
-
- /** Call any 9-param 1-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
- typename ArgT7, typename ArgT8, typename ArgT9, typename RetT1
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, ArgT9 a_Arg9, const cRet & a_Mark, RetT1 & a_Ret1)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- Push(a_Arg4);
- Push(a_Arg5);
- Push(a_Arg6);
- Push(a_Arg7);
- Push(a_Arg8);
- Push(a_Arg9);
- if (!CallFunction(1))
- {
- return false;
- }
- GetStackValue(-1, a_Ret1);
- lua_pop(m_LuaState, 1);
- return true;
- }
-
- /** Call any 10-param 1-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
- typename ArgT7, typename ArgT8, typename ArgT9, typename ArgT10, typename RetT1
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, ArgT9 a_Arg9, ArgT10 a_Arg10, const cRet & a_Mark, RetT1 & a_Ret1)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- Push(a_Arg4);
- Push(a_Arg5);
- Push(a_Arg6);
- Push(a_Arg7);
- Push(a_Arg8);
- Push(a_Arg9);
- Push(a_Arg10);
- if (!CallFunction(1))
- {
- return false;
- }
- GetStackValue(-1, a_Ret1);
- lua_pop(m_LuaState, 1);
- return true;
- }
-
- /** Call any 1-param 2-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename RetT1, typename RetT2
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- if (!CallFunction(2))
- {
- return false;
- }
- GetStackValue(-2, a_Ret1);
- GetStackValue(-1, a_Ret2);
- lua_pop(m_LuaState, 2);
- return true;
- }
-
- /** Call any 2-param 2-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename RetT1, typename RetT2
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- if (!CallFunction(2))
- {
- return false;
- }
- GetStackValue(-2, a_Ret1);
- GetStackValue(-1, a_Ret2);
- lua_pop(m_LuaState, 2);
- return true;
- }
-
- /** Call any 3-param 2-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3,
- typename RetT1, typename RetT2
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- if (!CallFunction(2))
- {
- return false;
- }
- GetStackValue(-2, a_Ret1);
- GetStackValue(-1, a_Ret2);
- lua_pop(m_LuaState, 2);
- return true;
- }
-
- /** Call any 4-param 2-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4,
- typename RetT1, typename RetT2
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- Push(a_Arg4);
- if (!CallFunction(2))
- {
- return false;
- }
- GetStackValue(-2, a_Ret1);
- GetStackValue(-1, a_Ret2);
- lua_pop(m_LuaState, 2);
- return true;
- }
-
- /** Call any 5-param 2-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
- typename RetT1, typename RetT2
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- Push(a_Arg4);
- Push(a_Arg5);
- if (!CallFunction(2))
- {
- return false;
- }
- GetStackValue(-2, a_Ret1);
- GetStackValue(-1, a_Ret2);
- lua_pop(m_LuaState, 2);
- return true;
- }
-
- /** Call any 6-param 2-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
- typename ArgT6,
- typename RetT1, typename RetT2
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- Push(a_Arg4);
- Push(a_Arg5);
- Push(a_Arg6);
- if (!CallFunction(2))
- {
- return false;
- }
- GetStackValue(-2, a_Ret1);
- GetStackValue(-1, a_Ret2);
- lua_pop(m_LuaState, 2);
- return true;
- }
-
- /** Call any 7-param 2-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
- typename ArgT6, typename ArgT7,
- typename RetT1, typename RetT2
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- Push(a_Arg4);
- Push(a_Arg5);
- Push(a_Arg6);
- Push(a_Arg7);
- if (!CallFunction(2))
- {
- return false;
- }
- GetStackValue(-2, a_Ret1);
- GetStackValue(-1, a_Ret2);
- lua_pop(m_LuaState, 2);
- return true;
- }
-
- /** Call any 7-param 3-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
- typename ArgT6, typename ArgT7,
- typename RetT1, typename RetT2, typename RetT3
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- Push(a_Arg4);
- Push(a_Arg5);
- Push(a_Arg6);
- Push(a_Arg7);
- if (!CallFunction(3))
- {
- return false;
- }
- GetStackValue(-3, a_Ret1);
- GetStackValue(-2, a_Ret2);
- GetStackValue(-1, a_Ret3);
- lua_pop(m_LuaState, 3);
- return true;
- }
-
- /** Call any 8-param 3-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
- typename ArgT6, typename ArgT7, typename ArgT8,
- typename RetT1, typename RetT2, typename RetT3
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- Push(a_Arg4);
- Push(a_Arg5);
- Push(a_Arg6);
- Push(a_Arg7);
- Push(a_Arg8);
- if (!CallFunction(3))
- {
- return false;
- }
- GetStackValue(-3, a_Ret1);
- GetStackValue(-2, a_Ret2);
- GetStackValue(-1, a_Ret3);
- lua_pop(m_LuaState, 3);
- return true;
- }
-
- /** Call any 9-param 5-return Lua function in a single line: */
- template<
- typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
- typename ArgT6, typename ArgT7, typename ArgT8, typename ArgT9,
- typename RetT1, typename RetT2, typename RetT3, typename RetT4, typename RetT5
- >
- bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, ArgT9 a_Arg9, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3, RetT4 & a_Ret4, RetT5 & a_Ret5)
- {
- UNUSED(a_Mark);
- if (!PushFunction(a_FnName))
- {
- return false;
- }
- Push(a_Arg1);
- Push(a_Arg2);
- Push(a_Arg3);
- Push(a_Arg4);
- Push(a_Arg5);
- Push(a_Arg6);
- Push(a_Arg7);
- Push(a_Arg8);
- Push(a_Arg9);
- if (!CallFunction(5))
- {
- return false;
- }
- GetStackValue(-5, a_Ret1);
- GetStackValue(-4, a_Ret2);
- GetStackValue(-3, a_Ret3);
- GetStackValue(-2, a_Ret4);
- GetStackValue(-1, a_Ret5);
- lua_pop(m_LuaState, 5);
- return true;
- }
+ // Include the cLuaState::Call() overload implementation that is generated by the gen_LuaState_Call.lua script:
+ #include "LuaState_Call.inc"
/** Returns true if the specified parameters on the stack are of the specified usertable type; also logs warning if not. Used for static functions */
diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp
index acfd6f4f8..88d40bfd9 100644
--- a/src/Bindings/ManualBindings.cpp
+++ b/src/Bindings/ManualBindings.cpp
@@ -4,7 +4,7 @@
#include "ManualBindings.h"
#undef TOLUA_TEMPLATE_BIND
#include "tolua++/include/tolua++.h"
-
+#include "polarssl/md5.h"
#include "Plugin.h"
#include "PluginLua.h"
#include "PluginManager.h"
@@ -25,7 +25,6 @@
#include "../BlockEntities/NoteEntity.h"
#include "../BlockEntities/MobHeadEntity.h"
#include "../BlockEntities/FlowerPotEntity.h"
-#include "md5/md5.h"
#include "../LineBlockTracer.h"
#include "../WorldStorage/SchematicFileSerializer.h"
#include "../CompositeChat.h"
@@ -1765,6 +1764,7 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S)
if (!ChunkStay->AddChunks(2))
{
delete ChunkStay;
+ ChunkStay = NULL;
return 0;
}
@@ -2000,9 +2000,11 @@ static int tolua_cPlugin_Call(lua_State * tolua_S)
static int tolua_md5(lua_State* tolua_S)
{
- std::string SourceString = tolua_tostring(tolua_S, 1, 0);
- std::string CryptedString = md5( SourceString );
- tolua_pushstring( tolua_S, CryptedString.c_str() );
+ unsigned char Output[16];
+ size_t len = 0;
+ const unsigned char * SourceString = (const unsigned char *)lua_tolstring(tolua_S, 1, &len);
+ md5(SourceString, len, Output);
+ lua_pushlstring(tolua_S, (const char *)Output, ARRAYCOUNT(Output));
return 1;
}
diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h
index 2e02cba54..dabe8debb 100644
--- a/src/Bindings/Plugin.h
+++ b/src/Bindings/Plugin.h
@@ -73,6 +73,7 @@ public:
virtual bool OnPlayerEating (cPlayer & a_Player) = 0;
virtual bool OnPlayerFished (cPlayer & a_Player, const cItems & a_Reward) = 0;
virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) = 0;
+ virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) = 0;
virtual bool OnPlayerJoined (cPlayer & a_Player) = 0;
virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) = 0;
virtual bool OnPlayerMoved (cPlayer & a_Player) = 0;
diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp
index 09ffa6064..e10cca708 100644
--- a/src/Bindings/PluginLua.cpp
+++ b/src/Bindings/PluginLua.cpp
@@ -735,6 +735,26 @@ bool cPluginLua::OnPlayerEating(cPlayer & a_Player)
+bool cPluginLua::OnPlayerFoodLevelChange(cPlayer & a_Player, int a_NewFoodLevel)
+{
+ cCSLock Lock(m_CriticalSection);
+ bool res = false;
+ cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_FOOD_LEVEL_CHANGE];
+ for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
+ {
+ m_LuaState.Call((int)(**itr), &a_Player, a_NewFoodLevel, cLuaState::Return, res);
+ if (res)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
+
bool cPluginLua::OnPlayerFished(cPlayer & a_Player, const cItems & a_Reward)
{
cCSLock Lock(m_CriticalSection);
@@ -1347,18 +1367,15 @@ bool cPluginLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather)
{
cCSLock Lock(m_CriticalSection);
bool res = false;
- int NewWeather = a_NewWeather;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_WEATHER_CHANGING];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{
- m_LuaState.Call((int)(**itr), &a_World, NewWeather, cLuaState::Return, res, NewWeather);
+ m_LuaState.Call((int)(**itr), &a_World, a_NewWeather, cLuaState::Return, res, a_NewWeather);
if (res)
{
- a_NewWeather = (eWeather)NewWeather;
return true;
}
}
- a_NewWeather = (eWeather)NewWeather;
return false;
}
@@ -1592,6 +1609,7 @@ bool cPluginLua::AddHookRef(int a_HookType, int a_FnRefIdx)
LOGWARNING("Plugin %s tried to add a hook %d with bad handler function.", GetName().c_str(), a_HookType);
m_LuaState.LogStackTrace();
delete Ref;
+ Ref = NULL;
return false;
}
@@ -1734,7 +1752,7 @@ bool cPluginLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer
ASSERT(a_FnRef != LUA_REFNIL);
cCSLock Lock(m_CriticalSection);
- bool res;
+ bool res = false;
m_LuaState.Call(a_FnRef, &a_Window, &a_Player, a_CanRefuse, cLuaState::Return, res);
return res;
}
diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h
index d0dcfb011..94371c830 100644
--- a/src/Bindings/PluginLua.h
+++ b/src/Bindings/PluginLua.h
@@ -96,6 +96,7 @@ public:
virtual bool OnPlayerEating (cPlayer & a_Player) override;
virtual bool OnPlayerFished (cPlayer & a_Player, const cItems & a_Reward) override;
virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) override;
+ virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) override;
virtual bool OnPlayerJoined (cPlayer & a_Player) override;
virtual bool OnPlayerMoved (cPlayer & a_Player) override;
virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) override;
diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp
index d332980bd..c80344c30 100644
--- a/src/Bindings/PluginManager.cpp
+++ b/src/Bindings/PluginManager.cpp
@@ -257,18 +257,44 @@ bool cPluginManager::CallHookBlockToPickups(
bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message)
{
- bool WasCommandForbidden = false;
- if (HandleCommand(a_Player, a_Message, true, WasCommandForbidden)) // We use HandleCommand as opposed to ExecuteCommand to accomodate the need to the WasCommandForbidden bool
+ // Check if the message contains a command, execute it:
+ switch (HandleCommand(a_Player, a_Message, true))
{
- return true; // Chat message was handled as command
- }
- else if (WasCommandForbidden) // Couldn't be handled as command, was it because of insufficient permissions?
- {
- return true; // Yes - message was sent in HandleCommand, abort
+ case crExecuted:
+ {
+ // The command has executed successfully
+ return true;
+ }
+
+ case crBlocked:
+ {
+ // The command was blocked by a plugin using HOOK_EXECUTE_COMMAND
+ // The plugin has most likely sent a message to the player already
+ return true;
+ }
+
+ case crError:
+ {
+ // An error in the plugin has prevented the command from executing. Report the error to the player:
+ a_Player->SendMessageFailure(Printf("Something went wrong while executing command \"%s\"", a_Message.c_str()));
+ return true;
+ }
+
+ case crNoPermission:
+ {
+ // The player is not allowed to execute this command
+ a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", a_Message.c_str()));
+ return true;
+ }
+
+ case crUnknownCommand:
+ {
+ // This was not a known command, keep processing as a message
+ break;
+ }
}
- // Check if it was a standard command (starts with a slash)
- // If it was, we know that it was completely unrecognised (WasCommandForbidden == false)
+ // Check if the message is a command (starts with a slash). If it is, we know that it wasn't recognised:
if (!a_Message.empty() && (a_Message[0] == '/'))
{
AStringVector Split(StringSplit(a_Message, " "));
@@ -716,6 +742,25 @@ bool cPluginManager::CallHookPlayerEating(cPlayer & a_Player)
+bool cPluginManager::CallHookPlayerFoodLevelChange(cPlayer & a_Player, int a_NewFoodLevel)
+{
+ FIND_HOOK(HOOK_PLAYER_FOOD_LEVEL_CHANGE);
+ VERIFY_HOOK;
+
+ for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
+ {
+ if ((*itr)->OnPlayerFoodLevelChange(a_Player, a_NewFoodLevel))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
+
bool cPluginManager::CallHookPlayerFished(cPlayer & a_Player, const cItems a_Reward)
{
FIND_HOOK(HOOK_PLAYER_FISHED);
@@ -1339,28 +1384,28 @@ bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt, int a_LastT
-bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions, bool & a_WasCommandForbidden)
+cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions)
{
ASSERT(a_Player != NULL);
AStringVector Split(StringSplit(a_Command, " "));
if (Split.empty())
{
- return false;
+ return crUnknownCommand;
}
CommandMap::iterator cmd = m_Commands.find(Split[0]);
if (cmd == m_Commands.end())
{
// Command not found
- return false;
+ return crUnknownCommand;
}
// Ask plugins first if a command is okay to execute the command:
if (CallHookExecuteCommand(a_Player, Split))
{
LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player->GetName().c_str(), Split[0].c_str());
- return false;
+ return crBlocked;
}
if (
@@ -1369,15 +1414,18 @@ bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command
!a_Player->HasPermission(cmd->second.m_Permission)
)
{
- a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", Split[0].c_str()));
LOGINFO("Player %s tried to execute forbidden command: \"%s\"", a_Player->GetName().c_str(), Split[0].c_str());
- a_WasCommandForbidden = true;
- return false;
+ return crNoPermission;
}
ASSERT(cmd->second.m_Plugin != NULL);
- return cmd->second.m_Plugin->HandleCommand(Split, a_Player);
+ if (!cmd->second.m_Plugin->HandleCommand(Split, a_Player))
+ {
+ return crError;
+ }
+
+ return crExecuted;
}
@@ -1488,6 +1536,7 @@ void cPluginManager::RemovePlugin(cPlugin * a_Plugin)
a_Plugin->OnDisable();
}
delete a_Plugin;
+ a_Plugin = NULL;
}
@@ -1574,7 +1623,7 @@ AString cPluginManager::GetCommandPermission(const AString & a_Command)
-bool cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Command)
+cPluginManager::CommandResult cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Command)
{
return HandleCommand(a_Player, a_Command, true);
}
@@ -1583,7 +1632,7 @@ bool cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Comman
-bool cPluginManager::ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command)
+cPluginManager::CommandResult cPluginManager::ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command)
{
return HandleCommand(a_Player, a_Command, false);
}
diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h
index 4bd6b4837..4d5a350d4 100644
--- a/src/Bindings/PluginManager.h
+++ b/src/Bindings/PluginManager.h
@@ -57,8 +57,17 @@ public: // tolua_export
// Called each tick
virtual void Tick(float a_Dt);
-
+
// tolua_begin
+ enum CommandResult
+ {
+ crExecuted,
+ crUnknownCommand,
+ crError,
+ crBlocked,
+ crNoPermission,
+ } ;
+
enum PluginHook
{
HOOK_BLOCK_SPREAD,
@@ -88,6 +97,7 @@ public: // tolua_export
HOOK_PLAYER_EATING,
HOOK_PLAYER_FISHED,
HOOK_PLAYER_FISHING,
+ HOOK_PLAYER_FOOD_LEVEL_CHANGE,
HOOK_PLAYER_JOINED,
HOOK_PLAYER_LEFT_CLICK,
HOOK_PLAYER_MOVING,
@@ -190,6 +200,7 @@ public: // tolua_export
bool CallHookPlayerEating (cPlayer & a_Player);
bool CallHookPlayerFished (cPlayer & a_Player, const cItems a_Reward);
bool CallHookPlayerFishing (cPlayer & a_Player, cItems a_Reward);
+ bool CallHookPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel);
bool CallHookPlayerJoined (cPlayer & a_Player);
bool CallHookPlayerMoving (cPlayer & a_Player);
bool CallHookPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status);
@@ -246,11 +257,11 @@ public: // tolua_export
/** Returns the permission needed for the specified command; empty string if command not found */
AString GetCommandPermission(const AString & a_Command); // tolua_export
- /** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns true if executed. */
- bool ExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export
+ /** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns crExecuted if executed. */
+ CommandResult ExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export
- /** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns true if executed (false if not found) */
- bool ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export
+ /** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns crExecuted if executed. */
+ CommandResult ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export
/** Removes all console command bindings that the specified plugin has made */
void RemovePluginConsoleCommands(cPlugin * a_Plugin);
@@ -323,13 +334,8 @@ private:
/** Adds the plugin into the internal list of plugins and initializes it. If initialization fails, the plugin is removed again. */
bool AddPlugin(cPlugin * a_Plugin);
- /** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns true if the command is handled. */
- bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions, bool & a_WasCommandForbidden);
- bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions)
- {
- bool DummyBoolean = false;
- return HandleCommand(a_Player, a_Command, a_ShouldCheckPermissions, DummyBoolean);
- }
+ /** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns crExecuted if the command is executed. */
+ cPluginManager::CommandResult HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions);
} ; // tolua_export
diff --git a/src/Bindings/gen_LuaState_Call.lua b/src/Bindings/gen_LuaState_Call.lua
new file mode 100644
index 000000000..fb1797dc0
--- /dev/null
+++ b/src/Bindings/gen_LuaState_Call.lua
@@ -0,0 +1,196 @@
+
+-- gen_LuaState_Call.lua
+
+-- Generates the cLuaState::Call() function templates that are included from LuaState.h
+
+--[[
+The cLuaState::Call() family of functions provides a template-based system for calling any Lua function
+either by name or by reference with almost any number of parameters and return values. This is done by
+providing a number of overloads of the same name with variable number of template-type parameters. To
+separate the arguments from the return values, a special type of cLuaState::cRet is used.
+--]]
+
+
+
+
+print("Generating LuaState_Call.inc...")
+
+
+
+
+-- List of combinations (# params, # returns) to generate:
+local Combinations =
+{
+ -- no return values:
+ {0, 0},
+ {1, 0},
+ {2, 0},
+ {3, 0},
+ {4, 0},
+
+ -- 1 return value:
+ {0, 1},
+ {1, 1},
+ {2, 1},
+ {3, 1},
+ {4, 1},
+ {5, 1},
+ {6, 1},
+ {7, 1},
+ {8, 1},
+ {9, 1},
+ {10, 1},
+
+ -- 2 return values:
+ {0, 2},
+ {1, 2},
+ {2, 2},
+ {3, 2},
+ {4, 2},
+ {5, 2},
+ {6, 2},
+ {7, 2},
+ {8, 2},
+ {9, 2},
+
+ -- Special combinations:
+ {7, 3},
+ {8, 3},
+ {9, 5},
+}
+
+
+
+
+--- Writes a single overloaded function definition for the specified number of params and returns into f
+--[[
+The format for the generated function is this:
+/** Call the specified 3-param 2-return Lua function:
+Returns true if call succeeded, false if there was an error. */
+template <typename FnT, typename ParamT1, typename ParamT2, typename ParamT3, typename RetT1, typename RetT2>
+bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2)
+{
+ UNUSED(a_RetMark);
+ if (!PushFunction(a_Function))
+ {
+ return false;
+ }
+ Push(a_Param1);
+ Push(a_Param2);
+ Push(a_Param3);
+ if (!CallFunction(2))
+ {
+ return false;
+ }
+ GetStackValue(-2, a_Ret1);
+ GetStackValue(-1, a_Ret2);
+ lua_pop(m_LuaState, 2);
+ return true;
+}
+Note especially the negative numbers in GetStackValue() calls.
+--]]
+local function WriteOverload(f, a_NumParams, a_NumReturns)
+ -- Write the function doxy-comments:
+ f:write("/** Call the specified ", a_NumParams, "-param ", a_NumReturns, "-return Lua function:\n")
+ f:write("Returns true if call succeeded, false if there was an error. */\n")
+
+ -- Write the template <...> line:
+ f:write("template <typename FnT")
+ for i = 1, a_NumParams do
+ f:write(", typename ParamT", i)
+ end
+ if (a_NumReturns > 0) then
+ for i = 1, a_NumReturns do
+ f:write(", typename RetT", i)
+ end
+ end
+ f:write(">\n")
+
+ -- Write the function signature:
+ f:write("bool Call(")
+ f:write("FnT a_Function")
+ for i = 1, a_NumParams do
+ f:write(", ParamT", i, " a_Param", i)
+ end
+ if (a_NumReturns > 0) then
+ f:write(", const cLuaState::cRet & a_RetMark")
+ for i = 1, a_NumReturns do
+ f:write(", RetT", i, " & a_Ret", i)
+ end
+ end
+ f:write(")\n")
+
+ -- Common code:
+ f:write("{\n")
+ if (a_NumReturns > 0) then
+ f:write("\tUNUSED(a_RetMark);\n")
+ end
+ f:write("\tif (!PushFunction(a_Function))\n")
+ f:write("\t{\n")
+ f:write("\t\treturn false;\n")
+ f:write("\t}\n")
+
+ -- Push the params:
+ for i = 1, a_NumParams do
+ f:write("\tPush(a_Param", i, ");\n")
+ end
+
+ -- Call the function:
+ f:write("\tif (!CallFunction(", a_NumReturns, "))\n")
+ f:write("\t{\n")
+ f:write("\t\treturn false;\n")
+ f:write("\t}\n")
+
+ -- Get the return values:
+ for i = 1, a_NumReturns do
+ f:write("\tGetStackValue(", -1 - a_NumReturns + i, ", a_Ret", i, ");\n")
+ end
+
+ -- Pop the returns off the stack, if needed:
+ if (a_NumReturns > 0) then
+ f:write("\tlua_pop(m_LuaState, ", a_NumReturns, ");\n")
+ end
+
+ -- Everything ok:
+ f:write("\treturn true;\n")
+ f:write("}\n")
+
+ -- Separate from the next function:
+ f:write("\n\n\n\n\n")
+end
+
+
+
+
+
+local f = assert(io.open("LuaState_Call.inc", "w"))
+
+-- Write file header:
+f:write([[
+// LuaState_Call.inc
+
+// This file is auto-generated by gen_LuaState_Call.lua
+// Make changes to the generator instead of to this file!
+
+// This file contains the various overloads for the cLuaState::Call() function
+// Each overload handles a different number of parameters / return values
+]])
+f:write("\n\n\n\n\n")
+
+-- Write out a template function for each overload:
+for _, combination in ipairs(Combinations) do
+ WriteOverload(f, combination[1], combination[2])
+end
+
+-- Close the generated file
+f:close()
+
+
+
+
+
+print("LuaState_Call.inc generated")
+
+
+
+
diff --git a/src/Bindings/virtual_method_hooks.lua b/src/Bindings/virtual_method_hooks.lua
index c610d424f..8ad30bf78 100644
--- a/src/Bindings/virtual_method_hooks.lua
+++ b/src/Bindings/virtual_method_hooks.lua
@@ -3,6 +3,20 @@ local disable_virtual_hooks = true
local enable_pure_virtual = true
local default_private_access = false
+
+
+
+
+-- Code generators used by the build
+-- Note that these are not exactly needed for the bindings, but rather we
+-- misuse tolua's Lua engine to process files for us
+dofile("gen_LuaState_Call.lua")
+
+
+
+
+
+
local access = {public = 0, protected = 1, private = 2}
function preparse_hook(p)
diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp
index 4fe6cd51e..185582ba3 100644
--- a/src/BlockArea.cpp
+++ b/src/BlockArea.cpp
@@ -295,9 +295,9 @@ cBlockArea::~cBlockArea()
void cBlockArea::Clear(void)
{
- delete[] m_BlockTypes; m_BlockTypes = NULL;
- delete[] m_BlockMetas; m_BlockMetas = NULL;
- delete[] m_BlockLight; m_BlockLight = NULL;
+ delete[] m_BlockTypes; m_BlockTypes = NULL;
+ delete[] m_BlockMetas; m_BlockMetas = NULL;
+ delete[] m_BlockLight; m_BlockLight = NULL;
delete[] m_BlockSkyLight; m_BlockSkyLight = NULL;
m_Origin.Set(0, 0, 0);
m_Size.Set(0, 0, 0);
@@ -1013,8 +1013,8 @@ void cBlockArea::RotateCCW(void)
} // for x
std::swap(m_BlockTypes, NewTypes);
std::swap(m_BlockMetas, NewMetas);
- delete[] NewTypes;
- delete[] NewMetas;
+ delete[] NewTypes; NewTypes = NULL;
+ delete[] NewMetas; NewMetas = NULL;
std::swap(m_Size.x, m_Size.z);
}
@@ -1058,8 +1058,8 @@ void cBlockArea::RotateCW(void)
} // for x
std::swap(m_BlockTypes, NewTypes);
std::swap(m_BlockMetas, NewMetas);
- delete[] NewTypes;
- delete[] NewMetas;
+ delete[] NewTypes; NewTypes = NULL;
+ delete[] NewMetas; NewMetas = NULL;
std::swap(m_Size.x, m_Size.z);
}
@@ -1206,7 +1206,7 @@ void cBlockArea::RotateCCWNoMeta(void)
} // for z
} // for x
std::swap(m_BlockTypes, NewTypes);
- delete[] NewTypes;
+ delete[] NewTypes; NewTypes = NULL;
}
if (HasBlockMetas())
{
@@ -1224,7 +1224,7 @@ void cBlockArea::RotateCCWNoMeta(void)
} // for z
} // for x
std::swap(m_BlockMetas, NewMetas);
- delete[] NewMetas;
+ delete[] NewMetas; NewMetas = NULL;
}
std::swap(m_Size.x, m_Size.z);
}
@@ -1251,7 +1251,7 @@ void cBlockArea::RotateCWNoMeta(void)
} // for x
} // for z
std::swap(m_BlockTypes, NewTypes);
- delete[] NewTypes;
+ delete[] NewTypes; NewTypes = NULL;
}
if (HasBlockMetas())
{
@@ -1269,7 +1269,7 @@ void cBlockArea::RotateCWNoMeta(void)
} // for x
} // for z
std::swap(m_BlockMetas, NewMetas);
- delete[] NewMetas;
+ delete[] NewMetas; NewMetas = NULL;
}
std::swap(m_Size.x, m_Size.z);
}
@@ -1658,6 +1658,7 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
if (m_BlockMetas == NULL)
{
delete[] m_BlockTypes;
+ m_BlockTypes = NULL;
return false;
}
}
@@ -1667,7 +1668,9 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
if (m_BlockLight == NULL)
{
delete[] m_BlockMetas;
+ m_BlockMetas = NULL;
delete[] m_BlockTypes;
+ m_BlockTypes = NULL;
return false;
}
}
@@ -1677,8 +1680,11 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
if (m_BlockSkyLight == NULL)
{
delete[] m_BlockLight;
+ m_BlockLight = NULL;
delete[] m_BlockMetas;
+ m_BlockMetas = NULL;
delete[] m_BlockTypes;
+ m_BlockTypes = NULL;
return false;
}
}
diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp
index dfbe6ae87..cb9cc89bf 100644
--- a/src/BlockEntities/ChestEntity.cpp
+++ b/src/BlockEntities/ChestEntity.cpp
@@ -122,6 +122,13 @@ void cChestEntity::UsedBy(cPlayer * a_Player)
void cChestEntity::OpenNewWindow(void)
{
+ // TODO: cats are an obstruction
+ if ((GetPosY() + 1 < cChunkDef::Height) && cBlockInfo::IsSolid(GetWorld()->GetBlock(GetPosX(), GetPosY() + 1, GetPosZ())))
+ {
+ // Obstruction, don't open
+ return;
+ }
+
// Callback for opening together with neighbor chest:
class cOpenDouble :
public cChestCallback
@@ -135,6 +142,12 @@ void cChestEntity::OpenNewWindow(void)
virtual bool Item(cChestEntity * a_Chest) override
{
+ if ((a_Chest->GetPosY() + 1 < cChunkDef::Height) && cBlockInfo::IsSolid(a_Chest->GetWorld()->GetBlock(a_Chest->GetPosX(), a_Chest->GetPosY() + 1, a_Chest->GetPosZ())))
+ {
+ // Obstruction, don't open
+ return false;
+ }
+
// The primary chest should eb the one with lesser X or Z coord:
cChestEntity * Primary = a_Chest;
cChestEntity * Secondary = m_ThisChest;
diff --git a/src/BlockEntities/EnderChestEntity.cpp b/src/BlockEntities/EnderChestEntity.cpp
index e53930798..17816d63e 100644
--- a/src/BlockEntities/EnderChestEntity.cpp
+++ b/src/BlockEntities/EnderChestEntity.cpp
@@ -12,9 +12,8 @@
cEnderChestEntity::cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
- super(E_BLOCK_ENDER_CHEST, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World)
+ super(E_BLOCK_ENDER_CHEST, a_BlockX, a_BlockY, a_BlockZ, a_World)
{
- cBlockEntityWindowOwner::SetBlockEntity(this);
}
@@ -34,95 +33,63 @@ cEnderChestEntity::~cEnderChestEntity()
-bool cEnderChestEntity::LoadFromJson(const Json::Value & a_Value)
+void cEnderChestEntity::UsedBy(cPlayer * a_Player)
{
- m_PosX = a_Value.get("x", 0).asInt();
- m_PosY = a_Value.get("y", 0).asInt();
- m_PosZ = a_Value.get("z", 0).asInt();
-
- Json::Value AllSlots = a_Value.get("Slots", 0);
- int SlotIdx = 0;
- for (Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr)
+ // If the window is not created, open it anew:
+ cWindow * Window = GetWindow();
+ if (Window == NULL)
{
- cItem Item;
- Item.FromJson(*itr);
- SetSlot(SlotIdx, Item);
- SlotIdx++;
+ OpenNewWindow();
+ Window = GetWindow();
}
- return true;
-}
-
-
-
-
-
-void cEnderChestEntity::SaveToJson(Json::Value & a_Value)
-{
- a_Value["x"] = m_PosX;
- a_Value["y"] = m_PosY;
- a_Value["z"] = m_PosZ;
-
- Json::Value AllSlots;
- for (int i = m_Contents.GetNumSlots() - 1; i >= 0; i--)
+
+ // Open the window for the player:
+ if (Window != NULL)
{
- Json::Value Slot;
- m_Contents.GetSlot(i).GetJson(Slot);
- AllSlots.append(Slot);
+ if (a_Player->GetWindow() != Window)
+ {
+ a_Player->OpenWindow(Window);
+ }
}
- a_Value["Slots"] = AllSlots;
}
-void cEnderChestEntity::SendTo(cClientHandle & a_Client)
+void cEnderChestEntity::OpenNewWindow()
{
- // The chest entity doesn't need anything sent to the client when it's created / gets in the viewdistance
- // All the actual handling is in the cWindow UI code that gets called when the chest is rclked
-
- UNUSED(a_Client);
+ OpenWindow(new cEnderChestWindow(this));
}
-void cEnderChestEntity::UsedBy(cPlayer * a_Player)
+void cEnderChestEntity::LoadFromJson(const Json::Value & a_Value, cItemGrid & a_Grid)
{
- // If the window is not created, open it anew:
- cWindow * Window = GetWindow();
- if (Window == NULL)
- {
- OpenNewWindow();
- Window = GetWindow();
- }
-
- // Open the window for the player:
- if (Window != NULL)
+ int SlotIdx = 0;
+ for (Json::Value::iterator itr = a_Value.begin(); itr != a_Value.end(); ++itr)
{
- if (a_Player->GetWindow() != Window)
- {
- a_Player->OpenWindow(Window);
- }
+ cItem Item;
+ Item.FromJson(*itr);
+ a_Grid.SetSlot(SlotIdx, Item);
+ SlotIdx++;
}
-
- // This is rather a hack
- // Instead of marking the chunk as dirty upon chest contents change, we mark it dirty now
- // We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first.
- // The few false positives aren't much to worry about
- int ChunkX, ChunkZ;
- cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ);
- m_World->MarkChunkDirty(ChunkX, ChunkZ);
}
-void cEnderChestEntity::OpenNewWindow(void)
+void cEnderChestEntity::SaveToJson(Json::Value & a_Value, const cItemGrid & a_Grid)
{
- OpenWindow(new cEnderChestWindow(this));
+ for (int i = 0; i < a_Grid.GetNumSlots(); i++)
+ {
+ Json::Value Slot;
+ a_Grid.GetSlot(i).GetJson(Slot);
+ a_Value.append(Slot);
+ }
}
diff --git a/src/BlockEntities/EnderChestEntity.h b/src/BlockEntities/EnderChestEntity.h
index 45beee45f..04af67683 100644
--- a/src/BlockEntities/EnderChestEntity.h
+++ b/src/BlockEntities/EnderChestEntity.h
@@ -1,20 +1,9 @@
#pragma once
-#include "BlockEntityWithItems.h"
-
-
-
-
-
-namespace Json
-{
- class Value;
-};
-
-class cClientHandle;
-class cServer;
-class cNBTData;
+#include "BlockEntity.h"
+#include "UI/WindowOwner.h"
+#include "json/json.h"
@@ -22,33 +11,28 @@ class cNBTData;
// tolua_begin
class cEnderChestEntity :
- public cBlockEntityWithItems
+ public cBlockEntity,
+ public cBlockEntityWindowOwner
{
- typedef cBlockEntityWithItems super;
-
-public:
- enum {
- ContentsHeight = 3,
- ContentsWidth = 9,
- } ;
+ typedef cBlockEntity super;
+public:
// tolua_end
- /// Constructor used for normal operation
- cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
-
+ cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
virtual ~cEnderChestEntity();
static const char * GetClassStatic(void) { return "cEnderChestEntity"; }
-
- bool LoadFromJson(const Json::Value & a_Value);
// cBlockEntity overrides:
- virtual void SaveToJson(Json::Value & a_Value) override;
- virtual void SendTo(cClientHandle & a_Client) override;
virtual void UsedBy(cPlayer * a_Player) override;
+ virtual void SaveToJson(Json::Value & a_Value) override { UNUSED(a_Value); }
+ virtual void SendTo(cClientHandle & a_Client) override { UNUSED(a_Client); }
+
+ static void LoadFromJson(const Json::Value & a_Value, cItemGrid & a_Grid);
+ static void SaveToJson(Json::Value & a_Value, const cItemGrid & a_Grid);
- /// Opens a new chest window for this chest. Scans for neighbors to open a double chest window, if appropriate.
+ /** Opens a new enderchest window for this enderchest */
void OpenNewWindow(void);
} ; // tolua_export
diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp
index 7f001c739..5856f20d1 100644
--- a/src/BlockEntities/HopperEntity.cpp
+++ b/src/BlockEntities/HopperEntity.cpp
@@ -294,23 +294,24 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
return false;
}
- int bx, by, bz;
+ // Get the coords of the block where to output items:
+ int OutX, OutY, OutZ;
NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ);
- if (!GetOutputBlockPos(Meta, bx, by, bz))
+ if (!GetOutputBlockPos(Meta, OutX, OutY, OutZ))
{
// Not attached to another container
return false;
}
- if (by < 0)
+ if (OutY < 0)
{
// Cannot output below the zero-th block level
return false;
}
// Convert coords to relative:
- int rx = bx - a_Chunk.GetPosX() * cChunkDef::Width;
- int rz = bz - a_Chunk.GetPosZ() * cChunkDef::Width;
- cChunk * DestChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(rx, rz);
+ int OutRelX = OutX - a_Chunk.GetPosX() * cChunkDef::Width;
+ int OutRelZ = OutZ - a_Chunk.GetPosZ() * cChunkDef::Width;
+ cChunk * DestChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(OutRelX, OutRelZ);
if (DestChunk == NULL)
{
// The destination chunk has been unloaded, don't tick
@@ -319,26 +320,32 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
// Call proper moving function, based on the blocktype present at the coords:
bool res = false;
- switch (DestChunk->GetBlock(rx, by, rz))
+ switch (DestChunk->GetBlock(OutRelX, OutY, OutRelZ))
{
case E_BLOCK_CHEST:
{
// Chests have special handling because of double-chests
- res = MoveItemsToChest(*DestChunk, bx, by, bz);
+ res = MoveItemsToChest(*DestChunk, OutX, OutY, OutZ);
break;
}
case E_BLOCK_LIT_FURNACE:
case E_BLOCK_FURNACE:
{
// Furnaces have special handling because of the direction-to-slot relation
- res = MoveItemsToFurnace(*DestChunk, bx, by, bz, Meta);
+ res = MoveItemsToFurnace(*DestChunk, OutX, OutY, OutZ, Meta);
break;
}
case E_BLOCK_DISPENSER:
case E_BLOCK_DROPPER:
case E_BLOCK_HOPPER:
{
- res = MoveItemsToGrid(*(cBlockEntityWithItems *)DestChunk->GetBlockEntity(bx, by, bz));
+ cBlockEntityWithItems * BlockEntity = (cBlockEntityWithItems *)DestChunk->GetBlockEntity(OutX, OutY, OutZ);
+ if (BlockEntity == NULL)
+ {
+ LOGWARNING("%s: A block entity was not found where expected at {%d, %d, %d}", __FUNCTION__, OutX, OutY, OutZ);
+ return false;
+ }
+ res = MoveItemsToGrid(*BlockEntity);
break;
}
}
@@ -359,7 +366,13 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
/// Moves items from a chest (dblchest) above the hopper into this hopper. Returns true if contents have changed.
bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
{
- if (MoveItemsFromGrid(*(cChestEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ)))
+ cChestEntity * Chest = (cChestEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ);
+ if (Chest == NULL)
+ {
+ LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX, m_PosY + 1, m_PosZ);
+ return false;
+ }
+ if (MoveItemsFromGrid(*Chest))
{
// Moved the item from the chest directly above the hopper
return true;
@@ -389,9 +402,17 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
{
continue;
}
- if (MoveItemsFromGrid(*(cChestEntity *)Neighbor->GetBlockEntity(x, m_PosY, z)))
+ Chest = (cChestEntity *)Neighbor->GetBlockEntity(m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z);
+ if (Chest == NULL)
{
- return true;
+ LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z);
+ }
+ else
+ {
+ if (MoveItemsFromGrid(*Chest))
+ {
+ return true;
+ }
}
return false;
}
@@ -408,7 +429,11 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk)
{
cFurnaceEntity * Furnace = (cFurnaceEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ);
- ASSERT(Furnace != NULL);
+ if (Furnace == NULL)
+ {
+ LOGWARNING("%s: A furnace entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX, m_PosY + 1, m_PosZ);
+ return false;
+ }
// Try move from the output slot:
if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsOutput, true))
@@ -517,7 +542,13 @@ bool cHopperEntity::MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_Sl
bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ)
{
// Try the chest directly connected to the hopper:
- if (MoveItemsToGrid(*(cChestEntity *)a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ)))
+ cChestEntity * Chest = (cChestEntity *)a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ);
+ if (Chest == NULL)
+ {
+ LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, a_BlockX, a_BlockY, a_BlockZ);
+ return false;
+ }
+ if (MoveItemsToGrid(*Chest))
{
return true;
}
@@ -534,19 +565,27 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block
{0, 1},
{0, -1},
} ;
+ int RelX = a_BlockX - a_Chunk.GetPosX() * cChunkDef::Width;
+ int RelZ = a_BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width;
for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
{
- int x = m_RelX + Coords[i].x;
- int z = m_RelZ + Coords[i].z;
+ int x = RelX + Coords[i].x;
+ int z = RelZ + Coords[i].z;
cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z);
if (
(Neighbor == NULL) ||
- (Neighbor->GetBlock(x, m_PosY + 1, z) != E_BLOCK_CHEST)
+ (Neighbor->GetBlock(x, a_BlockY, z) != E_BLOCK_CHEST)
)
{
continue;
}
- if (MoveItemsToGrid(*(cChestEntity *)Neighbor->GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ)))
+ Chest = (cChestEntity *)Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z);
+ if (Chest == NULL)
+ {
+ LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d} (%d, %d)", __FUNCTION__, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z, x, z);
+ continue;
+ }
+ if (MoveItemsToGrid(*Chest))
{
return true;
}
diff --git a/src/BlockEntities/MobHeadEntity.cpp b/src/BlockEntities/MobHeadEntity.cpp
index dc9c18d58..ce895eb6f 100644
--- a/src/BlockEntities/MobHeadEntity.cpp
+++ b/src/BlockEntities/MobHeadEntity.cpp
@@ -70,6 +70,8 @@ void cMobHeadEntity::SetOwner(const AString & a_Owner)
void cMobHeadEntity::SendTo(cClientHandle & a_Client)
{
+ cWorld * World = a_Client.GetPlayer()->GetWorld();
+ a_Client.SendBlockChange(m_PosX, m_PosY, m_PosZ, m_BlockType, World->GetBlockMeta(m_PosX, m_PosY, m_PosZ));
a_Client.SendUpdateBlockEntity(*this);
}
diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp
index 564b3fcca..9a953e396 100644
--- a/src/BlockInfo.cpp
+++ b/src/BlockInfo.cpp
@@ -8,12 +8,6 @@
-cBlockInfo cBlockInfo::ms_Info[256];
-
-
-
-
-
cBlockInfo::cBlockInfo()
: m_LightValue(0x00)
, m_SpreadLightFalloff(0x0f)
@@ -34,14 +28,25 @@ cBlockInfo::cBlockInfo()
cBlockInfo::~cBlockInfo()
{
delete m_Handler;
+ m_Handler = NULL;
}
+/** This accessor makes sure that the cBlockInfo structures are properly initialized exactly once.
+It does so by using the C++ singleton approximation - storing the actual singleton as the function's static variable.
+It works only if it is called for the first time before the app spawns other threads. */
cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type)
{
+ static cBlockInfo ms_Info[256];
+ static bool IsBlockInfoInitialized = false;
+ if (!IsBlockInfoInitialized)
+ {
+ cBlockInfo::Initialize(ms_Info);
+ IsBlockInfoInitialized = true;
+ }
return ms_Info[a_Type];
}
@@ -49,416 +54,409 @@ cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type)
-void cBlockInfo::Initialize(void)
+void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
{
for (unsigned int i = 0; i < 256; ++i)
{
- if (ms_Info[i].m_Handler == NULL)
+ if (a_Info[i].m_Handler == NULL)
{
- ms_Info[i].m_Handler = cBlockHandler::CreateBlockHandler((BLOCKTYPE) i);
+ a_Info[i].m_Handler = cBlockHandler::CreateBlockHandler((BLOCKTYPE) i);
}
}
// Emissive blocks
- ms_Info[E_BLOCK_FIRE ].m_LightValue = 15;
- ms_Info[E_BLOCK_GLOWSTONE ].m_LightValue = 15;
- ms_Info[E_BLOCK_JACK_O_LANTERN ].m_LightValue = 15;
- ms_Info[E_BLOCK_LAVA ].m_LightValue = 15;
- ms_Info[E_BLOCK_STATIONARY_LAVA ].m_LightValue = 15;
- ms_Info[E_BLOCK_END_PORTAL ].m_LightValue = 15;
- ms_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_LightValue = 15;
- ms_Info[E_BLOCK_TORCH ].m_LightValue = 14;
- ms_Info[E_BLOCK_BURNING_FURNACE ].m_LightValue = 13;
- ms_Info[E_BLOCK_NETHER_PORTAL ].m_LightValue = 11;
- ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_LightValue = 9;
- ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_LightValue = 9;
- ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_LightValue = 7;
- ms_Info[E_BLOCK_BREWING_STAND ].m_LightValue = 1;
- ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_LightValue = 1;
- ms_Info[E_BLOCK_DRAGON_EGG ].m_LightValue = 1;
+ a_Info[E_BLOCK_FIRE ].m_LightValue = 15;
+ a_Info[E_BLOCK_GLOWSTONE ].m_LightValue = 15;
+ a_Info[E_BLOCK_JACK_O_LANTERN ].m_LightValue = 15;
+ a_Info[E_BLOCK_LAVA ].m_LightValue = 15;
+ a_Info[E_BLOCK_STATIONARY_LAVA ].m_LightValue = 15;
+ a_Info[E_BLOCK_END_PORTAL ].m_LightValue = 15;
+ a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_LightValue = 15;
+ a_Info[E_BLOCK_TORCH ].m_LightValue = 14;
+ a_Info[E_BLOCK_BURNING_FURNACE ].m_LightValue = 13;
+ a_Info[E_BLOCK_NETHER_PORTAL ].m_LightValue = 11;
+ a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_LightValue = 9;
+ a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_LightValue = 9;
+ a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_LightValue = 7;
+ a_Info[E_BLOCK_BREWING_STAND ].m_LightValue = 1;
+ a_Info[E_BLOCK_BROWN_MUSHROOM ].m_LightValue = 1;
+ a_Info[E_BLOCK_DRAGON_EGG ].m_LightValue = 1;
// Spread blocks
- ms_Info[E_BLOCK_AIR ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_CAKE ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_CHEST ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_COBWEB ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_CROPS ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_FENCE ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_FENCE_GATE ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_FIRE ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_GLASS ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_GLASS_PANE ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_GLOWSTONE ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_LEAVES ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_NEW_LEAVES ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_TORCH ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_WALLSIGN ].m_SpreadLightFalloff = 1;
- ms_Info[E_BLOCK_WOODEN_DOOR ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_AIR ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_CAKE ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_CHEST ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_COBWEB ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_CROPS ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_FENCE ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_FENCE_GATE ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_FIRE ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_GLASS ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_GLASS_PANE ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_GLOWSTONE ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_LEAVES ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_NEW_LEAVES ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_TORCH ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_TRIPWIRE ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_WALLSIGN ].m_SpreadLightFalloff = 1;
+ a_Info[E_BLOCK_WOODEN_DOOR ].m_SpreadLightFalloff = 1;
// Light in water and lava dissapears faster:
- ms_Info[E_BLOCK_LAVA ].m_SpreadLightFalloff = 3;
- ms_Info[E_BLOCK_STATIONARY_LAVA ].m_SpreadLightFalloff = 3;
- ms_Info[E_BLOCK_STATIONARY_WATER ].m_SpreadLightFalloff = 3;
- ms_Info[E_BLOCK_WATER ].m_SpreadLightFalloff = 3;
+ a_Info[E_BLOCK_LAVA ].m_SpreadLightFalloff = 3;
+ a_Info[E_BLOCK_STATIONARY_LAVA ].m_SpreadLightFalloff = 3;
+ a_Info[E_BLOCK_STATIONARY_WATER ].m_SpreadLightFalloff = 3;
+ a_Info[E_BLOCK_WATER ].m_SpreadLightFalloff = 3;
// 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;
- ms_Info[E_BLOCK_DETECTOR_RAIL ].m_Transparent = true;
- ms_Info[E_BLOCK_ENDER_CHEST ].m_Transparent = true;
- ms_Info[E_BLOCK_FENCE ].m_Transparent = true;
- ms_Info[E_BLOCK_FENCE_GATE ].m_Transparent = true;
- ms_Info[E_BLOCK_FIRE ].m_Transparent = true;
- ms_Info[E_BLOCK_FLOWER ].m_Transparent = true;
- 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;
- ms_Info[E_BLOCK_LADDER ].m_Transparent = true;
- ms_Info[E_BLOCK_LAVA ].m_Transparent = true;
- ms_Info[E_BLOCK_LEAVES ].m_Transparent = true;
- ms_Info[E_BLOCK_LEVER ].m_Transparent = true;
- ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_Transparent = true;
- ms_Info[E_BLOCK_MELON_STEM ].m_Transparent = true;
- ms_Info[E_BLOCK_NETHER_BRICK_FENCE ].m_Transparent = true;
- ms_Info[E_BLOCK_NEW_LEAVES ].m_Transparent = true;
- ms_Info[E_BLOCK_POTATOES ].m_Transparent = true;
- ms_Info[E_BLOCK_POWERED_RAIL ].m_Transparent = true;
- ms_Info[E_BLOCK_PISTON_EXTENSION ].m_Transparent = true;
- ms_Info[E_BLOCK_PUMPKIN_STEM ].m_Transparent = true;
- ms_Info[E_BLOCK_RAIL ].m_Transparent = true;
- ms_Info[E_BLOCK_RED_MUSHROOM ].m_Transparent = true;
- ms_Info[E_BLOCK_SIGN_POST ].m_Transparent = true;
- ms_Info[E_BLOCK_SNOW ].m_Transparent = true;
- ms_Info[E_BLOCK_STAINED_GLASS ].m_Transparent = true;
- ms_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Transparent = true;
- ms_Info[E_BLOCK_STATIONARY_LAVA ].m_Transparent = true;
- ms_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true;
- ms_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true;
- ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true;
- ms_Info[E_BLOCK_TALL_GRASS ].m_Transparent = true;
- ms_Info[E_BLOCK_TORCH ].m_Transparent = true;
- ms_Info[E_BLOCK_VINES ].m_Transparent = true;
- ms_Info[E_BLOCK_WALLSIGN ].m_Transparent = true;
- ms_Info[E_BLOCK_WATER ].m_Transparent = true;
- ms_Info[E_BLOCK_WOODEN_BUTTON ].m_Transparent = true;
- ms_Info[E_BLOCK_WOODEN_DOOR ].m_Transparent = true;
- ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_Transparent = true;
+ a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_Transparent = true;
+ a_Info[E_BLOCK_AIR ].m_Transparent = true;
+ a_Info[E_BLOCK_ANVIL ].m_Transparent = true;
+ a_Info[E_BLOCK_BIG_FLOWER ].m_Transparent = true;
+ a_Info[E_BLOCK_BROWN_MUSHROOM ].m_Transparent = true;
+ a_Info[E_BLOCK_CAKE ].m_Transparent = true;
+ a_Info[E_BLOCK_CARROTS ].m_Transparent = true;
+ a_Info[E_BLOCK_CHEST ].m_Transparent = true;
+ a_Info[E_BLOCK_COBBLESTONE_WALL ].m_Transparent = true;
+ a_Info[E_BLOCK_COBWEB ].m_Transparent = true;
+ a_Info[E_BLOCK_CROPS ].m_Transparent = true;
+ a_Info[E_BLOCK_DANDELION ].m_Transparent = true;
+ a_Info[E_BLOCK_DETECTOR_RAIL ].m_Transparent = true;
+ a_Info[E_BLOCK_ENDER_CHEST ].m_Transparent = true;
+ a_Info[E_BLOCK_FENCE ].m_Transparent = true;
+ a_Info[E_BLOCK_FENCE_GATE ].m_Transparent = true;
+ a_Info[E_BLOCK_FIRE ].m_Transparent = true;
+ a_Info[E_BLOCK_FLOWER ].m_Transparent = true;
+ a_Info[E_BLOCK_FLOWER_POT ].m_Transparent = true;
+ a_Info[E_BLOCK_GLASS ].m_Transparent = true;
+ a_Info[E_BLOCK_GLASS_PANE ].m_Transparent = true;
+ a_Info[E_BLOCK_HEAD ].m_Transparent = true;
+ a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_Transparent = true;
+ a_Info[E_BLOCK_ICE ].m_Transparent = true;
+ a_Info[E_BLOCK_IRON_DOOR ].m_Transparent = true;
+ a_Info[E_BLOCK_LADDER ].m_Transparent = true;
+ a_Info[E_BLOCK_LAVA ].m_Transparent = true;
+ a_Info[E_BLOCK_LEAVES ].m_Transparent = true;
+ a_Info[E_BLOCK_LEVER ].m_Transparent = true;
+ a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_Transparent = true;
+ a_Info[E_BLOCK_MELON_STEM ].m_Transparent = true;
+ a_Info[E_BLOCK_NETHER_BRICK_FENCE ].m_Transparent = true;
+ a_Info[E_BLOCK_NEW_LEAVES ].m_Transparent = true;
+ a_Info[E_BLOCK_POTATOES ].m_Transparent = true;
+ a_Info[E_BLOCK_POWERED_RAIL ].m_Transparent = true;
+ a_Info[E_BLOCK_PISTON_EXTENSION ].m_Transparent = true;
+ a_Info[E_BLOCK_PUMPKIN_STEM ].m_Transparent = true;
+ a_Info[E_BLOCK_RAIL ].m_Transparent = true;
+ a_Info[E_BLOCK_RED_MUSHROOM ].m_Transparent = true;
+ a_Info[E_BLOCK_SIGN_POST ].m_Transparent = true;
+ a_Info[E_BLOCK_SNOW ].m_Transparent = true;
+ a_Info[E_BLOCK_STAINED_GLASS ].m_Transparent = true;
+ a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Transparent = true;
+ a_Info[E_BLOCK_STATIONARY_LAVA ].m_Transparent = true;
+ a_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true;
+ a_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true;
+ a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true;
+ a_Info[E_BLOCK_TRIPWIRE ].m_Transparent = true;
+ a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_Transparent = true;
+ a_Info[E_BLOCK_TALL_GRASS ].m_Transparent = true;
+ a_Info[E_BLOCK_TORCH ].m_Transparent = true;
+ a_Info[E_BLOCK_VINES ].m_Transparent = true;
+ a_Info[E_BLOCK_WALLSIGN ].m_Transparent = true;
+ a_Info[E_BLOCK_WATER ].m_Transparent = true;
+ a_Info[E_BLOCK_WOODEN_BUTTON ].m_Transparent = true;
+ a_Info[E_BLOCK_WOODEN_DOOR ].m_Transparent = true;
+ a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_Transparent = true;
// TODO: Any other transparent blocks?
// One hit break blocks:
- ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_OneHitDig = true;
- ms_Info[E_BLOCK_BIG_FLOWER ].m_OneHitDig = true;
- ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_OneHitDig = true;
- ms_Info[E_BLOCK_CARROTS ].m_OneHitDig = true;
- ms_Info[E_BLOCK_CROPS ].m_OneHitDig = true;
- ms_Info[E_BLOCK_DANDELION ].m_OneHitDig = true;
- ms_Info[E_BLOCK_FIRE ].m_OneHitDig = true;
- ms_Info[E_BLOCK_FLOWER ].m_OneHitDig = true;
- ms_Info[E_BLOCK_FLOWER_POT ].m_OneHitDig = true;
- ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true;
- ms_Info[E_BLOCK_MELON_STEM ].m_OneHitDig = true;
- ms_Info[E_BLOCK_POTATOES ].m_OneHitDig = true;
- ms_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true;
- ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true;
- ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_OneHitDig = true;
- ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_OneHitDig = true;
- ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_OneHitDig = true;
- ms_Info[E_BLOCK_REDSTONE_WIRE ].m_OneHitDig = true;
- ms_Info[E_BLOCK_RED_MUSHROOM ].m_OneHitDig = true;
- ms_Info[E_BLOCK_REEDS ].m_OneHitDig = true;
- ms_Info[E_BLOCK_SAPLING ].m_OneHitDig = true;
- ms_Info[E_BLOCK_TNT ].m_OneHitDig = true;
- ms_Info[E_BLOCK_TALL_GRASS ].m_OneHitDig = true;
- ms_Info[E_BLOCK_TORCH ].m_OneHitDig = true;
+ a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_OneHitDig = true;
+ a_Info[E_BLOCK_BIG_FLOWER ].m_OneHitDig = true;
+ a_Info[E_BLOCK_BROWN_MUSHROOM ].m_OneHitDig = true;
+ a_Info[E_BLOCK_CARROTS ].m_OneHitDig = true;
+ a_Info[E_BLOCK_CROPS ].m_OneHitDig = true;
+ a_Info[E_BLOCK_DANDELION ].m_OneHitDig = true;
+ a_Info[E_BLOCK_FIRE ].m_OneHitDig = true;
+ a_Info[E_BLOCK_FLOWER ].m_OneHitDig = true;
+ a_Info[E_BLOCK_FLOWER_POT ].m_OneHitDig = true;
+ a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true;
+ a_Info[E_BLOCK_MELON_STEM ].m_OneHitDig = true;
+ a_Info[E_BLOCK_POTATOES ].m_OneHitDig = true;
+ a_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true;
+ a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true;
+ a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_OneHitDig = true;
+ a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_OneHitDig = true;
+ a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_OneHitDig = true;
+ a_Info[E_BLOCK_REDSTONE_WIRE ].m_OneHitDig = true;
+ a_Info[E_BLOCK_RED_MUSHROOM ].m_OneHitDig = true;
+ a_Info[E_BLOCK_REEDS ].m_OneHitDig = true;
+ a_Info[E_BLOCK_SAPLING ].m_OneHitDig = true;
+ a_Info[E_BLOCK_TNT ].m_OneHitDig = true;
+ a_Info[E_BLOCK_TALL_GRASS ].m_OneHitDig = true;
+ a_Info[E_BLOCK_TORCH ].m_OneHitDig = true;
+ a_Info[E_BLOCK_TRIPWIRE ].m_OneHitDig = true;
// Blocks that break when pushed by piston:
- ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_AIR ].m_PistonBreakable = true;
- 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;
- ms_Info[E_BLOCK_JACK_O_LANTERN ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true;
- ms_Info[E_BLOCK_LADDER ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_LAVA ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_LEVER ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_MELON ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_MELON_STEM ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_PUMPKIN ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_PUMPKIN_STEM ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_PistonBreakable = true;
- ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_PistonBreakable = true;
- ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_REDSTONE_WIRE ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_RED_MUSHROOM ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_REEDS ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_SNOW ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_STATIONARY_LAVA ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_STATIONARY_WATER ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_STONE_BUTTON ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_PistonBreakable = true;
- ms_Info[E_BLOCK_TALL_GRASS ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_TORCH ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_VINES ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_WATER ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_WOODEN_BUTTON ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_WOODEN_DOOR ].m_PistonBreakable = true;
- ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_PistonBreakable = true;
+ a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_AIR ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_BED ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_BIG_FLOWER ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_BROWN_MUSHROOM ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_CAKE ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_COBWEB ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_CROPS ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_DANDELION ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_DEAD_BUSH ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_FIRE ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_FLOWER ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_HEAD ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true;
+ a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_IRON_DOOR ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_JACK_O_LANTERN ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true;
+ a_Info[E_BLOCK_LADDER ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_LAVA ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_LEVER ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_MELON ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_MELON_STEM ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_PUMPKIN ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_PUMPKIN_STEM ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_PistonBreakable = true;
+ a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_PistonBreakable = true;
+ a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_REDSTONE_WIRE ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_RED_MUSHROOM ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_REEDS ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_SNOW ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_STATIONARY_LAVA ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_STATIONARY_WATER ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_STONE_BUTTON ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_PistonBreakable = true;
+ a_Info[E_BLOCK_TALL_GRASS ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_TORCH ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_TRIPWIRE ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_VINES ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_WATER ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_WOODEN_BUTTON ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_WOODEN_DOOR ].m_PistonBreakable = true;
+ a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_PistonBreakable = true;
// Blocks that cannot be snowed over:
- ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_IsSnowable = false;
- ms_Info[E_BLOCK_AIR ].m_IsSnowable = false;
- ms_Info[E_BLOCK_BIG_FLOWER ].m_IsSnowable = false;
- ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSnowable = false;
- 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;
- ms_Info[E_BLOCK_GLASS ].m_IsSnowable = false;
- ms_Info[E_BLOCK_ICE ].m_IsSnowable = false;
- ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_IsSnowable = false;
- ms_Info[E_BLOCK_LAVA ].m_IsSnowable = false;
- ms_Info[E_BLOCK_LILY_PAD ].m_IsSnowable = false;
- ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_IsSnowable = false;
- ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_IsSnowable = false;
- ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSnowable = false;
- ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSnowable = false;
- ms_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSnowable = false;
- ms_Info[E_BLOCK_RED_MUSHROOM ].m_IsSnowable = false;
- ms_Info[E_BLOCK_REEDS ].m_IsSnowable = false;
- ms_Info[E_BLOCK_SAPLING ].m_IsSnowable = false;
- ms_Info[E_BLOCK_SIGN_POST ].m_IsSnowable = false;
- ms_Info[E_BLOCK_SNOW ].m_IsSnowable = false;
- ms_Info[E_BLOCK_STAINED_GLASS ].m_IsSnowable = false;
- ms_Info[E_BLOCK_STAINED_GLASS_PANE ].m_IsSnowable = false;
- ms_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSnowable = false;
- ms_Info[E_BLOCK_STATIONARY_WATER ].m_IsSnowable = false;
- ms_Info[E_BLOCK_TALL_GRASS ].m_IsSnowable = false;
- ms_Info[E_BLOCK_TNT ].m_IsSnowable = false;
- ms_Info[E_BLOCK_TORCH ].m_IsSnowable = false;
- ms_Info[E_BLOCK_VINES ].m_IsSnowable = false;
- ms_Info[E_BLOCK_WALLSIGN ].m_IsSnowable = false;
- ms_Info[E_BLOCK_WATER ].m_IsSnowable = false;
- ms_Info[E_BLOCK_RAIL ].m_IsSnowable = false;
- ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSnowable = false;
- 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;
+ a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_IsSnowable = false;
+ a_Info[E_BLOCK_AIR ].m_IsSnowable = false;
+ a_Info[E_BLOCK_BIG_FLOWER ].m_IsSnowable = false;
+ a_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSnowable = false;
+ a_Info[E_BLOCK_CACTUS ].m_IsSnowable = false;
+ a_Info[E_BLOCK_CHEST ].m_IsSnowable = false;
+ a_Info[E_BLOCK_CROPS ].m_IsSnowable = false;
+ a_Info[E_BLOCK_COBBLESTONE_WALL ].m_IsSnowable = false;
+ a_Info[E_BLOCK_DANDELION ].m_IsSnowable = false;
+ a_Info[E_BLOCK_FIRE ].m_IsSnowable = false;
+ a_Info[E_BLOCK_FLOWER ].m_IsSnowable = false;
+ a_Info[E_BLOCK_GLASS ].m_IsSnowable = false;
+ a_Info[E_BLOCK_ICE ].m_IsSnowable = false;
+ a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_IsSnowable = false;
+ a_Info[E_BLOCK_LAVA ].m_IsSnowable = false;
+ a_Info[E_BLOCK_LILY_PAD ].m_IsSnowable = false;
+ a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_IsSnowable = false;
+ a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_IsSnowable = false;
+ a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSnowable = false;
+ a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSnowable = false;
+ a_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSnowable = false;
+ a_Info[E_BLOCK_RED_MUSHROOM ].m_IsSnowable = false;
+ a_Info[E_BLOCK_REEDS ].m_IsSnowable = false;
+ a_Info[E_BLOCK_SAPLING ].m_IsSnowable = false;
+ a_Info[E_BLOCK_SIGN_POST ].m_IsSnowable = false;
+ a_Info[E_BLOCK_SNOW ].m_IsSnowable = false;
+ a_Info[E_BLOCK_STAINED_GLASS ].m_IsSnowable = false;
+ a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_IsSnowable = false;
+ a_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSnowable = false;
+ a_Info[E_BLOCK_STATIONARY_WATER ].m_IsSnowable = false;
+ a_Info[E_BLOCK_TALL_GRASS ].m_IsSnowable = false;
+ a_Info[E_BLOCK_TNT ].m_IsSnowable = false;
+ a_Info[E_BLOCK_TORCH ].m_IsSnowable = false;
+ a_Info[E_BLOCK_TRIPWIRE ].m_IsSnowable = false;
+ a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_IsSnowable = false;
+ a_Info[E_BLOCK_VINES ].m_IsSnowable = false;
+ a_Info[E_BLOCK_WALLSIGN ].m_IsSnowable = false;
+ a_Info[E_BLOCK_WATER ].m_IsSnowable = false;
+ a_Info[E_BLOCK_RAIL ].m_IsSnowable = false;
+ a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSnowable = false;
+ a_Info[E_BLOCK_POWERED_RAIL ].m_IsSnowable = false;
+ a_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSnowable = false;
+ a_Info[E_BLOCK_COBWEB ].m_IsSnowable = false;
+ a_Info[E_BLOCK_HEAD ].m_IsSnowable = false;
// Blocks that don't drop without a special tool:
- ms_Info[E_BLOCK_BRICK ].m_RequiresSpecialTool = true;
- 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;
- ms_Info[E_BLOCK_DIAMOND_ORE ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_EMERALD_ORE ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_END_STONE ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_GOLD_BLOCK ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_GOLD_ORE ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_IRON_BLOCK ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_IRON_ORE ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_LAPIS_BLOCK ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_LAPIS_ORE ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_NETHERRACK ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_NETHER_BRICK ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_NETHER_BRICK_STAIRS ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_OBSIDIAN ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_REDSTONE_ORE ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_SANDSTONE ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_SANDSTONE_STAIRS ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_SNOW ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_STONE ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_STONE_BRICKS ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_STONE_BRICK_STAIRS ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_STONE_SLAB ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_VINES ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_FURNACE ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_LIT_FURNACE ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_ANVIL ].m_RequiresSpecialTool = true;
- ms_Info[E_BLOCK_ENCHANTMENT_TABLE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_BRICK ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_CAULDRON ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_COAL_ORE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_COBBLESTONE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_COBBLESTONE_WALL ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_COBBLESTONE_STAIRS ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_COBWEB ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_DIAMOND_BLOCK ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_DIAMOND_ORE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_EMERALD_ORE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_END_STONE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_GOLD_BLOCK ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_GOLD_ORE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_IRON_BLOCK ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_IRON_ORE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_LAPIS_BLOCK ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_LAPIS_ORE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_NETHERRACK ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_NETHER_BRICK ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_NETHER_BRICK_STAIRS ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_OBSIDIAN ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_REDSTONE_ORE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_SANDSTONE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_SANDSTONE_STAIRS ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_SNOW ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_STONE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_STONE_BRICKS ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_STONE_BRICK_STAIRS ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_STONE_SLAB ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_VINES ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_FURNACE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_LIT_FURNACE ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_ANVIL ].m_RequiresSpecialTool = true;
+ a_Info[E_BLOCK_ENCHANTMENT_TABLE ].m_RequiresSpecialTool = true;
// Nonsolid blocks:
- ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSolid = false;
- 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;
- ms_Info[E_BLOCK_DANDELION ].m_IsSolid = false;
- ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSolid = false;
- ms_Info[E_BLOCK_END_PORTAL ].m_IsSolid = false;
- ms_Info[E_BLOCK_FENCE ].m_IsSolid = false;
- ms_Info[E_BLOCK_FENCE_GATE ].m_IsSolid = false;
- ms_Info[E_BLOCK_FIRE ].m_IsSolid = false;
- ms_Info[E_BLOCK_FLOWER ].m_IsSolid = false;
- ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false;
- ms_Info[E_BLOCK_LAVA ].m_IsSolid = false;
- ms_Info[E_BLOCK_LEVER ].m_IsSolid = false;
- ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false;
- ms_Info[E_BLOCK_MELON_STEM ].m_IsSolid = false;
- ms_Info[E_BLOCK_NETHER_PORTAL ].m_IsSolid = false;
- ms_Info[E_BLOCK_PISTON_EXTENSION ].m_IsSolid = false;
- ms_Info[E_BLOCK_POTATOES ].m_IsSolid = false;
- ms_Info[E_BLOCK_POWERED_RAIL ].m_IsSolid = false;
- ms_Info[E_BLOCK_RAIL ].m_IsSolid = false;
- ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSolid = false;
- ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSolid = false;
- ms_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSolid = false;
- ms_Info[E_BLOCK_RED_MUSHROOM ].m_IsSolid = false;
- ms_Info[E_BLOCK_REEDS ].m_IsSolid = false;
- ms_Info[E_BLOCK_SAPLING ].m_IsSolid = false;
- ms_Info[E_BLOCK_SIGN_POST ].m_IsSolid = false;
- ms_Info[E_BLOCK_SNOW ].m_IsSolid = false;
- ms_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSolid = false;
- ms_Info[E_BLOCK_STATIONARY_WATER ].m_IsSolid = false;
- ms_Info[E_BLOCK_STONE_BUTTON ].m_IsSolid = false;
- ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_IsSolid = false;
- ms_Info[E_BLOCK_TALL_GRASS ].m_IsSolid = false;
- ms_Info[E_BLOCK_TORCH ].m_IsSolid = false;
- ms_Info[E_BLOCK_TRIPWIRE ].m_IsSolid = false;
- ms_Info[E_BLOCK_VINES ].m_IsSolid = false;
- ms_Info[E_BLOCK_WALLSIGN ].m_IsSolid = false;
- ms_Info[E_BLOCK_WATER ].m_IsSolid = false;
- ms_Info[E_BLOCK_WOODEN_BUTTON ].m_IsSolid = false;
- ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_IsSolid = false;
- ms_Info[E_BLOCK_WOODEN_SLAB ].m_IsSolid = false;
+ a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSolid = false;
+ a_Info[E_BLOCK_AIR ].m_IsSolid = false;
+ a_Info[E_BLOCK_BIG_FLOWER ].m_IsSolid = false;
+ a_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSolid = false;
+ a_Info[E_BLOCK_CAKE ].m_IsSolid = false;
+ a_Info[E_BLOCK_CARROTS ].m_IsSolid = false;
+ a_Info[E_BLOCK_COBWEB ].m_IsSolid = false;
+ a_Info[E_BLOCK_CROPS ].m_IsSolid = false;
+ a_Info[E_BLOCK_DANDELION ].m_IsSolid = false;
+ a_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSolid = false;
+ a_Info[E_BLOCK_END_PORTAL ].m_IsSolid = false;
+ a_Info[E_BLOCK_FENCE ].m_IsSolid = false;
+ a_Info[E_BLOCK_FENCE_GATE ].m_IsSolid = false;
+ a_Info[E_BLOCK_FIRE ].m_IsSolid = false;
+ a_Info[E_BLOCK_FLOWER ].m_IsSolid = false;
+ a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false;
+ a_Info[E_BLOCK_LAVA ].m_IsSolid = false;
+ a_Info[E_BLOCK_LEVER ].m_IsSolid = false;
+ a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false;
+ a_Info[E_BLOCK_MELON_STEM ].m_IsSolid = false;
+ a_Info[E_BLOCK_NETHER_PORTAL ].m_IsSolid = false;
+ a_Info[E_BLOCK_POTATOES ].m_IsSolid = false;
+ a_Info[E_BLOCK_POWERED_RAIL ].m_IsSolid = false;
+ a_Info[E_BLOCK_RAIL ].m_IsSolid = false;
+ a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSolid = false;
+ a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSolid = false;
+ a_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSolid = false;
+ a_Info[E_BLOCK_RED_MUSHROOM ].m_IsSolid = false;
+ a_Info[E_BLOCK_REEDS ].m_IsSolid = false;
+ a_Info[E_BLOCK_SAPLING ].m_IsSolid = false;
+ a_Info[E_BLOCK_SIGN_POST ].m_IsSolid = false;
+ a_Info[E_BLOCK_SNOW ].m_IsSolid = false;
+ a_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSolid = false;
+ a_Info[E_BLOCK_STATIONARY_WATER ].m_IsSolid = false;
+ a_Info[E_BLOCK_STONE_BUTTON ].m_IsSolid = false;
+ a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_IsSolid = false;
+ a_Info[E_BLOCK_TALL_GRASS ].m_IsSolid = false;
+ a_Info[E_BLOCK_TORCH ].m_IsSolid = false;
+ a_Info[E_BLOCK_TRIPWIRE ].m_IsSolid = false;
+ a_Info[E_BLOCK_VINES ].m_IsSolid = false;
+ a_Info[E_BLOCK_WALLSIGN ].m_IsSolid = false;
+ a_Info[E_BLOCK_WATER ].m_IsSolid = false;
+ a_Info[E_BLOCK_WOODEN_BUTTON ].m_IsSolid = false;
+ a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_IsSolid = false;
+ a_Info[E_BLOCK_WOODEN_SLAB ].m_IsSolid = false;
// Blocks that fully occupy their voxel - used as a guide for torch placeable blocks, amongst other things:
- ms_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_BEDROCK ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_BLOCK_OF_COAL ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_BOOKCASE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_BRICK ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_CLAY ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_COAL_ORE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_COBBLESTONE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_COMMAND_BLOCK ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_CRAFTING_TABLE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_DIAMOND_BLOCK ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_DIAMOND_ORE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_DIRT ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_DISPENSER ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_DROPPER ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_EMERALD_BLOCK ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_EMERALD_ORE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_END_STONE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_FURNACE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_GLOWSTONE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_GOLD_BLOCK ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_GOLD_ORE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_GRASS ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_GRAVEL ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_HARDENED_CLAY ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_HAY_BALE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_ICE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_IRON_BLOCK ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_IRON_ORE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_JACK_O_LANTERN ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_JUKEBOX ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_LAPIS_BLOCK ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_LAPIS_ORE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_LOG ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_MELON ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_MYCELIUM ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_NETHERRACK ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_NETHER_BRICK ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_NOTE_BLOCK ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_OBSIDIAN ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_PACKED_ICE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_PLANKS ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_PUMPKIN ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_QUARTZ_BLOCK ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_REDSTONE_ORE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_SANDSTONE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_SAND ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_SILVERFISH_EGG ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_SPONGE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_STAINED_CLAY ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_WOOL ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_STONE ].m_FullyOccupiesVoxel = true;
- ms_Info[E_BLOCK_STONE_BRICKS ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_BEDROCK ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_BLOCK_OF_COAL ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_BOOKCASE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_BRICK ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_CLAY ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_COAL_ORE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_COBBLESTONE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_COMMAND_BLOCK ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_CRAFTING_TABLE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_DIAMOND_BLOCK ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_DIAMOND_ORE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_DIRT ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_DISPENSER ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_DROPPER ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_EMERALD_BLOCK ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_EMERALD_ORE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_END_STONE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_FURNACE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_GLOWSTONE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_GOLD_BLOCK ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_GOLD_ORE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_GRASS ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_GRAVEL ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_HARDENED_CLAY ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_HAY_BALE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_ICE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_IRON_BLOCK ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_IRON_ORE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_JACK_O_LANTERN ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_JUKEBOX ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_LAPIS_BLOCK ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_LAPIS_ORE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_LOG ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_MELON ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_MYCELIUM ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_NETHERRACK ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_NETHER_BRICK ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_NOTE_BLOCK ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_OBSIDIAN ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_PACKED_ICE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_PLANKS ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_PUMPKIN ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_QUARTZ_BLOCK ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_REDSTONE_ORE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_SANDSTONE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_SAND ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_SILVERFISH_EGG ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_SPONGE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_STAINED_CLAY ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_WOOL ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_STONE ].m_FullyOccupiesVoxel = true;
+ a_Info[E_BLOCK_STONE_BRICKS ].m_FullyOccupiesVoxel = true;
}
-
-// This is actually just some code that needs to run at program startup, so it is wrapped into a global var's constructor:
-class cBlockInfoInitializer
-{
-public:
- cBlockInfoInitializer(void)
- {
- cBlockInfo::Initialize();
- }
-} BlockInfoInitializer;
-
-
-
-
-
diff --git a/src/BlockInfo.h b/src/BlockInfo.h
index 40c1db867..d6d4e7430 100644
--- a/src/BlockInfo.h
+++ b/src/BlockInfo.h
@@ -16,18 +16,8 @@ class cBlockHandler;
class cBlockInfo
{
public:
- // tolua_end
-
- cBlockInfo();
-
- ~cBlockInfo();
-
- /** (Re-)Initializes the internal BlockInfo structures. */
- static void Initialize(void);
- // tolua_begin
-
- /** Returns the associated BlockInfo structure. */
+ /** Returns the associated BlockInfo structure for the specified block type. */
static cBlockInfo & Get(BLOCKTYPE a_Type);
@@ -79,13 +69,18 @@ public:
inline static cBlockHandler * GetHandler (BLOCKTYPE a_Type) { return Get(a_Type).m_Handler; }
-
protected:
+ /** Storage for all the BlockInfo structures. */
+ typedef cBlockInfo cBlockInfoArray[256];
- // TODO xdot: Change to std::vector to support dynamic block IDs
- static cBlockInfo ms_Info[256];
+ /** Creates a default BlockInfo structure, initializes all values to their defaults */
+ cBlockInfo();
+ /** Cleans up the stored values */
+ ~cBlockInfo();
+ /** Initializes the specified BlockInfo structures with block-specific values. */
+ static void Initialize(cBlockInfoArray & a_BlockInfos);
}; // tolua_export
diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h
index 4b2f6f618..ada7d58f7 100644
--- a/src/Blocks/BlockButton.h
+++ b/src/Blocks/BlockButton.h
@@ -23,6 +23,7 @@ public:
NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) | 0x08);
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
+ a_WorldInterface.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
// Queue a button reset (unpress)
@@ -102,7 +103,7 @@ public:
AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true);
BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
- return (a_RelY > 0) && (cBlockInfo::IsSolid(BlockIsOn));
+ return (a_RelY > 0) && (cBlockInfo::FullyOccupiesVoxel(BlockIsOn));
}
} ;
diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp
index fb2d6f2dc..934a01994 100644
--- a/src/Blocks/BlockDoor.cpp
+++ b/src/Blocks/BlockDoor.cpp
@@ -45,9 +45,16 @@ void cBlockDoorHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldIn
void cBlockDoorHandler::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)
{
+ UNUSED(a_WorldInterface);
+ UNUSED(a_BlockFace);
+ UNUSED(a_CursorX);
+ UNUSED(a_CursorY);
+ UNUSED(a_CursorZ);
+
if (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_DOOR)
{
ChangeDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
+ a_Player->GetWorld()->BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle());
}
}
diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h
index e202c6610..e992870d4 100644
--- a/src/Blocks/BlockFenceGate.h
+++ b/src/Blocks/BlockFenceGate.h
@@ -45,6 +45,7 @@ public:
// Standing aside - use last direction
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, OldMetaData);
}
+ a_Player->GetWorld()->BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle());
}
diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h
index f9f32eb50..147e4b53e 100644
--- a/src/Blocks/BlockFire.h
+++ b/src/Blocks/BlockFire.h
@@ -36,8 +36,8 @@ public:
- Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir
*/
- a_BlockY--; // Because we want the block below the fire
- FindAndSetPortalFrame(a_BlockX, a_BlockY, a_BlockZ, a_ChunkInterface, a_WorldInterface);
+ // a_BlockY - 1: Because we want the block below the fire
+ FindAndSetPortalFrame(a_BlockX, a_BlockY - 1, a_BlockZ, a_ChunkInterface, a_WorldInterface);
}
virtual void OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index 6b08ec9ba..3ddb7531d 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -38,6 +38,7 @@
#include "BlockGlass.h"
#include "BlockGlowstone.h"
#include "BlockGravel.h"
+#include "BlockHayBale.h"
#include "BlockMobHead.h"
#include "BlockHopper.h"
#include "BlockIce.h"
@@ -64,6 +65,8 @@
#include "BlockRedstoneRepeater.h"
#include "BlockRedstoneTorch.h"
#include "BlockTNT.h"
+#include "BlockTripwire.h"
+#include "BlockTripwireHook.h"
#include "BlockSand.h"
#include "BlockSapling.h"
#include "BlockSideways.h"
@@ -84,6 +87,91 @@
+/*
+// Tests the meta rotation and mirroring.
+// Note that the cMetaRotator needs to have its assert paths disabled for this test to work!
+static class cBlockHandlerRotationTester
+{
+public:
+ cBlockHandlerRotationTester(void)
+ {
+ printf("Performing block handlers test...\n");
+ for (BLOCKTYPE Type = 0; Type < E_BLOCK_MAX_TYPE_ID; Type++)
+ {
+ cBlockHandler * Handler = cBlockInfo::GetHandler(Type);
+ if (Handler == NULL)
+ {
+ printf("NULL handler for block type %d!\n", Type);
+ continue;
+ }
+ AString BlockName = ItemTypeToString(Type);
+ for (NIBBLETYPE Meta = 0; Meta < 16; Meta++)
+ {
+ // Test the CW / CCW rotations:
+ NIBBLETYPE TestMeta;
+ TestMeta = Handler->MetaRotateCW(Handler->MetaRotateCW(Handler->MetaRotateCW(Handler->MetaRotateCW(Meta))));
+ if (TestMeta != Meta)
+ {
+ // 4 CW rotations should produce no change in the meta
+ printf("Handler for blocktype %d (%s) fails CW 4-rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
+ }
+ TestMeta = Handler->MetaRotateCCW(Handler->MetaRotateCCW(Handler->MetaRotateCCW(Handler->MetaRotateCCW(Meta))));
+ if (TestMeta != Meta)
+ {
+ // 4 CCW rotations should produce no change in the meta
+ printf("Handler for blocktype %d (%s) fails CCW 4-rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
+ }
+ TestMeta = Handler->MetaRotateCCW(Handler->MetaRotateCW(Meta));
+ if (TestMeta != Meta)
+ {
+ // CCW rotation of a CW rotation should produce no change in the meta
+ printf("Handler for blocktype %d (%s) fails CCW(CW) rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
+ }
+ TestMeta = Handler->MetaRotateCW(Handler->MetaRotateCCW(Meta));
+ if (TestMeta != Meta)
+ {
+ // CW rotation of a CCW rotation should produce no change in the meta
+ printf("Handler for blocktype %d (%s) fails CW(CCW) rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
+ }
+
+ // Test the mirroring:
+ TestMeta = Handler->MetaMirrorXY(Handler->MetaMirrorXY(Meta));
+ if (TestMeta != Meta)
+ {
+ // Double-mirroring should produce the same meta:
+ printf("Handler for blocktype %d (%s) fails XY mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
+ }
+ TestMeta = Handler->MetaMirrorXZ(Handler->MetaMirrorXZ(Meta));
+ if (TestMeta != Meta)
+ {
+ // Double-mirroring should produce the same meta:
+ printf("Handler for blocktype %d (%s) fails XZ mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
+ }
+ TestMeta = Handler->MetaMirrorYZ(Handler->MetaMirrorYZ(Meta));
+ if (TestMeta != Meta)
+ {
+ // Double-mirroring should produce the same meta:
+ printf("Handler for blocktype %d (%s) fails YZ mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
+ }
+
+ // Test mirror-rotating:
+ TestMeta = Handler->MetaRotateCW(Handler->MetaRotateCW(Handler->MetaMirrorXY(Handler->MetaMirrorYZ(Meta))));
+ if (TestMeta != Meta)
+ {
+ // 2 CW rotations should be the same as XY, YZ mirroring:
+ printf("Handler for blocktype %d (%s) fails rotation-mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
+ }
+ }
+ } // for Type
+ printf("Block handlers test complete.\n");
+ }
+} g_BlockHandlerRotationTester;
+//*/
+
+
+
+
+
cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
{
switch(a_BlockType)
@@ -134,7 +222,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_GLASS_PANE: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType);
case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType);
- case E_BLOCK_HAY_BALE: return new cBlockSidewaysHandler (a_BlockType);
+ case E_BLOCK_HAY_BALE: return new cBlockHayBaleHandler (a_BlockType);
case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType);
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType);
case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType);
@@ -174,7 +262,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_QUARTZ_BLOCK: return new cBlockQuartzHandler (a_BlockType);
case E_BLOCK_QUARTZ_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_RAIL: return new cBlockRailHandler (a_BlockType);
- case E_BLOCK_REDSTONE_LAMP_ON: return new cBlockRedstoneLampHandler (a_BlockType); // We need this to change pickups to an off lamp; else 1.7+ clients crash
+ case E_BLOCK_REDSTONE_LAMP_ON: return new cBlockRedstoneLampHandler (a_BlockType);
case E_BLOCK_REDSTONE_ORE: return new cBlockOreHandler (a_BlockType);
case E_BLOCK_REDSTONE_ORE_GLOWING: return new cBlockOreHandler (a_BlockType);
case E_BLOCK_REDSTONE_REPEATER_OFF: return new cBlockRedstoneRepeaterHandler(a_BlockType);
@@ -205,8 +293,10 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_TORCH: return new cBlockTorchHandler (a_BlockType);
case E_BLOCK_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType);
case E_BLOCK_TNT: return new cBlockTNTHandler (a_BlockType);
+ case E_BLOCK_TRIPWIRE: return new cBlockTripwireHandler (a_BlockType);
+ case E_BLOCK_TRIPWIRE_HOOK: return new cBlockTripwireHookHandler (a_BlockType);
case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType);
- case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType);
+ case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType); // TODO: This needs a special handler
case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType);
case E_BLOCK_WOODEN_BUTTON: return new cBlockButtonHandler (a_BlockType);
case E_BLOCK_WOODEN_DOOR: return new cBlockDoorHandler (a_BlockType);
diff --git a/src/Blocks/BlockHayBale.h b/src/Blocks/BlockHayBale.h
new file mode 100644
index 000000000..5b646e264
--- /dev/null
+++ b/src/Blocks/BlockHayBale.h
@@ -0,0 +1,29 @@
+
+#pragma once
+
+#include "BlockHandler.h"
+#include "BlockSideways.h"
+
+
+
+
+
+class cBlockHayBaleHandler :
+ public cBlockSidewaysHandler
+{
+public:
+ cBlockHayBaleHandler(BLOCKTYPE a_BlockType)
+ : cBlockSidewaysHandler(a_BlockType)
+ {
+ }
+
+
+ virtual const char * GetStepSound(void) override
+ {
+ return "step.grass";
+ }
+} ;
+
+
+
+
diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h
index ad2ae29e5..4e745d413 100644
--- a/src/Blocks/BlockLever.h
+++ b/src/Blocks/BlockLever.h
@@ -7,12 +7,13 @@
class cBlockLeverHandler :
- public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false>
+ public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, false>
{
- typedef cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false> super;
+ typedef cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, false> super;
+
public:
- cBlockLeverHandler(BLOCKTYPE a_BlockType)
- : cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false>(a_BlockType)
+ cBlockLeverHandler(BLOCKTYPE a_BlockType) :
+ super(a_BlockType)
{
}
@@ -21,7 +22,8 @@ public:
// Flip the ON bit on/off using the XOR bitwise operation
NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08);
- a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LEVER, Meta); // SetMeta doesn't work for unpowering levers, so setblock
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta);
+ a_WorldInterface.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ);
a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f);
}
@@ -103,7 +105,7 @@ public:
AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true);
BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
- return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn);
+ return (a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn);
}
@@ -132,7 +134,7 @@ public:
case 0x05: return 0x06; // Ground rotation
case 0x06: return 0x05;
- default: return super::MetaRotateCCW(a_Meta); // Wall Rotation
+ default: return super::MetaRotateCW(a_Meta); // Wall Rotation
}
}
} ;
diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h
index 9855574ad..301386568 100644
--- a/src/Blocks/BlockMobHead.h
+++ b/src/Blocks/BlockMobHead.h
@@ -19,24 +19,69 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
- a_Pickups.push_back(cItem(E_ITEM_HEAD, 1, 0));
+ // The drop spawn is in OnDestroyed method
}
+
+ virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
+ {
+ if (a_Player->IsGameModeCreative())
+ {
+ // No drops in creative mode
+ return;
+ }
+
+ class cCallback : public cBlockEntityCallback
+ {
+ virtual bool Item(cBlockEntity * a_BlockEntity)
+ {
+ if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
+ {
+ return false;
+ }
+ cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
+
+ cItems Pickups;
+ Pickups.Add(E_ITEM_HEAD, 1, (short) MobHeadEntity->GetType());
+ MTRand r1;
+
+ // Mid-block position first
+ double MicroX, MicroY, MicroZ;
+ MicroX = MobHeadEntity->GetPosX() + 0.5;
+ MicroY = MobHeadEntity->GetPosY() + 0.5;
+ MicroZ = MobHeadEntity->GetPosZ() + 0.5;
+
+ // Add random offset second
+ MicroX += r1.rand(1) - 0.5;
+ MicroZ += r1.rand(1) - 0.5;
- bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
+ MobHeadEntity->GetWorld()->SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ);
+ return false;
+ }
+ } Callback;
+
+ a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
+ }
+
+ bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
if (a_BlockY < 2)
{
return false;
}
- class cCallback : public cMobHeadCallback
+ class cCallback : public cBlockEntityCallback
{
bool m_IsWither;
- virtual bool Item (cMobHeadEntity * a_MobHeadEntity)
+ virtual bool Item(cBlockEntity * a_BlockEntity)
{
- m_IsWither = (a_MobHeadEntity->GetType() == SKULL_TYPE_WITHER);
+ if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
+ {
+ return false;
+ }
+ cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
+ m_IsWither = (MobHeadEntity->GetType() == SKULL_TYPE_WITHER);
return false;
}
@@ -70,7 +115,7 @@ public:
} PlayerCallback(Vector3f((float)a_BlockX, (float)a_BlockY, (float)a_BlockZ));
- a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA);
+ a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA);
if (!CallbackA.IsWither())
{
@@ -87,8 +132,8 @@ public:
return false;
}
- a_World->DoWithMobHeadAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA);
- a_World->DoWithMobHeadAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB);
+ a_WorldInterface.DoWithBlockEntityAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA);
+ a_WorldInterface.DoWithBlockEntityAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB);
BLOCKTYPE Block1 = a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ);
BLOCKTYPE Block2 = a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ);
@@ -101,15 +146,15 @@ public:
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
// Block entities
- a_World->SetBlock(a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
- a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
- a_World->SetBlock(a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
// Spawn the wither:
- a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
+ a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
// Award Achievement
- a_World->ForEachPlayer(PlayerCallback);
+ a_WorldInterface.ForEachPlayer(PlayerCallback);
return true;
}
@@ -117,8 +162,8 @@ public:
CallbackA.Reset();
CallbackB.Reset();
- a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA);
- a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB);
+ a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA);
+ a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB);
Block1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1);
Block2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1);
@@ -131,15 +176,15 @@ public:
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
// Block entities
- a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0);
- a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
- a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
+ a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0);
+ a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
+ a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
// Spawn the wither:
- a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
+ a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
// Award Achievement
- a_World->ForEachPlayer(PlayerCallback);
+ a_WorldInterface.ForEachPlayer(PlayerCallback);
return true;
}
@@ -154,23 +199,29 @@ public:
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
) override
{
- class cCallback : public cMobHeadCallback
+ class cCallback : public cBlockEntityCallback
{
cPlayer * m_Player;
NIBBLETYPE m_OldBlockMeta;
NIBBLETYPE m_NewBlockMeta;
- virtual bool Item (cMobHeadEntity * a_MobHeadEntity)
+ virtual bool Item(cBlockEntity * a_BlockEntity)
{
+ if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
+ {
+ return false;
+ }
+ cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
+
int Rotation = 0;
if (m_NewBlockMeta == 1)
{
Rotation = (int) floor(m_Player->GetYaw() * 16.0F / 360.0F + 0.5) & 0xF;
}
-
- a_MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta));
- a_MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
- a_MobHeadEntity->GetWorld()->BroadcastBlockEntity(a_MobHeadEntity->GetPosX(), a_MobHeadEntity->GetPosY(), a_MobHeadEntity->GetPosZ(), m_Player->GetClientHandle());
+
+ MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta));
+ MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
+ MobHeadEntity->GetWorld()->BroadcastBlockEntity(MobHeadEntity->GetPosX(), MobHeadEntity->GetPosY(), MobHeadEntity->GetPosZ());
return false;
}
@@ -184,8 +235,7 @@ public:
cCallback Callback(a_Player, a_BlockMeta, static_cast<NIBBLETYPE>(a_BlockFace));
a_BlockMeta = (NIBBLETYPE)a_BlockFace;
- cWorld * World = (cWorld *) &a_WorldInterface;
- World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
+ a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta);
if (a_BlockMeta == SKULL_TYPE_WITHER)
@@ -200,7 +250,7 @@ public:
};
for (size_t i = 0; i < ARRAYCOUNT(Coords); ++i)
{
- if (TrySpawnWither(a_ChunkInterface, World, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z))
+ if (TrySpawnWither(a_ChunkInterface, a_WorldInterface, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z))
{
break;
}
diff --git a/src/Blocks/BlockSign.h b/src/Blocks/BlockSign.h
index 9d6fede21..f5630bdb0 100644
--- a/src/Blocks/BlockSign.h
+++ b/src/Blocks/BlockSign.h
@@ -75,13 +75,13 @@ public:
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
{
- return (++a_Meta) & 0x0F;
+ return (a_Meta + 4) & 0x0f;
}
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
{
- return (--a_Meta) & 0x0F;
+ return (a_Meta + 12) & 0x0f;
}
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
@@ -90,7 +90,7 @@ public:
// There are 16 meta values which correspond to different directions.
// These values are equated to angles on a circle; 0x08 = 180 degrees.
- return (a_Meta < 0x08) ? 0x08 + a_Meta : 0x08 - a_Meta;
+ return (a_Meta < 0x08) ? (0x08 + a_Meta) : (0x08 - a_Meta);
}
diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h
index 80841b094..6c861be86 100644
--- a/src/Blocks/BlockSlab.h
+++ b/src/Blocks/BlockSlab.h
@@ -80,6 +80,7 @@ public:
if (IsAnySlabType(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ)))
{
a_BlockType = GetDoubleSlabType(m_BlockType);
+ a_BlockMeta = a_BlockMeta & 0x7;
}
return true;
@@ -123,6 +124,12 @@ public:
return E_BLOCK_AIR;
}
+
+ virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
+ {
+ // Toggle the 4th bit - up / down:
+ return (a_Meta ^ 0x08);
+ }
} ;
@@ -166,15 +173,6 @@ public:
ASSERT(!"Unhandled double slab type!");
return "";
}
-
-
- virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
- {
- NIBBLETYPE OtherMeta = a_Meta & 0x07; // Contains unrelated meta data.
-
- // 8th bit is up/down. 1 right-side-up, 0 is up-side-down.
- return (a_Meta & 0x08) ? 0x00 + OtherMeta : 0x01 + OtherMeta;
- }
} ;
diff --git a/src/Blocks/BlockStone.h b/src/Blocks/BlockStone.h
index af4c6509a..cd5230f49 100644
--- a/src/Blocks/BlockStone.h
+++ b/src/Blocks/BlockStone.h
@@ -2,8 +2,6 @@
#pragma once
#include "BlockHandler.h"
-#include "../MersenneTwister.h"
-#include "../World.h"
diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h
index 8ddec8de1..44c33c429 100644
--- a/src/Blocks/BlockTorch.h
+++ b/src/Blocks/BlockTorch.h
@@ -154,7 +154,11 @@ public:
if (
(BlockInQuestion == E_BLOCK_GLASS) ||
+ (BlockInQuestion == E_BLOCK_STAINED_GLASS) ||
(BlockInQuestion == E_BLOCK_FENCE) ||
+ (BlockInQuestion == E_BLOCK_SOULSAND) ||
+ (BlockInQuestion == E_BLOCK_MOB_SPAWNER) ||
+ (BlockInQuestion == E_BLOCK_END_PORTAL_FRAME) || // Actual vanilla behaviour
(BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) ||
(BlockInQuestion == E_BLOCK_COBBLESTONE_WALL)
)
diff --git a/src/Blocks/BlockTripwire.h b/src/Blocks/BlockTripwire.h
new file mode 100644
index 000000000..3ab17bf4a
--- /dev/null
+++ b/src/Blocks/BlockTripwire.h
@@ -0,0 +1,32 @@
+
+#pragma once
+
+#include "BlockHandler.h"
+
+
+
+
+
+class cBlockTripwireHandler :
+ public cBlockHandler
+{
+public:
+ cBlockTripwireHandler(BLOCKTYPE a_BlockType)
+ : cBlockHandler(a_BlockType)
+ {
+ }
+
+ virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
+ {
+ a_Pickups.push_back(cItem(E_ITEM_STRING, 1, 0));
+ }
+
+ virtual const char * GetStepSound(void) override
+ {
+ return "";
+ }
+};
+
+
+
+
diff --git a/src/Blocks/BlockTripwireHook.h b/src/Blocks/BlockTripwireHook.h
new file mode 100644
index 000000000..f849fb8ad
--- /dev/null
+++ b/src/Blocks/BlockTripwireHook.h
@@ -0,0 +1,82 @@
+#pragma once
+
+#include "BlockHandler.h"
+#include "MetaRotator.h"
+
+
+
+
+
+class cBlockTripwireHookHandler :
+ public cMetaRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01>
+{
+public:
+ cBlockTripwireHookHandler(BLOCKTYPE a_BlockType)
+ : cMetaRotator<cBlockHandler, 0x03, 0x02, 0x03, 0x00, 0x01>(a_BlockType)
+ {
+ }
+
+ virtual bool GetPlacementBlockTypeMeta(
+ cChunkInterface & a_ChunkInterface, cPlayer * a_Player,
+ int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ,
+ BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
+ ) override
+ {
+ a_BlockType = m_BlockType;
+
+ a_BlockMeta = DirectionToMetadata(a_BlockFace);
+
+ return true;
+ }
+
+ inline static NIBBLETYPE DirectionToMetadata(eBlockFace a_Direction)
+ {
+ switch (a_Direction)
+ {
+ case BLOCK_FACE_XM: return 0x1;
+ case BLOCK_FACE_XP: return 0x3;
+ case BLOCK_FACE_ZM: return 0x2;
+ case BLOCK_FACE_ZP: return 0x0;
+ default: ASSERT(!"Unhandled tripwire hook direction!"); return 0x0;
+ }
+ }
+
+ inline static eBlockFace MetadataToDirection(NIBBLETYPE a_Meta)
+ {
+ switch (a_Meta & 0x03)
+ {
+ case 0x1: return BLOCK_FACE_XM;
+ case 0x3: return BLOCK_FACE_XP;
+ case 0x2: return BLOCK_FACE_ZM;
+ case 0x0: return BLOCK_FACE_ZP;
+ default: ASSERT(!"Unhandled tripwire hook metadata!"); return BLOCK_FACE_NONE;
+ }
+ }
+
+ virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
+ {
+ // Reset meta to 0
+ a_Pickups.push_back(cItem(E_BLOCK_TRIPWIRE_HOOK, 1, 0));
+ }
+
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ {
+ NIBBLETYPE Meta;
+ a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta);
+
+ AddFaceDirection(a_RelX, a_RelY, a_RelZ, MetadataToDirection(Meta), true);
+ BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn);
+
+ return (a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn);
+ }
+
+ virtual const char * GetStepSound(void) override
+ {
+ return "step.wood";
+ }
+};
+
+
+
+
diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h
index bfbb053d9..251b28d03 100644
--- a/src/Blocks/WorldInterface.h
+++ b/src/Blocks/WorldInterface.h
@@ -6,6 +6,12 @@
class cItems;
+typedef cItemCallback<cBlockEntity> cBlockEntityCallback;
+
+
+
+
+
class cWorldInterface
{
public:
@@ -29,6 +35,9 @@ public:
/** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0;
+ /** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
+ virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) = 0;
+
/** Sends the block on those coords to the player */
virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player) = 0;
@@ -37,4 +46,7 @@ public:
virtual void SetTimeOfDay(Int64 a_TimeOfDay) = 0;
+ /** Wakes up the simulators for the specified block */
+ virtual void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) = 0;
+
};
diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp
index d77f402fd..1a69c856f 100644
--- a/src/ByteBuffer.cpp
+++ b/src/ByteBuffer.cpp
@@ -165,6 +165,7 @@ cByteBuffer::~cByteBuffer()
{
CheckValid();
delete[] m_Buffer;
+ m_Buffer = NULL;
}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 678db3fb4..fdc33cd82 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,9 +1,9 @@
cmake_minimum_required (VERSION 2.8.2)
project (MCServer)
-include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/")
-include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/jsoncpp/include")
-include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/polarssl/include")
+include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/")
+include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/jsoncpp/include")
+include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include")
set(FOLDERS OSSupport HTTPServer Items Blocks Protocol Generating PolarSSL++)
set(FOLDERS ${FOLDERS} WorldStorage Mobs Entities Simulator UI BlockEntities Generating/Prefabs)
@@ -12,6 +12,7 @@ set(BINDING_DEPENDECIES
tolua
${CMAKE_CURRENT_SOURCE_DIR}/Bindings/virtual_method_hooks.lua
${CMAKE_CURRENT_SOURCE_DIR}/Bindings/AllToLua.pkg
+ Bindings/gen_LuaState_Call.lua
Bindings/LuaFunctions.h
Bindings/LuaWindow.h
Bindings/Plugin.h
@@ -79,16 +80,22 @@ set(BINDING_DEPENDECIES
World.h
)
+# List all the files that are generated as part of the Bindings build process
+set (BINDING_OUTPUTS
+ ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/LuaState_Call.inc
+)
+
include_directories(Bindings)
include_directories(.)
if (WIN32)
ADD_CUSTOM_COMMAND(
- # add any new generated bindings here
- OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.h
+ OUTPUT ${BINDING_OUTPUTS}
# Copy the Lua DLL into the Bindings folder, so that tolua can run from there:
- COMMAND copy /y ..\\..\\MCServer\\lua51.dll .
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different ../../MCServer/lua51.dll ./lua51.dll
# Regenerate bindings:
COMMAND tolua -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
@@ -119,7 +126,8 @@ if (NOT MSVC)
# lib dependencies are not included
-
+ include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include")
+
#add cpp files here
add_library(Bindings
Bindings/Bindings
@@ -134,7 +142,7 @@ if (NOT MSVC)
Bindings/WebPlugin
)
- target_link_libraries(Bindings lua sqlite tolualib)
+ target_link_libraries(Bindings lua sqlite tolualib polarssl)
#clear file
file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/BindingDependecies.txt)
@@ -260,4 +268,4 @@ endif ()
if (WIN32)
target_link_libraries(${EXECUTABLE} expat tolualib ws2_32.lib Psapi.lib)
endif()
-target_link_libraries(${EXECUTABLE} md5 luaexpat iniFile jsoncpp polarssl zlib lua sqlite)
+target_link_libraries(${EXECUTABLE} luaexpat iniFile jsoncpp polarssl zlib sqlite lua)
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index 4703e4536..0fee40cac 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -152,7 +152,9 @@ cChunk::~cChunk()
m_NeighborZP->m_NeighborZM = NULL;
}
delete m_WaterSimulatorData;
+ m_WaterSimulatorData = NULL;
delete m_LavaSimulatorData;
+ m_LavaSimulatorData = NULL;
}
@@ -596,6 +598,7 @@ void cChunk::Tick(float a_Dt)
cEntity * ToDelete = *itr;
itr = m_Entities.erase(itr);
delete ToDelete;
+ ToDelete = NULL;
continue;
}
++itr;
@@ -1417,6 +1420,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType,
BlockEntity->Destroy();
RemoveBlockEntity(BlockEntity);
delete BlockEntity;
+ BlockEntity = NULL;
}
// If the new block is a block entity, create the entity object:
@@ -1612,6 +1616,12 @@ void cChunk::AddBlockEntity(cBlockEntity * a_BlockEntity)
cBlockEntity * cChunk::GetBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ)
{
+ // Check that the query coords are within chunk bounds:
+ ASSERT(a_BlockX >= m_PosX * cChunkDef::Width);
+ ASSERT(a_BlockX < m_PosX * cChunkDef::Width + cChunkDef::Width);
+ ASSERT(a_BlockZ >= m_PosZ * cChunkDef::Width);
+ ASSERT(a_BlockZ < m_PosZ * cChunkDef::Width + cChunkDef::Width);
+
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
{
if (
@@ -2691,7 +2701,7 @@ void cChunk::BroadcastChunkData(cChunkDataSerializer & a_Serializer, const cClie
-void cChunk::BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude)
+void cChunk::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude)
{
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr )
{
@@ -2699,7 +2709,7 @@ void cChunk::BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_
{
continue;
}
- (*itr)->SendCollectPickup(a_Pickup, a_Player);
+ (*itr)->SendCollectEntity(a_Entity, a_Player);
} // for itr - LoadedByClient[]
}
diff --git a/src/Chunk.h b/src/Chunk.h
index 7664a7afd..e9d964e05 100644
--- a/src/Chunk.h
+++ b/src/Chunk.h
@@ -279,7 +279,7 @@ public:
void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = NULL);
void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL);
void BroadcastChunkData (cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
- void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
+ void BroadcastCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL);
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp
index d2ccca94e..c9fb0b59e 100644
--- a/src/ChunkMap.cpp
+++ b/src/ChunkMap.cpp
@@ -419,16 +419,16 @@ void cChunkMap::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSeriali
-void cChunkMap::BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude)
+void cChunkMap::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude)
{
cCSLock Lock(m_CSLayers);
- cChunkPtr Chunk = GetChunkNoGen(a_Pickup.GetChunkX(), ZERO_CHUNK_Y, a_Pickup.GetChunkZ());
+ cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
if (Chunk == NULL)
{
return;
}
// It's perfectly legal to broadcast packets even to invalid chunks!
- Chunk->BroadcastCollectPickup(a_Pickup, a_Player, a_Exclude);
+ Chunk->BroadcastCollectEntity(a_Entity, a_Player, a_Exclude);
}
diff --git a/src/ChunkMap.h b/src/ChunkMap.h
index f02dd3302..433516490 100644
--- a/src/ChunkMap.h
+++ b/src/ChunkMap.h
@@ -35,8 +35,8 @@ class cBlockArea;
class cMobCensus;
class cMobSpawner;
-typedef std::list<cClientHandle *> cClientHandleList;
-typedef cChunk * cChunkPtr;
+typedef std::list<cClientHandle *> cClientHandleList;
+typedef cChunk * cChunkPtr;
typedef cItemCallback<cEntity> cEntityCallback;
typedef cItemCallback<cBlockEntity> cBlockEntityCallback;
typedef cItemCallback<cChestEntity> cChestCallback;
@@ -70,6 +70,7 @@ public:
void BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude = NULL);
void BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude);
void BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
+ void BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
void BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
void BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL);
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 9443cf2c9..6ee9d9e1d 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -30,7 +30,7 @@
#include "CompositeChat.h"
#include "Items/ItemSword.h"
-#include "md5/md5.h"
+#include "polarssl/md5.h"
@@ -232,22 +232,49 @@ AString cClientHandle::FormatMessageType(bool ShouldAppendChatPrefixes, eMessage
AString cClientHandle::GenerateOfflineUUID(const AString & a_Username)
{
+ // Online UUIDs are always version 4 (random)
+ // We use Version 3 (MD5 hash) UUIDs for the offline UUIDs
+ // This guarantees that they will never collide with an online UUID and can be distinguished.
// Proper format for a version 3 UUID is:
// xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, A, or B
// Generate an md5 checksum, and use it as base for the ID:
- MD5 Checksum(a_Username);
- AString UUID = Checksum.hexdigest();
- UUID[12] = '3'; // Version 3 UUID
- UUID[16] = '8'; // Variant 1 UUID
-
- // Now the digest doesn't have the UUID slashes, but the client requires them, so add them into the appropriate positions:
- UUID.insert(8, "-");
- UUID.insert(13, "-");
- UUID.insert(18, "-");
- UUID.insert(23, "-");
-
- return UUID;
+ unsigned char MD5[16];
+ md5((const unsigned char *)a_Username.c_str(), a_Username.length(), MD5);
+ MD5[6] &= 0x0f; // Need to trim to 4 bits only...
+ MD5[8] &= 0x0f; // ... otherwise %01x overflows into two chars
+ return Printf("%02x%02x%02x%02x-%02x%02x-3%01x%02x-8%01x%02x-%02x%02x%02x%02x%02x%02x",
+ MD5[0], MD5[1], MD5[2], MD5[3],
+ MD5[4], MD5[5], MD5[6], MD5[7],
+ MD5[8], MD5[9], MD5[10], MD5[11],
+ MD5[12], MD5[13], MD5[14], MD5[15]
+ );
+}
+
+
+
+
+
+bool cClientHandle::IsUUIDOnline(const AString & a_UUID)
+{
+ // Online UUIDs are always version 4 (random)
+ // We use Version 3 (MD5 hash) UUIDs for the offline UUIDs
+ // This guarantees that they will never collide with an online UUID and can be distinguished.
+ // The version-specifying char is at pos #12 of raw UUID, pos #14 in dashed-UUID.
+ switch (a_UUID.size())
+ {
+ case 32:
+ {
+ // This is the UUID format without dashes, the version char is at pos #12:
+ return (a_UUID[12] == '4');
+ }
+ case 36:
+ {
+ // This is the UUID format with dashes, the version char is at pos #14:
+ return (a_UUID[14] == '4');
+ }
+ }
+ return false;
}
@@ -336,6 +363,9 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID)
// Send scoreboard data
World->GetScoreBoard().SendTo(*this);
+ // Send statistics
+ SendStatistics(m_Player->GetStatManager());
+
// Delay the first ping until the client "settles down"
// This should fix #889, "BadCast exception, cannot convert bit to fm" error in client
cTimer t1;
@@ -953,6 +983,26 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
m_LastDigBlockY = a_BlockY;
m_LastDigBlockZ = a_BlockZ;
+ // Check for clickthrough-blocks:
+ /* When the user breaks a fire block, the client send the wrong block location.
+ We must find the right block with the face direction. */
+ if (a_BlockFace != BLOCK_FACE_NONE)
+ {
+ int pX = a_BlockX;
+ int pY = a_BlockY;
+ int pZ = a_BlockZ;
+
+ AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
+ cBlockHandler * Handler = cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(pX, pY, pZ));
+
+ if (Handler->IsClickedThrough())
+ {
+ cChunkInterface ChunkInterface(m_Player->GetWorld()->GetChunkMap());
+ Handler->OnDigging(ChunkInterface, *m_Player->GetWorld(), m_Player, pX, pY, pZ);
+ return;
+ }
+ }
+
if (
(m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately
cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too
@@ -979,22 +1029,6 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
ItemHandler->OnDiggingBlock(World, m_Player, m_Player->GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
-
- // Check for clickthrough-blocks:
- if (a_BlockFace != BLOCK_FACE_NONE)
- {
- int pX = a_BlockX;
- int pY = a_BlockY;
- int pZ = a_BlockZ;
-
- AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
- Handler = cBlockInfo::GetHandler(World->GetBlock(pX, pY, pZ));
-
- if (Handler->IsClickedThrough())
- {
- Handler->OnDigging(ChunkInterface, *World, m_Player, pX, pY, pZ);
- }
- }
}
@@ -1052,12 +1086,7 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo
void cClientHandle::FinishDigAnimation()
{
- if (
- !m_HasStartedDigging || // Hasn't received the DIG_STARTED packet
- (m_LastDigBlockX == -1) ||
- (m_LastDigBlockY == -1) ||
- (m_LastDigBlockZ == -1)
- )
+ if (!m_HasStartedDigging) // Hasn't received the DIG_STARTED packet
{
return;
}
@@ -1195,9 +1224,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
{
// A plugin won't let us eat, abort (send the proper packets to the client, too):
m_Player->AbortEating();
- return;
}
- return;
}
else
{
@@ -2045,9 +2072,9 @@ void cClientHandle::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializ
-void cClientHandle::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player)
+void cClientHandle::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
{
- m_Protocol->SendCollectPickup(a_Pickup, a_Player);
+ m_Protocol->SendCollectEntity(a_Entity, a_Player);
}
@@ -2369,9 +2396,9 @@ void cClientHandle::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effec
-void cClientHandle::SendRespawn(const cWorld & a_World)
+void cClientHandle::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks)
{
- m_Protocol->SendRespawn(a_World);
+ m_Protocol->SendRespawn(a_World, a_ShouldIgnoreDimensionChecks);
}
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index 0d883f3af..6f2c86b27 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -63,7 +63,7 @@ public:
const AString & GetIPString(void) const { return m_IPString; }
- cPlayer* GetPlayer() { return m_Player; } // tolua_export
+ cPlayer * GetPlayer(void) { return m_Player; } // tolua_export
const AString & GetUUID(void) const { return m_UUID; } // tolua_export
void SetUUID(const AString & a_UUID) { m_UUID = a_UUID; }
@@ -76,9 +76,16 @@ public:
/** Generates an UUID based on the player name provided.
This is used for the offline (non-auth) mode, when there's no UUID source.
- Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same. */
+ Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same.
+ Returns a 36-char UUID (with dashes). */
static AString GenerateOfflineUUID(const AString & a_Username); // tolua_export
+ /** Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID.
+ We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart.
+ Accepts both 32-char and 36-char UUIDs (with and without dashes).
+ If the string given is not a valid UUID, returns false. */
+ static bool IsUUIDOnline(const AString & a_UUID); // tolua_export
+
/** Formats the type of message with the proper color and prefix for sending to the client. **/
static AString FormatMessageType(bool ShouldAppendChatPrefixes, eMessageType a_ChatPrefix, const AString & a_AdditionalData);
@@ -116,7 +123,7 @@ public:
void SendChat (const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData = "");
void SendChat (const cCompositeChat & a_Message);
void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer);
- void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player);
+ void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player);
void SendDestroyEntity (const cEntity & a_Entity);
void SendDisconnect (const AString & a_Reason);
void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ);
@@ -149,7 +156,7 @@ public:
void SendPlayerSpawn (const cPlayer & a_Player);
void SendPluginMessage (const AString & a_Channel, const AString & a_Message); // Exported in ManualBindings.cpp
void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID);
- void SendRespawn (const cWorld & a_World);
+ void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false);
void SendExperience (void);
void SendExperienceOrb (const cExpOrb & a_ExpOrb);
void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode);
diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp
index 53a638ee5..0f1951351 100644
--- a/src/CraftingRecipes.cpp
+++ b/src/CraftingRecipes.cpp
@@ -59,6 +59,7 @@ cCraftingGrid::cCraftingGrid(const cCraftingGrid & a_Original) :
cCraftingGrid::~cCraftingGrid()
{
delete[] m_Items;
+ m_Items = NULL;
}
diff --git a/src/Defines.h b/src/Defines.h
index 563fc308c..ee91ee596 100644
--- a/src/Defines.h
+++ b/src/Defines.h
@@ -274,8 +274,19 @@ inline eBlockFace RotateBlockFaceCW(eBlockFace a_BlockFace)
}
}
-
-
+inline eBlockFace ReverseBlockFace(eBlockFace a_BlockFace)
+{
+ switch (a_BlockFace)
+ {
+ case BLOCK_FACE_YP: return BLOCK_FACE_YM;
+ case BLOCK_FACE_XP: return BLOCK_FACE_XM;
+ case BLOCK_FACE_ZP: return BLOCK_FACE_ZM;
+ case BLOCK_FACE_YM: return BLOCK_FACE_YP;
+ case BLOCK_FACE_XM: return BLOCK_FACE_XP;
+ case BLOCK_FACE_ZM: return BLOCK_FACE_ZP;
+ default: return a_BlockFace;
+ }
+}
/** Returns the textual representation of the BlockFace constant. */
diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp
index 8d2569125..d59088e72 100644
--- a/src/Entities/ArrowEntity.cpp
+++ b/src/Entities/ArrowEntity.cpp
@@ -3,6 +3,7 @@
#include "Player.h"
#include "ArrowEntity.h"
#include "../Chunk.h"
+#include "FastRandom.h"
@@ -24,9 +25,9 @@ cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a
SetYawFromSpeed();
SetPitchFromSpeed();
LOGD("Created arrow %d with speed {%.02f, %.02f, %.02f} and rot {%.02f, %.02f}",
- m_UniqueID, GetSpeedX(), GetSpeedY(), GetSpeedZ(),
- GetYaw(), GetPitch()
- );
+ m_UniqueID, GetSpeedX(), GetSpeedY(), GetSpeedZ(),
+ GetYaw(), GetPitch()
+ );
}
@@ -44,6 +45,10 @@ cArrowEntity::cArrowEntity(cPlayer & a_Player, double a_Force) :
m_bIsCollected(false),
m_HitBlockPos(0, 0, 0)
{
+ if (a_Player.IsGameModeCreative())
+ {
+ m_PickupState = psInCreative;
+ }
}
@@ -67,26 +72,24 @@ bool cArrowEntity::CanPickup(const cPlayer & a_Player) const
void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace)
-{
- if (a_HitFace == BLOCK_FACE_NONE) { return; }
-
- super::OnHitSolidBlock(a_HitPos, a_HitFace);
- int a_X = (int)a_HitPos.x, a_Y = (int)a_HitPos.y, a_Z = (int)a_HitPos.z;
-
- switch (a_HitFace)
+{
+ if (GetSpeed().EqualsEps(Vector3d(0, 0, 0), 0.0000001))
{
- case BLOCK_FACE_XM: // Strangely, bounding boxes / block tracers return the actual block for these two directions, so AddFace not needed
- case BLOCK_FACE_YM:
- {
- break;
- }
- default: AddFaceDirection(a_X, a_Y, a_Z, a_HitFace, true);
+ SetSpeed(GetLookVector().NormalizeCopy() * 0.1); // Ensure that no division by zero happens later
}
-
- m_HitBlockPos = Vector3i(a_X, a_Y, a_Z);
+
+ Vector3d Hit = a_HitPos;
+ Vector3d SinkMovement = (GetSpeed() / 800);
+ Hit += (SinkMovement * 0.01) / SinkMovement.Length(); // Make arrow sink into block a centimetre so it lodges (but not to far so it goes black clientside)
+
+ super::OnHitSolidBlock(Hit, a_HitFace);
+ Vector3i BlockHit = Hit.Floor();
+
+ int X = BlockHit.x, Y = BlockHit.y, Z = BlockHit.z;
+ m_HitBlockPos = Vector3i(X, Y, Z);
// Broadcast arrow hit sound
- m_World->BroadcastSoundEffect("random.bowhit", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
+ m_World->BroadcastSoundEffect("random.bowhit", X * 8, Y * 8, Z * 8, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
}
@@ -94,13 +97,7 @@ void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFa
void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos)
-{
- if (!a_EntityHit.IsMob() && !a_EntityHit.IsMinecart() && !a_EntityHit.IsPlayer() && !a_EntityHit.IsBoat())
- {
- // Not an entity that interacts with an arrow
- return;
- }
-
+{
int Damage = (int)(GetSpeed().Length() / 20 * m_DamageCoeff + 0.5);
if (m_IsCritical)
{
@@ -109,7 +106,7 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos)
a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, 1);
// Broadcast successful hit sound
- m_World->BroadcastSoundEffect("random.successful_hit", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
+ GetWorld()->BroadcastSoundEffect("random.successful_hit", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
Destroy();
}
@@ -120,16 +117,22 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos)
void cArrowEntity::CollectedBy(cPlayer * a_Dest)
{
- if ((m_IsInGround) && (!m_bIsCollected) && (CanPickup(*a_Dest)))
+ if (m_IsInGround && !m_bIsCollected && CanPickup(*a_Dest))
{
- int NumAdded = a_Dest->GetInventory().AddItem(E_ITEM_ARROW);
- if (NumAdded > 0) // Only play effects if there was space in inventory
+ // Do not add the arrow to the inventory when the player is in creative:
+ if (!a_Dest->IsGameModeCreative())
{
- m_World->BroadcastCollectPickup((const cPickup &)*this, *a_Dest);
- // Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;)
- m_World->BroadcastSoundEffect("random.pop", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
- m_bIsCollected = true;
+ int NumAdded = a_Dest->GetInventory().AddItem(E_ITEM_ARROW);
+ if (NumAdded == 0)
+ {
+ // No space in the inventory
+ return;
+ }
}
+
+ GetWorld()->BroadcastCollectEntity(*this, *a_Dest);
+ GetWorld()->BroadcastSoundEffect("random.pop", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
+ m_bIsCollected = true;
}
}
@@ -165,7 +168,7 @@ void cArrowEntity::Tick(float a_Dt, cChunk & a_Chunk)
if (!m_HasTeleported) // Sent a teleport already, don't do again
{
- if (m_HitGroundTimer > 1000.f) // Send after a second, could be less, but just in case
+ if (m_HitGroundTimer > 500.f) // Send after half a second, could be less, but just in case
{
m_World->BroadcastTeleportEntity(*this);
m_HasTeleported = true;
diff --git a/src/Entities/ArrowEntity.h b/src/Entities/ArrowEntity.h
index 1fe3032ee..76cb24449 100644
--- a/src/Entities/ArrowEntity.h
+++ b/src/Entities/ArrowEntity.h
@@ -58,8 +58,14 @@ public:
/// Sets the IsCritical flag
void SetIsCritical(bool a_IsCritical) { m_IsCritical = a_IsCritical; }
+
+ /** Gets the block arrow is in */
+ Vector3i GetBlockHit(void) const { return m_HitBlockPos; }
// tolua_end
+
+ /** Sets the block arrow is in. To be used by the MCA loader only! */
+ void SetBlockHit(const Vector3i & a_BlockHit) { m_HitBlockPos = a_BlockHit; }
protected:
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 06833e1ba..042c4b4c3 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -1092,7 +1092,10 @@ void cEntity::HandleAir(void)
if (IsSubmerged())
{
- SetSpeedY(1); // Float in the water
+ if (!IsPlayer()) // Players control themselves
+ {
+ SetSpeedY(1); // Float in the water
+ }
// Either reduce air level or damage player
if (m_AirLevel < 1)
@@ -1478,8 +1481,7 @@ void cEntity::SetWidth(double a_Width)
void cEntity::AddPosX(double a_AddPosX)
{
- m_Pos.x += a_AddPosX;
-
+ m_Pos.x += a_AddPosX;
}
@@ -1487,8 +1489,7 @@ void cEntity::AddPosX(double a_AddPosX)
void cEntity::AddPosY(double a_AddPosY)
{
- m_Pos.y += a_AddPosY;
-
+ m_Pos.y += a_AddPosY;
}
@@ -1496,8 +1497,7 @@ void cEntity::AddPosY(double a_AddPosY)
void cEntity::AddPosZ(double a_AddPosZ)
{
- m_Pos.z += a_AddPosZ;
-
+ m_Pos.z += a_AddPosZ;
}
@@ -1507,8 +1507,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_Pos.z += a_AddPosZ;
}
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index b5d5cc34c..867d87bb7 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -238,9 +238,9 @@ public:
void AddPosY (double a_AddPosY);
void AddPosZ (double a_AddPosZ);
void AddPosition(double a_AddPosX, double a_AddPosY, double a_AddPosZ);
- void AddPosition(const Vector3d & a_AddPos) { AddPosition(a_AddPos.x,a_AddPos.y,a_AddPos.z);}
+ void AddPosition(const Vector3d & a_AddPos) { AddPosition(a_AddPos.x, a_AddPos.y, a_AddPos.z); }
void AddSpeed (double a_AddSpeedX, double a_AddSpeedY, double a_AddSpeedZ);
- void AddSpeed (const Vector3d & a_AddSpeed) { AddSpeed(a_AddSpeed.x,a_AddSpeed.y,a_AddSpeed.z);}
+ void AddSpeed (const Vector3d & a_AddSpeed) { AddSpeed(a_AddSpeed.x, a_AddSpeed.y, a_AddSpeed.z); }
void AddSpeedX (double a_AddSpeedX);
void AddSpeedY (double a_AddSpeedY);
void AddSpeedZ (double a_AddSpeedZ);
diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp
index 0fd006485..24fa591da 100644
--- a/src/Entities/Pickup.cpp
+++ b/src/Entities/Pickup.cpp
@@ -30,7 +30,7 @@ public:
virtual bool Item(cEntity * a_Entity) override
{
- if (!a_Entity->IsPickup() || (a_Entity->GetUniqueID() == m_Pickup->GetUniqueID()) || a_Entity->IsDestroyed())
+ if (!a_Entity->IsPickup() || (a_Entity->GetUniqueID() <= m_Pickup->GetUniqueID()) || a_Entity->IsDestroyed())
{
return false;
}
@@ -38,10 +38,31 @@ public:
Vector3d EntityPos = a_Entity->GetPosition();
double Distance = (EntityPos - m_Position).Length();
- if ((Distance < 1.2) && ((cPickup *)a_Entity)->GetItem().IsEqual(m_Pickup->GetItem()))
+ cItem & Item = ((cPickup *)a_Entity)->GetItem();
+ if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem()))
{
- m_Pickup->GetItem().AddCount(((cPickup *)a_Entity)->GetItem().m_ItemCount);
- a_Entity->Destroy();
+ short CombineCount = Item.m_ItemCount;
+ if ((CombineCount + m_Pickup->GetItem().m_ItemCount) > Item.GetMaxStackSize())
+ {
+ CombineCount = Item.GetMaxStackSize() - m_Pickup->GetItem().m_ItemCount;
+ }
+
+ if (CombineCount <= 0)
+ {
+ return false;
+ }
+
+ m_Pickup->GetItem().AddCount((char)CombineCount);
+ Item.m_ItemCount -= CombineCount;
+
+ if (Item.m_ItemCount <= 0)
+ {
+ a_Entity->Destroy();
+ }
+ else
+ {
+ a_Entity->GetWorld()->BroadcastEntityMetadata(*a_Entity);
+ }
m_FoundMatchingPickup = true;
}
return false;
@@ -129,7 +150,7 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk)
}
}
- if (!IsDestroyed()) // Don't try to combine if someone has tried to combine me
+ if (!IsDestroyed() && (m_Item.m_ItemCount < m_Item.GetMaxStackSize())) // Don't combine into an already full pickup
{
cPickupCombiningCallback PickupCombiningCallback(GetPosition(), this);
m_World->ForEachEntity(PickupCombiningCallback); // Not ForEachEntityInChunk, otherwise pickups don't combine across chunk boundaries
@@ -203,10 +224,10 @@ bool cPickup::CollectedBy(cPlayer * a_Dest)
}
m_Item.m_ItemCount -= NumAdded;
- m_World->BroadcastCollectPickup(*this, *a_Dest);
+ m_World->BroadcastCollectEntity(*this, *a_Dest);
// Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;)
m_World->BroadcastSoundEffect("random.pop",(int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
- if (m_Item.m_ItemCount == 0)
+ if (m_Item.m_ItemCount <= 0)
{
// All of the pickup has been collected, schedule the pickup for destroying
m_bCollected = true;
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 77ab6d309..cc07c25a8 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -1,4 +1,4 @@
-
+
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Player.h"
@@ -8,6 +8,7 @@
#include "../World.h"
#include "../Bindings/PluginManager.h"
#include "../BlockEntities/BlockEntity.h"
+#include "../BlockEntities/EnderChestEntity.h"
#include "../GroupManager.h"
#include "../Group.h"
#include "../Root.h"
@@ -37,14 +38,15 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
: super(etPlayer, 0.6, 1.8)
, m_bVisible(true)
, m_FoodLevel(MAX_FOOD_LEVEL)
- , m_FoodSaturationLevel(5)
+ , m_FoodSaturationLevel(5.0)
, m_FoodTickTimer(0)
- , m_FoodExhaustionLevel(0)
+ , m_FoodExhaustionLevel(0.0)
, m_LastJumpHeight(0)
, m_LastGroundHeight(0)
, m_bTouchGround(false)
, m_Stance(0.0)
, m_Inventory(*this)
+ , m_EnderChestContents(9, 3)
, m_CurrentWindow(NULL)
, m_InventoryWindow(NULL)
, m_Color('-')
@@ -70,6 +72,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
, m_FloaterID(-1)
, m_Team(NULL)
, m_TicksUntilNextSave(PLAYER_INVENTORY_SAVE_INTERVAL)
+ , m_bIsTeleporting(false)
{
LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d",
a_PlayerName.c_str(), a_Client->GetIPString().c_str(),
@@ -145,6 +148,7 @@ cPlayer::~cPlayer(void)
m_ClientHandle = NULL;
delete m_InventoryWindow;
+ m_InventoryWindow = NULL;
LOGD("Player %p deleted", this);
}
@@ -223,7 +227,7 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
SendExperience();
}
- if (GetPosition() != m_LastPos) // Change in position from last tick?
+ if (!GetPosition().EqualsEps(m_LastPos, 0.01)) // Non negligible change in position from last tick?
{
// Apply food exhaustion from movement:
ApplyFoodExhaustionFromMovement();
@@ -410,6 +414,7 @@ void cPlayer::StartChargingBow(void)
LOGD("Player \"%s\" started charging their bow", GetName().c_str());
m_IsChargingBow = true;
m_BowCharge = 0;
+ m_World->BroadcastEntityMetadata(*this, m_ClientHandle);
}
@@ -422,6 +427,8 @@ int cPlayer::FinishChargingBow(void)
int res = m_BowCharge;
m_IsChargingBow = false;
m_BowCharge = 0;
+ m_World->BroadcastEntityMetadata(*this, m_ClientHandle);
+
return res;
}
@@ -434,6 +441,7 @@ void cPlayer::CancelChargingBow(void)
LOGD("Player \"%s\" cancelled charging their bow at a charge of %d", GetName().c_str(), m_BowCharge);
m_IsChargingBow = false;
m_BowCharge = 0;
+ m_World->BroadcastEntityMetadata(*this, m_ClientHandle);
}
@@ -515,7 +523,15 @@ void cPlayer::Heal(int a_Health)
void cPlayer::SetFoodLevel(int a_FoodLevel)
{
- m_FoodLevel = std::max(0, std::min(a_FoodLevel, (int)MAX_FOOD_LEVEL));
+ int FoodLevel = std::max(0, std::min(a_FoodLevel, (int)MAX_FOOD_LEVEL));
+
+ if (cRoot::Get()->GetPluginManager()->CallHookPlayerFoodLevelChange(*this, FoodLevel))
+ {
+ m_FoodSaturationLevel = 5.0;
+ return;
+ }
+
+ m_FoodLevel = FoodLevel;
SendHealth();
}
@@ -556,11 +572,9 @@ bool cPlayer::Feed(int a_Food, double a_Saturation)
{
return false;
}
-
- m_FoodLevel = std::min(a_Food + m_FoodLevel, (int)MAX_FOOD_LEVEL);
- m_FoodSaturationLevel = std::min(m_FoodSaturationLevel + a_Saturation, (double)m_FoodLevel);
-
- SendHealth();
+
+ SetFoodSaturationLevel(m_FoodSaturationLevel + a_Saturation);
+ SetFoodLevel(m_FoodLevel + a_Food);
return true;
}
@@ -944,14 +958,15 @@ void cPlayer::Respawn(void)
// Reset food level:
m_FoodLevel = MAX_FOOD_LEVEL;
- m_FoodSaturationLevel = 5;
+ m_FoodSaturationLevel = 5.0;
+ m_FoodExhaustionLevel = 0.0;
// Reset Experience
m_CurrentXp = 0;
m_LifetimeTotalXp = 0;
// ToDo: send score to client? How?
- m_ClientHandle->SendRespawn(*m_World);
+ m_ClientHandle->SendRespawn(*m_World, true);
// Extinguish the fire:
StopBurning();
@@ -1201,6 +1216,7 @@ void cPlayer::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ)
SetPosition(a_PosX, a_PosY, a_PosZ);
m_LastGroundHeight = (float)a_PosY;
m_LastJumpHeight = (float)a_PosY;
+ m_bIsTeleporting = true;
m_World->BroadcastTeleportEntity(*this, GetClientHandle());
m_ClientHandle->SendPlayerMoveLook();
@@ -1718,6 +1734,7 @@ bool cPlayer::LoadFromDisk()
}
m_Inventory.LoadFromJson(root["inventory"]);
+ cEnderChestEntity::LoadFromJson(root["enderchestinventory"], m_EnderChestContents);
m_LoadedWorldName = root.get("world", "world").asString();
@@ -1755,20 +1772,24 @@ bool cPlayer::SaveToDisk()
Json::Value JSON_Inventory;
m_Inventory.SaveToJson(JSON_Inventory);
+ Json::Value JSON_EnderChestInventory;
+ cEnderChestEntity::SaveToJson(JSON_EnderChestInventory, m_EnderChestContents);
+
Json::Value root;
- root["position"] = JSON_PlayerPosition;
- root["rotation"] = JSON_PlayerRotation;
- root["inventory"] = JSON_Inventory;
- root["health"] = m_Health;
- root["xpTotal"] = m_LifetimeTotalXp;
- root["xpCurrent"] = m_CurrentXp;
- root["air"] = m_AirLevel;
- root["food"] = m_FoodLevel;
- root["foodSaturation"] = m_FoodSaturationLevel;
- root["foodTickTimer"] = m_FoodTickTimer;
- root["foodExhaustion"] = m_FoodExhaustionLevel;
- root["world"] = GetWorld()->GetName();
- root["isflying"] = IsFlying();
+ root["position"] = JSON_PlayerPosition;
+ root["rotation"] = JSON_PlayerRotation;
+ root["inventory"] = JSON_Inventory;
+ root["enderchestinventory"] = JSON_EnderChestInventory;
+ root["health"] = m_Health;
+ root["xpTotal"] = m_LifetimeTotalXp;
+ root["xpCurrent"] = m_CurrentXp;
+ root["air"] = m_AirLevel;
+ root["food"] = m_FoodLevel;
+ root["foodSaturation"] = m_FoodSaturationLevel;
+ root["foodTickTimer"] = m_FoodTickTimer;
+ root["foodExhaustion"] = m_FoodExhaustionLevel;
+ root["world"] = GetWorld()->GetName();
+ root["isflying"] = IsFlying();
if (m_GameMode == GetWorld()->GetGameMode())
{
@@ -1870,16 +1891,13 @@ void cPlayer::TickBurning(cChunk & a_Chunk)
void cPlayer::HandleFood(void)
{
// Ref.: http://www.minecraftwiki.net/wiki/Hunger
-
+
if (IsGameModeCreative())
{
// Hunger is disabled for Creative
return;
}
-
- // Remember the food level before processing, for later comparison
- int LastFoodLevel = m_FoodLevel;
-
+
// Heal or damage, based on the food level, using the m_FoodTickTimer:
if ((m_FoodLevel > 17) || (m_FoodLevel <= 0))
{
@@ -1888,11 +1906,11 @@ void cPlayer::HandleFood(void)
{
m_FoodTickTimer = 0;
- if (m_FoodLevel >= 17)
+ if ((m_FoodLevel > 17) && (GetHealth() < GetMaxHealth()))
{
// Regenerate health from food, incur 3 pts of food exhaustion:
Heal(1);
- m_FoodExhaustionLevel += 3;
+ m_FoodExhaustionLevel += 3.0;
}
else if ((m_FoodLevel <= 0) && (m_Health > 1))
{
@@ -1903,24 +1921,19 @@ void cPlayer::HandleFood(void)
}
// Apply food exhaustion that has accumulated:
- if (m_FoodExhaustionLevel >= 4)
+ if (m_FoodExhaustionLevel >= 4.0)
{
- m_FoodExhaustionLevel -= 4;
+ m_FoodExhaustionLevel -= 4.0;
- if (m_FoodSaturationLevel >= 1)
+ if (m_FoodSaturationLevel >= 1.0)
{
- m_FoodSaturationLevel -= 1;
+ m_FoodSaturationLevel -= 1.0;
}
else
{
- m_FoodLevel = std::max(m_FoodLevel - 1, 0);
+ SetFoodLevel(m_FoodLevel - 1);
}
}
-
- if (m_FoodLevel != LastFoodLevel)
- {
- SendHealth();
- }
}
@@ -2043,6 +2056,11 @@ void cPlayer::ApplyFoodExhaustionFromMovement()
{
return;
}
+ if (m_bIsTeleporting)
+ {
+ m_bIsTeleporting = false;
+ return;
+ }
// If riding anything, apply no food exhaustion
if (m_AttachedTo != NULL)
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index e80b82901..2053305ea 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -124,6 +124,9 @@ public:
inline double GetStance(void) const { return GetPosY() + 1.62; } // tolua_export // TODO: Proper stance when crouching etc.
inline cInventory & GetInventory(void) { return m_Inventory; } // tolua_export
inline const cInventory & GetInventory(void) const { return m_Inventory; }
+
+ /** Gets the contents of the player's associated enderchest */
+ cItemGrid & GetEnderChestContents(void) { return m_EnderChestContents; }
inline const cItem & GetEquippedItem(void) const { return GetInventory().GetEquippedItem(); } // tolua_export
@@ -402,7 +405,7 @@ public:
// cEntity overrides:
virtual bool IsCrouched (void) const { return m_IsCrouched; }
virtual bool IsSprinting(void) const { return m_IsSprinting; }
- virtual bool IsRclking (void) const { return IsEating(); }
+ virtual bool IsRclking (void) const { return IsEating() || IsChargingBow(); }
virtual void Detach(void);
@@ -444,7 +447,13 @@ protected:
float m_LastGroundHeight;
bool m_bTouchGround;
double m_Stance;
+
+ /** Stores the player's inventory, consisting of crafting grid, hotbar, and main slots */
cInventory m_Inventory;
+
+ /** An item grid that stores the player specific enderchest contents */
+ cItemGrid m_EnderChestContents;
+
cWindow * m_CurrentWindow;
cWindow * m_InventoryWindow;
@@ -505,8 +514,6 @@ protected:
cStatManager m_Stats;
-
-
/** Sets the speed and sends it to the client, so that they are forced to move so. */
virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override;
@@ -541,6 +548,11 @@ protected:
Default save interval is #defined in PLAYER_INVENTORY_SAVE_INTERVAL */
unsigned int m_TicksUntilNextSave;
+ /** Flag used by food handling system to determine whether a teleport has just happened
+ Will not apply food penalties if found to be true; will set to false after processing
+ */
+ bool m_bIsTeleporting;
+
} ; // tolua_export
diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp
index 664f929f6..c2d97589f 100644
--- a/src/Entities/ProjectileEntity.cpp
+++ b/src/Entities/ProjectileEntity.cpp
@@ -22,6 +22,7 @@
#include "FireworkEntity.h"
#include "GhastFireballEntity.h"
#include "WitherSkullEntity.h"
+#include "Player.h"
@@ -68,16 +69,17 @@ protected:
if (cBlockInfo::IsSolid(a_BlockType))
{
- // The projectile hit a solid block
- // Calculate the exact hit coords:
- cBoundingBox bb(a_BlockX, a_BlockX + 1, a_BlockY, a_BlockY + 1, a_BlockZ, a_BlockZ + 1);
- Vector3d Line1 = m_Projectile->GetPosition();
- Vector3d Line2 = Line1 + m_Projectile->GetSpeed();
- double LineCoeff = 0;
- eBlockFace Face;
- if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face))
+ // The projectile hit a solid block, calculate the exact hit coords:
+ cBoundingBox bb(a_BlockX, a_BlockX + 1, a_BlockY, a_BlockY + 1, a_BlockZ, a_BlockZ + 1); // Bounding box of the block hit
+ const Vector3d LineStart = m_Projectile->GetPosition(); // Start point for the imaginary line that goes through the block hit
+ const Vector3d LineEnd = LineStart + m_Projectile->GetSpeed(); // End point for the imaginary line that goes through the block hit
+ double LineCoeff = 0; // Used to calculate where along the line an intersection with the bounding box occurs
+ eBlockFace Face; // Face hit
+
+ if (bb.CalcLineIntersection(LineStart, LineEnd, LineCoeff, Face))
{
- Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff;
+ Vector3d Intersection = LineStart + m_Projectile->GetSpeed() * LineCoeff; // Point where projectile goes into the hit block
+
if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, a_BlockX, a_BlockY, a_BlockZ, Face, &Intersection))
{
return false;
@@ -141,7 +143,7 @@ public:
{
if (
(a_Entity == m_Projectile) || // Do not check collisions with self
- (a_Entity == m_Projectile->GetCreator()) // Do not check whoever shot the projectile
+ (a_Entity->GetUniqueID() == m_Projectile->GetCreatorUniqueID()) // Do not check whoever shot the projectile
)
{
// TODO: Don't check creator only for the first 5 ticks
@@ -162,7 +164,12 @@ public:
return false;
}
- // TODO: Some entities don't interact with the projectiles (pickups, falling blocks)
+ if (!a_Entity->IsMob() && !a_Entity->IsMinecart() && !a_Entity->IsPlayer() && !a_Entity->IsBoat())
+ {
+ // Not an entity that interacts with a projectile
+ return false;
+ }
+
if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, *a_Entity))
{
// A plugin disagreed.
@@ -210,7 +217,10 @@ protected:
cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, double a_Width, double a_Height) :
super(etProjectile, a_X, a_Y, a_Z, a_Width, a_Height),
m_ProjectileKind(a_Kind),
- m_Creator(a_Creator),
+ m_CreatorData(
+ ((a_Creator != NULL) ? a_Creator->GetUniqueID() : -1),
+ ((a_Creator != NULL) ? (a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : "") : "")
+ ),
m_IsInGround(false)
{
}
@@ -222,7 +232,7 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a
cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Vector3d & a_Pos, const Vector3d & a_Speed, double a_Width, double a_Height) :
super(etProjectile, a_Pos.x, a_Pos.y, a_Pos.z, a_Width, a_Height),
m_ProjectileKind(a_Kind),
- m_Creator(a_Creator),
+ m_CreatorData(a_Creator->GetUniqueID(), a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : ""),
m_IsInGround(false)
{
SetSpeed(a_Speed);
@@ -300,7 +310,7 @@ AString cProjectileEntity::GetMCAClassName(void) const
case pkEgg: return "Egg";
case pkGhastFireball: return "Fireball";
case pkFireCharge: return "SmallFireball";
- case pkEnderPearl: return "ThrownEnderPearl";
+ case pkEnderPearl: return "ThrownEnderpearl";
case pkExpBottle: return "ThrownExpBottle";
case pkSplashPotion: return "ThrownPotion";
case pkWitherSkull: return "WitherSkull";
@@ -318,8 +328,9 @@ AString cProjectileEntity::GetMCAClassName(void) const
void cProjectileEntity::Tick(float a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
-
- if (GetProjectileKind() != pkArrow) // See cArrow::Tick
+
+ // TODO: see BroadcastMovementUpdate; RelativeMove packet jerkiness affects projectiles too (cause of sympton described in cArrowEntity::Tick())
+ if (GetProjectileKind() != pkArrow)
{
BroadcastMovementUpdate();
}
@@ -337,19 +348,10 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
return;
}
- Vector3d PerTickSpeed = GetSpeed() / 20;
- Vector3d Pos = GetPosition();
-
- // Trace the tick's worth of movement as a line:
- Vector3d NextPos = Pos + PerTickSpeed;
- cProjectileTracerCallback TracerCallback(this);
- if (!cLineBlockTracer::Trace(*m_World, TracerCallback, Pos, NextPos))
- {
- // Something has been hit, abort all other processing
- return;
- }
- // The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later in its SlowdownCoeff
-
+ const Vector3d PerTickSpeed = GetSpeed() / 20;
+ const Vector3d Pos = GetPosition();
+ const Vector3d NextPos = Pos + PerTickSpeed;
+
// Test for entity collisions:
cProjectileEntityCollisionCallback EntityCollisionCallback(this, Pos, NextPos);
a_Chunk.ForEachEntity(EntityCollisionCallback);
@@ -366,10 +368,19 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
HitPos.x, HitPos.y, HitPos.z,
EntityCollisionCallback.GetMinCoeff()
);
-
+
OnHitEntity(*(EntityCollisionCallback.GetHitEntity()), HitPos);
}
// TODO: Test the entities in the neighboring chunks, too
+
+ // Trace the tick's worth of movement as a line:
+ cProjectileTracerCallback TracerCallback(this);
+ if (!cLineBlockTracer::Trace(*m_World, TracerCallback, Pos, NextPos))
+ {
+ // Something has been hit, abort all other processing
+ return;
+ }
+ // The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later in its SlowdownCoeff
// Update the position:
SetPosition(NextPos);
diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h
index ae06b072f..7b38169e2 100644
--- a/src/Entities/ProjectileEntity.h
+++ b/src/Entities/ProjectileEntity.h
@@ -66,8 +66,15 @@ public:
/// Returns the kind of the projectile (fast class identification)
eKind GetProjectileKind(void) const { return m_ProjectileKind; }
- /// Returns the entity who created this projectile; may be NULL
- cEntity * GetCreator(void) { return m_Creator; }
+ /** Returns the unique ID of the entity who created this projectile
+ May return an ID <0
+ */
+ int GetCreatorUniqueID(void) { return m_CreatorData.m_UniqueID; }
+
+ /** Returns the name of the player that created the projectile
+ Will be empty for non-player creators
+ */
+ AString GetCreatorName(void) const { return m_CreatorData.m_Name; }
/// Returns the string that is used as the entity type (class name) in MCA files
AString GetMCAClassName(void) const;
@@ -81,10 +88,29 @@ public:
void SetIsInGround(bool a_IsInGround) { m_IsInGround = a_IsInGround; }
protected:
+
+ /** A structure that stores the Entity ID and Playername of the projectile's creator
+ Used to migitate invalid pointers caused by the creator being destroyed
+ */
+ struct CreatorData
+ {
+ CreatorData(int a_UniqueID, const AString & a_Name) :
+ m_UniqueID(a_UniqueID),
+ m_Name(a_Name)
+ {
+ }
+
+ const int m_UniqueID;
+ AString m_Name;
+ };
+
+ /** The type of projectile I am */
eKind m_ProjectileKind;
- /// The entity who has created this projectile; may be NULL (e. g. for dispensers)
- cEntity * m_Creator;
+ /** The structure for containing the entity ID and name who has created this projectile
+ The ID and/or name may be NULL (e.g. for dispensers/mobs)
+ */
+ CreatorData m_CreatorData;
/// True if the projectile has hit the ground and is stuck there
bool m_IsInGround;
diff --git a/src/Entities/ThrownEggEntity.cpp b/src/Entities/ThrownEggEntity.cpp
index 224019091..456083108 100644
--- a/src/Entities/ThrownEggEntity.cpp
+++ b/src/Entities/ThrownEggEntity.cpp
@@ -8,7 +8,8 @@
cThrownEggEntity::cThrownEggEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) :
- super(pkEgg, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25)
+ super(pkEgg, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25),
+ m_DestroyTimer(-1)
{
SetSpeed(a_Speed);
}
@@ -21,7 +22,7 @@ void cThrownEggEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_H
{
TrySpawnChicken(a_HitPos);
- Destroy();
+ m_DestroyTimer = 2;
}
@@ -36,7 +37,7 @@ void cThrownEggEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_Hit
TrySpawnChicken(a_HitPos);
a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1);
- Destroy(true);
+ m_DestroyTimer = 5;
}
diff --git a/src/Entities/ThrownEggEntity.h b/src/Entities/ThrownEggEntity.h
index 5ba8f051b..dc72c279f 100644
--- a/src/Entities/ThrownEggEntity.h
+++ b/src/Entities/ThrownEggEntity.h
@@ -30,8 +30,29 @@ protected:
// cProjectileEntity overrides:
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
virtual void OnHitEntity (cEntity & a_EntityHit, const Vector3d & a_HitPos) override;
+ virtual void Tick (float a_Dt, cChunk & a_Chunk) override
+ {
+ if (m_DestroyTimer > 0)
+ {
+ m_DestroyTimer--;
+ if (m_DestroyTimer == 0)
+ {
+ Destroy();
+ return;
+ }
+ }
+ else
+ {
+ super::Tick(a_Dt, a_Chunk);
+ }
+ }
// Randomly decides whether to spawn a chicken where the egg lands.
void TrySpawnChicken(const Vector3d & a_HitPos);
+
+private:
+
+ /** Time in ticks to wait for the hit animation to begin before destroying */
+ int m_DestroyTimer;
} ; // tolua_export
diff --git a/src/Entities/ThrownEnderPearlEntity.cpp b/src/Entities/ThrownEnderPearlEntity.cpp
index c37161145..c7407e6ae 100644
--- a/src/Entities/ThrownEnderPearlEntity.cpp
+++ b/src/Entities/ThrownEnderPearlEntity.cpp
@@ -1,13 +1,15 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "ThrownEnderPearlEntity.h"
+#include "Player.h"
cThrownEnderPearlEntity::cThrownEnderPearlEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) :
- super(pkEnderPearl, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25)
+ super(pkEnderPearl, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25),
+ m_DestroyTimer(-1)
{
SetSpeed(a_Speed);
}
@@ -21,7 +23,7 @@ void cThrownEnderPearlEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockF
// TODO: Tweak a_HitPos based on block face.
TeleportCreator(a_HitPos);
- Destroy();
+ m_DestroyTimer = 2;
}
@@ -36,7 +38,7 @@ void cThrownEnderPearlEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d
TeleportCreator(a_HitPos);
a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1);
- Destroy(true);
+ m_DestroyTimer = 5;
}
@@ -45,10 +47,34 @@ void cThrownEnderPearlEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d
void cThrownEnderPearlEntity::TeleportCreator(const Vector3d & a_HitPos)
{
- // Teleport the creator here, make them take 5 damage:
- if (m_Creator != NULL)
+ if (m_CreatorData.m_Name.empty())
{
- m_Creator->TeleportToCoords(a_HitPos.x + 0.5, a_HitPos.y + 1.7, a_HitPos.z + 0.5);
- m_Creator->TakeDamage(dtEnderPearl, this, 5, 0);
+ return;
}
+
+ class cProjectileCreatorCallbackForPlayers : public cPlayerListCallback
+ {
+ public:
+ cProjectileCreatorCallbackForPlayers(cEntity * a_Attacker, Vector3i a_HitPos) :
+ m_Attacker(a_Attacker),
+ m_HitPos(a_HitPos)
+ {
+ }
+
+ virtual bool Item(cPlayer * a_Entity) override
+ {
+ // Teleport the creator here, make them take 5 damage:
+ a_Entity->TeleportToCoords(m_HitPos.x, m_HitPos.y + 0.2, m_HitPos.z);
+ a_Entity->TakeDamage(dtEnderPearl, m_Attacker, 5, 0);
+ return true;
+ }
+
+ private:
+
+ cEntity * m_Attacker;
+ Vector3i m_HitPos;
+ };
+
+ cProjectileCreatorCallbackForPlayers PCCFP(this, a_HitPos);
+ GetWorld()->FindAndDoWithPlayer(m_CreatorData.m_Name, PCCFP);
}
diff --git a/src/Entities/ThrownEnderPearlEntity.h b/src/Entities/ThrownEnderPearlEntity.h
index ddee5babe..1cea5f7d9 100644
--- a/src/Entities/ThrownEnderPearlEntity.h
+++ b/src/Entities/ThrownEnderPearlEntity.h
@@ -30,8 +30,29 @@ protected:
// cProjectileEntity overrides:
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
virtual void OnHitEntity (cEntity & a_EntityHit, const Vector3d & a_HitPos) override;
-
- // Teleports the creator where the ender pearl lands.
+ virtual void Tick (float a_Dt, cChunk & a_Chunk) override
+ {
+ if (m_DestroyTimer > 0)
+ {
+ m_DestroyTimer--;
+ if (m_DestroyTimer == 0)
+ {
+ Destroy();
+ return;
+ }
+ }
+ else
+ {
+ super::Tick(a_Dt, a_Chunk);
+ }
+ }
+
+ /** Teleports the creator where the ender pearl lands */
void TeleportCreator(const Vector3d & a_HitPos);
+
+private:
+
+ /** Time in ticks to wait for the hit animation to begin before destroying */
+ int m_DestroyTimer;
} ; // tolua_export
diff --git a/src/Entities/ThrownSnowballEntity.cpp b/src/Entities/ThrownSnowballEntity.cpp
index 427f630f7..d94e75898 100644
--- a/src/Entities/ThrownSnowballEntity.cpp
+++ b/src/Entities/ThrownSnowballEntity.cpp
@@ -8,7 +8,8 @@
cThrownSnowballEntity::cThrownSnowballEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) :
- super(pkSnowball, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25)
+ super(pkSnowball, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25),
+ m_DestroyTimer(-1)
{
SetSpeed(a_Speed);
}
@@ -19,7 +20,7 @@ cThrownSnowballEntity::cThrownSnowballEntity(cEntity * a_Creator, double a_X, do
void cThrownSnowballEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace)
{
- Destroy();
+ m_DestroyTimer = 2;
}
@@ -36,13 +37,9 @@ void cThrownSnowballEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d &
{
TotalDamage = 3;
}
- else if (MobType == cMonster::mtEnderDragon)
- {
- TotalDamage = 1;
- }
}
// TODO: If entity is Ender Crystal, destroy it
a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1);
- Destroy(true);
+ m_DestroyTimer = 5;
}
diff --git a/src/Entities/ThrownSnowballEntity.h b/src/Entities/ThrownSnowballEntity.h
index a09512e37..9a8770379 100644
--- a/src/Entities/ThrownSnowballEntity.h
+++ b/src/Entities/ThrownSnowballEntity.h
@@ -30,5 +30,26 @@ protected:
// cProjectileEntity overrides:
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override;
virtual void OnHitEntity (cEntity & a_EntityHit, const Vector3d & a_HitPos) override;
+ virtual void Tick (float a_Dt, cChunk & a_Chunk) override
+ {
+ if (m_DestroyTimer > 0)
+ {
+ m_DestroyTimer--;
+ if (m_DestroyTimer == 0)
+ {
+ Destroy();
+ return;
+ }
+ }
+ else
+ {
+ super::Tick(a_Dt, a_Chunk);
+ }
+ }
+
+private:
+
+ /** Time in ticks to wait for the hit animation to begin before destroying */
+ int m_DestroyTimer;
} ; // tolua_export
diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp
index bd7fd8079..8add9610c 100644
--- a/src/FurnaceRecipe.cpp
+++ b/src/FurnaceRecipe.cpp
@@ -5,7 +5,8 @@
#include "Item.h"
#include <fstream>
-#include <sstream>
+
+#define FURNACE_RECIPE_FILE "furnace.txt"
@@ -42,6 +43,7 @@ cFurnaceRecipe::~cFurnaceRecipe()
{
ClearRecipes();
delete m_pState;
+ m_pState = NULL;
}
@@ -53,128 +55,207 @@ void cFurnaceRecipe::ReloadRecipes(void)
ClearRecipes();
LOGD("Loading furnace recipes...");
- std::ifstream f;
- char a_File[] = "furnace.txt";
- f.open(a_File, std::ios::in);
-
+ std::ifstream f(FURNACE_RECIPE_FILE, std::ios::in);
if (!f.good())
{
- f.close();
- LOG("Could not open the furnace recipes file \"%s\"", a_File);
+ LOG("Could not open the furnace recipes file \"%s\". No furnace recipes are available.", FURNACE_RECIPE_FILE);
return;
}
+
+ unsigned int LineNum = 0;
+ AString ParsingLine;
- // TODO: Replace this messy parse with a high-level-structured one (ReadLine / ProcessLine)
- bool bSyntaxError = false;
- while (f.good())
+ while (std::getline(f, ParsingLine))
{
- char c;
+ LineNum++;
+ ParsingLine.erase(std::remove_if(ParsingLine.begin(), ParsingLine.end(), isspace), ParsingLine.end()); // Remove ALL whitespace from the line
+ if (ParsingLine.empty())
+ {
+ continue;
+ }
- //////////////////////////////////////////////////////////////////////////
- // comments
- f >> c;
- f.unget();
- if( c == '#' )
+ switch (ParsingLine[0])
{
- while( f.good() && c != '\n' )
+ case '#':
{
- f.get( c );
+ // Comment
+ break;
}
- continue;
- }
+
+ case '!':
+ {
+ AddFuelFromLine(ParsingLine, LineNum);
+ break;
+ }
+
+ default:
+ {
+ AddRecipeFromLine(ParsingLine, LineNum);
+ break;
+ }
+ } // switch (ParsingLine[0])
+ } // while (getline(ParsingLine))
+
+ LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size());
+}
+
+
+
+
+
+void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, int a_LineNum)
+{
+ // Fuel
+ int IItemID = 0, IItemCount = 0, IItemHealth = 0, IBurnTime = 0;
+ AString::size_type BeginPos = 1; // Begin at one after exclamation mark (bang)
+
+ if (
+ !ReadMandatoryNumber(BeginPos, ":", a_Line, a_LineNum, IItemID) || // Read item ID
+ !ReadOptionalNumbers(BeginPos, ":", "=", a_Line, a_LineNum, IItemCount, IItemHealth) || // Read item count (and optionally health)
+ !ReadMandatoryNumber(BeginPos, "0123456789", a_Line, a_LineNum, IBurnTime, true) // Read item burn time - last value
+ )
+ {
+ return;
+ }
+
+ // Add to fuel list:
+ Fuel F;
+ F.In = new cItem((ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth);
+ F.BurnTime = IBurnTime;
+ m_pState->Fuel.push_back(F);
+}
+
+
+
+
+
+void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, int a_LineNum)
+{
+ int IItemID = 0, IItemCount = 0, IItemHealth = 0, IBurnTime = 0;
+ int OItemID = 0, OItemCount = 0, OItemHealth = 0;
+ AString::size_type BeginPos = 0; // Begin at start of line
+
+ if (
+ !ReadMandatoryNumber(BeginPos, ":", a_Line, a_LineNum, IItemID) || // Read item ID
+ !ReadOptionalNumbers(BeginPos, ":", "@", a_Line, a_LineNum, IItemCount, IItemHealth) || // Read item count (and optionally health)
+ !ReadMandatoryNumber(BeginPos, "=", a_Line, a_LineNum, IBurnTime) || // Read item burn time
+ !ReadMandatoryNumber(BeginPos, ":", a_Line, a_LineNum, OItemID) || // Read result ID
+ !ReadOptionalNumbers(BeginPos, ":", "012456789", a_Line, a_LineNum, OItemCount, OItemHealth, true) // Read result count (and optionally health) - last value
+ )
+ {
+ return;
+ }
+
+ // Add to recipe list
+ Recipe R;
+ R.In = new cItem((ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth);
+ R.Out = new cItem((ENUM_ITEM_ID)OItemID, (char)OItemCount, (short)OItemHealth);
+ R.CookTime = IBurnTime;
+ m_pState->Recipes.push_back(R);
+}
+
+
+
- //////////////////////////////////////////////////////////////////////////
- // Line breaks
- f.get( c );
- while( f.good() && ( c == '\n' || c == '\r' ) ) { f.get( c ); }
- if (f.eof())
+void cFurnaceRecipe::PrintParseError(unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing)
+{
+ LOGWARN("Error parsing furnace recipes at line %i pos " SIZE_T_FMT ": missing '%s'", a_Line, a_Position, a_CharactersMissing.c_str());
+}
+
+
+
+
+
+bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const AString & a_Delimiter, const AString & a_Text, unsigned int a_Line, int & a_Value, bool a_IsLastValue)
+{
+ // TODO: replace atoi with std::stoi
+ AString::size_type End;
+ if (a_IsLastValue)
+ {
+ End = a_Text.find_first_not_of(a_Delimiter, a_Begin);
+ }
+ else
+ {
+ End = a_Text.find_first_of(a_Delimiter, a_Begin);
+ if (End == AString::npos)
{
- break;
+ PrintParseError(a_Line, a_Begin, a_Delimiter);
+ return false;
}
- f.unget();
+ }
+
+ // stoi won't throw an exception if the string is alphanumeric, we should check for this
+ if (!DoesStringContainOnlyNumbers(a_Text.substr(a_Begin, End - a_Begin)))
+ {
+ PrintParseError(a_Line, a_Begin, "number");
+ return false;
+ }
+ a_Value = atoi(a_Text.substr(a_Begin, End - a_Begin).c_str());
+
+ a_Begin = End + 1; // Jump over delimiter
+ return true;
+}
+
+
+
+
- //////////////////////////////////////////////////////////////////////////
- // Check for fuel
- f >> c;
- if( c == '!' ) // It's fuel :)
+bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const AString & a_DelimiterOne, const AString & a_DelimiterTwo, const AString & a_Text, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue)
+{
+ // TODO: replace atoi with std::stoi
+ AString::size_type End, Begin = a_Begin;
+
+ End = a_Text.find_first_of(a_DelimiterOne, Begin);
+ if (End != AString::npos)
+ {
+ if (DoesStringContainOnlyNumbers(a_Text.substr(Begin, End - Begin)))
{
- // Read item
- int IItemID = 0, IItemCount = 0, IItemHealth = 0;
- f >> IItemID;
- f >> c; if( c != ':' ) { bSyntaxError = true; break; }
- f >> IItemCount;
-
- // Optional health
- f >> c;
- if( c != ':' )
- f.unget();
+ a_ValueOne = std::atoi(a_Text.substr(Begin, End - Begin).c_str());
+ Begin = End + 1;
+
+ if (a_IsLastValue)
+ {
+ End = a_Text.find_first_not_of(a_DelimiterTwo, Begin);
+ }
else
{
- f >> IItemHealth;
+ End = a_Text.find_first_of(a_DelimiterTwo, Begin);
+ if (End == AString::npos)
+ {
+ PrintParseError(a_Line, Begin, a_DelimiterTwo);
+ return false;
+ }
}
- // Burn time
- int BurnTime;
- f >> c; if( c != '=' ) { bSyntaxError = true; break; }
- f >> BurnTime;
+ // stoi won't throw an exception if the string is alphanumeric, we should check for this
+ if (!DoesStringContainOnlyNumbers(a_Text.substr(Begin, End - Begin)))
+ {
+ PrintParseError(a_Line, Begin, "number");
+ return false;
+ }
+ a_ValueTwo = atoi(a_Text.substr(Begin, End - Begin).c_str());
- // Add to fuel list
- Fuel F;
- F.In = new cItem( (ENUM_ITEM_ID) IItemID, (char)IItemCount, (short)IItemHealth );
- F.BurnTime = BurnTime;
- m_pState->Fuel.push_back( F );
- continue;
+ a_Begin = End + 1; // Jump over delimiter
+ return true;
}
- f.unget();
-
- //////////////////////////////////////////////////////////////////////////
- // Read items
- int IItemID = 0, IItemCount = 0, IItemHealth = 0;
- f >> IItemID;
- f >> c; if( c != ':' ) { bSyntaxError = true; break; }
- f >> IItemCount;
-
- // Optional health
- f >> c;
- if( c != ':' )
- f.unget();
else
{
- f >> IItemHealth;
+ return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_Line, a_ValueOne, a_IsLastValue);
}
+ }
+
+ return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_Line, a_ValueOne, a_IsLastValue);
+}
- int CookTime;
- f >> c; if( c != '@' ) { bSyntaxError = true; break; }
- f >> CookTime;
- int OItemID = 0, OItemCount = 0, OItemHealth = 0;
- f >> c; if( c != '=' ) { bSyntaxError = true; break; }
- f >> OItemID;
- f >> c; if( c != ':' ) { bSyntaxError = true; break; }
- f >> OItemCount;
- // Optional health
- f >> c;
- if( c != ':' )
- f.unget();
- else
- {
- f >> OItemHealth;
- }
- // Add to recipe list
- Recipe R;
- R.In = new cItem( (ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth );
- R.Out = new cItem( (ENUM_ITEM_ID)OItemID, (char)OItemCount, (short)OItemHealth );
- R.CookTime = CookTime;
- m_pState->Recipes.push_back( R );
- }
- if (bSyntaxError)
- {
- LOGERROR("ERROR: FurnaceRecipe, syntax error" );
- }
- LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size());
+
+bool cFurnaceRecipe::DoesStringContainOnlyNumbers(const AString & a_String)
+{
+ // TODO: replace this with std::all_of(a_String.begin(), a_String.end(), isdigit)
+ return (a_String.find_first_not_of("0123456789") == AString::npos);
}
@@ -187,7 +268,9 @@ void cFurnaceRecipe::ClearRecipes(void)
{
Recipe R = *itr;
delete R.In;
+ R.In = NULL;
delete R.Out;
+ R.Out = NULL;
}
m_pState->Recipes.clear();
@@ -195,6 +278,7 @@ void cFurnaceRecipe::ClearRecipes(void)
{
Fuel F = *itr;
delete F.In;
+ F.In = NULL;
}
m_pState->Fuel.clear();
}
diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h
index 2f91e9bcb..77ed35a57 100644
--- a/src/FurnaceRecipe.h
+++ b/src/FurnaceRecipe.h
@@ -41,6 +41,36 @@ public:
private:
void ClearRecipes(void);
+ /** Parses the fuel contained in the line, adds it to m_pState's fuels.
+ Logs a warning to the console on input error. */
+ void AddFuelFromLine(const AString & a_Line, int a_LineNum);
+
+ /** Parses the recipe contained in the line, adds it to m_pState's recipes.
+ Logs a warning to the console on input error. */
+ void AddRecipeFromLine(const AString & a_Line, int a_LineNum);
+
+ /** Calls LOGWARN with the line, position, and error */
+ static void PrintParseError(unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing);
+
+ /** Reads a number from a string given, starting at a given position and ending at a delimiter given
+ Updates beginning position to the delimiter found + 1, and updates the value to the one read
+ If it encounters a substring that is not fully numeric, it will call SetParseError() and return false; the caller should abort processing
+ Otherwise, the function will return true
+ */
+ static bool ReadMandatoryNumber(AString::size_type & a_Begin, const AString & a_Delimiter, const AString & a_Text, unsigned int a_Line, int & a_Value, bool a_IsLastValue = false);
+
+ /** Reads two numbers from a string given, starting at a given position and ending at the first delimiter given, then again (with an updated position) until the second delimiter given
+ Updates beginning position to the second delimiter found + 1, and updates the values to the ones read
+ If it encounters a substring that is not fully numeric whilst reading the second value, it will call SetParseError() and return false; the caller should abort processing
+ If this happens whilst reading the first value, it will call ReadMandatoryNumber() with the appropriate position, as this may legitimately occur with the optional value and AString::find_first_of finding the incorrect delimiter. It will return the result of ReadMandatoryNumber()
+ True will be returned definitively for an optional value that is valid
+ */
+ static bool ReadOptionalNumbers(AString::size_type & a_Begin, const AString & a_DelimiterOne, const AString & a_DelimiterTwo, const AString & a_Text, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue = false);
+
+ /** Uses std::all_of to determine if a string contains only digits */
+ static bool DoesStringContainOnlyNumbers(const AString & a_String);
+
+
struct sFurnaceRecipeState;
sFurnaceRecipeState * m_pState;
};
diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp
index 47ba080c6..a17555f37 100644
--- a/src/Generating/BioGen.cpp
+++ b/src/Generating/BioGen.cpp
@@ -135,7 +135,9 @@ cBioGenCache::cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize) :
cBioGenCache::~cBioGenCache()
{
delete[] m_CacheData;
+ m_CacheData = NULL;
delete[] m_CacheOrder;
+ m_CacheOrder = NULL;
}
@@ -745,7 +747,12 @@ cBioGenTwoLevel::cBioGenTwoLevel(int a_Seed) :
m_VoronoiSmall(a_Seed + 2000),
m_DistortX(a_Seed + 3000),
m_DistortZ(a_Seed + 4000),
- m_Noise(a_Seed + 5000)
+ m_Noise1(a_Seed + 5001),
+ m_Noise2(a_Seed + 5002),
+ m_Noise3(a_Seed + 5003),
+ m_Noise4(a_Seed + 5004),
+ m_Noise5(a_Seed + 5005),
+ m_Noise6(a_Seed + 5006)
{
}
@@ -767,12 +774,12 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
int BlockZ = BaseZ + z * 4;
float BlockXF = (float)(16 * BlockX) / 128;
float BlockZF = (float)(16 * BlockZ) / 128;
- double NoiseX = m_Noise.CubicNoise3D(BlockXF / 16, BlockZF / 16, 1000);
- NoiseX += 0.5 * m_Noise.CubicNoise3D(BlockXF / 8, BlockZF / 8, 2000);
- NoiseX += 0.08 * m_Noise.CubicNoise3D(BlockXF, BlockZF, 3000);
- double NoiseZ = m_Noise.CubicNoise3D(BlockXF / 16, BlockZF / 16, 4000);
- NoiseZ += 0.5 * m_Noise.CubicNoise3D(BlockXF / 8, BlockZF / 8, 5000);
- NoiseZ += 0.08 * m_Noise.CubicNoise3D(BlockXF, BlockZF, 6000);
+ double NoiseX = m_Noise1.CubicNoise2D(BlockXF / 16, BlockZF / 16);
+ NoiseX += 0.5 * m_Noise2.CubicNoise2D(BlockXF / 8, BlockZF / 8);
+ NoiseX += 0.08 * m_Noise3.CubicNoise2D(BlockXF, BlockZF);
+ double NoiseZ = m_Noise4.CubicNoise2D(BlockXF / 16, BlockZF / 16);
+ NoiseZ += 0.5 * m_Noise5.CubicNoise2D(BlockXF / 8, BlockZF / 8);
+ NoiseZ += 0.08 * m_Noise6.CubicNoise2D(BlockXF, BlockZF);
DistortX[4 * x][4 * z] = BlockX + (int)(64 * NoiseX);
DistortZ[4 * x][4 * z] = BlockZ + (int)(64 * NoiseZ);
@@ -786,8 +793,8 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
{
for (int x = 0; x < cChunkDef::Width; x++)
{
- int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z]) / 7;
int MinDist1, MinDist2;
+ int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 7;
int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 11;
cChunkDef::SetBiome(a_BiomeMap, x, z, SelectBiome(BiomeGroup, BiomeIdx, (MinDist1 < MinDist2 / 4) ? 0 : 1));
}
diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h
index 8bd460d8f..227ec97d7 100644
--- a/src/Generating/BioGen.h
+++ b/src/Generating/BioGen.h
@@ -261,7 +261,12 @@ protected:
/// The noise used to distort the inupt Z coord
cPerlinNoise m_DistortZ;
- cNoise m_Noise;
+ cNoise m_Noise1;
+ cNoise m_Noise2;
+ cNoise m_Noise3;
+ cNoise m_Noise4;
+ cNoise m_Noise5;
+ cNoise m_Noise6;
// cBiomeGen overrides:
diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp
index 688d19c40..2da285d72 100644
--- a/src/Generating/CompoGen.cpp
+++ b/src/Generating/CompoGen.cpp
@@ -672,7 +672,9 @@ cCompoGenCache::cCompoGenCache(cTerrainCompositionGen & a_Underlying, int a_Cach
cCompoGenCache::~cCompoGenCache()
{
delete[] m_CacheData;
+ m_CacheData = NULL;
delete[] m_CacheOrder;
+ m_CacheOrder = NULL;
}
diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp
index 22941dcbe..7b6234161 100644
--- a/src/Generating/ComposableGenerator.cpp
+++ b/src/Generating/ComposableGenerator.cpp
@@ -26,6 +26,7 @@
#include "POCPieceGenerator.h"
#include "RainbowRoadsGen.h"
#include "Ravines.h"
+#include "TestRailsGen.h"
#include "UnderwaterBaseGen.h"
#include "VillageGen.h"
@@ -414,6 +415,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
{
m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed));
}
+ else if (NoCaseCompare(*itr, "TestRails") == 0)
+ {
+ m_FinishGens.push_back(new cTestRailsGen(Seed, 100, 1, 7, 50));
+ }
else if (NoCaseCompare(*itr, "Trees") == 0)
{
m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen));
diff --git a/src/Generating/GridStructGen.cpp b/src/Generating/GridStructGen.cpp
index 2931df3eb..95f8c38bc 100644
--- a/src/Generating/GridStructGen.cpp
+++ b/src/Generating/GridStructGen.cpp
@@ -88,8 +88,8 @@ void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructur
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)
+ ((*itr)->m_GridX >= MinX) && ((*itr)->m_GridX < MaxX) &&
+ ((*itr)->m_GridZ >= MinZ) && ((*itr)->m_GridZ < MaxZ)
)
{
// want
diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp
index 25ac912fd..202f7db7e 100644
--- a/src/Generating/HeiGen.cpp
+++ b/src/Generating/HeiGen.cpp
@@ -142,7 +142,9 @@ cHeiGenCache::cHeiGenCache(cTerrainHeightGen & a_HeiGenToCache, int a_CacheSize)
cHeiGenCache::~cHeiGenCache()
{
delete[] m_CacheData;
+ m_CacheData = NULL;
delete[] m_CacheOrder;
+ m_CacheOrder = NULL;
}
diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp
index 2ab1455b9..7d876909a 100644
--- a/src/Generating/Prefab.cpp
+++ b/src/Generating/Prefab.cpp
@@ -211,6 +211,17 @@ void cPrefab::Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumR
int ChunkStartZ = a_Dest.GetChunkZ() * cChunkDef::Width;
Placement.Move(-ChunkStartX, 0, -ChunkStartZ);
const cBlockArea & Image = m_BlockArea[a_NumRotations];
+
+ // If the placement is outside this chunk, bail out:
+ if (
+ (Placement.x > cChunkDef::Width) || (Placement.x + Image.GetSizeX() < 0) ||
+ (Placement.z > cChunkDef::Width) || (Placement.z + Image.GetSizeZ() < 0)
+ )
+ {
+ return;
+ }
+
+ // Write the image:
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)
diff --git a/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp b/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp
index eb0d30fdf..976f8490e 100644
--- a/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp
+++ b/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp
@@ -28,170 +28,172 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// Block definitions:
".: 0: 0\n" /* air */
- "A:171: 8\n" /* carpet */
- "B:101: 0\n" /* ironbars */
- "C: 64:12\n" /* wooddoorblock */
- "D:128: 2\n" /* sandstonestairs */
- "E: 24: 1\n" /* sandstone */
- "F: 44: 9\n" /* step */
- "G:126: 8\n" /* woodenslab */
- "H:128: 7\n" /* sandstonestairs */
- "I: 44: 1\n" /* step */
- "J: 64: 7\n" /* wooddoorblock */
- "K:128: 6\n" /* sandstonestairs */
- "a: 1: 0\n" /* stone */
- "b: 24: 0\n" /* sandstone */
- "c: 12: 0\n" /* sand */
- "d:134: 4\n" /* 134 */
- "e: 5: 1\n" /* wood */
- "f:134: 5\n" /* 134 */
- "g: 65: 5\n" /* ladder */
- "h: 17: 3\n" /* tree */
- "i: 69:11\n" /* lever */
- "j:134: 0\n" /* 134 */
- "k:134: 1\n" /* 134 */
- "l: 50: 4\n" /* torch */
+ "A: 65: 3\n" /* ladder */
+ "B: 50: 3\n" /* torch */
+ "C:171: 8\n" /* carpet */
+ "D:101: 0\n" /* ironbars */
+ "E: 64: 8\n" /* wooddoorblock */
+ "F:128: 2\n" /* sandstonestairs */
+ "G: 24: 1\n" /* sandstone */
+ "H: 44: 9\n" /* step */
+ "I:126: 8\n" /* woodenslab */
+ "J:128: 7\n" /* sandstonestairs */
+ "K: 44: 1\n" /* step */
+ "L: 64: 3\n" /* wooddoorblock */
+ "M:128: 6\n" /* sandstonestairs */
+ "a: 24: 2\n" /* sandstone */
+ "b: 1: 0\n" /* stone */
+ "c: 24: 0\n" /* sandstone */
+ "d: 12: 0\n" /* sand */
+ "e:134: 4\n" /* 134 */
+ "f: 5: 1\n" /* wood */
+ "g:134: 5\n" /* 134 */
+ "h: 65: 5\n" /* ladder */
+ "i: 17: 3\n" /* tree */
+ "j: 69:11\n" /* lever */
+ "k: 4: 0\n" /* cobblestone */
+ "l:134: 0\n" /* 134 */
"m: 19: 0\n" /* sponge */
- "n: 5: 0\n" /* wood */
- "o: 96:12\n" /* trapdoor */
- "p: 24: 2\n" /* sandstone */
- "q:128: 5\n" /* sandstonestairs */
- "r:107: 6\n" /* fencegate */
- "s:128: 4\n" /* sandstonestairs */
- "t:134: 3\n" /* 134 */
- "u: 85: 0\n" /* fence */
- "v:134: 7\n" /* 134 */
- "w:107: 5\n" /* fencegate */
- "x: 64: 5\n" /* wooddoorblock */
- "y: 65: 3\n" /* ladder */
- "z: 50: 3\n" /* torch */,
+ "n:134: 1\n" /* 134 */
+ "o: 50: 4\n" /* torch */
+ "p: 13: 0\n" /* gravel */
+ "q: 5: 0\n" /* wood */
+ "r: 96: 8\n" /* trapdoor */
+ "s:128: 5\n" /* sandstonestairs */
+ "t:107: 2\n" /* fencegate */
+ "u:128: 4\n" /* sandstonestairs */
+ "v:134: 3\n" /* 134 */
+ "w: 85: 0\n" /* fence */
+ "x:134: 7\n" /* 134 */
+ "y:107: 5\n" /* fencegate */
+ "z: 64: 1\n" /* wooddoorblock */,
// Block data:
// Level 0
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "aaaaaaaaaaa"
- /* 1 */ "aaaaaaaaaaa"
- /* 2 */ "aabbbbbbbaa"
- /* 3 */ "aabbbbbbbaa"
- /* 4 */ "aabbbbbbbaa"
- /* 5 */ "aabbbbbbbaa"
- /* 6 */ "aabbbbbbbaa"
- /* 7 */ "aabbbbbbbaa"
- /* 8 */ "aaaaaaaaaaa"
- /* 9 */ "aaaaaaaaaaa"
+ /* 0 */ "mmmabbbammm"
+ /* 1 */ "mcccccccccm"
+ /* 2 */ "abcccccccba"
+ /* 3 */ "cbcccccccbc"
+ /* 4 */ "cbcccccccbc"
+ /* 5 */ "cbcccccccbc"
+ /* 6 */ "cbcccccccbc"
+ /* 7 */ "cbcccccccbc"
+ /* 8 */ "abbbbbbbbba"
+ /* 9 */ "mmmmmmmmmmm"
// Level 1
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "ccccccccccc"
- /* 1 */ "cbbbbbbbbbc"
- /* 2 */ "cbdef.defbc"
- /* 3 */ "cbdef.defbc"
- /* 4 */ "cbdef.defbc"
- /* 5 */ "cb.......bc"
- /* 6 */ "cb.......bc"
- /* 7 */ "cbg......bc"
- /* 8 */ "cbbbbbbbbbc"
- /* 9 */ "ccccccccccc"
+ /* 0 */ "mmmadddammm"
+ /* 1 */ "mcccccccccm"
+ /* 2 */ "acefg.efgca"
+ /* 3 */ "ccefg.efgcc"
+ /* 4 */ "ccefg.efgcc"
+ /* 5 */ "cc.......cc"
+ /* 6 */ "cc.......cc"
+ /* 7 */ "cch......cc"
+ /* 8 */ "accccccccca"
+ /* 9 */ "mmmmmmmmmmm"
// Level 2
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "ccccccccccc"
- /* 1 */ "cbbbbbbbbbc"
- /* 2 */ "cbeee.eeebc"
- /* 3 */ "cbeee.eeebc"
- /* 4 */ "cbehe.ehebc"
- /* 5 */ "cb.i...i.bc"
- /* 6 */ "cb.......bc"
- /* 7 */ "cbg......bc"
- /* 8 */ "cbbbbbbbbbc"
- /* 9 */ "ccccccccccc"
+ /* 0 */ "mmmadddammm"
+ /* 1 */ "mcccccccccm"
+ /* 2 */ "acfff.fffca"
+ /* 3 */ "ccfff.fffcc"
+ /* 4 */ "ccfif.fifcc"
+ /* 5 */ "cc.j...j.cc"
+ /* 6 */ "cc.......cc"
+ /* 7 */ "cch......cc"
+ /* 8 */ "accccccccca"
+ /* 9 */ "mmmmmmmmmmm"
// Level 3
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "ccccccccccc"
- /* 1 */ "cbbbbbbbbbc"
- /* 2 */ "cbjek.jekbc"
- /* 3 */ "cbjek.jekbc"
- /* 4 */ "cbjek.jekbc"
- /* 5 */ "cb.......bc"
- /* 6 */ "cb.......bc"
- /* 7 */ "cbg..l...bc"
- /* 8 */ "cbbbbbbbbbc"
- /* 9 */ "ccccccccccc"
+ /* 0 */ "mmmakkkammm"
+ /* 1 */ "mcccccccccm"
+ /* 2 */ "aclfn.lfnca"
+ /* 3 */ "cclfn.lfncc"
+ /* 4 */ "cclfn.lfncc"
+ /* 5 */ "cc.......cc"
+ /* 6 */ "cc.......cc"
+ /* 7 */ "cch..o...cc"
+ /* 8 */ "accccccccca"
+ /* 9 */ "mmmmmmmmmmm"
// Level 4
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "ccccccccccc"
- /* 1 */ "ccccccccccc"
- /* 2 */ "ccnnnnnnncc"
- /* 3 */ "cnnnnnnnnnc"
- /* 4 */ "cnnnnnnnnnc"
- /* 5 */ "cnnnnnnnnnc"
- /* 6 */ "cnnnnnnnnnc"
- /* 7 */ "cnonnnnnnnc"
- /* 8 */ "cnccccccccc"
- /* 9 */ "ccccccccccc"
+ /* 0 */ "mmmapppammm"
+ /* 1 */ "mmmmpppmmmm"
+ /* 2 */ "acccqqqccca"
+ /* 3 */ "cqqqqqqqqqc"
+ /* 4 */ "cqqqqqqqqqc"
+ /* 5 */ "cqqqqqqqqqc"
+ /* 6 */ "cqqqqqqqqqc"
+ /* 7 */ "cqrqqqqqqqc"
+ /* 8 */ "aqcccccccca"
+ /* 9 */ "mmmmmmmmmmm"
// Level 5
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "...p...p..."
- /* 1 */ "..........."
- /* 2 */ "pbbbqrsbbbp"
- /* 3 */ "bkt.....ttb"
- /* 4 */ "bku.....ujb"
- /* 5 */ "b.........b"
- /* 6 */ "bfvvd.....b"
- /* 7 */ "b...w..kujb"
- /* 8 */ "pxbbbbbbbbp"
- /* 9 */ "..y........"
+ /* 0 */ "mmma...ammm"
+ /* 1 */ "mmm.....mmm"
+ /* 2 */ "acccstuccca"
+ /* 3 */ "cnv.....vvc"
+ /* 4 */ "cnw.....wlc"
+ /* 5 */ "c.........c"
+ /* 6 */ "cgxxe.....c"
+ /* 7 */ "c...y..nwlc"
+ /* 8 */ "azcccccccca"
+ /* 9 */ "mmAmmmmmmmm"
// Level 6
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "...p...p..."
- /* 1 */ "..........."
- /* 2 */ "pbbb...bbbp"
- /* 3 */ "b..z...z..b"
- /* 4 */ "b.A.....A.b"
- /* 5 */ "B.........B"
- /* 6 */ "b.........b"
- /* 7 */ "b.......A.b"
- /* 8 */ "pCbbBBBbbbp"
- /* 9 */ "..y........"
+ /* 0 */ "mmma...ammm"
+ /* 1 */ "mmm.....mmm"
+ /* 2 */ "accc...ccca"
+ /* 3 */ "c..B...B..c"
+ /* 4 */ "c.C.....C.c"
+ /* 5 */ "D.........D"
+ /* 6 */ "c.........c"
+ /* 7 */ "c.......C.c"
+ /* 8 */ "aEccDDDccca"
+ /* 9 */ "mmAmmmmmmmm"
// Level 7
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "...D...D..."
- /* 1 */ "...E...b..."
- /* 2 */ "pbbbqFsbbbp"
- /* 3 */ "bGGGGGGGGGb"
- /* 4 */ "bGGGGGGGGGb"
- /* 5 */ "sGGGGGGGGGq"
- /* 6 */ "bGGGGGGGGGb"
- /* 7 */ "bGGGGGGGGGb"
- /* 8 */ "pbbbHHHbbbp"
- /* 9 */ "..y........"
+ /* 0 */ "mmmF...Fmmm"
+ /* 1 */ "mmmG...cmmm"
+ /* 2 */ "acccsHuccca"
+ /* 3 */ "cIIIIIIIIIc"
+ /* 4 */ "cIIIIIIIIIc"
+ /* 5 */ "uIIIIIIIIIs"
+ /* 6 */ "cIIIIIIIIIc"
+ /* 7 */ "cIIIIIIIIIc"
+ /* 8 */ "acccJJJccca"
+ /* 9 */ "mmAmmmmmmmm"
// Level 8
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "..........."
- /* 1 */ "..........."
- /* 2 */ "bIIIIbIIIIb"
- /* 3 */ "IpbbbbbbbpI"
- /* 4 */ "Ib.......bI"
- /* 5 */ "bb.......bb"
- /* 6 */ "Ib.......bI"
- /* 7 */ "IpJbbbbbbpI"
- /* 8 */ "bI.IIbIIIIb"
- /* 9 */ "..........."
+ /* 0 */ "mmm.....mmm"
+ /* 1 */ "mmm.....mmm"
+ /* 2 */ "cKKKKcKKKKc"
+ /* 3 */ "KacccccccaK"
+ /* 4 */ "Kc.......cK"
+ /* 5 */ "cc.......cc"
+ /* 6 */ "Kc.......cK"
+ /* 7 */ "KaLccccccaK"
+ /* 8 */ "cK.KKcKKKKc"
+ /* 9 */ "mmmmmmmmmmm"
// Level 9
/* z\x* 1 */
@@ -199,11 +201,11 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
/* 0 */ "..........."
/* 1 */ "..........."
/* 2 */ "..........."
- /* 3 */ ".pbbBBBbbp."
- /* 4 */ ".b.......b."
- /* 5 */ ".B.......B."
- /* 6 */ ".b.......b."
- /* 7 */ ".pCbBBBbbp."
+ /* 3 */ ".accDDDcca."
+ /* 4 */ ".c.......c."
+ /* 5 */ ".D.......D."
+ /* 6 */ ".c.......c."
+ /* 7 */ ".aEcDDDcca."
/* 8 */ "..........."
/* 9 */ "..........."
@@ -213,11 +215,11 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
/* 0 */ "..........."
/* 1 */ "..........."
/* 2 */ "..........."
- /* 3 */ ".pbbKKKbbp."
- /* 4 */ ".bGGGGGGGb."
- /* 5 */ ".sGGGGGGGq."
- /* 6 */ ".bGGGGGGGb."
- /* 7 */ ".pbbHHHbbp."
+ /* 3 */ ".accMMMcca."
+ /* 4 */ ".cIIIIIIIc."
+ /* 5 */ ".uIIIIIIIs."
+ /* 6 */ ".cIIIIIIIc."
+ /* 7 */ ".accJJJcca."
/* 8 */ "..........."
/* 9 */ "..........."
@@ -227,11 +229,11 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
/* 0 */ "..........."
/* 1 */ "..........."
/* 2 */ "..........."
- /* 3 */ ".bIIIbIIIb."
- /* 4 */ ".I.......I."
- /* 5 */ ".b.......b."
- /* 6 */ ".I.......I."
- /* 7 */ ".bIIIbIIIb."
+ /* 3 */ ".cKKKcKKKc."
+ /* 4 */ ".K.......K."
+ /* 5 */ ".c.......c."
+ /* 6 */ ".K.......K."
+ /* 7 */ ".cKKKcKKKc."
/* 8 */ "..........."
/* 9 */ "...........",
@@ -267,161 +269,175 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 81, ID 597, created by STR_Warrior
{
// Size:
- 11, 8, 10, // SizeX = 11, SizeY = 8, SizeZ = 10
+ 11, 9, 10, // SizeX = 11, SizeY = 9, SizeZ = 10
// Hitbox (relative to bounding box):
-1, 0, 0, // MinX, MinY, MinZ
- 11, 7, 10, // MaxX, MaxY, MaxZ
+ 11, 8, 10, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "A:128: 7\n" /* sandstonestairs */
- "B: 44: 1\n" /* step */
- "C: 64: 3\n" /* wooddoorblock */
- "D: 64: 8\n" /* wooddoorblock */
+ "A:126: 8\n" /* woodenslab */
+ "B:128: 7\n" /* sandstonestairs */
+ "C: 44: 1\n" /* step */
+ "D: 64: 3\n" /* wooddoorblock */
"E:128: 6\n" /* sandstonestairs */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
- "c: 24: 2\n" /* sandstone */
- "d: 24: 0\n" /* sandstone */
- "e:128: 5\n" /* sandstonestairs */
- "f:107: 6\n" /* fencegate */
- "g:128: 4\n" /* sandstonestairs */
- "h:134: 1\n" /* 134 */
- "i:134: 3\n" /* 134 */
- "j: 85: 0\n" /* fence */
- "k:134: 0\n" /* 134 */
- "l:134: 5\n" /* 134 */
+ "a: 24: 2\n" /* sandstone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 24: 0\n" /* sandstone */
+ "d: 13: 0\n" /* gravel */
+ "e: 5: 0\n" /* wood */
+ "f:128: 5\n" /* sandstonestairs */
+ "g:107: 2\n" /* fencegate */
+ "h:128: 4\n" /* sandstonestairs */
+ "i:134: 1\n" /* 134 */
+ "j:134: 3\n" /* 134 */
+ "k: 85: 0\n" /* fence */
+ "l:134: 0\n" /* 134 */
"m: 19: 0\n" /* sponge */
- "n:134: 7\n" /* 134 */
- "o:134: 4\n" /* 134 */
- "p:107: 5\n" /* fencegate */
- "q: 64: 5\n" /* wooddoorblock */
- "r: 65: 3\n" /* ladder */
- "s: 50: 3\n" /* torch */
- "t:171: 8\n" /* carpet */
- "u:101: 0\n" /* ironbars */
- "v: 64:12\n" /* wooddoorblock */
- "w:128: 2\n" /* sandstonestairs */
- "x: 24: 1\n" /* sandstone */
- "y: 44: 9\n" /* step */
- "z:126: 8\n" /* woodenslab */,
+ "n:134: 5\n" /* 134 */
+ "o:134: 7\n" /* 134 */
+ "p:134: 4\n" /* 134 */
+ "q:107: 1\n" /* fencegate */
+ "r: 64: 1\n" /* wooddoorblock */
+ "s: 65: 3\n" /* ladder */
+ "t: 50: 3\n" /* torch */
+ "u:171: 8\n" /* carpet */
+ "v:101: 0\n" /* ironbars */
+ "w: 64: 8\n" /* wooddoorblock */
+ "x:128: 2\n" /* sandstonestairs */
+ "y: 24: 1\n" /* sandstone */
+ "z: 44: 9\n" /* step */,
// Block data:
// Level 0
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "aaaaaaaaaaa"
- /* 1 */ "aaaaaaaaaaa"
- /* 2 */ "aaaabbbaaaa"
- /* 3 */ "abbbbbbbbba"
- /* 4 */ "abbbbbbbbba"
- /* 5 */ "abbbbbbbbba"
- /* 6 */ "abbbbbbbbba"
- /* 7 */ "abbbbbbbbba"
- /* 8 */ "abaaaaaaaaa"
- /* 9 */ "aaaaaaaaaaa"
+ /* 0 */ "mmmabbbammm"
+ /* 1 */ "mmmmbbbmmmm"
+ /* 2 */ "accccccccca"
+ /* 3 */ "ccccccccccc"
+ /* 4 */ "ccccccccccc"
+ /* 5 */ "ccccccccccc"
+ /* 6 */ "ccccccccccc"
+ /* 7 */ "ccccccccccc"
+ /* 8 */ "accccccccca"
+ /* 9 */ "mmmmmmmmmmm"
// Level 1
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "...c...c..."
- /* 1 */ "..........."
- /* 2 */ "cdddefgdddc"
- /* 3 */ "dhi.....iid"
- /* 4 */ "dhj.....jkd"
- /* 5 */ "d.........d"
- /* 6 */ "dlnno.....d"
- /* 7 */ "d...p..hjkd"
- /* 8 */ "cqddddddddc"
- /* 9 */ "..r........"
+ /* 0 */ "mmmadddammm"
+ /* 1 */ "mmmmdddmmmm"
+ /* 2 */ "accceeeccca"
+ /* 3 */ "ceeeeeeeeec"
+ /* 4 */ "ceeeeeeeeec"
+ /* 5 */ "ceeeeeeeeec"
+ /* 6 */ "ceeeeeeeeec"
+ /* 7 */ "ceeeeeeeeec"
+ /* 8 */ "aecccccccca"
+ /* 9 */ "mmmmmmmmmmm"
// Level 2
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "...c...c..."
- /* 1 */ "..........."
- /* 2 */ "cddd...dddc"
- /* 3 */ "d..s...s..d"
- /* 4 */ "d.t.....t.d"
- /* 5 */ "u.........u"
- /* 6 */ "d.........d"
- /* 7 */ "d.......t.d"
- /* 8 */ "cvdduuudddc"
- /* 9 */ "..r........"
+ /* 0 */ "mmma...ammm"
+ /* 1 */ "mmm.....mmm"
+ /* 2 */ "acccfghccca"
+ /* 3 */ "cij.....jjc"
+ /* 4 */ "cik.....klc"
+ /* 5 */ "c.........c"
+ /* 6 */ "cnoop.....c"
+ /* 7 */ "c...q..iklc"
+ /* 8 */ "arcccccccca"
+ /* 9 */ "mmsmmmmmmmm"
// Level 3
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "...w...w..."
- /* 1 */ "...x...d..."
- /* 2 */ "cdddeygdddc"
- /* 3 */ "dzzzzzzzzzd"
- /* 4 */ "dzzzzzzzzzd"
- /* 5 */ "gzzzzzzzzze"
- /* 6 */ "dzzzzzzzzzd"
- /* 7 */ "dzzzzzzzzzd"
- /* 8 */ "cdddAAAdddc"
- /* 9 */ "..r........"
+ /* 0 */ "mmma...ammm"
+ /* 1 */ "mmm.....mmm"
+ /* 2 */ "accc...ccca"
+ /* 3 */ "c..t...t..c"
+ /* 4 */ "c.u.....u.c"
+ /* 5 */ "v.........v"
+ /* 6 */ "c.........c"
+ /* 7 */ "c.......u.c"
+ /* 8 */ "awccvvvccca"
+ /* 9 */ "mmsmmmmmmmm"
// Level 4
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "..........."
- /* 1 */ "..........."
- /* 2 */ "dBBBBdBBBBd"
- /* 3 */ "BcdddddddcB"
- /* 4 */ "Bd.......dB"
- /* 5 */ "dd.......dd"
- /* 6 */ "Bd.......dB"
- /* 7 */ "BcCddddddcB"
- /* 8 */ "dB.BBdBBBBd"
- /* 9 */ "..........."
+ /* 0 */ "mmmx...xmmm"
+ /* 1 */ "mmmy...cmmm"
+ /* 2 */ "acccfzhccca"
+ /* 3 */ "cAAAAAAAAAc"
+ /* 4 */ "cAAAAAAAAAc"
+ /* 5 */ "hAAAAAAAAAf"
+ /* 6 */ "cAAAAAAAAAc"
+ /* 7 */ "cAAAAAAAAAc"
+ /* 8 */ "acccBBBccca"
+ /* 9 */ "mmsmmmmmmmm"
// Level 5
/* z\x* 1 */
/* * 01234567890 */
+ /* 0 */ "mmm.....mmm"
+ /* 1 */ "mmm.....mmm"
+ /* 2 */ "cCCCCcCCCCc"
+ /* 3 */ "CacccccccaC"
+ /* 4 */ "Cc.......cC"
+ /* 5 */ "cc.......cc"
+ /* 6 */ "Cc.......cC"
+ /* 7 */ "CaDccccccaC"
+ /* 8 */ "cC.CCcCCCCc"
+ /* 9 */ "mmmmmmmmmmm"
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
/* 0 */ "..........."
/* 1 */ "..........."
/* 2 */ "..........."
- /* 3 */ ".cdduuuddc."
- /* 4 */ ".d.......d."
- /* 5 */ ".u.......u."
- /* 6 */ ".d.......d."
- /* 7 */ ".cDduuuddc."
+ /* 3 */ ".accvvvcca."
+ /* 4 */ ".c.......c."
+ /* 5 */ ".v.......v."
+ /* 6 */ ".c.......c."
+ /* 7 */ ".awcvvvcca."
/* 8 */ "..........."
/* 9 */ "..........."
- // Level 6
+ // Level 7
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
/* 1 */ "..........."
/* 2 */ "..........."
- /* 3 */ ".cddEEEddc."
- /* 4 */ ".dzzzzzzzd."
- /* 5 */ ".gzzzzzzze."
- /* 6 */ ".dzzzzzzzd."
- /* 7 */ ".cddAAAddc."
+ /* 3 */ ".accEEEcca."
+ /* 4 */ ".cAAAAAAAc."
+ /* 5 */ ".hAAAAAAAf."
+ /* 6 */ ".cAAAAAAAc."
+ /* 7 */ ".accBBBcca."
/* 8 */ "..........."
/* 9 */ "..........."
- // Level 7
+ // Level 8
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
/* 1 */ "..........."
/* 2 */ "..........."
- /* 3 */ ".dBBBdBBBd."
- /* 4 */ ".B.......B."
- /* 5 */ ".d.......d."
- /* 6 */ ".B.......B."
- /* 7 */ ".dBBBdBBBd."
+ /* 3 */ ".cCCCcCCCc."
+ /* 4 */ ".C.......C."
+ /* 5 */ ".c.......c."
+ /* 6 */ ".C.......C."
+ /* 7 */ ".cCCCcCCCc."
/* 8 */ "..........."
/* 9 */ "...........",
// Connectors:
- "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 5, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -452,127 +468,146 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 97, ID 642, created by STR_Warrior
{
// Size:
- 11, 5, 13, // SizeX = 11, SizeY = 5, SizeZ = 13
+ 11, 6, 13, // SizeX = 11, SizeY = 6, SizeZ = 13
// Hitbox (relative to bounding box):
-1, 0, 0, // MinX, MinY, MinZ
- 11, 4, 13, // MaxX, MaxY, MaxZ
+ 11, 5, 13, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
+ "a: 24: 2\n" /* sandstone */
+ "b: 4: 0\n" /* cobblestone */
"c: 24: 0\n" /* sandstone */
- "d: 24: 2\n" /* sandstone */
- "e: 64: 7\n" /* wooddoorblock */
- "f: 43: 0\n" /* doubleslab */
- "g: 53: 5\n" /* woodstairs */
- "h: 53: 4\n" /* woodstairs */
- "i: 10: 0\n" /* lava */
- "j: 54: 5\n" /* chest */
- "k: 64:12\n" /* wooddoorblock */
- "l: 50: 3\n" /* torch */
+ "d: 13: 0\n" /* gravel */
+ "e: 5: 0\n" /* wood */
+ "f: 12: 0\n" /* sand */
+ "g: 64: 3\n" /* wooddoorblock */
+ "h: 43: 0\n" /* doubleslab */
+ "i: 53: 5\n" /* woodstairs */
+ "j: 53: 4\n" /* woodstairs */
+ "k: 10: 0\n" /* lava */
+ "l: 54: 5\n" /* chest */
"m: 19: 0\n" /* sponge */
- "n:101: 0\n" /* ironbars */
- "o: 50: 1\n" /* torch */
- "p: 50: 2\n" /* torch */
- "q:128: 2\n" /* sandstonestairs */
- "r: 44: 9\n" /* step */
- "s:126: 8\n" /* woodenslab */
- "t:128: 4\n" /* sandstonestairs */
- "u:128: 5\n" /* sandstonestairs */
- "v:128: 7\n" /* sandstonestairs */
- "w: 44: 1\n" /* step */
- "x: 43: 1\n" /* doubleslab */,
+ "n: 64: 8\n" /* wooddoorblock */
+ "o: 50: 3\n" /* torch */
+ "p:101: 0\n" /* ironbars */
+ "q: 50: 1\n" /* torch */
+ "r: 50: 2\n" /* torch */
+ "s:128: 2\n" /* sandstonestairs */
+ "t: 44: 9\n" /* step */
+ "u:126: 8\n" /* woodenslab */
+ "v:128: 4\n" /* sandstonestairs */
+ "w:128: 5\n" /* sandstonestairs */
+ "x:128: 7\n" /* sandstonestairs */
+ "y: 44: 1\n" /* step */
+ "z: 43: 1\n" /* doubleslab */,
// Block data:
// Level 0
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "aaaaaaaaaaa"
- /* 1 */ "aaaaaaaaaaa"
- /* 2 */ "aaaaaaaabaa"
- /* 3 */ "acacacabbba"
- /* 4 */ "acaccaabbba"
- /* 5 */ "acccccabbba"
- /* 6 */ "acaadddbbba"
- /* 7 */ "aaacdddbbba"
- /* 8 */ "aaaadddbbba"
- /* 9 */ "abbbbbbbbba"
- /* 10 */ "abbbbbbbbba"
- /* 11 */ "abbbbbbbbba"
- /* 12 */ "aaaaaaaaaaa"
+ /* 0 */ "mmmmmmabbba"
+ /* 1 */ "mmmmmmbbbbm"
+ /* 2 */ "mmmmmmaccca"
+ /* 3 */ "maccccccccc"
+ /* 4 */ "mcccccccccc"
+ /* 5 */ "mcccccccccc"
+ /* 6 */ "mcccccacccc"
+ /* 7 */ "mcccccacccc"
+ /* 8 */ "acccaaacccc"
+ /* 9 */ "ccccccccccc"
+ /* 10 */ "ccccccccccc"
+ /* 11 */ "ccccccccccc"
+ /* 12 */ "accccccccca"
// Level 1
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "......d...d"
- /* 1 */ "..........."
- /* 2 */ "......dcecd"
- /* 3 */ ".d....c...c"
- /* 4 */ "..f...c...c"
- /* 5 */ "......c...c"
- /* 6 */ "....ddc...c"
- /* 7 */ ".gh.dic...c"
- /* 8 */ "dcccccd...c"
- /* 9 */ "cj........c"
- /* 10 */ "c.........c"
- /* 11 */ "c.........c"
- /* 12 */ "dcccccccccd"
+ /* 0 */ "mmmmmmaddda"
+ /* 1 */ "mmmmmmddddm"
+ /* 2 */ "mmmmmmaceca"
+ /* 3 */ "mafcfcceeec"
+ /* 4 */ "mcfccfceeec"
+ /* 5 */ "mcccccceeec"
+ /* 6 */ "mcffaaaeeec"
+ /* 7 */ "mffcaaaeeec"
+ /* 8 */ "acccaaaeeec"
+ /* 9 */ "ceeeeeeeeec"
+ /* 10 */ "ceeeeeeeeec"
+ /* 11 */ "ceeeeeeeeec"
+ /* 12 */ "accccccccca"
// Level 2
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "......d...d"
- /* 1 */ "..........."
- /* 2 */ "......dckcd"
- /* 3 */ ".d....c..lc"
- /* 4 */ "......n...c"
- /* 5 */ "......c...c"
- /* 6 */ "....nnc...n"
- /* 7 */ "....n.c...n"
- /* 8 */ "dcccccd...n"
- /* 9 */ "co........c"
- /* 10 */ "n.........c"
- /* 11 */ "c........pc"
- /* 12 */ "dcccnnncccd"
+ /* 0 */ "mmmmmma...a"
+ /* 1 */ "mmmmmm....."
+ /* 2 */ "mmmmmmacgca"
+ /* 3 */ "ma....c...c"
+ /* 4 */ "m.h...c...c"
+ /* 5 */ "m.....c...c"
+ /* 6 */ "m...aac...c"
+ /* 7 */ "mij.akc...c"
+ /* 8 */ "accccca...c"
+ /* 9 */ "cl........c"
+ /* 10 */ "c.........c"
+ /* 11 */ "c.........c"
+ /* 12 */ "accccccccca"
// Level 3
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "......q...q"
- /* 1 */ "......c...c"
- /* 2 */ "......dcccd"
- /* 3 */ ".drrrrcsssc"
- /* 4 */ ".rsssstsssc"
- /* 5 */ ".rsssscsssc"
- /* 6 */ ".rssddcsssu"
- /* 7 */ ".rssd.csssu"
- /* 8 */ "dcccccdsssu"
- /* 9 */ "csssssssssc"
- /* 10 */ "tsssssssssc"
- /* 11 */ "csssssssssc"
- /* 12 */ "dcccvvvcccd"
+ /* 0 */ "mmmmmma...a"
+ /* 1 */ "mmmmmm....."
+ /* 2 */ "mmmmmmacnca"
+ /* 3 */ "ma....c..oc"
+ /* 4 */ "m.....p...c"
+ /* 5 */ "m.....c...c"
+ /* 6 */ "m...ppc...p"
+ /* 7 */ "m...p.c...p"
+ /* 8 */ "accccca...p"
+ /* 9 */ "cq........c"
+ /* 10 */ "p.........c"
+ /* 11 */ "c........rc"
+ /* 12 */ "acccpppccca"
// Level 4
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "..........."
- /* 1 */ "..........."
- /* 2 */ "......cwwwc"
- /* 3 */ ".w.w.ww...w"
- /* 4 */ "......w...w"
- /* 5 */ ".w....w...w"
- /* 6 */ "....xwx...w"
- /* 7 */ ".w..w.w...c"
- /* 8 */ "cwwwxwc...w"
- /* 9 */ "w.........w"
- /* 10 */ "w.........w"
- /* 11 */ "w.........w"
- /* 12 */ "cwwwwcwwwwc",
+ /* 0 */ "mmmmmms...s"
+ /* 1 */ "mmmmmmc...c"
+ /* 2 */ "mmmmmmaccca"
+ /* 3 */ "mattttcuuuc"
+ /* 4 */ "mtuuuuvuuuc"
+ /* 5 */ "mtuuuucuuuc"
+ /* 6 */ "mtuuaacuuuw"
+ /* 7 */ "mtuua.cuuuw"
+ /* 8 */ "acccccauuuw"
+ /* 9 */ "cuuuuuuuuuc"
+ /* 10 */ "vuuuuuuuuuc"
+ /* 11 */ "cuuuuuuuuuc"
+ /* 12 */ "acccxxxccca"
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmmm....."
+ /* 1 */ "mmmmmm....."
+ /* 2 */ "mmmmmmcyyyc"
+ /* 3 */ "my.y.yy...y"
+ /* 4 */ "m.....y...y"
+ /* 5 */ "my....y...y"
+ /* 6 */ "m...zyz...y"
+ /* 7 */ "my..y.y...c"
+ /* 8 */ "cyyyzyc...y"
+ /* 9 */ "y.........y"
+ /* 10 */ "y.........y"
+ /* 11 */ "y.........y"
+ /* 12 */ "cyyyycyyyyc",
// Connectors:
- "-1: 8, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 8, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -603,180 +638,196 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 77, ID 577, created by STR_Warrior
{
// Size:
- 15, 13, 11, // SizeX = 15, SizeY = 13, SizeZ = 11
+ 15, 14, 11, // SizeX = 15, SizeY = 14, SizeZ = 11
// Hitbox (relative to bounding box):
-1, 0, -1, // MinX, MinY, MinZ
- 14, 12, 11, // MaxX, MaxY, MaxZ
+ 14, 13, 11, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "A:128: 4\n" /* sandstonestairs */
- "B:128: 5\n" /* sandstonestairs */
- "C:128: 7\n" /* sandstonestairs */
- "D: 44: 1\n" /* step */
- "E:128: 2\n" /* sandstonestairs */
- "F:128: 0\n" /* sandstonestairs */
- "G: 87: 0\n" /* netherstone */
- "H:128: 3\n" /* sandstonestairs */
- "I: 51: 0\n" /* fire */
- "J: 44: 9\n" /* step */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
- "c: 24: 2\n" /* sandstone */
- "d: 24: 0\n" /* sandstone */
- "e: 85: 0\n" /* fence */
- "f: 5: 1\n" /* wood */
- "g: 64: 6\n" /* wooddoorblock */
- "h: 64: 0\n" /* wooddoorblock */
- "i: 61: 2\n" /* furnace */
- "j:118: 0\n" /* cauldronblock */
- "k:134: 4\n" /* 134 */
- "l: 65: 2\n" /* ladder */
+ "A: 96:10\n" /* trapdoor */
+ "B:128: 4\n" /* sandstonestairs */
+ "C:128: 5\n" /* sandstonestairs */
+ "D:128: 7\n" /* sandstonestairs */
+ "E: 44: 1\n" /* step */
+ "F:128: 2\n" /* sandstonestairs */
+ "G:128: 0\n" /* sandstonestairs */
+ "H: 87: 0\n" /* netherstone */
+ "I:128: 3\n" /* sandstonestairs */
+ "J: 51: 0\n" /* fire */
+ "K: 44: 9\n" /* step */
+ "a: 24: 2\n" /* sandstone */
+ "b: 24: 0\n" /* sandstone */
+ "c: 12: 0\n" /* sand */
+ "d: 4: 0\n" /* cobblestone */
+ "e: 5: 0\n" /* wood */
+ "f: 13: 0\n" /* gravel */
+ "g: 85: 0\n" /* fence */
+ "h: 5: 1\n" /* wood */
+ "i: 64: 2\n" /* wooddoorblock */
+ "j: 64: 0\n" /* wooddoorblock */
+ "k: 61: 2\n" /* furnace */
+ "l:118: 0\n" /* cauldronblock */
"m: 19: 0\n" /* sponge */
- "n:101: 0\n" /* ironbars */
- "o: 50: 1\n" /* torch */
- "p:140: 0\n" /* flowerpotblock */
- "q: 64:12\n" /* wooddoorblock */
- "r: 50: 3\n" /* torch */
+ "n:134: 4\n" /* 134 */
+ "o: 65: 2\n" /* ladder */
+ "p:101: 0\n" /* ironbars */
+ "q: 50: 1\n" /* torch */
+ "r:140: 0\n" /* flowerpotblock */
"s: 64: 8\n" /* wooddoorblock */
- "t: 69:12\n" /* lever */
- "u: 50: 4\n" /* torch */
- "v:128: 6\n" /* sandstonestairs */
- "w: 44:10\n" /* step */
- "x:128: 1\n" /* sandstonestairs */
- "y: 47: 0\n" /* bookshelf */
- "z: 96:10\n" /* trapdoor */,
+ "t: 50: 3\n" /* torch */
+ "u: 69:12\n" /* lever */
+ "v: 50: 4\n" /* torch */
+ "w:128: 6\n" /* sandstonestairs */
+ "x: 44:10\n" /* step */
+ "y:128: 1\n" /* sandstonestairs */
+ "z: 47: 0\n" /* bookshelf */,
// Block data:
// Level 0
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "aaaaaaaaaaaaaaa"
- /* 1 */ "aaaaabbbbbbbaaa"
- /* 2 */ "aaaabbbbbbbbaaa"
- /* 3 */ "aaaaabbbbbbbbaa"
- /* 4 */ "aaaaabbbbbbbaaa"
- /* 5 */ "aaaaabbbbbbbaaa"
- /* 6 */ "aaaaabbbbbbbaaa"
- /* 7 */ "aaaaabbbbbbbaaa"
- /* 8 */ "aaaaabbbbbbbaaa"
- /* 9 */ "aaaaabbbbbbbaaa"
- /* 10 */ "aaaaaaaaaaaaaaa"
+ /* 0 */ "mmmmabbbbbbbamm"
+ /* 1 */ "ccccbbbbbbbbbma"
+ /* 2 */ "ccccbbbbbbbbbdd"
+ /* 3 */ "ccccbbbbbbbbbdd"
+ /* 4 */ "ccccbbbbbbbbbdd"
+ /* 5 */ "ccccbbbbbbbbbma"
+ /* 6 */ "ccccbbbbbbbbbmm"
+ /* 7 */ "mmmmbbbbbbbbbmm"
+ /* 8 */ "mmmmbbbbbbbbbmm"
+ /* 9 */ "mmmmbbbbbbbbbmm"
+ /* 10 */ "mmmmabbbbbbbamm"
// Level 1
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "....cdddddddc.."
- /* 1 */ "eeeed......fd.c"
- /* 2 */ "e...g.......d.."
- /* 3 */ "e...d.......h.."
- /* 4 */ "e...dijk..l.d.."
- /* 5 */ "e...dddd.dddd.c"
- /* 6 */ "eeeed.......d.."
- /* 7 */ "mmmmd.......d.."
- /* 8 */ "mmmmd.......d.."
- /* 9 */ "mmmmd.......d.."
- /* 10 */ "mmmmcdddddddc.."
+ /* 0 */ "mmmmabbbbbbbamm"
+ /* 1 */ "ccccbeeeeeeebma"
+ /* 2 */ "cccceeeeeeeebff"
+ /* 3 */ "ccccbeeeeeeeeff"
+ /* 4 */ "ccccbeeeeeeebff"
+ /* 5 */ "ccccbeeeeeeebma"
+ /* 6 */ "ccccbeeeeeeebmm"
+ /* 7 */ "mmmmbeeeeeeebmm"
+ /* 8 */ "mmmmbeeeeeeebmm"
+ /* 9 */ "mmmmbeeeeeeebmm"
+ /* 10 */ "mmmmabbbbbbbamm"
// Level 2
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "....cddnnnddc.."
- /* 1 */ "....do.....pd.c"
- /* 2 */ "....q.......d.r"
- /* 3 */ "....d.......s.."
- /* 4 */ "....d.t...l.d.u"
- /* 5 */ "....dddd.dddd.c"
- /* 6 */ "....n..r.r..n.."
- /* 7 */ "mmmmn.......n.."
- /* 8 */ "mmmmn.......n.."
- /* 9 */ "mmmmd.......d.."
- /* 10 */ "mmmmcddnnnddc.."
+ /* 0 */ "mmmmabbbbbbbamm"
+ /* 1 */ "ggggb......hb.a"
+ /* 2 */ "g...i.......b.."
+ /* 3 */ "g...b.......j.."
+ /* 4 */ "g...bkln..o.b.."
+ /* 5 */ "g...bbbb.bbbb.a"
+ /* 6 */ "ggggb.......bmm"
+ /* 7 */ "mmmmb.......bmm"
+ /* 8 */ "mmmmb.......bmm"
+ /* 9 */ "mmmmb.......bmm"
+ /* 10 */ "mmmmabbbbbbbamm"
// Level 3
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "....cddvvvddc.."
- /* 1 */ "....dwwwwwwwddx"
- /* 2 */ "....dwwwwwwwd.."
- /* 3 */ "....dwwwwwwwd.."
- /* 4 */ "....dyyywwzwd.."
- /* 5 */ "....ddddddddddx"
- /* 6 */ "....AwwwwwwwB.."
- /* 7 */ "mmmmAwwwwwwwB.."
- /* 8 */ "mmmmAwwwwwwwB.."
- /* 9 */ "mmmmdwwwwwwwd.."
- /* 10 */ "mmmmcddCCCddc.."
+ /* 0 */ "mmmmabbpppbbamm"
+ /* 1 */ "....bq.....rb.a"
+ /* 2 */ "....s.......b.t"
+ /* 3 */ "....b.......s.."
+ /* 4 */ "....b.u...o.b.v"
+ /* 5 */ "....bbbb.bbbb.a"
+ /* 6 */ "....p..t.t..pmm"
+ /* 7 */ "mmmmp.......pmm"
+ /* 8 */ "mmmmp.......pmm"
+ /* 9 */ "mmmmb.......bmm"
+ /* 10 */ "mmmmabbpppbbamm"
// Level 4
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "....dDDDdDDDd.."
- /* 1 */ "....DcdddddcD.."
- /* 2 */ "....Dd.....dD.."
- /* 3 */ "....Dd.....dD.."
- /* 4 */ "....Dd.....dD.."
- /* 5 */ "....dcdd.ddcd.."
- /* 6 */ "....D.......D.."
- /* 7 */ "mmmmD.......D.."
- /* 8 */ "mmmmD.......D.."
- /* 9 */ "mmmmD.......D.."
- /* 10 */ "mmmmdDDDdDDDd.."
+ /* 0 */ "mmmmabbwwwbbamm"
+ /* 1 */ "....bxxxxxxxbby"
+ /* 2 */ "....bxxxxxxxb.."
+ /* 3 */ "....bxxxxxxxb.."
+ /* 4 */ "....bzzzxxAxb.."
+ /* 5 */ "....bbbbbbbbbby"
+ /* 6 */ "....BxxxxxxxCmm"
+ /* 7 */ "mmmmBxxxxxxxCmm"
+ /* 8 */ "mmmmBxxxxxxxCmm"
+ /* 9 */ "mmmmbxxxxxxxbmm"
+ /* 10 */ "mmmmabbDDDbbamm"
// Level 5
/* z\x* 11111 */
/* * 012345678901234 */
+ /* 0 */ "mmmmbEEEbEEEbmm"
+ /* 1 */ "....EabbbbbaE.."
+ /* 2 */ "....Eb.....bE.."
+ /* 3 */ "....Eb.....bE.."
+ /* 4 */ "....Eb.....bE.."
+ /* 5 */ "....babb.bbab.."
+ /* 6 */ "....E.......Emm"
+ /* 7 */ "mmmmE.......Emm"
+ /* 8 */ "mmmmE.......Emm"
+ /* 9 */ "mmmmE.......Emm"
+ /* 10 */ "mmmmbEEEbEEEbmm"
+
+ // Level 6
+ /* z\x* 11111 */
+ /* * 012345678901234 */
/* 0 */ "..............."
- /* 1 */ ".....cddnddc..."
- /* 2 */ ".....n.....n..."
- /* 3 */ ".....n.....n..."
- /* 4 */ ".....n.....n..."
- /* 5 */ ".....cdd.ddc..."
+ /* 1 */ ".....abbpbba..."
+ /* 2 */ ".....p.....p..."
+ /* 3 */ ".....p.....p..."
+ /* 4 */ ".....p.....p..."
+ /* 5 */ ".....abb.bba..."
/* 6 */ "..............."
/* 7 */ "..............."
/* 8 */ "..............."
/* 9 */ "..............."
/* 10 */ "..............."
- // Level 6
+ // Level 7
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
- /* 1 */ ".....cddvddc..."
- /* 2 */ ".....AwwwwwB..."
- /* 3 */ ".....AwwwwwB..."
- /* 4 */ ".....AwwwwwB..."
- /* 5 */ ".....cdddddc..."
+ /* 1 */ ".....abbwbba..."
+ /* 2 */ ".....BxxxxxC..."
+ /* 3 */ ".....BxxxxxC..."
+ /* 4 */ ".....BxxxxxC..."
+ /* 5 */ ".....abbbbba..."
/* 6 */ "..............."
/* 7 */ "..............."
/* 8 */ "..............."
/* 9 */ "..............."
/* 10 */ "..............."
- // Level 7
+ // Level 8
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
- /* 1 */ ".....dDDdDDd..."
- /* 2 */ ".....D.ddd.D..."
- /* 3 */ ".....d.ddd.d..."
- /* 4 */ ".....D.ddd.D..."
- /* 5 */ ".....dDDdDDd..."
+ /* 1 */ ".....bEEbEEb..."
+ /* 2 */ ".....E.bbb.E..."
+ /* 3 */ ".....b.bbb.b..."
+ /* 4 */ ".....E.bbb.E..."
+ /* 5 */ ".....bEEbEEb..."
/* 6 */ "..............."
/* 7 */ "..............."
/* 8 */ "..............."
/* 9 */ "..............."
/* 10 */ "..............."
- // Level 8
+ // Level 9
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
/* 1 */ "..............."
- /* 2 */ ".......cEc....."
- /* 3 */ ".......FGx....."
- /* 4 */ ".......cHc....."
+ /* 2 */ ".......aFa....."
+ /* 3 */ ".......GHy....."
+ /* 4 */ ".......aIa....."
/* 5 */ "..............."
/* 6 */ "..............."
/* 7 */ "..............."
@@ -784,14 +835,14 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
/* 9 */ "..............."
/* 10 */ "..............."
- // Level 9
+ // Level 10
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
/* 1 */ "..............."
- /* 2 */ ".......c.c....."
- /* 3 */ "........I......"
- /* 4 */ ".......c.c....."
+ /* 2 */ ".......a.a....."
+ /* 3 */ "........J......"
+ /* 4 */ ".......a.a....."
/* 5 */ "..............."
/* 6 */ "..............."
/* 7 */ "..............."
@@ -799,14 +850,14 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
/* 9 */ "..............."
/* 10 */ "..............."
- // Level 10
+ // Level 11
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
/* 1 */ "..............."
- /* 2 */ ".......cvc....."
- /* 3 */ ".......A.B....."
- /* 4 */ ".......cCc....."
+ /* 2 */ ".......awa....."
+ /* 3 */ ".......B.C....."
+ /* 4 */ ".......aDa....."
/* 5 */ "..............."
/* 6 */ "..............."
/* 7 */ "..............."
@@ -814,14 +865,14 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
/* 9 */ "..............."
/* 10 */ "..............."
- // Level 11
+ // Level 12
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
/* 1 */ "..............."
- /* 2 */ ".......ddd....."
- /* 3 */ ".......dJd....."
- /* 4 */ ".......ddd....."
+ /* 2 */ ".......bbb....."
+ /* 3 */ ".......bKb....."
+ /* 4 */ ".......bbb....."
/* 5 */ "..............."
/* 6 */ "..............."
/* 7 */ "..............."
@@ -829,14 +880,14 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
/* 9 */ "..............."
/* 10 */ "..............."
- // Level 12
+ // Level 13
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
/* 1 */ "..............."
- /* 2 */ ".......D.D....."
+ /* 2 */ ".......E.E....."
/* 3 */ "..............."
- /* 4 */ ".......D.D....."
+ /* 4 */ ".......E.E....."
/* 5 */ "..............."
/* 6 */ "..............."
/* 7 */ "..............."
@@ -845,7 +896,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
/* 10 */ "...............",
// Connectors:
- "-1: 14, 1, 3: 5\n" /* Type -1, direction X+ */,
+ "-1: 14, 2, 3: 5\n" /* Type -1, direction X+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -876,149 +927,162 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 80, ID 596, created by STR_Warrior
{
// Size:
- 7, 11, 7, // SizeX = 7, SizeY = 11, SizeZ = 7
+ 7, 12, 7, // SizeX = 7, SizeY = 12, SizeZ = 7
// Hitbox (relative to bounding box):
-1, 0, 0, // MinX, MinY, MinZ
- 7, 10, 7, // MaxX, MaxY, MaxZ
+ 7, 11, 7, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
- "c:128: 2\n" /* sandstonestairs */
- "d:128: 0\n" /* sandstonestairs */
- "e: 24: 2\n" /* sandstone */
- "f: 24: 0\n" /* sandstone */
- "g: 71: 3\n" /* irondoorblock */
- "h:128: 1\n" /* sandstonestairs */
- "i:128: 3\n" /* sandstonestairs */
- "j: 77: 4\n" /* stonebutton */
- "k: 71: 8\n" /* irondoorblock */
- "l:128: 6\n" /* sandstonestairs */
+ "a: 24: 0\n" /* sandstone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 12: 0\n" /* sand */
+ "d: 5: 0\n" /* wood */
+ "e: 13: 0\n" /* gravel */
+ "f:128: 2\n" /* sandstonestairs */
+ "g:128: 0\n" /* sandstonestairs */
+ "h: 24: 2\n" /* sandstone */
+ "i: 71: 3\n" /* irondoorblock */
+ "j:128: 1\n" /* sandstonestairs */
+ "k:128: 3\n" /* sandstonestairs */
+ "l: 77: 4\n" /* stonebutton */
"m: 19: 0\n" /* sponge */
- "n:128: 4\n" /* sandstonestairs */
- "o:128: 5\n" /* sandstonestairs */
- "p: 50: 4\n" /* torch */
- "q:128: 7\n" /* sandstonestairs */
- "r: 85: 0\n" /* fence */
- "s: 24: 1\n" /* sandstone */
- "t: 44: 1\n" /* step */
- "u: 89: 0\n" /* lightstone */,
+ "n: 71: 8\n" /* irondoorblock */
+ "o: 77: 3\n" /* stonebutton */
+ "p:128: 6\n" /* sandstonestairs */
+ "q:128: 4\n" /* sandstonestairs */
+ "r:128: 5\n" /* sandstonestairs */
+ "s: 50: 4\n" /* torch */
+ "t:128: 7\n" /* sandstonestairs */
+ "u: 85: 0\n" /* fence */
+ "v: 24: 1\n" /* sandstone */
+ "w: 44: 1\n" /* step */
+ "x: 89: 0\n" /* lightstone */,
// Block data:
// Level 0
/* z\x* 0123456 */
- /* 0 */ "aaaaaaa"
- /* 1 */ "aaabaaa"
- /* 2 */ "aabbbaa"
- /* 3 */ "aabbbaa"
- /* 4 */ "aabbbaa"
+ /* 0 */ "mabbbam"
+ /* 1 */ "aacdcaa"
+ /* 2 */ "madddam"
+ /* 3 */ "madddam"
+ /* 4 */ "madddam"
/* 5 */ "aaaaaaa"
- /* 6 */ "aaaaaaa"
+ /* 6 */ "mammmam"
// Level 1
/* z\x* 0123456 */
- /* 0 */ "mc...cm"
- /* 1 */ "defgfeh"
- /* 2 */ ".f...f."
- /* 3 */ ".f...f."
- /* 4 */ ".f...f."
- /* 5 */ "defffeh"
- /* 6 */ "mi...im"
+ /* 0 */ "maeeeam"
+ /* 1 */ "aacdcaa"
+ /* 2 */ "madddam"
+ /* 3 */ "madddam"
+ /* 4 */ "madddam"
+ /* 5 */ "aaaaaaa"
+ /* 6 */ "mammmam"
// Level 2
/* z\x* 0123456 */
- /* 0 */ "m.j...m"
- /* 1 */ ".efkfe."
- /* 2 */ ".f...f."
- /* 3 */ ".f...f."
- /* 4 */ ".f...f."
- /* 5 */ ".efffe."
- /* 6 */ "m.....m"
+ /* 0 */ "mf...fm"
+ /* 1 */ "ghaiahj"
+ /* 2 */ "ma...am"
+ /* 3 */ "ma...am"
+ /* 4 */ "ma...am"
+ /* 5 */ "ghaaahj"
+ /* 6 */ "mkmmmkm"
// Level 3
/* z\x* 0123456 */
- /* 0 */ "......."
- /* 1 */ "..lfl.."
- /* 2 */ ".n...o."
- /* 3 */ ".f...f."
- /* 4 */ ".n.p.o."
- /* 5 */ "..qfq.."
- /* 6 */ "......."
+ /* 0 */ "m.l...m"
+ /* 1 */ ".hanah."
+ /* 2 */ ".ao..a."
+ /* 3 */ ".a...a."
+ /* 4 */ ".a...a."
+ /* 5 */ ".haaah."
+ /* 6 */ "m.....m"
// Level 4
/* z\x* 0123456 */
/* 0 */ "......."
- /* 1 */ "..frf.."
- /* 2 */ ".f...f."
- /* 3 */ ".r...r."
- /* 4 */ ".f...f."
- /* 5 */ "..frf.."
+ /* 1 */ "..pap.."
+ /* 2 */ ".q...r."
+ /* 3 */ ".a...a."
+ /* 4 */ ".q.s.r."
+ /* 5 */ "..tat.."
/* 6 */ "......."
// Level 5
/* z\x* 0123456 */
/* 0 */ "......."
- /* 1 */ "..frf.."
- /* 2 */ ".f...f."
- /* 3 */ ".r...r."
- /* 4 */ ".f...f."
- /* 5 */ "..frf.."
+ /* 1 */ "..aua.."
+ /* 2 */ ".a...a."
+ /* 3 */ ".u...u."
+ /* 4 */ ".a...a."
+ /* 5 */ "..aua.."
/* 6 */ "......."
// Level 6
/* z\x* 0123456 */
/* 0 */ "......."
- /* 1 */ "..frf.."
- /* 2 */ ".f...f."
- /* 3 */ ".r...r."
- /* 4 */ ".f...f."
- /* 5 */ "..frf.."
+ /* 1 */ "..aua.."
+ /* 2 */ ".a...a."
+ /* 3 */ ".u...u."
+ /* 4 */ ".a...a."
+ /* 5 */ "..aua.."
/* 6 */ "......."
// Level 7
/* z\x* 0123456 */
/* 0 */ "......."
- /* 1 */ "..cfc.."
- /* 2 */ ".d...h."
- /* 3 */ ".f...f."
- /* 4 */ ".d...h."
- /* 5 */ "..ifi.."
+ /* 1 */ "..aua.."
+ /* 2 */ ".a...a."
+ /* 3 */ ".u...u."
+ /* 4 */ ".a...a."
+ /* 5 */ "..aua.."
/* 6 */ "......."
// Level 8
/* z\x* 0123456 */
/* 0 */ "......."
- /* 1 */ ".ffsff."
- /* 2 */ ".f...f."
- /* 3 */ ".s...s."
- /* 4 */ ".f...f."
- /* 5 */ ".ffsff."
+ /* 1 */ "..faf.."
+ /* 2 */ ".g...j."
+ /* 3 */ ".a...a."
+ /* 4 */ ".g...j."
+ /* 5 */ "..kak.."
/* 6 */ "......."
// Level 9
/* z\x* 0123456 */
- /* 0 */ "...l..."
- /* 1 */ ".efffe."
- /* 2 */ ".ftttf."
- /* 3 */ "nftftfo"
- /* 4 */ ".ftttf."
- /* 5 */ ".efffe."
- /* 6 */ "...q..."
+ /* 0 */ "......."
+ /* 1 */ ".aavaa."
+ /* 2 */ ".a...a."
+ /* 3 */ ".v...v."
+ /* 4 */ ".a...a."
+ /* 5 */ ".aavaa."
+ /* 6 */ "......."
// Level 10
/* z\x* 0123456 */
- /* 0 */ "...t..."
- /* 1 */ ".t...t."
+ /* 0 */ "...p..."
+ /* 1 */ ".haaah."
+ /* 2 */ ".awwwa."
+ /* 3 */ "qawawar"
+ /* 4 */ ".awwwa."
+ /* 5 */ ".haaah."
+ /* 6 */ "...t..."
+
+ // Level 11
+ /* z\x* 0123456 */
+ /* 0 */ "...w..."
+ /* 1 */ ".w...w."
/* 2 */ "......."
- /* 3 */ "t..u..t"
+ /* 3 */ "w..x..w"
/* 4 */ "......."
- /* 5 */ ".t...t."
- /* 6 */ "...t...",
+ /* 5 */ ".w...w."
+ /* 6 */ "...w...",
// Connectors:
- "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 3, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1049,86 +1113,97 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 65, ID 551, created by STR_Warrior
{
// Size:
- 5, 5, 7, // SizeX = 5, SizeY = 5, SizeZ = 7
+ 5, 6, 7, // SizeX = 5, SizeY = 6, SizeZ = 7
// Hitbox (relative to bounding box):
-1, 0, 0, // MinX, MinY, MinZ
- 5, 4, 7, // MaxX, MaxY, MaxZ
+ 5, 5, 7, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
- "c: 24: 2\n" /* sandstone */
- "d: 24: 0\n" /* sandstone */
- "e: 64: 3\n" /* wooddoorblock */
- "f: 61: 2\n" /* furnace */
- "g: 65: 2\n" /* ladder */
- "h: 64: 8\n" /* wooddoorblock */
- "i:101: 0\n" /* ironbars */
- "j: 50: 4\n" /* torch */
- "k:128: 2\n" /* sandstonestairs */
- "l:126: 8\n" /* woodenslab */
+ "a: 24: 2\n" /* sandstone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 24: 0\n" /* sandstone */
+ "d: 13: 0\n" /* gravel */
+ "e: 5: 0\n" /* wood */
+ "f: 64: 3\n" /* wooddoorblock */
+ "g: 61: 2\n" /* furnace */
+ "h: 65: 2\n" /* ladder */
+ "i: 64: 8\n" /* wooddoorblock */
+ "j:101: 0\n" /* ironbars */
+ "k: 50: 4\n" /* torch */
+ "l:128: 2\n" /* sandstonestairs */
"m: 19: 0\n" /* sponge */
- "n:128: 4\n" /* sandstonestairs */
- "o:128: 5\n" /* sandstonestairs */
- "p:128: 7\n" /* sandstonestairs */
- "q: 44: 1\n" /* step */
- "r: 96: 6\n" /* trapdoor */,
+ "n:126: 8\n" /* woodenslab */
+ "o:128: 4\n" /* sandstonestairs */
+ "p:128: 5\n" /* sandstonestairs */
+ "q:128: 7\n" /* sandstonestairs */
+ "r: 44: 1\n" /* step */
+ "s: 96: 2\n" /* trapdoor */,
// Block data:
// Level 0
/* z\x* 01234 */
- /* 0 */ "aaaaa"
- /* 1 */ "aaaaa"
- /* 2 */ "aabaa"
- /* 3 */ "abbba"
- /* 4 */ "abbba"
- /* 5 */ "abbba"
- /* 6 */ "aaaaa"
+ /* 0 */ "abbba"
+ /* 1 */ "mbbbm"
+ /* 2 */ "accca"
+ /* 3 */ "ccccc"
+ /* 4 */ "ccccc"
+ /* 5 */ "ccccc"
+ /* 6 */ "accca"
// Level 1
/* z\x* 01234 */
- /* 0 */ "c...c"
- /* 1 */ "....."
- /* 2 */ "cdedc"
- /* 3 */ "d...d"
- /* 4 */ "d...d"
- /* 5 */ "df.gd"
- /* 6 */ "cdddc"
+ /* 0 */ "addda"
+ /* 1 */ "mdddm"
+ /* 2 */ "aceca"
+ /* 3 */ "ceeec"
+ /* 4 */ "ceeec"
+ /* 5 */ "ceeec"
+ /* 6 */ "accca"
// Level 2
/* z\x* 01234 */
- /* 0 */ "c...c"
+ /* 0 */ "a...a"
/* 1 */ "....."
- /* 2 */ "cdhdc"
- /* 3 */ "d...d"
- /* 4 */ "i...i"
- /* 5 */ "dj.gd"
- /* 6 */ "cdidc"
+ /* 2 */ "acfca"
+ /* 3 */ "c...c"
+ /* 4 */ "c...c"
+ /* 5 */ "cg.hc"
+ /* 6 */ "accca"
// Level 3
/* z\x* 01234 */
- /* 0 */ "k...k"
- /* 1 */ "d...d"
- /* 2 */ "cdddc"
- /* 3 */ "dllld"
- /* 4 */ "nlllo"
- /* 5 */ "dllgd"
- /* 6 */ "cdpdc"
+ /* 0 */ "a...a"
+ /* 1 */ "....."
+ /* 2 */ "acica"
+ /* 3 */ "c...c"
+ /* 4 */ "j...j"
+ /* 5 */ "ck.hc"
+ /* 6 */ "acjca"
// Level 4
/* z\x* 01234 */
+ /* 0 */ "l...l"
+ /* 1 */ "c...c"
+ /* 2 */ "accca"
+ /* 3 */ "cnnnc"
+ /* 4 */ "onnnp"
+ /* 5 */ "cnnhc"
+ /* 6 */ "acqca"
+
+ // Level 5
+ /* z\x* 01234 */
/* 0 */ "....."
/* 1 */ "....."
- /* 2 */ "dqdqd"
- /* 3 */ "q...q"
- /* 4 */ "d...d"
- /* 5 */ "q..rq"
- /* 6 */ "dqdqd",
+ /* 2 */ "crcrc"
+ /* 3 */ "r...r"
+ /* 4 */ "c...c"
+ /* 5 */ "r..sr"
+ /* 6 */ "crcrc",
// Connectors:
- "-1: 2, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 2, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1159,107 +1234,123 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 72, ID 562, created by STR_Warrior
{
// Size:
- 7, 5, 11, // SizeX = 7, SizeY = 5, SizeZ = 11
+ 7, 6, 11, // SizeX = 7, SizeY = 6, SizeZ = 11
// Hitbox (relative to bounding box):
-1, 0, 0, // MinX, MinY, MinZ
- 7, 4, 11, // MaxX, MaxY, MaxZ
+ 7, 5, 11, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
- "c: 24: 2\n" /* sandstone */
- "d: 24: 0\n" /* sandstone */
- "e: 64: 3\n" /* wooddoorblock */
- "f: 65: 5\n" /* ladder */
- "g: 85: 0\n" /* fence */
- "h:101: 0\n" /* ironbars */
- "i: 64: 8\n" /* wooddoorblock */
- "j: 50: 3\n" /* torch */
- "k:128: 2\n" /* sandstonestairs */
- "l:128: 6\n" /* sandstonestairs */
+ "a: 24: 2\n" /* sandstone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 24: 0\n" /* sandstone */
+ "d: 12: 0\n" /* sand */
+ "e: 13: 0\n" /* gravel */
+ "f: 5: 0\n" /* wood */
+ "g: 64: 3\n" /* wooddoorblock */
+ "h: 65: 5\n" /* ladder */
+ "i: 85: 0\n" /* fence */
+ "j:101: 0\n" /* ironbars */
+ "k: 64: 8\n" /* wooddoorblock */
+ "l: 50: 3\n" /* torch */
"m: 19: 0\n" /* sponge */
- "n:126: 8\n" /* woodenslab */
- "o:128: 4\n" /* sandstonestairs */
- "p:128: 5\n" /* sandstonestairs */
- "q:128: 7\n" /* sandstonestairs */
- "r: 44: 1\n" /* step */
- "s: 96: 0\n" /* trapdoor */,
+ "n:128: 2\n" /* sandstonestairs */
+ "o:128: 6\n" /* sandstonestairs */
+ "p:126: 8\n" /* woodenslab */
+ "q:128: 4\n" /* sandstonestairs */
+ "r:128: 5\n" /* sandstonestairs */
+ "s:128: 7\n" /* sandstonestairs */
+ "t: 44: 1\n" /* step */
+ "u: 96: 0\n" /* trapdoor */,
// Block data:
// Level 0
/* z\x* 0123456 */
- /* 0 */ "aaaaaaa"
- /* 1 */ "aaaaaaa"
- /* 2 */ "aaaabaa"
- /* 3 */ "abbbbba"
- /* 4 */ "abbbbba"
- /* 5 */ "abbbbba"
- /* 6 */ "aabaaaa"
- /* 7 */ "aaaaaaa"
- /* 8 */ "aaaaaaa"
- /* 9 */ "aaaaaaa"
- /* 10 */ "aaaaaaa"
+ /* 0 */ "mabbbam"
+ /* 1 */ "mmbbbmm"
+ /* 2 */ "accccca"
+ /* 3 */ "ccccccc"
+ /* 4 */ "ccccccc"
+ /* 5 */ "ccccccc"
+ /* 6 */ "accccca"
+ /* 7 */ "ddddddd"
+ /* 8 */ "ddddddd"
+ /* 9 */ "ddddddd"
+ /* 10 */ "ddddddd"
// Level 1
/* z\x* 0123456 */
- /* 0 */ ".c...c."
- /* 1 */ "......."
- /* 2 */ "cdddedc"
- /* 3 */ "d.....d"
- /* 4 */ "d.....d"
- /* 5 */ "df....d"
- /* 6 */ "cd.dddc"
- /* 7 */ "g.....g"
- /* 8 */ "g.....g"
- /* 9 */ "g.....g"
- /* 10 */ "ggggggg"
+ /* 0 */ "maeeeam"
+ /* 1 */ "mmeeemm"
+ /* 2 */ "acccfca"
+ /* 3 */ "cfffffc"
+ /* 4 */ "cfffffc"
+ /* 5 */ "cfffffc"
+ /* 6 */ "acfccca"
+ /* 7 */ "ddddddd"
+ /* 8 */ "ddddddd"
+ /* 9 */ "ddddddd"
+ /* 10 */ "ddddddd"
// Level 2
/* z\x* 0123456 */
- /* 0 */ ".c...c."
- /* 1 */ "......."
- /* 2 */ "cdhdidc"
- /* 3 */ "d..j..d"
- /* 4 */ "h.....h"
- /* 5 */ "df....d"
- /* 6 */ "cd.dhdc"
+ /* 0 */ "ma...am"
+ /* 1 */ "m.....m"
+ /* 2 */ "acccgca"
+ /* 3 */ "c.....c"
+ /* 4 */ "c.....c"
+ /* 5 */ "ch....c"
+ /* 6 */ "ac.ccca"
+ /* 7 */ "i.....i"
+ /* 8 */ "i.....i"
+ /* 9 */ "i.....i"
+ /* 10 */ "iiiiiii"
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "ma...am"
+ /* 1 */ "m.....m"
+ /* 2 */ "acjckca"
+ /* 3 */ "c..l..c"
+ /* 4 */ "j.....j"
+ /* 5 */ "ch....c"
+ /* 6 */ "ac.cjca"
/* 7 */ "......."
/* 8 */ "......."
/* 9 */ "......."
/* 10 */ "......."
- // Level 3
+ // Level 4
/* z\x* 0123456 */
- /* 0 */ ".k...k."
- /* 1 */ ".d...d."
- /* 2 */ "cdldddc"
- /* 3 */ "dnnnnnd"
- /* 4 */ "onnnnnp"
- /* 5 */ "dfnnnnd"
- /* 6 */ "cdddqdc"
+ /* 0 */ "mn...nm"
+ /* 1 */ "mc...cm"
+ /* 2 */ "acoccca"
+ /* 3 */ "cpppppc"
+ /* 4 */ "qpppppr"
+ /* 5 */ "chppppc"
+ /* 6 */ "acccsca"
/* 7 */ "......."
/* 8 */ "......."
/* 9 */ "......."
/* 10 */ "......."
- // Level 4
+ // Level 5
/* z\x* 0123456 */
- /* 0 */ "......."
- /* 1 */ "......."
- /* 2 */ "drrdrrd"
- /* 3 */ "r.....r"
- /* 4 */ "d.....d"
- /* 5 */ "rs....r"
- /* 6 */ "drrdrrd"
+ /* 0 */ "m.....m"
+ /* 1 */ "m.....m"
+ /* 2 */ "cttcttc"
+ /* 3 */ "t.....t"
+ /* 4 */ "c.....c"
+ /* 5 */ "tu....t"
+ /* 6 */ "cttcttc"
/* 7 */ "......."
/* 8 */ "......."
/* 9 */ "......."
/* 10 */ ".......",
// Connectors:
- "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 3, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1290,85 +1381,96 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 66, ID 553, created by STR_Warrior
{
// Size:
- 9, 5, 7, // SizeX = 9, SizeY = 5, SizeZ = 7
+ 9, 6, 7, // SizeX = 9, SizeY = 6, SizeZ = 7
// Hitbox (relative to bounding box):
-1, 0, 0, // MinX, MinY, MinZ
- 9, 4, 7, // MaxX, MaxY, MaxZ
+ 9, 5, 7, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
- "c: 24: 2\n" /* sandstone */
- "d: 24: 0\n" /* sandstone */
- "e: 64: 7\n" /* wooddoorblock */
- "f: 65: 2\n" /* ladder */
- "g: 64:12\n" /* wooddoorblock */
- "h:101: 0\n" /* ironbars */
- "i: 50: 4\n" /* torch */
- "j:128: 2\n" /* sandstonestairs */
- "k:126: 8\n" /* woodenslab */
- "l:128: 4\n" /* sandstonestairs */
+ "a: 24: 2\n" /* sandstone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 24: 0\n" /* sandstone */
+ "d: 13: 0\n" /* gravel */
+ "e: 5: 0\n" /* wood */
+ "f: 64: 3\n" /* wooddoorblock */
+ "g: 65: 2\n" /* ladder */
+ "h: 64: 8\n" /* wooddoorblock */
+ "i:101: 0\n" /* ironbars */
+ "j: 50: 4\n" /* torch */
+ "k:128: 2\n" /* sandstonestairs */
+ "l:126: 8\n" /* woodenslab */
"m: 19: 0\n" /* sponge */
- "n:128: 5\n" /* sandstonestairs */
- "o:128: 7\n" /* sandstonestairs */
- "p: 44: 1\n" /* step */
- "q: 96: 2\n" /* trapdoor */,
+ "n:128: 4\n" /* sandstonestairs */
+ "o:128: 5\n" /* sandstonestairs */
+ "p:128: 7\n" /* sandstonestairs */
+ "q: 44: 1\n" /* step */
+ "r: 96: 2\n" /* trapdoor */,
// Block data:
// Level 0
/* z\x* 012345678 */
- /* 0 */ "aaaaaaaaa"
- /* 1 */ "aaaaaaaaa"
- /* 2 */ "aaaabaaaa"
- /* 3 */ "abbbbbbba"
- /* 4 */ "abbbbbbba"
- /* 5 */ "abbbbbbba"
- /* 6 */ "aaaaaaaaa"
+ /* 0 */ "mmabbbamm"
+ /* 1 */ "mmmbbbmmm"
+ /* 2 */ "accccccca"
+ /* 3 */ "ccccccccc"
+ /* 4 */ "ccccccccc"
+ /* 5 */ "ccccccccc"
+ /* 6 */ "accccccca"
// Level 1
/* z\x* 012345678 */
- /* 0 */ "..c...c.."
- /* 1 */ "........."
- /* 2 */ "cdddedddc"
- /* 3 */ "d.......d"
- /* 4 */ "d.......d"
- /* 5 */ "d......fd"
- /* 6 */ "cdddddddc"
+ /* 0 */ "mmadddamm"
+ /* 1 */ "mmmdddmmm"
+ /* 2 */ "accceccca"
+ /* 3 */ "ceeeeeeec"
+ /* 4 */ "ceeeeeeec"
+ /* 5 */ "ceeeeeeec"
+ /* 6 */ "accccccca"
// Level 2
/* z\x* 012345678 */
- /* 0 */ "..c...c.."
- /* 1 */ "........."
- /* 2 */ "cdddgdddc"
- /* 3 */ "d.......d"
- /* 4 */ "h.......h"
- /* 5 */ "d.i....fd"
- /* 6 */ "cddhhhddc"
+ /* 0 */ "mma...amm"
+ /* 1 */ "mm.....mm"
+ /* 2 */ "acccfccca"
+ /* 3 */ "c.......c"
+ /* 4 */ "c.......c"
+ /* 5 */ "c......gc"
+ /* 6 */ "accccccca"
// Level 3
/* z\x* 012345678 */
- /* 0 */ "..j...j.."
- /* 1 */ "..d...d.."
- /* 2 */ "cdddddddc"
- /* 3 */ "dkkkkkkkd"
- /* 4 */ "lkkkkkkkn"
- /* 5 */ "dkkkkkkfd"
- /* 6 */ "cddoooddc"
+ /* 0 */ "mma...amm"
+ /* 1 */ "mm.....mm"
+ /* 2 */ "accchccca"
+ /* 3 */ "c.......c"
+ /* 4 */ "i.......i"
+ /* 5 */ "c.j....gc"
+ /* 6 */ "acciiicca"
// Level 4
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "dpppdpppd"
- /* 3 */ "p.......p"
- /* 4 */ "d.......d"
- /* 5 */ "p......qp"
- /* 6 */ "dpppdpppd",
+ /* 0 */ "mmk...kmm"
+ /* 1 */ "mmc...cmm"
+ /* 2 */ "accccccca"
+ /* 3 */ "clllllllc"
+ /* 4 */ "nlllllllo"
+ /* 5 */ "cllllllgc"
+ /* 6 */ "accpppcca"
+
+ // Level 5
+ /* z\x* 012345678 */
+ /* 0 */ "mm.....mm"
+ /* 1 */ "mm.....mm"
+ /* 2 */ "cqqqcqqqc"
+ /* 3 */ "q.......q"
+ /* 4 */ "c.......c"
+ /* 5 */ "q......rq"
+ /* 6 */ "cqqqcqqqc",
// Connectors:
- "-1: 4, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 4, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1399,112 +1501,127 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 70, ID 560, created by STR_Warrior
{
// Size:
- 5, 5, 11, // SizeX = 5, SizeY = 5, SizeZ = 11
+ 5, 6, 11, // SizeX = 5, SizeY = 6, SizeZ = 11
// Hitbox (relative to bounding box):
-1, 0, 0, // MinX, MinY, MinZ
- 5, 4, 11, // MaxX, MaxY, MaxZ
+ 5, 5, 11, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
- "c: 24: 2\n" /* sandstone */
- "d: 24: 0\n" /* sandstone */
- "e: 64: 7\n" /* wooddoorblock */
- "f: 65: 5\n" /* ladder */
- "g:134: 3\n" /* 134 */
- "h: 85: 0\n" /* fence */
- "i:134: 2\n" /* 134 */
- "j: 61: 2\n" /* furnace */
- "k:134: 6\n" /* 134 */
- "l:134: 4\n" /* 134 */
+ "a: 24: 2\n" /* sandstone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 24: 0\n" /* sandstone */
+ "d: 13: 0\n" /* gravel */
+ "e: 5: 0\n" /* wood */
+ "f: 64: 3\n" /* wooddoorblock */
+ "g: 65: 5\n" /* ladder */
+ "h:134: 3\n" /* 134 */
+ "i: 85: 0\n" /* fence */
+ "j:134: 2\n" /* 134 */
+ "k: 61: 2\n" /* furnace */
+ "l:134: 6\n" /* 134 */
"m: 19: 0\n" /* sponge */
- "n: 64:12\n" /* wooddoorblock */
- "o: 50: 2\n" /* torch */
- "p:101: 0\n" /* ironbars */
- "q:171: 8\n" /* carpet */
- "r:128: 2\n" /* sandstonestairs */
- "s:126: 8\n" /* woodenslab */
- "t:128: 4\n" /* sandstonestairs */
- "u:128: 5\n" /* sandstonestairs */
- "v:128: 7\n" /* sandstonestairs */
- "w: 44: 1\n" /* step */
- "x: 96: 1\n" /* trapdoor */,
+ "n:134: 4\n" /* 134 */
+ "o: 64: 8\n" /* wooddoorblock */
+ "p: 50: 2\n" /* torch */
+ "q:101: 0\n" /* ironbars */
+ "r:171: 8\n" /* carpet */
+ "s:128: 2\n" /* sandstonestairs */
+ "t:126: 8\n" /* woodenslab */
+ "u:128: 4\n" /* sandstonestairs */
+ "v:128: 5\n" /* sandstonestairs */
+ "w:128: 7\n" /* sandstonestairs */
+ "x: 44: 1\n" /* step */
+ "y: 96: 1\n" /* trapdoor */,
// Block data:
// Level 0
/* z\x* 01234 */
- /* 0 */ "aaaaa"
- /* 1 */ "aaaaa"
- /* 2 */ "aabaa"
- /* 3 */ "abbba"
- /* 4 */ "abbba"
- /* 5 */ "abbba"
- /* 6 */ "abbba"
- /* 7 */ "abbba"
- /* 8 */ "abbba"
- /* 9 */ "abbba"
- /* 10 */ "aaaaa"
+ /* 0 */ "abbba"
+ /* 1 */ "mbbbm"
+ /* 2 */ "accca"
+ /* 3 */ "ccccc"
+ /* 4 */ "ccccc"
+ /* 5 */ "ccccc"
+ /* 6 */ "ccccc"
+ /* 7 */ "ccccc"
+ /* 8 */ "ccccc"
+ /* 9 */ "ccccc"
+ /* 10 */ "accca"
// Level 1
/* z\x* 01234 */
- /* 0 */ "c...c"
- /* 1 */ "....."
- /* 2 */ "cdedc"
- /* 3 */ "df..d"
- /* 4 */ "d...d"
- /* 5 */ "d..gd"
- /* 6 */ "d..hd"
- /* 7 */ "d..id"
- /* 8 */ "d...d"
- /* 9 */ "djkld"
- /* 10 */ "cdddc"
+ /* 0 */ "addda"
+ /* 1 */ "mdddm"
+ /* 2 */ "aceca"
+ /* 3 */ "ceeec"
+ /* 4 */ "ceeec"
+ /* 5 */ "ceeec"
+ /* 6 */ "ceeec"
+ /* 7 */ "ceeec"
+ /* 8 */ "ceeec"
+ /* 9 */ "ceeec"
+ /* 10 */ "accca"
// Level 2
/* z\x* 01234 */
- /* 0 */ "c...c"
+ /* 0 */ "a...a"
/* 1 */ "....."
- /* 2 */ "cdndc"
- /* 3 */ "df..d"
- /* 4 */ "d..od"
- /* 5 */ "p...p"
- /* 6 */ "p..qp"
- /* 7 */ "p...p"
- /* 8 */ "d...d"
- /* 9 */ "d...d"
- /* 10 */ "cdpdc"
+ /* 2 */ "acfca"
+ /* 3 */ "cg..c"
+ /* 4 */ "c...c"
+ /* 5 */ "c..hc"
+ /* 6 */ "c..ic"
+ /* 7 */ "c..jc"
+ /* 8 */ "c...c"
+ /* 9 */ "cklnc"
+ /* 10 */ "accca"
// Level 3
/* z\x* 01234 */
- /* 0 */ "r...r"
- /* 1 */ "d...d"
- /* 2 */ "cdddc"
- /* 3 */ "dfssd"
- /* 4 */ "dsssd"
- /* 5 */ "tsssu"
- /* 6 */ "tsssu"
- /* 7 */ "tsssu"
- /* 8 */ "dsssd"
- /* 9 */ "dsssd"
- /* 10 */ "cdvdc"
+ /* 0 */ "a...a"
+ /* 1 */ "....."
+ /* 2 */ "acoca"
+ /* 3 */ "cg..c"
+ /* 4 */ "c..pc"
+ /* 5 */ "q...q"
+ /* 6 */ "q..rq"
+ /* 7 */ "q...q"
+ /* 8 */ "c...c"
+ /* 9 */ "c...c"
+ /* 10 */ "acqca"
// Level 4
/* z\x* 01234 */
+ /* 0 */ "s...s"
+ /* 1 */ "c...c"
+ /* 2 */ "accca"
+ /* 3 */ "cgttc"
+ /* 4 */ "ctttc"
+ /* 5 */ "utttv"
+ /* 6 */ "utttv"
+ /* 7 */ "utttv"
+ /* 8 */ "ctttc"
+ /* 9 */ "ctttc"
+ /* 10 */ "acwca"
+
+ // Level 5
+ /* z\x* 01234 */
/* 0 */ "....."
/* 1 */ "....."
- /* 2 */ "dwdwd"
- /* 3 */ "wx..w"
- /* 4 */ "w...w"
- /* 5 */ "w...w"
- /* 6 */ "d...d"
- /* 7 */ "w...w"
- /* 8 */ "w...w"
- /* 9 */ "w...w"
- /* 10 */ "dwdwd",
+ /* 2 */ "cxcxc"
+ /* 3 */ "xy..x"
+ /* 4 */ "x...x"
+ /* 5 */ "x...x"
+ /* 6 */ "c...c"
+ /* 7 */ "x...x"
+ /* 8 */ "x...x"
+ /* 9 */ "x...x"
+ /* 10 */ "cxcxc",
// Connectors:
- "-1: 2, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 2, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1535,97 +1652,110 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 68, ID 558, created by STR_Warrior
{
// Size:
- 9, 5, 9, // SizeX = 9, SizeY = 5, SizeZ = 9
+ 9, 6, 9, // SizeX = 9, SizeY = 6, SizeZ = 9
// Hitbox (relative to bounding box):
-1, 0, 0, // MinX, MinY, MinZ
- 9, 4, 9, // MaxX, MaxY, MaxZ
+ 9, 5, 9, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
- "c: 24: 2\n" /* sandstone */
- "d: 24: 0\n" /* sandstone */
- "e: 64: 7\n" /* wooddoorblock */
- "f: 65: 2\n" /* ladder */
- "g: 64:12\n" /* wooddoorblock */
- "h:101: 0\n" /* ironbars */
- "i: 50: 1\n" /* torch */
- "j: 50: 4\n" /* torch */
- "k:128: 2\n" /* sandstonestairs */
- "l:126: 8\n" /* woodenslab */
+ "a: 24: 2\n" /* sandstone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 24: 0\n" /* sandstone */
+ "d: 13: 0\n" /* gravel */
+ "e: 5: 0\n" /* wood */
+ "f: 64: 3\n" /* wooddoorblock */
+ "g: 65: 2\n" /* ladder */
+ "h: 64: 8\n" /* wooddoorblock */
+ "i:101: 0\n" /* ironbars */
+ "j: 50: 1\n" /* torch */
+ "k: 50: 4\n" /* torch */
+ "l:128: 2\n" /* sandstonestairs */
"m: 19: 0\n" /* sponge */
- "n:128: 6\n" /* sandstonestairs */
- "o:128: 5\n" /* sandstonestairs */
- "p:128: 4\n" /* sandstonestairs */
- "q:128: 7\n" /* sandstonestairs */
- "r: 44: 1\n" /* step */
- "s: 96: 6\n" /* trapdoor */,
+ "n:126: 8\n" /* woodenslab */
+ "o:128: 6\n" /* sandstonestairs */
+ "p:128: 5\n" /* sandstonestairs */
+ "q:128: 4\n" /* sandstonestairs */
+ "r:128: 7\n" /* sandstonestairs */
+ "s: 44: 1\n" /* step */
+ "t: 96: 2\n" /* trapdoor */,
// Block data:
// Level 0
/* z\x* 012345678 */
- /* 0 */ "aaaaaaaaa"
- /* 1 */ "aaaaaaaaa"
- /* 2 */ "aaaaaabaa"
- /* 3 */ "aaaaabbba"
- /* 4 */ "aaaaabbba"
- /* 5 */ "abbbbbbba"
- /* 6 */ "abbbbbbba"
- /* 7 */ "abbbbbbba"
- /* 8 */ "aaaaaaaaa"
+ /* 0 */ "mmmmabbba"
+ /* 1 */ "mmmmmbbbm"
+ /* 2 */ "mmmmaccca"
+ /* 3 */ "mmmmccccc"
+ /* 4 */ "acccacccc"
+ /* 5 */ "ccccccccc"
+ /* 6 */ "ccccccccc"
+ /* 7 */ "ccccccccc"
+ /* 8 */ "accccccca"
// Level 1
/* z\x* 012345678 */
- /* 0 */ "mmmmc...c"
- /* 1 */ "mmmm....."
- /* 2 */ "mmmmcdedc"
- /* 3 */ "mmmmd...d"
- /* 4 */ "cdddd...d"
- /* 5 */ "d.......d"
- /* 6 */ "d.......d"
- /* 7 */ "d......fd"
- /* 8 */ "cdddddddc"
+ /* 0 */ "mmmmaddda"
+ /* 1 */ "mmmmmdddm"
+ /* 2 */ "mmmmaceca"
+ /* 3 */ "mmmmceeec"
+ /* 4 */ "acccaeeec"
+ /* 5 */ "ceeeeeeec"
+ /* 6 */ "ceeeeeeec"
+ /* 7 */ "ceeeeeeec"
+ /* 8 */ "accccccca"
// Level 2
/* z\x* 012345678 */
- /* 0 */ "mmmmc...c"
+ /* 0 */ "mmmma...a"
/* 1 */ "mmmm....."
- /* 2 */ "mmmmcdgdc"
- /* 3 */ "mmmmd...d"
- /* 4 */ "cdhdd...h"
- /* 5 */ "d.......h"
- /* 6 */ "h.......d"
- /* 7 */ "di....jfd"
- /* 8 */ "cddhhhddc"
+ /* 2 */ "mmmmacfca"
+ /* 3 */ "mmmmc...c"
+ /* 4 */ "accca...c"
+ /* 5 */ "c.......c"
+ /* 6 */ "c.......c"
+ /* 7 */ "c......gc"
+ /* 8 */ "accccccca"
// Level 3
/* z\x* 012345678 */
- /* 0 */ "mmmmk...k"
- /* 1 */ "mmmmd...d"
- /* 2 */ "mmmmcdddc"
- /* 3 */ "mmmmdllld"
- /* 4 */ "cdnddlllo"
- /* 5 */ "dlllllllo"
- /* 6 */ "pllllllld"
- /* 7 */ "dllllllfd"
- /* 8 */ "cddqqqddc"
+ /* 0 */ "mmmma...a"
+ /* 1 */ "mmmm....."
+ /* 2 */ "mmmmachca"
+ /* 3 */ "mmmmc...c"
+ /* 4 */ "acica...i"
+ /* 5 */ "c.......i"
+ /* 6 */ "i.......i"
+ /* 7 */ "cj....kgc"
+ /* 8 */ "acciiicca"
// Level 4
/* z\x* 012345678 */
+ /* 0 */ "mmmml...l"
+ /* 1 */ "mmmmc...c"
+ /* 2 */ "mmmmaccca"
+ /* 3 */ "mmmmcnnnc"
+ /* 4 */ "acocannnp"
+ /* 5 */ "cnnnnnnnp"
+ /* 6 */ "qnnnnnnnp"
+ /* 7 */ "cnnnnnngc"
+ /* 8 */ "accrrrcca"
+
+ // Level 5
+ /* z\x* 012345678 */
/* 0 */ "mmmm....."
/* 1 */ "mmmm....."
- /* 2 */ "mmmmcrdrd"
- /* 3 */ "mmmmr...r"
- /* 4 */ "drrrd...d"
- /* 5 */ "r.......r"
- /* 6 */ "r.......r"
- /* 7 */ "r......sr"
- /* 8 */ "drrrdrrrd",
+ /* 2 */ "mmmmcscsc"
+ /* 3 */ "mmmms...s"
+ /* 4 */ "csssc...c"
+ /* 5 */ "s.......s"
+ /* 6 */ "s.......s"
+ /* 7 */ "s......ts"
+ /* 8 */ "cssscsssc",
// Connectors:
- "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 6, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1656,102 +1786,117 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 69, ID 559, created by STR_Warrior
{
// Size:
- 9, 5, 9, // SizeX = 9, SizeY = 5, SizeZ = 9
+ 9, 6, 9, // SizeX = 9, SizeY = 6, SizeZ = 9
// Hitbox (relative to bounding box):
-1, 0, 0, // MinX, MinY, MinZ
- 9, 4, 9, // MaxX, MaxY, MaxZ
+ 9, 5, 9, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
+ "A: 96: 2\n" /* trapdoor */
"a: 12: 0\n" /* sand */
- "b: 2: 0\n" /* grass */
- "c: 5: 0\n" /* wood */
- "d: 85: 0\n" /* fence */
- "e: 24: 2\n" /* sandstone */
- "f: 24: 0\n" /* sandstone */
- "g: 64: 7\n" /* wooddoorblock */
- "h: 38: 1\n" /* rose */
- "i: 38: 2\n" /* rose */
- "j: 38: 5\n" /* rose */
- "k: 65: 2\n" /* ladder */
- "l: 64:12\n" /* wooddoorblock */
+ "b: 24: 2\n" /* sandstone */
+ "c: 4: 0\n" /* cobblestone */
+ "d: 3: 0\n" /* dirt */
+ "e: 24: 0\n" /* sandstone */
+ "f: 13: 0\n" /* gravel */
+ "g: 2: 0\n" /* grass */
+ "h: 5: 0\n" /* wood */
+ "i: 85: 0\n" /* fence */
+ "j: 64: 3\n" /* wooddoorblock */
+ "k: 38: 1\n" /* rose */
+ "l: 38: 2\n" /* rose */
"m: 19: 0\n" /* sponge */
- "n:101: 0\n" /* ironbars */
- "o: 50: 1\n" /* torch */
- "p: 50: 4\n" /* torch */
- "q:128: 2\n" /* sandstonestairs */
- "r:126: 8\n" /* woodenslab */
- "s:128: 6\n" /* sandstonestairs */
- "t:128: 5\n" /* sandstonestairs */
- "u:128: 4\n" /* sandstonestairs */
- "v:128: 7\n" /* sandstonestairs */
- "w: 44: 1\n" /* step */
- "x: 96: 6\n" /* trapdoor */,
+ "n: 38: 5\n" /* rose */
+ "o: 65: 2\n" /* ladder */
+ "p: 64: 8\n" /* wooddoorblock */
+ "q:101: 0\n" /* ironbars */
+ "r: 50: 1\n" /* torch */
+ "s: 50: 4\n" /* torch */
+ "t:128: 2\n" /* sandstonestairs */
+ "u:126: 8\n" /* woodenslab */
+ "v:128: 6\n" /* sandstonestairs */
+ "w:128: 5\n" /* sandstonestairs */
+ "x:128: 4\n" /* sandstonestairs */
+ "y:128: 7\n" /* sandstonestairs */
+ "z: 44: 1\n" /* step */,
// Block data:
// Level 0
/* z\x* 012345678 */
- /* 0 */ "aaaaaaaaa"
- /* 1 */ "abbbaaaaa"
- /* 2 */ "abbbaacaa"
- /* 3 */ "abbbaccca"
- /* 4 */ "aaaaaccca"
- /* 5 */ "accccccca"
- /* 6 */ "accccccca"
- /* 7 */ "accccccca"
- /* 8 */ "aaaaaaaaa"
+ /* 0 */ "aaaabcccb"
+ /* 1 */ "adddccccm"
+ /* 2 */ "adddbeeeb"
+ /* 3 */ "adddeeeee"
+ /* 4 */ "beeebeeee"
+ /* 5 */ "eeeeeeeee"
+ /* 6 */ "eeeeeeeee"
+ /* 7 */ "eeeeeeeee"
+ /* 8 */ "beeeeeeeb"
// Level 1
/* z\x* 012345678 */
- /* 0 */ "dddde...e"
- /* 1 */ "d........"
- /* 2 */ "d...efgfe"
- /* 3 */ "dhijf...f"
- /* 4 */ "effff...f"
- /* 5 */ "f.......f"
- /* 6 */ "f.......f"
- /* 7 */ "f......kf"
- /* 8 */ "efffffffe"
+ /* 0 */ "aaaabfffb"
+ /* 1 */ "agggffffm"
+ /* 2 */ "agggbeheb"
+ /* 3 */ "agggehhhe"
+ /* 4 */ "beeebhhhe"
+ /* 5 */ "ehhhhhhhe"
+ /* 6 */ "ehhhhhhhe"
+ /* 7 */ "ehhhhhhhe"
+ /* 8 */ "beeeeeeeb"
// Level 2
/* z\x* 012345678 */
- /* 0 */ "....e...e"
- /* 1 */ "........."
- /* 2 */ "....eflfe"
- /* 3 */ "....f...f"
- /* 4 */ "efnff...n"
- /* 5 */ "f.......n"
- /* 6 */ "n.......f"
- /* 7 */ "fo....pkf"
- /* 8 */ "effnnnffe"
+ /* 0 */ "iiiib...b"
+ /* 1 */ "i........"
+ /* 2 */ "i...bejeb"
+ /* 3 */ "iklne...e"
+ /* 4 */ "beeeb...e"
+ /* 5 */ "e.......e"
+ /* 6 */ "e.......e"
+ /* 7 */ "e......oe"
+ /* 8 */ "beeeeeeeb"
// Level 3
/* z\x* 012345678 */
- /* 0 */ "....q...q"
- /* 1 */ "....f...f"
- /* 2 */ "....efffe"
- /* 3 */ "....frrrf"
- /* 4 */ "efsffrrrt"
- /* 5 */ "frrrrrrrt"
- /* 6 */ "urrrrrrrf"
- /* 7 */ "frrrrrrkf"
- /* 8 */ "effvvvffe"
+ /* 0 */ "....b...b"
+ /* 1 */ "........."
+ /* 2 */ "....bepeb"
+ /* 3 */ "....e...e"
+ /* 4 */ "beqeb...q"
+ /* 5 */ "e.......q"
+ /* 6 */ "q.......q"
+ /* 7 */ "er....soe"
+ /* 8 */ "beeqqqeeb"
// Level 4
/* z\x* 012345678 */
+ /* 0 */ "....t...t"
+ /* 1 */ "....e...e"
+ /* 2 */ "....beeeb"
+ /* 3 */ "....euuue"
+ /* 4 */ "bevebuuuw"
+ /* 5 */ "euuuuuuuw"
+ /* 6 */ "xuuuuuuuw"
+ /* 7 */ "euuuuuuoe"
+ /* 8 */ "beeyyyeeb"
+
+ // Level 5
+ /* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
- /* 2 */ "....ewfwf"
- /* 3 */ "....w...w"
- /* 4 */ "fwwwf...f"
- /* 5 */ "w.......w"
- /* 6 */ "w.......w"
- /* 7 */ "w......xw"
- /* 8 */ "fwwwfwwwf",
+ /* 2 */ "....ezeze"
+ /* 3 */ "....z...z"
+ /* 4 */ "ezzze...e"
+ /* 5 */ "z.......z"
+ /* 6 */ "z.......z"
+ /* 7 */ "z......Az"
+ /* 8 */ "ezzzezzze",
// Connectors:
- "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 6, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1782,107 +1927,122 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 73, ID 563, created by xoft
{
// Size:
- 9, 5, 11, // SizeX = 9, SizeY = 5, SizeZ = 11
+ 9, 6, 11, // SizeX = 9, SizeY = 6, SizeZ = 11
// Hitbox (relative to bounding box):
-1, 0, 0, // MinX, MinY, MinZ
- 9, 4, 11, // MaxX, MaxY, MaxZ
+ 9, 5, 11, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
- "c: 24: 2\n" /* sandstone */
- "d: 24: 0\n" /* sandstone */
- "e: 64: 7\n" /* wooddoorblock */
- "f: 65: 2\n" /* ladder */
- "g:101: 0\n" /* ironbars */
- "h: 64:12\n" /* wooddoorblock */
- "i: 50: 1\n" /* torch */
- "j: 50: 2\n" /* torch */
- "k:128: 2\n" /* sandstonestairs */
- "l:128: 6\n" /* sandstonestairs */
+ "a: 24: 2\n" /* sandstone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 24: 0\n" /* sandstone */
+ "d: 13: 0\n" /* gravel */
+ "e: 5: 0\n" /* wood */
+ "f: 64: 3\n" /* wooddoorblock */
+ "g: 65: 2\n" /* ladder */
+ "h:101: 0\n" /* ironbars */
+ "i: 64: 8\n" /* wooddoorblock */
+ "j: 50: 1\n" /* torch */
+ "k: 50: 2\n" /* torch */
+ "l:128: 2\n" /* sandstonestairs */
"m: 19: 0\n" /* sponge */
- "n:126: 8\n" /* woodenslab */
- "o:128: 4\n" /* sandstonestairs */
- "p:128: 5\n" /* sandstonestairs */
- "q:128: 7\n" /* sandstonestairs */
- "r: 44: 1\n" /* step */
- "s: 96: 6\n" /* trapdoor */,
+ "n:128: 6\n" /* sandstonestairs */
+ "o:126: 8\n" /* woodenslab */
+ "p:128: 4\n" /* sandstonestairs */
+ "q:128: 5\n" /* sandstonestairs */
+ "r:128: 7\n" /* sandstonestairs */
+ "s: 44: 1\n" /* step */
+ "t: 96: 2\n" /* trapdoor */,
// Block data:
// Level 0
/* z\x* 012345678 */
- /* 0 */ "aaaaaaaaa"
- /* 1 */ "aaaaaaaaa"
- /* 2 */ "aaaaaabaa"
- /* 3 */ "abbbbbbba"
- /* 4 */ "abbbbbbba"
- /* 5 */ "abbbbbbba"
- /* 6 */ "aaaaabbba"
- /* 7 */ "aaaaabbba"
- /* 8 */ "aaaaabbba"
- /* 9 */ "aaaaabbba"
- /* 10 */ "aaaaaaaaa"
+ /* 0 */ "mmmmabbba"
+ /* 1 */ "mmmmmbbbm"
+ /* 2 */ "accccccca"
+ /* 3 */ "ccccccccc"
+ /* 4 */ "ccccccccc"
+ /* 5 */ "ccccccccc"
+ /* 6 */ "acccacccc"
+ /* 7 */ "mmmmccccc"
+ /* 8 */ "mmmmccccc"
+ /* 9 */ "mmmmccccc"
+ /* 10 */ "mmmmaccca"
// Level 1
/* z\x* 012345678 */
- /* 0 */ "....c...c"
- /* 1 */ "........."
- /* 2 */ "cdddddedc"
- /* 3 */ "d.......d"
- /* 4 */ "d.......d"
- /* 5 */ "d.......d"
- /* 6 */ "cdddd...d"
- /* 7 */ "mmmmd...d"
- /* 8 */ "mmmmd...d"
- /* 9 */ "mmmmd..fd"
- /* 10 */ "mmmmddddc"
+ /* 0 */ "mmmmaddda"
+ /* 1 */ "mmmmmdddm"
+ /* 2 */ "accccceca"
+ /* 3 */ "ceeeeeeec"
+ /* 4 */ "ceeeeeeec"
+ /* 5 */ "ceeeeeeec"
+ /* 6 */ "acccaeeec"
+ /* 7 */ "mmmmceeec"
+ /* 8 */ "mmmmceeec"
+ /* 9 */ "mmmmceeec"
+ /* 10 */ "mmmmaccca"
// Level 2
/* z\x* 012345678 */
- /* 0 */ "....c...c"
- /* 1 */ "........."
- /* 2 */ "cdgdddhdc"
- /* 3 */ "d.......d"
- /* 4 */ "g.......d"
- /* 5 */ "di......g"
- /* 6 */ "cdgdd...g"
- /* 7 */ "mmmmd...g"
- /* 8 */ "mmmmg..jd"
- /* 9 */ "mmmmd..fd"
- /* 10 */ "mmmmddgdc"
+ /* 0 */ "mmmma...a"
+ /* 1 */ "mmmm....."
+ /* 2 */ "acccccfca"
+ /* 3 */ "c.......c"
+ /* 4 */ "c.......c"
+ /* 5 */ "c.......c"
+ /* 6 */ "accca...c"
+ /* 7 */ "mmmmc...c"
+ /* 8 */ "mmmmc...c"
+ /* 9 */ "mmmmc..gc"
+ /* 10 */ "mmmmaccca"
// Level 3
/* z\x* 012345678 */
- /* 0 */ "....k...k"
- /* 1 */ "....d...d"
- /* 2 */ "cdldddddc"
- /* 3 */ "dnnnnnnnd"
- /* 4 */ "onnnnnnnd"
- /* 5 */ "dnnnnnnnp"
- /* 6 */ "cdqddnnnp"
- /* 7 */ "mmmmdnnnp"
- /* 8 */ "mmmmonnnd"
- /* 9 */ "mmmmdnnfd"
- /* 10 */ "mmmmddqdc"
+ /* 0 */ "mmmma...a"
+ /* 1 */ "mmmm....."
+ /* 2 */ "achcccica"
+ /* 3 */ "c.......c"
+ /* 4 */ "h.......c"
+ /* 5 */ "cj......h"
+ /* 6 */ "achca...h"
+ /* 7 */ "mmmmc...h"
+ /* 8 */ "mmmmh..kc"
+ /* 9 */ "mmmmc..gc"
+ /* 10 */ "mmmmachca"
// Level 4
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "drrrdrdrd"
- /* 3 */ "r.......r"
- /* 4 */ "r.......r"
- /* 5 */ "r.......r"
- /* 6 */ "drrrd...d"
- /* 7 */ "mmmmr...r"
- /* 8 */ "mmmmr...r"
- /* 9 */ "mmmmr..sr"
- /* 10 */ "mmmmdrrrd",
+ /* 0 */ "mmmml...l"
+ /* 1 */ "mmmmc...c"
+ /* 2 */ "acnccccca"
+ /* 3 */ "coooooooc"
+ /* 4 */ "poooooooc"
+ /* 5 */ "coooooooq"
+ /* 6 */ "acrcaoooq"
+ /* 7 */ "mmmmcoooq"
+ /* 8 */ "mmmmpoooc"
+ /* 9 */ "mmmmcoogc"
+ /* 10 */ "mmmmacrca"
+
+ // Level 5
+ /* z\x* 012345678 */
+ /* 0 */ "mmmm....."
+ /* 1 */ "mmmm....."
+ /* 2 */ "cssscscsc"
+ /* 3 */ "s.......s"
+ /* 4 */ "s.......s"
+ /* 5 */ "s.......s"
+ /* 6 */ "csssc...c"
+ /* 7 */ "mmmms...s"
+ /* 8 */ "mmmms...s"
+ /* 9 */ "mmmms..ts"
+ /* 10 */ "mmmmcsssc",
// Connectors:
- "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 6, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1909,120 +2069,263 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // LittleTower:
- // The data has been exported from the gallery Desert, area index 79, ID 595, created by STR_Warrior
+ // LittleHouse8:
+ // The data has been exported from the gallery Desert, area index 99, ID 739, created by STR_Warrior
{
// Size:
- 5, 8, 7, // SizeX = 5, SizeY = 8, SizeZ = 7
+ 9, 6, 9, // SizeX = 9, SizeY = 6, SizeZ = 9
// Hitbox (relative to bounding box):
- -1, 0, 0, // MinX, MinY, MinZ
- 5, 7, 7, // MaxX, MaxY, MaxZ
+ 0, 0, -1, // MinX, MinY, MinZ
+ 9, 5, 9, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
- "c: 24: 2\n" /* sandstone */
- "d: 24: 0\n" /* sandstone */
- "e: 64: 7\n" /* wooddoorblock */
- "f: 65: 5\n" /* ladder */
- "g: 64:12\n" /* wooddoorblock */
+ "a: 24: 2\n" /* sandstone */
+ "b: 24: 0\n" /* sandstone */
+ "c: 4: 0\n" /* cobblestone */
+ "d: 13: 0\n" /* gravel */
+ "e: 5: 0\n" /* wood */
+ "f: 64: 2\n" /* wooddoorblock */
+ "g: 65: 2\n" /* ladder */
"h:101: 0\n" /* ironbars */
- "i: 50: 4\n" /* torch */
- "j:128: 2\n" /* sandstonestairs */
- "k:126: 8\n" /* woodenslab */
- "l:128: 4\n" /* sandstonestairs */
+ "i: 64: 8\n" /* wooddoorblock */
+ "j: 50: 1\n" /* torch */
+ "k:128: 6\n" /* sandstonestairs */
+ "l:126: 8\n" /* woodenslab */
"m: 19: 0\n" /* sponge */
"n:128: 5\n" /* sandstonestairs */
- "o:128: 7\n" /* sandstonestairs */
- "p:128: 6\n" /* sandstonestairs */
+ "o:128: 4\n" /* sandstonestairs */
+ "p:128: 7\n" /* sandstonestairs */
"q: 44: 1\n" /* step */
- "r: 96: 5\n" /* trapdoor */,
+ "r: 96: 2\n" /* trapdoor */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 012345678 */
+ /* 0 */ "mmmmabbba"
+ /* 1 */ "ccccbbbbb"
+ /* 2 */ "ccccbbbbb"
+ /* 3 */ "ccccbbbbb"
+ /* 4 */ "abbbabbbb"
+ /* 5 */ "bbbbbbbbb"
+ /* 6 */ "bbbbbbbbb"
+ /* 7 */ "bbbbbbbbb"
+ /* 8 */ "abbbbbbba"
+
+ // Level 1
+ /* z\x* 012345678 */
+ /* 0 */ "mmmmabbba"
+ /* 1 */ "ddddbeeeb"
+ /* 2 */ "ddddeeeeb"
+ /* 3 */ "ddddbeeeb"
+ /* 4 */ "abbbaeeeb"
+ /* 5 */ "beeeeeeeb"
+ /* 6 */ "beeeeeeeb"
+ /* 7 */ "beeeeeeeb"
+ /* 8 */ "abbbbbbba"
+
+ // Level 2
+ /* z\x* 012345678 */
+ /* 0 */ "mmmmabbba"
+ /* 1 */ "....b...b"
+ /* 2 */ "....f...b"
+ /* 3 */ "....b...b"
+ /* 4 */ "abbba...b"
+ /* 5 */ "b.......b"
+ /* 6 */ "b.......b"
+ /* 7 */ "b......gb"
+ /* 8 */ "abbbbbbba"
+
+ // Level 3
+ /* z\x* 012345678 */
+ /* 0 */ "mmmmabhba"
+ /* 1 */ "....b...b"
+ /* 2 */ "....i...b"
+ /* 3 */ "....b...h"
+ /* 4 */ "abhbaj..h"
+ /* 5 */ "b.......h"
+ /* 6 */ "h.......b"
+ /* 7 */ "b......gb"
+ /* 8 */ "abbhhhbba"
+
+ // Level 4
+ /* z\x* 012345678 */
+ /* 0 */ "mmmmabkba"
+ /* 1 */ "....blllb"
+ /* 2 */ "....blllb"
+ /* 3 */ "....bllln"
+ /* 4 */ "abkballln"
+ /* 5 */ "bllllllln"
+ /* 6 */ "olllllllb"
+ /* 7 */ "bllllllgb"
+ /* 8 */ "abbpppbba"
+
+ // Level 5
+ /* z\x* 012345678 */
+ /* 0 */ "mmmmbqbqb"
+ /* 1 */ "....q...q"
+ /* 2 */ "....q...q"
+ /* 3 */ "....q...q"
+ /* 4 */ "bqqqb...b"
+ /* 5 */ "q.......q"
+ /* 6 */ "b.......q"
+ /* 7 */ "q......rq"
+ /* 8 */ "bqqqbqqqb",
+
+ // Connectors:
+ "-1: 0, 2, 2: 4\n" /* Type -1, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // LittleHouse8
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LittleTower:
+ // The data has been exported from the gallery Desert, area index 79, ID 595, created by STR_Warrior
+ {
+ // Size:
+ 5, 9, 7, // SizeX = 5, SizeY = 9, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 5, 8, 7, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 24: 2\n" /* sandstone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 24: 0\n" /* sandstone */
+ "d: 13: 0\n" /* gravel */
+ "e: 5: 0\n" /* wood */
+ "f: 64: 3\n" /* wooddoorblock */
+ "g: 65: 5\n" /* ladder */
+ "h: 64: 8\n" /* wooddoorblock */
+ "i:101: 0\n" /* ironbars */
+ "j: 50: 4\n" /* torch */
+ "k:128: 2\n" /* sandstonestairs */
+ "l:126: 8\n" /* woodenslab */
+ "m: 19: 0\n" /* sponge */
+ "n:128: 4\n" /* sandstonestairs */
+ "o:128: 5\n" /* sandstonestairs */
+ "p:128: 7\n" /* sandstonestairs */
+ "q:128: 6\n" /* sandstonestairs */
+ "r: 44: 1\n" /* step */
+ "s: 96: 1\n" /* trapdoor */,
// Block data:
// Level 0
/* z\x* 01234 */
- /* 0 */ "aaaaa"
- /* 1 */ "aaaaa"
- /* 2 */ "aabaa"
- /* 3 */ "abbba"
- /* 4 */ "abbba"
- /* 5 */ "abbba"
- /* 6 */ "aaaaa"
+ /* 0 */ "abbba"
+ /* 1 */ "mbbbm"
+ /* 2 */ "accca"
+ /* 3 */ "ccccc"
+ /* 4 */ "ccccc"
+ /* 5 */ "ccccc"
+ /* 6 */ "accca"
// Level 1
/* z\x* 01234 */
- /* 0 */ "c...c"
- /* 1 */ "....."
- /* 2 */ "cdedc"
- /* 3 */ "df..d"
- /* 4 */ "d...d"
- /* 5 */ "d...d"
- /* 6 */ "cdddc"
+ /* 0 */ "addda"
+ /* 1 */ "mdddm"
+ /* 2 */ "aceca"
+ /* 3 */ "ceeec"
+ /* 4 */ "ceeec"
+ /* 5 */ "ceeec"
+ /* 6 */ "accca"
// Level 2
/* z\x* 01234 */
- /* 0 */ "c...c"
+ /* 0 */ "a...a"
/* 1 */ "....."
- /* 2 */ "cdgdc"
- /* 3 */ "df..d"
- /* 4 */ "h...h"
- /* 5 */ "d..id"
- /* 6 */ "cdhdc"
+ /* 2 */ "acfca"
+ /* 3 */ "cg..c"
+ /* 4 */ "c...c"
+ /* 5 */ "c...c"
+ /* 6 */ "accca"
// Level 3
/* z\x* 01234 */
- /* 0 */ "j...j"
- /* 1 */ "d...d"
- /* 2 */ "cdddc"
- /* 3 */ "dfkkd"
- /* 4 */ "lkkkn"
- /* 5 */ "dkkkd"
- /* 6 */ "cdodc"
+ /* 0 */ "a...a"
+ /* 1 */ "....."
+ /* 2 */ "achca"
+ /* 3 */ "cg..c"
+ /* 4 */ "i...i"
+ /* 5 */ "c..jc"
+ /* 6 */ "acica"
// Level 4
/* z\x* 01234 */
- /* 0 */ "....."
- /* 1 */ "....."
- /* 2 */ "cdddc"
- /* 3 */ "df..d"
- /* 4 */ "d...d"
- /* 5 */ "d...d"
- /* 6 */ "cdddc"
+ /* 0 */ "k...k"
+ /* 1 */ "c...c"
+ /* 2 */ "accca"
+ /* 3 */ "cgllc"
+ /* 4 */ "nlllo"
+ /* 5 */ "clllc"
+ /* 6 */ "acpca"
// Level 5
/* z\x* 01234 */
/* 0 */ "....."
/* 1 */ "....."
- /* 2 */ "cdhdc"
- /* 3 */ "df..d"
- /* 4 */ "h...h"
- /* 5 */ "d..id"
- /* 6 */ "cdhdc"
+ /* 2 */ "accca"
+ /* 3 */ "cg..c"
+ /* 4 */ "c...c"
+ /* 5 */ "c...c"
+ /* 6 */ "accca"
// Level 6
/* z\x* 01234 */
/* 0 */ "....."
/* 1 */ "....."
- /* 2 */ "cdpdc"
- /* 3 */ "dfkkd"
- /* 4 */ "lkkkn"
- /* 5 */ "dkkkd"
- /* 6 */ "cdodc"
+ /* 2 */ "acica"
+ /* 3 */ "cg..c"
+ /* 4 */ "i...i"
+ /* 5 */ "c..jc"
+ /* 6 */ "acica"
// Level 7
/* z\x* 01234 */
/* 0 */ "....."
/* 1 */ "....."
- /* 2 */ "dqdqd"
- /* 3 */ "qr..q"
- /* 4 */ "d...d"
- /* 5 */ "q...q"
- /* 6 */ "dqdqd",
+ /* 2 */ "acqca"
+ /* 3 */ "cgllc"
+ /* 4 */ "nlllo"
+ /* 5 */ "clllc"
+ /* 6 */ "acpca"
+
+ // Level 8
+ /* z\x* 01234 */
+ /* 0 */ "....."
+ /* 1 */ "....."
+ /* 2 */ "crcrc"
+ /* 3 */ "rs..r"
+ /* 4 */ "c...c"
+ /* 5 */ "r...r"
+ /* 6 */ "crcrc",
// Connectors:
- "-1: 2, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 2, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -2053,141 +2356,156 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 71, ID 561, created by STR_Warrior
{
// Size:
- 15, 8, 9, // SizeX = 15, SizeY = 8, SizeZ = 9
+ 15, 9, 9, // SizeX = 15, SizeY = 9, SizeZ = 9
// Hitbox (relative to bounding box):
-1, 0, 0, // MinX, MinY, MinZ
- 15, 7, 9, // MaxX, MaxY, MaxZ
+ 15, 8, 9, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
- "c: 24: 2\n" /* sandstone */
- "d: 24: 0\n" /* sandstone */
- "e: 64: 3\n" /* wooddoorblock */
- "f: 85: 0\n" /* fence */
- "g: 64: 0\n" /* wooddoorblock */
- "h: 65: 5\n" /* ladder */
- "i: 64: 8\n" /* wooddoorblock */
- "j:101: 0\n" /* ironbars */
- "k: 50: 4\n" /* torch */
- "l:128: 2\n" /* sandstonestairs */
+ "a: 24: 2\n" /* sandstone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 24: 0\n" /* sandstone */
+ "d: 12: 0\n" /* sand */
+ "e: 13: 0\n" /* gravel */
+ "f: 5: 0\n" /* wood */
+ "g: 64: 3\n" /* wooddoorblock */
+ "h: 85: 0\n" /* fence */
+ "i: 64: 0\n" /* wooddoorblock */
+ "j: 65: 5\n" /* ladder */
+ "k: 64: 8\n" /* wooddoorblock */
+ "l:101: 0\n" /* ironbars */
"m: 19: 0\n" /* sponge */
- "n:126: 8\n" /* woodenslab */
- "o:128: 4\n" /* sandstonestairs */
- "p:128: 7\n" /* sandstonestairs */
- "q: 44: 1\n" /* step */
- "r: 50: 3\n" /* torch */
- "s:128: 6\n" /* sandstonestairs */,
+ "n: 50: 4\n" /* torch */
+ "o:128: 2\n" /* sandstonestairs */
+ "p:126: 8\n" /* woodenslab */
+ "q:128: 4\n" /* sandstonestairs */
+ "r:128: 7\n" /* sandstonestairs */
+ "s: 44: 1\n" /* step */
+ "t: 50: 3\n" /* torch */
+ "u:128: 6\n" /* sandstonestairs */,
// Block data:
// Level 0
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "aaaaaaaaaaaaaaa"
- /* 1 */ "aaaaaaaaaaaaaaa"
- /* 2 */ "aaaaabaaaaaaaaa"
- /* 3 */ "abbbbbbbbbaaaaa"
- /* 4 */ "abbbbbbbbbaaaaa"
- /* 5 */ "abbbbbbbbbbaaaa"
- /* 6 */ "abbbbbbbbbaaaaa"
- /* 7 */ "abbbbbbbbbaaaaa"
- /* 8 */ "aaaaaaaaaaaaaaa"
+ /* 0 */ "mmmabbbammmmmmm"
+ /* 1 */ "mmmmbbbmmmmmmmm"
+ /* 2 */ "acccccccccadddd"
+ /* 3 */ "cccccccccccdddd"
+ /* 4 */ "cccccccccccdddd"
+ /* 5 */ "cccccccccccdddd"
+ /* 6 */ "cccccccccccdddd"
+ /* 7 */ "cccccccccccdddd"
+ /* 8 */ "acccccccccadddd"
// Level 1
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "...c...c......."
- /* 1 */ "..............."
- /* 2 */ "cddddeddddcffff"
- /* 3 */ "d.........d...f"
- /* 4 */ "d.........d...f"
- /* 5 */ "d.........g...f"
- /* 6 */ "d.........d...f"
- /* 7 */ "d.........dh..f"
- /* 8 */ "cdddddddddcffff"
+ /* 0 */ "mmmaeeeammmmmmm"
+ /* 1 */ "mmmmeeemmmmmmmm"
+ /* 2 */ "accccfccccadddd"
+ /* 3 */ "cfffffffffcdddd"
+ /* 4 */ "cfffffffffcdddd"
+ /* 5 */ "cffffffffffdddd"
+ /* 6 */ "cfffffffffcdddd"
+ /* 7 */ "cfffffffffcdddd"
+ /* 8 */ "acccccccccadddd"
// Level 2
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "...c...c......."
- /* 1 */ "..............."
- /* 2 */ "cddddiddddc...."
- /* 3 */ "d.........d...."
- /* 4 */ "j.........d...."
- /* 5 */ "j.........i...."
- /* 6 */ "j.........d...."
- /* 7 */ "d..k...k..dh..."
- /* 8 */ "cdddjjjdddc...."
+ /* 0 */ "mmma...ammmmmmm"
+ /* 1 */ "mmm.....mmmmmmm"
+ /* 2 */ "accccgccccahhhh"
+ /* 3 */ "c.........c...h"
+ /* 4 */ "c.........c...h"
+ /* 5 */ "c.........i...h"
+ /* 6 */ "c.........c...h"
+ /* 7 */ "c.........cj..h"
+ /* 8 */ "acccccccccahhhh"
// Level 3
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "...l...l......."
- /* 1 */ "...d...d......."
- /* 2 */ "cdddddddddc...."
- /* 3 */ "dnnnnnnnnnd...."
- /* 4 */ "onnnnnnnnnd...."
- /* 5 */ "onnnnnnnnnd...."
- /* 6 */ "onnnnnnnnnd...."
- /* 7 */ "dnnnnnnnnndh..."
- /* 8 */ "cdddpppdddc...."
+ /* 0 */ "mmma...ammmmmmm"
+ /* 1 */ "mmm.....mmmmmmm"
+ /* 2 */ "acccckcccca...."
+ /* 3 */ "c.........c...."
+ /* 4 */ "l.........c...."
+ /* 5 */ "l.........k...."
+ /* 6 */ "l.........c...."
+ /* 7 */ "c..n...n..cj..."
+ /* 8 */ "accclllccca...."
// Level 4
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "..............."
- /* 1 */ "..............."
- /* 2 */ "dqqqqdqqqqd...."
- /* 3 */ "q..cdddc..q...."
- /* 4 */ "q..d...d..q...."
- /* 5 */ "d.........d...."
- /* 6 */ "q..d...d..q...."
- /* 7 */ "q..cdddc..q...."
- /* 8 */ "dqqqqdqqqqd...."
+ /* 0 */ "mmmo...ommmmmmm"
+ /* 1 */ "mmmc...cmmmmmmm"
+ /* 2 */ "accccccccca...."
+ /* 3 */ "cpppppppppc...."
+ /* 4 */ "qpppppppppc...."
+ /* 5 */ "qpppppppppc...."
+ /* 6 */ "qpppppppppc...."
+ /* 7 */ "cpppppppppcj..."
+ /* 8 */ "acccrrrccca...."
// Level 5
/* z\x* 11111 */
/* * 012345678901234 */
+ /* 0 */ "mmm.....mmmmmmm"
+ /* 1 */ "mmm.....mmmmmmm"
+ /* 2 */ "csssscssssc...."
+ /* 3 */ "s..accca..s...."
+ /* 4 */ "s..c...c..s...."
+ /* 5 */ "c.........c...."
+ /* 6 */ "s..c...c..s...."
+ /* 7 */ "s..accca..s...."
+ /* 8 */ "csssscssssc...."
+
+ // Level 6
+ /* z\x* 11111 */
+ /* * 012345678901234 */
/* 0 */ "..............."
/* 1 */ "..............."
/* 2 */ "..............."
- /* 3 */ "...cdjdc......."
- /* 4 */ "...dr..d......."
+ /* 3 */ "...aclca......."
+ /* 4 */ "...ct..c......."
/* 5 */ "..............."
- /* 6 */ "...d...d......."
- /* 7 */ "...cdjdc......."
+ /* 6 */ "...c...c......."
+ /* 7 */ "...aclca......."
/* 8 */ "..............."
- // Level 6
+ // Level 7
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
/* 1 */ "..............."
/* 2 */ "..............."
- /* 3 */ "...cdsdc......."
- /* 4 */ "...dnnnd......."
- /* 5 */ "...dnnnd......."
- /* 6 */ "...dnnnd......."
- /* 7 */ "...cdpdc......."
+ /* 3 */ "...acuca......."
+ /* 4 */ "...cpppc......."
+ /* 5 */ "...cpppc......."
+ /* 6 */ "...cpppc......."
+ /* 7 */ "...acrca......."
/* 8 */ "..............."
- // Level 7
+ // Level 8
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
/* 1 */ "..............."
/* 2 */ "..............."
- /* 3 */ "...dqdqd......."
- /* 4 */ "...q...q......."
- /* 5 */ "...d...d......."
- /* 6 */ "...q...q......."
- /* 7 */ "...dqdqd......."
+ /* 3 */ "...cscsc......."
+ /* 4 */ "...s...s......."
+ /* 5 */ "...c...c......."
+ /* 6 */ "...s...s......."
+ /* 7 */ "...cscsc......."
/* 8 */ "...............",
// Connectors:
- "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 5, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -2218,130 +2536,145 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 74, ID 573, created by STR_Warrior
{
// Size:
- 11, 9, 9, // SizeX = 11, SizeY = 9, SizeZ = 9
+ 11, 10, 9, // SizeX = 11, SizeY = 10, SizeZ = 9
// Hitbox (relative to bounding box):
-1, 0, 0, // MinX, MinY, MinZ
- 11, 8, 9, // MaxX, MaxY, MaxZ
+ 11, 9, 9, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "A: 96: 3\n" /* trapdoor */
- "B: 96: 6\n" /* trapdoor */
- "C:128: 2\n" /* sandstonestairs */
- "D:128: 0\n" /* sandstonestairs */
- "E: 87: 0\n" /* netherstone */
- "F:128: 1\n" /* sandstonestairs */
- "G:128: 3\n" /* sandstonestairs */
- "H: 51: 0\n" /* fire */
- "I: 44: 9\n" /* step */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
- "c: 24: 2\n" /* sandstone */
- "d: 24: 0\n" /* sandstone */
- "e: 65: 3\n" /* ladder */
- "f: 85: 0\n" /* fence */
- "g: 64: 7\n" /* wooddoorblock */
- "h:134: 1\n" /* 134 */
- "i:134: 2\n" /* 134 */
- "j: 61: 2\n" /* furnace */
- "k:134: 6\n" /* 134 */
- "l:134: 4\n" /* 134 */
+ "A:128: 7\n" /* sandstonestairs */
+ "B: 44: 1\n" /* step */
+ "C: 96: 3\n" /* trapdoor */
+ "D: 96: 2\n" /* trapdoor */
+ "E:128: 2\n" /* sandstonestairs */
+ "F:128: 0\n" /* sandstonestairs */
+ "G: 87: 0\n" /* netherstone */
+ "H:128: 1\n" /* sandstonestairs */
+ "I:128: 3\n" /* sandstonestairs */
+ "J: 51: 0\n" /* fire */
+ "K: 44: 9\n" /* step */
+ "a: 24: 2\n" /* sandstone */
+ "b: 24: 0\n" /* sandstone */
+ "c: 4: 0\n" /* cobblestone */
+ "d: 12: 0\n" /* sand */
+ "e: 13: 0\n" /* gravel */
+ "f: 5: 0\n" /* wood */
+ "g: 65: 3\n" /* ladder */
+ "h: 85: 0\n" /* fence */
+ "i: 64: 3\n" /* wooddoorblock */
+ "j:134: 1\n" /* 134 */
+ "k:134: 2\n" /* 134 */
+ "l: 61: 2\n" /* furnace */
"m: 19: 0\n" /* sponge */
- "n: 65: 2\n" /* ladder */
- "o:101: 0\n" /* ironbars */
- "p: 50: 2\n" /* torch */
- "q: 47: 0\n" /* bookshelf */
- "r: 64:12\n" /* wooddoorblock */
- "s: 50: 3\n" /* torch */
- "t:171: 8\n" /* carpet */
- "u:128: 6\n" /* sandstonestairs */
- "v:126: 8\n" /* woodenslab */
- "w:128: 5\n" /* sandstonestairs */
- "x:128: 4\n" /* sandstonestairs */
- "y:128: 7\n" /* sandstonestairs */
- "z: 44: 1\n" /* step */,
+ "n:134: 6\n" /* 134 */
+ "o:134: 4\n" /* 134 */
+ "p: 65: 2\n" /* ladder */
+ "q:101: 0\n" /* ironbars */
+ "r: 50: 2\n" /* torch */
+ "s: 47: 0\n" /* bookshelf */
+ "t: 64: 8\n" /* wooddoorblock */
+ "u: 50: 3\n" /* torch */
+ "v:171: 8\n" /* carpet */
+ "w:128: 6\n" /* sandstonestairs */
+ "x:126: 8\n" /* woodenslab */
+ "y:128: 5\n" /* sandstonestairs */
+ "z:128: 4\n" /* sandstonestairs */,
// Block data:
// Level 0
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "aaaaaaaaaaa"
- /* 1 */ "abbbaaaaaaa"
- /* 2 */ "abbbaaaaaaa"
- /* 3 */ "abbbaaaaaaa"
- /* 4 */ "abbbaaaabaa"
- /* 5 */ "abbbbbbbbba"
- /* 6 */ "abbbbbbbbba"
- /* 7 */ "abbbbbbbbba"
- /* 8 */ "aaaaaaaaaaa"
+ /* 0 */ "abbbammmcmm"
+ /* 1 */ "bbbbbdddcdm"
+ /* 2 */ "bbbbbmmmcdm"
+ /* 3 */ "bbbbbmmmcdm"
+ /* 4 */ "bbbbabbbbba"
+ /* 5 */ "bbbbbbbbbbb"
+ /* 6 */ "bbbbbbbbbbb"
+ /* 7 */ "bbbbbbbbbbb"
+ /* 8 */ "abbbbbbbbba"
// Level 1
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "cdddc......"
- /* 1 */ "de..dfff.f."
- /* 2 */ "d...d....f."
- /* 3 */ "d...d....f."
- /* 4 */ "d...ddddgdc"
- /* 5 */ "d.........d"
- /* 6 */ "dhf.......d"
- /* 7 */ "dhi.jkl..nd"
- /* 8 */ "cdddddddddc"
+ /* 0 */ "abbbammmemm"
+ /* 1 */ "bfffbdddedm"
+ /* 2 */ "bfffbmmmedm"
+ /* 3 */ "bfffbmmmedm"
+ /* 4 */ "bfffabbbfba"
+ /* 5 */ "bfffffffffb"
+ /* 6 */ "bfffffffffb"
+ /* 7 */ "bfffffffffb"
+ /* 8 */ "abbbbbbbbba"
// Level 2
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "cdodc......"
- /* 1 */ "de..o......"
- /* 2 */ "d...o......"
- /* 3 */ "o..pd......"
- /* 4 */ "o...qdodrdc"
- /* 5 */ "o......s..d"
- /* 6 */ "d.t.......o"
- /* 7 */ "d........nd"
- /* 8 */ "cdddooodddc"
+ /* 0 */ "abbba......"
+ /* 1 */ "bg..bhhh.h."
+ /* 2 */ "b...b....h."
+ /* 3 */ "b...b....h."
+ /* 4 */ "b...abbbiba"
+ /* 5 */ "b.........b"
+ /* 6 */ "bjh.......b"
+ /* 7 */ "bjk.lno..pb"
+ /* 8 */ "abbbbbbbbba"
// Level 3
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "cdudc......"
- /* 1 */ "devvw......"
- /* 2 */ "dvvvw......"
- /* 3 */ "xvvvd......"
- /* 4 */ "xvvvddudddc"
- /* 5 */ "xvvvvvvvvvd"
- /* 6 */ "dvvvvvvvvvw"
- /* 7 */ "dvvvqqqvvnd"
- /* 8 */ "cdddyyydddc"
+ /* 0 */ "abqba......"
+ /* 1 */ "bg..q......"
+ /* 2 */ "b...q......"
+ /* 3 */ "q..rb......"
+ /* 4 */ "q...sbqbtba"
+ /* 5 */ "q......u..b"
+ /* 6 */ "b.v.......q"
+ /* 7 */ "b........pb"
+ /* 8 */ "abbbqqqbbba"
// Level 4
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "dzzzd......"
- /* 1 */ "zA..z......"
- /* 2 */ "z...z......"
- /* 3 */ "z...z......"
- /* 4 */ "d...dzzzzzd"
- /* 5 */ "zddd......z"
- /* 6 */ "zddd......z"
- /* 7 */ "zddd.....Bz"
- /* 8 */ "dzzzzdzzzzd"
+ /* 0 */ "abwba......"
+ /* 1 */ "bgxxy......"
+ /* 2 */ "bxxxy......"
+ /* 3 */ "zxxxb......"
+ /* 4 */ "zxxxabwbbba"
+ /* 5 */ "zxxxxxxxxxb"
+ /* 6 */ "bxxxxxxxxxy"
+ /* 7 */ "bxxxsssxxpb"
+ /* 8 */ "abbbAAAbbba"
// Level 5
/* z\x* 1 */
/* * 01234567890 */
+ /* 0 */ "bBBBb......"
+ /* 1 */ "BC..B......"
+ /* 2 */ "B...B......"
+ /* 3 */ "B...B......"
+ /* 4 */ "b...bBBBBBb"
+ /* 5 */ "Bbbb......B"
+ /* 6 */ "Bbbb......B"
+ /* 7 */ "Bbbb.....DB"
+ /* 8 */ "bBBBBbBBBBb"
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
/* 0 */ "..........."
/* 1 */ "..........."
/* 2 */ "..........."
/* 3 */ "..........."
/* 4 */ "..........."
- /* 5 */ ".cCc......."
- /* 6 */ ".DEF......."
- /* 7 */ ".cGc......."
+ /* 5 */ ".aEa......."
+ /* 6 */ ".FGH......."
+ /* 7 */ ".aIa......."
/* 8 */ "..........."
- // Level 6
+ // Level 7
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
@@ -2349,12 +2682,12 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
/* 2 */ "..........."
/* 3 */ "..........."
/* 4 */ "..........."
- /* 5 */ ".c.c......."
- /* 6 */ "..H........"
- /* 7 */ ".c.c......."
+ /* 5 */ ".a.a......."
+ /* 6 */ "..J........"
+ /* 7 */ ".a.a......."
/* 8 */ "..........."
- // Level 7
+ // Level 8
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
@@ -2362,12 +2695,12 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
/* 2 */ "..........."
/* 3 */ "..........."
/* 4 */ "..........."
- /* 5 */ ".ddd......."
- /* 6 */ ".dId......."
- /* 7 */ ".ddd......."
+ /* 5 */ ".bbb......."
+ /* 6 */ ".bKb......."
+ /* 7 */ ".bbb......."
/* 8 */ "..........."
- // Level 8
+ // Level 9
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
@@ -2375,13 +2708,13 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
/* 2 */ "..........."
/* 3 */ "..........."
/* 4 */ "..........."
- /* 5 */ ".z.z......."
+ /* 5 */ ".B.B......."
/* 6 */ "..........."
- /* 7 */ ".z.z......."
+ /* 7 */ ".B.B......."
/* 8 */ "...........",
// Connectors:
- "-1: 8, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 8, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -2420,30 +2753,30 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// Block definitions:
".: 0: 0\n" /* air */
- "a: 12: 0\n" /* sand */
- "b: 3: 0\n" /* dirt */
- "c: 2: 0\n" /* grass */
- "d: 5: 0\n" /* wood */
- "e: 24: 0\n" /* sandstone */
- "f: 24: 2\n" /* sandstone */
- "g: 85: 0\n" /* fence */
- "h: 64: 3\n" /* wooddoorblock */
- "i: 64: 6\n" /* wooddoorblock */
- "j: 65: 4\n" /* ladder */
- "k: 65: 2\n" /* ladder */
- "l: 50: 1\n" /* torch */
+ "a: 24: 2\n" /* sandstone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 3: 0\n" /* dirt */
+ "d: 24: 0\n" /* sandstone */
+ "e: 13: 0\n" /* gravel */
+ "f: 2: 0\n" /* grass */
+ "g: 5: 0\n" /* wood */
+ "h: 85: 0\n" /* fence */
+ "i: 64: 3\n" /* wooddoorblock */
+ "j: 64: 2\n" /* wooddoorblock */
+ "k: 65: 4\n" /* ladder */
+ "l: 65: 2\n" /* ladder */
"m: 19: 0\n" /* sponge */
- "n: 50: 2\n" /* torch */
- "o:101: 0\n" /* ironbars */
- "p: 64: 8\n" /* wooddoorblock */
- "q: 64:12\n" /* wooddoorblock */
+ "n: 50: 1\n" /* torch */
+ "o: 50: 2\n" /* torch */
+ "p:101: 0\n" /* ironbars */
+ "q: 64: 8\n" /* wooddoorblock */
"r:128: 2\n" /* sandstonestairs */
"s:128: 6\n" /* sandstonestairs */
"t:126: 8\n" /* woodenslab */
"u:128: 5\n" /* sandstonestairs */
"v:128: 7\n" /* sandstonestairs */
"w: 44: 1\n" /* step */
- "x: 96: 4\n" /* trapdoor */
+ "x: 96: 0\n" /* trapdoor */
"y:126: 0\n" /* woodenslab */
"z:128: 4\n" /* sandstonestairs */,
@@ -2451,92 +2784,92 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// Level 0
/* z\x* 11 */
/* * 012345678901 */
- /* 0 */ "aaaaaaaaaaaa"
- /* 1 */ "aaaaaaaaaaaa"
- /* 2 */ "bbbbbaaaaaaa"
- /* 3 */ "bbbbbaaaaaaa"
- /* 4 */ "bbbbbaaaaaaa"
- /* 5 */ "bbbbbaaaaaaa"
- /* 6 */ "bbbaaaaaaaaa"
- /* 7 */ "aaaaaaaaaaaa"
- /* 8 */ "aaaaaaaaaaaa"
- /* 9 */ "aaaaaaaaaaaa"
- /* 10 */ "aaaaaaaaaaaa"
+ /* 0 */ "mmmmmammbbba"
+ /* 1 */ "mmmmmmmmbbbm"
+ /* 2 */ "cccccaddddda"
+ /* 3 */ "cccccddddddd"
+ /* 4 */ "cccccddddddd"
+ /* 5 */ "cccccddddddd"
+ /* 6 */ "cccddddddddd"
+ /* 7 */ "mmmddddddddd"
+ /* 8 */ "mmmdddddddda"
+ /* 9 */ "mmmdddddmmmm"
+ /* 10 */ "mmmadddammmm"
// Level 1
/* z\x* 11 */
/* * 012345678901 */
- /* 0 */ "aaaaaaaaaaaa"
- /* 1 */ "aaaaaaaaaaaa"
- /* 2 */ "cccccaaaadaa"
- /* 3 */ "cccccaddddda"
- /* 4 */ "cccccdddddda"
- /* 5 */ "cccccaddddda"
- /* 6 */ "cccaadddddda"
- /* 7 */ "aaaaddddddda"
- /* 8 */ "aaaadddaaaaa"
- /* 9 */ "aaaadddaaaaa"
- /* 10 */ "aaaaaaaaaaaa"
+ /* 0 */ "mmmmmammeeea"
+ /* 1 */ "mmmmmmmmeeem"
+ /* 2 */ "fffffadddgda"
+ /* 3 */ "fffffdgggggd"
+ /* 4 */ "fffffggggggd"
+ /* 5 */ "fffffdgggggd"
+ /* 6 */ "fffddggggggd"
+ /* 7 */ "mmmdgggggggd"
+ /* 8 */ "mmmdggggddda"
+ /* 9 */ "mmmdgggdmmmm"
+ /* 10 */ "mmmadddammmm"
// Level 2
/* z\x* 11 */
/* * 012345678901 */
- /* 0 */ ".....e.....f"
- /* 1 */ "............"
- /* 2 */ "gggggfeeehef"
- /* 3 */ "g....e.....e"
- /* 4 */ "g....i.....e"
- /* 5 */ "g....e.....e"
- /* 6 */ "gggfe......e"
- /* 7 */ "mmme......je"
- /* 8 */ "mmme...eeeef"
- /* 9 */ "mmme..kemmmm"
- /* 10 */ "mmmfeeefmmmm"
+ /* 0 */ "mmmmma.....a"
+ /* 1 */ "mmmmm......."
+ /* 2 */ "hhhhhadddida"
+ /* 3 */ "h....d.....d"
+ /* 4 */ "h....j.....d"
+ /* 5 */ "h....d.....d"
+ /* 6 */ "hhhad......d"
+ /* 7 */ "mmmd......kd"
+ /* 8 */ "mmmd....ddda"
+ /* 9 */ "mmmd..ldmmmm"
+ /* 10 */ "mmmadddammmm"
// Level 3
/* z\x* 11 */
/* * 012345678901 */
- /* 0 */ ".....el...nf"
- /* 1 */ "............"
- /* 2 */ ".....fooepef"
- /* 3 */ ".....e.....e"
- /* 4 */ ".....q.....e"
- /* 5 */ ".....e.....o"
- /* 6 */ "...ge......e"
- /* 7 */ "mmme......je"
- /* 8 */ "mmme...eeoof"
- /* 9 */ "mmme..kemmmm"
- /* 10 */ "mmmgeeegmmmm"
+ /* 0 */ "mmmmman...oa"
+ /* 1 */ "mmmmm......."
+ /* 2 */ ".....appdqda"
+ /* 3 */ ".....d.....d"
+ /* 4 */ ".....q.....d"
+ /* 5 */ ".....d.....p"
+ /* 6 */ "...hd......d"
+ /* 7 */ "mmmd......kd"
+ /* 8 */ "mmmd....dppa"
+ /* 9 */ "mmmd..ldmmmm"
+ /* 10 */ "mmmhdddhmmmm"
// Level 4
/* z\x* 11 */
/* * 012345678901 */
- /* 0 */ ".....r.....r"
- /* 1 */ ".....e.....e"
- /* 2 */ ".....fsseeef"
- /* 3 */ ".....ettttte"
- /* 4 */ ".....ettttte"
- /* 5 */ ".....etttttu"
- /* 6 */ "...getttttte"
- /* 7 */ "mmmettttttje"
- /* 8 */ "mmmettteevvf"
- /* 9 */ "mmmettkemmmm"
- /* 10 */ "mmmgeeegmmmm"
+ /* 0 */ "mmmmmr.....r"
+ /* 1 */ "mmmmmd.....d"
+ /* 2 */ ".....assddda"
+ /* 3 */ ".....dtttttd"
+ /* 4 */ ".....dtttttd"
+ /* 5 */ ".....dtttttu"
+ /* 6 */ "...hdatttttd"
+ /* 7 */ "mmmdttttttkd"
+ /* 8 */ "mmmdtttadvva"
+ /* 9 */ "mmmdttldmmmm"
+ /* 10 */ "mmmhdddhmmmm"
// Level 5
/* z\x* 11 */
/* * 012345678901 */
/* 0 */ "............"
/* 1 */ "............"
- /* 2 */ ".....ewwewwe"
+ /* 2 */ ".....dwwdwwd"
/* 3 */ ".....w.....w"
/* 4 */ ".....w.....w"
- /* 5 */ ".....w.....e"
- /* 6 */ "...geeeg...w"
- /* 7 */ "mmme...e..xw"
- /* 8 */ "mmme...ewwwe"
- /* 9 */ "mmme..kemmmm"
- /* 10 */ "mmmgeeegmmmm"
+ /* 5 */ ".....w.....d"
+ /* 6 */ "...hdadh...w"
+ /* 7 */ "mmmd...d..xw"
+ /* 8 */ "mmmd...awwwd"
+ /* 9 */ "mmmd..ldmmmm"
+ /* 10 */ "mmmhdddhmmmm"
// Level 6
/* z\x* 11 */
@@ -2547,11 +2880,11 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
/* 3 */ "............"
/* 4 */ "............"
/* 5 */ "............"
- /* 6 */ "...ge.eg...."
- /* 7 */ "mmme...e...."
- /* 8 */ "mmmo........"
- /* 9 */ "mmme..kemmmm"
- /* 10 */ "mmmgeoegmmmm"
+ /* 6 */ "...hd.dh...."
+ /* 7 */ "mmmd...d...."
+ /* 8 */ "mmmp........"
+ /* 9 */ "mmmd..ldmmmm"
+ /* 10 */ "mmmhdpdhmmmm"
// Level 7
/* z\x* 11 */
@@ -2562,11 +2895,11 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
/* 3 */ "............"
/* 4 */ "............"
/* 5 */ "............"
- /* 6 */ "...ge.eg...."
- /* 7 */ "mmme...e...."
- /* 8 */ "mmmo........"
- /* 9 */ "mmmel.kemmmm"
- /* 10 */ "mmmgeoegmmmm"
+ /* 6 */ "...hd.dh...."
+ /* 7 */ "mmmd...d...."
+ /* 8 */ "mmmp........"
+ /* 9 */ "mmmdn.ldmmmm"
+ /* 10 */ "mmmhdpdhmmmm"
// Level 8
/* z\x* 11 */
@@ -2577,11 +2910,11 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
/* 3 */ "............"
/* 4 */ "............"
/* 5 */ "............"
- /* 6 */ "...fesef...."
- /* 7 */ "mmmeyyye...."
+ /* 6 */ "...adsda...."
+ /* 7 */ "mmmdyyyd...."
/* 8 */ "mmmzyyyu...."
- /* 9 */ "mmmeyykemmmm"
- /* 10 */ "mmmfevefmmmm"
+ /* 9 */ "mmmdyyldmmmm"
+ /* 10 */ "mmmadvdammmm"
// Level 9
/* z\x* 11 */
@@ -2630,107 +2963,122 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 67, ID 556, created by STR_Warrior
{
// Size:
- 9, 5, 11, // SizeX = 9, SizeY = 5, SizeZ = 11
+ 9, 6, 11, // SizeX = 9, SizeY = 6, SizeZ = 11
// Hitbox (relative to bounding box):
-1, 0, 0, // MinX, MinY, MinZ
- 9, 4, 11, // MaxX, MaxY, MaxZ
+ 9, 5, 11, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
- "c: 24: 2\n" /* sandstone */
- "d: 24: 0\n" /* sandstone */
- "e: 64: 7\n" /* wooddoorblock */
- "f: 65: 2\n" /* ladder */
- "g: 64:12\n" /* wooddoorblock */
- "h:101: 0\n" /* ironbars */
- "i: 50: 2\n" /* torch */
- "j: 50: 1\n" /* torch */
- "k:128: 2\n" /* sandstonestairs */
- "l:126: 8\n" /* woodenslab */
+ "a: 24: 2\n" /* sandstone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 24: 0\n" /* sandstone */
+ "d: 13: 0\n" /* gravel */
+ "e: 5: 0\n" /* wood */
+ "f: 64: 3\n" /* wooddoorblock */
+ "g: 65: 2\n" /* ladder */
+ "h: 64: 8\n" /* wooddoorblock */
+ "i:101: 0\n" /* ironbars */
+ "j: 50: 2\n" /* torch */
+ "k: 50: 1\n" /* torch */
+ "l:128: 2\n" /* sandstonestairs */
"m: 19: 0\n" /* sponge */
- "n:128: 5\n" /* sandstonestairs */
- "o:128: 6\n" /* sandstonestairs */
- "p:128: 4\n" /* sandstonestairs */
- "q:128: 7\n" /* sandstonestairs */
- "r: 44: 1\n" /* step */
- "s: 96: 6\n" /* trapdoor */,
+ "n:126: 8\n" /* woodenslab */
+ "o:128: 5\n" /* sandstonestairs */
+ "p:128: 6\n" /* sandstonestairs */
+ "q:128: 4\n" /* sandstonestairs */
+ "r:128: 7\n" /* sandstonestairs */
+ "s: 44: 1\n" /* step */
+ "t: 96: 2\n" /* trapdoor */,
// Block data:
// Level 0
/* z\x* 012345678 */
- /* 0 */ "aaaaaaaaa"
- /* 1 */ "aaaaaaaaa"
- /* 2 */ "aaaaaabaa"
- /* 3 */ "aaaaabbba"
- /* 4 */ "aaaaabbba"
- /* 5 */ "aaaaabbba"
- /* 6 */ "aaaaabbba"
- /* 7 */ "abbbbbbba"
- /* 8 */ "abbbbbbba"
- /* 9 */ "abbbbbbba"
- /* 10 */ "aaaaaaaaa"
+ /* 0 */ "mmmmabbba"
+ /* 1 */ "mmmmmbbbm"
+ /* 2 */ "mmmmaccca"
+ /* 3 */ "mmmmccccc"
+ /* 4 */ "mmmmccccc"
+ /* 5 */ "mmmmccccc"
+ /* 6 */ "acccacccc"
+ /* 7 */ "ccccccccc"
+ /* 8 */ "ccccccccc"
+ /* 9 */ "ccccccccc"
+ /* 10 */ "accccccca"
// Level 1
/* z\x* 012345678 */
- /* 0 */ "mmmmc...c"
- /* 1 */ "mmmm....."
- /* 2 */ "mmmmcdedc"
- /* 3 */ "mmmmd...d"
- /* 4 */ "mmmmd...d"
- /* 5 */ "mmmmd...d"
- /* 6 */ "cdddd...d"
- /* 7 */ "d.......d"
- /* 8 */ "d.......d"
- /* 9 */ "d......fd"
- /* 10 */ "cdddddddc"
+ /* 0 */ "mmmmaddda"
+ /* 1 */ "mmmmmdddm"
+ /* 2 */ "mmmmaceca"
+ /* 3 */ "mmmmceeec"
+ /* 4 */ "mmmmceeec"
+ /* 5 */ "mmmmceeec"
+ /* 6 */ "acccaeeec"
+ /* 7 */ "ceeeeeeec"
+ /* 8 */ "ceeeeeeec"
+ /* 9 */ "ceeeeeeec"
+ /* 10 */ "accccccca"
// Level 2
/* z\x* 012345678 */
- /* 0 */ "mmmmc...c"
+ /* 0 */ "mmmma...a"
/* 1 */ "mmmm....."
- /* 2 */ "mmmmcdgdc"
- /* 3 */ "mmmmd...d"
- /* 4 */ "mmmmd...d"
- /* 5 */ "mmmmd...h"
- /* 6 */ "cdhdd...h"
- /* 7 */ "d.......h"
- /* 8 */ "h......id"
- /* 9 */ "dj.....fd"
- /* 10 */ "cddhhhddc"
+ /* 2 */ "mmmmacfca"
+ /* 3 */ "mmmmc...c"
+ /* 4 */ "mmmmc...c"
+ /* 5 */ "mmmmc...c"
+ /* 6 */ "accca...c"
+ /* 7 */ "c.......c"
+ /* 8 */ "c.......c"
+ /* 9 */ "c......gc"
+ /* 10 */ "accccccca"
// Level 3
/* z\x* 012345678 */
- /* 0 */ "mmmmk...k"
- /* 1 */ "mmmmd...d"
- /* 2 */ "mmmmcdddc"
- /* 3 */ "mmmmdllld"
- /* 4 */ "mmmmdllld"
- /* 5 */ "mmmmdllln"
- /* 6 */ "cdoddllln"
- /* 7 */ "dllllllln"
- /* 8 */ "pllllllld"
- /* 9 */ "dllllllfd"
- /* 10 */ "cddqqqddc"
+ /* 0 */ "mmmma...a"
+ /* 1 */ "mmmm....."
+ /* 2 */ "mmmmachca"
+ /* 3 */ "mmmmc...c"
+ /* 4 */ "mmmmc...c"
+ /* 5 */ "mmmmc...i"
+ /* 6 */ "acica...i"
+ /* 7 */ "c.......i"
+ /* 8 */ "i......jc"
+ /* 9 */ "ck.....gc"
+ /* 10 */ "acciiicca"
// Level 4
/* z\x* 012345678 */
+ /* 0 */ "mmmml...l"
+ /* 1 */ "mmmmc...c"
+ /* 2 */ "mmmmaccca"
+ /* 3 */ "mmmmcnnnc"
+ /* 4 */ "mmmmcnnnc"
+ /* 5 */ "mmmmcnnno"
+ /* 6 */ "acpcannno"
+ /* 7 */ "cnnnnnnno"
+ /* 8 */ "qnnnnnnnc"
+ /* 9 */ "cnnnnnngc"
+ /* 10 */ "accrrrcca"
+
+ // Level 5
+ /* z\x* 012345678 */
/* 0 */ "mmmm....."
/* 1 */ "mmmm....."
- /* 2 */ "mmmmdrdrd"
- /* 3 */ "mmmmr...r"
- /* 4 */ "mmmmr...r"
- /* 5 */ "mmmmr...r"
- /* 6 */ "drrrd...d"
- /* 7 */ "r.......r"
- /* 8 */ "r.......r"
- /* 9 */ "r......sr"
- /* 10 */ "drrrdrrrd",
+ /* 2 */ "mmmmcscsc"
+ /* 3 */ "mmmms...s"
+ /* 4 */ "mmmms...s"
+ /* 5 */ "mmmms...s"
+ /* 6 */ "csssc...c"
+ /* 7 */ "s.......s"
+ /* 8 */ "s.......s"
+ /* 9 */ "s......ts"
+ /* 10 */ "cssscsssc",
// Connectors:
- "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 6, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -2761,162 +3109,176 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 83, ID 599, created by STR_Warrior
{
// Size:
- 13, 9, 9, // SizeX = 13, SizeY = 9, SizeZ = 9
+ 13, 10, 9, // SizeX = 13, SizeY = 10, SizeZ = 9
// Hitbox (relative to bounding box):
-1, 0, 0, // MinX, MinY, MinZ
- 13, 8, 9, // MaxX, MaxY, MaxZ
+ 13, 9, 9, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "A: 44: 9\n" /* step */
- "a: 12: 0\n" /* sand */
- "b: 5: 0\n" /* wood */
- "c: 24: 2\n" /* sandstone */
- "d: 24: 0\n" /* sandstone */
- "e: 64: 7\n" /* wooddoorblock */
- "f: 17: 0\n" /* tree */
- "g:128: 5\n" /* sandstonestairs */
- "h:128: 4\n" /* sandstonestairs */
- "i:128: 7\n" /* sandstonestairs */
- "j:128: 6\n" /* sandstonestairs */
- "k:118: 3\n" /* cauldronblock */
- "l:155: 1\n" /* quartzblock */
+ "A: 51: 0\n" /* fire */
+ "B: 44: 9\n" /* step */
+ "a: 24: 2\n" /* sandstone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 24: 0\n" /* sandstone */
+ "d: 13: 0\n" /* gravel */
+ "e: 5: 0\n" /* wood */
+ "f: 64: 3\n" /* wooddoorblock */
+ "g: 17: 0\n" /* tree */
+ "h:128: 5\n" /* sandstonestairs */
+ "i:128: 4\n" /* sandstonestairs */
+ "j:128: 7\n" /* sandstonestairs */
+ "k:128: 6\n" /* sandstonestairs */
+ "l:118: 3\n" /* cauldronblock */
"m: 19: 0\n" /* sponge */
- "n: 64:12\n" /* wooddoorblock */
- "o: 50: 3\n" /* torch */
- "p:101: 0\n" /* ironbars */
- "q:140: 0\n" /* flowerpotblock */
- "r: 24: 1\n" /* sandstone */
- "s:128: 2\n" /* sandstonestairs */
- "t:126: 8\n" /* woodenslab */
- "u: 44: 1\n" /* step */
- "v:128: 0\n" /* sandstonestairs */
- "w: 87: 0\n" /* netherstone */
- "x:128: 1\n" /* sandstonestairs */
- "y:128: 3\n" /* sandstonestairs */
- "z: 51: 0\n" /* fire */,
+ "n:155: 1\n" /* quartzblock */
+ "o: 64: 8\n" /* wooddoorblock */
+ "p: 50: 3\n" /* torch */
+ "q:101: 0\n" /* ironbars */
+ "r:140: 0\n" /* flowerpotblock */
+ "s: 24: 1\n" /* sandstone */
+ "t:128: 2\n" /* sandstonestairs */
+ "u:126: 8\n" /* woodenslab */
+ "v: 44: 1\n" /* step */
+ "w:128: 0\n" /* sandstonestairs */
+ "x: 87: 0\n" /* netherstone */
+ "y:128: 1\n" /* sandstonestairs */
+ "z:128: 3\n" /* sandstonestairs */,
// Block data:
// Level 0
/* z\x* 111 */
/* * 0123456789012 */
- /* 0 */ "aaaaaaaaaaaaa"
- /* 1 */ "aaaaaaaaaaaaa"
- /* 2 */ "aaabbababbaaa"
- /* 3 */ "abbbbbbbbbbba"
- /* 4 */ "abbbbbbbbbbba"
- /* 5 */ "abbbbbbbbbbba"
- /* 6 */ "abbbbbbbbbbba"
- /* 7 */ "abbbbbbbbbbba"
- /* 8 */ "aaaaaaaaaaaaa"
+ /* 0 */ "mmmmabbbammmm"
+ /* 1 */ "mmmmmbbbmmmmm"
+ /* 2 */ "accccccccccca"
+ /* 3 */ "ccccccccccccc"
+ /* 4 */ "ccccccccccccc"
+ /* 5 */ "ccccccccccccc"
+ /* 6 */ "ccccccccccccc"
+ /* 7 */ "ccccccccccccc"
+ /* 8 */ "accccccccccca"
// Level 1
/* z\x* 111 */
/* * 0123456789012 */
- /* 0 */ "....c...c...."
- /* 1 */ "............."
- /* 2 */ "cdddddedddddc"
- /* 3 */ "dfg.......hfd"
- /* 4 */ "di.........id"
- /* 5 */ "d...........d"
- /* 6 */ "dj.........jd"
- /* 7 */ "dfg.khlgk.hfd"
- /* 8 */ "cdddddddddddc"
+ /* 0 */ "mmmmadddammmm"
+ /* 1 */ "mmmmmdddmmmmm"
+ /* 2 */ "accccceccccca"
+ /* 3 */ "ceeeeeeeeeeec"
+ /* 4 */ "ceeeeeeeeeeec"
+ /* 5 */ "ceeeeeeeeeeec"
+ /* 6 */ "ceeeeeeeeeeec"
+ /* 7 */ "ceeeeeeeeeeec"
+ /* 8 */ "accccccccccca"
// Level 2
/* z\x* 111 */
/* * 0123456789012 */
- /* 0 */ "....c...c...."
- /* 1 */ "............."
- /* 2 */ "cdddddndddddc"
- /* 3 */ "df...o.o...fd"
- /* 4 */ "d...........d"
- /* 5 */ "p...........p"
- /* 6 */ "d...........d"
- /* 7 */ "df...qrq...fd"
- /* 8 */ "cdpppdddpppdc"
+ /* 0 */ "mmmma...ammmm"
+ /* 1 */ "mmmm.....mmmm"
+ /* 2 */ "acccccfccccca"
+ /* 3 */ "cgh.......igc"
+ /* 4 */ "cj.........jc"
+ /* 5 */ "c...........c"
+ /* 6 */ "ck.........kc"
+ /* 7 */ "cgh.linhl.igc"
+ /* 8 */ "accccccccccca"
// Level 3
/* z\x* 111 */
/* * 0123456789012 */
- /* 0 */ "....s...s...."
- /* 1 */ "....r...d...."
- /* 2 */ "cdddddddddddc"
- /* 3 */ "dftttttttttfd"
- /* 4 */ "dtttttttttttd"
- /* 5 */ "htttttttttttg"
- /* 6 */ "dtttttttttttd"
- /* 7 */ "dftttttttttfd"
- /* 8 */ "cdiiidddiiidc"
+ /* 0 */ "mmmma...ammmm"
+ /* 1 */ "mmmm.....mmmm"
+ /* 2 */ "acccccoccccca"
+ /* 3 */ "cg...p.p...gc"
+ /* 4 */ "c...........c"
+ /* 5 */ "q...........q"
+ /* 6 */ "c...........c"
+ /* 7 */ "cg...rsr...gc"
+ /* 8 */ "acqqqcccqqqca"
// Level 4
/* z\x* 111 */
/* * 0123456789012 */
- /* 0 */ "............."
- /* 1 */ "............."
- /* 2 */ "duuuuuduuuuud"
- /* 3 */ "u...........u"
- /* 4 */ "u.ddd...ddd.u"
- /* 5 */ "d.ddd...ddd.d"
- /* 6 */ "u.ddd...ddd.u"
- /* 7 */ "u...........u"
- /* 8 */ "duuuuuduuuuud"
+ /* 0 */ "mmmmt...tmmmm"
+ /* 1 */ "mmmms...cmmmm"
+ /* 2 */ "accccccccccca"
+ /* 3 */ "cguuuuuuuuugc"
+ /* 4 */ "cuuuuuuuuuuuc"
+ /* 5 */ "iuuuuuuuuuuuh"
+ /* 6 */ "cuuuuuuuuuuuc"
+ /* 7 */ "cguuuuuuuuugc"
+ /* 8 */ "acjjjcccjjjca"
// Level 5
/* z\x* 111 */
/* * 0123456789012 */
+ /* 0 */ "mmmm.....mmmm"
+ /* 1 */ "mmmm.....mmmm"
+ /* 2 */ "cvvvvvcvvvvvc"
+ /* 3 */ "v...........v"
+ /* 4 */ "v.ccc...ccc.v"
+ /* 5 */ "c.ccc...ccc.c"
+ /* 6 */ "v.ccc...ccc.v"
+ /* 7 */ "v...........v"
+ /* 8 */ "cvvvvvcvvvvvc"
+
+ // Level 6
+ /* z\x* 111 */
+ /* * 0123456789012 */
/* 0 */ "............."
/* 1 */ "............."
/* 2 */ "............."
/* 3 */ "............."
- /* 4 */ "..csc...csc.."
- /* 5 */ "..vwx...vwx.."
- /* 6 */ "..cyc...cyc.."
+ /* 4 */ "..ata...ata.."
+ /* 5 */ "..wxy...wxy.."
+ /* 6 */ "..aza...aza.."
/* 7 */ "............."
/* 8 */ "............."
- // Level 6
+ // Level 7
/* z\x* 111 */
/* * 0123456789012 */
/* 0 */ "............."
/* 1 */ "............."
/* 2 */ "............."
/* 3 */ "............."
- /* 4 */ "..c.c...c.c.."
- /* 5 */ "...z.....z..."
- /* 6 */ "..c.c...c.c.."
+ /* 4 */ "..a.a...a.a.."
+ /* 5 */ "...A.....A..."
+ /* 6 */ "..a.a...a.a.."
/* 7 */ "............."
/* 8 */ "............."
- // Level 7
+ // Level 8
/* z\x* 111 */
/* * 0123456789012 */
/* 0 */ "............."
/* 1 */ "............."
/* 2 */ "............."
/* 3 */ "............."
- /* 4 */ "..ddd...ddd.."
- /* 5 */ "..dAd...dAd.."
- /* 6 */ "..ddd...ddd.."
+ /* 4 */ "..ccc...ccc.."
+ /* 5 */ "..cBc...cBc.."
+ /* 6 */ "..ccc...ccc.."
/* 7 */ "............."
/* 8 */ "............."
- // Level 8
+ // Level 9
/* z\x* 111 */
/* * 0123456789012 */
/* 0 */ "............."
/* 1 */ "............."
/* 2 */ "............."
/* 3 */ "............."
- /* 4 */ "..u.u...u.u.."
+ /* 4 */ "..v.v...v.v.."
/* 5 */ "............."
- /* 6 */ "..u.u...u.u.."
+ /* 6 */ "..v.v...v.v.."
/* 7 */ "............."
/* 8 */ ".............",
// Connectors:
- "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 6, 2, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -2953,201 +3315,245 @@ const cPrefab::sDef g_AlchemistVillageStartingPrefabs[] =
// The data has been exported from the gallery Desert, area index 90, ID 631, created by STR_Warrior
{
// Size:
- 5, 21, 5, // SizeX = 5, SizeY = 21, SizeZ = 5
+ 7, 21, 7, // SizeX = 7, SizeY = 21, SizeZ = 7
// Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ
- 4, 20, 4, // MaxX, MaxY, MaxZ
+ 6, 20, 6, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
"a: 1: 0\n" /* stone */
- "b: 24: 0\n" /* sandstone */
- "c: 8: 0\n" /* water */
- "d: 24: 2\n" /* sandstone */
- "e:128: 1\n" /* sandstonestairs */
- "f: 44: 1\n" /* step */
- "g:128: 0\n" /* sandstonestairs */
- "h:128: 3\n" /* sandstonestairs */
- "i:128: 2\n" /* sandstonestairs */
- "j: 44: 9\n" /* step */
- "k:126: 0\n" /* woodenslab */
- "m: 19: 0\n" /* sponge */,
+ "b: 24: 2\n" /* sandstone */
+ "c: 24: 0\n" /* sandstone */
+ "d: 8: 0\n" /* water */
+ "e: 4: 0\n" /* cobblestone */
+ "f: 13: 0\n" /* gravel */
+ "g:128: 1\n" /* sandstonestairs */
+ "h: 44: 1\n" /* step */
+ "i:128: 0\n" /* sandstonestairs */
+ "j:128: 3\n" /* sandstonestairs */
+ "k:128: 2\n" /* sandstonestairs */
+ "l: 44: 9\n" /* step */
+ "m: 19: 0\n" /* sponge */
+ "n:126: 0\n" /* woodenslab */,
// Block data:
// Level 0
- /* z\x* 01234 */
- /* 0 */ "aaaaa"
- /* 1 */ "aaaaa"
- /* 2 */ "aaaaa"
- /* 3 */ "aaaaa"
- /* 4 */ "aaaaa"
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "maaaaam"
+ /* 2 */ "maaaaam"
+ /* 3 */ "maaaaam"
+ /* 4 */ "maaaaam"
+ /* 5 */ "maaaaam"
+ /* 6 */ "mmmmmmm"
// Level 1
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "mcdddcm"
+ /* 3 */ "mcdddcm"
+ /* 4 */ "mcdddcm"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmmmmmm"
// Level 2
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "mcdddcm"
+ /* 3 */ "mcdddcm"
+ /* 4 */ "mcdddcm"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmmmmmm"
// Level 3
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "mcdddcm"
+ /* 3 */ "mcdddcm"
+ /* 4 */ "mcdddcm"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmmmmmm"
// Level 4
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "mcdddcm"
+ /* 3 */ "mcdddcm"
+ /* 4 */ "mcdddcm"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmmmmmm"
// Level 5
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "mcdddcm"
+ /* 3 */ "mcdddcm"
+ /* 4 */ "mcdddcm"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmmmmmm"
// Level 6
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "mcdddcm"
+ /* 3 */ "mcdddcm"
+ /* 4 */ "mcdddcm"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmmmmmm"
// Level 7
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "mcdddcm"
+ /* 3 */ "mcdddcm"
+ /* 4 */ "mcdddcm"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmmmmmm"
// Level 8
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "mcdddcm"
+ /* 3 */ "mcdddcm"
+ /* 4 */ "mcdddcm"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmmmmmm"
// Level 9
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "mcdddcm"
+ /* 3 */ "mcdddcm"
+ /* 4 */ "mcdddcm"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmmmmmm"
// Level 10
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "mcdddcm"
+ /* 3 */ "mcdddcm"
+ /* 4 */ "mcdddcm"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmmmmmm"
// Level 11
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "mcdddcm"
+ /* 3 */ "mcdddcm"
+ /* 4 */ "mcdddcm"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmmmmmm"
// Level 12
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "mcdddcm"
+ /* 3 */ "mcdddcm"
+ /* 4 */ "mcdddcm"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmmmmmm"
// Level 13
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "mcdddcm"
+ /* 3 */ "mcdddcm"
+ /* 4 */ "mcdddcm"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmmmmmm"
// Level 14
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmeeemm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "ecdddce"
+ /* 3 */ "ecdddce"
+ /* 4 */ "ecdddce"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmeeemm"
// Level 15
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bcccb"
- /* 2 */ "bcccb"
- /* 3 */ "bcccb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mmfffmm"
+ /* 1 */ "mbcccbm"
+ /* 2 */ "fcdddcf"
+ /* 3 */ "fcdddcf"
+ /* 4 */ "fcdddcf"
+ /* 5 */ "mbcccbm"
+ /* 6 */ "mmfffmm"
// Level 16
- /* z\x* 01234 */
- /* 0 */ "defgd"
- /* 1 */ "h...h"
- /* 2 */ "f...f"
- /* 3 */ "i...i"
- /* 4 */ "defgd"
+ /* z\x* 0123456 */
+ /* 0 */ "mm...mm"
+ /* 1 */ "mbghibm"
+ /* 2 */ ".j...j."
+ /* 3 */ ".h...h."
+ /* 4 */ ".k...k."
+ /* 5 */ "mbghibm"
+ /* 6 */ "mm...mm"
// Level 17
- /* z\x* 01234 */
- /* 0 */ "d...d"
- /* 1 */ "....."
- /* 2 */ "....."
- /* 3 */ "....."
- /* 4 */ "d...d"
+ /* z\x* 0123456 */
+ /* 0 */ "mm...mm"
+ /* 1 */ "mb...bm"
+ /* 2 */ "......."
+ /* 3 */ "......."
+ /* 4 */ "......."
+ /* 5 */ "mb...bm"
+ /* 6 */ "mm...mm"
// Level 18
- /* z\x* 01234 */
- /* 0 */ "djjjd"
- /* 1 */ "j...j"
- /* 2 */ "j...j"
- /* 3 */ "j...j"
- /* 4 */ "djjjd"
+ /* z\x* 0123456 */
+ /* 0 */ "mm...mm"
+ /* 1 */ "mblllbm"
+ /* 2 */ ".l...l."
+ /* 3 */ ".l...l."
+ /* 4 */ ".l...l."
+ /* 5 */ "mblllbm"
+ /* 6 */ "mm...mm"
// Level 19
- /* z\x* 01234 */
- /* 0 */ "bbbbb"
- /* 1 */ "bkkkb"
- /* 2 */ "bkkkb"
- /* 3 */ "bkkkb"
- /* 4 */ "bbbbb"
+ /* z\x* 0123456 */
+ /* 0 */ "mm...mm"
+ /* 1 */ "mcccccm"
+ /* 2 */ ".cnnnc."
+ /* 3 */ ".cnnnc."
+ /* 4 */ ".cnnnc."
+ /* 5 */ "mcccccm"
+ /* 6 */ "mm...mm"
// Level 20
- /* z\x* 01234 */
- /* 0 */ "f.f.f"
- /* 1 */ "....."
- /* 2 */ "f...f"
- /* 3 */ "....."
- /* 4 */ "f.f.f",
+ /* z\x* 0123456 */
+ /* 0 */ "mm...mm"
+ /* 1 */ "mh.h.hm"
+ /* 2 */ "......."
+ /* 3 */ ".h...h."
+ /* 4 */ "......."
+ /* 5 */ "mh.h.hm"
+ /* 6 */ "mm...mm",
// Connectors:
- "2: 2, 16, 4: 3\n" /* Type 2, direction Z+ */
- "2: 0, 16, 2: 4\n" /* Type 2, direction X- */
- "2: 2, 16, 0: 2\n" /* Type 2, direction Z- */
- "2: 4, 16, 2: 5\n" /* Type 2, direction X+ */,
+ "2: 3, 16, 6: 3\n" /* Type 2, direction Z+ */
+ "2: 0, 16, 3: 4\n" /* Type 2, direction X- */
+ "2: 3, 16, 0: 2\n" /* Type 2, direction Z- */
+ "2: 6, 16, 3: 5\n" /* Type 2, direction X+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
diff --git a/src/Generating/Prefabs/JapaneseVillagePrefabs.cpp b/src/Generating/Prefabs/JapaneseVillagePrefabs.cpp
index 5ec222f84..d22153d87 100644
--- a/src/Generating/Prefabs/JapaneseVillagePrefabs.cpp
+++ b/src/Generating/Prefabs/JapaneseVillagePrefabs.cpp
@@ -130,6 +130,176 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] =
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Farm:
+ // The data has been exported from the gallery Plains, area index 166, ID 554, created by Aloe_vera
+ {
+ // Size:
+ 11, 7, 13, // SizeX = 11, SizeY = 7, SizeZ = 13
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 10, 6, 12, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 3: 0\n" /* dirt */
+ "b: 60: 7\n" /* tilleddirt */
+ "c: 8: 0\n" /* water */
+ "d: 43: 0\n" /* doubleslab */
+ "e: 44: 0\n" /* step */
+ "f: 59: 7\n" /* crops */
+ "g: 83: 0\n" /* reedblock */
+ "h:113: 0\n" /* netherbrickfence */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmmmmmmmm"
+ /* 1 */ "maaaaaaaaam"
+ /* 2 */ "maaaaaaaaam"
+ /* 3 */ "maaaaaaaaam"
+ /* 4 */ "maaaaaaaaam"
+ /* 5 */ "maaaaaaaaam"
+ /* 6 */ "maaaaaaaaam"
+ /* 7 */ "maaaaaaaaam"
+ /* 8 */ "maaaaaaaaam"
+ /* 9 */ "maaaaaaaaam"
+ /* 10 */ "maaaaaaaaam"
+ /* 11 */ "maaaaaaaaam"
+ /* 12 */ "mmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmmmmmmmm"
+ /* 1 */ "maaaaaaaaam"
+ /* 2 */ "mabbbbbbbam"
+ /* 3 */ "mabbbbbbbam"
+ /* 4 */ "mabbbbbbbam"
+ /* 5 */ "mabbbbbbbam"
+ /* 6 */ "mabcccccaam"
+ /* 7 */ "mabbbbbbbam"
+ /* 8 */ "mabbbbbbbam"
+ /* 9 */ "mabbbbbbbam"
+ /* 10 */ "mabbbbbbbam"
+ /* 11 */ "maaaaaaaaam"
+ /* 12 */ "mmmmmmmmmmm"
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".deeeeeeed."
+ /* 2 */ ".efffffffe."
+ /* 3 */ ".efffffffe."
+ /* 4 */ ".efffffffe."
+ /* 5 */ ".efgggggfe."
+ /* 6 */ ".eg.....ge."
+ /* 7 */ ".efgggggfe."
+ /* 8 */ ".efffffffe."
+ /* 9 */ ".efffffffe."
+ /* 10 */ ".efffffffe."
+ /* 11 */ ".deeeeeeed."
+ /* 12 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".h.......h."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ "..........."
+ /* 5 */ "...ggggg..."
+ /* 6 */ "..g.....g.."
+ /* 7 */ "...ggggg..."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+ /* 11 */ ".h.......h."
+ /* 12 */ "..........."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".h.......h."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ "..........."
+ /* 5 */ "...ggggg..."
+ /* 6 */ "..g.....g.."
+ /* 7 */ "...ggggg..."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+ /* 11 */ ".h.......h."
+ /* 12 */ "..........."
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".h.......h."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ "..........."
+ /* 5 */ "..........."
+ /* 6 */ "..........."
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+ /* 11 */ ".h.......h."
+ /* 12 */ "..........."
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ ".h.......h."
+ /* 1 */ "hhh.....hhh"
+ /* 2 */ ".h.......h."
+ /* 3 */ "..........."
+ /* 4 */ "..........."
+ /* 5 */ "..........."
+ /* 6 */ "..........."
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ ".h.......h."
+ /* 11 */ "hhh.....hhh"
+ /* 12 */ ".h.......h.",
+
+ // Connectors:
+ "-1: 10, 2, 6: 5\n" /* Type -1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // Farm
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Forge:
// The data has been exported from the gallery Plains, area index 79, ID 145, created by Aloe_vera
{
@@ -2025,12 +2195,12 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] =
// Level 1
/* z\x* 0123456 */
- /* 0 */ "bbbbbbb"
- /* 1 */ "bbbbbbb"
- /* 2 */ "bbbbbbb"
- /* 3 */ "bbbabbb"
- /* 4 */ "bbbbbbb"
- /* 5 */ "bbbbbbb"
+ /* 0 */ "bmmmmmm"
+ /* 1 */ "bmmmmmm"
+ /* 2 */ "bmmmmmm"
+ /* 3 */ "bmmmmmm"
+ /* 4 */ "bmmmmmm"
+ /* 5 */ "bmmmmmm"
/* 6 */ "bbbbbbb"
// Level 2
@@ -3005,159 +3175,157 @@ const cPrefab::sDef g_JapaneseVillageStartingPrefabs[] =
"a: 1: 0\n" /* stone */
"b: 4: 0\n" /* cobblestone */
"c: 8: 0\n" /* water */
- "d: 3: 0\n" /* dirt */
- "e: 2: 0\n" /* grass */
- "f: 13: 0\n" /* gravel */
- "g: 67: 1\n" /* stairs */
- "h: 67: 2\n" /* stairs */
- "i: 67: 0\n" /* stairs */
- "j: 67: 3\n" /* stairs */
- "k: 85: 0\n" /* fence */
- "l: 44: 8\n" /* step */
- "m: 19: 0\n" /* sponge */
- "n: 44: 0\n" /* step */
- "o: 43: 0\n" /* doubleslab */,
+ "d: 13: 0\n" /* gravel */
+ "e: 67: 1\n" /* stairs */
+ "f: 67: 2\n" /* stairs */
+ "g: 67: 0\n" /* stairs */
+ "h: 67: 3\n" /* stairs */
+ "i: 85: 0\n" /* fence */
+ "j: 44: 8\n" /* step */
+ "k: 44: 0\n" /* step */
+ "l: 43: 0\n" /* doubleslab */
+ "m: 19: 0\n" /* sponge */,
// Block data:
// Level 0
/* z\x* 0123456 */
- /* 0 */ "aaaaaaa"
- /* 1 */ "aaaaaaa"
- /* 2 */ "aaaaaaa"
- /* 3 */ "aaaaaaa"
- /* 4 */ "aaaaaaa"
- /* 5 */ "aaaaaaa"
- /* 6 */ "aaaaaaa"
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "maaaaam"
+ /* 2 */ "maaaaam"
+ /* 3 */ "maaaaam"
+ /* 4 */ "maaaaam"
+ /* 5 */ "maaaaam"
+ /* 6 */ "mmmmmmm"
// Level 1
/* z\x* 0123456 */
- /* 0 */ "aaaaaaa"
- /* 1 */ "abbbbba"
- /* 2 */ "abcc.ba"
- /* 3 */ "abcccba"
- /* 4 */ "abcccba"
- /* 5 */ "abbbbba"
- /* 6 */ "aaaaaaa"
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbbbbbm"
+ /* 2 */ "mbcc.bm"
+ /* 3 */ "mbcccbm"
+ /* 4 */ "mbcccbm"
+ /* 5 */ "mbbbbbm"
+ /* 6 */ "mmmmmmm"
// Level 2
/* z\x* 0123456 */
- /* 0 */ "aaaaaaa"
- /* 1 */ "abbbbba"
- /* 2 */ "abcccba"
- /* 3 */ "abcccba"
- /* 4 */ "abcccba"
- /* 5 */ "abbbbba"
- /* 6 */ "aaaaaaa"
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbbbbbm"
+ /* 2 */ "mbcccbm"
+ /* 3 */ "mbcccbm"
+ /* 4 */ "mbcccbm"
+ /* 5 */ "mbbbbbm"
+ /* 6 */ "mmmmmmm"
// Level 3
/* z\x* 0123456 */
- /* 0 */ "aaaaaaa"
- /* 1 */ "abbbbba"
- /* 2 */ "abcccba"
- /* 3 */ "abcccba"
- /* 4 */ "abcccba"
- /* 5 */ "abbbbba"
- /* 6 */ "aaaaaaa"
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbbbbbm"
+ /* 2 */ "mbcccbm"
+ /* 3 */ "mbcccbm"
+ /* 4 */ "mbcccbm"
+ /* 5 */ "mbbbbbm"
+ /* 6 */ "mmmmmmm"
// Level 4
/* z\x* 0123456 */
- /* 0 */ "aaaaaaa"
- /* 1 */ "abbbbba"
- /* 2 */ "abcccba"
- /* 3 */ "abcccba"
- /* 4 */ "abcccba"
- /* 5 */ "abbbbba"
- /* 6 */ "aaaaaaa"
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbbbbbm"
+ /* 2 */ "mbcccbm"
+ /* 3 */ "mbcccbm"
+ /* 4 */ "mbcccbm"
+ /* 5 */ "mbbbbbm"
+ /* 6 */ "mmmmmmm"
// Level 5
/* z\x* 0123456 */
- /* 0 */ "ddddddd"
- /* 1 */ "dbbbbbd"
- /* 2 */ "dbcccbd"
- /* 3 */ "dbcccbd"
- /* 4 */ "dbcccbd"
- /* 5 */ "dbbbbbd"
- /* 6 */ "ddddddd"
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbbbbbm"
+ /* 2 */ "mbcccbm"
+ /* 3 */ "mbcccbm"
+ /* 4 */ "mbcccbm"
+ /* 5 */ "mbbbbbm"
+ /* 6 */ "mmmmmmm"
// Level 6
/* z\x* 0123456 */
- /* 0 */ "ddddddd"
- /* 1 */ "dbbbbbd"
- /* 2 */ "dbcccbd"
- /* 3 */ "dbcccbd"
- /* 4 */ "dbcccbd"
- /* 5 */ "dbbbbbd"
- /* 6 */ "ddddddd"
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mbbbbbm"
+ /* 2 */ "mbcccbm"
+ /* 3 */ "mbcccbm"
+ /* 4 */ "mbcccbm"
+ /* 5 */ "mbbbbbm"
+ /* 6 */ "mmmmmmm"
// Level 7
/* z\x* 0123456 */
- /* 0 */ "ddddddd"
- /* 1 */ "dbbbbbd"
- /* 2 */ "dbcccbd"
- /* 3 */ "dbcccbd"
- /* 4 */ "dbcccbd"
- /* 5 */ "dbbbbbd"
- /* 6 */ "ddddddd"
+ /* 0 */ "mmbbbmm"
+ /* 1 */ "mbbbbbm"
+ /* 2 */ "bbcccbb"
+ /* 3 */ "bbcccbb"
+ /* 4 */ "bbcccbb"
+ /* 5 */ "mbbbbbm"
+ /* 6 */ "mmbbbmm"
// Level 8
/* z\x* 0123456 */
- /* 0 */ "eefffee"
- /* 1 */ "ebbbbbe"
- /* 2 */ "fbcccbf"
- /* 3 */ "fbcccbf"
- /* 4 */ "fbcccbf"
- /* 5 */ "ebbbbbe"
- /* 6 */ "eefffee"
+ /* 0 */ "mmdddmm"
+ /* 1 */ "mbbbbbm"
+ /* 2 */ "dbcccbd"
+ /* 3 */ "dbcccbd"
+ /* 4 */ "dbcccbd"
+ /* 5 */ "mbbbbbm"
+ /* 6 */ "mmdddmm"
// Level 9
/* z\x* 0123456 */
- /* 0 */ "......."
- /* 1 */ ".bghib."
- /* 2 */ ".j...j."
- /* 3 */ ".i...g."
- /* 4 */ ".h...h."
- /* 5 */ ".bgjib."
- /* 6 */ "......."
+ /* 0 */ "mm...mm"
+ /* 1 */ "mbefgbm"
+ /* 2 */ ".h...h."
+ /* 3 */ ".g...e."
+ /* 4 */ ".f...f."
+ /* 5 */ "mbehgbm"
+ /* 6 */ "mm...mm"
// Level 10
/* z\x* 0123456 */
- /* 0 */ "......."
- /* 1 */ ".k...k."
+ /* 0 */ "mm...mm"
+ /* 1 */ "mi...im"
/* 2 */ "......."
/* 3 */ "......."
/* 4 */ "......."
- /* 5 */ ".k...k."
- /* 6 */ "......."
+ /* 5 */ "mi...im"
+ /* 6 */ "mm...mm"
// Level 11
/* z\x* 0123456 */
- /* 0 */ "......."
- /* 1 */ ".k...k."
+ /* 0 */ "mm...mm"
+ /* 1 */ "mi...im"
/* 2 */ "......."
/* 3 */ "......."
/* 4 */ "......."
- /* 5 */ ".k...k."
- /* 6 */ "......."
+ /* 5 */ "mi...im"
+ /* 6 */ "mm...mm"
// Level 12
/* z\x* 0123456 */
- /* 0 */ ".lnnnl."
- /* 1 */ "loooool"
- /* 2 */ "nooooon"
- /* 3 */ "nooooon"
- /* 4 */ "nooooon"
- /* 5 */ "loooool"
- /* 6 */ ".lnnnl."
+ /* 0 */ "mjkkkjm"
+ /* 1 */ "jlllllj"
+ /* 2 */ "klllllk"
+ /* 3 */ "klllllk"
+ /* 4 */ "klllllk"
+ /* 5 */ "jlllllj"
+ /* 6 */ "mjkkkjm"
// Level 13
/* z\x* 0123456 */
- /* 0 */ "n.....n"
+ /* 0 */ "k.....k"
/* 1 */ "......."
- /* 2 */ "..nnn.."
- /* 3 */ "..non.."
- /* 4 */ "..nnn.."
+ /* 2 */ "..kkk.."
+ /* 3 */ "..klk.."
+ /* 4 */ "..kkk.."
/* 5 */ "......."
- /* 6 */ "n.....n",
+ /* 6 */ "k.....k",
// Connectors:
"2: 0, 9, 3: 4\n" /* Type 2, direction X- */
diff --git a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp
index f5c5b7a20..bba493bf1 100644
--- a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp
+++ b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp
@@ -356,35 +356,36 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
"e: 8: 0\n" /* water */
"f: 50: 5\n" /* torch */
"g: 59: 7\n" /* crops */
+ "h:111: 0\n" /* lilypad */
"m: 19: 0\n" /* sponge */,
// Block data:
// Level 0
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "aaaaaaaaaaaaaaa"
+ /* 0 */ "aaaaaaabaaaaaaa"
/* 1 */ "aaaaaaaaaaaaaaa"
/* 2 */ "aaaaaaaaaaaaaaa"
/* 3 */ "aaaaaaaaaaaaaaa"
/* 4 */ "aaaaaaaaaaaaaaa"
- /* 5 */ "aaaaaaaaaaaaaaa"
- /* 6 */ "aaaaaaaaaaaaaaa"
- /* 7 */ "aaaaaaaaaaaaaaa"
- /* 8 */ "aaaaaaaaaaaaaaa"
-
- // Level 1
- /* z\x* 11111 */
- /* * 012345678901234 */
- /* 0 */ "aaaaaaabaaaaaaa"
- /* 1 */ "aaaaaaabaaaaaaa"
- /* 2 */ "aaaaaaabaaaaaaa"
- /* 3 */ "aaaaaaabaaaaaaa"
- /* 4 */ "aaaaaaabaaaaaaa"
/* 5 */ "aaaaaaabaaaaaaa"
/* 6 */ "aaaaaaabaaaaaaa"
/* 7 */ "aaaaaaabaaaaaaa"
/* 8 */ "aaaaaaabaaaaaaa"
+ // Level 1
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "aaaaaaamaaaaaaa"
+ /* 1 */ "aaaaaaamaaaaaaa"
+ /* 2 */ "aaaaaaamaaaaaaa"
+ /* 3 */ "aaaaaaamaaaaaaa"
+ /* 4 */ "aaaaaaamaaaaaaa"
+ /* 5 */ "aaaaaaamaaaaaaa"
+ /* 6 */ "aaaaaaamaaaaaaa"
+ /* 7 */ "aaaaaaamaaaaaaa"
+ /* 8 */ "aaaaaaamaaaaaaa"
+
// Level 2
/* z\x* 11111 */
/* * 012345678901234 */
@@ -407,7 +408,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 3 */ ".g.......gg.gg."
/* 4 */ ".gg..g...gg.gg."
/* 5 */ ".gg..g...gg.gg."
- /* 6 */ "..g..g...gg.gg."
+ /* 6 */ "..g..g...gghgg."
/* 7 */ "..g.g....gg.gg."
/* 8 */ "f.....f.f.....f"
@@ -509,12 +510,12 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
"d: 67: 1\n" /* stairs */
"e: 17: 0\n" /* tree */
"f: 5: 0\n" /* wood */
- "g: 64: 6\n" /* wooddoorblock */
+ "g: 64: 2\n" /* wooddoorblock */
"h: 10: 0\n" /* lava */
"i: 54: 2\n" /* chest */
"j: 61: 2\n" /* furnace */
"k:102: 0\n" /* glasspane */
- "l: 64:12\n" /* wooddoorblock */
+ "l: 64: 8\n" /* wooddoorblock */
"m: 19: 0\n" /* sponge */
"n:139: 0\n" /* cobblestonewall */
"o:101: 0\n" /* ironbars */
@@ -2544,7 +2545,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
true,
// DefaultWeight:
- 100,
+ 20,
// DepthWeight:
"",
@@ -2746,8 +2747,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
"d: 67: 1\n" /* stairs */
"e: 17: 0\n" /* tree */
"f: 5: 0\n" /* wood */
- "g: 64: 7\n" /* wooddoorblock */
- "h: 64:12\n" /* wooddoorblock */
+ "g: 64: 3\n" /* wooddoorblock */
+ "h: 64: 8\n" /* wooddoorblock */
"i:102: 0\n" /* glasspane */
"j: 53: 2\n" /* woodstairs */
"k: 53: 7\n" /* woodstairs */
@@ -3000,9 +3001,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
"d: 67: 1\n" /* stairs */
"e: 17: 0\n" /* tree */
"f: 5: 0\n" /* wood */
- "g: 64: 7\n" /* wooddoorblock */
+ "g: 64: 3\n" /* wooddoorblock */
"h:102: 0\n" /* glasspane */
- "i: 64:12\n" /* wooddoorblock */
+ "i: 64: 8\n" /* wooddoorblock */
"j: 53: 2\n" /* woodstairs */
"k: 53: 7\n" /* woodstairs */
"l: 50: 3\n" /* torch */
@@ -3141,31 +3142,32 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
"k: 85: 0\n" /* fence */
"l: 53: 0\n" /* woodstairs */
"m: 19: 0\n" /* sponge */
- "n: 64: 6\n" /* wooddoorblock */
+ "n: 64: 2\n" /* wooddoorblock */
"o: 64: 4\n" /* wooddoorblock */
"p:102: 0\n" /* glasspane */
"q: 72: 0\n" /* woodplate */
- "r: 64:12\n" /* wooddoorblock */
- "s: 53: 5\n" /* woodstairs */
- "t: 53: 4\n" /* woodstairs */
- "u: 50: 1\n" /* torch */
- "v: 50: 2\n" /* torch */,
+ "r: 64: 8\n" /* wooddoorblock */
+ "s: 64:12\n" /* wooddoorblock */
+ "t: 53: 5\n" /* woodstairs */
+ "u: 53: 4\n" /* woodstairs */
+ "v: 50: 1\n" /* torch */
+ "w: 50: 2\n" /* torch */,
// Block data:
// Level 0
/* z\x* */
/* * 0123456789 */
- /* 0 */ ".........."
- /* 1 */ ".aaaaa...."
- /* 2 */ ".aaaaa...."
- /* 3 */ ".aaaaabbbb"
+ /* 0 */ "mmmmmmmmmm"
+ /* 1 */ "maaaaammmm"
+ /* 2 */ "maaaaammmm"
+ /* 3 */ "maaaaabbbb"
/* 4 */ "aaaaaabbbb"
/* 5 */ "aaaaaabbbb"
/* 6 */ "aaaaaabbbb"
- /* 7 */ ".aaaaabbbb"
- /* 8 */ ".aaaaabbbb"
- /* 9 */ ".aaaaa...."
- /* 10 */ ".........."
+ /* 7 */ "maaaaabbbb"
+ /* 8 */ "maaaaabbbb"
+ /* 9 */ "maaaaammmm"
+ /* 10 */ "mmmmmmmmmm"
// Level 1
/* z\x* */
@@ -3205,7 +3207,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 2 */ ".p.q.pmmmm"
/* 3 */ ".p...p...."
/* 4 */ ".c...c...."
- /* 5 */ ".r...r...."
+ /* 5 */ ".r...s...."
/* 6 */ ".c...c...."
/* 7 */ ".p...p...."
/* 8 */ ".p...p...."
@@ -3215,47 +3217,47 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
// Level 4
/* z\x* */
/* * 0123456789 */
- /* 0 */ "ls...tjmmm"
+ /* 0 */ "lt...ujmmm"
/* 1 */ "licccijmmm"
/* 2 */ "lc...cjmmm"
/* 3 */ "lc...cj..."
- /* 4 */ "lcu.vcj..."
+ /* 4 */ "lcv.wcj..."
/* 5 */ "lc...cj..."
- /* 6 */ "lcu.vcj..."
+ /* 6 */ "lcv.wcj..."
/* 7 */ "lc...cj..."
/* 8 */ "lc...cj..."
/* 9 */ "licccijmmm"
- /* 10 */ "ls...tjmmm"
+ /* 10 */ "lt...ujmmm"
// Level 5
/* z\x* */
/* * 0123456789 */
- /* 0 */ "mls.tjmmmm"
- /* 1 */ "mlcccjmmmm"
- /* 2 */ "mlc.cjmmmm"
- /* 3 */ "mlc.cjm..."
- /* 4 */ "mlc.cjm..."
- /* 5 */ "mlc.cjm..."
- /* 6 */ "mlc.cjm..."
- /* 7 */ "mlc.cjm..."
- /* 8 */ "mlc.cjm..."
- /* 9 */ "mlcccjmmmm"
- /* 10 */ "mls.tjmmmm"
+ /* 0 */ ".lt.uj.mmm"
+ /* 1 */ ".lcccj.mmm"
+ /* 2 */ ".lc.cj.mmm"
+ /* 3 */ ".lc.cj...."
+ /* 4 */ ".lc.cj...."
+ /* 5 */ ".lc.cj...."
+ /* 6 */ ".lc.cj...."
+ /* 7 */ ".lc.cj...."
+ /* 8 */ ".lc.cj...."
+ /* 9 */ ".lcccj.mmm"
+ /* 10 */ ".lt.uj.mmm"
// Level 6
/* z\x* */
/* * 0123456789 */
- /* 0 */ "mmlcjmmmmm"
- /* 1 */ "mmlcjmmmmm"
- /* 2 */ "mmlcjmmmmm"
- /* 3 */ "mmlcjmm..."
- /* 4 */ "mmlcjmm..."
- /* 5 */ "mmlcjmm..."
- /* 6 */ "mmlcjmm..."
- /* 7 */ "mmlcjmm..."
- /* 8 */ "mmlcjmm..."
- /* 9 */ "mmlcjmmmmm"
- /* 10 */ "mmlcjmmmmm",
+ /* 0 */ "..lcj..mmm"
+ /* 1 */ "..lcj..mmm"
+ /* 2 */ "..lcj..mmm"
+ /* 3 */ "..lcj....."
+ /* 4 */ "..lcj....."
+ /* 5 */ "..lcj....."
+ /* 6 */ "..lcj....."
+ /* 7 */ "..lcj....."
+ /* 8 */ "..lcj....."
+ /* 9 */ "..lcj..mmm"
+ /* 10 */ "..lcj..mmm",
// Connectors:
"-1: 0, 1, 5: 4\n" /* Type -1, direction X- */,
@@ -3626,7 +3628,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
// Level 0
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "aaabbbbaaaa"
+ /* 0 */ "aaaabbbaaaa"
/* 1 */ "abbbbbbbbba"
/* 2 */ "abbbbbbbbba"
/* 3 */ "abbbbbbbbba"
@@ -4509,10 +4511,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ ".aaaaaaaaa."
/* 5 */ ".aaaaaaaaa."
/* 6 */ ".....aaaaa."
- /* 7 */ ".....aaaaa."
- /* 8 */ ".....aaaaa."
- /* 9 */ ".....aaaaa."
- /* 10 */ "..........."
+ /* 7 */ "mmmm.aaaaa."
+ /* 8 */ "mmmm.aaaaa."
+ /* 9 */ "mmmm.aaaaa."
+ /* 10 */ "mmmm......."
// Level 2
/* z\x* 1 */
@@ -4524,10 +4526,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ ".f.......f."
/* 5 */ ".efffe...f."
/* 6 */ ".....f...f."
- /* 7 */ ".....f...f."
- /* 8 */ ".....f...f."
- /* 9 */ ".....efffe."
- /* 10 */ "..........."
+ /* 7 */ "mmmm.f...f."
+ /* 8 */ "mmmm.f...f."
+ /* 9 */ "mmmm.efffe."
+ /* 10 */ "mmmm......."
// Level 3
/* z\x* 1 */
@@ -4539,10 +4541,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ ".h.......h."
/* 5 */ ".ehhhe...f."
/* 6 */ ".....h...h."
- /* 7 */ ".....h...h."
- /* 8 */ ".....h...h."
- /* 9 */ ".....ehhhe."
- /* 10 */ "..........."
+ /* 7 */ "mmmm.h...h."
+ /* 8 */ "mmmm.h...h."
+ /* 9 */ "mmmm.ehhhe."
+ /* 10 */ "mmmm......."
// Level 4
/* z\x* 1 */
@@ -4554,10 +4556,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ ".f...o...fl"
/* 5 */ "pfffffq.rfl"
/* 6 */ "sssssf...fl"
- /* 7 */ "....tf...fl"
- /* 8 */ "....tf...fl"
- /* 9 */ "....tfffffl"
- /* 10 */ "....tu...vl"
+ /* 7 */ "mmmmtf...fl"
+ /* 8 */ "mmmmtf...fl"
+ /* 9 */ "mmmmtfffffl"
+ /* 10 */ "mmmmtu...vl"
// Level 5
/* z\x* 1 */
@@ -4569,10 +4571,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ "pffffff.fl."
/* 5 */ "ssssssf.fl."
/* 6 */ ".....tf.fl."
- /* 7 */ ".....tf.fl."
- /* 8 */ ".....tf.fl."
- /* 9 */ ".....tfffl."
- /* 10 */ ".....tu.vl."
+ /* 7 */ "mmmm.tf.fl."
+ /* 8 */ "mmmm.tf.fl."
+ /* 9 */ "mmmm.tfffl."
+ /* 10 */ "mmmm.tu.vl."
// Level 6
/* z\x* 1 */
@@ -4584,10 +4586,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ "sssssstfl.."
/* 5 */ "......tfl.."
/* 6 */ "......tfl.."
- /* 7 */ "......tfl.."
- /* 8 */ "......tfl.."
- /* 9 */ "......tfl.."
- /* 10 */ "......tfl..",
+ /* 7 */ "mmmm..tfl.."
+ /* 8 */ "mmmm..tfl.."
+ /* 9 */ "mmmm..tfl.."
+ /* 10 */ "mmmm..tfl..",
// Connectors:
"-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
@@ -4837,9 +4839,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
// Level 1
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "........."
+ /* 0 */ "mmmmmmm.."
+ /* 1 */ "mmmmmmm.."
+ /* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ ".aaaaa..."
/* 5 */ ".aaaaab.."
@@ -4847,15 +4849,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".aaaaad.."
/* 8 */ ".aaaaa..."
/* 9 */ "........."
- /* 10 */ "........."
- /* 11 */ "........."
- /* 12 */ "........."
+ /* 10 */ "mmmmmmm.."
+ /* 11 */ "mmmmmmm.."
+ /* 12 */ "mmmmmmm.."
// Level 2
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "........."
+ /* 0 */ "mmmmmmm.."
+ /* 1 */ "mmmmmmm.."
+ /* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ ".efffe..."
/* 5 */ ".f...f..."
@@ -4863,15 +4865,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f...f..."
/* 8 */ ".efffe..."
/* 9 */ "........."
- /* 10 */ "........."
- /* 11 */ "........."
- /* 12 */ "........."
+ /* 10 */ "mmmmmmm.."
+ /* 11 */ "mmmmmmm.."
+ /* 12 */ "mmmmmmm.."
// Level 3
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "........."
+ /* 0 */ "mmmmmmm.."
+ /* 1 */ "mmmmmmm.."
+ /* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ ".ejjje..."
/* 5 */ ".j...f..."
@@ -4879,15 +4881,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".j...f..."
/* 8 */ ".ejjje..."
/* 9 */ "........."
- /* 10 */ "........."
- /* 11 */ "........."
- /* 12 */ "........."
+ /* 10 */ "mmmmmmm.."
+ /* 11 */ "mmmmmmm.."
+ /* 12 */ "mmmmmmm.."
// Level 4
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "........."
+ /* 0 */ "mmmmmmm.."
+ /* 1 */ "mmmmmmm.."
+ /* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ ".efffe..."
/* 5 */ ".f..nf..."
@@ -4895,15 +4897,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f..nf..k"
/* 8 */ ".efffe..o"
/* 9 */ "........."
- /* 10 */ "........."
- /* 11 */ "........."
- /* 12 */ "........."
+ /* 10 */ "mmmmmmm.."
+ /* 11 */ "mmmmmmm.."
+ /* 12 */ "mmmmmmm.."
// Level 5
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "........."
+ /* 0 */ "mmmmmmm.."
+ /* 1 */ "mmmmmmm.."
+ /* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ ".epppe..."
/* 5 */ ".q...q..."
@@ -4911,15 +4913,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".q...q..k"
/* 8 */ ".epppe..o"
/* 9 */ "........."
- /* 10 */ "........."
- /* 11 */ "........."
- /* 12 */ "........."
+ /* 10 */ "mmmmmmm.."
+ /* 11 */ "mmmmmmm.."
+ /* 12 */ "mmmmmmm.."
// Level 6
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "........."
+ /* 0 */ "mmmmmmm.."
+ /* 1 */ "mmmmmmm.."
+ /* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ ".efffe..."
/* 5 */ ".f...f..."
@@ -4927,15 +4929,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f...f..o"
/* 8 */ ".efffe..o"
/* 9 */ "........."
- /* 10 */ "........."
- /* 11 */ "........."
- /* 12 */ "........."
+ /* 10 */ "mmmmmmm.."
+ /* 11 */ "mmmmmmm.."
+ /* 12 */ "mmmmmmm.."
// Level 7
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "........."
+ /* 0 */ "mmmmmmm.."
+ /* 1 */ "mmmmmmm.."
+ /* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ ".ejjje..."
/* 5 */ ".j...j..."
@@ -4943,15 +4945,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".j...j..o"
/* 8 */ ".ejjje..."
/* 9 */ "........."
- /* 10 */ "........."
- /* 11 */ "........."
- /* 12 */ "........."
+ /* 10 */ "mmmmmmm.."
+ /* 11 */ "mmmmmmm.."
+ /* 12 */ "mmmmmmm.."
// Level 8
/* z\x* 012345678 */
- /* 0 */ "........o"
- /* 1 */ "........o"
- /* 2 */ "........o"
+ /* 0 */ "mmmmmmm.o"
+ /* 1 */ "mmmmmmm.o"
+ /* 2 */ "mmmmmmm.o"
/* 3 */ "........."
/* 4 */ ".efffe..."
/* 5 */ ".f...f..k"
@@ -4959,15 +4961,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f...f..o"
/* 8 */ ".efffe..."
/* 9 */ "........."
- /* 10 */ "........."
- /* 11 */ "........."
- /* 12 */ "........."
+ /* 10 */ "mmmmmmm.."
+ /* 11 */ "mmmmmmm.."
+ /* 12 */ "mmmmmmm.."
// Level 9
/* z\x* 012345678 */
- /* 0 */ "........k"
- /* 1 */ "........k"
- /* 2 */ "........o"
+ /* 0 */ "mmmmmmm.k"
+ /* 1 */ "mmmmmmm.k"
+ /* 2 */ "mmmmmmm.o"
/* 3 */ "........o"
/* 4 */ ".epppe..o"
/* 5 */ ".q...q..k"
@@ -4975,15 +4977,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".q...q..k"
/* 8 */ ".epppe..k"
/* 9 */ "........."
- /* 10 */ "........."
- /* 11 */ "........."
- /* 12 */ "........."
+ /* 10 */ "mmmmmmm.."
+ /* 11 */ "mmmmmmm.."
+ /* 12 */ "mmmmmmm.."
// Level 10
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "........k"
+ /* 0 */ "mmmmmmm.."
+ /* 1 */ "mmmmmmm.."
+ /* 2 */ "mmmmmmm.k"
/* 3 */ "rrrrrrr.k"
/* 4 */ "sfffffs.o"
/* 5 */ ".f...f..o"
@@ -4991,15 +4993,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f...f..o"
/* 8 */ "tffffft.o"
/* 9 */ "uuuuuuu.k"
- /* 10 */ "........k"
- /* 11 */ "........."
- /* 12 */ "........."
+ /* 10 */ "mmmmmmm.k"
+ /* 11 */ "mmmmmmm.."
+ /* 12 */ "mmmmmmm.."
// Level 11
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "........."
+ /* 0 */ "mmmmmmm.."
+ /* 1 */ "mmmmmmm.."
+ /* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ "rrrrrrr.k"
/* 5 */ "sfffffs.k"
@@ -5007,15 +5009,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "tffffft.k"
/* 8 */ "uuuuuuu.o"
/* 9 */ "........o"
- /* 10 */ "........o"
- /* 11 */ "........k"
- /* 12 */ "........k"
+ /* 10 */ "mmmmmmm.o"
+ /* 11 */ "mmmmmmm.k"
+ /* 12 */ "mmmmmmm.k"
// Level 12
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "........."
+ /* 0 */ "mmmmmmm.."
+ /* 1 */ "mmmmmmm.."
+ /* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ "........."
/* 5 */ "rrrrrrr.o"
@@ -5023,15 +5025,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "uuuuuuu.k"
/* 8 */ "........."
/* 9 */ "........."
- /* 10 */ "........o"
- /* 11 */ "........o"
- /* 12 */ "........o"
+ /* 10 */ "mmmmmmm.o"
+ /* 11 */ "mmmmmmm.o"
+ /* 12 */ "mmmmmmm.o"
// Level 13
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "........."
+ /* 0 */ "mmmmmmm.."
+ /* 1 */ "mmmmmmm.."
+ /* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ "........."
/* 5 */ "........o"
@@ -5039,15 +5041,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "........."
/* 8 */ "........."
/* 9 */ "........."
- /* 10 */ "........."
- /* 11 */ "........."
- /* 12 */ "........."
+ /* 10 */ "mmmmmmm.."
+ /* 11 */ "mmmmmmm.."
+ /* 12 */ "mmmmmmm.."
// Level 14
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "........."
+ /* 0 */ "mmmmmmm.."
+ /* 1 */ "mmmmmmm.."
+ /* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ "........o"
/* 5 */ "........o"
@@ -5055,15 +5057,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "........."
/* 8 */ "........."
/* 9 */ "........."
- /* 10 */ "........."
- /* 11 */ "........."
- /* 12 */ "........."
+ /* 10 */ "mmmmmmm.."
+ /* 11 */ "mmmmmmm.."
+ /* 12 */ "mmmmmmm.."
// Level 15
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "........."
+ /* 0 */ "mmmmmmm.."
+ /* 1 */ "mmmmmmm.."
+ /* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ "........o"
/* 5 */ "........k"
@@ -5071,15 +5073,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "........."
/* 8 */ "........."
/* 9 */ "........."
- /* 10 */ "........."
- /* 11 */ "........."
- /* 12 */ "........."
+ /* 10 */ "mmmmmmm.."
+ /* 11 */ "mmmmmmm.."
+ /* 12 */ "mmmmmmm.."
// Level 16
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ "........."
- /* 2 */ "........."
+ /* 0 */ "mmmmmmm.."
+ /* 1 */ "mmmmmmm.."
+ /* 2 */ "mmmmmmm.."
/* 3 */ "........."
/* 4 */ "........o"
/* 5 */ "........k"
@@ -5087,9 +5089,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "........."
/* 8 */ "........."
/* 9 */ "........."
- /* 10 */ "........."
- /* 11 */ "........."
- /* 12 */ ".........",
+ /* 10 */ "mmmmmmm.."
+ /* 11 */ "mmmmmmm.."
+ /* 12 */ "mmmmmmm..",
// Connectors:
"-1: 8, 1, 6: 5\n" /* Type -1, direction X+ */,
@@ -5472,13 +5474,15 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] =
"l: 66: 7\n" /* tracks */
"m: 19: 0\n" /* sponge */
"n: 50: 2\n" /* torch */
- "o: 2: 0\n" /* grass */
- "p: 53: 2\n" /* woodstairs */
- "q: 77: 1\n" /* stonebutton */
- "r: 27: 0\n" /* poweredrail */
- "s: 53: 7\n" /* woodstairs */
- "t: 53: 6\n" /* woodstairs */
- "u: 53: 3\n" /* woodstairs */,
+ "o: 4: 0\n" /* cobblestone */
+ "p: 2: 0\n" /* grass */
+ "q: 13: 0\n" /* gravel */
+ "r: 53: 2\n" /* woodstairs */
+ "s: 77: 1\n" /* stonebutton */
+ "t: 27: 0\n" /* poweredrail */
+ "u: 53: 7\n" /* woodstairs */
+ "v: 53: 6\n" /* woodstairs */
+ "w: 53: 3\n" /* woodstairs */,
// Block data:
// Level 0
@@ -5783,28 +5787,28 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] =
// Level 30
/* z\x* 0123456 */
- /* 0 */ "mmmmmmm"
+ /* 0 */ "mmooomm"
/* 1 */ "mmmammm"
- /* 2 */ "mm...mm"
- /* 3 */ "ma..aam"
- /* 4 */ "mmfgamm"
+ /* 2 */ "om...mo"
+ /* 3 */ "oa..aao"
+ /* 4 */ "omfgamo"
/* 5 */ "mmmammm"
- /* 6 */ "mmmmmmm"
+ /* 6 */ "mmooomm"
// Level 31
/* z\x* 0123456 */
- /* 0 */ "ooomooo"
- /* 1 */ "oaaaaao"
- /* 2 */ "oa.aaao"
- /* 3 */ "oa..iao"
- /* 4 */ "oa..jao"
- /* 5 */ "oaaaaao"
- /* 6 */ "ooooooo"
+ /* 0 */ "ppqqqpp"
+ /* 1 */ "paaaaap"
+ /* 2 */ "qa.aaaq"
+ /* 3 */ "qa..iaq"
+ /* 4 */ "qa..jaq"
+ /* 5 */ "paaaaap"
+ /* 6 */ "ppqqqpp"
// Level 32
/* z\x* 0123456 */
- /* 0 */ "...p..."
- /* 1 */ ".aqrba."
+ /* 0 */ "...r..."
+ /* 1 */ ".astba."
/* 2 */ "...fl.."
/* 3 */ "......."
/* 4 */ "......."
@@ -5833,31 +5837,31 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] =
// Level 35
/* z\x* 0123456 */
- /* 0 */ "ppppppp"
- /* 1 */ "saaaaas"
+ /* 0 */ "rrrrrrr"
+ /* 1 */ "uaaaaau"
/* 2 */ ".a...a."
/* 3 */ ".a...a."
/* 4 */ ".a...a."
- /* 5 */ "taaaaat"
- /* 6 */ "uuuuuuu"
+ /* 5 */ "vaaaaav"
+ /* 6 */ "wwwwwww"
// Level 36
/* z\x* 0123456 */
/* 0 */ "......."
- /* 1 */ "ppppppp"
- /* 2 */ "saaaaas"
+ /* 1 */ "rrrrrrr"
+ /* 2 */ "uaaaaau"
/* 3 */ ".aaaaa."
- /* 4 */ "taaaaat"
- /* 5 */ "uuuuuuu"
+ /* 4 */ "vaaaaav"
+ /* 5 */ "wwwwwww"
/* 6 */ "......."
// Level 37
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ "......."
- /* 2 */ "ppppppp"
+ /* 2 */ "rrrrrrr"
/* 3 */ "aaaaaaa"
- /* 4 */ "uuuuuuu"
+ /* 4 */ "wwwwwww"
/* 5 */ "......."
/* 6 */ ".......",
diff --git a/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp b/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp
index eb01cf59e..44e947952 100644
--- a/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp
+++ b/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp
@@ -23,8 +23,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
12, 6, 10, // SizeX = 12, SizeY = 6, SizeZ = 10
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 11, 5, 9, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 12, 5, 10, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
@@ -170,8 +170,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
13, 6, 9, // SizeX = 13, SizeY = 6, SizeZ = 9
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 12, 5, 8, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 13, 5, 9, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
@@ -309,8 +309,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
7, 6, 6, // SizeX = 7, SizeY = 6, SizeZ = 6
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 6, 5, 5, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 7, 5, 6, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
@@ -420,8 +420,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 6, 5, 6, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 7, 5, 7, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
@@ -538,8 +538,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
9, 6, 7, // SizeX = 9, SizeY = 6, SizeZ = 7
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 8, 5, 6, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 9, 5, 7, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
@@ -656,8 +656,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
10, 6, 7, // SizeX = 10, SizeY = 6, SizeZ = 7
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 9, 5, 6, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 10, 5, 7, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
@@ -780,8 +780,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
10, 6, 9, // SizeX = 10, SizeY = 6, SizeZ = 9
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 9, 5, 8, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 10, 5, 9, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
@@ -918,8 +918,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
11, 6, 9, // SizeX = 11, SizeY = 6, SizeZ = 9
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 10, 5, 8, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 11, 5, 9, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
@@ -1054,18 +1054,18 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 53, ID 345, created by jakibaki
{
// Size:
- 15, 5, 14, // SizeX = 15, SizeY = 5, SizeZ = 14
+ 15, 6, 14, // SizeX = 15, SizeY = 6, SizeZ = 14
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 14, 4, 13, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 15, 5, 14, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a:128: 0\n" /* sandstonestairs */
- "b:128: 2\n" /* sandstonestairs */
- "c:128: 1\n" /* sandstonestairs */
- "d: 24: 0\n" /* sandstone */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
"e: 43: 1\n" /* doubleslab */
"f: 64: 7\n" /* wooddoorblock */
"g:171: 0\n" /* carpet */
@@ -1088,43 +1088,61 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
// Level 0
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "...abc........."
- /* 1 */ ".ddddddddddddd."
- /* 2 */ ".ddddddddddddd."
- /* 3 */ ".ddddddddddddd."
- /* 4 */ ".ddddddddddddd."
- /* 5 */ ".ddddddddddded."
- /* 6 */ ".ddddddddddddd."
- /* 7 */ ".ddddddddddddd."
- /* 8 */ ".......deddddd."
- /* 9 */ "mmmmmm.ddddddd."
- /* 10 */ "mmmmmm.ddddddd."
- /* 11 */ "mmmmmm.ddddddd."
- /* 12 */ "mmmmmm.ddddddd."
- /* 13 */ "..............."
+ /* 0 */ "mmmaaammmmmmmmm"
+ /* 1 */ "maaaaaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaaaaam"
+ /* 6 */ "maaaaaaaaaaaaam"
+ /* 7 */ "maaaaaaaaaaaaam"
+ /* 8 */ "mmmmmmmaaaaaaam"
+ /* 9 */ "mmmmmmmaaaaaaam"
+ /* 10 */ "mmmmmmmaaaaaaam"
+ /* 11 */ "mmmmmmmaaaaaaam"
+ /* 12 */ "mmmmmmmaaaaaaam"
+ /* 13 */ "mmmmmmmmmmmmmmm"
// Level 1
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "..............."
- /* 1 */ ".dddfddddddddd."
- /* 2 */ ".dgghhhhhhhhgd."
- /* 3 */ ".dghiiiiiiiihd."
- /* 4 */ ".dghiggggggihd."
- /* 5 */ ".dghiiiiiigihd."
- /* 6 */ ".dgghhhhhigihd."
- /* 7 */ ".dddddddhigihd."
- /* 8 */ ".......dhigihd."
- /* 9 */ "mmmmmm.dhiiihd."
- /* 10 */ "mmmmmm.dghhhgd."
- /* 11 */ "mmmmmm.dggggjd."
- /* 12 */ "mmmmmm.ddddddd."
+ /* 0 */ "...bcd........."
+ /* 1 */ ".aaaaaaaaaaaaa."
+ /* 2 */ ".aaaaaaaaaaaaa."
+ /* 3 */ ".aaaaaaaaaaaaa."
+ /* 4 */ ".aaaaaaaaaaaaa."
+ /* 5 */ ".aaaaaaaaaaaea."
+ /* 6 */ ".aaaaaaaaaaaaa."
+ /* 7 */ ".aaaaaaaaaaaaa."
+ /* 8 */ ".......aeaaaaa."
+ /* 9 */ "mmmmmm.aaaaaaa."
+ /* 10 */ "mmmmmm.aaaaaaa."
+ /* 11 */ "mmmmmm.aaaaaaa."
+ /* 12 */ "mmmmmm.aaaaaaa."
/* 13 */ "..............."
// Level 2
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
+ /* 1 */ ".aaafaaaaaaaaa."
+ /* 2 */ ".agghhhhhhhhga."
+ /* 3 */ ".aghiiiiiiiiha."
+ /* 4 */ ".aghiggggggiha."
+ /* 5 */ ".aghiiiiiigiha."
+ /* 6 */ ".agghhhhhigiha."
+ /* 7 */ ".aaaaaaahigiha."
+ /* 8 */ ".......ahigiha."
+ /* 9 */ "mmmmmm.ahiiiha."
+ /* 10 */ "mmmmmm.aghhhga."
+ /* 11 */ "mmmmmm.aggggja."
+ /* 12 */ "mmmmmm.aaaaaaa."
+ /* 13 */ "..............."
+
+ // Level 3
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
/* 1 */ ".kkklkkkk.kkkk."
/* 2 */ ".k...........k."
/* 3 */ ".k...........k."
@@ -1139,44 +1157,44 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
/* 12 */ "mmmmmm.kkk.kkk."
/* 13 */ "..............."
- // Level 3
+ // Level 4
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
- /* 1 */ ".ddddddddddddd."
- /* 2 */ ".d......n....d."
- /* 3 */ ".d...........d."
- /* 4 */ ".do..........d."
- /* 5 */ ".d...........d."
- /* 6 */ ".d..........pd."
- /* 7 */ ".ddddddd.....d."
- /* 8 */ ".......d.....d."
- /* 9 */ "mmmmmm.d.....d."
- /* 10 */ "mmmmmm.d.....d."
- /* 11 */ "mmmmmm.d..q..d."
- /* 12 */ "mmmmmm.ddddddd."
+ /* 1 */ ".aaaaaaaaaaaaa."
+ /* 2 */ ".a......n....a."
+ /* 3 */ ".a...........a."
+ /* 4 */ ".ao..........a."
+ /* 5 */ ".a...........a."
+ /* 6 */ ".a..........pa."
+ /* 7 */ ".aaaaaaa.....a."
+ /* 8 */ ".......a.....a."
+ /* 9 */ "mmmmmm.a.....a."
+ /* 10 */ "mmmmmm.a.....a."
+ /* 11 */ "mmmmmm.a..q..a."
+ /* 12 */ "mmmmmm.aaaaaaa."
/* 13 */ "..............."
- // Level 4
+ // Level 5
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "rrrrrrrrrrrrrrs"
- /* 1 */ "tddddddddddddds"
- /* 2 */ "tddddddddddddds"
- /* 3 */ "tddddddddddddds"
- /* 4 */ "tddddddddddddds"
- /* 5 */ "tddddddddddddds"
- /* 6 */ "tddddddddddddds"
- /* 7 */ "tddddddddddddds"
- /* 8 */ "tuuuuutddddddds"
- /* 9 */ "mmmmmmtddddddds"
- /* 10 */ "mmmmmmtddddddds"
- /* 11 */ "mmmmmmtddddddds"
- /* 12 */ "mmmmmmtddddddds"
+ /* 1 */ "taaaaaaaaaaaaas"
+ /* 2 */ "taaaaaaaaaaaaas"
+ /* 3 */ "taaaaaaaaaaaaas"
+ /* 4 */ "taaaaaaaaaaaaas"
+ /* 5 */ "taaaaaaaaaaaaas"
+ /* 6 */ "taaaaaaaaaaaaas"
+ /* 7 */ "taaaaaaaaaaaaas"
+ /* 8 */ "tuuuuutaaaaaaas"
+ /* 9 */ "mmmmmmtaaaaaaas"
+ /* 10 */ "mmmmmmtaaaaaaas"
+ /* 11 */ "mmmmmmtaaaaaaas"
+ /* 12 */ "mmmmmmtaaaaaaas"
/* 13 */ "......tuuuuuuuu",
// Connectors:
- "-1: 4, 0, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 4, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1210,8 +1228,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 6, 5, 6, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 7, 5, 7, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
@@ -1320,8 +1338,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
14, 4, 16, // SizeX = 14, SizeY = 4, SizeZ = 16
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 13, 3, 15, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 14, 3, 16, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
diff --git a/src/Generating/Prefabs/SandVillagePrefabs.cpp b/src/Generating/Prefabs/SandVillagePrefabs.cpp
index a062f8cd4..72881a678 100644
--- a/src/Generating/Prefabs/SandVillagePrefabs.cpp
+++ b/src/Generating/Prefabs/SandVillagePrefabs.cpp
@@ -20,11 +20,11 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 5, ID 75, created by tonibm1999
{
// Size:
- 13, 2, 9, // SizeX = 13, SizeY = 2, SizeZ = 9
+ 13, 3, 9, // SizeX = 13, SizeY = 3, SizeZ = 9
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 12, 1, 8, // MaxX, MaxY, MaxZ
+ -1, 0, -1, // MinX, MinY, MinZ
+ 13, 2, 8, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
@@ -40,6 +40,19 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
/* z\x* 111 */
/* * 0123456789012 */
/* 0 */ "aaaaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaaaa"
+ /* 2 */ "aaaaaaaaaaaaa"
+ /* 3 */ "aaaaaaaaaaaaa"
+ /* 4 */ "aaaaaaaaaaaaa"
+ /* 5 */ "aaaaaaaaaaaaa"
+ /* 6 */ "aaaaaaaaaaaaa"
+ /* 7 */ "aaaaaaaaaaaaa"
+ /* 8 */ "aaaaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "aaaaaaaaaaaaa"
/* 1 */ "abbcbbabbcbba"
/* 2 */ "abbcbbabbcbba"
/* 3 */ "abbcbbabbcbba"
@@ -49,21 +62,21 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
/* 7 */ "abbcbbabbcbba"
/* 8 */ "aaaaaaaaaaaaa"
- // Level 1
+ // Level 2
/* z\x* 111 */
/* * 0123456789012 */
/* 0 */ "d.....d.....d"
- /* 1 */ ".......ee.ee."
- /* 2 */ ".......ee.ee."
- /* 3 */ ".......ee.ee."
- /* 4 */ ".......ee.ee."
- /* 5 */ ".......ee.ee."
- /* 6 */ ".......ee.ee."
- /* 7 */ ".......ee.ee."
+ /* 1 */ ".ee.ee.ee.ee."
+ /* 2 */ ".ee.ee.ee.ee."
+ /* 3 */ ".ee.ee.ee.ee."
+ /* 4 */ ".ee.ee.ee.ee."
+ /* 5 */ ".ee.ee.ee.ee."
+ /* 6 */ ".ee.ee.ee.ee."
+ /* 7 */ ".ee.ee.ee.ee."
/* 8 */ "d.....d.....d",
// Connectors:
- "-1: 6, 0, 8: 3\n" /* Type -1, direction Z+ */,
+ "-1: 6, 1, 8: 3\n" /* Type -1, direction Z+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -94,18 +107,18 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 6, ID 81, created by Aloe_vera
{
// Size:
- 11, 6, 7, // SizeX = 11, SizeY = 6, SizeZ = 7
+ 11, 7, 7, // SizeX = 11, SizeY = 7, SizeZ = 7
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 10, 5, 6, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 11, 6, 7, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a:128: 0\n" /* sandstonestairs */
- "b:128: 2\n" /* sandstonestairs */
- "c:128: 1\n" /* sandstonestairs */
- "d: 24: 0\n" /* sandstone */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
"e: 64: 7\n" /* wooddoorblock */
"f:102: 0\n" /* glasspane */
"g: 64:12\n" /* wooddoorblock */
@@ -122,71 +135,82 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// Level 0
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "....abc...."
- /* 1 */ ".ddddddddd."
- /* 2 */ ".ddddddddd."
- /* 3 */ ".ddddddddd."
- /* 4 */ ".ddddddddd."
- /* 5 */ ".ddddddddd."
- /* 6 */ "..........."
+ /* 0 */ "mmmmaaammmm"
+ /* 1 */ "maaaaaaaaam"
+ /* 2 */ "maaaaaaaaam"
+ /* 3 */ "maaaaaaaaam"
+ /* 4 */ "maaaaaaaaam"
+ /* 5 */ "maaaaaaaaam"
+ /* 6 */ "mmmmmmmmmmm"
// Level 1
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "..........."
- /* 1 */ ".ddddedddd."
- /* 2 */ ".d.......d."
- /* 3 */ ".d.......d."
- /* 4 */ ".d.......d."
- /* 5 */ ".ddddddddd."
+ /* 0 */ "....bcd...."
+ /* 1 */ ".aaaaaaaaa."
+ /* 2 */ ".aaaaaaaaa."
+ /* 3 */ ".aaaaaaaaa."
+ /* 4 */ ".aaaaaaaaa."
+ /* 5 */ ".aaaaaaaaa."
/* 6 */ "..........."
// Level 2
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
- /* 1 */ ".dffdgdffd."
+ /* 1 */ ".aaaaeaaaa."
+ /* 2 */ ".a.......a."
+ /* 3 */ ".a.......a."
+ /* 4 */ ".a.......a."
+ /* 5 */ ".aaaaaaaaa."
+ /* 6 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".affagaffa."
/* 2 */ ".f.......f."
/* 3 */ ".f.......f."
/* 4 */ ".f.......f."
- /* 5 */ ".dffdfdffd."
+ /* 5 */ ".affafaffa."
/* 6 */ "..........."
- // Level 3
+ // Level 4
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "bbbbbbbbbbb"
- /* 1 */ "hdddddddddh"
- /* 2 */ ".d..i.i..d."
- /* 3 */ ".d.......d."
- /* 4 */ ".d..j.j..d."
- /* 5 */ "kdddddddddk"
+ /* 0 */ "ccccccccccc"
+ /* 1 */ "haaaaaaaaah"
+ /* 2 */ ".a..i.i..a."
+ /* 3 */ ".a.......a."
+ /* 4 */ ".a..j.j..a."
+ /* 5 */ "kaaaaaaaaak"
/* 6 */ "lllllllllll"
- // Level 4
+ // Level 5
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
- /* 1 */ "bbbbbbbbbbb"
- /* 2 */ "hdddddddddh"
- /* 3 */ ".dn.....od."
- /* 4 */ "kdddddddddk"
+ /* 1 */ "ccccccccccc"
+ /* 2 */ "haaaaaaaaah"
+ /* 3 */ ".an.....oa."
+ /* 4 */ "kaaaaaaaaak"
/* 5 */ "lllllllllll"
/* 6 */ "..........."
- // Level 5
+ // Level 6
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
/* 1 */ "..........."
- /* 2 */ "bbbbbbbbbbb"
- /* 3 */ "ddddddddddd"
+ /* 2 */ "ccccccccccc"
+ /* 3 */ "aaaaaaaaaaa"
/* 4 */ "lllllllllll"
/* 5 */ "..........."
/* 6 */ "...........",
// Connectors:
- "-1: 5, 0, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -217,18 +241,18 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 11, ID 115, created by xoft
{
// Size:
- 11, 7, 9, // SizeX = 11, SizeY = 7, SizeZ = 9
+ 11, 8, 9, // SizeX = 11, SizeY = 8, SizeZ = 9
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 10, 6, 8, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 11, 7, 9, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a:128: 0\n" /* sandstonestairs */
- "b:128: 2\n" /* sandstonestairs */
- "c:128: 1\n" /* sandstonestairs */
- "d: 24: 0\n" /* sandstone */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
"e: 64: 7\n" /* wooddoorblock */
"f:102: 0\n" /* glasspane */
"g: 64:12\n" /* wooddoorblock */
@@ -243,96 +267,109 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// Level 0
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "....abc...."
- /* 1 */ ".ddddddddd."
- /* 2 */ ".ddddddddd."
- /* 3 */ ".ddddddddd."
- /* 4 */ ".ddddddddd."
- /* 5 */ ".ddddddddd."
- /* 6 */ ".ddddddddd."
- /* 7 */ ".ddddddddd."
- /* 8 */ "..........."
+ /* 0 */ "mmmmaaammmm"
+ /* 1 */ "maaaaaaaaam"
+ /* 2 */ "maaaaaaaaam"
+ /* 3 */ "maaaaaaaaam"
+ /* 4 */ "maaaaaaaaam"
+ /* 5 */ "maaaaaaaaam"
+ /* 6 */ "maaaaaaaaam"
+ /* 7 */ "maaaaaaaaam"
+ /* 8 */ "mmmmmmmmmmm"
// Level 1
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "..........."
- /* 1 */ ".ddddedddd."
- /* 2 */ ".d.......d."
- /* 3 */ ".d.......d."
- /* 4 */ ".d.......d."
- /* 5 */ ".d.......d."
- /* 6 */ ".d.......d."
- /* 7 */ ".ddddddddd."
+ /* 0 */ "....bcd...."
+ /* 1 */ ".aaaaaaaaa."
+ /* 2 */ ".aaaaaaaaa."
+ /* 3 */ ".aaaaaaaaa."
+ /* 4 */ ".aaaaaaaaa."
+ /* 5 */ ".aaaaaaaaa."
+ /* 6 */ ".aaaaaaaaa."
+ /* 7 */ ".aaaaaaaaa."
/* 8 */ "..........."
// Level 2
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
- /* 1 */ ".dffdgdffd."
+ /* 1 */ ".aaaaeaaaa."
+ /* 2 */ ".a.......a."
+ /* 3 */ ".a.......a."
+ /* 4 */ ".a.......a."
+ /* 5 */ ".a.......a."
+ /* 6 */ ".a.......a."
+ /* 7 */ ".aaaaaaaaa."
+ /* 8 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".affagaffa."
/* 2 */ ".f.......f."
/* 3 */ ".f.......f."
- /* 4 */ ".d.......d."
+ /* 4 */ ".a.......a."
/* 5 */ ".f.......f."
/* 6 */ ".f.......f."
- /* 7 */ ".dfffdfffd."
+ /* 7 */ ".afffafffa."
/* 8 */ "..........."
- // Level 3
+ // Level 4
/* z\x* 1 */
/* * 01234567890 */
- /* 0 */ "bbbbbbbbbbb"
- /* 1 */ "hdddddddddh"
- /* 2 */ ".d..i.i..d."
- /* 3 */ ".d.......d."
- /* 4 */ ".d.......d."
- /* 5 */ ".d.......d."
- /* 6 */ ".d...j...d."
- /* 7 */ "kdddddddddk"
+ /* 0 */ "ccccccccccc"
+ /* 1 */ "haaaaaaaaah"
+ /* 2 */ ".a..i.i..a."
+ /* 3 */ ".a.......a."
+ /* 4 */ ".a.......a."
+ /* 5 */ ".a.......a."
+ /* 6 */ ".a...j...a."
+ /* 7 */ "kaaaaaaaaak"
/* 8 */ "lllllllllll"
- // Level 4
+ // Level 5
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
- /* 1 */ "bbbbbbbbbbb"
- /* 2 */ "hdddddddddh"
- /* 3 */ ".d.......d."
- /* 4 */ ".d.......d."
- /* 5 */ ".d.......d."
- /* 6 */ "kdddddddddk"
+ /* 1 */ "ccccccccccc"
+ /* 2 */ "haaaaaaaaah"
+ /* 3 */ ".a.......a."
+ /* 4 */ ".a.......a."
+ /* 5 */ ".a.......a."
+ /* 6 */ "kaaaaaaaaak"
/* 7 */ "lllllllllll"
/* 8 */ "..........."
- // Level 5
+ // Level 6
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
/* 1 */ "..........."
- /* 2 */ "bbbbbbbbbbb"
- /* 3 */ "hdddddddddh"
- /* 4 */ ".d.......d."
- /* 5 */ "kdddddddddk"
+ /* 2 */ "ccccccccccc"
+ /* 3 */ "haaaaaaaaah"
+ /* 4 */ ".a.......a."
+ /* 5 */ "kaaaaaaaaak"
/* 6 */ "lllllllllll"
/* 7 */ "..........."
/* 8 */ "..........."
- // Level 6
+ // Level 7
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
/* 1 */ "..........."
/* 2 */ "..........."
- /* 3 */ "bbbbbbbbbbb"
- /* 4 */ "ddddddddddd"
+ /* 3 */ "ccccccccccc"
+ /* 4 */ "aaaaaaaaaaa"
/* 5 */ "lllllllllll"
/* 6 */ "..........."
/* 7 */ "..........."
/* 8 */ "...........",
// Connectors:
- "-1: 5, 0, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -363,18 +400,18 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 15, ID 125, created by Aloe_vera
{
// Size:
- 13, 6, 7, // SizeX = 13, SizeY = 6, SizeZ = 7
+ 13, 7, 7, // SizeX = 13, SizeY = 7, SizeZ = 7
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 12, 5, 6, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 13, 6, 7, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a:128: 0\n" /* sandstonestairs */
- "b:128: 2\n" /* sandstonestairs */
- "c:128: 1\n" /* sandstonestairs */
- "d: 24: 0\n" /* sandstone */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
"e: 64: 7\n" /* wooddoorblock */
"f:102: 0\n" /* glasspane */
"g: 64:12\n" /* wooddoorblock */
@@ -389,71 +426,82 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// Level 0
/* z\x* 111 */
/* * 0123456789012 */
- /* 0 */ ".....abc....."
- /* 1 */ ".ddddddddddd."
- /* 2 */ ".ddddddddddd."
- /* 3 */ ".ddddddddddd."
- /* 4 */ ".ddddddddddd."
- /* 5 */ ".ddddddddddd."
- /* 6 */ "............."
+ /* 0 */ "mmmmmaaammmmm"
+ /* 1 */ "maaaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaaam"
+ /* 6 */ "mmmmmmmmmmmmm"
// Level 1
/* z\x* 111 */
/* * 0123456789012 */
- /* 0 */ "............."
- /* 1 */ ".dddddeddddd."
- /* 2 */ ".d.........d."
- /* 3 */ ".d.........d."
- /* 4 */ ".d.........d."
- /* 5 */ ".ddddddddddd."
+ /* 0 */ ".....bcd....."
+ /* 1 */ ".aaaaaaaaaaa."
+ /* 2 */ ".aaaaaaaaaaa."
+ /* 3 */ ".aaaaaaaaaaa."
+ /* 4 */ ".aaaaaaaaaaa."
+ /* 5 */ ".aaaaaaaaaaa."
/* 6 */ "............."
// Level 2
/* z\x* 111 */
/* * 0123456789012 */
/* 0 */ "............."
- /* 1 */ ".dfffdgdfffd."
+ /* 1 */ ".aaaaaeaaaaa."
+ /* 2 */ ".a.........a."
+ /* 3 */ ".a.........a."
+ /* 4 */ ".a.........a."
+ /* 5 */ ".aaaaaaaaaaa."
+ /* 6 */ "............."
+
+ // Level 3
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ ".afffagafffa."
/* 2 */ ".f.........f."
/* 3 */ ".f.........f."
/* 4 */ ".f.........f."
- /* 5 */ ".dffdfffdffd."
+ /* 5 */ ".affafffaffa."
/* 6 */ "............."
- // Level 3
+ // Level 4
/* z\x* 111 */
/* * 0123456789012 */
- /* 0 */ "bbbbbbbbbbbbb"
- /* 1 */ "hdddddddddddh"
- /* 2 */ ".d...i.i...d."
- /* 3 */ ".d.........d."
- /* 4 */ ".d..j...j..d."
- /* 5 */ "kdddddddddddk"
+ /* 0 */ "ccccccccccccc"
+ /* 1 */ "haaaaaaaaaaah"
+ /* 2 */ ".a...i.i...a."
+ /* 3 */ ".a.........a."
+ /* 4 */ ".a..j...j..a."
+ /* 5 */ "kaaaaaaaaaaak"
/* 6 */ "lllllllllllll"
- // Level 4
+ // Level 5
/* z\x* 111 */
/* * 0123456789012 */
/* 0 */ "............."
- /* 1 */ "bbbbbbbbbbbbb"
- /* 2 */ "hdddddddddddh"
- /* 3 */ ".d.........d."
- /* 4 */ "kdddddddddddk"
+ /* 1 */ "ccccccccccccc"
+ /* 2 */ "haaaaaaaaaaah"
+ /* 3 */ ".a.........a."
+ /* 4 */ "kaaaaaaaaaaak"
/* 5 */ "lllllllllllll"
/* 6 */ "............."
- // Level 5
+ // Level 6
/* z\x* 111 */
/* * 0123456789012 */
/* 0 */ "............."
/* 1 */ "............."
- /* 2 */ "bbbbbbbbbbbbb"
- /* 3 */ "ddddddddddddd"
+ /* 2 */ "ccccccccccccc"
+ /* 3 */ "aaaaaaaaaaaaa"
/* 4 */ "lllllllllllll"
/* 5 */ "............."
/* 6 */ ".............",
// Connectors:
- "-1: 6, 0, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -484,18 +532,18 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 12, ID 116, created by xoft
{
// Size:
- 13, 7, 9, // SizeX = 13, SizeY = 7, SizeZ = 9
+ 13, 8, 9, // SizeX = 13, SizeY = 8, SizeZ = 9
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 12, 6, 8, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 13, 7, 9, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a:128: 0\n" /* sandstonestairs */
- "b:128: 2\n" /* sandstonestairs */
- "c:128: 1\n" /* sandstonestairs */
- "d: 24: 0\n" /* sandstone */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
"e: 64: 7\n" /* wooddoorblock */
"f:102: 0\n" /* glasspane */
"g: 64:12\n" /* wooddoorblock */
@@ -510,96 +558,109 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// Level 0
/* z\x* 111 */
/* * 0123456789012 */
- /* 0 */ ".....abc....."
- /* 1 */ ".ddddddddddd."
- /* 2 */ ".ddddddddddd."
- /* 3 */ ".ddddddddddd."
- /* 4 */ ".ddddddddddd."
- /* 5 */ ".ddddddddddd."
- /* 6 */ ".ddddddddddd."
- /* 7 */ ".ddddddddddd."
- /* 8 */ "............."
+ /* 0 */ "mmmmmaaammmmm"
+ /* 1 */ "maaaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaaam"
+ /* 6 */ "maaaaaaaaaaam"
+ /* 7 */ "maaaaaaaaaaam"
+ /* 8 */ "mmmmmmmmmmmmm"
// Level 1
/* z\x* 111 */
/* * 0123456789012 */
- /* 0 */ "............."
- /* 1 */ ".dddddeddddd."
- /* 2 */ ".d.........d."
- /* 3 */ ".d.........d."
- /* 4 */ ".d.........d."
- /* 5 */ ".d.........d."
- /* 6 */ ".d.........d."
- /* 7 */ ".ddddddddddd."
+ /* 0 */ ".....bcd....."
+ /* 1 */ ".aaaaaaaaaaa."
+ /* 2 */ ".aaaaaaaaaaa."
+ /* 3 */ ".aaaaaaaaaaa."
+ /* 4 */ ".aaaaaaaaaaa."
+ /* 5 */ ".aaaaaaaaaaa."
+ /* 6 */ ".aaaaaaaaaaa."
+ /* 7 */ ".aaaaaaaaaaa."
/* 8 */ "............."
// Level 2
/* z\x* 111 */
/* * 0123456789012 */
/* 0 */ "............."
- /* 1 */ ".dfffdgdfffd."
+ /* 1 */ ".aaaaaeaaaaa."
+ /* 2 */ ".a.........a."
+ /* 3 */ ".a.........a."
+ /* 4 */ ".a.........a."
+ /* 5 */ ".a.........a."
+ /* 6 */ ".a.........a."
+ /* 7 */ ".aaaaaaaaaaa."
+ /* 8 */ "............."
+
+ // Level 3
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ ".afffagafffa."
/* 2 */ ".f.........f."
/* 3 */ ".f.........f."
- /* 4 */ ".d.........d."
+ /* 4 */ ".a.........a."
/* 5 */ ".f.........f."
/* 6 */ ".f.........f."
- /* 7 */ ".dffdffdfffd."
+ /* 7 */ ".affaffafffa."
/* 8 */ "............."
- // Level 3
+ // Level 4
/* z\x* 111 */
/* * 0123456789012 */
- /* 0 */ "bbbbbbbbbbbbb"
- /* 1 */ "hdddddddddddh"
- /* 2 */ ".d...i.i...d."
- /* 3 */ ".d.........d."
- /* 4 */ ".d.........d."
- /* 5 */ ".d.........d."
- /* 6 */ ".d..j..j...d."
- /* 7 */ "kdddddddddddk"
+ /* 0 */ "ccccccccccccc"
+ /* 1 */ "haaaaaaaaaaah"
+ /* 2 */ ".a...i.i...a."
+ /* 3 */ ".a.........a."
+ /* 4 */ ".a.........a."
+ /* 5 */ ".a.........a."
+ /* 6 */ ".a..j..j...a."
+ /* 7 */ "kaaaaaaaaaaak"
/* 8 */ "lllllllllllll"
- // Level 4
+ // Level 5
/* z\x* 111 */
/* * 0123456789012 */
/* 0 */ "............."
- /* 1 */ "bbbbbbbbbbbbb"
- /* 2 */ "hdddddddddddh"
- /* 3 */ ".d.........d."
- /* 4 */ ".d.........d."
- /* 5 */ ".d.........d."
- /* 6 */ "kdddddddddddk"
+ /* 1 */ "ccccccccccccc"
+ /* 2 */ "haaaaaaaaaaah"
+ /* 3 */ ".a.........a."
+ /* 4 */ ".a.........a."
+ /* 5 */ ".a.........a."
+ /* 6 */ "kaaaaaaaaaaak"
/* 7 */ "lllllllllllll"
/* 8 */ "............."
- // Level 5
+ // Level 6
/* z\x* 111 */
/* * 0123456789012 */
/* 0 */ "............."
/* 1 */ "............."
- /* 2 */ "bbbbbbbbbbbbb"
- /* 3 */ "hdddddddddddh"
- /* 4 */ ".d.........d."
- /* 5 */ "kdddddddddddk"
+ /* 2 */ "ccccccccccccc"
+ /* 3 */ "haaaaaaaaaaah"
+ /* 4 */ ".a.........a."
+ /* 5 */ "kaaaaaaaaaaak"
/* 6 */ "lllllllllllll"
/* 7 */ "............."
/* 8 */ "............."
- // Level 6
+ // Level 7
/* z\x* 111 */
/* * 0123456789012 */
/* 0 */ "............."
/* 1 */ "............."
/* 2 */ "............."
- /* 3 */ "bbbbbbbbbbbbb"
- /* 4 */ "ddddddddddddd"
+ /* 3 */ "ccccccccccccc"
+ /* 4 */ "aaaaaaaaaaaaa"
/* 5 */ "lllllllllllll"
/* 6 */ "............."
/* 7 */ "............."
/* 8 */ ".............",
// Connectors:
- "-1: 6, 0, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -630,18 +691,18 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 13, ID 118, created by xoft
{
// Size:
- 15, 7, 9, // SizeX = 15, SizeY = 7, SizeZ = 9
+ 15, 8, 9, // SizeX = 15, SizeY = 8, SizeZ = 9
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 14, 6, 8, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 15, 7, 9, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a:128: 0\n" /* sandstonestairs */
- "b:128: 2\n" /* sandstonestairs */
- "c:128: 1\n" /* sandstonestairs */
- "d: 24: 0\n" /* sandstone */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
"e: 64: 7\n" /* wooddoorblock */
"f:102: 0\n" /* glasspane */
"g: 64:12\n" /* wooddoorblock */
@@ -656,96 +717,109 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// Level 0
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ ".....abc......."
- /* 1 */ ".ddddddddddddd."
- /* 2 */ ".ddddddddddddd."
- /* 3 */ ".ddddddddddddd."
- /* 4 */ ".ddddddddddddd."
- /* 5 */ ".ddddddddddddd."
- /* 6 */ ".ddddddddddddd."
- /* 7 */ ".ddddddddddddd."
- /* 8 */ "..............."
+ /* 0 */ "mmmmmaaammmmmmm"
+ /* 1 */ "maaaaaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaaaaam"
+ /* 6 */ "maaaaaaaaaaaaam"
+ /* 7 */ "maaaaaaaaaaaaam"
+ /* 8 */ "mmmmmmmmmmmmmmm"
// Level 1
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "..............."
- /* 1 */ ".dddddeddddddd."
- /* 2 */ ".d...........d."
- /* 3 */ ".d...........d."
- /* 4 */ ".d...........d."
- /* 5 */ ".d...........d."
- /* 6 */ ".d...........d."
- /* 7 */ ".ddddddddddddd."
+ /* 0 */ ".....bcd......."
+ /* 1 */ ".aaaaaaaaaaaaa."
+ /* 2 */ ".aaaaaaaaaaaaa."
+ /* 3 */ ".aaaaaaaaaaaaa."
+ /* 4 */ ".aaaaaaaaaaaaa."
+ /* 5 */ ".aaaaaaaaaaaaa."
+ /* 6 */ ".aaaaaaaaaaaaa."
+ /* 7 */ ".aaaaaaaaaaaaa."
/* 8 */ "..............."
// Level 2
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
- /* 1 */ ".dfffdgdffdffd."
+ /* 1 */ ".aaaaaeaaaaaaa."
+ /* 2 */ ".a...........a."
+ /* 3 */ ".a...........a."
+ /* 4 */ ".a...........a."
+ /* 5 */ ".a...........a."
+ /* 6 */ ".a...........a."
+ /* 7 */ ".aaaaaaaaaaaaa."
+ /* 8 */ "..............."
+
+ // Level 3
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".afffagaffaffa."
/* 2 */ ".f...........f."
/* 3 */ ".f...........f."
- /* 4 */ ".d...........d."
+ /* 4 */ ".a...........a."
/* 5 */ ".f...........f."
/* 6 */ ".f...........f."
- /* 7 */ ".dffdffdffdffd."
+ /* 7 */ ".affaffaffaffa."
/* 8 */ "..............."
- // Level 3
+ // Level 4
/* z\x* 11111 */
/* * 012345678901234 */
- /* 0 */ "bbbbbbbbbbbbbbb"
- /* 1 */ "hdddddddddddddh"
- /* 2 */ ".d...i.i..i..d."
- /* 3 */ ".d...........d."
- /* 4 */ ".d...........d."
- /* 5 */ ".d...........d."
- /* 6 */ ".d..j..j..j..d."
- /* 7 */ "kdddddddddddddk"
+ /* 0 */ "ccccccccccccccc"
+ /* 1 */ "haaaaaaaaaaaaah"
+ /* 2 */ ".a...i.i..i..a."
+ /* 3 */ ".a...........a."
+ /* 4 */ ".a...........a."
+ /* 5 */ ".a...........a."
+ /* 6 */ ".a..j..j..j..a."
+ /* 7 */ "kaaaaaaaaaaaaak"
/* 8 */ "lllllllllllllll"
- // Level 4
+ // Level 5
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
- /* 1 */ "bbbbbbbbbbbbbbb"
- /* 2 */ "hdddddddddddddh"
- /* 3 */ ".d...........d."
- /* 4 */ ".d...........d."
- /* 5 */ ".d...........d."
- /* 6 */ "kdddddddddddddk"
+ /* 1 */ "ccccccccccccccc"
+ /* 2 */ "haaaaaaaaaaaaah"
+ /* 3 */ ".a...........a."
+ /* 4 */ ".a...........a."
+ /* 5 */ ".a...........a."
+ /* 6 */ "kaaaaaaaaaaaaak"
/* 7 */ "lllllllllllllll"
/* 8 */ "..............."
- // Level 5
+ // Level 6
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
/* 1 */ "..............."
- /* 2 */ "bbbbbbbbbbbbbbb"
- /* 3 */ "hdddddddddddddh"
- /* 4 */ ".d...........d."
- /* 5 */ "kdddddddddddddk"
+ /* 2 */ "ccccccccccccccc"
+ /* 3 */ "haaaaaaaaaaaaah"
+ /* 4 */ ".a...........a."
+ /* 5 */ "kaaaaaaaaaaaaak"
/* 6 */ "lllllllllllllll"
/* 7 */ "..............."
/* 8 */ "..............."
- // Level 6
+ // Level 7
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
/* 1 */ "..............."
/* 2 */ "..............."
- /* 3 */ "bbbbbbbbbbbbbbb"
- /* 4 */ "ddddddddddddddd"
+ /* 3 */ "ccccccccccccccc"
+ /* 4 */ "aaaaaaaaaaaaaaa"
/* 5 */ "lllllllllllllll"
/* 6 */ "..............."
/* 7 */ "..............."
/* 8 */ "...............",
// Connectors:
- "-1: 6, 0, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -776,18 +850,18 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 16, ID 126, created by Aloe_vera
{
// Size:
- 16, 7, 9, // SizeX = 16, SizeY = 7, SizeZ = 9
+ 16, 8, 9, // SizeX = 16, SizeY = 8, SizeZ = 9
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 15, 6, 8, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 16, 7, 9, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a:128: 0\n" /* sandstonestairs */
- "b:128: 2\n" /* sandstonestairs */
- "c:128: 1\n" /* sandstonestairs */
- "d: 24: 0\n" /* sandstone */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
"e: 64: 7\n" /* wooddoorblock */
"f:102: 0\n" /* glasspane */
"g: 64:12\n" /* wooddoorblock */
@@ -802,96 +876,109 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// Level 0
/* z\x* 111111 */
/* * 0123456789012345 */
- /* 0 */ "........abc....."
- /* 1 */ ".dddddddddddddd."
- /* 2 */ ".dddddddddddddd."
- /* 3 */ ".dddddddddddddd."
- /* 4 */ ".dddddddddddddd."
- /* 5 */ ".dddddddddddddd."
- /* 6 */ ".dddddddddddddd."
- /* 7 */ ".dddddddddddddd."
- /* 8 */ "................"
+ /* 0 */ "mmmmmmmmaaammmmm"
+ /* 1 */ "maaaaaaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaaaaaam"
+ /* 6 */ "maaaaaaaaaaaaaam"
+ /* 7 */ "maaaaaaaaaaaaaam"
+ /* 8 */ "mmmmmmmmmmmmmmmm"
// Level 1
/* z\x* 111111 */
/* * 0123456789012345 */
- /* 0 */ "................"
- /* 1 */ ".ddddddddeddddd."
- /* 2 */ ".d............d."
- /* 3 */ ".d............d."
- /* 4 */ ".d............d."
- /* 5 */ ".d............d."
- /* 6 */ ".d............d."
- /* 7 */ ".dddddddddddddd."
+ /* 0 */ "........bcd....."
+ /* 1 */ ".aaaaaaaaaaaaaa."
+ /* 2 */ ".aaaaaaaaaaaaaa."
+ /* 3 */ ".aaaaaaaaaaaaaa."
+ /* 4 */ ".aaaaaaaaaaaaaa."
+ /* 5 */ ".aaaaaaaaaaaaaa."
+ /* 6 */ ".aaaaaaaaaaaaaa."
+ /* 7 */ ".aaaaaaaaaaaaaa."
/* 8 */ "................"
// Level 2
/* z\x* 111111 */
/* * 0123456789012345 */
/* 0 */ "................"
- /* 1 */ ".dffdfffdgdfffd."
+ /* 1 */ ".aaaaaaaaeaaaaa."
+ /* 2 */ ".a............a."
+ /* 3 */ ".a............a."
+ /* 4 */ ".a............a."
+ /* 5 */ ".a............a."
+ /* 6 */ ".a............a."
+ /* 7 */ ".aaaaaaaaaaaaaa."
+ /* 8 */ "................"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ ".affafffagafffa."
/* 2 */ ".f............f."
/* 3 */ ".f............f."
- /* 4 */ ".d............d."
+ /* 4 */ ".a............a."
/* 5 */ ".f............f."
/* 6 */ ".f............f."
- /* 7 */ ".dffdffdfffdffd."
+ /* 7 */ ".affaffafffaffa."
/* 8 */ "................"
- // Level 3
+ // Level 4
/* z\x* 111111 */
/* * 0123456789012345 */
- /* 0 */ "bbbbbbbbbbbbbbbb"
- /* 1 */ "hddddddddddddddh"
- /* 2 */ ".d..i...i.i...d."
- /* 3 */ ".d............d."
- /* 4 */ ".d............d."
- /* 5 */ ".d............d."
- /* 6 */ ".d..j..j...j..d."
- /* 7 */ "kddddddddddddddk"
+ /* 0 */ "cccccccccccccccc"
+ /* 1 */ "haaaaaaaaaaaaaah"
+ /* 2 */ ".a..i...i.i...a."
+ /* 3 */ ".a............a."
+ /* 4 */ ".a............a."
+ /* 5 */ ".a............a."
+ /* 6 */ ".a..j..j...j..a."
+ /* 7 */ "kaaaaaaaaaaaaaak"
/* 8 */ "llllllllllllllll"
- // Level 4
+ // Level 5
/* z\x* 111111 */
/* * 0123456789012345 */
/* 0 */ "................"
- /* 1 */ "bbbbbbbbbbbbbbbb"
- /* 2 */ "hddddddddddddddh"
- /* 3 */ ".d............d."
- /* 4 */ ".d............d."
- /* 5 */ ".d............d."
- /* 6 */ "kddddddddddddddk"
+ /* 1 */ "cccccccccccccccc"
+ /* 2 */ "haaaaaaaaaaaaaah"
+ /* 3 */ ".a............a."
+ /* 4 */ ".a............a."
+ /* 5 */ ".a............a."
+ /* 6 */ "kaaaaaaaaaaaaaak"
/* 7 */ "llllllllllllllll"
/* 8 */ "................"
- // Level 5
+ // Level 6
/* z\x* 111111 */
/* * 0123456789012345 */
/* 0 */ "................"
/* 1 */ "................"
- /* 2 */ "bbbbbbbbbbbbbbbb"
- /* 3 */ "hddddddddddddddh"
- /* 4 */ ".d............d."
- /* 5 */ "kddddddddddddddk"
+ /* 2 */ "cccccccccccccccc"
+ /* 3 */ "haaaaaaaaaaaaaah"
+ /* 4 */ ".a............a."
+ /* 5 */ "kaaaaaaaaaaaaaak"
/* 6 */ "llllllllllllllll"
/* 7 */ "................"
/* 8 */ "................"
- // Level 6
+ // Level 7
/* z\x* 111111 */
/* * 0123456789012345 */
/* 0 */ "................"
/* 1 */ "................"
/* 2 */ "................"
- /* 3 */ "bbbbbbbbbbbbbbbb"
- /* 4 */ "dddddddddddddddd"
+ /* 3 */ "cccccccccccccccc"
+ /* 4 */ "aaaaaaaaaaaaaaaa"
/* 5 */ "llllllllllllllll"
/* 6 */ "................"
/* 7 */ "................"
/* 8 */ "................",
// Connectors:
- "-1: 9, 0, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 9, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -922,18 +1009,18 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 8, ID 112, created by Aloe_vera
{
// Size:
- 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7
+ 7, 7, 7, // SizeX = 7, SizeY = 7, SizeZ = 7
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 6, 5, 6, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 7, 6, 7, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a:128: 0\n" /* sandstonestairs */
- "b:128: 2\n" /* sandstonestairs */
- "c:128: 1\n" /* sandstonestairs */
- "d: 24: 0\n" /* sandstone */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
"e: 64: 7\n" /* wooddoorblock */
"f:102: 0\n" /* glasspane */
"g: 64:12\n" /* wooddoorblock */
@@ -946,66 +1033,76 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// Block data:
// Level 0
/* z\x* 0123456 */
- /* 0 */ "...abc."
- /* 1 */ ".ddddd."
- /* 2 */ ".ddddd."
- /* 3 */ ".ddddd."
- /* 4 */ ".ddddd."
- /* 5 */ ".ddddd."
- /* 6 */ "......."
+ /* 0 */ "mmmaaam"
+ /* 1 */ "maaaaam"
+ /* 2 */ "maaaaam"
+ /* 3 */ "maaaaam"
+ /* 4 */ "maaaaam"
+ /* 5 */ "maaaaam"
+ /* 6 */ "mmmmmmm"
// Level 1
/* z\x* 0123456 */
- /* 0 */ "......."
- /* 1 */ ".ddded."
- /* 2 */ ".d...d."
- /* 3 */ ".d...d."
- /* 4 */ ".d...d."
- /* 5 */ ".ddddd."
+ /* 0 */ "...bcd."
+ /* 1 */ ".aaaaa."
+ /* 2 */ ".aaaaa."
+ /* 3 */ ".aaaaa."
+ /* 4 */ ".aaaaa."
+ /* 5 */ ".aaaaa."
/* 6 */ "......."
// Level 2
/* z\x* 0123456 */
/* 0 */ "......."
- /* 1 */ ".dfdgd."
+ /* 1 */ ".aaaea."
+ /* 2 */ ".a...a."
+ /* 3 */ ".a...a."
+ /* 4 */ ".a...a."
+ /* 5 */ ".aaaaa."
+ /* 6 */ "......."
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".afaga."
/* 2 */ ".f...f."
/* 3 */ ".f...f."
/* 4 */ ".f...f."
- /* 5 */ ".dfffd."
+ /* 5 */ ".afffa."
/* 6 */ "......."
- // Level 3
+ // Level 4
/* z\x* 0123456 */
- /* 0 */ "bbbbbbb"
- /* 1 */ "hdddddh"
- /* 2 */ ".d.i.d."
- /* 3 */ ".d...d."
- /* 4 */ ".d...d."
- /* 5 */ "jdddddj"
+ /* 0 */ "ccccccc"
+ /* 1 */ "haaaaah"
+ /* 2 */ ".a.i.a."
+ /* 3 */ ".a...a."
+ /* 4 */ ".a...a."
+ /* 5 */ "jaaaaaj"
/* 6 */ "kkkkkkk"
- // Level 4
+ // Level 5
/* z\x* 0123456 */
/* 0 */ "......."
- /* 1 */ "bbbbbbb"
- /* 2 */ "hdddddh"
- /* 3 */ ".d...d."
- /* 4 */ "jdddddj"
+ /* 1 */ "ccccccc"
+ /* 2 */ "haaaaah"
+ /* 3 */ ".a...a."
+ /* 4 */ "jaaaaaj"
/* 5 */ "kkkkkkk"
/* 6 */ "......."
- // Level 5
+ // Level 6
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ "......."
- /* 2 */ "bbbbbbb"
- /* 3 */ "ddddddd"
+ /* 2 */ "ccccccc"
+ /* 3 */ "aaaaaaa"
/* 4 */ "kkkkkkk"
/* 5 */ "......."
/* 6 */ ".......",
// Connectors:
- "-1: 4, 0, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 4, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1036,18 +1133,18 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 9, ID 113, created by xoft
{
// Size:
- 9, 6, 7, // SizeX = 9, SizeY = 6, SizeZ = 7
+ 9, 7, 7, // SizeX = 9, SizeY = 7, SizeZ = 7
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 8, 5, 6, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 9, 6, 7, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a:128: 0\n" /* sandstonestairs */
- "b:128: 2\n" /* sandstonestairs */
- "c:128: 1\n" /* sandstonestairs */
- "d: 24: 0\n" /* sandstone */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
"e: 64: 7\n" /* wooddoorblock */
"f:102: 0\n" /* glasspane */
"g: 64:12\n" /* wooddoorblock */
@@ -1061,66 +1158,76 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// Block data:
// Level 0
/* z\x* 012345678 */
- /* 0 */ "...abc..."
- /* 1 */ ".ddddddd."
- /* 2 */ ".ddddddd."
- /* 3 */ ".ddddddd."
- /* 4 */ ".ddddddd."
- /* 5 */ ".ddddddd."
- /* 6 */ "........."
+ /* 0 */ "mmmaaammm"
+ /* 1 */ "maaaaaaam"
+ /* 2 */ "maaaaaaam"
+ /* 3 */ "maaaaaaam"
+ /* 4 */ "maaaaaaam"
+ /* 5 */ "maaaaaaam"
+ /* 6 */ "mmmmmmmmm"
// Level 1
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ ".dddeddd."
- /* 2 */ ".d.....d."
- /* 3 */ ".d.....d."
- /* 4 */ ".d.....d."
- /* 5 */ ".ddddddd."
+ /* 0 */ "...bcd..."
+ /* 1 */ ".aaaaaaa."
+ /* 2 */ ".aaaaaaa."
+ /* 3 */ ".aaaaaaa."
+ /* 4 */ ".aaaaaaa."
+ /* 5 */ ".aaaaaaa."
/* 6 */ "........."
// Level 2
/* z\x* 012345678 */
/* 0 */ "........."
- /* 1 */ ".dfdgdfd."
+ /* 1 */ ".aaaeaaa."
+ /* 2 */ ".a.....a."
+ /* 3 */ ".a.....a."
+ /* 4 */ ".a.....a."
+ /* 5 */ ".aaaaaaa."
+ /* 6 */ "........."
+
+ // Level 3
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ ".afagafa."
/* 2 */ ".f.....f."
/* 3 */ ".f.....f."
/* 4 */ ".f.....f."
- /* 5 */ ".dffdffd."
+ /* 5 */ ".affaffa."
/* 6 */ "........."
- // Level 3
+ // Level 4
/* z\x* 012345678 */
- /* 0 */ "bbbbbbbbb"
- /* 1 */ "hdddddddh"
- /* 2 */ ".d.i.i.d."
- /* 3 */ ".d.....d."
- /* 4 */ ".d..j..d."
- /* 5 */ "kdddddddk"
+ /* 0 */ "ccccccccc"
+ /* 1 */ "haaaaaaah"
+ /* 2 */ ".a.i.i.a."
+ /* 3 */ ".a.....a."
+ /* 4 */ ".a..j..a."
+ /* 5 */ "kaaaaaaak"
/* 6 */ "lllllllll"
- // Level 4
+ // Level 5
/* z\x* 012345678 */
/* 0 */ "........."
- /* 1 */ "bbbbbbbbb"
- /* 2 */ "hdddddddh"
- /* 3 */ ".d.....d."
- /* 4 */ "kdddddddk"
+ /* 1 */ "ccccccccc"
+ /* 2 */ "haaaaaaah"
+ /* 3 */ ".a.....a."
+ /* 4 */ "kaaaaaaak"
/* 5 */ "lllllllll"
/* 6 */ "........."
- // Level 5
+ // Level 6
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
- /* 2 */ "bbbbbbbbb"
- /* 3 */ "ddddddddd"
+ /* 2 */ "ccccccccc"
+ /* 3 */ "aaaaaaaaa"
/* 4 */ "lllllllll"
/* 5 */ "........."
/* 6 */ ".........",
// Connectors:
- "-1: 4, 0, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 4, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1151,18 +1258,18 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 10, ID 114, created by xoft
{
// Size:
- 9, 7, 9, // SizeX = 9, SizeY = 7, SizeZ = 9
+ 9, 8, 9, // SizeX = 9, SizeY = 8, SizeZ = 9
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 8, 6, 8, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 9, 7, 9, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a:128: 0\n" /* sandstonestairs */
- "b:128: 2\n" /* sandstonestairs */
- "c:128: 1\n" /* sandstonestairs */
- "d: 24: 0\n" /* sandstone */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
"e: 64: 7\n" /* wooddoorblock */
"f:102: 0\n" /* glasspane */
"g: 64:12\n" /* wooddoorblock */
@@ -1176,90 +1283,102 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// Block data:
// Level 0
/* z\x* 012345678 */
- /* 0 */ "...abc..."
- /* 1 */ ".ddddddd."
- /* 2 */ ".ddddddd."
- /* 3 */ ".ddddddd."
- /* 4 */ ".ddddddd."
- /* 5 */ ".ddddddd."
- /* 6 */ ".ddddddd."
- /* 7 */ ".ddddddd."
- /* 8 */ "........."
+ /* 0 */ "mmmaaammm"
+ /* 1 */ "maaaaaaam"
+ /* 2 */ "maaaaaaam"
+ /* 3 */ "maaaaaaam"
+ /* 4 */ "maaaaaaam"
+ /* 5 */ "maaaaaaam"
+ /* 6 */ "maaaaaaam"
+ /* 7 */ "maaaaaaam"
+ /* 8 */ "mmmmmmmmm"
// Level 1
/* z\x* 012345678 */
- /* 0 */ "........."
- /* 1 */ ".dddeddd."
- /* 2 */ ".d.....d."
- /* 3 */ ".d.....d."
- /* 4 */ ".d.....d."
- /* 5 */ ".d.....d."
- /* 6 */ ".d.....d."
- /* 7 */ ".ddddddd."
+ /* 0 */ "...bcd..."
+ /* 1 */ ".aaaaaaa."
+ /* 2 */ ".aaaaaaa."
+ /* 3 */ ".aaaaaaa."
+ /* 4 */ ".aaaaaaa."
+ /* 5 */ ".aaaaaaa."
+ /* 6 */ ".aaaaaaa."
+ /* 7 */ ".aaaaaaa."
/* 8 */ "........."
// Level 2
/* z\x* 012345678 */
/* 0 */ "........."
- /* 1 */ ".dfdgdfd."
+ /* 1 */ ".aaaeaaa."
+ /* 2 */ ".a.....a."
+ /* 3 */ ".a.....a."
+ /* 4 */ ".a.....a."
+ /* 5 */ ".a.....a."
+ /* 6 */ ".a.....a."
+ /* 7 */ ".aaaaaaa."
+ /* 8 */ "........."
+
+ // Level 3
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ ".afagafa."
/* 2 */ ".f.....f."
/* 3 */ ".f.....f."
- /* 4 */ ".d.....d."
+ /* 4 */ ".a.....a."
/* 5 */ ".f.....f."
/* 6 */ ".f.....f."
- /* 7 */ ".dffdffd."
+ /* 7 */ ".affaffa."
/* 8 */ "........."
- // Level 3
+ // Level 4
/* z\x* 012345678 */
- /* 0 */ "bbbbbbbbb"
- /* 1 */ "hdddddddh"
- /* 2 */ ".d.i.i.d."
- /* 3 */ ".d.....d."
- /* 4 */ ".d.....d."
- /* 5 */ ".d.....d."
- /* 6 */ ".d..j..d."
- /* 7 */ "kdddddddk"
+ /* 0 */ "ccccccccc"
+ /* 1 */ "haaaaaaah"
+ /* 2 */ ".a.i.i.a."
+ /* 3 */ ".a.....a."
+ /* 4 */ ".a.....a."
+ /* 5 */ ".a.....a."
+ /* 6 */ ".a..j..a."
+ /* 7 */ "kaaaaaaak"
/* 8 */ "lllllllll"
- // Level 4
+ // Level 5
/* z\x* 012345678 */
/* 0 */ "........."
- /* 1 */ "bbbbbbbbb"
- /* 2 */ "hdddddddh"
- /* 3 */ ".d.....d."
- /* 4 */ ".d.....d."
- /* 5 */ ".d.....d."
- /* 6 */ "kdddddddk"
+ /* 1 */ "ccccccccc"
+ /* 2 */ "haaaaaaah"
+ /* 3 */ ".a.....a."
+ /* 4 */ ".a.....a."
+ /* 5 */ ".a.....a."
+ /* 6 */ "kaaaaaaak"
/* 7 */ "lllllllll"
/* 8 */ "........."
- // Level 5
+ // Level 6
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
- /* 2 */ "bbbbbbbbb"
- /* 3 */ "hdddddddh"
- /* 4 */ ".d.....d."
- /* 5 */ "kdddddddk"
+ /* 2 */ "ccccccccc"
+ /* 3 */ "haaaaaaah"
+ /* 4 */ ".a.....a."
+ /* 5 */ "kaaaaaaak"
/* 6 */ "lllllllll"
/* 7 */ "........."
/* 8 */ "........."
- // Level 6
+ // Level 7
/* z\x* 012345678 */
/* 0 */ "........."
/* 1 */ "........."
/* 2 */ "........."
- /* 3 */ "bbbbbbbbb"
- /* 4 */ "ddddddddd"
+ /* 3 */ "ccccccccc"
+ /* 4 */ "aaaaaaaaa"
/* 5 */ "lllllllll"
/* 6 */ "........."
/* 7 */ "........."
/* 8 */ ".........",
// Connectors:
- "-1: 4, 0, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 4, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1290,147 +1409,164 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 14, ID 124, created by Aloe_vera
{
// Size:
- 14, 7, 12, // SizeX = 14, SizeY = 7, SizeZ = 12
+ 14, 8, 12, // SizeX = 14, SizeY = 8, SizeZ = 12
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 13, 6, 11, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 14, 7, 12, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a:128: 0\n" /* sandstonestairs */
- "b:128: 2\n" /* sandstonestairs */
- "c:128: 1\n" /* sandstonestairs */
- "d: 24: 0\n" /* sandstone */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
"e:128: 3\n" /* sandstonestairs */
- "f: 64: 7\n" /* wooddoorblock */
- "g:102: 0\n" /* glasspane */
- "h: 64:12\n" /* wooddoorblock */
- "i:128: 7\n" /* sandstonestairs */
- "j: 50: 3\n" /* torch */
- "k: 50: 2\n" /* torch */
- "l: 50: 4\n" /* torch */
+ "f: 64: 3\n" /* wooddoorblock */
+ "g: 64: 1\n" /* wooddoorblock */
+ "h:102: 0\n" /* glasspane */
+ "i: 64: 8\n" /* wooddoorblock */
+ "j:128: 7\n" /* sandstonestairs */
+ "k: 50: 3\n" /* torch */
+ "l: 50: 2\n" /* torch */
"m: 19: 0\n" /* sponge */
- "n:128: 6\n" /* sandstonestairs */
- "o: 50: 1\n" /* torch */
- "p:128: 5\n" /* sandstonestairs */
- "q:128: 4\n" /* sandstonestairs */,
+ "n: 50: 4\n" /* torch */
+ "o:128: 6\n" /* sandstonestairs */
+ "p: 50: 1\n" /* torch */
+ "q:128: 5\n" /* sandstonestairs */
+ "r:128: 4\n" /* sandstonestairs */,
// Block data:
// Level 0
/* z\x* 1111 */
/* * 01234567890123 */
- /* 0 */ "....abc......."
- /* 1 */ ".dddddddddddd."
- /* 2 */ ".dddddddddddd."
- /* 3 */ ".dddddddddddd."
- /* 4 */ ".dddddddddddd."
- /* 5 */ ".dddddddddddd."
- /* 6 */ ".dddddddddddd."
- /* 7 */ ".dddddddddddd."
- /* 8 */ "....aeddddddd."
- /* 9 */ "mmmmm.ddddddd."
- /* 10 */ "mmmmm.ddddddd."
- /* 11 */ "mmmmm........."
+ /* 0 */ "mmmmaaammmmmmm"
+ /* 1 */ "maaaaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaaaam"
+ /* 6 */ "maaaaaaaaaaaam"
+ /* 7 */ "maaaaaaaaaaaam"
+ /* 8 */ "mmmmaaaaaaaaam"
+ /* 9 */ "mmmmmmaaaaaaam"
+ /* 10 */ "mmmmmmaaaaaaam"
+ /* 11 */ "mmmmmmmmmmmmmm"
// Level 1
/* z\x* 1111 */
/* * 01234567890123 */
- /* 0 */ ".............."
- /* 1 */ ".ddddfddddddd."
- /* 2 */ ".d..........d."
- /* 3 */ ".d..........d."
- /* 4 */ ".d..........d."
- /* 5 */ ".d..........d."
- /* 6 */ ".d..........d."
- /* 7 */ ".ddddfd.....d."
- /* 8 */ "......d.....d."
- /* 9 */ "mmmmm.d.....d."
- /* 10 */ "mmmmm.ddddddd."
+ /* 0 */ "....bcd......."
+ /* 1 */ ".aaaaaaaaaaaa."
+ /* 2 */ ".aaaaaaaaaaaa."
+ /* 3 */ ".aaaaaaaaaaaa."
+ /* 4 */ ".aaaaaaaaaaaa."
+ /* 5 */ ".aaaaaaaaaaaa."
+ /* 6 */ ".aaaaaaaaaaaa."
+ /* 7 */ ".aaaaaaaaaaaa."
+ /* 8 */ "....beaaaaaaa."
+ /* 9 */ "mmmmm.aaaaaaa."
+ /* 10 */ "mmmmm.aaaaaaa."
/* 11 */ "mmmmm........."
// Level 2
/* z\x* 1111 */
/* * 01234567890123 */
/* 0 */ ".............."
- /* 1 */ ".dggdhdggdggd."
- /* 2 */ ".g..........g."
- /* 3 */ ".g..........g."
- /* 4 */ ".d..........d."
- /* 5 */ ".g..........g."
- /* 6 */ ".g..........g."
- /* 7 */ ".dggdhd.....d."
- /* 8 */ "......g.....g."
- /* 9 */ "mmmmm.g.....g."
- /* 10 */ "mmmmm.dggdggd."
+ /* 1 */ ".aaaafaaaaaaa."
+ /* 2 */ ".a..........a."
+ /* 3 */ ".a..........a."
+ /* 4 */ ".a..........a."
+ /* 5 */ ".a..........a."
+ /* 6 */ ".a..........a."
+ /* 7 */ ".aaaaga.....a."
+ /* 8 */ "......a.....a."
+ /* 9 */ "mmmmm.a.....a."
+ /* 10 */ "mmmmm.aaaaaaa."
/* 11 */ "mmmmm........."
// Level 3
/* z\x* 1111 */
/* * 01234567890123 */
- /* 0 */ "bbbbbbbbbbbbbb"
- /* 1 */ "iddddddddddddc"
- /* 2 */ ".d..j.j.....dc"
- /* 3 */ ".d..........dc"
- /* 4 */ ".d.........kdc"
- /* 5 */ ".d..........dc"
- /* 6 */ ".d..l.l.....dc"
- /* 7 */ "nddddddo...kdc"
- /* 8 */ "eeeeead.....dc"
- /* 9 */ "mmmmmad.....dc"
- /* 10 */ "mmmmmadddddddc"
- /* 11 */ "mmmmmap.....qc"
+ /* 0 */ ".............."
+ /* 1 */ ".ahhaiahhahha."
+ /* 2 */ ".h..........h."
+ /* 3 */ ".h..........h."
+ /* 4 */ ".a..........a."
+ /* 5 */ ".h..........h."
+ /* 6 */ ".h..........h."
+ /* 7 */ ".ahhaia.....a."
+ /* 8 */ "......h.....h."
+ /* 9 */ "mmmmm.h.....h."
+ /* 10 */ "mmmmm.ahhahha."
+ /* 11 */ "mmmmm........."
// Level 4
/* z\x* 1111 */
/* * 01234567890123 */
- /* 0 */ ".............."
- /* 1 */ "bbbbbbbbbbbbc."
- /* 2 */ "idddddddddddc."
- /* 3 */ ".d.........dc."
- /* 4 */ ".d.........dc."
- /* 5 */ ".d.........dc."
- /* 6 */ "nddddddd...dc."
- /* 7 */ "eeeeeead...dc."
- /* 8 */ "......ad...dc."
- /* 9 */ "mmmmm.ad...dc."
- /* 10 */ "mmmmm.adddddc."
- /* 11 */ "mmmmm.ap...qc."
+ /* 0 */ "cccccccccccccc"
+ /* 1 */ "jaaaaaaaaaaaad"
+ /* 2 */ ".a..k.k.....ad"
+ /* 3 */ ".a..........ad"
+ /* 4 */ ".a.........lad"
+ /* 5 */ ".a..........ad"
+ /* 6 */ ".a..n.n.....ad"
+ /* 7 */ "oaaaaaap...lad"
+ /* 8 */ "eeeeeba.....ad"
+ /* 9 */ "mmmmmba.....ad"
+ /* 10 */ "mmmmmbaaaaaaad"
+ /* 11 */ "mmmmmbq.....rd"
// Level 5
/* z\x* 1111 */
/* * 01234567890123 */
/* 0 */ ".............."
- /* 1 */ ".............."
- /* 2 */ "bbbbbbbbbbbb.."
- /* 3 */ "iddddddddddc.."
- /* 4 */ ".d........dc.."
- /* 5 */ "ndddddddd.dc.."
- /* 6 */ "eeeeeeeed.dc.."
- /* 7 */ ".......ad.dc.."
- /* 8 */ ".......ad.dc.."
- /* 9 */ "mmmmm..ad.dc.."
- /* 10 */ "mmmmm..adddc.."
- /* 11 */ "mmmmm..ap.qc.."
+ /* 1 */ "ccccccccccccd."
+ /* 2 */ "jaaaaaaaaaaad."
+ /* 3 */ ".a.........ad."
+ /* 4 */ ".a.........ad."
+ /* 5 */ ".a.........ad."
+ /* 6 */ "oaaaaaaa...ad."
+ /* 7 */ "eeeeeeba...ad."
+ /* 8 */ "......ba...ad."
+ /* 9 */ "mmmmm.ba...ad."
+ /* 10 */ "mmmmm.baaaaad."
+ /* 11 */ "mmmmm.bq...rd."
// Level 6
/* z\x* 1111 */
/* * 01234567890123 */
/* 0 */ ".............."
/* 1 */ ".............."
+ /* 2 */ "cccccccccccc.."
+ /* 3 */ "jaaaaaaaaaad.."
+ /* 4 */ ".a........ad.."
+ /* 5 */ "oaaaaaaaa.ad.."
+ /* 6 */ "eeeeeeeea.ad.."
+ /* 7 */ ".......ba.ad.."
+ /* 8 */ ".......ba.ad.."
+ /* 9 */ "mmmmm..ba.ad.."
+ /* 10 */ "mmmmm..baaad.."
+ /* 11 */ "mmmmm..bq.rd.."
+
+ // Level 7
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ ".............."
/* 2 */ ".............."
- /* 3 */ "bbbbbbbbbbb..."
- /* 4 */ "ddddddddddc..."
- /* 5 */ "eeeeeeeeadc..."
- /* 6 */ "........adc..."
- /* 7 */ "........adc..."
- /* 8 */ "........adc..."
- /* 9 */ "mmmmm...adc..."
- /* 10 */ "mmmmm...adc..."
- /* 11 */ "mmmmm...adc...",
+ /* 3 */ "ccccccccccc..."
+ /* 4 */ "aaaaaaaaaad..."
+ /* 5 */ "eeeeeeeebad..."
+ /* 6 */ "........bad..."
+ /* 7 */ "........bad..."
+ /* 8 */ "........bad..."
+ /* 9 */ "mmmmm...bad..."
+ /* 10 */ "mmmmm...bad..."
+ /* 11 */ "mmmmm...bad...",
// Connectors:
- "-1: 5, 0, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1461,18 +1597,18 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 7, ID 82, created by Aloe_vera
{
// Size:
- 14, 6, 12, // SizeX = 14, SizeY = 6, SizeZ = 12
+ 14, 7, 12, // SizeX = 14, SizeY = 7, SizeZ = 12
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 13, 5, 11, // MaxX, MaxY, MaxZ
+ -1, 0, 0, // MinX, MinY, MinZ
+ 14, 6, 12, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
- "a:128: 0\n" /* sandstonestairs */
- "b:128: 2\n" /* sandstonestairs */
- "c:128: 1\n" /* sandstonestairs */
- "d: 24: 0\n" /* sandstone */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
"e:128: 3\n" /* sandstonestairs */
"f: 64: 7\n" /* wooddoorblock */
"g: 64: 5\n" /* wooddoorblock */
@@ -1491,101 +1627,117 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// Level 0
/* z\x* 1111 */
/* * 01234567890123 */
- /* 0 */ ".......abc...."
- /* 1 */ ".dddddddddddd."
- /* 2 */ ".dddddddddddd."
- /* 3 */ ".dddddddddddd."
- /* 4 */ ".dddddddddddd."
- /* 5 */ ".dddddddddddd."
- /* 6 */ "....aec.ddddd."
- /* 7 */ "mmmmmmm.ddddd."
- /* 8 */ "mmmmmmm.ddddd."
- /* 9 */ "mmmmmmm.ddddd."
- /* 10 */ "mmmmmmm.ddddd."
- /* 11 */ "mmmmmmm......."
+ /* 0 */ "mmmmmmmaaammmm"
+ /* 1 */ "maaaaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaaaam"
+ /* 6 */ "mmmmaaamaaaaam"
+ /* 7 */ "mmmmmmmmaaaaam"
+ /* 8 */ "mmmmmmmmaaaaam"
+ /* 9 */ "mmmmmmmmaaaaam"
+ /* 10 */ "mmmmmmmmaaaaam"
+ /* 11 */ "mmmmmmmmmmmmmm"
// Level 1
/* z\x* 1111 */
/* * 01234567890123 */
- /* 0 */ ".............."
- /* 1 */ ".dddddddfdddd."
- /* 2 */ ".d..........d."
- /* 3 */ ".d..........d."
- /* 4 */ ".d..........d."
- /* 5 */ ".ddddgddd...d."
- /* 6 */ "........d...d."
- /* 7 */ "mmmmmmm.d...d."
- /* 8 */ "mmmmmmm.d...d."
- /* 9 */ "mmmmmmm.d...d."
- /* 10 */ "mmmmmmm.ddddd."
- /* 11 */ "mmmmmmm......."
+ /* 0 */ ".......bcd...."
+ /* 1 */ ".aaaaaaaaaaaa."
+ /* 2 */ ".aaaaaaaaaaaa."
+ /* 3 */ ".aaaaaaaaaaaa."
+ /* 4 */ ".aaaaaaaaaaaa."
+ /* 5 */ ".aaaaaaaaaaaa."
+ /* 6 */ "....bed.aaaaa."
+ /* 7 */ "........aaaaa."
+ /* 8 */ "........aaaaa."
+ /* 9 */ "........aaaaa."
+ /* 10 */ "........aaaaa."
+ /* 11 */ ".............."
// Level 2
/* z\x* 1111 */
/* * 01234567890123 */
/* 0 */ ".............."
- /* 1 */ ".dhhdhhdidhhd."
+ /* 1 */ ".aaaaaaafaaaa."
+ /* 2 */ ".a..........a."
+ /* 3 */ ".a..........a."
+ /* 4 */ ".a..........a."
+ /* 5 */ ".aaaagaaa...a."
+ /* 6 */ "........a...a."
+ /* 7 */ "........a...a."
+ /* 8 */ "........a...a."
+ /* 9 */ "........a...a."
+ /* 10 */ "........aaaaa."
+ /* 11 */ ".............."
+
+ // Level 3
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ ".ahhahhaiahha."
/* 2 */ ".h..........h."
/* 3 */ ".h..........h."
- /* 4 */ ".h..........d."
- /* 5 */ ".dhhdidhh...h."
+ /* 4 */ ".h..........a."
+ /* 5 */ ".ahhaiahh...h."
/* 6 */ "........h...h."
- /* 7 */ "mmmmmmm.d...d."
- /* 8 */ "mmmmmmm.h...h."
- /* 9 */ "mmmmmmm.h...h."
- /* 10 */ "mmmmmmm.dhhhd."
- /* 11 */ "mmmmmmm......."
+ /* 7 */ "........a...a."
+ /* 8 */ "........h...h."
+ /* 9 */ "........h...h."
+ /* 10 */ "........ahhha."
+ /* 11 */ ".............."
- // Level 3
+ // Level 4
/* z\x* 1111 */
/* * 01234567890123 */
- /* 0 */ "bbbbbbbbbbbbbb"
- /* 1 */ "jddddddddddddc"
- /* 2 */ ".d.....k.k..dc"
- /* 3 */ ".d..........dc"
- /* 4 */ ".d..l.l.....dc"
- /* 5 */ "ndddddddd...dc"
- /* 6 */ "eeeeeeead...dc"
- /* 7 */ "mmmmmmmad...dc"
- /* 8 */ "mmmmmmmad...dc"
- /* 9 */ "mmmmmmmad...dc"
- /* 10 */ "mmmmmmmadddddc"
- /* 11 */ "mmmmmmmao...pc"
+ /* 0 */ "cccccccccccccc"
+ /* 1 */ "jaaaaaaaaaaaad"
+ /* 2 */ ".a.....k.k..ad"
+ /* 3 */ ".a..........ad"
+ /* 4 */ ".a..l.l.....ad"
+ /* 5 */ "naaaaaaaa...ad"
+ /* 6 */ "eeeeeeeba...ad"
+ /* 7 */ ".......ba...ad"
+ /* 8 */ ".......ba...ad"
+ /* 9 */ ".......ba...ad"
+ /* 10 */ ".......baaaaad"
+ /* 11 */ ".......bo...pd"
- // Level 4
+ // Level 5
/* z\x* 1111 */
/* * 01234567890123 */
/* 0 */ ".............."
- /* 1 */ "bbbbbbbbbbbbb."
- /* 2 */ "jdddddddddddc."
- /* 3 */ ".dq........dc."
- /* 4 */ "nddddddddd.dc."
- /* 5 */ "eeeeeeeead.dc."
- /* 6 */ "........ad.dc."
- /* 7 */ "mmmmmmm.ad.dc."
- /* 8 */ "mmmmmmm.ad.dc."
- /* 9 */ "mmmmmmm.adldc."
- /* 10 */ "mmmmmmm.adddc."
- /* 11 */ "mmmmmmm.ao.pc."
+ /* 1 */ "ccccccccccccc."
+ /* 2 */ "jaaaaaaaaaaad."
+ /* 3 */ ".aq........ad."
+ /* 4 */ "naaaaaaaaa.ad."
+ /* 5 */ "eeeeeeeeba.ad."
+ /* 6 */ "........ba.ad."
+ /* 7 */ "........ba.ad."
+ /* 8 */ "........ba.ad."
+ /* 9 */ "........balad."
+ /* 10 */ "........baaad."
+ /* 11 */ "........bo.pd."
- // Level 5
+ // Level 6
/* z\x* 1111 */
/* * 01234567890123 */
/* 0 */ ".............."
/* 1 */ ".............."
- /* 2 */ "bbbbbbbbbbbb.."
- /* 3 */ "dddddddddddc.."
- /* 4 */ "eeeeeeeeeadc.."
- /* 5 */ ".........adc.."
- /* 6 */ ".........adc.."
- /* 7 */ "mmmmmmm..adc.."
- /* 8 */ "mmmmmmm..adc.."
- /* 9 */ "mmmmmmm..adc.."
- /* 10 */ "mmmmmmm..adc.."
- /* 11 */ "mmmmmmm..adc..",
+ /* 2 */ "cccccccccccc.."
+ /* 3 */ "aaaaaaaaaaad.."
+ /* 4 */ "eeeeeeeeebad.."
+ /* 5 */ ".........bad.."
+ /* 6 */ ".........bad.."
+ /* 7 */ ".........bad.."
+ /* 8 */ ".........bad.."
+ /* 9 */ ".........bad.."
+ /* 10 */ ".........bad.."
+ /* 11 */ ".........bad..",
// Connectors:
- "-1: 8, 0, 0: 2\n" /* Type -1, direction Z- */,
+ "-1: 8, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1616,11 +1768,11 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 17, ID 127, created by Aloe_vera
{
// Size:
- 10, 2, 7, // SizeX = 10, SizeY = 2, SizeZ = 7
+ 10, 3, 7, // SizeX = 10, SizeY = 3, SizeZ = 7
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 9, 1, 6, // MaxX, MaxY, MaxZ
+ 0, 0, -1, // MinX, MinY, MinZ
+ 10, 2, 7, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
@@ -1636,6 +1788,17 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
/* z\x* */
/* * 0123456789 */
/* 0 */ "aaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaa"
+ /* 2 */ "aaaaaaaaaa"
+ /* 3 */ "aaaaaaaaaa"
+ /* 4 */ "aaaaaaaaaa"
+ /* 5 */ "aaaaaaaaaa"
+ /* 6 */ "aaaaaaaaaa"
+
+ // Level 1
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "aaaaaaaaaa"
/* 1 */ "abbbbbbbba"
/* 2 */ "abbbbbbbba"
/* 3 */ "acccccccca"
@@ -1643,7 +1806,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
/* 5 */ "abbbbbbbba"
/* 6 */ "aaaaaaaaaa"
- // Level 1
+ // Level 2
/* z\x* */
/* * 0123456789 */
/* 0 */ "d........d"
@@ -1655,7 +1818,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
/* 6 */ "d........d",
// Connectors:
- "-1: 0, 0, 3: 4\n" /* Type -1, direction X- */,
+ "-1: 0, 1, 3: 4\n" /* Type -1, direction X- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1686,11 +1849,11 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 4, ID 68, created by tonibm1999
{
// Size:
- 5, 5, 6, // SizeX = 5, SizeY = 5, SizeZ = 6
+ 5, 6, 6, // SizeX = 5, SizeY = 6, SizeZ = 6
// Hitbox (relative to bounding box):
- 0, 0, 0, // MinX, MinY, MinZ
- 4, 4, 5, // MaxX, MaxY, MaxZ
+ -1, 0, -1, // MinX, MinY, MinZ
+ 5, 5, 5, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
@@ -1712,10 +1875,19 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
/* 2 */ "aaaaa"
/* 3 */ "aaaaa"
/* 4 */ "aaaaa"
- /* 5 */ "..b.."
+ /* 5 */ "mmamm"
// Level 1
/* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aaaaa"
+ /* 3 */ "aaaaa"
+ /* 4 */ "aaaaa"
+ /* 5 */ "..b.."
+
+ // Level 2
+ /* z\x* 01234 */
/* 0 */ "accca"
/* 1 */ "cdedc"
/* 2 */ "c.f.c"
@@ -1723,7 +1895,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
/* 4 */ "acgca"
/* 5 */ "....."
- // Level 2
+ // Level 3
/* z\x* 01234 */
/* 0 */ "ac.ca"
/* 1 */ "c...c"
@@ -1732,7 +1904,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
/* 4 */ "achca"
/* 5 */ "....."
- // Level 3
+ // Level 4
/* z\x* 01234 */
/* 0 */ "accca"
/* 1 */ "c...c"
@@ -1741,7 +1913,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
/* 4 */ "accca"
/* 5 */ "....."
- // Level 4
+ // Level 5
/* z\x* 01234 */
/* 0 */ ".aaa."
/* 1 */ "aaaaa"
@@ -1751,7 +1923,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] =
/* 5 */ ".....",
// Connectors:
- "-1: 2, 0, 5: 3\n" /* Type -1, direction Z+ */,
+ "-1: 2, 1, 5: 3\n" /* Type -1, direction Z+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
@@ -1800,15 +1972,17 @@ const cPrefab::sDef g_SandVillageStartingPrefabs[] =
"b: 24: 0\n" /* sandstone */
"c: 8: 0\n" /* water */
"d: 12: 0\n" /* sand */
- "e:118: 3\n" /* cauldronblock */
- "f: 85: 0\n" /* fence */
- "g:128: 2\n" /* sandstonestairs */
- "h:128: 7\n" /* sandstonestairs */
- "i:128: 4\n" /* sandstonestairs */
- "j:128: 5\n" /* sandstonestairs */
- "k:128: 6\n" /* sandstonestairs */
- "l:128: 3\n" /* sandstonestairs */
- "m: 19: 0\n" /* sponge */,
+ "e: 4: 0\n" /* cobblestone */
+ "f: 13: 0\n" /* gravel */
+ "g:118: 3\n" /* cauldronblock */
+ "h: 85: 0\n" /* fence */
+ "i:128: 2\n" /* sandstonestairs */
+ "j:128: 7\n" /* sandstonestairs */
+ "k:128: 4\n" /* sandstonestairs */
+ "l:128: 5\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */
+ "n:128: 6\n" /* sandstonestairs */
+ "o:128: 3\n" /* sandstonestairs */,
// Block data:
// Level 0
@@ -1873,30 +2047,30 @@ const cPrefab::sDef g_SandVillageStartingPrefabs[] =
// Level 6
/* z\x* 0123456 */
- /* 0 */ "ddddddd"
+ /* 0 */ "ddeeedd"
/* 1 */ "dbbbbbd"
- /* 2 */ "dbcccbd"
- /* 3 */ "dbcccbd"
- /* 4 */ "dbcccbd"
+ /* 2 */ "ebcccbe"
+ /* 3 */ "ebcccbe"
+ /* 4 */ "ebcccbe"
/* 5 */ "dbbbbbd"
- /* 6 */ "ddddddd"
+ /* 6 */ "ddeeedd"
// Level 7
/* z\x* 0123456 */
- /* 0 */ "ddbbbdd"
+ /* 0 */ "ddfffdd"
/* 1 */ "dbbbbbd"
- /* 2 */ "bbcccbb"
- /* 3 */ "bbcccbb"
- /* 4 */ "bbcccbb"
+ /* 2 */ "fbcccbf"
+ /* 3 */ "fbcccbf"
+ /* 4 */ "fbcccbf"
/* 5 */ "dbbbbbd"
- /* 6 */ "ddbbbdd"
+ /* 6 */ "ddfffdd"
// Level 8
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ ".bbbbb."
/* 2 */ ".b...b."
- /* 3 */ ".b.e.b."
+ /* 3 */ ".b.g.b."
/* 4 */ ".b...b."
/* 5 */ ".bbbbb."
/* 6 */ "......."
@@ -1904,50 +2078,50 @@ const cPrefab::sDef g_SandVillageStartingPrefabs[] =
// Level 9
/* z\x* 0123456 */
/* 0 */ "......."
- /* 1 */ ".f...f."
+ /* 1 */ ".h...h."
/* 2 */ "......."
- /* 3 */ "...f..."
+ /* 3 */ "...h..."
/* 4 */ "......."
- /* 5 */ ".f...f."
+ /* 5 */ ".h...h."
/* 6 */ "......."
// Level 10
/* z\x* 0123456 */
/* 0 */ "......."
- /* 1 */ ".f...f."
+ /* 1 */ ".h...h."
/* 2 */ "......."
- /* 3 */ "...f..."
+ /* 3 */ "...h..."
/* 4 */ "......."
- /* 5 */ ".f...f."
+ /* 5 */ ".h...h."
/* 6 */ "......."
// Level 11
/* z\x* 0123456 */
- /* 0 */ "ggggggg"
- /* 1 */ "hbhhhbh"
- /* 2 */ ".i...j."
- /* 3 */ ".i.f.j."
- /* 4 */ ".i...j."
- /* 5 */ "kbkkkbk"
- /* 6 */ "lllllll"
+ /* 0 */ "iiiiiii"
+ /* 1 */ "jbjjjbj"
+ /* 2 */ ".k...l."
+ /* 3 */ ".k.h.l."
+ /* 4 */ ".k...l."
+ /* 5 */ "nbnnnbn"
+ /* 6 */ "ooooooo"
// Level 12
/* z\x* 0123456 */
/* 0 */ "......."
- /* 1 */ "ggggggg"
- /* 2 */ "hb...bh"
- /* 3 */ ".b.f.b."
- /* 4 */ "kb...bk"
- /* 5 */ "lllllll"
+ /* 1 */ "iiiiiii"
+ /* 2 */ "jb...bj"
+ /* 3 */ ".b.h.b."
+ /* 4 */ "nb...bn"
+ /* 5 */ "ooooooo"
/* 6 */ "......."
// Level 13
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ "......."
- /* 2 */ "ggggggg"
+ /* 2 */ "iiiiiii"
/* 3 */ "bbbbbbb"
- /* 4 */ "lllllll"
+ /* 4 */ "ooooooo"
/* 5 */ "......."
/* 6 */ ".......",
diff --git a/src/Generating/Prefabs/TestRailsPrefabs.cpp b/src/Generating/Prefabs/TestRailsPrefabs.cpp
new file mode 100644
index 000000000..3444cb1fa
--- /dev/null
+++ b/src/Generating/Prefabs/TestRailsPrefabs.cpp
@@ -0,0 +1,484 @@
+
+// TestRailsPrefabs.cpp
+
+// Defines the prefabs in the group TestRails
+
+// NOTE: This file has been generated automatically by GalExport!
+// Any manual changes will be overwritten by the next automatic export!
+
+#include "Globals.h"
+#include "TestRailsPrefabs.h"
+
+
+
+
+
+const cPrefab::sDef g_TestRailsPrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // ActivatorRail:
+ // The data has been exported from the gallery Plains, area index 251, ID 746, created by Aloe_vera
+ {
+ // Size:
+ 7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 2, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 1: 0\n" /* stone */
+ "b: 5: 0\n" /* wood */
+ "c:157: 0\n" /* activatorrail */
+ "d:157: 2\n" /* activatorrail */
+ "e:157: 3\n" /* activatorrail */
+ "f:157: 5\n" /* activatorrail */
+ "g: 50: 5\n" /* torch */
+ "h:157: 4\n" /* activatorrail */
+ "i:157: 1\n" /* activatorrail */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "aaab..."
+ /* 1 */ "abbbbb."
+ /* 2 */ "abbb.b."
+ /* 3 */ "bbbb.bb"
+ /* 4 */ ".b...b."
+ /* 5 */ ".bbbbb."
+ /* 6 */ "...b..."
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".cdbec."
+ /* 2 */ ".fg..f."
+ /* 3 */ ".b.g.b."
+ /* 4 */ ".h...h."
+ /* 5 */ ".cdbec."
+ /* 6 */ "......."
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "...i..."
+ /* 2 */ "......."
+ /* 3 */ ".c...c."
+ /* 4 */ "......."
+ /* 5 */ "...i..."
+ /* 6 */ ".......",
+
+ // Connectors:
+ "1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
+ "-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
+ "1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
+ "-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
+ "1: 0, 1, 3: 4\n" /* Type 1, direction X- */
+ "-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
+ "1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // ActivatorRail
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // DetectorRail:
+ // The data has been exported from the gallery Plains, area index 250, ID 745, created by Aloe_vera
+ {
+ // Size:
+ 7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 2, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 1: 0\n" /* stone */
+ "b: 5: 0\n" /* wood */
+ "c: 28: 0\n" /* detectorrail */
+ "d: 28: 2\n" /* detectorrail */
+ "e: 28: 3\n" /* detectorrail */
+ "f: 28: 5\n" /* detectorrail */
+ "g: 50: 5\n" /* torch */
+ "h: 28: 4\n" /* detectorrail */
+ "i: 28: 1\n" /* detectorrail */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "aaab..."
+ /* 1 */ "abbbbb."
+ /* 2 */ "abbb.b."
+ /* 3 */ "bbbb.bb"
+ /* 4 */ ".b...b."
+ /* 5 */ ".bbbbb."
+ /* 6 */ "...b..."
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".cdbec."
+ /* 2 */ ".fg..f."
+ /* 3 */ ".b.g.b."
+ /* 4 */ ".h...h."
+ /* 5 */ ".cdbec."
+ /* 6 */ "......."
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "...i..."
+ /* 2 */ "......."
+ /* 3 */ ".c...c."
+ /* 4 */ "......."
+ /* 5 */ "...i..."
+ /* 6 */ ".......",
+
+ // Connectors:
+ "1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
+ "-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
+ "1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */
+ "1: 0, 1, 3: 4\n" /* Type 1, direction X- */
+ "-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
+ "1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
+ "-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // DetectorRail
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // PowerRail:
+ // The data has been exported from the gallery Plains, area index 248, ID 743, created by Aloe_vera
+ {
+ // Size:
+ 7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 2, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 1: 0\n" /* stone */
+ "b: 5: 0\n" /* wood */
+ "c: 27: 0\n" /* poweredrail */
+ "d: 27: 2\n" /* poweredrail */
+ "e: 27: 3\n" /* poweredrail */
+ "f: 27: 5\n" /* poweredrail */
+ "g: 50: 5\n" /* torch */
+ "h: 27: 4\n" /* poweredrail */
+ "i: 27: 1\n" /* poweredrail */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "aaab..."
+ /* 1 */ "abbbbb."
+ /* 2 */ "abbb.b."
+ /* 3 */ "bbbb.bb"
+ /* 4 */ ".b...b."
+ /* 5 */ ".bbbbb."
+ /* 6 */ "...b..."
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".cdbec."
+ /* 2 */ ".fg..f."
+ /* 3 */ ".b.g.b."
+ /* 4 */ ".h...h."
+ /* 5 */ ".cdbec."
+ /* 6 */ "......."
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "...i..."
+ /* 2 */ "......."
+ /* 3 */ ".c...c."
+ /* 4 */ "......."
+ /* 5 */ "...i..."
+ /* 6 */ ".......",
+
+ // Connectors:
+ "1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
+ "-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
+ "1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
+ "-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
+ "1: 0, 1, 3: 4\n" /* Type 1, direction X- */
+ "-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
+ "1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */
+ "1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
+ "-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // PowerRail
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // RegularRail:
+ // The data has been exported from the gallery Plains, area index 247, ID 742, created by Aloe_vera
+ {
+ // Size:
+ 7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 2, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 1: 0\n" /* stone */
+ "b: 5: 0\n" /* wood */
+ "c: 66: 6\n" /* tracks */
+ "d: 66: 2\n" /* tracks */
+ "e: 66: 3\n" /* tracks */
+ "f: 66: 7\n" /* tracks */
+ "g: 66: 5\n" /* tracks */
+ "h: 50: 5\n" /* torch */
+ "i: 66: 4\n" /* tracks */
+ "j: 66: 9\n" /* tracks */
+ "k: 66: 8\n" /* tracks */
+ "l: 66: 1\n" /* tracks */
+ "m: 19: 0\n" /* sponge */
+ "n: 66: 0\n" /* tracks */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "aaab..."
+ /* 1 */ "abbbbb."
+ /* 2 */ "abbb.b."
+ /* 3 */ "bbbb.bb"
+ /* 4 */ ".b...b."
+ /* 5 */ ".bbbbb."
+ /* 6 */ "...b..."
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".cdbef."
+ /* 2 */ ".gh..g."
+ /* 3 */ ".b.h.b."
+ /* 4 */ ".i...i."
+ /* 5 */ ".jdbek."
+ /* 6 */ "......."
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "...l..."
+ /* 2 */ "......."
+ /* 3 */ ".n...n."
+ /* 4 */ "......."
+ /* 5 */ "...l..."
+ /* 6 */ ".......",
+
+ // Connectors:
+ "1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
+ "-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
+ "1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
+ "-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
+ "1: 0, 1, 3: 4\n" /* Type 1, direction X- */
+ "-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
+ "1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // RegularRail
+}; // g_TestRailsPrefabs
+
+
+
+
+
+
+const cPrefab::sDef g_TestRailsStartingPrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CentralPiece:
+ // The data has been exported from the gallery Plains, area index 249, ID 744, created by Aloe_vera
+ {
+ // Size:
+ 6, 3, 6, // SizeX = 6, SizeY = 3, SizeZ = 6
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 5, 2, 5, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 1: 0\n" /* stone */
+ "b: 5: 0\n" /* wood */
+ "c: 66: 6\n" /* tracks */
+ "d: 66: 2\n" /* tracks */
+ "e: 66: 3\n" /* tracks */
+ "f: 66: 7\n" /* tracks */
+ "g: 66: 5\n" /* tracks */
+ "h: 50: 5\n" /* torch */
+ "i: 66: 4\n" /* tracks */
+ "j: 66: 9\n" /* tracks */
+ "k: 66: 8\n" /* tracks */
+ "l: 66: 1\n" /* tracks */
+ "m: 19: 0\n" /* sponge */
+ "n: 66: 0\n" /* tracks */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 012345 */
+ /* 0 */ "aaab.."
+ /* 1 */ "abbbbb"
+ /* 2 */ "abbb.b"
+ /* 3 */ "bbbb.b"
+ /* 4 */ ".b...b"
+ /* 5 */ ".bbbbb"
+
+ // Level 1
+ /* z\x* 012345 */
+ /* 0 */ "......"
+ /* 1 */ ".cdbef"
+ /* 2 */ ".gh..g"
+ /* 3 */ ".b.h.b"
+ /* 4 */ ".i...i"
+ /* 5 */ ".jdbek"
+
+ // Level 2
+ /* z\x* 012345 */
+ /* 0 */ "......"
+ /* 1 */ "...l.."
+ /* 2 */ "......"
+ /* 3 */ ".n...n"
+ /* 4 */ "......"
+ /* 5 */ "...l..",
+
+ // Connectors:
+ "1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
+ "1: 0, 1, 3: 4\n" /* Type 1, direction X- */
+ "-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
+ "-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
+ "1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
+ "-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
+ "1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // CentralPiece
+};
+
+
+
+
+
+// The prefab counts:
+
+const size_t g_TestRailsPrefabsCount = ARRAYCOUNT(g_TestRailsPrefabs);
+
+const size_t g_TestRailsStartingPrefabsCount = ARRAYCOUNT(g_TestRailsStartingPrefabs);
+
diff --git a/src/Generating/Prefabs/TestRailsPrefabs.h b/src/Generating/Prefabs/TestRailsPrefabs.h
new file mode 100644
index 000000000..24b84de74
--- /dev/null
+++ b/src/Generating/Prefabs/TestRailsPrefabs.h
@@ -0,0 +1,15 @@
+
+// TestRailsPrefabs.h
+
+// Declares the prefabs in the group TestRails
+
+#include "../Prefab.h"
+
+
+
+
+
+extern const cPrefab::sDef g_TestRailsPrefabs[];
+extern const cPrefab::sDef g_TestRailsStartingPrefabs[];
+extern const size_t g_TestRailsPrefabsCount;
+extern const size_t g_TestRailsStartingPrefabsCount;
diff --git a/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp b/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp
index 39748a223..691d8aa9d 100644
--- a/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp
+++ b/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp
@@ -366,7 +366,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] =
true,
// DefaultWeight:
- 100,
+ 200,
// DepthWeight:
"",
diff --git a/src/Generating/TestRailsGen.cpp b/src/Generating/TestRailsGen.cpp
new file mode 100644
index 000000000..c40c1a9b6
--- /dev/null
+++ b/src/Generating/TestRailsGen.cpp
@@ -0,0 +1,116 @@
+
+// TestRailsGen.cpp
+
+// Implements the cTestRailsGen class representing the testing rails generator
+
+#include "Globals.h"
+#include "TestRailsGen.h"
+#include "Prefabs/TestRailsPrefabs.h"
+#include "PieceGenerator.h"
+
+
+
+
+
+static cPrefabPiecePool g_TestRails(g_TestRailsPrefabs, g_TestRailsPrefabsCount, g_TestRailsStartingPrefabs, g_TestRailsStartingPrefabsCount);
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cTestRailsGen::cTestRails:
+
+class cTestRailsGen::cTestRails :
+ public cGridStructGen::cStructure
+{
+ typedef cGridStructGen::cStructure super;
+
+public:
+ cTestRails(
+ int a_Seed,
+ int a_GridX, int a_GridZ,
+ int a_OriginX, int a_OriginZ,
+ int a_MaxDepth,
+ int a_MaxSize
+ ) :
+ super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
+ m_Seed(a_Seed),
+ m_Noise(a_Seed),
+ m_MaxSize(a_MaxSize),
+ m_Borders(a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize, a_OriginX + a_MaxSize, 255, a_OriginZ + a_MaxSize)
+ {
+ // Generate the pieces for this test:
+ cBFSPieceGenerator pg(g_TestRails, a_Seed);
+ pg.PlacePieces(a_OriginX, 150, a_OriginZ, a_MaxDepth, m_Pieces);
+ if (m_Pieces.empty())
+ {
+ return;
+ }
+ }
+
+ ~cTestRails()
+ {
+ cPieceGenerator::FreePieces(m_Pieces);
+ }
+
+protected:
+ /** Seed for the random functions */
+ int m_Seed;
+
+ /** The noise used as a pseudo-random generator */
+ cNoise m_Noise;
+
+ /** Maximum size, in X/Z blocks, of the structure (radius from the origin) */
+ int m_MaxSize;
+
+ /** Borders of the structure - no item may reach out of this cuboid. */
+ cCuboid m_Borders;
+
+ /** The rails pieces, placed by the generator. */
+ cPlacedPieces m_Pieces;
+
+
+ // cGridStructGen::cStructure overrides:
+ virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override
+ {
+ for (cPlacedPieces::iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr)
+ {
+ cPrefab & Prefab = (cPrefab &)((*itr)->GetPiece());
+ Prefab.Draw(a_Chunk, *itr);
+ } // for itr - m_PlacedPieces[]
+ }
+} ;
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cTestRailsGen:
+
+
+
+
+
+cTestRailsGen::cTestRailsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize) :
+ super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100),
+ m_Noise(a_Seed + 1000),
+ m_MaxDepth(a_MaxDepth),
+ m_MaxSize(a_MaxSize)
+{
+}
+
+
+
+
+
+cGridStructGen::cStructurePtr cTestRailsGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
+{
+ // Create a base based on the chosen prefabs:
+ return cStructurePtr(new cTestRails(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize));
+}
+
+
+
+
diff --git a/src/Generating/TestRailsGen.h b/src/Generating/TestRailsGen.h
new file mode 100644
index 000000000..5b0ce95f4
--- /dev/null
+++ b/src/Generating/TestRailsGen.h
@@ -0,0 +1,47 @@
+
+// TestRailsGen.h
+
+// Declares the cTestRailsGen class representing the testing rails generator
+
+
+
+
+
+#pragma once
+
+#include "GridStructGen.h"
+#include "PrefabPiecePool.h"
+
+
+
+
+
+class cTestRailsGen :
+ public cGridStructGen
+{
+ typedef cGridStructGen super;
+
+public:
+ cTestRailsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize);
+
+protected:
+ class cTestRails; // fwd: TestRailsGen.cpp
+
+
+ /** The noise used for generating random numbers */
+ cNoise m_Noise;
+
+ /** Maximum depth of the generator tree*/
+ int m_MaxDepth;
+
+ /** Maximum size, in X/Z blocks, of the base (radius from the origin) */
+ int m_MaxSize;
+
+
+ // cGridStructGen overrides:
+ virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
+} ;
+
+
+
+
diff --git a/src/Globals.h b/src/Globals.h
index e99333693..998676fb1 100644
--- a/src/Globals.h
+++ b/src/Globals.h
@@ -71,9 +71,24 @@
#define FORMATSTRING(formatIndex, va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex)))
- #define SIZE_T_FMT "%zu"
- #define SIZE_T_FMT_PRECISION(x) "%" #x "zu"
- #define SIZE_T_FMT_HEX "%zx"
+ #if defined(_WIN32)
+ // We're compiling on MinGW, which uses an old MSVCRT library that has no support for size_t printfing.
+ // We need direct size formats:
+ #if defined(_WIN64)
+ #define SIZE_T_FMT "%I64u"
+ #define SIZE_T_FMT_PRECISION(x) "%" #x "I64u"
+ #define SIZE_T_FMT_HEX "%I64x"
+ #else
+ #define SIZE_T_FMT "%u"
+ #define SIZE_T_FMT_PRECISION(x) "%" #x "u"
+ #define SIZE_T_FMT_HEX "%x"
+ #endif
+ #else
+ // We're compiling on Linux, so we can use libc's size_t printf format:
+ #define SIZE_T_FMT "%zu"
+ #define SIZE_T_FMT_PRECISION(x) "%" #x "zu"
+ #define SIZE_T_FMT_HEX "%zx"
+ #endif
#define NORETURN __attribute((__noreturn__))
diff --git a/src/GroupManager.cpp b/src/GroupManager.cpp
index e570bb2b1..11e62c223 100644
--- a/src/GroupManager.cpp
+++ b/src/GroupManager.cpp
@@ -30,10 +30,12 @@ cGroupManager::~cGroupManager()
for( GroupMap::iterator itr = m_pState->Groups.begin(); itr != m_pState->Groups.end(); ++itr )
{
delete itr->second;
+ itr->second = NULL;
}
m_pState->Groups.clear();
delete m_pState;
+ m_pState = NULL;
}
diff --git a/src/HTTPServer/HTTPConnection.cpp b/src/HTTPServer/HTTPConnection.cpp
index b127e7091..21ff14373 100644
--- a/src/HTTPServer/HTTPConnection.cpp
+++ b/src/HTTPServer/HTTPConnection.cpp
@@ -28,6 +28,7 @@ cHTTPConnection::~cHTTPConnection()
{
// LOGD("HTTP: Connection deleting: %p", this);
delete m_CurrentRequest;
+ m_CurrentRequest = NULL;
}
diff --git a/src/HTTPServer/HTTPServer.cpp b/src/HTTPServer/HTTPServer.cpp
index d288c83c9..036b2e042 100644
--- a/src/HTTPServer/HTTPServer.cpp
+++ b/src/HTTPServer/HTTPServer.cpp
@@ -179,6 +179,8 @@ bool cHTTPServer::Initialize(const AString & a_PortsIPv4, const AString & a_Port
// Open up requested ports:
bool HasAnyPort;
+ m_ListenThreadIPv4.SetReuseAddr(true);
+ m_ListenThreadIPv6.SetReuseAddr(true);
HasAnyPort = m_ListenThreadIPv4.Initialize(a_PortsIPv4);
HasAnyPort = m_ListenThreadIPv6.Initialize(a_PortsIPv6) || HasAnyPort;
if (!HasAnyPort)
diff --git a/src/Item.cpp b/src/Item.cpp
index d6e8b224a..56ceae0b7 100644
--- a/src/Item.cpp
+++ b/src/Item.cpp
@@ -1,4 +1,4 @@
-
+
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Item.h"
diff --git a/src/ItemGrid.cpp b/src/ItemGrid.cpp
index 34a267bab..cd36b1f2a 100644
--- a/src/ItemGrid.cpp
+++ b/src/ItemGrid.cpp
@@ -28,6 +28,7 @@ cItemGrid::cItemGrid(int a_Width, int a_Height) :
cItemGrid::~cItemGrid()
{
delete[] m_Slots;
+ m_Slots = NULL;
}
diff --git a/src/Items/ItemBow.h b/src/Items/ItemBow.h
index e0ab339d3..185f17fee 100644
--- a/src/Items/ItemBow.h
+++ b/src/Items/ItemBow.h
@@ -46,20 +46,17 @@ public:
{
// Actual shot - produce the arrow with speed based on the ticks that the bow was charged
ASSERT(a_Player != NULL);
-
+
int BowCharge = a_Player->FinishChargingBow();
- double Force = (double)BowCharge / 20;
- Force = (Force * Force + 2 * Force) / 3; // This formula is used by the 1.6.2 client
+ double Force = (double)BowCharge / 20.0;
+ Force = (Force * Force + 2.0 * Force) / 3.0; // This formula is used by the 1.6.2 client
if (Force < 0.1)
{
// Too little force, ignore the shot
return;
}
- if (Force > 1)
- {
- Force = 1;
- }
-
+ Force = std::min(Force, 1.0);
+
// Create the arrow entity:
cArrowEntity * Arrow = new cArrowEntity(*a_Player, Force * 2);
if (Arrow == NULL)
@@ -69,11 +66,11 @@ public:
if (!Arrow->Initialize(*a_Player->GetWorld()))
{
delete Arrow;
+ Arrow = NULL;
return;
}
- a_Player->GetWorld()->BroadcastSpawnEntity(*Arrow);
- a_Player->GetWorld()->BroadcastSoundEffect("random.bow", (int)a_Player->GetPosX() * 8, (int)a_Player->GetPosY() * 8, (int)a_Player->GetPosZ() * 8, 0.5, (float)Force);
+ a_Player->GetWorld()->BroadcastSoundEffect("random.bow", (int)a_Player->GetPosX() * 8, (int)a_Player->GetPosY() * 8, (int)a_Player->GetPosZ() * 8, 0.5, (float)Force);
if (!a_Player->IsGameModeCreative())
{
a_Player->UseEquippedItem();
diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp
index 3d13af3a7..7fae2d395 100644
--- a/src/Items/ItemHandler.cpp
+++ b/src/Items/ItemHandler.cpp
@@ -46,6 +46,7 @@
#include "ItemSign.h"
#include "ItemMobHead.h"
#include "ItemSpawnEgg.h"
+#include "ItemString.h"
#include "ItemSugarcane.h"
#include "ItemSword.h"
@@ -64,7 +65,7 @@ cItemHandler * cItemHandler::m_ItemHandler[2268];
cItemHandler * cItemHandler::GetItemHandler(int a_ItemType)
{
- if (a_ItemType < 0)
+ if ((a_ItemType < 0) || ((unsigned long)a_ItemType >= ARRAYCOUNT(m_ItemHandler)))
{
// Either nothing (-1), or bad value, both cases should return the air handler
if (a_ItemType < -1)
@@ -133,6 +134,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
case E_ITEM_HEAD: return new cItemMobHeadHandler(a_ItemType);
case E_ITEM_SNOWBALL: return new cItemSnowballHandler();
case E_ITEM_SPAWN_EGG: return new cItemSpawnEggHandler(a_ItemType);
+ case E_ITEM_STRING: return new cItemStringHandler(a_ItemType);
case E_ITEM_SUGARCANE: return new cItemSugarcaneHandler(a_ItemType);
case E_ITEM_WOODEN_HOE:
@@ -264,6 +266,7 @@ void cItemHandler::Deinit()
for(int i = 0; i < 2267; i++)
{
delete m_ItemHandler[i];
+ m_ItemHandler[i] = NULL;
}
memset(m_ItemHandler, 0, sizeof(m_ItemHandler)); // Don't leave any dangling pointers around, just in case
m_HandlerInitialized = false;
diff --git a/src/Items/ItemItemFrame.h b/src/Items/ItemItemFrame.h
index 097f04d0b..b258b4aea 100644
--- a/src/Items/ItemItemFrame.h
+++ b/src/Items/ItemItemFrame.h
@@ -37,6 +37,7 @@ public:
if (!ItemFrame->Initialize(*a_World))
{
delete ItemFrame;
+ ItemFrame = NULL;
return false;
}
diff --git a/src/Items/ItemString.h b/src/Items/ItemString.h
new file mode 100644
index 000000000..a97fbe0ce
--- /dev/null
+++ b/src/Items/ItemString.h
@@ -0,0 +1,39 @@
+
+#pragma once
+
+#include "ItemHandler.h"
+
+
+
+
+
+class cItemStringHandler :
+ public cItemHandler
+{
+public:
+ cItemStringHandler(int a_ItemType) :
+ cItemHandler(a_ItemType)
+ {
+ }
+
+ virtual bool IsPlaceable(void) override
+ {
+ return true;
+ }
+
+ virtual bool GetPlacementBlockTypeMeta(
+ cWorld * a_World, cPlayer * a_Player,
+ int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
+ int a_CursorX, int a_CursorY, int a_CursorZ,
+ BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
+ ) override
+ {
+ a_BlockType = E_BLOCK_TRIPWIRE;
+ a_BlockMeta = 0;
+ return true;
+ }
+};
+
+
+
+
diff --git a/src/Items/ItemThrowable.h b/src/Items/ItemThrowable.h
index 35c2b8731..25935a1bc 100644
--- a/src/Items/ItemThrowable.h
+++ b/src/Items/ItemThrowable.h
@@ -31,6 +31,17 @@ public:
Vector3d Pos = a_Player->GetThrowStartPos();
Vector3d Speed = a_Player->GetLookVector() * m_SpeedCoeff;
+ // Play sound
+ cFastRandom Random;
+ a_World->BroadcastSoundEffect(
+ "random.bow",
+ (int)std::floor(a_Player->GetPosX() * 8.0),
+ (int)std::floor((a_Player->GetPosY() - a_Player->GetHeight()) * 8.0),
+ (int)std::floor(a_Player->GetPosZ() * 8.0),
+ 0.5F,
+ 0.4F / (Random.NextFloat(1.0F) * 0.4F + 0.8F)
+ );
+
if (a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, a_Player->GetEquippedItem(), &Speed) < 0)
{
return false;
diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp
index 583438d65..ad2029589 100644
--- a/src/MCLogger.cpp
+++ b/src/MCLogger.cpp
@@ -57,6 +57,7 @@ cMCLogger::~cMCLogger()
{
m_Log->Log("--- Stopped Log ---\n");
delete m_Log;
+ m_Log = NULL;
if (this == s_MCLogger)
{
s_MCLogger = NULL;
diff --git a/src/Mobs/Blaze.cpp b/src/Mobs/Blaze.cpp
index 19bdf8737..b4104d530 100644
--- a/src/Mobs/Blaze.cpp
+++ b/src/Mobs/Blaze.cpp
@@ -47,6 +47,7 @@ void cBlaze::Attack(float a_Dt)
if (!FireCharge->Initialize(*m_World))
{
delete FireCharge;
+ FireCharge = NULL;
return;
}
m_World->BroadcastSpawnEntity(*FireCharge);
diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp
index a7b97f604..b9041bd5a 100644
--- a/src/Mobs/Creeper.cpp
+++ b/src/Mobs/Creeper.cpp
@@ -67,9 +67,27 @@ void cCreeper::GetDrops(cItems & a_Drops, cEntity * a_Killer)
}
AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_GUNPOWDER);
- if ((a_Killer != NULL) && (a_Killer->IsProjectile()))
+ if ((a_Killer != NULL) && a_Killer->IsProjectile() && (((cProjectileEntity *)a_Killer)->GetCreatorUniqueID() >= 0))
{
- if (((cMonster *)((cProjectileEntity *)a_Killer)->GetCreator())->GetMobType() == mtSkeleton)
+ class cProjectileCreatorCallback : public cEntityCallback
+ {
+ public:
+ cProjectileCreatorCallback(void)
+ {
+ }
+
+ virtual bool Item(cEntity * a_Entity) override
+ {
+ if (a_Entity->IsMob() && ((cMonster *)a_Entity)->GetMobType() == mtSkeleton)
+ {
+ return true;
+ }
+ return false;
+ }
+ };
+
+ cProjectileCreatorCallback PCC;
+ if (GetWorld()->DoWithEntityByID(((cProjectileEntity *)a_Killer)->GetCreatorUniqueID(), PCC))
{
// 12 music discs. TickRand starts from 0 to 11. Disk IDs start at 2256, so add that. There.
AddRandomDropItem(a_Drops, 1, 1, (short)m_World->GetTickRandomNumber(11) + 2256);
diff --git a/src/Mobs/Ghast.cpp b/src/Mobs/Ghast.cpp
index 4df8e165c..6aac14779 100644
--- a/src/Mobs/Ghast.cpp
+++ b/src/Mobs/Ghast.cpp
@@ -49,6 +49,7 @@ void cGhast::Attack(float a_Dt)
if (!GhastBall->Initialize(*m_World))
{
delete GhastBall;
+ GhastBall = NULL;
return;
}
m_World->BroadcastSpawnEntity(*GhastBall);
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index a51315ecf..f4827d5f5 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -46,8 +46,8 @@ static const struct
{cMonster::mtSheep, "sheep"},
{cMonster::mtSilverfish, "silverfish"},
{cMonster::mtSkeleton, "skeleton"},
- {cMonster::mtSnowGolem, "snowgolem"},
{cMonster::mtSlime, "slime"},
+ {cMonster::mtSnowGolem, "snowgolem"},
{cMonster::mtSpider, "spider"},
{cMonster::mtSquid, "squid"},
{cMonster::mtVillager, "villager"},
diff --git a/src/Mobs/Pig.cpp b/src/Mobs/Pig.cpp
index e862f5aaa..1f77cf613 100644
--- a/src/Mobs/Pig.cpp
+++ b/src/Mobs/Pig.cpp
@@ -78,3 +78,23 @@ void cPig::OnRightClicked(cPlayer & a_Player)
+
+
+void cPig::Tick(float a_Dt, cChunk & a_Chunk)
+{
+ super::Tick(a_Dt, a_Chunk);
+
+ // If the attachee player is holding a carrot-on-stick, let them drive this pig:
+ if (m_bIsSaddled && (m_Attachee != NULL))
+ {
+ if (m_Attachee->IsPlayer() && (m_Attachee->GetEquippedWeapon().m_ItemType == E_ITEM_CARROT_ON_STICK))
+ {
+ MoveToPosition((m_Attachee->GetPosition()) + (m_Attachee->GetLookVector()*10));
+ m_bMovingToDestination = true;
+ }
+ }
+}
+
+
+
+
diff --git a/src/Mobs/Pig.h b/src/Mobs/Pig.h
index d434324c1..313af2f44 100644
--- a/src/Mobs/Pig.h
+++ b/src/Mobs/Pig.h
@@ -19,6 +19,7 @@ public:
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
virtual void OnRightClicked(cPlayer & a_Player) override;
+ virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_CARROT); }
diff --git a/src/Mobs/Skeleton.cpp b/src/Mobs/Skeleton.cpp
index e7f3971cc..0641a3d57 100644
--- a/src/Mobs/Skeleton.cpp
+++ b/src/Mobs/Skeleton.cpp
@@ -49,11 +49,10 @@ void cSkeleton::GetDrops(cItems & a_Drops, cEntity * a_Killer)
void cSkeleton::MoveToPosition(const Vector3f & a_Position)
{
- // If the destination is in the sun and if it is not night AND the skeleton isn't on fire then block the movement.
+ // If the destination is sufficiently skylight challenged AND the skeleton isn't on fire then block the movement
if (
!IsOnFire() &&
- (m_World->GetTimeOfDay() < 13187) &&
- (m_World->GetBlockSkyLight((int) a_Position.x, (int) a_Position.y, (int) a_Position.z) == 15)
+ (m_World->GetBlockSkyLight((int)floor(a_Position.x), (int)floor(a_Position.y), (int)floor(a_Position.z)) - m_World->GetSkyDarkness() > 8)
)
{
m_bMovingToDestination = false;
@@ -84,6 +83,7 @@ void cSkeleton::Attack(float a_Dt)
if (!Arrow->Initialize(*m_World))
{
delete Arrow;
+ Arrow = NULL;
return;
}
m_World->BroadcastSpawnEntity(*Arrow);
diff --git a/src/Mobs/Zombie.cpp b/src/Mobs/Zombie.cpp
index f19e096ee..725790ed9 100644
--- a/src/Mobs/Zombie.cpp
+++ b/src/Mobs/Zombie.cpp
@@ -44,11 +44,10 @@ void cZombie::GetDrops(cItems & a_Drops, cEntity * a_Killer)
void cZombie::MoveToPosition(const Vector3f & a_Position)
{
- // If the destination is in the sun and if it is not night AND the zombie isn't on fire then block the movement.
+ // If the destination is sufficiently skylight challenged AND the skeleton isn't on fire then block the movement
if (
!IsOnFire() &&
- (m_World->GetTimeOfDay() < 13187) &&
- (m_World->GetBlockSkyLight((int)a_Position.x, (int)a_Position.y, (int)a_Position.z) == 15)
+ (m_World->GetBlockSkyLight((int)floor(a_Position.x), (int)floor(a_Position.y), (int)floor(a_Position.z)) - m_World->GetSkyDarkness() > 8)
)
{
m_bMovingToDestination = false;
diff --git a/src/MonsterConfig.cpp b/src/MonsterConfig.cpp
index 72a3a3245..f5e746ce8 100644
--- a/src/MonsterConfig.cpp
+++ b/src/MonsterConfig.cpp
@@ -47,6 +47,7 @@ cMonsterConfig::cMonsterConfig(void)
cMonsterConfig::~cMonsterConfig()
{
delete m_pState;
+ m_pState = NULL;
}
diff --git a/src/Noise.cpp b/src/Noise.cpp
index 040421106..fbd2a1800 100644
--- a/src/Noise.cpp
+++ b/src/Noise.cpp
@@ -877,6 +877,7 @@ void cPerlinNoise::Generate2D(
if (ShouldFreeWorkspace)
{
delete[] a_Workspace;
+ a_Workspace = NULL;
}
}
@@ -943,6 +944,7 @@ void cPerlinNoise::Generate3D(
if (ShouldFreeWorkspace)
{
delete[] a_Workspace;
+ a_Workspace = NULL;
}
}
@@ -1045,6 +1047,7 @@ void cRidgedMultiNoise::Generate2D(
if (ShouldFreeWorkspace)
{
delete[] a_Workspace;
+ a_Workspace = NULL;
}
}
@@ -1111,6 +1114,7 @@ void cRidgedMultiNoise::Generate3D(
if (ShouldFreeWorkspace)
{
delete[] a_Workspace;
+ a_Workspace = NULL;
}
}
diff --git a/src/OSSupport/Event.cpp b/src/OSSupport/Event.cpp
index 649a0a3cf..72bce4c3c 100644
--- a/src/OSSupport/Event.cpp
+++ b/src/OSSupport/Event.cpp
@@ -18,7 +18,7 @@ cEvent::cEvent(void)
m_Event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (m_Event == NULL)
{
- LOGERROR("cEvent: cannot create event, GLE = %d. Aborting server.", GetLastError());
+ LOGERROR("cEvent: cannot create event, GLE = %u. Aborting server.", (unsigned)GetLastError());
abort();
}
#else // *nix
@@ -71,6 +71,7 @@ cEvent::~cEvent()
{
sem_destroy(m_Event);
delete m_Event;
+ m_Event = NULL;
}
#endif
}
@@ -85,7 +86,7 @@ void cEvent::Wait(void)
DWORD res = WaitForSingleObject(m_Event, INFINITE);
if (res != WAIT_OBJECT_0)
{
- LOGWARN("cEvent: waiting for the event failed: %d, GLE = %d. Continuing, but server may be unstable.", res, GetLastError());
+ LOGWARN("cEvent: waiting for the event failed: %u, GLE = %u. Continuing, but server may be unstable.", (unsigned)res, (unsigned)GetLastError());
}
#else
int res = sem_wait(m_Event);
@@ -106,7 +107,7 @@ void cEvent::Set(void)
#ifdef _WIN32
if (!SetEvent(m_Event))
{
- LOGWARN("cEvent: Could not set cEvent: GLE = %d", GetLastError());
+ LOGWARN("cEvent: Could not set cEvent: GLE = %u", (unsigned)GetLastError());
}
#else
int res = sem_post(m_Event);
diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp
index 8c24fa541..addf8f928 100644
--- a/src/OSSupport/File.cpp
+++ b/src/OSSupport/File.cpp
@@ -7,6 +7,9 @@
#include "File.h"
#include <fstream>
+#ifdef _WIN32
+ #include <share.h> // for _SH_DENYWRITE
+#endif // _WIN32
diff --git a/src/OSSupport/IsThread.cpp b/src/OSSupport/IsThread.cpp
index 67f336c97..1a436623a 100644
--- a/src/OSSupport/IsThread.cpp
+++ b/src/OSSupport/IsThread.cpp
@@ -90,7 +90,7 @@ bool cIsThread::Start(void)
m_Handle = CreateThread(NULL, 0, thrExecute, this, CREATE_SUSPENDED, &m_ThreadID);
if (m_Handle == NULL)
{
- LOGERROR("ERROR: Could not create thread \"%s\", GLE = %d!", m_ThreadName.c_str(), GetLastError());
+ LOGERROR("ERROR: Could not create thread \"%s\", GLE = %u!", m_ThreadName.c_str(), (unsigned)GetLastError());
return false;
}
ResumeThread(m_Handle);
diff --git a/src/OSSupport/SocketThreads.cpp b/src/OSSupport/SocketThreads.cpp
index 0ab5b6298..ca8b8438d 100644
--- a/src/OSSupport/SocketThreads.cpp
+++ b/src/OSSupport/SocketThreads.cpp
@@ -61,6 +61,7 @@ bool cSocketThreads::AddClient(const cSocket & a_Socket, cCallback * a_Client)
// There was an error launching the thread (but it was already logged along with the reason)
LOGERROR("A new cSocketThread failed to start");
delete Thread;
+ Thread = NULL;
return false;
}
Thread->AddClient(a_Socket, a_Client);
diff --git a/src/OSSupport/Thread.cpp b/src/OSSupport/Thread.cpp
index 7a10ef8d2..535784613 100644
--- a/src/OSSupport/Thread.cpp
+++ b/src/OSSupport/Thread.cpp
@@ -66,11 +66,13 @@ cThread::cThread( ThreadFunc a_ThreadFunction, void* a_Param, const char* a_Thre
cThread::~cThread()
{
delete m_Event;
+ m_Event = NULL;
if( m_StopEvent )
{
m_StopEvent->Wait();
delete m_StopEvent;
+ m_StopEvent = NULL;
}
}
diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h
index c6e569919..ac872a2f2 100644
--- a/src/Protocol/Protocol.h
+++ b/src/Protocol/Protocol.h
@@ -64,7 +64,7 @@ public:
virtual void SendChat (const AString & a_Message) = 0;
virtual void SendChat (const cCompositeChat & a_Message) = 0;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) = 0;
- virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) = 0;
+ virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) = 0;
virtual void SendDestroyEntity (const cEntity & a_Entity) = 0;
virtual void SendDisconnect (const AString & a_Reason) = 0;
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; ///< Request the client to open up the sign editor for the sign (1.6+)
@@ -100,7 +100,7 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0;
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) = 0;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) = 0;
- virtual void SendRespawn (const cWorld & a_World) = 0;
+ virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) = 0;
virtual void SendExperience (void) = 0;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) = 0;
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) = 0;
diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp
index 491058919..6dc2e918d 100644
--- a/src/Protocol/Protocol125.cpp
+++ b/src/Protocol/Protocol125.cpp
@@ -274,11 +274,11 @@ void cProtocol125::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize
-void cProtocol125::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player)
+void cProtocol125::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
{
cCSLock Lock(m_CSPacket);
WriteByte(PACKET_COLLECT_PICKUP);
- WriteInt (a_Pickup.GetUniqueID());
+ WriteInt (a_Entity.GetUniqueID());
WriteInt (a_Player.GetUniqueID());
Flush();
}
@@ -833,12 +833,12 @@ void cProtocol125::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect
-void cProtocol125::SendRespawn(const cWorld & a_World)
+void cProtocol125::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks)
{
cCSLock Lock(m_CSPacket);
- if (m_LastSentDimension == a_World.GetDimension())
+ if ((m_LastSentDimension == a_World.GetDimension()) && !a_ShouldIgnoreDimensionChecks)
{
- // Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do
+ // Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do (unless we are respawning from death)
return;
}
cPlayer * Player = m_Client->GetPlayer();
diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h
index 85418f71f..9dbefd3a3 100644
--- a/src/Protocol/Protocol125.h
+++ b/src/Protocol/Protocol125.h
@@ -36,7 +36,7 @@ public:
virtual void SendChat (const AString & a_Message) override;
virtual void SendChat (const cCompositeChat & a_Message) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
- virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
+ virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
virtual void SendDisconnect (const AString & a_Reason) override;
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+)
@@ -72,7 +72,7 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
- virtual void SendRespawn (const cWorld & a_World) override;
+ virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) override;
virtual void SendExperience (void) override;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp
index 1e3fc8de8..31cf99f53 100644
--- a/src/Protocol/Protocol132.cpp
+++ b/src/Protocol/Protocol132.cpp
@@ -188,19 +188,19 @@ void cProtocol132::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize
-void cProtocol132::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player)
+void cProtocol132::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
{
cCSLock Lock(m_CSPacket);
WriteByte(PACKET_COLLECT_PICKUP);
- WriteInt (a_Pickup.GetUniqueID());
+ WriteInt (a_Entity.GetUniqueID());
WriteInt (a_Player.GetUniqueID());
Flush();
// Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;)
SendSoundEffect(
"random.pop",
- (int)(a_Pickup.GetPosX() * 8), (int)(a_Pickup.GetPosY() * 8), (int)(a_Pickup.GetPosZ() * 8),
- 0.5, (float)(0.75 + ((float)((a_Pickup.GetUniqueID() * 23) % 32)) / 64)
+ (int)(a_Entity.GetPosX() * 8), (int)(a_Entity.GetPosY() * 8), (int)(a_Entity.GetPosZ() * 8),
+ 0.5, (float)(0.75 + ((float)((a_Entity.GetUniqueID() * 23) % 32)) / 64)
);
}
diff --git a/src/Protocol/Protocol132.h b/src/Protocol/Protocol132.h
index 32bc7d581..e5d3ee80c 100644
--- a/src/Protocol/Protocol132.h
+++ b/src/Protocol/Protocol132.h
@@ -48,7 +48,7 @@ public:
virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
- virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
+ virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
diff --git a/src/Protocol/Protocol16x.cpp b/src/Protocol/Protocol16x.cpp
index 9e0f3f852..eba795f61 100644
--- a/src/Protocol/Protocol16x.cpp
+++ b/src/Protocol/Protocol16x.cpp
@@ -158,10 +158,10 @@ void cProtocol161::SendPlayerMaxSpeed(void)
-void cProtocol161::SendRespawn(const cWorld & a_World)
+void cProtocol161::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks)
{
// Besides sending the respawn, we need to also send the player max speed, otherwise the client reverts to super-fast
- super::SendRespawn(a_World);
+ super::SendRespawn(a_World, a_ShouldIgnoreDimensionChecks);
SendPlayerMaxSpeed();
}
diff --git a/src/Protocol/Protocol16x.h b/src/Protocol/Protocol16x.h
index e91dc8a1c..e6e79027e 100644
--- a/src/Protocol/Protocol16x.h
+++ b/src/Protocol/Protocol16x.h
@@ -42,7 +42,7 @@ protected:
virtual void SendGameMode (eGameMode a_GameMode) override;
virtual void SendHealth (void) override;
virtual void SendPlayerMaxSpeed(void) override;
- virtual void SendRespawn (const cWorld & a_World) override;
+ virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) override;
virtual void SendWindowOpen (const cWindow & a_Window) override;
virtual int ParseEntityAction (void) override;
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index 02c577dc8..855687269 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -351,12 +351,12 @@ void cProtocol172::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize
-void cProtocol172::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player)
+void cProtocol172::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
{
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x0d); // Collect Item packet
- Pkt.WriteInt(a_Pickup.GetUniqueID());
+ Pkt.WriteInt(a_Entity.GetUniqueID());
Pkt.WriteInt(a_Player.GetUniqueID());
}
@@ -986,11 +986,11 @@ void cProtocol172::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect
-void cProtocol172::SendRespawn(const cWorld & a_World)
+void cProtocol172::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks)
{
- if (m_LastSentDimension == a_World.GetDimension())
+ if ((m_LastSentDimension == a_World.GetDimension()) && !a_ShouldIgnoreDimensionChecks)
{
- // Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do
+ // Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do (unless we are respawning from death)
return;
}
@@ -1221,10 +1221,9 @@ void cProtocol172::SendStatistics(const cStatManager & a_Manager)
cPacketizer Pkt(*this, 0x37);
Pkt.WriteVarInt(statCount); // TODO 2014-05-11 xdot: Optimization: Send "dirty" statistics only
- for (unsigned int i = 0; i < (unsigned int)statCount; ++i)
+ for (size_t i = 0; i < (size_t)statCount; ++i)
{
StatValue Value = a_Manager.GetValue((eStatistic) i);
-
const AString & StatName = cStatInfo::GetName((eStatistic) i);
Pkt.WriteString(StatName);
@@ -2334,7 +2333,7 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
for (int loretag = NBT.GetFirstChild(displaytag); loretag >= 0; loretag = NBT.GetNextSibling(loretag)) // Loop through array of strings
{
- AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a newline, used internally by MCS to display a new line in the client; don't forget to c_str ;)
+ AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a grave accent/backtick, used internally by MCS to display a new line in the client; don't forget to c_str ;)
}
a_Item.m_Lore = Lore;
diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h
index 8be1d9211..1a65cfa1c 100644
--- a/src/Protocol/Protocol17x.h
+++ b/src/Protocol/Protocol17x.h
@@ -68,7 +68,7 @@ public:
virtual void SendChat (const AString & a_Message) override;
virtual void SendChat (const cCompositeChat & a_Message) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
- virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
+ virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
virtual void SendDisconnect (const AString & a_Reason) override;
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+)
@@ -104,7 +104,7 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
- virtual void SendRespawn (const cWorld & a_World) override;
+ virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) override;
virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8
virtual void SendExperience (void) override;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp
index 35a331f43..c0c9e08ee 100644
--- a/src/Protocol/ProtocolRecognizer.cpp
+++ b/src/Protocol/ProtocolRecognizer.cpp
@@ -37,6 +37,7 @@ cProtocolRecognizer::cProtocolRecognizer(cClientHandle * a_Client) :
cProtocolRecognizer::~cProtocolRecognizer()
{
delete m_Protocol;
+ m_Protocol = NULL;
}
@@ -180,10 +181,10 @@ void cProtocolRecognizer::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSe
-void cProtocolRecognizer::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player)
+void cProtocolRecognizer::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
{
ASSERT(m_Protocol != NULL);
- m_Protocol->SendCollectPickup(a_Pickup, a_Player);
+ m_Protocol->SendCollectEntity(a_Entity, a_Player);
}
@@ -555,10 +556,10 @@ void cProtocolRecognizer::SendRemoveEntityEffect(const cEntity & a_Entity, int a
-void cProtocolRecognizer::SendRespawn(const cWorld & a_World)
+void cProtocolRecognizer::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks)
{
ASSERT(m_Protocol != NULL);
- m_Protocol->SendRespawn(a_World);
+ m_Protocol->SendRespawn(a_World, a_ShouldIgnoreDimensionChecks);
}
diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h
index 5e178447c..0a9a42e93 100644
--- a/src/Protocol/ProtocolRecognizer.h
+++ b/src/Protocol/ProtocolRecognizer.h
@@ -71,7 +71,7 @@ public:
virtual void SendChat (const AString & a_Message) override;
virtual void SendChat (const cCompositeChat & a_Message) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
- virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
+ virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
virtual void SendDisconnect (const AString & a_Reason) override;
virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+)
@@ -107,7 +107,7 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
- virtual void SendRespawn (const cWorld & a_World) override;
+ virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) override;
virtual void SendExperience (void) override;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
diff --git a/src/Server.cpp b/src/Server.cpp
index 66bccd680..2c695cc70 100644
--- a/src/Server.cpp
+++ b/src/Server.cpp
@@ -326,6 +326,7 @@ void cServer::OnConnectionAccepted(cSocket & a_Socket)
LOGERROR("Client \"%s\" cannot be handled, server probably unstable", ClientIP.c_str());
a_Socket.CloseSocket();
delete NewHandle;
+ NewHandle = NULL;
return;
}
diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp
index e95af3a1c..4ffda2365 100644
--- a/src/Simulator/FloodyFluidSimulator.cpp
+++ b/src/Simulator/FloodyFluidSimulator.cpp
@@ -217,14 +217,20 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i
{
ASSERT(a_NewMeta <= 8); // Invalid meta values
ASSERT(a_NewMeta > 0); // Source blocks aren't spread
-
- BLOCKTYPE BlockType;
- NIBBLETYPE BlockMeta;
- if (!a_NearChunk->UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta))
+
+ a_NearChunk = a_NearChunk->GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ);
+ if ((a_NearChunk == NULL) || (!a_NearChunk->IsValid()))
{
// Chunk not available
return;
}
+
+ const int BlockX = a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX;
+ const int BlockZ = a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ;
+
+ BLOCKTYPE BlockType;
+ NIBBLETYPE BlockMeta;
+ a_NearChunk->GetBlockTypeMeta(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta);
if (IsAllowedBlock(BlockType))
{
@@ -246,15 +252,9 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i
a_RelX, a_RelY, a_RelZ,
ItemTypeToString(NewBlock).c_str()
);
- a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0);
+ a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0);
- int BaseX = a_NearChunk->GetPosX() * cChunkDef::Width;
- int BaseZ = a_NearChunk->GetPosZ() * cChunkDef::Width;
-
- BaseX += a_RelX;
- BaseZ += a_RelZ;
-
- a_NearChunk->BroadcastSoundEffect("random.fizz", BaseX * 8, a_RelY * 8, BaseZ * 8, 0.5f, 1.5f);
+ a_NearChunk->BroadcastSoundEffect("random.fizz", BlockX * 8, a_RelY * 8, BlockZ * 8, 0.5f, 1.5f);
return;
}
}
@@ -267,15 +267,9 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i
FLOG(" Water flowing into lava, turning lava at rel {%d, %d, %d} into %s",
a_RelX, a_RelY, a_RelZ, ItemTypeToString(NewBlock).c_str()
);
- a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0);
-
- int BaseX = a_NearChunk->GetPosX() * cChunkDef::Width;
- int BaseZ = a_NearChunk->GetPosZ() * cChunkDef::Width;
-
- BaseX += a_RelX;
- BaseZ += a_RelZ;
+ a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0);
- a_NearChunk->BroadcastSoundEffect("random.fizz", BaseX * 8, a_RelY * 8, BaseZ * 8, 0.5f, 1.5f);
+ a_NearChunk->BroadcastSoundEffect("random.fizz", BlockX * 8, a_RelY * 8, BlockZ * 8, 0.5f, 1.5f);
return;
}
}
@@ -303,21 +297,17 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i
m_World,
PluginInterface,
NULL,
- a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX,
+ BlockX,
a_RelY,
- a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ
+ BlockZ
);
}
} // if (CanWashAway)
-
+
// Spread:
- FLOG(" Spreading to {%d, %d, %d} with meta %d",
- a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX,
- a_RelY,
- a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ,
- a_NewMeta
- );
- a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta);
+ FLOG(" Spreading to {%d, %d, %d} with meta %d", BlockX, a_RelY, BlockZ, a_NewMeta);
+ a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta);
+ m_World.GetSimulatorManager()->WakeUp(BlockX, a_RelY, BlockZ, a_NearChunk);
HardenBlock(a_NearChunk, a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta);
}
@@ -409,13 +399,13 @@ bool cFloodyFluidSimulator::HardenBlock(cChunk * a_Chunk, int a_RelX, int a_RelY
if (a_Meta == 0)
{
// Source lava block
- a_Chunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_OBSIDIAN, 0);
+ a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_OBSIDIAN, 0);
return true;
}
// Ignore last lava level
else if (a_Meta <= 4)
{
- a_Chunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_COBBLESTONE, 0);
+ a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_COBBLESTONE, 0);
return true;
}
}
diff --git a/src/Simulator/FluidSimulator.cpp b/src/Simulator/FluidSimulator.cpp
index 4a84084d2..f64955cb2 100644
--- a/src/Simulator/FluidSimulator.cpp
+++ b/src/Simulator/FluidSimulator.cpp
@@ -169,7 +169,8 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a
X = Pos->x;
Z = Pos->z;
}
- }else if(BlockID == E_BLOCK_AIR)
+ }
+ else if(BlockID == E_BLOCK_AIR)
{
LowestPoint = 9; //This always dominates
X = Pos->x;
@@ -177,6 +178,7 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a
}
delete Pos;
+ Pos = NULL;
}
if (LowestPoint == m_World.GetBlockMeta(a_X, a_Y, a_Z))
diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp
index b8da978f2..5af9a295d 100644
--- a/src/Simulator/IncrementalRedstoneSimulator.cpp
+++ b/src/Simulator/IncrementalRedstoneSimulator.cpp
@@ -2,6 +2,7 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "IncrementalRedstoneSimulator.h"
+#include "BoundingBox.h"
#include "../BlockEntities/DropSpenserEntity.h"
#include "../BlockEntities/NoteEntity.h"
#include "../BlockEntities/CommandBlockEntity.h"
@@ -12,10 +13,13 @@
#include "../Blocks/BlockButton.h"
#include "../Blocks/BlockLever.h"
#include "../Blocks/BlockPiston.h"
+#include "../Blocks/BlockTripwireHook.h"
+
+#define WAKE_SIMULATOR_IF_DIRTY(a_Chunk, a_BlockX, a_BlockY, a_BlockZ) if (a_Chunk->IsRedstoneDirty()) WakeUp(a_BlockX, a_BlockY, a_BlockZ, a_Chunk);
+
-
cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulator(cWorld & a_World) :
super(a_World),
@@ -59,21 +63,20 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
int RelZ = 0;
BLOCKTYPE Block;
NIBBLETYPE Meta;
- cChunk * Chunk;
+ cChunk * OtherChunk = a_Chunk;
if (a_OtherChunk != NULL)
{
RelX = a_BlockX - a_OtherChunk->GetPosX() * cChunkDef::Width;
RelZ = a_BlockZ - a_OtherChunk->GetPosZ() * cChunkDef::Width;
a_OtherChunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta);
- Chunk = a_OtherChunk;
+ OtherChunk = a_OtherChunk;
}
else
{
RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width;
RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width;
a_Chunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta);
- Chunk = a_Chunk;
}
// Every time a block is changed (AddBlock called), we want to go through all lists and check to see if the coordiantes stored within are still valid
@@ -92,36 +95,40 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list as it no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = PoweredBlocks->erase(itr);
- Chunk->SetIsRedstoneDirty(true);
+ a_Chunk->SetIsRedstoneDirty(true);
+ OtherChunk->SetIsRedstoneDirty(true);
continue;
}
else if (
// Changeable sources
((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) ||
((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) ||
- ((Block == E_BLOCK_DETECTOR_RAIL) && (Meta & 0x08) == 0) ||
+ ((Block == E_BLOCK_DETECTOR_RAIL) && ((Meta & 0x08) == 0)) ||
(((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))
+ (((Block == E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE) || (Block == E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE)) && (Meta == 0)) ||
+ ((Block == E_BLOCK_TRIPWIRE_HOOK) && ((Meta & 0x08) == 0))
)
{
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = PoweredBlocks->erase(itr);
- Chunk->SetIsRedstoneDirty(true);
+ a_Chunk->SetIsRedstoneDirty(true);
+ OtherChunk->SetIsRedstoneDirty(true);
continue;
}
else if (Block == E_BLOCK_DAYLIGHT_SENSOR)
{
- if (!m_World.IsChunkLighted(Chunk->GetPosX(), Chunk->GetPosZ()))
+ if (!m_World.IsChunkLighted(OtherChunk->GetPosX(), OtherChunk->GetPosZ()))
{
- m_World.QueueLightChunk(Chunk->GetPosX(), Chunk->GetPosZ());
+ m_World.QueueLightChunk(OtherChunk->GetPosX(), OtherChunk->GetPosZ());
}
else
{
- if (Chunk->GetTimeAlteredLight(Chunk->GetSkyLight(RelX, a_BlockY + 1, RelZ)) <= 7)
+ if (OtherChunk->GetTimeAlteredLight(OtherChunk->GetSkyLight(RelX, a_BlockY + 1, RelZ)) <= 7)
{
itr = PoweredBlocks->erase(itr);
- Chunk->SetIsRedstoneDirty(true);
+ a_Chunk->SetIsRedstoneDirty(true);
+ OtherChunk->SetIsRedstoneDirty(true);
continue;
}
}
@@ -139,7 +146,8 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = LinkedPoweredBlocks->erase(itr);
- Chunk->SetIsRedstoneDirty(true);
+ a_Chunk->SetIsRedstoneDirty(true);
+ OtherChunk->SetIsRedstoneDirty(true);
continue;
}
else if (
@@ -153,7 +161,8 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{
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);
itr = LinkedPoweredBlocks->erase(itr);
- Chunk->SetIsRedstoneDirty(true);
+ a_Chunk->SetIsRedstoneDirty(true);
+ OtherChunk->SetIsRedstoneDirty(true);
continue;
}
}
@@ -163,7 +172,8 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer powered through a valid middle block", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = LinkedPoweredBlocks->erase(itr);
- Chunk->SetIsRedstoneDirty(true);
+ a_Chunk->SetIsRedstoneDirty(true);
+ OtherChunk->SetIsRedstoneDirty(true);
continue;
}
}
@@ -271,6 +281,8 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
ShouldUpdateSimulateOnceBlocks = true;
}
+ HandleRedstoneRepeaterDelays();
+
for (cRedstoneSimulatorChunkData::iterator dataitr = m_RedstoneSimulatorChunkData->begin(); dataitr != m_RedstoneSimulatorChunkData->end();)
{
if (dataitr->DataTwo)
@@ -282,26 +294,9 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
switch (dataitr->Data)
{
case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_TRIPWIRE: HandleTripwire(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_TRIPWIRE_HOOK: HandleTripwireHook(dataitr->x, dataitr->y, dataitr->z); break;
- case E_BLOCK_REDSTONE_REPEATER_OFF:
- case E_BLOCK_REDSTONE_REPEATER_ON:
- {
- bool FoundItem = false;
- for (RepeatersDelayList::iterator repeateritr = m_RepeatersDelayList->begin(); repeateritr != m_RepeatersDelayList->end(); ++repeateritr)
- {
- if (repeateritr->a_RelBlockPos == Vector3i(dataitr->x, dataitr->y, dataitr->z))
- {
- HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data, repeateritr);
- FoundItem = true;
- break;
- }
- }
- if (!FoundItem && ShouldUpdateSimulateOnceBlocks)
- {
- HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data, m_RepeatersDelayList->end());
- }
- break;
- }
case E_BLOCK_WOODEN_PRESSURE_PLATE:
case E_BLOCK_STONE_PRESSURE_PLATE:
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
@@ -357,6 +352,12 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
HandlePiston(dataitr->x, dataitr->y, dataitr->z);
break;
}
+ case E_BLOCK_REDSTONE_REPEATER_OFF:
+ case E_BLOCK_REDSTONE_REPEATER_ON:
+ {
+ HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
+ break;
+ }
case E_BLOCK_REDSTONE_TORCH_OFF:
case E_BLOCK_REDSTONE_TORCH_ON:
{
@@ -511,29 +512,10 @@ void cIncrementalRedstoneSimulator::HandleRedstoneLever(int a_RelBlockX, int a_R
{
SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
- 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;
- }
- }
+ eBlockFace Dir = cBlockLeverHandler::BlockMetaDataToBlockFace(Meta);
+
+ Dir = ReverseBlockFace(Dir);
+
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir);
}
}
@@ -552,8 +534,11 @@ void cIncrementalRedstoneSimulator::HandleFenceGate(int a_RelBlockX, int a_RelBl
{
if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true))
{
- m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData | 0x4);
- m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0);
+ if ((MetaData & 0x4) == 0)
+ {
+ 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);
}
}
@@ -561,8 +546,11 @@ void cIncrementalRedstoneSimulator::HandleFenceGate(int a_RelBlockX, int a_RelBl
{
if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false))
{
- m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData & 0xFFFFFFFB);
- m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0);
+ if ((MetaData & 0x4) != 0)
+ {
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData & ~0x04);
+ m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0);
+ }
SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false);
}
}
@@ -579,27 +567,8 @@ void cIncrementalRedstoneSimulator::HandleRedstoneButton(int a_RelBlockX, int a_
{
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;
- }
- }
+ eBlockFace Dir = cBlockButtonHandler::BlockMetaDataToBlockFace(Meta);
+ Dir = ReverseBlockFace(Dir);
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir);
}
}
@@ -766,7 +735,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_RelBlockX, int a_Re
-void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState, RepeatersDelayList::iterator a_Itr)
+void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState)
{
/* Repeater Orientation Mini Guide:
===================================
@@ -793,102 +762,80 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int
NIBBLETYPE a_Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
bool IsOn = (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON);
- bool WereItrsChanged = false;
if (!IsRepeaterLocked(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta)) // If we're locked, change nothing. Otherwise:
{
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.
{
- WereItrsChanged = QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 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.
{
- WereItrsChanged = QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false);
- }
- else if (a_Itr == m_RepeatersDelayList->end())
- {
- return;
+ QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false);
}
}
- else if (a_Itr == m_RepeatersDelayList->end())
- {
- return;
- }
+}
- if (WereItrsChanged)
+void cIncrementalRedstoneSimulator::HandleRedstoneRepeaterDelays()
+{
+ for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end();)
{
- for (a_Itr = m_RepeatersDelayList->begin(); a_Itr != m_RepeatersDelayList->end(); ++a_Itr)
- {
- if (a_Itr->a_RelBlockPos == Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ))
- {
- // Leave a_Itr at where we found the entry
- break;
- }
- }
- }
- // a_Itr may be passed with m_RepeatersDelayList::end, however, we can guarantee this iterator is always valid because...
- // ...QueueRepeaterPowerChange is called to add an entry (and the above code updates iterator). However, if the repeater was locked or something similar...
- // ...we will never get here because of the returns.
- if (a_Itr->a_ElapsedTicks >= a_Itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks?
- {
- if (a_Itr->ShouldPowerOn)
+ if (itr->a_ElapsedTicks >= itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks?
{
- if (!IsOn)
+ int RelBlockX = itr->a_RelBlockPos.x;
+ int RelBlockY = itr->a_RelBlockPos.y;
+ int RelBlockZ = itr->a_RelBlockPos.z;
+ NIBBLETYPE Meta = m_Chunk->GetMeta(RelBlockX, RelBlockY, RelBlockZ);
+ if (itr->ShouldPowerOn)
{
- m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); // For performance
- }
+
+ m_Chunk->SetBlock(itr->a_RelBlockPos, E_BLOCK_REDSTONE_REPEATER_ON, Meta); // For performance
- switch (a_Meta & 0x3) // We only want the direction (bottom) bits
- {
- case 0x0:
+ switch (Meta & 0x3) // We only want the direction (bottom) bits
{
- 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_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_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_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
- SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XM);
- break;
+ case 0x0:
+ {
+ SetBlockPowered(RelBlockX, RelBlockY, RelBlockZ - 1, RelBlockX, RelBlockY, RelBlockZ);
+ SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_ZM);
+ break;
+ }
+ case 0x1:
+ {
+ SetBlockPowered(RelBlockX + 1, RelBlockY, RelBlockZ, RelBlockX, RelBlockY, RelBlockZ);
+ SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_XP);
+ break;
+ }
+ case 0x2:
+ {
+ SetBlockPowered(RelBlockX, RelBlockY, RelBlockZ + 1, RelBlockX, RelBlockY, RelBlockZ);
+ SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_ZP);
+ break;
+ }
+ case 0x3:
+ {
+ SetBlockPowered(RelBlockX - 1, RelBlockY, RelBlockZ, RelBlockX, RelBlockY, RelBlockZ);
+ SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_XM);
+ break;
+ }
}
}
-
- // Removal of the data entry will be handled in SimChunk - we still want to continue trying to power blocks, even if our delay time has reached
- // Otherwise, the power state of blocks in front won't update after we have powered on
- return;
+ else
+ {
+ m_Chunk->SetBlock(RelBlockX, RelBlockY, RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, Meta);
+ }
+ itr = m_RepeatersDelayList->erase(itr);
}
else
{
- if (IsOn)
- {
- m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta);
- }
- m_RepeatersDelayList->erase(a_Itr); // We can remove off repeaters which don't need further updating
- return;
+ // 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_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks);
+ itr->a_ElapsedTicks++;
+ itr++;
}
}
- else
- {
- // 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", a_Itr->a_RelBlockPos.x, a_Itr->a_RelBlockPos.y, a_Itr->a_RelBlockPos.z, a_Itr->a_ElapsedTicks, a_Itr->a_DelayTicks);
- a_Itr->a_ElapsedTicks++;
- }
}
@@ -1146,19 +1093,17 @@ void cIncrementalRedstoneSimulator::HandleNoteBlock(int a_RelBlockX, int a_RelBl
void cIncrementalRedstoneSimulator::HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
- int a_ChunkX, a_ChunkZ;
- cChunkDef::BlockToChunk(a_RelBlockX, a_RelBlockZ, a_ChunkX, a_ChunkZ);
+ int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX, BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+ int ChunkX, ChunkZ;
+ cChunkDef::BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ);
- if (!m_World.IsChunkLighted(a_ChunkX, a_ChunkZ))
+ if (!m_World.IsChunkLighted(ChunkX, ChunkZ))
{
- m_World.QueueLightChunk(a_ChunkX, a_ChunkZ);
+ m_World.QueueLightChunk(ChunkX, ChunkZ);
}
else
{
- 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)
+ if (m_Chunk->GetTimeAlteredLight(m_World.GetBlockSkyLight(BlockX, a_RelBlockY + 1, BlockZ)) > 8)
{
SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
}
@@ -1183,7 +1128,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
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(BlockX + 0.5f, (float)a_RelBlockY, BlockZ + 0.5f), 0.7f, false);
+ cPlayer * a_Player = m_World.FindClosestPlayer(Vector3f(BlockX + 0.5f, (float)a_RelBlockY, BlockZ + 0.5f), 0.5f, false);
if (a_Player != NULL)
{
@@ -1194,7 +1139,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
else
{
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0);
- m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ);
+ WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
}
break;
}
@@ -1218,7 +1163,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f);
double Distance = (EntityPos - BlockPos).Length();
- if (Distance <= 0.7)
+ if (Distance <= 0.5)
{
m_NumberOfEntities++;
}
@@ -1240,7 +1185,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
};
cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ);
- m_World.ForEachEntity(PressurePlateCallback);
+ m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback);
unsigned char Power;
NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
@@ -1261,7 +1206,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
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);
+ WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
}
break;
@@ -1286,7 +1231,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f);
double Distance = (EntityPos - BlockPos).Length();
- if (Distance <= 0.7)
+ if (Distance <= 0.5)
{
m_NumberOfEntities++;
}
@@ -1295,7 +1240,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
bool GetPowerLevel(unsigned char & a_PowerLevel) const
{
- a_PowerLevel = std::min((int)ceil(m_NumberOfEntities / (float)10), MAX_POWER_LEVEL);
+ a_PowerLevel = std::min((int)ceil(m_NumberOfEntities / 10.f), MAX_POWER_LEVEL);
return (a_PowerLevel > 0);
}
@@ -1308,7 +1253,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
};
cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ);
- m_World.ForEachEntity(PressurePlateCallback);
+ m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback);
unsigned char Power;
NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
@@ -1329,7 +1274,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
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);
+ WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
}
break;
@@ -1354,7 +1299,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f);
double Distance = (EntityPos - BlockPos).Length();
- if (Distance <= 0.7)
+ if (Distance <= 0.5)
{
m_FoundEntity = true;
return true; // Break out, we only need to know for plates that at least one entity is on top
@@ -1376,7 +1321,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
} ;
cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ);
- m_World.ForEachEntity(PressurePlateCallback);
+ m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback);
NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
if (PressurePlateCallback.FoundEntity())
@@ -1396,7 +1341,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
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);
+ WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
}
break;
}
@@ -1412,6 +1357,131 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R
+void cIncrementalRedstoneSimulator::HandleTripwireHook(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;
+ int RelX = a_RelBlockX, RelZ = a_RelBlockZ;
+ bool FoundActivated = false;
+ eBlockFace FaceToGoTowards = cBlockTripwireHookHandler::MetadataToDirection(m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ));
+
+ for (int i = 0; i < 40; ++i) // Tripwires can be connected up to 40 blocks
+ {
+ BLOCKTYPE Type;
+ NIBBLETYPE Meta;
+
+ AddFaceDirection(RelX, a_RelBlockY, RelZ, FaceToGoTowards);
+ m_Chunk->UnboundedRelGetBlock(RelX, a_RelBlockY, RelZ, Type, Meta);
+
+ if (Type == E_BLOCK_TRIPWIRE)
+ {
+ if (Meta == 0x1)
+ {
+ FoundActivated = true;
+ }
+ }
+ else if (Type == E_BLOCK_TRIPWIRE_HOOK)
+ {
+ if (ReverseBlockFace(cBlockTripwireHookHandler::MetadataToDirection(Meta)) == FaceToGoTowards)
+ {
+ // Other hook not facing in opposite direction
+ break;
+ }
+ else
+ {
+ // Tripwire hook not connected at all, AND away all the power state bits
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3);
+ WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
+ return;
+ }
+ }
+ else
+ {
+ // Tripwire hook not connected at all, AND away all the power state bits
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3);
+ WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
+ return;
+ }
+ }
+
+ if (FoundActivated)
+ {
+ // Connected and activated, set the 3rd and 4th highest bits
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) | 0xC);
+ SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ }
+ else
+ {
+ // Connected but not activated, AND away the highest bit
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, (m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x7) | 0x4);
+ WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ);
+ }
+}
+
+
+
+
+
+void cIncrementalRedstoneSimulator::HandleTripwire(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;
+
+ class cTripwireCallback :
+ public cEntityCallback
+ {
+ public:
+ cTripwireCallback(int a_BlockX, int a_BlockY, int a_BlockZ) :
+ m_FoundEntity(false),
+ m_X(a_BlockX),
+ m_Y(a_BlockY),
+ m_Z(a_BlockZ)
+ {
+ }
+
+ virtual bool Item(cEntity * a_Entity) override
+ {
+ cBoundingBox bbWire(m_X, m_X + 1, m_Y, m_Y + 0.1, m_Z, m_Z + 1);
+ cBoundingBox bbEntity(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight());
+
+ if (bbEntity.DoesIntersect(bbWire))
+ {
+ m_FoundEntity = true;
+ return true; // One entity is sufficient to trigger the wire
+ }
+ return false;
+ }
+
+ bool FoundEntity(void) const
+ {
+ return m_FoundEntity;
+ }
+
+ protected:
+ bool m_FoundEntity;
+
+ int m_X;
+ int m_Y;
+ int m_Z;
+ };
+
+ cTripwireCallback TripwireCallback(BlockX, a_RelBlockY, BlockZ);
+ m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), TripwireCallback);
+
+ if (TripwireCallback.FoundEntity())
+ {
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x1);
+ }
+ else
+ {
+ m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0);
+ }
+}
+
+
+
+
+
bool cIncrementalRedstoneSimulator::AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
@@ -1630,7 +1700,7 @@ bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBloc
{
continue;
}
- a_PowerLevel = itr->a_PowerLevel;
+ a_PowerLevel = std::max(itr->a_PowerLevel , a_PowerLevel); // Get the highest power level (a_PowerLevel is initialised already and there CAN be multiple levels for one block)
}
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) // Check linked powered list
@@ -1639,7 +1709,7 @@ bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBloc
{
continue;
}
- a_PowerLevel = itr->a_PowerLevel;
+ a_PowerLevel = std::max(itr->a_PowerLevel, a_PowerLevel);
}
return (a_PowerLevel != 0); // Answer the inital question: is the wire powered?
diff --git a/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h
index 1d6a49aca..6cefdebf2 100644
--- a/src/Simulator/IncrementalRedstoneSimulator.h
+++ b/src/Simulator/IncrementalRedstoneSimulator.h
@@ -102,13 +102,20 @@ private:
void HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles pressure plates */
void HandlePressurePlate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType);
+ /** Handles tripwire hooks
+ Performs correct meta and power setting for self by going in the direction it faces and looking for a continous line of tripwire bounded by another oppositely facing hook
+ If this line is complete, it verifies that at least on wire reports an entity is on top (via its meta), and performs its task
+ */
+ void HandleTripwireHook(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/* ==================== */
/* ====== CARRIERS ====== */
/** Handles redstone wire */
void HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles repeaters */
- void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState, RepeatersDelayList::iterator a_Itr);
+ void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
+ /** Handles delayed updates to Repeaters **/
+ void HandleRedstoneRepeaterDelays();
/* ====================== */
/* ====== DEVICES ====== */
@@ -132,6 +139,8 @@ private:
void HandleFenceGate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles noteblocks */
void HandleNoteBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
+ /** Handles tripwires */
+ void HandleTripwire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/* ===================== */
/* ====== Helper functions ====== */
@@ -269,6 +278,7 @@ private:
case E_BLOCK_TNT:
case E_BLOCK_TRAPDOOR:
case E_BLOCK_TRIPWIRE_HOOK:
+ case E_BLOCK_TRIPWIRE:
case E_BLOCK_WOODEN_BUTTON:
case E_BLOCK_WOODEN_DOOR:
case E_BLOCK_WOODEN_PRESSURE_PLATE:
diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp
index 728692f2a..e220960ff 100644
--- a/src/UI/SlotArea.cpp
+++ b/src/UI/SlotArea.cpp
@@ -60,12 +60,35 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA
ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
return;
}
-
case caDblClick:
{
DblClicked(a_Player, a_SlotNum);
return;
}
+ case caMiddleClick:
+ {
+ MiddleClicked(a_Player, a_SlotNum);
+ return;
+ }
+ case caDropKey:
+ case caCtrlDropKey:
+ {
+ DropClicked(a_Player, a_SlotNum, (a_ClickAction == caCtrlDropKey));
+ return;
+ }
+ case caNumber1:
+ case caNumber2:
+ case caNumber3:
+ case caNumber4:
+ case caNumber5:
+ case caNumber6:
+ case caNumber7:
+ case caNumber8:
+ case caNumber9:
+ {
+ NumberClicked(a_Player, a_SlotNum, a_ClickAction);
+ return;
+ }
default:
{
break;
@@ -226,6 +249,77 @@ void cSlotArea::DblClicked(cPlayer & a_Player, int a_SlotNum)
+void cSlotArea::MiddleClicked(cPlayer & a_Player, int a_SlotNum)
+{
+ cItem Slot(*GetSlot(a_SlotNum, a_Player));
+ cItem & DraggingItem = a_Player.GetDraggingItem();
+
+ if (!a_Player.IsGameModeCreative() || Slot.IsEmpty() || !DraggingItem.IsEmpty())
+ {
+ return;
+ }
+
+ DraggingItem = Slot;
+ DraggingItem.m_ItemCount = DraggingItem.GetMaxStackSize();
+}
+
+
+
+
+
+void cSlotArea::DropClicked(cPlayer & a_Player, int a_SlotNum, bool a_DropStack)
+{
+ cItem Slot(*GetSlot(a_SlotNum, a_Player));
+ if (Slot.IsEmpty())
+ {
+ return;
+ }
+
+ cItem ItemToDrop = Slot.CopyOne();
+ if (a_DropStack)
+ {
+ ItemToDrop.m_ItemCount = Slot.m_ItemCount;
+ }
+
+ Slot.m_ItemCount -= ItemToDrop.m_ItemCount;
+ if (Slot.m_ItemCount <= 0)
+ {
+ Slot.Empty();
+ }
+ SetSlot(a_SlotNum, a_Player, Slot);
+
+ a_Player.TossPickup(ItemToDrop);
+}
+
+
+
+
+
+void cSlotArea::NumberClicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction)
+{
+ if ((a_ClickAction < caNumber1) || (a_ClickAction > caNumber9))
+ {
+ return;
+ }
+
+ int HotbarSlot = (int)a_ClickAction - (int)caNumber1;
+ cItem ItemInHotbar(a_Player.GetInventory().GetHotbarSlot(HotbarSlot));
+ cItem ItemInSlot(*GetSlot(a_SlotNum, a_Player));
+
+ // The items are equal. Do nothing.
+ if (ItemInHotbar.IsEqual(ItemInSlot))
+ {
+ return;
+ }
+
+ a_Player.GetInventory().SetHotbarSlot(HotbarSlot, ItemInSlot);
+ SetSlot(a_SlotNum, a_Player, ItemInHotbar);
+}
+
+
+
+
+
void cSlotArea::OnPlayerAdded(cPlayer & a_Player)
{
UNUSED(a_Player);
@@ -410,6 +504,12 @@ cSlotAreaCrafting::cSlotAreaCrafting(int a_GridSize, cWindow & a_ParentWindow) :
void cSlotAreaCrafting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem)
{
+ if (a_ClickAction == caMiddleClick)
+ {
+ MiddleClicked(a_Player, a_SlotNum);
+ return;
+ }
+
// Override for craft result slot
if (a_SlotNum == 0)
{
@@ -417,12 +517,17 @@ void cSlotAreaCrafting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction
{
ShiftClickedResult(a_Player);
}
+ else if ((a_ClickAction == caDropKey) || (a_ClickAction == caCtrlDropKey))
+ {
+ DropClickedResult(a_Player);
+ }
else
{
ClickedResult(a_Player);
}
return;
}
+
super::Clicked(a_Player, a_SlotNum, a_ClickAction, a_ClickedItem);
UpdateRecipe(a_Player);
}
@@ -468,6 +573,20 @@ void cSlotAreaCrafting::OnPlayerRemoved(cPlayer & a_Player)
+void cSlotAreaCrafting::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item)
+{
+ // Update the recipe after setting the slot, if the slot is not the result slot:
+ super::SetSlot(a_SlotNum, a_Player, a_Item);
+ if (a_SlotNum != 0)
+ {
+ UpdateRecipe(a_Player);
+ }
+}
+
+
+
+
+
void cSlotAreaCrafting::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots)
{
UNUSED(a_ItemStack);
@@ -545,16 +664,20 @@ void cSlotAreaCrafting::ShiftClickedResult(cPlayer & a_Player)
// Distribute the result, this time for real:
ResultCopy = Result;
m_ParentWindow.DistributeStack(ResultCopy, a_Player, this, true);
-
+
// Remove the ingredients from the crafting grid and update the recipe:
cCraftingRecipe & Recipe = GetRecipeForPlayer(a_Player);
cCraftingGrid Grid(PlayerSlots, m_GridSize, m_GridSize);
Recipe.ConsumeIngredients(Grid);
Grid.CopyToItems(PlayerSlots);
UpdateRecipe(a_Player);
+
+ // Broadcast the window, we sometimes move items to different locations than Vanilla, causing needless desyncs:
+ m_ParentWindow.BroadcastWholeWindow();
+
+ // If the recipe has changed, bail out:
if (!Recipe.GetResult().IsEqual(Result))
{
- // The recipe has changed, bail out
return;
}
}
@@ -564,6 +687,27 @@ void cSlotAreaCrafting::ShiftClickedResult(cPlayer & a_Player)
+void cSlotAreaCrafting::DropClickedResult(cPlayer & a_Player)
+{
+ // Get the current recipe:
+ cCraftingRecipe & Recipe = GetRecipeForPlayer(a_Player);
+ const cItem & Result = Recipe.GetResult();
+
+ cItem * PlayerSlots = GetPlayerSlots(a_Player) + 1;
+ cCraftingGrid Grid(PlayerSlots, m_GridSize, m_GridSize);
+
+ a_Player.TossPickup(Result);
+ Recipe.ConsumeIngredients(Grid);
+ Grid.CopyToItems(PlayerSlots);
+
+ HandleCraftItem(Result, a_Player);
+ UpdateRecipe(a_Player);
+}
+
+
+
+
+
void cSlotAreaCrafting::UpdateRecipe(cPlayer & a_Player)
{
cCraftingGrid Grid(GetPlayerSlots(a_Player) + 1, m_GridSize, m_GridSize);
@@ -651,15 +795,37 @@ void cSlotAreaAnvil::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_C
return;
}
- if (a_ClickAction == caDblClick)
- {
- return;
- }
-
- if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick))
+ switch (a_ClickAction)
{
- ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
- return;
+ case caDblClick:
+ {
+ return;
+ }
+ case caShiftLeftClick:
+ case caShiftRightClick:
+ {
+ ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
+ return;
+ }
+ case caMiddleClick:
+ {
+ MiddleClicked(a_Player, a_SlotNum);
+ return;
+ }
+ case caDropKey:
+ case caCtrlDropKey:
+ {
+ if (CanTakeResultItem(a_Player))
+ {
+ DropClicked(a_Player, a_SlotNum, true);
+ OnTakeResult(a_Player);
+ }
+ return;
+ }
+ default:
+ {
+ break;
+ }
}
cItem Slot(*GetSlot(a_SlotNum, a_Player));
@@ -1057,12 +1223,16 @@ void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickActio
ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
return;
}
-
case caDblClick:
{
DblClicked(a_Player, a_SlotNum);
return;
}
+ case caMiddleClick:
+ {
+ MiddleClicked(a_Player, a_SlotNum);
+ return;
+ }
default:
{
break;
@@ -1341,8 +1511,7 @@ cSlotAreaEnderChest::cSlotAreaEnderChest(cEnderChestEntity * a_EnderChest, cWind
const cItem * cSlotAreaEnderChest::GetSlot(int a_SlotNum, cPlayer & a_Player) const
{
- // a_SlotNum ranges from 0 to 26, use that to index the chest entity's inventory directly:
- return &(m_EnderChest->GetSlot(a_SlotNum));
+ return &(a_Player.GetEnderChestContents().GetSlot(a_SlotNum));
}
@@ -1351,7 +1520,7 @@ const cItem * cSlotAreaEnderChest::GetSlot(int a_SlotNum, cPlayer & a_Player) co
void cSlotAreaEnderChest::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item)
{
- m_EnderChest->SetSlot(a_SlotNum, a_Item);
+ a_Player.GetEnderChestContents().SetSlot(a_SlotNum, a_Item);
}
@@ -1408,11 +1577,32 @@ void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a
bAsync = true;
}
- if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick))
+ switch (a_ClickAction)
{
- HandleSmeltItem(Slot, a_Player);
- ShiftClicked(a_Player, a_SlotNum, Slot);
- return;
+ case caShiftLeftClick:
+ case caShiftRightClick:
+ {
+ HandleSmeltItem(Slot, a_Player);
+ ShiftClicked(a_Player, a_SlotNum, Slot);
+ return;
+ }
+ case caMiddleClick:
+ {
+ MiddleClicked(a_Player, a_SlotNum);
+ return;
+ }
+ case caDropKey:
+ case caCtrlDropKey:
+ {
+ DropClicked(a_Player, a_SlotNum, (a_SlotNum == caCtrlDropKey));
+ Slot.m_ItemCount = Slot.m_ItemCount - GetSlot(a_SlotNum, a_Player)->m_ItemCount;
+ HandleSmeltItem(Slot, a_Player);
+ return;
+ }
+ default:
+ {
+ break;
+ }
}
cItem & DraggingItem = a_Player.GetDraggingItem();
@@ -1590,6 +1780,12 @@ void cSlotAreaInventoryBase::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAc
{
if (a_Player.IsGameModeCreative() && (m_ParentWindow.GetWindowType() == cWindow::wtInventory))
{
+ if ((a_ClickAction == caDropKey) || (a_ClickAction == caCtrlDropKey))
+ {
+ DropClicked(a_Player, a_SlotNum, (a_ClickAction == caCtrlDropKey));
+ return;
+ }
+
// Creative inventory must treat a_ClickedItem as a DraggedItem instead, replacing the inventory slot with it
SetSlot(a_SlotNum, a_Player, a_ClickedItem);
return;
@@ -1677,16 +1873,28 @@ void cSlotAreaArmor::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_C
return;
}
- if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick))
- {
- ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
- return;
- }
-
- // Armors haven't a dbl click
- if (a_ClickAction == caDblClick)
+ switch (a_ClickAction)
{
- return;
+ case caDblClick:
+ {
+ // Armors haven't a dbl click
+ return;
+ }
+ case caShiftLeftClick:
+ case caShiftRightClick:
+ {
+ ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
+ return;
+ }
+ case caMiddleClick:
+ {
+ MiddleClicked(a_Player, a_SlotNum);
+ return;
+ }
+ default:
+ {
+ break;
+ }
}
cItem Slot(*GetSlot(a_SlotNum, a_Player));
diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h
index b4b693cf6..3dc5c3849 100644
--- a/src/UI/SlotArea.h
+++ b/src/UI/SlotArea.h
@@ -46,10 +46,19 @@ public:
/// Called from Clicked when the action is a shiftclick (left or right)
virtual void ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem & a_ClickedItem);
-
+
/// Called from Clicked when the action is a caDblClick
virtual void DblClicked(cPlayer & a_Player, int a_SlotNum);
-
+
+ /** Called from Clicked when the action is a middleclick */
+ virtual void MiddleClicked(cPlayer & a_Player, int a_SlotNum);
+
+ /** Called from Clicked when the action is a drop click. */
+ virtual void DropClicked(cPlayer & a_Player, int a_SlotNum, bool a_DropStack);
+
+ /** Called from Clicked when the action is a number click. */
+ virtual void NumberClicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction);
+
/// Called when a new player opens the same parent window. The window already tracks the player. CS-locked.
virtual void OnPlayerAdded(cPlayer & a_Player);
@@ -232,10 +241,12 @@ public:
virtual void Clicked (cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
virtual void DblClicked (cPlayer & a_Player, int a_SlotNum);
virtual void OnPlayerRemoved(cPlayer & a_Player) override;
+ virtual void SetSlot (int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
// Distributing items into this area is completely disabled
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) override;
+
protected:
/// Maps player's EntityID -> current recipe; not a std::map because cCraftingGrid needs proper constructor params
typedef std::list<std::pair<int, cCraftingRecipe> > cRecipeMap;
@@ -248,7 +259,10 @@ protected:
/// Handles a shift-click in the result slot. Crafts using the current recipe until it changes or no more space for result.
void ShiftClickedResult(cPlayer & a_Player);
-
+
+ /** Handles a drop-click in the result slot. */
+ void DropClickedResult(cPlayer & a_Player);
+
/// Updates the current recipe and result slot based on the ingredients currently in the crafting grid of the specified player
void UpdateRecipe(cPlayer & a_Player);
diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp
index 98a9a0cec..ebdc1aea8 100644
--- a/src/UI/Window.cpp
+++ b/src/UI/Window.cpp
@@ -145,8 +145,7 @@ void cWindow::GetSlots(cPlayer & a_Player, cItems & a_Slots) const
{
int NumSlots = (*itr)->GetNumSlots();
for (int i = 0; i < NumSlots; i++)
- {
-
+ {
const cItem * Item = (*itr)->GetSlot(i, a_Player);
if (Item == NULL)
{
@@ -170,7 +169,7 @@ void cWindow::Clicked(
const cItem & a_ClickedItem
)
{
- cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
+ cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
if (a_WindowID != m_WindowID)
{
LOGWARNING("%s: Wrong window ID (exp %d, got %d) received from \"%s\"; ignoring click.", __FUNCTION__, m_WindowID, a_WindowID, a_Player.GetName().c_str());
@@ -179,6 +178,7 @@ void cWindow::Clicked(
switch (a_ClickAction)
{
+ case caLeftClickOutside:
case caRightClickOutside:
{
if (PlgMgr->CallHookPlayerTossingItem(a_Player))
@@ -191,25 +191,16 @@ void cWindow::Clicked(
a_Player.TossPickup(a_ClickedItem);
}
- // Toss one of the dragged items:
- a_Player.TossHeldItem();
- return;
- }
- case caLeftClickOutside:
- {
- if (PlgMgr->CallHookPlayerTossingItem(a_Player))
+ if (a_ClickAction == caLeftClickOutside)
{
- // A plugin doesn't agree with the tossing. The plugin itself is responsible for handling the consequences (possible inventory mismatch)
- return;
+ // Toss all dragged items:
+ a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount);
}
-
- if (a_Player.IsGameModeCreative())
+ else
{
- a_Player.TossPickup(a_ClickedItem);
+ // Toss one of the dragged items:
+ a_Player.TossHeldItem();
}
-
- // Toss all dragged items:
- a_Player.TossHeldItem(a_Player.GetDraggingItem().m_ItemCount);
return;
}
case caLeftClickOutsideHoldNothing:
@@ -1017,6 +1008,7 @@ cEnderChestWindow::~cEnderChestWindow()
// Send out the chest-close packet:
m_World->BroadcastBlockAction(m_BlockX, m_BlockY, m_BlockZ, 1, 0, E_BLOCK_ENDER_CHEST);
+ // Play the closing sound
m_World->BroadcastSoundEffect("random.chestclosed", m_BlockX * 8, m_BlockY * 8, m_BlockZ * 8, 1, 1);
}
diff --git a/src/Vector3.h b/src/Vector3.h
index 5faac1457..9e855b8af 100644
--- a/src/Vector3.h
+++ b/src/Vector3.h
@@ -134,6 +134,16 @@ public:
z += a_Diff.z;
}
+ /** Runs each value of the vector through std::floor() */
+ inline Vector3<int> Floor(void) const
+ {
+ return Vector3<int>(
+ (int)floor(x),
+ (int)floor(y),
+ (int)floor(z)
+ );
+ }
+
// tolua_end
inline bool operator != (const Vector3<T> & a_Rhs) const
@@ -146,6 +156,16 @@ public:
return Equals(a_Rhs);
}
+ inline bool operator > (const Vector3<T> & a_Rhs) const
+ {
+ return (SqrLength() > a_Rhs.SqrLength());
+ }
+
+ inline bool operator < (const Vector3<T> & a_Rhs) const
+ {
+ return (SqrLength() < a_Rhs.SqrLength());
+ }
+
inline void operator += (const Vector3<T> & a_Rhs)
{
x += a_Rhs.x;
@@ -288,6 +308,7 @@ protected:
{
return (a_Value < 0) ? -a_Value : a_Value;
}
+
};
// tolua_end
diff --git a/src/VoronoiMap.cpp b/src/VoronoiMap.cpp
index 7a36edebc..5efd09c01 100644
--- a/src/VoronoiMap.cpp
+++ b/src/VoronoiMap.cpp
@@ -11,8 +11,12 @@
cVoronoiMap::cVoronoiMap(int a_Seed, int a_CellSize) :
- m_Noise(a_Seed),
- m_CellSize(a_CellSize)
+ m_Noise1(a_Seed + 1),
+ m_Noise2(a_Seed + 2),
+ m_Noise3(a_Seed + 3),
+ m_CellSize(a_CellSize),
+ m_CurrentCellX(9999999), // Cell coords that are definitely out of the range for normal generator, so that the first query will overwrite them
+ m_CurrentCellZ(9999999)
{
}
@@ -57,26 +61,25 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2
int CellX = a_X / m_CellSize;
int CellZ = a_Y / m_CellSize;
+ UpdateCell(CellX, CellZ);
+
// Get 5x5 neighboring cell seeds, compare distance to each. Return the value in the minumim-distance cell
int MinDist = m_CellSize * m_CellSize * 16; // There has to be a cell closer than this
int MinDist2 = MinDist;
int res = 0; // Will be overriden
- for (int x = CellX - 2; x <= CellX + 2; x++)
+ for (int x = 0; x < 5; x++)
{
- int BaseX = x * m_CellSize;
- for (int z = CellZ - 2; z < CellZ + 2; z++)
+ for (int z = 0; z < 5; z++)
{
- int OffsetX = (m_Noise.IntNoise3DInt(x, 16 * x + 32 * z, z) / 8) % m_CellSize;
- int OffsetZ = (m_Noise.IntNoise3DInt(x, 32 * x - 16 * z, z) / 8) % m_CellSize;
- int SeedX = BaseX + OffsetX;
- int SeedZ = z * m_CellSize + OffsetZ;
+ int SeedX = m_SeedX[x][z];
+ int SeedZ = m_SeedZ[x][z];
int Dist = (SeedX - a_X) * (SeedX - a_X) + (SeedZ - a_Y) * (SeedZ - a_Y);
if (Dist < MinDist)
{
MinDist2 = MinDist;
MinDist = Dist;
- res = m_Noise.IntNoise3DInt(x, x - z + 1000, z);
+ res = m_Noise3.IntNoise2DInt(x + CellX - 2, z + CellZ - 2);
}
else if (Dist < MinDist2)
{
@@ -93,3 +96,33 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2
+
+void cVoronoiMap::UpdateCell(int a_CellX, int a_CellZ)
+{
+ // If the specified cell is currently cached, bail out:
+ if ((a_CellX == m_CurrentCellX) && (a_CellZ == m_CurrentCellZ))
+ {
+ return;
+ }
+
+ // Update the cell cache for the new cell position:
+ int NoiseBaseX = a_CellX - 2;
+ int NoiseBaseZ = a_CellZ - 2;
+ for (int x = 0; x < 5; x++)
+ {
+ int BaseX = (NoiseBaseX + x) * m_CellSize;
+ for (int z = 0; z < 5; z++)
+ {
+ int OffsetX = (m_Noise1.IntNoise2DInt(NoiseBaseX + x, NoiseBaseZ + z) / 8) % m_CellSize;
+ int OffsetZ = (m_Noise2.IntNoise2DInt(NoiseBaseX + x, NoiseBaseZ + z) / 8) % m_CellSize;
+ m_SeedX[x][z] = BaseX + OffsetX;
+ m_SeedZ[x][z] = (NoiseBaseZ + z) * m_CellSize + OffsetZ;
+ } // for z
+ } // for x
+ m_CurrentCellX = a_CellX;
+ m_CurrentCellZ = a_CellZ;
+}
+
+
+
+
diff --git a/src/VoronoiMap.h b/src/VoronoiMap.h
index bcd37f9cf..84cf206e9 100644
--- a/src/VoronoiMap.h
+++ b/src/VoronoiMap.h
@@ -29,15 +29,34 @@ public:
/// Returns the value in the cell into which the specified point lies, and the distance to the nearest Voronoi seed
int GetValueAt(int a_X, int a_Y, int & a_MinDistance);
- /// Returns the value in the cell into which the specified point lies, and the distances to the 2 nearest Voronoi seeds
+ /// Returns the value in the cell into which the specified point lies, and the distances to the 2 nearest Voronoi seeds. Uses a cache
int GetValueAt(int a_X, int a_Y, int & a_MinDistance1, int & a_MinDistance2);
-
+
protected:
/// The noise used for generating Voronoi seeds
- cNoise m_Noise;
+ cNoise m_Noise1;
+ cNoise m_Noise2;
+ cNoise m_Noise3;
/// Size of the Voronoi cells (avg X/Y distance between the seeds)
int m_CellSize;
+
+ /** The X coordinate of the currently cached cell neighborhood */
+ int m_CurrentCellX;
+
+ /** The Z coordinate of the currently cached cell neighborhood */
+ int m_CurrentCellZ;
+
+ /** The seeds of cells around m_CurrentCellX, m_CurrentCellZ, X-coords */
+ int m_SeedX[5][5];
+
+ /** The seeds of cells around m_CurrentCellX, m_CurrentCellZ, X-coords */
+ int m_SeedZ[5][5];
+
+
+ /** Updates the cached cell seeds to match the specified cell. Noop if cell pos already matches.
+ Updates m_SeedX and m_SeedZ. */
+ void UpdateCell(int a_CellX, int a_CellZ);
} ;
diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp
index 08e164d78..d80849433 100644
--- a/src/WebAdmin.cpp
+++ b/src/WebAdmin.cpp
@@ -524,6 +524,7 @@ void cWebAdmin::OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest &
// Delete any request data assigned to the request:
cRequestData * Data = (cRequestData *)(a_Request.GetUserData());
delete Data;
+ Data = NULL;
}
diff --git a/src/World.cpp b/src/World.cpp
index 6bcd1391a..a6607de12 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -267,12 +267,12 @@ cWorld::cWorld(const AString & a_WorldName) :
cWorld::~cWorld()
{
- delete m_SimulatorManager;
- delete m_SandSimulator;
- delete m_WaterSimulator;
- delete m_LavaSimulator;
- delete m_FireSimulator;
- delete m_RedstoneSimulator;
+ delete m_SimulatorManager; m_SimulatorManager = NULL;
+ delete m_SandSimulator; m_SandSimulator = NULL;
+ delete m_WaterSimulator; m_WaterSimulator = NULL;
+ delete m_LavaSimulator; m_LavaSimulator = NULL;
+ delete m_FireSimulator; m_FireSimulator = NULL;
+ delete m_RedstoneSimulator; m_RedstoneSimulator = NULL;
UnloadUnusedChunks();
@@ -1877,9 +1877,9 @@ void cWorld::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer
-void cWorld::BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude)
+void cWorld::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude)
{
- m_ChunkMap->BroadcastCollectPickup(a_Pickup, a_Player, a_Exclude);
+ m_ChunkMap->BroadcastCollectEntity(a_Entity, a_Player, a_Exclude);
}
@@ -2767,10 +2767,8 @@ bool cWorld::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunk
void cWorld::SaveAllChunks(void)
{
- LOGINFO("Saving all chunks...");
m_LastSave = m_WorldAge;
m_ChunkMap->SaveAllChunks();
- m_Storage.QueueSavedMessage();
}
@@ -2972,11 +2970,13 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster)
if (cPluginManager::Get()->CallHookSpawningMonster(*this, *a_Monster))
{
delete a_Monster;
+ a_Monster = NULL;
return -1;
}
if (!a_Monster->Initialize(*this))
{
delete a_Monster;
+ a_Monster = NULL;
return -1;
}
BroadcastSpawnEntity(*a_Monster);
@@ -2999,6 +2999,7 @@ int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProje
if (!Projectile->Initialize(*this))
{
delete Projectile;
+ Projectile = NULL;
return -1;
}
return Projectile->GetUniqueID();
diff --git a/src/World.h b/src/World.h
index 3e63e2b8c..476a49739 100644
--- a/src/World.h
+++ b/src/World.h
@@ -206,7 +206,7 @@ public:
// tolua_end
void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);
- void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
+ void BroadcastCollectEntity (const cEntity & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL);
@@ -485,7 +485,7 @@ public:
double GetSpawnZ(void) const { return m_SpawnZ; }
/** Wakes up the simulators for the specified block */
- void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ);
+ virtual void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) override;
/** Wakes up the simulators for the specified area of blocks */
void WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ);
@@ -532,7 +532,7 @@ public:
virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) override; // tolua_export
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
- bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp
+ virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) override; // Exported in ManualBindings.cpp
/** Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found */
bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp
@@ -830,6 +830,7 @@ private:
virtual ~cScheduledTask()
{
delete m_Task;
+ m_Task = NULL;
}
};
diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp
index a3b0d57be..317ace795 100644
--- a/src/WorldStorage/NBTChunkSerializer.cpp
+++ b/src/WorldStorage/NBTChunkSerializer.cpp
@@ -345,6 +345,7 @@ void cNBTChunkSerializer::AddBasicEntity(cEntity * a_Entity, const AString & a_C
m_Writer.AddDouble("", a_Entity->GetYaw());
m_Writer.AddDouble("", a_Entity->GetPitch());
m_Writer.EndList();
+ m_Writer.AddShort("Health", a_Entity->GetHealth());
}
@@ -575,7 +576,6 @@ void cNBTChunkSerializer::AddPickupEntity(cPickup * a_Pickup)
m_Writer.BeginCompound("");
AddBasicEntity(a_Pickup, "Item");
AddItem(a_Pickup->GetItem(), -1, "Item");
- m_Writer.AddShort("Health", (Int16)(unsigned char)a_Pickup->GetHealth());
m_Writer.AddShort("Age", (Int16)a_Pickup->GetAge());
m_Writer.EndCompound();
}
@@ -589,50 +589,41 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile)
m_Writer.BeginCompound("");
AddBasicEntity(a_Projectile, a_Projectile->GetMCAClassName());
Vector3d Pos = a_Projectile->GetPosition();
- m_Writer.AddShort("xTile", (Int16)floor(Pos.x));
- m_Writer.AddShort("yTile", (Int16)floor(Pos.y));
- m_Writer.AddShort("zTile", (Int16)floor(Pos.z));
- m_Writer.AddShort("inTile", 0); // TODO: Query the block type
- m_Writer.AddShort("shake", 0); // TODO: Any shake?
- m_Writer.AddByte ("inGround", a_Projectile->IsInGround() ? 1 : 0);
+ m_Writer.AddByte("inGround", a_Projectile->IsInGround() ? 1 : 0);
switch (a_Projectile->GetProjectileKind())
{
case cProjectileEntity::pkArrow:
{
- m_Writer.AddByte("inData", 0); // TODO: Query the block meta (is it needed?)
- m_Writer.AddByte("pickup", ((cArrowEntity *)a_Projectile)->GetPickupState());
- m_Writer.AddDouble("damage", ((cArrowEntity *)a_Projectile)->GetDamageCoeff());
+ cArrowEntity * Arrow = (cArrowEntity *)a_Projectile;
+
+ m_Writer.AddInt("xTile", (Int16)Arrow->GetBlockHit().x);
+ m_Writer.AddInt("yTile", (Int16)Arrow->GetBlockHit().y);
+ m_Writer.AddInt("zTile", (Int16)Arrow->GetBlockHit().z);
+ m_Writer.AddByte("pickup", Arrow->GetPickupState());
+ m_Writer.AddDouble("damage", Arrow->GetDamageCoeff());
break;
}
case cProjectileEntity::pkGhastFireball:
{
m_Writer.AddInt("ExplosionPower", 1);
- // fall-through:
+ break;
}
case cProjectileEntity::pkFireCharge:
case cProjectileEntity::pkWitherSkull:
case cProjectileEntity::pkEnderPearl:
{
- m_Writer.BeginList("Motion", TAG_Double);
- m_Writer.AddDouble("", a_Projectile->GetSpeedX());
- m_Writer.AddDouble("", a_Projectile->GetSpeedY());
- m_Writer.AddDouble("", a_Projectile->GetSpeedZ());
- m_Writer.EndList();
break;
}
default:
{
ASSERT(!"Unsaved projectile entity!");
}
- } // switch (ProjectileKind)
- cEntity * Creator = a_Projectile->GetCreator();
- if (Creator != NULL)
+ } // switch (ProjectileKind)
+
+ if (!a_Projectile->GetCreatorName().empty())
{
- if (Creator->GetEntityType() == cEntity::etPlayer)
- {
- m_Writer.AddString("ownerName", ((cPlayer *)Creator)->GetName());
- }
+ m_Writer.AddString("ownerName", a_Projectile->GetCreatorName());
}
m_Writer.EndCompound();
}
@@ -683,7 +674,6 @@ void cNBTChunkSerializer::AddExpOrbEntity(cExpOrb * a_ExpOrb)
{
m_Writer.BeginCompound("");
AddBasicEntity(a_ExpOrb, "XPOrb");
- m_Writer.AddShort("Health", (Int16)(unsigned char)a_ExpOrb->GetHealth());
m_Writer.AddShort("Age", (Int16)a_ExpOrb->GetAge());
m_Writer.AddShort("Value", (Int16)a_ExpOrb->GetReward());
m_Writer.EndCompound();
@@ -826,6 +816,7 @@ void cNBTChunkSerializer::BlockEntity(cBlockEntity * a_Entity)
case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity); break;
case E_BLOCK_DISPENSER: AddDispenserEntity ((cDispenserEntity *) a_Entity); break;
case E_BLOCK_DROPPER: AddDropperEntity ((cDropperEntity *) a_Entity); break;
+ case E_BLOCK_ENDER_CHEST: /* No need to be saved */ break;
case E_BLOCK_FLOWER_POT: AddFlowerPotEntity ((cFlowerPotEntity *) a_Entity); break;
case E_BLOCK_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break;
case E_BLOCK_HOPPER: AddHopperEntity ((cHopperEntity *) a_Entity); break;
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index 1891762fd..f13c4d4d2 100644
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -469,6 +469,9 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_
a_Writer.AddByte("MCSIsLightValid", 1);
}
+ // Store the flag that the chunk has all the ores, trees, dungeons etc. MCS chunks are always complete.
+ a_Writer.AddByte("TerrainPopulated", 1);
+
a_Writer.EndCompound(); // "Level"
return true;
}
@@ -1458,13 +1461,6 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a
{
return;
}
-
- // Load health:
- int Health = a_NBT.FindChildByName(a_TagIdx, "Health");
- if (Health > 0)
- {
- Pickup->SetHealth((int) (a_NBT.GetShort(Health) & 0xFF));
- }
// Load age:
int Age = a_NBT.FindChildByName(a_TagIdx, "Age");
@@ -1510,13 +1506,6 @@ void cWSSAnvil::LoadExpOrbFromNBT(cEntityList & a_Entities, const cParsedNBT & a
return;
}
- // Load Health:
- int Health = a_NBT.FindChildByName(a_TagIdx, "Health");
- if (Health > 0)
- {
- ExpOrb->SetHealth((int) (a_NBT.GetShort(Health) & 0xFF));
- }
-
// Load Age:
int Age = a_NBT.FindChildByName(a_TagIdx, "Age");
if (Age > 0)
@@ -1653,6 +1642,15 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
Arrow->SetDamageCoeff(a_NBT.GetDouble(DamageIdx));
}
+ // Load block hit:
+ int InBlockXIdx = a_NBT.FindChildByName(a_TagIdx, "xTile");
+ int InBlockYIdx = a_NBT.FindChildByName(a_TagIdx, "yTile");
+ int InBlockZIdx = a_NBT.FindChildByName(a_TagIdx, "zTile");
+ if ((InBlockXIdx > 0) && (InBlockYIdx > 0) && (InBlockZIdx > 0))
+ {
+ Arrow->SetBlockHit(Vector3i(a_NBT.GetInt(InBlockXIdx), a_NBT.GetInt(InBlockYIdx), a_NBT.GetInt(InBlockZIdx)));
+ }
+
// Store the new arrow in the entities list:
a_Entities.push_back(Arrow.release());
}
@@ -2434,6 +2432,13 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N
}
a_Entity.SetYaw(Rotation[0]);
a_Entity.SetRoll(Rotation[1]);
+
+ // Load health:
+ int Health = a_NBT.FindChildByName(a_TagIdx, "Health");
+ if (Health > 0)
+ {
+ a_Entity.SetHealth(a_NBT.GetShort(Health));
+ }
return true;
}
@@ -2478,8 +2483,6 @@ bool cWSSAnvil::LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cP
}
a_Entity.SetIsInGround(IsInGround);
- // TODO: Load inTile, TileCoords
-
return true;
}
diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp
index 7a113849a..a853f6ec9 100644
--- a/src/WorldStorage/WSSCompact.cpp
+++ b/src/WorldStorage/WSSCompact.cpp
@@ -473,6 +473,7 @@ cWSSCompact::cPAKFile::cPAKFile(const AString & a_FileName, int a_LayerX, int a_
{
LOGERROR("ERROR READING %s FROM FILE %s (line %d); file offset %d", "Header", m_FileName.c_str(), __LINE__, f.Tell());
delete Header;
+ Header = NULL;
return;
}
m_ChunkHeaders.push_back(Header);
diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp
index 6867ad5bc..d3f35384b 100644
--- a/src/WorldStorage/WorldStorage.cpp
+++ b/src/WorldStorage/WorldStorage.cpp
@@ -17,13 +17,6 @@
-/// If a chunk with this Y coord is de-queued, it is a signal to emit the saved-all message (cWorldStorage::QueueSavedMessage())
-#define CHUNK_Y_MESSAGE 2
-
-
-
-
-
/// Example storage schema - forgets all chunks ;)
class cWSSForgetful :
public cWSSchema
@@ -168,17 +161,6 @@ void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
-void cWorldStorage::QueueSavedMessage(void)
-{
- // Pushes a special coord pair into the queue, signalizing a message instead
- m_SaveQueue.EnqueueItem(cChunkCoords(0, CHUNK_Y_MESSAGE, 0));
- m_Event.Set();
-}
-
-
-
-
-
void cWorldStorage::UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
{
m_LoadQueue.Remove(sChunkLoad(a_ChunkX, a_ChunkY, a_ChunkZ,true));
@@ -286,19 +268,12 @@ bool cWorldStorage::SaveOneChunk(void)
{
cChunkCoords ToSave(0, 0, 0);
bool ShouldSave = m_SaveQueue.TryDequeueItem(ToSave);
- if(ShouldSave) {
- if (ToSave.m_ChunkY == CHUNK_Y_MESSAGE)
- {
- LOGINFO("Saved all chunks in world %s", m_World->GetName().c_str());
- return ShouldSave;
- }
- if (ShouldSave && m_World->IsChunkValid(ToSave.m_ChunkX, ToSave.m_ChunkZ))
+ if (ShouldSave && m_World->IsChunkValid(ToSave.m_ChunkX, ToSave.m_ChunkZ))
+ {
+ m_World->MarkChunkSaving(ToSave.m_ChunkX, ToSave.m_ChunkZ);
+ if (m_SaveSchema->SaveChunk(ToSave))
{
- m_World->MarkChunkSaving(ToSave.m_ChunkX, ToSave.m_ChunkZ);
- if (m_SaveSchema->SaveChunk(ToSave))
- {
- m_World->MarkChunkSaved(ToSave.m_ChunkX, ToSave.m_ChunkZ);
- }
+ m_World->MarkChunkSaved(ToSave.m_ChunkX, ToSave.m_ChunkZ);
}
}
return ShouldSave;
diff --git a/src/WorldStorage/WorldStorage.h b/src/WorldStorage/WorldStorage.h
index bb189b6c9..1204b4310 100644
--- a/src/WorldStorage/WorldStorage.h
+++ b/src/WorldStorage/WorldStorage.h
@@ -67,9 +67,6 @@ public:
void QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate); // Queues the chunk for loading; if not loaded, the chunk will be generated if a_Generate is true
void QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);
- /// Signals that a message should be output to the console when all the chunks have been saved
- void QueueSavedMessage(void);
-
/// Loads the chunk specified; returns true on success, false on failure
bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ);