diff options
Diffstat (limited to 'src')
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); |