From cd7ef264be438a7c1b19eb6a0478ed5748e551bd Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 14 Mar 2014 07:16:55 -0700 Subject: [PATCH 001/145] Disable global constructors and exit-time destructors warnings --- SetFlags.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 42cfa6769..05f2b90c0 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -196,8 +196,8 @@ macro(set_exe_flags) add_flags_cxx("-Wno-error=deprecated -Wno-error=weak-vtables -Wno-error=float-equal") add_flags_cxx("-Wno-error=missing-prototypes -Wno-error=non-virtual-dtor") add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=shadow") - add_flags_cxx("-Wno-error=exit-time-destructors -Wno-error=missing-variable-declarations") - add_flags_cxx("-Wno-error=global-constructors -Wno-implicit-fallthrough") + add_flags_cxx("-Wno-exit-time-destructors -Wno-error=missing-variable-declarations") + add_flags_cxx("-Wno-global-constructors -Wno-implicit-fallthrough") add_flags_cxx("-Wno-missing-noreturn -Wno-error=unreachable-code -Wno-error=undef") endif() endif() From 7f84c8d60b1265f31aa58bfa4e01739dd279c528 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 15 Mar 2014 10:42:35 -0700 Subject: [PATCH 002/145] Patched tolua to understand size_t --- lib/tolua++/src/bin/basic_lua.h | 4 +++- lib/tolua++/src/bin/lua/basic.lua | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/tolua++/src/bin/basic_lua.h b/lib/tolua++/src/bin/basic_lua.h index 9f3b114b4..6adbaa4a6 100644 --- a/lib/tolua++/src/bin/basic_lua.h +++ b/lib/tolua++/src/bin/basic_lua.h @@ -61,6 +61,8 @@ unsigned char lua_basic_lua[] = { 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, 0x0a, + 0x20, 0x5b, 0x27, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x74, 0x27, 0x5d, 0x20, + 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x5f, 0x63, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, @@ -743,4 +745,4 @@ unsigned char lua_basic_lua[] = { 0x5f, 0x69, 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a }; -unsigned int lua_basic_lua_len = 8909; +unsigned int lua_basic_lua_len = 8933; diff --git a/lib/tolua++/src/bin/lua/basic.lua b/lib/tolua++/src/bin/lua/basic.lua index f651f1fe6..10cb5b18b 100644 --- a/lib/tolua++/src/bin/lua/basic.lua +++ b/lib/tolua++/src/bin/lua/basic.lua @@ -23,6 +23,7 @@ _basic = { ['unsigned'] = 'number', ['float'] = 'number', ['double'] = 'number', + ['size_t'] = 'number', ['_cstring'] = 'string', ['_userdata'] = 'userdata', ['char*'] = 'string', From c9163d39f74302fc943e6c9b3b8442061a5f089e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 21 Mar 2014 22:53:46 +0100 Subject: [PATCH 003/145] Implemented faster upscaling using templates. Fixes #819. --- src/Generating/BioGen.cpp | 16 +++++----- src/Generating/CompoGen.cpp | 4 +-- src/Generating/HeiGen.cpp | 2 +- src/Generating/Noise3DGenerator.cpp | 2 +- src/Generating/StructGen.cpp | 4 +-- src/LinearUpscale.h | 46 +++++++++++++++-------------- 6 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index 967deba6a..32a687201 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -371,8 +371,8 @@ void cBioGenDistortedVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::B Distort(BaseX + x * 4, BaseZ + z * 4, DistortX[4 * x][4 * z], DistortZ[4 * x][4 * z]); } - LinearUpscale2DArrayInPlace(&DistortX[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); - LinearUpscale2DArrayInPlace(&DistortZ[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); + LinearUpscale2DArrayInPlace(&DistortX[0][0]); + LinearUpscale2DArrayInPlace(&DistortZ[0][0]); for (int z = 0; z < cChunkDef::Width; z++) { @@ -477,8 +477,8 @@ void cBioGenMultiStepMap::DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cC { Distort(BaseX + x * 4, BaseZ + z * 4, DistortX[4 * x][4 * z], DistortZ[4 * x][4 * z], DistortSize); } - LinearUpscale2DArrayInPlace(&DistortX[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); - LinearUpscale2DArrayInPlace(&DistortZ[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); + LinearUpscale2DArrayInPlace(&DistortX[0][0]); + LinearUpscale2DArrayInPlace(&DistortZ[0][0]); // Prepare a 9x9 area of neighboring cell seeds // (assuming that 7x7 cell area is larger than a chunk being generated) @@ -651,8 +651,8 @@ void cBioGenMultiStepMap::BuildTemperatureHumidityMaps(int a_ChunkX, int a_Chunk HumidityMap[x + 17 * z] = NoiseH; } // for x } // for z - LinearUpscale2DArrayInPlace(TemperatureMap, 17, 17, 8, 8); - LinearUpscale2DArrayInPlace(HumidityMap, 17, 17, 8, 8); + LinearUpscale2DArrayInPlace<17, 17, 8, 8>(TemperatureMap); + LinearUpscale2DArrayInPlace<17, 17, 8, 8>(HumidityMap); // Re-map into integral values in [0 .. 255] range: for (size_t idx = 0; idx < ARRAYCOUNT(a_TemperatureMap); idx++) @@ -778,8 +778,8 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap DistortZ[4 * x][4 * z] = BlockZ + (int)(64 * NoiseZ); } - LinearUpscale2DArrayInPlace(&DistortX[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); - LinearUpscale2DArrayInPlace(&DistortZ[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); + LinearUpscale2DArrayInPlace(&DistortX[0][0]); + LinearUpscale2DArrayInPlace(&DistortZ[0][0]); // Apply distortion to each block coord, then query the voronoi maps for biome group and biome index and choose biome based on that: for (int z = 0; z < cChunkDef::Width; z++) diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp index 60356fe46..578bb2481 100644 --- a/src/Generating/CompoGen.cpp +++ b/src/Generating/CompoGen.cpp @@ -566,7 +566,7 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc) m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, 0, BaseZ + INTERPOL_Z * z) / 256; } // for x, z - FloorLo[] - LinearUpscale2DArrayInPlace(FloorLo, 17, 17, INTERPOL_X, INTERPOL_Z); + LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo); // Interpolate segments: for (int Segment = 0; Segment < MaxHeight; Segment += SEGMENT_HEIGHT) @@ -579,7 +579,7 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc) m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) / 256; } // for x, z - FloorLo[] - LinearUpscale2DArrayInPlace(FloorHi, 17, 17, INTERPOL_X, INTERPOL_Z); + LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorHi); // Interpolate between FloorLo and FloorHi: for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++) diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index 10710b4a1..3621421c2 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -428,7 +428,7 @@ void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMa Height[x + 17 * z] = GetHeightAt(x, z, a_ChunkX, a_ChunkZ, Biomes); } } - LinearUpscale2DArrayInPlace(Height, 17, 17, STEPX, STEPZ); + LinearUpscale2DArrayInPlace<17, 17, STEPX, STEPZ>(Height); // Copy into the heightmap for (int z = 0; z < cChunkDef::Width; z++) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index afa40c647..15a588d45 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -420,7 +420,7 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ) } } // Linear-interpolate this XZ floor: - LinearUpscale2DArrayInPlace(CurFloor, 17, 17, UPSCALE_X, UPSCALE_Z); + LinearUpscale2DArrayInPlace<17, 17, UPSCALE_X, UPSCALE_Z>(CurFloor); } // Finish the 3D linear interpolation by interpolating between each XZ-floors on the Y axis diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index 3cc8a09c3..db9d5578c 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -578,7 +578,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, BaseY, BaseZ + INTERPOL_Z * z) / 256; } // for x, z - FloorLo[] - LinearUpscale2DArrayInPlace(FloorLo, 17, 17, INTERPOL_X, INTERPOL_Z); + LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo); // Interpolate segments: for (int Segment = BaseY; Segment < MaxHeight; Segment += SEGMENT_HEIGHT) @@ -591,7 +591,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) / 256; } // for x, z - FloorLo[] - LinearUpscale2DArrayInPlace(FloorHi, 17, 17, INTERPOL_X, INTERPOL_Z); + LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorHi); // Interpolate between FloorLo and FloorHi: for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++) diff --git a/src/LinearUpscale.h b/src/LinearUpscale.h index b337b3219..0b04408cf 100644 --- a/src/LinearUpscale.h +++ b/src/LinearUpscale.h @@ -18,7 +18,7 @@ Therefore, there is no cpp file. InPlace upscaling works on a single array and assumes that the values to work on have already been interspersed into the array to the cell boundaries. -Specifically, a_Array[x * a_AnchorStepX + y * a_AnchorStepY] contains the anchor value. +Specifically, a_Array[x * AnchorStepX + y * AnchorStepY] contains the anchor value. Regular upscaling takes two arrays and "moves" the input from src to dst; src is expected packed. */ @@ -29,46 +29,48 @@ Regular upscaling takes two arrays and "moves" the input from src to dst; src is /** Linearly interpolates values in the array between the equidistant anchor points (upscales). Works in-place (input is already present at the correct output coords) +Uses templates to make it possible for the compiler to further optimizer the loops */ -template void LinearUpscale2DArrayInPlace( - TYPE * a_Array, - int a_SizeX, int a_SizeY, // Dimensions of the array - int a_AnchorStepX, int a_AnchorStepY // Distances between the anchor points in each direction -) +template< + int SizeX, int SizeY, // Dimensions of the array + int AnchorStepX, int AnchorStepY, + typename TYPE +> +void LinearUpscale2DArrayInPlace(TYPE * a_Array) { // First interpolate columns where the anchor points are: - int LastYCell = a_SizeY - a_AnchorStepY; - for (int y = 0; y < LastYCell; y += a_AnchorStepY) + int LastYCell = SizeY - AnchorStepY; + for (int y = 0; y < LastYCell; y += AnchorStepY) { - int Idx = a_SizeX * y; - for (int x = 0; x < a_SizeX; x += a_AnchorStepX) + int Idx = SizeX * y; + for (int x = 0; x < SizeX; x += AnchorStepX) { TYPE StartValue = a_Array[Idx]; - TYPE EndValue = a_Array[Idx + a_SizeX * a_AnchorStepY]; + TYPE EndValue = a_Array[Idx + SizeX * AnchorStepY]; TYPE Diff = EndValue - StartValue; - for (int CellY = 1; CellY < a_AnchorStepY; CellY++) + for (int CellY = 1; CellY < AnchorStepY; CellY++) { - a_Array[Idx + a_SizeX * CellY] = StartValue + Diff * CellY / a_AnchorStepY; + a_Array[Idx + SizeX * CellY] = StartValue + Diff * CellY / AnchorStepY; } // for CellY - Idx += a_AnchorStepX; + Idx += AnchorStepX; } // for x } // for y // Now interpolate in rows, each row has values in the anchor columns - int LastXCell = a_SizeX - a_AnchorStepX; - for (int y = 0; y < a_SizeY; y++) + int LastXCell = SizeX - AnchorStepX; + for (int y = 0; y < SizeY; y++) { - int Idx = a_SizeX * y; - for (int x = 0; x < LastXCell; x += a_AnchorStepX) + int Idx = SizeX * y; + for (int x = 0; x < LastXCell; x += AnchorStepX) { TYPE StartValue = a_Array[Idx]; - TYPE EndValue = a_Array[Idx + a_AnchorStepX]; + TYPE EndValue = a_Array[Idx + AnchorStepX]; TYPE Diff = EndValue - StartValue; - for (int CellX = 1; CellX < a_AnchorStepX; CellX++) + for (int CellX = 1; CellX < AnchorStepX; CellX++) { - a_Array[Idx + CellX] = StartValue + CellX * Diff / a_AnchorStepX; + a_Array[Idx + CellX] = StartValue + CellX * Diff / AnchorStepX; } // for CellY - Idx += a_AnchorStepX; + Idx += AnchorStepX; } } } From 0cfb12f0d11b40d48974177f01494758ed800ff9 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 22 Mar 2014 08:30:49 -0700 Subject: [PATCH 004/145] Added Additonal check for xxd existance --- lib/tolua++/CMakeLists.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/tolua++/CMakeLists.txt b/lib/tolua++/CMakeLists.txt index 75a301a53..7e7498411 100644 --- a/lib/tolua++/CMakeLists.txt +++ b/lib/tolua++/CMakeLists.txt @@ -7,25 +7,28 @@ include_directories ("${PROJECT_SOURCE_DIR}/include/") include_directories ("${PROJECT_SOURCE_DIR}/../") include_directories ("${PROJECT_SOURCE_DIR}") -if(UNIX) +find_program(XXD_EXECUTABLE xxd) + +if(NOT XXD_EXECUTABLE STREQUAL "xxd-NOTFOUND") add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/basic_lua.h - COMMAND xxd -i lua/basic.lua | sed 's/unsigned char/static const unsigned char/g' >basic_lua.h + COMMAND ${XXD_EXECUTABLE} -i lua/basic.lua | sed 's/unsigned char/static const unsigned char/g' >basic_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/basic.lua) add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/enumerate_lua.h - COMMAND xxd -i lua/enumerate.lua | sed 's/unsigned char/static const unsigned char/g' >enumerate_lua.h + COMMAND ${XXD_EXECUTABLE} -i lua/enumerate.lua | sed 's/unsigned char/static const unsigned char/g' >enumerate_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/enumerate.lua) add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/function_lua.h - COMMAND xxd -i lua/function.lua | sed 's/unsigned char/static const unsigned char/g' >function_lua.h + COMMAND ${XXD_EXECUTABLE} -i lua/function.lua | sed 's/unsigned char/static const unsigned char/g' >function_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/function.lua) add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/declaration_lua.h - COMMAND xxd -i lua/declaration.lua | sed 's/unsigned char/static const unsigned char/g' >declaration_lua.h + COMMAND ${XXD_EXECUTABLE} -i lua/declaration.lua | sed 's/unsigned char/static const unsigned char/g' >declaration_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/declaration.lua) set_property(SOURCE src/bin/toluabind.c APPEND PROPERTY OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/enumerate_lua.h ${PROJECT_SOURCE_DIR}/src/bin/basic_lua.h ${PROJECT_SOURCE_DIR}/src/bin/function_lua.h ${PROJECT_SOURCE_DIR}/src/bin/declaration_lua.h) - message(hello) +else() + message("xxd not found, changes to tolua scripts will be ignored") endif() From fd8e5bf551db4c138b8c2ebe8e464c85603c0ef2 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 23 Mar 2014 20:54:37 +0100 Subject: [PATCH 005/145] Updated the ToLua windows executable. --- src/Bindings/tolua++.exe | Bin 185856 -> 200192 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/Bindings/tolua++.exe b/src/Bindings/tolua++.exe index 86ab1d70f040c52d116becd9e824aa62535b0b5a..1e3cc77890111f44cb7775b0813aec88e2a9ee82 100644 GIT binary patch delta 44244 zcmb@v4?t8^+CP4o8DNmXK^+to6$St0pRkb<2MWbO)+C3}LDo>))TXKSb#1QN243hw zFg8=E^ouVX6m}j&vUrA%R_nklb8R>?^Tz7$?wne`>9|OQL1dkv@ zNW{J4wPy_8h^NxbQsE-E;!BM$a~+(hJ>@6vOB63Pt`w~zq- z5D9?YRXTvHPw`U9{RO1zS*_@~H^m52FYUW2JB13zZ`QMIDBOp*qXh6`8~~1{>AbmY zzTWh1${p`O?)qEx+z&&!A>t>I+ z2ZfLuCM;W8QiGl&EU7}%Q`*4wxm3c`WYf6@~q5M1v ziJrq9*@EYb7EN<&36qiGrH3>;C|$~&)Fc<)GVwOI$lHU*=>$O!)PdxNv}M=vbBr!e zEAX*HR5?+xYdBG1(P?{4PhH|-Pw-^3H-deYEQD#{2++5Sv;-T~-;Qb$>0tyB;CUN} z(R?K_L6* zXH6=-ELG;<#Z{9`F9kJ8baU1u((TqzAsfBiToX^X8)__cOQ|u_ElJ13B6~DVZZHMo zht-%UJ+el?&C}DNE{htPK)ms6!4LalScvn7hN^+66p6F0n^>o`Xdf23wGW{~38VpX zLt?Ka-OTni;kSgjq>V@Wet^q?%Y|zYuBo`bv}Fs)xX;G*8(dMit|Bdn>s~xB$Mra_ z*KrB)@#>Ay1rk|nGv^?1x!LoBxK41@T}t{>KmZnRgu7`@ss;KiXbGj9Kyy{C57xd2 zSz5w+Bq=i>B?Df3c=2op2k=ZyR7TuIDeYX3o0Tc6@rH(eNG+V&%*%U_IS(mXhkLPq-7xngldOy!zqUkPY88SUZH2t^>%WJk#>5!bz(^>Z`Q4_8! zjm|bS_PQuxGEBr17yAUQbg@^*P+Q~ewILQ36fRO8NVQSBY(q;B8e!R`3VQ9ZwzzJ){;zHtupxOx$Xbtjw;223FnL@bCe0wsyi zjRm@m1HsLqs?h#EjZBogB7HM^IS&p)@u?^4;C&Q=NSqwBhAp}-ShHN3nk4vcb+Z>R z7DLmZ1k+q-+=p(Kg%pmMIHY7P=Z#FPl4^ZsNvsa=)mW0uZ(W7GwAqgkL7YTKm&;a&fILEV^T7=f=tLR1Q#%@~3~9%q!trRN~IeORC5%--a^Iy4m}&U&Wz=Bysl zr@-XimQ- z86C7wVjm@y4i}Pwe%}h~a~HXRY;h`~Z`L&;fs9J8Sg33{66A(dZsqbQlgu5-hnIr= z3wL0>+VHH(BT&1N`;M!eaY`1AAXEcXDfN=tV;gGQ#j8jJDT&?)vPlWsFR7CfMsstk z_u6|rHqIvu)9T#`V+|Z&*a(qqwwADsBLGLjo-ESlUsB&mNVp*rS-O$*baDOrP#@%J z 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 Date: Sun, 23 Mar 2014 20:37:23 +0000 Subject: [PATCH 006/145] Fixed bad cmake document interpretation Docs say: "If nothing is found, the result will be -NOTFOUND" --- lib/tolua++/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tolua++/CMakeLists.txt b/lib/tolua++/CMakeLists.txt index 7e7498411..e5c8ce3e8 100644 --- a/lib/tolua++/CMakeLists.txt +++ b/lib/tolua++/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories ("${PROJECT_SOURCE_DIR}") find_program(XXD_EXECUTABLE xxd) -if(NOT XXD_EXECUTABLE STREQUAL "xxd-NOTFOUND") +if(NOT XXD_EXECUTABLE STREQUAL "XXD_EXECUTABLE-NOTFOUND") add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/basic_lua.h COMMAND ${XXD_EXECUTABLE} -i lua/basic.lua | sed 's/unsigned char/static const unsigned char/g' >basic_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ From f622f4317c76aa287649da965456562a32bce41b Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 23 Mar 2014 22:32:45 +0000 Subject: [PATCH 007/145] Implemented lilypad placement --- src/Blocks/BlockHandler.cpp | 2 + src/Blocks/BlockLilypad.h | 84 +++++++++++++++++++++++++++++++++++++ src/ClientHandle.cpp | 12 ++++-- src/Items/ItemBucket.h | 8 ++-- 4 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 src/Blocks/BlockLilypad.h diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 4f74e2f45..7fd8c183c 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -41,6 +41,7 @@ #include "BlockIce.h" #include "BlockLadder.h" #include "BlockLeaves.h" +#include "BlockLilypad.h" #include "BlockNewLeaves.h" #include "BlockLever.h" #include "BlockMelon.h" @@ -142,6 +143,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_LAPIS_ORE: return new cBlockOreHandler (a_BlockType); case E_BLOCK_LAVA: return new cBlockLavaHandler (a_BlockType); case E_BLOCK_LEAVES: return new cBlockLeavesHandler (a_BlockType); + case E_BLOCK_LILY_PAD: return new cBlockLilypadHandler (a_BlockType); case E_BLOCK_LIT_FURNACE: return new cBlockFurnaceHandler (a_BlockType); case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType); case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType); diff --git a/src/Blocks/BlockLilypad.h b/src/Blocks/BlockLilypad.h new file mode 100644 index 000000000..3db280d80 --- /dev/null +++ b/src/Blocks/BlockLilypad.h @@ -0,0 +1,84 @@ + +#pragma once + +#include "BlockHandler.h" +#include "../Entities/Player.h" +#include "Vector3.h" +#include "../LineBlockTracer.h" + + + + + +class cBlockLilypadHandler : + public cBlockHandler +{ + typedef cBlockHandler super; + +public: + cBlockLilypadHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(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 + { + if (a_BlockFace > 0) + { + return false; + } + + class cCallbacks : + public cBlockTracer::cCallbacks + { + public: + cCallbacks(void) : + m_HasHitFluid(false) + { + } + + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override + { + if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType)) + { + if ((a_BlockMeta != 0) || (a_EntryFace == BLOCK_FACE_NONE)) // The hit block should be a source. The FACE_NONE check is for AddFaceDir below + { + return false; + } + m_HasHitFluid = true; + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, (eBlockFace)a_EntryFace); + m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ); + return true; + } + return false; + } + + Vector3i m_Pos; + bool m_HasHitFluid; + + } Callbacks; + + cLineBlockTracer Tracer(*a_Player->GetWorld(), Callbacks); + Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector()); + Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5); + + Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z); + + if (Callbacks.m_HasHitFluid) + { + a_Player->GetWorld()->SetBlock(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z, E_BLOCK_LILY_PAD, 0); + } + + return false; + } +}; + + + + diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 46c10ae82..2c47faa65 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -988,7 +988,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemType); - if (ItemHandler->IsPlaceable() && (a_BlockFace > -1)) + if (ItemHandler->IsPlaceable() && ((a_BlockFace > -1) || (Equipped.m_ItemType == E_BLOCK_LILY_PAD))) { HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); } @@ -1026,7 +1026,8 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler) { - if (a_BlockFace < 0) + BLOCKTYPE EquippedBlock = (BLOCKTYPE)(m_Player->GetEquippedItem().m_ItemType); + if ((a_BlockFace < 0) && (EquippedBlock != E_BLOCK_LILY_PAD)) { // Clicked in air return; @@ -1036,7 +1037,6 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e BLOCKTYPE ClickedBlock; NIBBLETYPE ClickedBlockMeta; - BLOCKTYPE EquippedBlock = (BLOCKTYPE)(m_Player->GetEquippedItem().m_ItemType); NIBBLETYPE EquippedBlockDamage = (NIBBLETYPE)(m_Player->GetEquippedItem().m_ItemDamage); if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) @@ -1085,7 +1085,10 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e } else { - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + if (EquippedBlock != E_BLOCK_LILY_PAD) + { + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + } if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) { @@ -1106,6 +1109,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e else { if ( + (EquippedBlock != E_BLOCK_LILY_PAD) && !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision() && !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(m_Player, PlaceMeta) ) diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h index 72cb8fa0a..68c89dd85 100644 --- a/src/Items/ItemBucket.h +++ b/src/Items/ItemBucket.h @@ -172,12 +172,12 @@ public: virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override { - if (a_BlockMeta != 0) // Even if it was a water block it would not be a source. - { - return false; - } if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType)) { + if (a_BlockMeta != 0) // GetBlockFromTrace is called for scooping up fluids; the hit block should be a source + { + return false; + } m_HasHitFluid = true; m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ); return true; From 2343b0dfbe12f6db76de1b4ed03cd902975d77b3 Mon Sep 17 00:00:00 2001 From: narroo Date: Sun, 23 Mar 2014 22:11:01 -0400 Subject: [PATCH 008/145] Added MetaRotate/Mirror Support for a number of classes. --- src/Blocks/BlockChest.h | 4 +- src/Blocks/BlockDoor.cpp | 75 ++++++++++++++++ src/Blocks/BlockDoor.h | 66 ++------------ src/Blocks/BlockFurnace.h | 8 +- src/Blocks/BlockHopper.h | 21 ++++- src/Blocks/BlockLadder.h | 4 +- src/Blocks/BlockLever.h | 37 +++++++- src/Blocks/BlockPumpkin.h | 6 +- src/Blocks/BlockRail.h | 135 +++++++++++++++++++++++++++++ src/Blocks/BlockRedstoneRepeater.h | 6 +- src/Blocks/BlockSlab.h | 11 ++- src/Blocks/BlockTrapdoor.h | 6 +- 12 files changed, 295 insertions(+), 84 deletions(-) diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h index 30588d8fc..890b5b933 100644 --- a/src/Blocks/BlockChest.h +++ b/src/Blocks/BlockChest.h @@ -11,11 +11,11 @@ class cBlockChestHandler : - public cMetaRotater + public cMetaRotater { public: cBlockChestHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index 4e38ef334..c027daed2 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -110,3 +110,78 @@ const char * cBlockDoorHandler::GetStepSound(void) + +NIBBLETYPE cBlockDoorHandler::MetaRotateCCW(NIBBLETYPE a_Meta) +{ + if (a_Meta & 0x08) + { + return a_Meta; + } + else + { + return super::MetaRotateCCW(a_Meta); + } +} + + + +NIBBLETYPE cBlockDoorHandler::MetaRotateCW(NIBBLETYPE a_Meta) +{ + if (a_Meta & 0x08) + { + return a_Meta; + } + else + { + return super::MetaRotateCW(a_Meta); + } +} + + + +NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta) +{ + // Top bit (0x08) contains door panel type (Top/Bottom panel) Only Bottom panels contain position data + // Return a_Meta if panel is a top panel (0x08 bit is set to 1) + LOG("Test MirrorXY"); + if (a_Meta & 0x08) return a_Meta; + + // Holds open/closed meta data. 0x0C == 1100. + NIBBLETYPE OtherMeta = a_Meta & 0x0C; + + // Mirrors according to a table. 0x03 == 0011. + switch (a_Meta & 0x03) + { + case 0x03: return 0x01 + OtherMeta; // South -> North + case 0x01: return 0x03 + OtherMeta; // North -> South + } + + // Not Facing North or South; No change. + return a_Meta; +} + + + +NIBBLETYPE cBlockDoorHandler::MetaMirrorYZ(NIBBLETYPE a_Meta) +{ + // Top bit (0x08) contains door panel type (Top/Bottom panel) Only Bottom panels contain position data + // Return a_Meta if panel is a top panel (0x08 bit is set to 1) + LOG("Test MirrorYZ"); + if (a_Meta & 0x08) return a_Meta; + + // Holds open/closed meta data. 0x0C == 1100. + NIBBLETYPE OtherMeta = a_Meta & 0x0C; + + // Mirrors according to a table. 0x03 == 0011. + switch (a_Meta & 0x03) + { + case 0x00: return 0x02 + OtherMeta; // West -> East + case 0x02: return 0x00 + OtherMeta; // East -> West + } + + // Not Facing North or South; No change. + return a_Meta; +} + + + diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index 981774c17..066e1ab28 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -21,6 +21,10 @@ public: virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override; virtual const char * GetStepSound(void) override; + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override; + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override; + virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override; + virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override; virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, @@ -142,14 +146,14 @@ public: static void ChangeDoor(cChunkInterface & a_ChunkInterface, int a_X, int a_Y, int a_Z) { NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_X, a_Y, a_Z); - + a_ChunkInterface.SetBlockMeta(a_X, a_Y, a_Z, ChangeStateMetaData(OldMetaData)); - + if (OldMetaData & 8) { // Current block is top of the door BLOCKTYPE BottomBlock = a_ChunkInterface.GetBlock(a_X, a_Y - 1, a_Z); - NIBBLETYPE BottomMeta = a_ChunkInterface.GetBlockMeta(a_X, a_Y - 1, a_Z); + NIBBLETYPE BottomMeta = a_ChunkInterface.GetBlockMeta(a_X, a_Y - 1, a_Z); if (IsDoor(BottomBlock) && !(BottomMeta & 8)) { @@ -168,62 +172,6 @@ public: } } } - - - virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override - { - if (a_Meta & 0x08) - { - return a_Meta; - } - else - { - return super::MetaRotateCCW(a_Meta); - } - } - - - - virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override - { - if (a_Meta & 0x08) - { - return a_Meta; - } - else - { - return super::MetaRotateCW(a_Meta); - } - } - - - - virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override - { - if (a_Meta & 0x08) - { - return a_Meta; - } - else - { - return super::MetaMirrorXY(a_Meta); - } - } - - - - virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override - { - if (a_Meta & 0x08) - { - return a_Meta; - } - else - { - return super::MetaMirrorYZ(a_Meta); - } - } - } ; diff --git a/src/Blocks/BlockFurnace.h b/src/Blocks/BlockFurnace.h index 27ef2689f..c7f8ff8d2 100644 --- a/src/Blocks/BlockFurnace.h +++ b/src/Blocks/BlockFurnace.h @@ -4,17 +4,17 @@ #include "BlockEntity.h" #include "../World.h" #include "../Piston.h" - +#include "MetaRotater.h" class cBlockFurnaceHandler : - public cBlockEntityHandler + public cMetaRotater { public: - cBlockFurnaceHandler(BLOCKTYPE a_BlockType) : - cBlockEntityHandler(a_BlockType) + cBlockFurnaceHandler(BLOCKTYPE a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockHopper.h b/src/Blocks/BlockHopper.h index 59b84aa0e..610296529 100644 --- a/src/Blocks/BlockHopper.h +++ b/src/Blocks/BlockHopper.h @@ -3,16 +3,16 @@ // Declares the cBlockHopperHandler class representing the handler for the Hopper block - +#include "MetaRotator.h" class cBlockHopperHandler : - public cBlockEntityHandler + public cMetaRotater { public: cBlockHopperHandler(BLOCKTYPE a_BlockType) - : cBlockEntityHandler(a_BlockType) + : cMetaRotater(a_BlockType) { } @@ -39,6 +39,21 @@ public: } return true; } + + + virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override + { + // Bit 0x08 is a flag. Lowest three bits are position. 0x08 == 1000 + NIBBLETYPE OtherMeta = a_Meta & 0x08; + // Mirrors defined by by a table. (Source, mincraft.gamepedia.com) 0x07 == 0111 + switch (a_Meta & 0x07) + { + case 0x00: return 0x01 + OtherMeta; // Down -> Up + case 0x01: return 0x00 + OtherMeta; // Up -> Down + } + // Not Facing Up or Down; No change. + return a_Meta; + } } ; diff --git a/src/Blocks/BlockLadder.h b/src/Blocks/BlockLadder.h index a3e9edc6b..12408759e 100644 --- a/src/Blocks/BlockLadder.h +++ b/src/Blocks/BlockLadder.h @@ -9,11 +9,11 @@ class cBlockLadderHandler : - public cBlockHandler + public cMetaRotater { public: cBlockLadderHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index ef6e102cd..ad2ae29e5 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -1,17 +1,18 @@ #pragma once #include "BlockHandler.h" - +#include "MetaRotator.h" class cBlockLeverHandler : - public cBlockHandler + public cMetaRotator { + typedef cMetaRotator super; public: cBlockLeverHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotator(a_BlockType) { } @@ -104,6 +105,36 @@ public: return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn); } + + + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override + { + switch (a_Meta) + { + case 0x00: return 0x07; // Ceiling rotation + case 0x07: return 0x00; + + case 0x05: return 0x06; // Ground rotation + case 0x06: return 0x05; + + default: return super::MetaRotateCCW(a_Meta); // Wall Rotation + } + } + + + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override + { + switch (a_Meta) + { + case 0x00: return 0x07; // Ceiling rotation + case 0x07: return 0x00; + + case 0x05: return 0x06; // Ground rotation + case 0x06: return 0x05; + + default: return super::MetaRotateCCW(a_Meta); // Wall Rotation + } + } } ; diff --git a/src/Blocks/BlockPumpkin.h b/src/Blocks/BlockPumpkin.h index 349f52605..ac2b9817a 100644 --- a/src/Blocks/BlockPumpkin.h +++ b/src/Blocks/BlockPumpkin.h @@ -1,16 +1,16 @@ #pragma once #include "BlockHandler.h" - +#include "MetaRotator.h" class cBlockPumpkinHandler : - public cBlockHandler + public cMetaRotator { public: cBlockPumpkinHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h index 07e9814cd..f56ec7152 100644 --- a/src/Blocks/BlockRail.h +++ b/src/Blocks/BlockRail.h @@ -434,6 +434,141 @@ public: } return true; } + + + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override + { + // Bit 0x08 is a flag when a_Meta is in the range 0x00--0x05 and 0x0A--0x0F. + // Bit 0x08 specifies direction when a_Meta is in the range 0x06-0x09. + if ((a_Meta < 0x06) || (a_Meta > 0x09)) + { + // Save powered rail flag. + NIBBLETYPE OtherMeta = a_Meta & 0x08; + // Rotates according to table; 0x07 == 0111. + // Rails can either be flat (North/South) or Ascending (Asc. East) + switch (a_Meta & 0x07) + { + case 0x00: return 0x01 + OtherMeta; // North/South -> East/West + case 0x01: return 0x00 + OtherMeta; // East/West -> North/South + + case 0x02: return 0x04 + OtherMeta; // Asc. East -> Asc. North + case 0x04: return 0x03 + OtherMeta; // Asc. North -> Asc. West + case 0x03: return 0x05 + OtherMeta; // Asc. West -> Asc. South + case 0x05: return 0x02 + OtherMeta; // Asc. South -> Asc. East + } + } + else + { + switch (a_Meta) + { + // Corner Directions + case 0x06: return 0x09; // Northwest Cnr. -> Southwest Cnr. + case 0x07: return 0x06; // Northeast Cnr. -> Northwest Cnr. + case 0x08: return 0x07; // Southeast Cnr. -> Northeast Cnr. + case 0x09: return 0x08; // Southwest Cnr. -> Southeast Cnr. + } + } + // To avoid a compiler warning; + return a_Meta; + } + + + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override + { + // Bit 0x08 is a flag for value in the range 0x00--0x05 and specifies direction for values withint 0x006--0x09. + if ((a_Meta < 0x06) || (a_Meta > 0x09)) + { + // Save powered rail flag. + NIBBLETYPE OtherMeta = a_Meta & 0x08; + // Rotates according to table; 0x07 == 0111. + // Rails can either be flat (North/South) or Ascending (Asc. East) + switch (a_Meta & 0x07) + { + case 0x00: return 0x01 + OtherMeta; // North/South -> East/West + case 0x01: return 0x00 + OtherMeta; // East/West -> North/South + + case 0x02: return 0x05 + OtherMeta; // Asc. East -> Asc. South + case 0x05: return 0x03 + OtherMeta; // Asc. South -> Asc. West + case 0x03: return 0x04 + OtherMeta; // Asc. West -> Asc. North + case 0x04: return 0x02 + OtherMeta; // Asc. North -> Asc. East + } + } + else + { + switch (a_Meta) + { + // Corner Directions + case 0x06: return 0x07; // Northwest Cnr. -> Northeast Cnr. + case 0x07: return 0x08; // Northeast Cnr. -> Southeast Cnr. + case 0x08: return 0x09; // Southeast Cnr. -> Southwest Cnr. + case 0x09: return 0x06; // Southwest Cnr. -> Northwest Cnr. + } + } + // To avoid a compiler warning; + return a_Meta; + } + + + virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override + { + // Bit 0x08 is a flag for value in the range 0x00--0x05 and specifies direction for values withint 0x006--0x09. + if ((a_Meta < 0x06) || (a_Meta > 0x09)) + { + // Save powered rail flag. + NIBBLETYPE OtherMeta = a_Meta & 0x08; + // Mirrors according to table; 0x07 == 0111. + // Rails can either be flat (North/South) or Ascending (Asc. East) + switch (a_Meta & 0x07) + { + case 0x05: return 0x04 + OtherMeta; // Asc. South -> Asc. North + case 0x04: return 0x05 + OtherMeta; // Asc. North -> Asc. South + } + } + else + { + switch (a_Meta) + { + // Corner Directions + case 0x06: return 0x09; // Northwest Cnr. -> Southwest Cnr. + case 0x07: return 0x08; // Northeast Cnr. -> Southeast Cnr. + case 0x08: return 0x07; // Southeast Cnr. -> Northeast Cnr. + case 0x09: return 0x06; // Southwest Cnr. -> Northwest Cnr. + } + } + // To avoid a compiler warning; + return a_Meta; + } + + + virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override + { + // Bit 0x08 is a flag for value in the range 0x00--0x05 and specifies direction for values withint 0x006--0x09. + if ((a_Meta < 0x06) || (a_Meta > 0x09)) + { + // Save powered rail flag. + NIBBLETYPE OtherMeta = a_Meta & 0x08; + // Mirrors according to table; 0x07 == 0111. + // Rails can either be flat (North/South) or Ascending (Asc. East) + switch (a_Meta & 0x07) + { + case 0x02: return 0x03 + OtherMeta; // Asc. East -> Asc. West + case 0x03: return 0x02 + OtherMeta; // Asc. West -> Asc. East + } + } + else + { + switch (a_Meta) + { + // Corner Directions + case 0x06: return 0x07; // Northwest Cnr. -> Northeast Cnr. + case 0x07: return 0x06; // Northeast Cnr. -> Northwest Cnr. + case 0x08: return 0x09; // Southeast Cnr. -> Southwest Cnr. + case 0x09: return 0x08; // Southwest Cnr. -> Southeast Cnr. + } + } + // To avoid a compiler warning; + return a_Meta; + } } ; diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h index 1e2a86949..fe6cd21b9 100644 --- a/src/Blocks/BlockRedstoneRepeater.h +++ b/src/Blocks/BlockRedstoneRepeater.h @@ -3,17 +3,17 @@ #include "BlockHandler.h" #include "Chunk.h" - +#include "MetaRotator.h" class cBlockRedstoneRepeaterHandler : - public cBlockHandler + public cMetaRotator { public: cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index 7cd2c97b2..b18bf7ef3 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -14,8 +14,6 @@ - - class cBlockSlabHandler : public cBlockHandler { @@ -184,6 +182,15 @@ public: ASSERT(!"Unhandled double slab type!"); return ""; } + + + virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override + { + NIBBLETYPE OtherMeta = a_Meta & 0x07; // Contains unrelate 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/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index 9bae92c4d..6a36ab874 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -2,17 +2,17 @@ #pragma once #include "BlockHandler.h" - +#include "MetaRotator.h" class cBlockTrapdoorHandler : - public cBlockHandler + public cMetaRotator { public: cBlockTrapdoorHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotator(a_BlockType) { } From 6b77dc74ade3d8088da09d26c1b701d92ef28e9e Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 24 Mar 2014 12:29:19 +0200 Subject: [PATCH 009/145] Wither invulnerability --- src/Blocks/BlockMobHead.h | 14 +++++++ src/Mobs/Monster.cpp | 1 + src/Mobs/Wither.cpp | 52 ++++++++++++++++++++++++- src/Mobs/Wither.h | 14 +++++++ src/World.h | 2 +- src/WorldStorage/MapSerializer.cpp | 6 ++- src/WorldStorage/NBTChunkSerializer.cpp | 8 +++- src/WorldStorage/WSSAnvil.cpp | 8 +++- 8 files changed, 100 insertions(+), 5 deletions(-) diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 2b128f13b..6aa01f986 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -21,6 +21,18 @@ public: { a_Pickups.push_back(cItem(E_ITEM_HEAD, 1, 0)); } + + bool TrySpawnWither(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) + { + if (a_BlockY < 2) + { + return false; + } + + // TODO 2014-03-24 xdot + + return false; + } virtual void OnPlacedByPlayer( cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, @@ -62,6 +74,8 @@ public: cWorld * World = (cWorld *) &a_WorldInterface; World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); + + TrySpawnWither(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); } } ; diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 16d6aed1f..d3e0f1c26 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -758,6 +758,7 @@ cMonster::eFamily cMonster::FamilyFromType(eType a_Type) case mtSquid: return mfWater; case mtVillager: return mfPassive; case mtWitch: return mfHostile; + case mtWither: return mfHostile; case mtWolf: return mfHostile; case mtZombie: return mfHostile; case mtZombiePigman: return mfHostile; diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index c46e0beab..0e42194ac 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -2,14 +2,64 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Wither.h" +#include "../World.h" cWither::cWither(void) : - super("Wither", mtWither, "mob.wither.hurt", "mob.wither.death", 0.9, 4.0) + super("Wither", mtWither, "mob.wither.hurt", "mob.wither.death", 0.9, 4.0), + m_InvulnerableTicks(220) { + SetMaxHealth(300); + + SetHealth(GetMaxHealth() / 3); +} + + + + + +void cWither::DoTakeDamage(TakeDamageInfo & a_TDI) +{ + if (a_TDI.DamageType == dtDrowning) + { + return; + } + + if (m_InvulnerableTicks > 0) + { + return; + } + + super::DoTakeDamage(a_TDI); +} + + + + + +void cWither::Tick(float a_Dt, cChunk & a_Chunk) +{ + super::Tick(a_Dt, a_Chunk); + + if (m_InvulnerableTicks > 0) + { + unsigned int NewTicks = m_InvulnerableTicks - 1; + + if (NewTicks == 0) + { + m_World->DoExplosionAt(7.0, GetPosX(), GetPosY(), GetPosZ(), false, esWitherBirth, this); + } + + m_InvulnerableTicks = NewTicks; + + if ((NewTicks % 10) == 0) + { + Heal(10); + } + } } diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h index 56effc6bb..df3a57798 100644 --- a/src/Mobs/Wither.h +++ b/src/Mobs/Wither.h @@ -16,8 +16,22 @@ public: cWither(void); CLASS_PROTODEF(cWither); + + unsigned int GetNumInvulnerableTicks(void) const { return m_InvulnerableTicks; } + + void SetNumInvulnerableTicks(unsigned int a_Ticks) { m_InvulnerableTicks = a_Ticks; } + // Override functions virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + + virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; + + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + +private: + + /** The number of ticks of invulnerability left after being initially created. Zero once invulnerability has expired. */ + unsigned int m_InvulnerableTicks; } ; diff --git a/src/World.h b/src/World.h index 46aece18f..79fcc5616 100644 --- a/src/World.h +++ b/src/World.h @@ -505,7 +505,7 @@ public: | esGhastFireball | cGhastFireball * | | esWitherSkullBlack | TBD | | esWitherSkullBlue | TBD | - | esWitherBirth | TBD | + | esWitherBirth | cWither * | | esPlugin | void * | */ virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData); // tolua_export // override, cannot specify due to tolua diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp index a4a0aab57..df72d1cc9 100644 --- a/src/WorldStorage/MapSerializer.cpp +++ b/src/WorldStorage/MapSerializer.cpp @@ -141,7 +141,11 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) { eDimension Dimension = (eDimension) a_NBT.GetByte(CurrLine); - ASSERT(Dimension == m_Map->m_World->GetDimension()); + if (Dimension != m_Map->m_World->GetDimension()) + { + // TODO 2014-03-20 xdot: We should store nether maps in nether worlds, e.t.c. + return false; + } } CurrLine = a_NBT.FindChildByName(Data, "width"); diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index acca96ba8..f9cca1495 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -43,6 +43,7 @@ #include "../Mobs/Slime.h" #include "../Mobs/Skeleton.h" #include "../Mobs/Villager.h" +#include "../Mobs/Wither.h" #include "../Mobs/Wolf.h" #include "../Mobs/Zombie.h" @@ -422,7 +423,7 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) case cMonster::mtSquid: EntityClass = "Squid"; break; case cMonster::mtVillager: EntityClass = "Villager"; break; case cMonster::mtWitch: EntityClass = "Witch"; break; - case cMonster::mtWither: EntityClass = "Wither"; break; + case cMonster::mtWither: EntityClass = "WitherBoss"; break; case cMonster::mtWolf: EntityClass = "Wolf"; break; case cMonster::mtZombie: EntityClass = "Zombie"; break; case cMonster::mtZombiePigman: EntityClass = "PigZombie"; break; @@ -501,6 +502,11 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) m_Writer.AddInt("Profession", ((const cVillager *)a_Monster)->GetVilType()); break; } + case cMonster::mtWither: + { + m_Writer.AddInt("Invul", ((const cWither *)a_Monster)->GetNumInvulnerableTicks()); + break; + } case cMonster::mtWolf: { m_Writer.AddString("Owner", ((const cWolf *)a_Monster)->GetOwner()); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 7a2366755..2516ac07a 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1238,7 +1238,7 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { LoadWitchFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } - else if (strncmp(a_IDTag, "Wither", a_IDTagLength) == 0) + else if (strncmp(a_IDTag, "WitherBoss", a_IDTagLength) == 0) { LoadWitherFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } @@ -2250,6 +2250,12 @@ void cWSSAnvil::LoadWitherFromNBT(cEntityList & a_Entities, const cParsedNBT & a return; } + int CurrLine = a_NBT.FindChildByName(a_TagIdx, "Invul"); + if (CurrLine > 0) + { + Monster->SetNumInvulnerableTicks(a_NBT.GetInt(CurrLine)); + } + a_Entities.push_back(Monster.release()); } From a6414d334834692c1d8b573b1e90c464d4d4469c Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 24 Mar 2014 19:52:35 +0100 Subject: [PATCH 010/145] Add log pickups. --- src/Blocks/BlockSideways.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Blocks/BlockSideways.h b/src/Blocks/BlockSideways.h index 69c0a7230..d67c3aa24 100644 --- a/src/Blocks/BlockSideways.h +++ b/src/Blocks/BlockSideways.h @@ -29,7 +29,13 @@ public: return true; } - + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.Add(m_BlockType, 1, a_BlockMeta & 0x3); + } + + inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace, NIBBLETYPE a_WoodMeta) { switch (a_BlockFace) From 4f3377bbbfa12623be61561ae75bdd9d8d5fbe8c Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 25 Mar 2014 09:10:55 +0200 Subject: [PATCH 011/145] Minor fixes --- src/Mobs/Villager.h | 2 +- src/Mobs/Wither.h | 5 ++--- src/World.h | 20 ++++++++++---------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/Mobs/Villager.h b/src/Mobs/Villager.h index b99ae876f..5bba4d4ba 100644 --- a/src/Mobs/Villager.h +++ b/src/Mobs/Villager.h @@ -29,7 +29,7 @@ public: CLASS_PROTODEF(cVillager); - // Override functions + // cEntity overrides virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; virtual void Tick (float a_Dt, cChunk & a_Chunk) override; diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h index df3a57798..d09e3607a 100644 --- a/src/Mobs/Wither.h +++ b/src/Mobs/Wither.h @@ -21,17 +21,16 @@ public: void SetNumInvulnerableTicks(unsigned int a_Ticks) { m_InvulnerableTicks = a_Ticks; } - // Override functions + // cEntity overrides virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; - virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; - virtual void Tick(float a_Dt, cChunk & a_Chunk) override; private: /** The number of ticks of invulnerability left after being initially created. Zero once invulnerability has expired. */ unsigned int m_InvulnerableTicks; + } ; diff --git a/src/World.h b/src/World.h index 79fcc5616..bb2eb0b21 100644 --- a/src/World.h +++ b/src/World.h @@ -497,16 +497,16 @@ public: /** Does an explosion with the specified strength at the specified coordinate a_SourceData exact type depends on the a_Source: - | esOther | void * | - | esPrimedTNT | cTNTEntity * | - | esMonster | cMonster * | - | esBed | cVector3i * | - | esEnderCrystal | Vector3i * | - | esGhastFireball | cGhastFireball * | - | esWitherSkullBlack | TBD | - | esWitherSkullBlue | TBD | - | esWitherBirth | cWither * | - | esPlugin | void * | + | esOther | void * | + | esPrimedTNT | cTNTEntity * | + | esMonster | cMonster * | + | esBed | cVector3i * | + | esEnderCrystal | Vector3i * | + | esGhastFireball | cGhastFireball * | + | esWitherSkullBlack | TBD | + | esWitherSkullBlue | TBD | + | esWitherBirth | cMonster * | + | esPlugin | void * | */ virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData); // tolua_export // override, cannot specify due to tolua From 0fe1e50ffc744d861744e4aa4905e1b4b15e10fd Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 25 Mar 2014 10:32:58 +0200 Subject: [PATCH 012/145] Protocol: Wither metadata --- src/Blocks/BlockMobHead.h | 82 ++++++++++++++++++++++++++++++++++-- src/Mobs/Wither.cpp | 16 +++++++ src/Mobs/Wither.h | 3 ++ src/Protocol/Protocol125.cpp | 8 ++++ src/Protocol/Protocol17x.cpp | 10 +++++ 5 files changed, 116 insertions(+), 3 deletions(-) diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 6aa01f986..9935c2496 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -22,14 +22,90 @@ public: a_Pickups.push_back(cItem(E_ITEM_HEAD, 1, 0)); } - bool TrySpawnWither(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) + bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) { if (a_BlockY < 2) { return false; } + + class cCallback : public cMobHeadCallback + { + bool m_IsWither; + + virtual bool Item (cMobHeadEntity * a_MobHeadEntity) + { + m_IsWither = (a_MobHeadEntity->GetType() == SKULL_TYPE_WITHER); + + return false; + } - // TODO 2014-03-24 xdot + public: + cCallback () : m_IsWither(false) {} + + bool IsWither(void) const { return m_IsWither; } + + void Reset(void) { m_IsWither = false; } + } CallbackA, CallbackB; + + BLOCKTYPE BlockY1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); + BLOCKTYPE BlockY2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 2, a_BlockZ); + + if ((BlockY1 != E_BLOCK_SOULSAND) || (BlockY2 != E_BLOCK_SOULSAND)) + { + return false; + } + + a_World->DoWithMobHeadAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA); + a_World->DoWithMobHeadAt(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); + + if ((Block1 == E_BLOCK_SOULSAND) && (Block2 == E_BLOCK_SOULSAND) && CallbackA.IsWither() && CallbackB.IsWither()) + { + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.FastSetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.FastSetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); + 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); + + // Spawn the wither: + a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); + + return true; + } + + 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); + + Block1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1); + Block2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1); + + if ((Block1 == E_BLOCK_SOULSAND) && (Block2 == E_BLOCK_SOULSAND) && CallbackA.IsWither() && CallbackB.IsWither()) + { + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1, E_BLOCK_AIR, 0); + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1, E_BLOCK_AIR, 0); + 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); + + // Spawn the wither: + a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); + + return true; + } return false; } @@ -75,7 +151,7 @@ public: World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); - TrySpawnWither(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); + TrySpawnWither(a_ChunkInterface, World, a_BlockX, a_BlockY, a_BlockZ); } } ; diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index 0e42194ac..790f127f2 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -21,6 +21,15 @@ cWither::cWither(void) : +bool cWither::IsArmored(void) const +{ + return GetHealth() <= (GetMaxHealth() / 2); +} + + + + + void cWither::DoTakeDamage(TakeDamageInfo & a_TDI) { if (a_TDI.DamageType == dtDrowning) @@ -33,6 +42,11 @@ void cWither::DoTakeDamage(TakeDamageInfo & a_TDI) return; } + if (IsArmored() && (a_TDI.DamageType == dtRangedAttack)) + { + return; + } + super::DoTakeDamage(a_TDI); } @@ -60,6 +74,8 @@ void cWither::Tick(float a_Dt, cChunk & a_Chunk) Heal(10); } } + + m_World->BroadcastEntityMetadata(*this); } diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h index d09e3607a..52666a190 100644 --- a/src/Mobs/Wither.h +++ b/src/Mobs/Wither.h @@ -20,6 +20,9 @@ public: unsigned int GetNumInvulnerableTicks(void) const { return m_InvulnerableTicks; } void SetNumInvulnerableTicks(unsigned int a_Ticks) { m_InvulnerableTicks = a_Ticks; } + + /** Returns whether the wither is invulnerable to arrows. */ + bool IsArmored(void) const; // cEntity overrides virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 69f4934d8..d8b340350 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -1972,6 +1972,14 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) WriteByte(((const cWitch &)a_Mob).IsAngry() ? 1 : 0); // Aggravated? Doesn't seem to do anything break; } + case cMonster::mtWither: + { + WriteByte(0x54); // Int at index 20 + WriteInt(((const cWither &)a_Mob).GetNumInvulnerableTicks()); + WriteByte(0x66); // Float at index 6 + WriteFloat((float)(a_Mob.GetHealth())); + break; + } case cMonster::mtSlime: case cMonster::mtMagmaCube: { diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 721ed349e..c678fc9a0 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2535,6 +2535,7 @@ void cProtocol172::cPacketizer::WriteEntityMetadata(const cEntity & a_Entity) WriteByte(Frame.GetRotation()); break; } + default: break; } } @@ -2659,6 +2660,15 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) WriteByte(((const cWitch &)a_Mob).IsAngry() ? 1 : 0); break; } + + case cMonster::mtWither: + { + WriteByte(0x54); // Int at index 20 + WriteInt(((const cWither &)a_Mob).GetNumInvulnerableTicks()); + WriteByte(0x66); // Float at index 6 + WriteFloat((float)(a_Mob.GetHealth())); + break; + } case cMonster::mtSlime: { From ba4216641120ec2f49464ed0b136af3198d48f89 Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 25 Mar 2014 11:13:27 +0200 Subject: [PATCH 013/145] Fixed wither summoning --- src/Blocks/BlockMobHead.h | 25 ++++++++++++++++++++++++- src/Mobs/Wither.cpp | 14 ++++++++++++-- src/Mobs/Wither.h | 1 + 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 9935c2496..693240898 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -47,6 +47,15 @@ public: void Reset(void) { m_IsWither = false; } } CallbackA, CallbackB; + + a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA); + + if (!CallbackA.IsWither()) + { + return false; + } + + CallbackA.Reset(); BLOCKTYPE BlockY1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); BLOCKTYPE BlockY2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 2, a_BlockZ); @@ -151,7 +160,21 @@ public: World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); - TrySpawnWither(a_ChunkInterface, World, a_BlockX, a_BlockY, a_BlockZ); + static const Vector3i Coords[] = + { + Vector3i( 0, 0, 0), + Vector3i( 1, 0, 0), + Vector3i(-1, 0, 0), + Vector3i( 0, 0, 1), + Vector3i( 0, 0, -1), + }; + 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)) + { + break; + } + } // for i - Coords[] } } ; diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index 790f127f2..39dc6aab9 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -13,8 +13,6 @@ cWither::cWither(void) : m_InvulnerableTicks(220) { SetMaxHealth(300); - - SetHealth(GetMaxHealth() / 3); } @@ -30,6 +28,18 @@ bool cWither::IsArmored(void) const +bool cWither::Initialize(cWorld * a_World) override +{ + // Set health before BroadcastSpawnEntity() + SetHealth(GetMaxHealth() / 3); + + return super::Initialize(a_World); +} + + + + + void cWither::DoTakeDamage(TakeDamageInfo & a_TDI) { if (a_TDI.DamageType == dtDrowning) diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h index 52666a190..bc78bfaad 100644 --- a/src/Mobs/Wither.h +++ b/src/Mobs/Wither.h @@ -25,6 +25,7 @@ public: bool IsArmored(void) const; // cEntity overrides + virtual bool Initialize(cWorld * a_World) override; virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; From c8445cd93479d4729a180b21df1783449ce01b7e Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 25 Mar 2014 11:40:54 +0200 Subject: [PATCH 014/145] Fixed clang compilation --- src/Blocks/BlockMobHead.h | 29 ++++++++++++++++------------- src/Mobs/Wither.cpp | 2 +- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 693240898..e172cee69 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -160,21 +160,24 @@ public: World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); - static const Vector3i Coords[] = + if (a_BlockMeta == SKULL_TYPE_WITHER) { - Vector3i( 0, 0, 0), - Vector3i( 1, 0, 0), - Vector3i(-1, 0, 0), - Vector3i( 0, 0, 1), - Vector3i( 0, 0, -1), - }; - 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)) + static const Vector3i Coords[] = { - break; - } - } // for i - Coords[] + Vector3i( 0, 0, 0), + Vector3i( 1, 0, 0), + Vector3i(-1, 0, 0), + Vector3i( 0, 0, 1), + Vector3i( 0, 0, -1), + }; + 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)) + { + break; + } + } // for i - Coords[] + } } } ; diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index 39dc6aab9..8f5d28b68 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -28,7 +28,7 @@ bool cWither::IsArmored(void) const -bool cWither::Initialize(cWorld * a_World) override +bool cWither::Initialize(cWorld * a_World) { // Set health before BroadcastSpawnEntity() SetHealth(GetMaxHealth() / 3); From d77a6417f62990f5c986e03a7e226c03b5a74fb8 Mon Sep 17 00:00:00 2001 From: Samuel Barney Date: Tue, 25 Mar 2014 10:33:52 -0600 Subject: [PATCH 015/145] Added newlines. Without them, the files would not compile. --- src/Entities/Effects.h | 2 +- src/Entities/Floater.h | 2 +- src/OSSupport/Sleep.h | 2 +- src/OSSupport/Thread.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Entities/Effects.h b/src/Entities/Effects.h index e7611847d..baf3302fb 100644 --- a/src/Entities/Effects.h +++ b/src/Entities/Effects.h @@ -27,4 +27,4 @@ enum ENUM_ENTITY_EFFECT E_EFFECT_ABSORPTION = 22, E_EFFECT_SATURATION = 23, } ; -// tolua_end \ No newline at end of file +// tolua_end diff --git a/src/Entities/Floater.h b/src/Entities/Floater.h index f3b51d77b..547d503f1 100644 --- a/src/Entities/Floater.h +++ b/src/Entities/Floater.h @@ -43,4 +43,4 @@ protected: // Entity IDs int m_PlayerID; int m_AttachedMobID; -} ; // tolua_export \ No newline at end of file +} ; // tolua_export diff --git a/src/OSSupport/Sleep.h b/src/OSSupport/Sleep.h index 5298c15da..0ec0adf9d 100644 --- a/src/OSSupport/Sleep.h +++ b/src/OSSupport/Sleep.h @@ -4,4 +4,4 @@ class cSleep { public: static void MilliSleep( unsigned int a_MilliSeconds ); -}; \ No newline at end of file +}; diff --git a/src/OSSupport/Thread.h b/src/OSSupport/Thread.h index 3c9316424..4153b2427 100644 --- a/src/OSSupport/Thread.h +++ b/src/OSSupport/Thread.h @@ -23,4 +23,4 @@ private: cEvent* m_StopEvent; AString m_ThreadName; -}; \ No newline at end of file +}; From 71e9133e49c238ce74de144c5ab3b3d01d29152e Mon Sep 17 00:00:00 2001 From: Samuel Barney Date: Tue, 25 Mar 2014 10:34:31 -0600 Subject: [PATCH 016/145] Added one more missing newline. --- src/WorldStorage/FireworksSerializer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WorldStorage/FireworksSerializer.h b/src/WorldStorage/FireworksSerializer.h index 5b87bafdb..cbc544a14 100644 --- a/src/WorldStorage/FireworksSerializer.h +++ b/src/WorldStorage/FireworksSerializer.h @@ -89,4 +89,4 @@ public: short m_FlightTimeInTicks; std::vector m_Colours; std::vector m_FadeColours; -}; \ No newline at end of file +}; From eb3cc729d4e367c54a47369f712831908f8da22c Mon Sep 17 00:00:00 2001 From: Samuel Barney Date: Tue, 25 Mar 2014 11:15:05 -0600 Subject: [PATCH 017/145] More fixes to get it to compile for me on Mac 10.9. Mostly just newline additions, but some of the unused variables were causing errors, so I wrapped them in #ifndef __APPLE__ calls, since I didn't know if they were going to be used in the future. Also had to undefine TOLUA_TEMPLATE_BIND a couple of times. --- lib/md5/md5.h | 2 +- src/Bindings/DeprecatedBindings.cpp | 1 + src/Bindings/LuaState.cpp | 1 + src/Bindings/ManualBindings.cpp | 1 + src/Bindings/ManualBindings.h | 2 +- src/Bindings/PluginLua.cpp | 5 +++++ src/Bindings/WebPlugin.cpp | 2 +- src/DeadlockDetect.cpp | 2 ++ src/Entities/Boat.cpp | 2 -- src/Entities/ExpOrb.h | 2 +- src/Group.cpp | 2 +- src/Mobs/Blaze.cpp | 2 +- src/Mobs/Blaze.h | 4 ---- src/Mobs/Skeleton.cpp | 2 +- src/OSSupport/Errors.cpp | 2 +- src/World.cpp | 3 ++- 16 files changed, 20 insertions(+), 15 deletions(-) diff --git a/lib/md5/md5.h b/lib/md5/md5.h index ad5ad5384..3aa88ac22 100644 --- a/lib/md5/md5.h +++ b/lib/md5/md5.h @@ -90,4 +90,4 @@ private: std::string md5(const std::string & str); -#endif \ No newline at end of file +#endif diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index 408b1b84a..fbc008be6 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "DeprecatedBindings.h" +#undef TOLUA_TEMPLATE_BIND #include "tolua++/include/tolua++.h" #include "Plugin.h" diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 47380b8a7..7afae5e38 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -11,6 +11,7 @@ extern "C" #include "lua/src/lualib.h" } +#undef TOLUA_TEMPLATE_BIND #include "tolua++/include/tolua++.h" #include "Bindings.h" #include "ManualBindings.h" diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 20bbc48f2..081ea4d59 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "ManualBindings.h" +#undef TOLUA_TEMPLATE_BIND #include "tolua++/include/tolua++.h" #include "Plugin.h" diff --git a/src/Bindings/ManualBindings.h b/src/Bindings/ManualBindings.h index e6594947e..f38e26267 100644 --- a/src/Bindings/ManualBindings.h +++ b/src/Bindings/ManualBindings.h @@ -5,4 +5,4 @@ class ManualBindings { public: static void Bind( lua_State* tolua_S ); -}; \ No newline at end of file +}; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index cccbc3c93..ebabeb222 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -5,7 +5,11 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules +#ifdef __APPLE__ +#define LUA_USE_MACOSX +#else #define LUA_USE_POSIX +#endif #include "PluginLua.h" #include "../CommandOutput.h" @@ -14,6 +18,7 @@ extern "C" #include "lua/src/lualib.h" } +#undef TOLUA_TEMPLATE_BIND #include "tolua++/include/tolua++.h" diff --git a/src/Bindings/WebPlugin.cpp b/src/Bindings/WebPlugin.cpp index 3b71d553c..bf45405ba 100644 --- a/src/Bindings/WebPlugin.cpp +++ b/src/Bindings/WebPlugin.cpp @@ -110,4 +110,4 @@ AString cWebPlugin::SafeString( const AString & a_String ) RetVal.push_back( c ); } return RetVal; -} \ No newline at end of file +} diff --git a/src/DeadlockDetect.cpp b/src/DeadlockDetect.cpp index 4dc7bfde6..8e1283bba 100644 --- a/src/DeadlockDetect.cpp +++ b/src/DeadlockDetect.cpp @@ -17,7 +17,9 @@ const int CYCLE_MILLISECONDS = 100; /// When the number of cycles for the same world age hits this value, it is considered a deadlock +#ifndef __APPLE__ const int NUM_CYCLES_LIMIT = 200; // 200 = twenty seconds +#endif diff --git a/src/Entities/Boat.cpp b/src/Entities/Boat.cpp index 94b24c5af..921252253 100644 --- a/src/Entities/Boat.cpp +++ b/src/Entities/Boat.cpp @@ -122,5 +122,3 @@ void cBoat::HandleSpeedFromAttachee(float a_Forward, float a_Sideways) AddSpeed(ToAddSpeed); } - - \ No newline at end of file diff --git a/src/Entities/ExpOrb.h b/src/Entities/ExpOrb.h index c1150bd03..e76274ac9 100644 --- a/src/Entities/ExpOrb.h +++ b/src/Entities/ExpOrb.h @@ -42,4 +42,4 @@ protected: /** The number of ticks that the entity has existed / timer between collect and destroy; in msec */ float m_Timer; -} ; // tolua_export \ No newline at end of file +} ; // tolua_export diff --git a/src/Group.cpp b/src/Group.cpp index 5f1f25782..9c2467144 100644 --- a/src/Group.cpp +++ b/src/Group.cpp @@ -38,4 +38,4 @@ void cGroup::InheritFrom( cGroup* a_Group ) void cGroup::ClearPermission() { m_Permissions.clear(); -} \ No newline at end of file +} diff --git a/src/Mobs/Blaze.cpp b/src/Mobs/Blaze.cpp index ac42cf40b..84ff8929b 100644 --- a/src/Mobs/Blaze.cpp +++ b/src/Mobs/Blaze.cpp @@ -53,4 +53,4 @@ void cBlaze::Attack(float a_Dt) m_AttackInterval = 0.0; // ToDo: Shoot 3 fireballs instead of 1. } -} \ No newline at end of file +} diff --git a/src/Mobs/Blaze.h b/src/Mobs/Blaze.h index cdb3a1306..5970451c7 100644 --- a/src/Mobs/Blaze.h +++ b/src/Mobs/Blaze.h @@ -20,7 +20,3 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void Attack(float a_Dt) override; } ; - - - - diff --git a/src/Mobs/Skeleton.cpp b/src/Mobs/Skeleton.cpp index 47fcdbb26..1685f40c5 100644 --- a/src/Mobs/Skeleton.cpp +++ b/src/Mobs/Skeleton.cpp @@ -88,4 +88,4 @@ void cSkeleton::Attack(float a_Dt) m_World->BroadcastSpawnEntity(*Arrow); m_AttackInterval = 0.0; } -} \ No newline at end of file +} diff --git a/src/OSSupport/Errors.cpp b/src/OSSupport/Errors.cpp index 2e05f1df1..6072b6ac6 100644 --- a/src/OSSupport/Errors.cpp +++ b/src/OSSupport/Errors.cpp @@ -22,7 +22,7 @@ AString GetOSErrorString( int a_ErrNo ) // According to http://linux.die.net/man/3/strerror_r there are two versions of strerror_r(): - #if ( _GNU_SOURCE ) && !defined(ANDROID_NDK) // GNU version of strerror_r() + #if !defined(__APPLE__) && ( _GNU_SOURCE ) && !defined(ANDROID_NDK) // GNU version of strerror_r() char * res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) ); if( res != NULL ) diff --git a/src/World.cpp b/src/World.cpp index 3f157157a..98f6a4b5a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -59,9 +59,10 @@ - +#ifndef __APPLE__ /// Up to this many m_SpreadQueue elements are handled each world tick const int MAX_LIGHTING_SPREAD_PER_TICK = 10; +#endif const int TIME_SUNSET = 12000; const int TIME_NIGHT_START = 13187; From 2e28c09770a937b253680d7f62b9b2f4c8f4670c Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 25 Mar 2014 20:59:33 +0200 Subject: [PATCH 018/145] Ender crystals --- src/Entities/EnderCrystal.cpp | 56 +++++++++++++++++++++++++ src/Entities/EnderCrystal.h | 33 +++++++++++++++ src/Entities/Entity.h | 24 ++++++----- src/WorldStorage/NBTChunkSerializer.cpp | 13 ++++++ src/WorldStorage/NBTChunkSerializer.h | 2 + src/WorldStorage/WSSAnvil.cpp | 19 +++++++++ src/WorldStorage/WSSAnvil.h | 1 + 7 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 src/Entities/EnderCrystal.cpp create mode 100644 src/Entities/EnderCrystal.h diff --git a/src/Entities/EnderCrystal.cpp b/src/Entities/EnderCrystal.cpp new file mode 100644 index 000000000..a640b236c --- /dev/null +++ b/src/Entities/EnderCrystal.cpp @@ -0,0 +1,56 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "EnderCrystal.h" +#include "ClientHandle.h" +#include "Player.h" +#include "../Chunk.h" + + + + + +cEnderCrystal::cEnderCrystal(double a_X, double a_Y, double a_Z) + : cEntity(etEnderCrystal, a_X, a_Y, a_Z, 1.0, 1.0) +{ + SetMaxHealth(5); +} + + + + + +void cEnderCrystal::SpawnOn(cClientHandle & a_ClientHandle) +{ + a_ClientHandle.SendSpawnObject(*this, 51, 0, (Byte)GetYaw(), (Byte)GetPitch()); +} + + + + + +void cEnderCrystal::Tick(float a_Dt, cChunk & a_Chunk) +{ + UNUSED(a_Dt); + + a_Chunk.SetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT, E_BLOCK_FIRE, 0); + + // No further processing (physics e.t.c.) is needed +} + + + + + +void cEnderCrystal::KilledBy(cEntity * a_Killer) +{ + super::KilledBy(a_Killer); + + m_World->DoExplosionAt(6.0, GetPosX(), GetPosY(), GetPosZ(), true, esEnderCrystal, this); + + Destroy(); +} + + + + diff --git a/src/Entities/EnderCrystal.h b/src/Entities/EnderCrystal.h new file mode 100644 index 000000000..5b86df987 --- /dev/null +++ b/src/Entities/EnderCrystal.h @@ -0,0 +1,33 @@ + +#pragma once + +#include "Entity.h" + + + + + +// tolua_begin +class cEnderCrystal : + public cEntity +{ + // tolua_end + typedef cEntity super; + +public: + CLASS_PROTODEF(cEnderCrystal); + + cEnderCrystal(double a_X, double a_Y, double a_Z); + +private: + + // cEntity overrides: + virtual void SpawnOn(cClientHandle & a_ClientHandle) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + virtual void KilledBy(cEntity * a_Killer) override; + +}; // tolua_export + + + + diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index df80093e5..e41f74b09 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -69,6 +69,7 @@ public: enum eEntityType { etEntity, // For all other types + etEnderCrystal, etPlayer, etPickup, etMonster, @@ -130,18 +131,19 @@ public: eEntityType GetEntityType(void) const { return m_EntityType; } - bool IsPlayer (void) const { return (m_EntityType == etPlayer); } - bool IsPickup (void) const { return (m_EntityType == etPickup); } - bool IsMob (void) const { return (m_EntityType == etMonster); } + bool IsEnderCrystal(void) const { return (m_EntityType == etEnderCrystal); } + bool IsPlayer (void) const { return (m_EntityType == etPlayer); } + bool IsPickup (void) const { return (m_EntityType == etPickup); } + bool IsMob (void) const { return (m_EntityType == etMonster); } bool IsFallingBlock(void) const { return (m_EntityType == etFallingBlock); } - bool IsMinecart (void) const { return (m_EntityType == etMinecart); } - bool IsBoat (void) const { return (m_EntityType == etBoat); } - bool IsTNT (void) const { return (m_EntityType == etTNT); } - bool IsProjectile (void) const { return (m_EntityType == etProjectile); } - bool IsExpOrb (void) const { return (m_EntityType == etExpOrb); } - bool IsFloater (void) const { return (m_EntityType == etFloater); } - bool IsItemFrame (void) const { return (m_EntityType == etItemFrame); } - bool IsPainting (void) const { return (m_EntityType == etPainting); } + bool IsMinecart (void) const { return (m_EntityType == etMinecart); } + bool IsBoat (void) const { return (m_EntityType == etBoat); } + bool IsTNT (void) const { return (m_EntityType == etTNT); } + bool IsProjectile (void) const { return (m_EntityType == etProjectile); } + bool IsExpOrb (void) const { return (m_EntityType == etExpOrb); } + bool IsFloater (void) const { return (m_EntityType == etFloater); } + bool IsItemFrame (void) const { return (m_EntityType == etItemFrame); } + bool IsPainting (void) const { return (m_EntityType == etPainting); } /// Returns true if the entity is of the specified class or a subclass (cPawn's IsA("cEntity") returns true) virtual bool IsA(const char * a_ClassName) const; diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index acca96ba8..9a14d7152 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -23,6 +23,7 @@ #include "../BlockEntities/FlowerPotEntity.h" #include "../Entities/Entity.h" +#include "../Entities/EnderCrystal.h" #include "../Entities/FallingBlock.h" #include "../Entities/Boat.h" #include "../Entities/Minecart.h" @@ -335,6 +336,17 @@ void cNBTChunkSerializer::AddBoatEntity(cBoat * a_Boat) +void cNBTChunkSerializer::AddEnderCrystalEntity(cEnderCrystal * a_EnderCrystal) +{ + m_Writer.BeginCompound(""); + AddBasicEntity(a_EnderCrystal, "EnderCrystal"); + m_Writer.EndCompound(); +} + + + + + void cNBTChunkSerializer::AddFallingBlockEntity(cFallingBlock * a_FallingBlock) { m_Writer.BeginCompound(""); @@ -729,6 +741,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity) switch (a_Entity->GetEntityType()) { case cEntity::etBoat: AddBoatEntity ((cBoat *) a_Entity); break; + case cEntity::etEnderCrystal: AddEnderCrystalEntity((cEnderCrystal *) a_Entity); break; case cEntity::etFallingBlock: AddFallingBlockEntity((cFallingBlock *) a_Entity); break; case cEntity::etMinecart: AddMinecartEntity ((cMinecart *) a_Entity); break; case cEntity::etMonster: AddMonsterEntity ((cMonster *) a_Entity); break; diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index c1134cd00..51d104970 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -24,6 +24,7 @@ class cChestEntity; class cCommandBlockEntity; class cDispenserEntity; class cDropperEntity; +class cEnderCrystal; class cFurnaceEntity; class cHopperEntity; class cJukeboxEntity; @@ -106,6 +107,7 @@ protected: // Entities: void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName); void AddBoatEntity (cBoat * a_Boat); + void AddEnderCrystalEntity(cEnderCrystal * a_EnderCrystal); void AddFallingBlockEntity(cFallingBlock * a_FallingBlock); void AddMinecartEntity (cMinecart * a_Minecart); void AddMonsterEntity (cMonster * a_Monster); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 7a2366755..1214089a1 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -32,6 +32,7 @@ #include "../Mobs/IncludeAllMonsters.h" #include "../Entities/Boat.h" +#include "../Entities/EnderCrystal.h" #include "../Entities/FallingBlock.h" #include "../Entities/Minecart.h" #include "../Entities/Pickup.h" @@ -1057,6 +1058,10 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { LoadBoatFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } + else if (strncmp(a_IDTag, "EnderCrystal", a_IDTagLength) == 0) + { + LoadEnderCrystalFromNBT(a_Entities, a_NBT, a_EntityTagIdx); + } else if (strncmp(a_IDTag, "FallingBlock", a_IDTagLength) == 0) { LoadFallingBlockFromNBT(a_Entities, a_NBT, a_EntityTagIdx); @@ -1275,6 +1280,20 @@ void cWSSAnvil::LoadBoatFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N +void cWSSAnvil::LoadEnderCrystalFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + std::auto_ptr EnderCrystal(new cEnderCrystal(0, 0, 0)); + if (!LoadEntityBaseFromNBT(*EnderCrystal.get(), a_NBT, a_TagIdx)) + { + return; + } + a_Entities.push_back(EnderCrystal.release()); +} + + + + + void cWSSAnvil::LoadFallingBlockFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { int TypeIdx = a_NBT.FindChildByName(a_TagIdx, "TileID"); diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 50d0e555e..1773ee882 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -148,6 +148,7 @@ protected: void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength); void LoadBoatFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadEnderCrystalFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadFallingBlockFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadPickupFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadTNTFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); From f67ad369659307c4148f825cd3e0cdba909ab229 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 24 Mar 2014 08:15:27 +0100 Subject: [PATCH 019/145] InfoReg updated for multi-verb console commands. --- MCServer/Plugins/InfoReg.lua | 51 +++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/MCServer/Plugins/InfoReg.lua b/MCServer/Plugins/InfoReg.lua index b3717884a..27e63aa5b 100644 --- a/MCServer/Plugins/InfoReg.lua +++ b/MCServer/Plugins/InfoReg.lua @@ -9,16 +9,30 @@ --- Lists all the subcommands that the player has permissions for local function ListSubcommands(a_Player, a_Subcommands, a_CmdString) - a_Player:SendMessage("The " .. a_CmdString .. " command requires another verb:"); + if (a_Player == nil) then + LOGINFO("The " .. a_CmdString .. " command requires another verb:") + else + a_Player:SendMessage("The " .. a_CmdString .. " command requires another verb:") + end + + -- Enum all the subcommands: local Verbs = {}; for cmd, info in pairs(a_Subcommands) do if (a_Player:HasPermission(info.Permission or "")) then - table.insert(Verbs, a_CmdString .. " " .. cmd); + table.insert(Verbs, " " .. a_CmdString .. " " .. cmd); end end table.sort(Verbs); - for idx, verb in ipairs(Verbs) do - a_Player:SendMessage(verb); + + -- Send the list: + if (a_Player == nil) then + for idx, verb in ipairs(Verbs) do + LOGINFO(verb); + end + else + for idx, verb in ipairs(Verbs) do + a_Player:SendMessage(verb); + end end end @@ -28,6 +42,7 @@ end --- This is a generic command callback used for handling multicommands' parent commands -- For example, if there are "/gal save" and "/gal load" commands, this callback handles the "/gal" command +-- It is used for both console and in-game commands; the console version has a_Player set to nil local function MultiCommandHandler(a_Split, a_Player, a_CmdString, a_CmdInfo, a_Level) local Verb = a_Split[a_Level + 1]; if (Verb == nil) then @@ -46,7 +61,11 @@ local function MultiCommandHandler(a_Split, a_Player, a_CmdString, a_CmdInfo, a_ if (a_Level > 1) then -- This is a true subcommand, display the message and make MCS think the command was handled -- Otherwise we get weird behavior: for "/cmd verb" we get "unknown command /cmd" although "/cmd" is valid - a_Player:SendMessage("The " .. a_CmdString .. " command doesn't support verb " .. Verb); + if (a_Player == nil) then + LOGWARNING("The " .. a_CmdString .. " command doesn't support verb " .. Verb) + else + a_Player:SendMessage("The " .. a_CmdString .. " command doesn't support verb " .. Verb) + end return true; end -- This is a top-level command, let MCS handle the unknown message @@ -54,9 +73,11 @@ local function MultiCommandHandler(a_Split, a_Player, a_CmdString, a_CmdInfo, a_ end -- Check the permission: - if not(a_Player:HasPermission(Subcommand.Permission or "")) then - a_Player:SendMessage("You don't have permission to execute this command"); - return true; + if (a_Player ~= nil) then + if not(a_Player:HasPermission(Subcommand.Permission or "")) then + a_Player:SendMessage("You don't have permission to execute this command"); + return true; + end end -- If the handler is not valid, check the next sublevel: @@ -149,21 +170,27 @@ end function RegisterPluginInfoConsoleCommands() -- A sub-function that registers all subcommands of a single command, using the command's Subcommands table -- The a_Prefix param already contains the space after the previous command - local function RegisterSubcommands(a_Prefix, a_Subcommands) + local function RegisterSubcommands(a_Prefix, a_Subcommands, a_Level) assert(a_Subcommands ~= nil); for cmd, info in pairs(a_Subcommands) do local CmdName = a_Prefix .. cmd; - cPluginManager.BindConsoleCommand(cmd, info.Handler, info.HelpString or ""); + local Handler = info.Handler + if (Handler == nil) then + Handler = function(a_Split) + return MultiCommandHandler(a_Split, nil, CmdName, info, a_Level); + end + end + cPluginManager.BindConsoleCommand(CmdName, Handler, info.HelpString or ""); -- Recursively register any subcommands: if (info.Subcommands ~= nil) then - RegisterSubcommands(a_Prefix .. cmd .. " ", info.Subcommands); + RegisterSubcommands(a_Prefix .. cmd .. " ", info.Subcommands, a_Level + 1); end end end -- Loop through all commands in the plugin info, register each: - RegisterSubcommands("", g_PluginInfo.ConsoleCommands); + RegisterSubcommands("", g_PluginInfo.ConsoleCommands, 1); end From 0984cf9deb4b60e119adeac56c5d891d2a7cbec6 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 25 Mar 2014 21:33:23 +0100 Subject: [PATCH 020/145] Added Vector3::Move(const Vector3 &). --- src/Vector3.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Vector3.h b/src/Vector3.h index ba4abe3eb..a00e14508 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -121,6 +121,13 @@ public: z += a_Z; } + inline void Move(const Vector3 & a_Diff) + { + x += a_Diff.x; + y += a_Diff.y; + z += a_Diff.z; + } + // tolua_end inline void operator += (const Vector3 & a_Rhs) From 87e0bd54b426bafb6b267725b0e1a94511a38f4e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 25 Mar 2014 21:59:25 +0100 Subject: [PATCH 021/145] BlockArea: Switched internal coords to Vector3i. --- src/BlockArea.cpp | 324 +++++++++---------- src/BlockArea.h | 36 ++- src/Generating/ChunkDesc.cpp | 6 +- src/WorldStorage/SchematicFileSerializer.cpp | 10 +- 4 files changed, 176 insertions(+), 200 deletions(-) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 406e18a3b..692b006d5 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -162,13 +162,6 @@ static void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBB // cBlockArea: cBlockArea::cBlockArea(void) : - m_OriginX(0), - m_OriginY(0), - m_OriginZ(0), - m_SizeX(0), - m_SizeY(0), - m_SizeZ(0), - m_WEOffset(0, 0, 0), m_BlockTypes(NULL), m_BlockMetas(NULL), m_BlockLight(NULL), @@ -195,12 +188,8 @@ void cBlockArea::Clear(void) delete[] m_BlockMetas; m_BlockMetas = NULL; delete[] m_BlockLight; m_BlockLight = NULL; delete[] m_BlockSkyLight; m_BlockSkyLight = NULL; - m_OriginX = 0; - m_OriginY = 0; - m_OriginZ = 0; - m_SizeX = 0; - m_SizeY = 0; - m_SizeZ = 0; + m_Origin.Set(0, 0, 0); + m_Size.Set(0, 0, 0); } @@ -243,12 +232,8 @@ void cBlockArea::Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) m_BlockSkyLight[i] = 0x0f; } } - m_SizeX = a_SizeX; - m_SizeY = a_SizeY; - m_SizeZ = a_SizeZ; - m_OriginX = 0; - m_OriginY = 0; - m_OriginZ = 0; + m_Size.Set(a_SizeX, a_SizeY, a_SizeZ); + m_Origin.Set(0, 0, 0); } @@ -275,9 +260,7 @@ void cBlockArea::SetWEOffset(const Vector3i & a_Offset) void cBlockArea::SetOrigin(int a_OriginX, int a_OriginY, int a_OriginZ) { - m_OriginX = a_OriginX; - m_OriginY = a_OriginY; - m_OriginZ = a_OriginZ; + m_Origin.Set(a_OriginX, a_OriginY, a_OriginZ); } @@ -286,7 +269,7 @@ void cBlockArea::SetOrigin(int a_OriginX, int a_OriginY, int a_OriginZ) void cBlockArea::SetOrigin(const Vector3i & a_Origin) { - SetOrigin(a_Origin.x, a_Origin.y, a_Origin.z); + m_Origin.Set(a_Origin.x, a_Origin.y, a_Origin.z); } @@ -342,9 +325,7 @@ bool cBlockArea::Read(cForEachChunkProvider * a_ForEachChunkProvider, int a_MinB { return false; } - m_OriginX = a_MinBlockX; - m_OriginY = a_MinBlockY; - m_OriginZ = a_MinBlockZ; + m_Origin.Set(a_MinBlockX, a_MinBlockY, a_MinBlockZ); cChunkReader Reader(*this); // Convert block coords to chunks coords: @@ -408,10 +389,10 @@ bool cBlockArea::Write(cForEachChunkProvider * a_ForEachChunkProvider, int a_Min LOGWARNING("%s: MinBlockY less than zero, adjusting to zero", __FUNCTION__); a_MinBlockY = 0; } - else if (a_MinBlockY > cChunkDef::Height - m_SizeY) + else if (a_MinBlockY > cChunkDef::Height - m_Size.y) { LOGWARNING("%s: MinBlockY + m_SizeY more than chunk height, adjusting to chunk height", __FUNCTION__); - a_MinBlockY = cChunkDef::Height - m_SizeY; + a_MinBlockY = cChunkDef::Height - m_Size.y; } return a_ForEachChunkProvider->WriteBlockArea(*this, a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_DataTypes); @@ -443,10 +424,8 @@ void cBlockArea::CopyTo(cBlockArea & a_Into) const } a_Into.Clear(); - a_Into.SetSize(m_SizeX, m_SizeY, m_SizeZ, GetDataTypes()); - a_Into.m_OriginX = m_OriginX; - a_Into.m_OriginY = m_OriginY; - a_Into.m_OriginZ = m_OriginZ; + a_Into.SetSize(m_Size.x, m_Size.y, m_Size.z, GetDataTypes()); + a_Into.m_Origin = m_Origin; int BlockCount = GetBlockCount(); if (HasBlockTypes()) { @@ -487,9 +466,9 @@ void cBlockArea::DumpToRawFile(const AString & a_FileName) LOGWARNING("cBlockArea: Cannot open file \"%s\" for raw dump", a_FileName.c_str()); return; } - UInt32 SizeX = ntohl(m_SizeX); - UInt32 SizeY = ntohl(m_SizeY); - UInt32 SizeZ = ntohl(m_SizeZ); + UInt32 SizeX = ntohl(m_Size.x); + UInt32 SizeY = ntohl(m_Size.y); + UInt32 SizeZ = ntohl(m_Size.z); f.Write(&SizeX, 4); f.Write(&SizeY, 4); f.Write(&SizeZ, 4); @@ -532,13 +511,13 @@ void cBlockArea::DumpToRawFile(const AString & a_FileName) void cBlockArea::Crop(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY, int a_AddMinZ, int a_SubMaxZ) { if ( - (a_AddMinX + a_SubMaxX >= m_SizeX) || - (a_AddMinY + a_SubMaxY >= m_SizeY) || - (a_AddMinZ + a_SubMaxZ >= m_SizeZ) + (a_AddMinX + a_SubMaxX >= m_Size.x) || + (a_AddMinY + a_SubMaxY >= m_Size.y) || + (a_AddMinZ + a_SubMaxZ >= m_Size.z) ) { LOGWARNING("cBlockArea:Crop called with more croping than the dimensions: %d x %d x %d with cropping %d, %d and %d", - m_SizeX, m_SizeY, m_SizeZ, + m_Size.x, m_Size.y, m_Size.z, a_AddMinX + a_SubMaxX, a_AddMinY + a_SubMaxY, a_AddMinZ + a_SubMaxZ ); return; @@ -560,12 +539,10 @@ void cBlockArea::Crop(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY { CropNibbles(m_BlockSkyLight, a_AddMinX, a_SubMaxX, a_AddMinY, a_SubMaxY, a_AddMinZ, a_SubMaxZ); } - m_OriginX += a_AddMinX; - m_OriginY += a_AddMinY; - m_OriginZ += a_AddMinZ; - m_SizeX -= a_AddMinX + a_SubMaxX; - m_SizeY -= a_AddMinY + a_SubMaxY; - m_SizeZ -= a_AddMinZ + a_SubMaxZ; + m_Origin.Move(a_AddMinX, a_AddMinY, a_AddMinZ); + m_Size.x -= a_AddMinX + a_SubMaxX; + m_Size.y -= a_AddMinY + a_SubMaxY; + m_Size.z -= a_AddMinZ + a_SubMaxZ; } @@ -590,12 +567,10 @@ void cBlockArea::Expand(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMa { ExpandNibbles(m_BlockSkyLight, a_SubMinX, a_AddMaxX, a_SubMinY, a_AddMaxY, a_SubMinZ, a_AddMaxZ); } - m_OriginX -= a_SubMinX; - m_OriginY -= a_SubMinY; - m_OriginZ -= a_SubMinZ; - m_SizeX += a_SubMinX + a_AddMaxX; - m_SizeY += a_SubMinY + a_AddMaxY; - m_SizeZ += a_SubMinZ + a_AddMaxZ; + m_Origin.Move(-a_SubMinX, -a_SubMinY, -a_SubMinZ); + m_Size.x += a_SubMinX + a_AddMaxX; + m_Size.y += a_SubMinY + a_AddMaxY; + m_Size.z += a_SubMinZ + a_AddMaxZ; } @@ -645,7 +620,7 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), - m_SizeX, m_SizeY, m_SizeZ, + m_Size.x, m_Size.y, m_Size.z, MergeCombinatorOverwrite ); break; @@ -660,7 +635,7 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), - m_SizeX, m_SizeY, m_SizeZ, + m_Size.x, m_Size.y, m_Size.z, MergeCombinatorFillAir ); break; @@ -675,7 +650,7 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), - m_SizeX, m_SizeY, m_SizeZ, + m_Size.x, m_Size.y, m_Size.z, MergeCombinatorImprint ); break; @@ -690,7 +665,7 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), - m_SizeX, m_SizeY, m_SizeZ, + m_Size.x, m_Size.y, m_Size.z, MergeCombinatorLake ); break; @@ -982,17 +957,17 @@ void cBlockArea::RotateCCW(void) } // We are guaranteed that both blocktypes and blockmetas exist; rotate both at the same time: - BLOCKTYPE * NewTypes = new BLOCKTYPE[m_SizeX * m_SizeY * m_SizeZ]; - NIBBLETYPE * NewMetas = new NIBBLETYPE[m_SizeX * m_SizeY * m_SizeZ]; - for (int x = 0; x < m_SizeX; x++) + BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; + NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; + for (int x = 0; x < m_Size.x; x++) { - int NewZ = m_SizeX - x - 1; - for (int z = 0; z < m_SizeZ; z++) + int NewZ = m_Size.x - x - 1; + for (int z = 0; z < m_Size.z; z++) { int NewX = z; - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - int NewIdx = NewX + NewZ * m_SizeZ + y * m_SizeX * m_SizeZ; + int NewIdx = NewX + NewZ * m_Size.z + y * m_Size.x * m_Size.z; int OldIdx = MakeIndex(x, y, z); NewTypes[NewIdx] = m_BlockTypes[OldIdx]; NewMetas[NewIdx] = BlockHandler(m_BlockTypes[OldIdx])->MetaRotateCCW(m_BlockMetas[OldIdx]); @@ -1004,7 +979,7 @@ void cBlockArea::RotateCCW(void) delete[] NewTypes; delete[] NewMetas; - std::swap(m_SizeX, m_SizeZ); + std::swap(m_Size.x, m_Size.z); } @@ -1027,17 +1002,17 @@ void cBlockArea::RotateCW(void) } // We are guaranteed that both blocktypes and blockmetas exist; rotate both at the same time: - BLOCKTYPE * NewTypes = new BLOCKTYPE[m_SizeX * m_SizeY * m_SizeZ]; - NIBBLETYPE * NewMetas = new NIBBLETYPE[m_SizeX * m_SizeY * m_SizeZ]; - for (int x = 0; x < m_SizeX; x++) + BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; + NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; + for (int x = 0; x < m_Size.x; x++) { int NewZ = x; - for (int z = 0; z < m_SizeZ; z++) + for (int z = 0; z < m_Size.z; z++) { - int NewX = m_SizeZ - z - 1; - for (int y = 0; y < m_SizeY; y++) + int NewX = m_Size.z - z - 1; + for (int y = 0; y < m_Size.y; y++) { - int NewIdx = NewX + NewZ * m_SizeZ + y * m_SizeX * m_SizeZ; + int NewIdx = NewX + NewZ * m_Size.z + y * m_Size.x * m_Size.z; int OldIdx = MakeIndex(x, y, z); NewTypes[NewIdx] = m_BlockTypes[OldIdx]; NewMetas[NewIdx] = BlockHandler(m_BlockTypes[OldIdx])->MetaRotateCW(m_BlockMetas[OldIdx]); @@ -1049,7 +1024,7 @@ void cBlockArea::RotateCW(void) delete[] NewTypes; delete[] NewMetas; - std::swap(m_SizeX, m_SizeZ); + std::swap(m_Size.x, m_Size.z); } @@ -1072,13 +1047,13 @@ void cBlockArea::MirrorXY(void) } // We are guaranteed that both blocktypes and blockmetas exist; mirror both at the same time: - int HalfZ = m_SizeZ / 2; - int MaxZ = m_SizeZ - 1; - for (int y = 0; y < m_SizeY; y++) + int HalfZ = m_Size.z / 2; + int MaxZ = m_Size.z - 1; + for (int y = 0; y < m_Size.y; y++) { for (int z = 0; z < HalfZ; z++) { - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { int Idx1 = MakeIndex(x, y, z); int Idx2 = MakeIndex(x, y, MaxZ - z); @@ -1112,13 +1087,13 @@ void cBlockArea::MirrorXZ(void) } // We are guaranteed that both blocktypes and blockmetas exist; mirror both at the same time: - int HalfY = m_SizeY / 2; - int MaxY = m_SizeY - 1; + int HalfY = m_Size.y / 2; + int MaxY = m_Size.y - 1; for (int y = 0; y < HalfY; y++) { - for (int z = 0; z < m_SizeZ; z++) + for (int z = 0; z < m_Size.z; z++) { - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { int Idx1 = MakeIndex(x, y, z); int Idx2 = MakeIndex(x, MaxY - y, z); @@ -1152,11 +1127,11 @@ void cBlockArea::MirrorYZ(void) } // We are guaranteed that both blocktypes and blockmetas exist; mirror both at the same time: - int HalfX = m_SizeX / 2; - int MaxX = m_SizeX - 1; - for (int y = 0; y < m_SizeY; y++) + int HalfX = m_Size.x / 2; + int MaxX = m_Size.x - 1; + for (int y = 0; y < m_Size.y; y++) { - for (int z = 0; z < m_SizeZ; z++) + for (int z = 0; z < m_Size.z; z++) { for (int x = 0; x < HalfX; x++) { @@ -1180,16 +1155,16 @@ void cBlockArea::RotateCCWNoMeta(void) { if (HasBlockTypes()) { - BLOCKTYPE * NewTypes = new BLOCKTYPE[m_SizeX * m_SizeY * m_SizeZ]; - for (int x = 0; x < m_SizeX; x++) + BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; + for (int x = 0; x < m_Size.x; x++) { - int NewZ = m_SizeX - x - 1; - for (int z = 0; z < m_SizeZ; z++) + int NewZ = m_Size.x - x - 1; + for (int z = 0; z < m_Size.z; z++) { int NewX = z; - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - NewTypes[NewX + NewZ * m_SizeZ + y * m_SizeX * m_SizeZ] = m_BlockTypes[MakeIndex(x, y, z)]; + NewTypes[NewX + NewZ * m_Size.z + y * m_Size.x * m_Size.z] = m_BlockTypes[MakeIndex(x, y, z)]; } // for y } // for z } // for x @@ -1198,23 +1173,23 @@ void cBlockArea::RotateCCWNoMeta(void) } if (HasBlockMetas()) { - NIBBLETYPE * NewMetas = new NIBBLETYPE[m_SizeX * m_SizeY * m_SizeZ]; - for (int x = 0; x < m_SizeX; x++) + NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; + for (int x = 0; x < m_Size.x; x++) { - int NewZ = m_SizeX - x - 1; - for (int z = 0; z < m_SizeZ; z++) + int NewZ = m_Size.x - x - 1; + for (int z = 0; z < m_Size.z; z++) { int NewX = z; - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - NewMetas[NewX + NewZ * m_SizeZ + y * m_SizeX * m_SizeZ] = m_BlockMetas[MakeIndex(x, y, z)]; + NewMetas[NewX + NewZ * m_Size.z + y * m_Size.x * m_Size.z] = m_BlockMetas[MakeIndex(x, y, z)]; } // for y } // for z } // for x std::swap(m_BlockMetas, NewMetas); delete[] NewMetas; } - std::swap(m_SizeX, m_SizeZ); + std::swap(m_Size.x, m_Size.z); } @@ -1225,16 +1200,16 @@ void cBlockArea::RotateCWNoMeta(void) { if (HasBlockTypes()) { - BLOCKTYPE * NewTypes = new BLOCKTYPE[m_SizeX * m_SizeY * m_SizeZ]; - for (int z = 0; z < m_SizeZ; z++) + BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; + for (int z = 0; z < m_Size.z; z++) { - int NewX = m_SizeZ - z - 1; - for (int x = 0; x < m_SizeX; x++) + int NewX = m_Size.z - z - 1; + for (int x = 0; x < m_Size.x; x++) { int NewZ = x; - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - NewTypes[NewX + NewZ * m_SizeZ + y * m_SizeX * m_SizeZ] = m_BlockTypes[MakeIndex(x, y, z)]; + NewTypes[NewX + NewZ * m_Size.z + y * m_Size.x * m_Size.z] = m_BlockTypes[MakeIndex(x, y, z)]; } // for y } // for x } // for z @@ -1243,23 +1218,23 @@ void cBlockArea::RotateCWNoMeta(void) } if (HasBlockMetas()) { - NIBBLETYPE * NewMetas = new NIBBLETYPE[m_SizeX * m_SizeY * m_SizeZ]; - for (int z = 0; z < m_SizeZ; z++) + NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; + for (int z = 0; z < m_Size.z; z++) { - int NewX = m_SizeZ - z - 1; - for (int x = 0; x < m_SizeX; x++) + int NewX = m_Size.z - z - 1; + for (int x = 0; x < m_Size.x; x++) { int NewZ = x; - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - NewMetas[NewX + NewZ * m_SizeZ + y * m_SizeX * m_SizeZ] = m_BlockMetas[MakeIndex(x, y, z)]; + NewMetas[NewX + NewZ * m_Size.z + y * m_Size.x * m_Size.z] = m_BlockMetas[MakeIndex(x, y, z)]; } // for y } // for x } // for z std::swap(m_BlockMetas, NewMetas); delete[] NewMetas; } - std::swap(m_SizeX, m_SizeZ); + std::swap(m_Size.x, m_Size.z); } @@ -1268,15 +1243,15 @@ void cBlockArea::RotateCWNoMeta(void) void cBlockArea::MirrorXYNoMeta(void) { - int HalfZ = m_SizeZ / 2; - int MaxZ = m_SizeZ - 1; + int HalfZ = m_Size.z / 2; + int MaxZ = m_Size.z - 1; if (HasBlockTypes()) { - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { for (int z = 0; z < HalfZ; z++) { - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { std::swap(m_BlockTypes[MakeIndex(x, y, z)], m_BlockTypes[MakeIndex(x, y, MaxZ - z)]); } // for x @@ -1286,11 +1261,11 @@ void cBlockArea::MirrorXYNoMeta(void) if (HasBlockMetas()) { - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { for (int z = 0; z < HalfZ; z++) { - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { std::swap(m_BlockMetas[MakeIndex(x, y, z)], m_BlockMetas[MakeIndex(x, y, MaxZ - z)]); } // for x @@ -1305,15 +1280,15 @@ void cBlockArea::MirrorXYNoMeta(void) void cBlockArea::MirrorXZNoMeta(void) { - int HalfY = m_SizeY / 2; - int MaxY = m_SizeY - 1; + int HalfY = m_Size.y / 2; + int MaxY = m_Size.y - 1; if (HasBlockTypes()) { for (int y = 0; y < HalfY; y++) { - for (int z = 0; z < m_SizeZ; z++) + for (int z = 0; z < m_Size.z; z++) { - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { std::swap(m_BlockTypes[MakeIndex(x, y, z)], m_BlockTypes[MakeIndex(x, MaxY - y, z)]); } // for x @@ -1325,9 +1300,9 @@ void cBlockArea::MirrorXZNoMeta(void) { for (int y = 0; y < HalfY; y++) { - for (int z = 0; z < m_SizeZ; z++) + for (int z = 0; z < m_Size.z; z++) { - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { std::swap(m_BlockMetas[MakeIndex(x, y, z)], m_BlockMetas[MakeIndex(x, MaxY - y, z)]); } // for x @@ -1342,13 +1317,13 @@ void cBlockArea::MirrorXZNoMeta(void) void cBlockArea::MirrorYZNoMeta(void) { - int HalfX = m_SizeX / 2; - int MaxX = m_SizeX - 1; + int HalfX = m_Size.x / 2; + int MaxX = m_Size.x - 1; if (HasBlockTypes()) { - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - for (int z = 0; z < m_SizeZ; z++) + for (int z = 0; z < m_Size.z; z++) { for (int x = 0; x < HalfX; x++) { @@ -1360,9 +1335,9 @@ void cBlockArea::MirrorYZNoMeta(void) if (HasBlockMetas()) { - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - for (int z = 0; z < m_SizeZ; z++) + for (int z = 0; z < m_Size.z; z++) { for (int x = 0; x < HalfX; x++) { @@ -1393,7 +1368,7 @@ void cBlockArea::SetRelBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a void cBlockArea::SetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType) { - SetRelBlockType(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_BlockType); + SetRelBlockType(a_BlockX - m_Origin.x, a_BlockY - m_Origin.y, a_BlockZ - m_Origin.z, a_BlockType); } @@ -1470,7 +1445,7 @@ BLOCKTYPE cBlockArea::GetRelBlockType(int a_RelX, int a_RelY, int a_RelZ) const BLOCKTYPE cBlockArea::GetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ) const { - return GetRelBlockType(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ); + return GetRelBlockType(a_BlockX - m_Origin.x, a_BlockY - m_Origin.y, a_BlockZ - m_Origin.z); } @@ -1533,7 +1508,7 @@ NIBBLETYPE cBlockArea::GetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ void cBlockArea::SetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { - SetRelBlockTypeMeta(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_BlockType, a_BlockMeta); + SetRelBlockTypeMeta(a_BlockX - m_Origin.x, a_BlockY - m_Origin.y, a_BlockZ - m_Origin.z, a_BlockType, a_BlockMeta); } @@ -1567,7 +1542,7 @@ void cBlockArea::SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, B void cBlockArea::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const { - return GetRelBlockTypeMeta(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_BlockType, a_BlockMeta); + return GetRelBlockTypeMeta(a_BlockX - m_Origin.x, a_BlockY - m_Origin.y, a_BlockZ - m_Origin.z, a_BlockType, a_BlockMeta); } @@ -1670,9 +1645,7 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) return false; } } - m_SizeX = a_SizeX; - m_SizeY = a_SizeY; - m_SizeZ = a_SizeZ; + m_Size.Set(a_SizeX, a_SizeY, a_SizeZ); return true; } @@ -1683,13 +1656,13 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) int cBlockArea::MakeIndex(int a_RelX, int a_RelY, int a_RelZ) const { ASSERT(a_RelX >= 0); - ASSERT(a_RelX < m_SizeX); + ASSERT(a_RelX < m_Size.x); ASSERT(a_RelY >= 0); - ASSERT(a_RelY < m_SizeY); + ASSERT(a_RelY < m_Size.y); ASSERT(a_RelZ >= 0); - ASSERT(a_RelZ < m_SizeZ); + ASSERT(a_RelZ < m_Size.z); - return a_RelX + a_RelZ * m_SizeX + a_RelY * m_SizeX * m_SizeZ; + return a_RelX + a_RelZ * m_Size.x + a_RelY * m_Size.x * m_Size.z; } @@ -1712,7 +1685,7 @@ void cBlockArea::SetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_V void cBlockArea::SetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array) { - SetRelNibble(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_Value, a_Array); + SetRelNibble(a_BlockX - m_Origin.x, a_BlockY - m_Origin.y, a_BlockZ - m_Origin.z, a_Value, a_Array); } @@ -1735,7 +1708,7 @@ NIBBLETYPE cBlockArea::GetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETY NIBBLETYPE cBlockArea::GetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE * a_Array) const { - return GetRelNibble(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_Array); + return GetRelNibble(a_BlockX - m_Origin.x, a_BlockY - m_Origin.y, a_BlockZ - m_Origin.z, a_Array); } @@ -1748,9 +1721,7 @@ NIBBLETYPE cBlockArea::GetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBL cBlockArea::cChunkReader::cChunkReader(cBlockArea & a_Area) : m_Area(a_Area), - m_OriginX(a_Area.m_OriginX), - m_OriginY(a_Area.m_OriginY), - m_OriginZ(a_Area.m_OriginZ) + m_Origin(a_Area.m_Origin.x, a_Area.m_Origin.y, a_Area.m_Origin.z) { } @@ -1760,8 +1731,8 @@ cBlockArea::cChunkReader::cChunkReader(cBlockArea & a_Area) : void cBlockArea::cChunkReader::CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLETYPE * a_ChunkSrc) { - int SizeY = m_Area.m_SizeY; - int MinY = m_OriginY; + int SizeY = m_Area.m_Size.y; + int MinY = m_Origin.y; // SizeX, SizeZ are the dmensions of the block data to copy from the current chunk (size of the geometric union) // OffX, OffZ are the offsets of the current chunk data from the area origin @@ -1770,7 +1741,7 @@ void cBlockArea::cChunkReader::CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLET int SizeZ = cChunkDef::Width; int OffX, OffZ; int BaseX, BaseZ; - OffX = m_CurrentChunkX * cChunkDef::Width - m_OriginX; + OffX = m_CurrentChunkX * cChunkDef::Width - m_Origin.x; if (OffX < 0) { BaseX = -OffX; @@ -1781,7 +1752,7 @@ void cBlockArea::cChunkReader::CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLET { BaseX = 0; } - OffZ = m_CurrentChunkZ * cChunkDef::Width - m_OriginZ; + OffZ = m_CurrentChunkZ * cChunkDef::Width - m_Origin.z; if (OffZ < 0) { BaseZ = -OffZ; @@ -1793,13 +1764,13 @@ void cBlockArea::cChunkReader::CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLET BaseZ = 0; } // If the chunk extends beyond the area in the X or Z axis, cut off the Size: - if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_OriginX + m_Area.m_SizeX) + if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_Origin.x + m_Area.m_Size.x) { - SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_OriginX + m_Area.m_SizeX); + SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_Origin.x + m_Area.m_Size.x); } - if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_OriginZ + m_Area.m_SizeZ) + if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_Origin.z + m_Area.m_Size.z) { - SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_OriginZ + m_Area.m_SizeZ); + SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_Origin.z + m_Area.m_Size.z); } for (int y = 0; y < SizeY; y++) @@ -1843,8 +1814,8 @@ void cBlockArea::cChunkReader::BlockTypes(const BLOCKTYPE * a_BlockTypes) return; } - int SizeY = m_Area.m_SizeY; - int MinY = m_OriginY; + int SizeY = m_Area.m_Size.y; + int MinY = m_Origin.y; // SizeX, SizeZ are the dmensions of the block data to copy from the current chunk (size of the geometric union) // OffX, OffZ are the offsets of the current chunk data from the area origin @@ -1853,7 +1824,7 @@ void cBlockArea::cChunkReader::BlockTypes(const BLOCKTYPE * a_BlockTypes) int SizeZ = cChunkDef::Width; int OffX, OffZ; int BaseX, BaseZ; - OffX = m_CurrentChunkX * cChunkDef::Width - m_OriginX; + OffX = m_CurrentChunkX * cChunkDef::Width - m_Origin.x; if (OffX < 0) { BaseX = -OffX; @@ -1864,7 +1835,7 @@ void cBlockArea::cChunkReader::BlockTypes(const BLOCKTYPE * a_BlockTypes) { BaseX = 0; } - OffZ = m_CurrentChunkZ * cChunkDef::Width - m_OriginZ; + OffZ = m_CurrentChunkZ * cChunkDef::Width - m_Origin.z; if (OffZ < 0) { BaseZ = -OffZ; @@ -1876,13 +1847,13 @@ void cBlockArea::cChunkReader::BlockTypes(const BLOCKTYPE * a_BlockTypes) BaseZ = 0; } // If the chunk extends beyond the area in the X or Z axis, cut off the Size: - if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_OriginX + m_Area.m_SizeX) + if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_Origin.x + m_Area.m_Size.x) { - SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_OriginX + m_Area.m_SizeX); + SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_Origin.x + m_Area.m_Size.x); } - if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_OriginZ + m_Area.m_SizeZ) + if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_Origin.z + m_Area.m_Size.z) { - SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_OriginZ + m_Area.m_SizeZ); + SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_Origin.z + m_Area.m_Size.z); } for (int y = 0; y < SizeY; y++) @@ -2002,21 +1973,21 @@ void cBlockArea::CropNibbles(NIBBLEARRAY & a_Array, int a_AddMinX, int a_SubMaxX void cBlockArea::ExpandBlockTypes(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ) { - int NewSizeX = m_SizeX + a_SubMinX + a_AddMaxX; - int NewSizeY = m_SizeY + a_SubMinY + a_AddMaxY; - int NewSizeZ = m_SizeZ + a_SubMinZ + a_AddMaxZ; + int NewSizeX = m_Size.x + a_SubMinX + a_AddMaxX; + int NewSizeY = m_Size.y + a_SubMinY + a_AddMaxY; + int NewSizeZ = m_Size.z + a_SubMinZ + a_AddMaxZ; int BlockCount = NewSizeX * NewSizeY * NewSizeZ; BLOCKTYPE * NewBlockTypes = new BLOCKTYPE[BlockCount]; memset(NewBlockTypes, 0, BlockCount * sizeof(BLOCKTYPE)); int OldIndex = 0; - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - int IndexBaseY = (y + a_SubMinY) * m_SizeX * m_SizeZ; - for (int z = 0; z < m_SizeZ; z++) + int IndexBaseY = (y + a_SubMinY) * m_Size.x * m_Size.z; + for (int z = 0; z < m_Size.z; z++) { - int IndexBaseZ = IndexBaseY + (z + a_SubMinZ) * m_SizeX; + int IndexBaseZ = IndexBaseY + (z + a_SubMinZ) * m_Size.x; int idx = IndexBaseZ + a_SubMinX; - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { NewBlockTypes[idx++] = m_BlockTypes[OldIndex++]; } // for x @@ -2032,21 +2003,21 @@ void cBlockArea::ExpandBlockTypes(int a_SubMinX, int a_AddMaxX, int a_SubMinY, i void cBlockArea::ExpandNibbles(NIBBLEARRAY & a_Array, int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ) { - int NewSizeX = m_SizeX + a_SubMinX + a_AddMaxX; - int NewSizeY = m_SizeY + a_SubMinY + a_AddMaxY; - int NewSizeZ = m_SizeZ + a_SubMinZ + a_AddMaxZ; + int NewSizeX = m_Size.x + a_SubMinX + a_AddMaxX; + int NewSizeY = m_Size.y + a_SubMinY + a_AddMaxY; + int NewSizeZ = m_Size.z + a_SubMinZ + a_AddMaxZ; int BlockCount = NewSizeX * NewSizeY * NewSizeZ; NIBBLETYPE * NewNibbles = new NIBBLETYPE[BlockCount]; memset(NewNibbles, 0, BlockCount * sizeof(NIBBLETYPE)); int OldIndex = 0; - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - int IndexBaseY = (y + a_SubMinY) * m_SizeX * m_SizeZ; - for (int z = 0; z < m_SizeZ; z++) + int IndexBaseY = (y + a_SubMinY) * m_Size.x * m_Size.z; + for (int z = 0; z < m_Size.z; z++) { - int IndexBaseZ = IndexBaseY + (z + a_SubMinZ) * m_SizeX; + int IndexBaseZ = IndexBaseY + (z + a_SubMinZ) * m_Size.x; int idx = IndexBaseZ + a_SubMinX; - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { NewNibbles[idx++] = a_Array[OldIndex++]; } // for x @@ -2057,6 +2028,9 @@ void cBlockArea::ExpandNibbles(NIBBLEARRAY & a_Array, int a_SubMinX, int a_AddMa } + + + void cBlockArea::RelSetData( int a_RelX, int a_RelY, int a_RelZ, int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, diff --git a/src/BlockArea.h b/src/BlockArea.h index e0e8fe972..22d55e2c9 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -43,6 +43,8 @@ public: baSkyLight = 8, } ; + /** The per-block strategy to use when merging another block area into this object. + See the Merge function for the description of these */ enum eMergeStrategy { msOverwrite, @@ -232,18 +234,24 @@ public: void GetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const; void GetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const; + // GetSize() is already exported manually to return 3 numbers, can't auto-export + const Vector3i & GetSize(void) const { return m_Size; } + + // GetOrigin() is already exported manually to return 3 numbers, can't auto-export + const Vector3i & GetOrigin(void) const { return m_Origin; } + // tolua_begin - int GetSizeX(void) const { return m_SizeX; } - int GetSizeY(void) const { return m_SizeY; } - int GetSizeZ(void) const { return m_SizeZ; } + int GetSizeX(void) const { return m_Size.x; } + int GetSizeY(void) const { return m_Size.y; } + int GetSizeZ(void) const { return m_Size.z; } /** Returns the volume of the area, as number of blocks */ - int GetVolume(void) const { return m_SizeX * m_SizeY * m_SizeZ; } + int GetVolume(void) const { return m_Size.x * m_Size.y * m_Size.z; } - int GetOriginX(void) const { return m_OriginX; } - int GetOriginY(void) const { return m_OriginY; } - int GetOriginZ(void) const { return m_OriginZ; } + int GetOriginX(void) const { return m_Origin.x; } + int GetOriginY(void) const { return m_Origin.y; } + int GetOriginZ(void) const { return m_Origin.z; } /** Returns the datatypes that are stored in the object (bitmask of baXXX values) */ int GetDataTypes(void) const; @@ -261,7 +269,7 @@ public: NIBBLETYPE * GetBlockMetas (void) const { return m_BlockMetas; } // NOTE: one byte per block! NIBBLETYPE * GetBlockLight (void) const { return m_BlockLight; } // NOTE: one byte per block! NIBBLETYPE * GetBlockSkyLight(void) const { return m_BlockSkyLight; } // NOTE: one byte per block! - int GetBlockCount(void) const { return m_SizeX * m_SizeY * m_SizeZ; } + int GetBlockCount(void) const { return m_Size.x * m_Size.y * m_Size.z; } int MakeIndex(int a_RelX, int a_RelY, int a_RelZ) const; protected: @@ -276,9 +284,7 @@ protected: protected: cBlockArea & m_Area; - int m_OriginX; - int m_OriginY; - int m_OriginZ; + Vector3i m_Origin; int m_CurrentChunkX; int m_CurrentChunkZ; @@ -295,12 +301,8 @@ protected: typedef NIBBLETYPE * NIBBLEARRAY; - int m_OriginX; - int m_OriginY; - int m_OriginZ; - int m_SizeX; - int m_SizeY; - int m_SizeZ; + Vector3i m_Origin; + Vector3i m_Size; /** An extra data value sometimes stored in the .schematic file. Used mainly by the WorldEdit plugin. cBlockArea doesn't use this value in any way. */ diff --git a/src/Generating/ChunkDesc.cpp b/src/Generating/ChunkDesc.cpp index 308fbe423..7711723fc 100644 --- a/src/Generating/ChunkDesc.cpp +++ b/src/Generating/ChunkDesc.cpp @@ -343,9 +343,9 @@ void cChunkDesc::ReadBlockArea(cBlockArea & a_Dest, int a_MinRelX, int a_MaxRelX int SizeY = a_MaxRelY - a_MinRelY; int SizeZ = a_MaxRelZ - a_MinRelZ; a_Dest.Clear(); - a_Dest.m_OriginX = m_ChunkX * cChunkDef::Width + a_MinRelX; - a_Dest.m_OriginY = a_MinRelY; - a_Dest.m_OriginZ = m_ChunkZ * cChunkDef::Width + a_MinRelZ; + a_Dest.m_Origin.x = m_ChunkX * cChunkDef::Width + a_MinRelX; + a_Dest.m_Origin.y = a_MinRelY; + a_Dest.m_Origin.z = m_ChunkZ * cChunkDef::Width + a_MinRelZ; a_Dest.SetSize(SizeX, SizeY, SizeZ, cBlockArea::baTypes | cBlockArea::baMetas); for (int y = 0; y < SizeY; y++) diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp index ef67fdb13..d8531d965 100644 --- a/src/WorldStorage/SchematicFileSerializer.cpp +++ b/src/WorldStorage/SchematicFileSerializer.cpp @@ -197,7 +197,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP } // Copy the block types and metas: - int NumBytes = a_BlockArea.m_SizeX * a_BlockArea.m_SizeY * a_BlockArea.m_SizeZ; + int NumBytes = a_BlockArea.GetBlockCount(); if (a_NBT.GetDataLength(TBlockTypes) < NumBytes) { LOG("BlockTypes truncated in the schematic file (exp %d, got %d bytes). Loading partial.", @@ -209,7 +209,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP if (AreMetasPresent) { - int NumBytes = a_BlockArea.m_SizeX * a_BlockArea.m_SizeY * a_BlockArea.m_SizeZ; + int NumBytes = a_BlockArea.GetBlockCount(); if (a_NBT.GetDataLength(TBlockMetas) < NumBytes) { LOG("BlockMetas truncated in the schematic file (exp %d, got %d bytes). Loading partial.", @@ -230,9 +230,9 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockArea) { cFastNBTWriter Writer("Schematic"); - Writer.AddShort("Width", a_BlockArea.m_SizeX); - Writer.AddShort("Height", a_BlockArea.m_SizeY); - Writer.AddShort("Length", a_BlockArea.m_SizeZ); + Writer.AddShort("Width", a_BlockArea.m_Size.x); + Writer.AddShort("Height", a_BlockArea.m_Size.y); + Writer.AddShort("Length", a_BlockArea.m_Size.z); Writer.AddString("Materials", "Alpha"); if (a_BlockArea.HasBlockTypes()) { From 87de5960785e0e007eaee0a8dbb77c64e20e7c8c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 25 Mar 2014 22:05:45 +0100 Subject: [PATCH 022/145] BlockArea: Create() can take the size as Vector3i, too. --- src/BlockArea.cpp | 9 +++++++++ src/BlockArea.h | 10 ++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 692b006d5..f6d54e41c 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -240,6 +240,15 @@ void cBlockArea::Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) +void cBlockArea::Create(const Vector3i & a_Size, int a_DataTypes) +{ + Create(a_Size.x, a_Size.y, a_Size.z, a_DataTypes); +} + + + + + void cBlockArea::SetWEOffset(int a_OffsetX, int a_OffsetY, int a_OffsetZ) { m_WEOffset.Set(a_OffsetX, a_OffsetY, a_OffsetZ); diff --git a/src/BlockArea.h b/src/BlockArea.h index 22d55e2c9..d28325d7d 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -59,12 +59,18 @@ public: /** Clears the data stored to reclaim memory */ void Clear(void); - /** Creates a new area of the specified size and contents. - Origin is set to all zeroes. + /** Creates a new area of the specified size and contents. + Origin is set to all zeroes. BlockTypes are set to air, block metas to zero, blocklights to zero and skylights to full light. */ void Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes = baTypes | baMetas); + /** Creates a new area of the specified size and contents. + Origin is set to all zeroes. + BlockTypes are set to air, block metas to zero, blocklights to zero and skylights to full light. + */ + void Create(const Vector3i & a_Size, int a_DataTypes = baTypes | baMetas); + /** Resets the origin. No other changes are made, contents are untouched. */ void SetOrigin(int a_OriginX, int a_OriginY, int a_OriginZ); From 37778e5f82f02eb417642390a36587a970e5479c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 25 Mar 2014 22:10:53 +0100 Subject: [PATCH 023/145] Added a basic cPrefab class. Can be defined in the source by GalExport's cpp output. --- src/Generating/Prefab.cpp | 139 ++++++++++++++++++++++++++++++++++++++ src/Generating/Prefab.h | 83 +++++++++++++++++++++++ 2 files changed, 222 insertions(+) create mode 100644 src/Generating/Prefab.cpp create mode 100644 src/Generating/Prefab.h diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp new file mode 100644 index 000000000..824800119 --- /dev/null +++ b/src/Generating/Prefab.cpp @@ -0,0 +1,139 @@ + +// Prefab.cpp + +/* +Implements the cPrefab class, representing a cPiece descendant for the cPieceGenerator that +uses a prefabricate in a cBlockArea for drawing itself. +*/ + +#include "Globals.h" +#include "Prefab.h" +#include "../WorldStorage/SchematicFileSerializer.h" + + + + + +cPrefab::cPrefab(const cPrefab::sDef & a_Def) : + m_Size(a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), + m_HitBox(0, 0, 0, a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), + m_AllowedRotations(7), // TODO: All rotations allowed (not in the definition yet) + m_MergeStrategy(cBlockArea::msImprint) +{ + m_BlockArea.Create(m_Size); + CharMap cm; + ParseCharMap(cm, a_Def.m_CharMap); + ParseBlockImage(cm, a_Def.m_Image); +} + + + + + +void cPrefab::Draw(cBlockArea & a_Dest, const cPlacedPiece * a_Placement) +{ + Vector3i Placement = a_Placement->GetCoords(); + Placement.Move(a_Dest.GetOrigin() * (-1)); + a_Dest.Merge(m_BlockArea, Placement, m_MergeStrategy); + +} + + + + + +void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) +{ + // Initialize the charmap to all-invalid values: + for (size_t i = 0; i < ARRAYCOUNT(a_CharMapOut); i++) + { + a_CharMapOut[i] = -1; + } + + // Process the lines in the definition: + AStringVector Lines = StringSplitAndTrim(a_CharMapDef, "\n"); + for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) + { + AStringVector CharDef = StringSplitAndTrim(*itr, ":"); + size_t NumElements = CharDef.size(); + if ((NumElements < 2) || CharDef[0].empty() || CharDef[1].empty()) + { + LOGWARNING("Bad prefab CharMap definition line: \"%s\", skipping.", itr->c_str()); + continue; + } + unsigned char Src = (unsigned char)CharDef[0][0]; + BLOCKTYPE BlockType = (BLOCKTYPE)atoi(CharDef[1].c_str()); + NIBBLETYPE BlockMeta = 0; + if ((NumElements >= 3) && !CharDef[2].empty()) + { + BlockMeta = (NIBBLETYPE)atoi(CharDef[2].c_str()); + ASSERT((BlockMeta >= 0) && (BlockMeta <= 15)); + } + ASSERT(a_CharMapOut[Src] == -1); // Any duplicates letter-wise? + a_CharMapOut[Src] = (BlockType << 4) | BlockMeta; + } // for itr - Lines[] +} + + + + + +void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockImage) +{ + // Map each letter in the a_BlockImage (from the in-source definition) to real blocktype / blockmeta: + for (int y = 0; y < m_Size.y; y++) + { + for (int z = 0; z < m_Size.z; z++) + { + const unsigned char * BlockImage = (const unsigned char *)a_BlockImage + y * m_Size.x * m_Size.z + z * m_Size.x; + for (int x = 0; x < m_Size.x; x++) + { + int MappedValue = a_CharMap[BlockImage[x]]; + ASSERT(MappedValue != -1); // Using a letter not defined in the CharMap? + BLOCKTYPE BlockType = MappedValue >> 4; + NIBBLETYPE BlockMeta = MappedValue & 0x0f; + m_BlockArea.SetRelBlockTypeMeta(x, y, z, BlockType, BlockMeta); + } + } + } +} + + + + + +cPiece::cConnectors cPrefab::GetConnectors(void) const +{ + return m_Connectors; +} + + + + + +Vector3i cPrefab::GetSize(void) const +{ + return m_Size; +} + + + + + +cCuboid cPrefab::GetHitBox(void) const +{ + return m_HitBox; +} + + + + + +bool cPrefab::CanRotateCCW(int a_NumRotations) const +{ + return ((m_AllowedRotations & (1 << (a_NumRotations % 4))) != 0); +} + + + + diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h new file mode 100644 index 000000000..6596b906b --- /dev/null +++ b/src/Generating/Prefab.h @@ -0,0 +1,83 @@ + +// Prefab.h + +/* +Declares the cPrefab class, representing a cPiece descendant for the cPieceGenerator that +uses a prefabricate in a cBlockArea for drawing itself. +The class can be constructed from data that is stored directly in the executable, in a sPrefabDef structure +declared in this file as well; the Gallery server exports areas in this format. +*/ + + + + + +#pragma once + +#include "PieceGenerator.h" +#include "../BlockArea.h" + + + + + + +class cPrefab : + public cPiece +{ +public: + struct sDef + { + int m_SizeX; + int m_SizeY; + int m_SizeZ; + const char * m_CharMap; + const char * m_Image; + // TODO: Connectors + }; + + cPrefab(const sDef & a_Def); + + /** Draws the prefab into the specified block area, according to the placement stored in the PlacedPiece. */ + void Draw(cBlockArea & a_Dest, const cPlacedPiece * a_Placement); + +protected: + /** Maps letters in the sDef::m_Image onto a number, BlockType * 16 | BlockMeta */ + typedef int CharMap[256]; + + + /** The cBlockArea that contains the block definitions for the prefab */ + cBlockArea m_BlockArea; + + /** The size of the prefab */ + Vector3i m_Size; + + /** The hitbox of the prefab. In first version is the same as the m_BlockArea dimensions */ + cCuboid m_HitBox; + + /** The connectors through which the piece connects to other pieces */ + cConnectors m_Connectors; + + /** Bitmask, bit N set -> N rotations CCW supported */ + int m_AllowedRotations; + + /** The merge strategy to use when drawing the prefab into a block area */ + cBlockArea::eMergeStrategy m_MergeStrategy; + + + // cPiece overrides: + virtual cConnectors GetConnectors(void) const override; + virtual Vector3i GetSize(void) const override; + virtual cCuboid GetHitBox(void) const override; + virtual bool CanRotateCCW(int a_NumRotations) const override; + + /** Parses the CharMap in the definition into a CharMap binary data used for translating the definition into BlockArea. */ + void ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef); + + /** Parses the Image in the definition into m_BlockArea's block types and metas, using the specified CharMap. */ + void ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockImage); +}; + + + + From e1285eb84f357c3111f5c7382c94bccc7068c660 Mon Sep 17 00:00:00 2001 From: narroo Date: Tue, 25 Mar 2014 17:17:05 -0400 Subject: [PATCH 024/145] Changed Rotater to Rotator. Added partial sign post rotation support. --- src/Blocks/BlockSign.h | 12 ++++++++++++ src/Blocks/{MetaRotater.h => MetaRotator.h} | 0 2 files changed, 12 insertions(+) rename src/Blocks/{MetaRotater.h => MetaRotator.h} (100%) diff --git a/src/Blocks/BlockSign.h b/src/Blocks/BlockSign.h index cd0c02a40..82d9a2fcc 100644 --- a/src/Blocks/BlockSign.h +++ b/src/Blocks/BlockSign.h @@ -71,6 +71,18 @@ public: { a_Player->GetClientHandle()->SendEditSign(a_BlockX, a_BlockY, a_BlockZ); } + + + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override + { + return ++a_Meta; + } + + + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override + { + return --a_Meta; + } } ; diff --git a/src/Blocks/MetaRotater.h b/src/Blocks/MetaRotator.h similarity index 100% rename from src/Blocks/MetaRotater.h rename to src/Blocks/MetaRotator.h From 3df4f8609dc2e28c2328ddf448fa53f5483f4262 Mon Sep 17 00:00:00 2001 From: narroo Date: Tue, 25 Mar 2014 17:26:13 -0400 Subject: [PATCH 025/145] Fixed spelling; Rotater to Rotator. --- src/Blocks/BlockBed.h | 6 +++--- src/Blocks/BlockButton.h | 6 +++--- src/Blocks/BlockChest.h | 6 +++--- src/Blocks/BlockComparator.h | 6 +++--- src/Blocks/BlockDoor.h | 6 +++--- src/Blocks/BlockDropSpenser.h | 6 +++--- src/Blocks/BlockEnderchest.h | 6 +++--- src/Blocks/BlockFenceGate.h | 6 +++--- src/Blocks/BlockFurnace.h | 6 +++--- src/Blocks/BlockHopper.h | 4 ++-- src/Blocks/BlockLadder.h | 4 ++-- src/Blocks/BlockStairs.h | 6 +++--- src/Blocks/BlockTorch.h | 6 +++--- src/Blocks/BlockVine.h | 2 +- src/Blocks/MetaRotator.h | 16 ++++++++-------- 15 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h index 6daa94730..92804aaac 100644 --- a/src/Blocks/BlockBed.h +++ b/src/Blocks/BlockBed.h @@ -4,7 +4,7 @@ #include "BlockHandler.h" #include "ChunkInterface.h" #include "WorldInterface.h" -#include "MetaRotater.h" +#include "MetaRotator.h" #include "../Entities/Player.h" @@ -12,11 +12,11 @@ class cBlockBedHandler : - public cMetaRotater + public cMetaRotator { public: cBlockBedHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index 740cbe3c4..4b2f6f618 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -2,17 +2,17 @@ #include "BlockHandler.h" #include "Chunk.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockButtonHandler : - public cMetaRotater + public cMetaRotator { public: cBlockButtonHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h index 890b5b933..a1ded4c26 100644 --- a/src/Blocks/BlockChest.h +++ b/src/Blocks/BlockChest.h @@ -4,18 +4,18 @@ #include "BlockEntity.h" #include "../BlockArea.h" #include "../Entities/Player.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockChestHandler : - public cMetaRotater + public cMetaRotator { public: cBlockChestHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h index e570ff302..4dd05366d 100644 --- a/src/Blocks/BlockComparator.h +++ b/src/Blocks/BlockComparator.h @@ -3,18 +3,18 @@ #include "BlockHandler.h" #include "BlockRedstoneRepeater.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockComparatorHandler : - public cMetaRotater + public cMetaRotator { public: cBlockComparatorHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index 066e1ab28..797fe484c 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -4,15 +4,15 @@ #include "BlockHandler.h" #include "../Entities/Player.h" #include "Chunk.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockDoorHandler : - public cMetaRotater + public cMetaRotator { - typedef cMetaRotater super; + typedef cMetaRotator super; public: cBlockDoorHandler(BLOCKTYPE a_BlockType); diff --git a/src/Blocks/BlockDropSpenser.h b/src/Blocks/BlockDropSpenser.h index 7e0ad0e55..88b61a418 100644 --- a/src/Blocks/BlockDropSpenser.h +++ b/src/Blocks/BlockDropSpenser.h @@ -6,18 +6,18 @@ #pragma once #include "../Piston.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockDropSpenserHandler : - public cMetaRotater + public cMetaRotator { public: cBlockDropSpenserHandler(BLOCKTYPE a_BlockType) : - cMetaRotater(a_BlockType) + cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockEnderchest.h b/src/Blocks/BlockEnderchest.h index 97cf484fb..67955f8ce 100644 --- a/src/Blocks/BlockEnderchest.h +++ b/src/Blocks/BlockEnderchest.h @@ -2,17 +2,17 @@ #pragma once #include "BlockEntity.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockEnderchestHandler : - public cMetaRotater + public cMetaRotator { public: cBlockEnderchestHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index e3162bbd6..e202c6610 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -2,17 +2,17 @@ #pragma once #include "BlockHandler.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockFenceGateHandler : - public cMetaRotater + public cMetaRotator { public: cBlockFenceGateHandler(BLOCKTYPE a_BlockType) : - cMetaRotater(a_BlockType) + cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockFurnace.h b/src/Blocks/BlockFurnace.h index c7f8ff8d2..a7a807957 100644 --- a/src/Blocks/BlockFurnace.h +++ b/src/Blocks/BlockFurnace.h @@ -4,17 +4,17 @@ #include "BlockEntity.h" #include "../World.h" #include "../Piston.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockFurnaceHandler : - public cMetaRotater + public cMetaRotator { public: cBlockFurnaceHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockHopper.h b/src/Blocks/BlockHopper.h index 610296529..a882bb077 100644 --- a/src/Blocks/BlockHopper.h +++ b/src/Blocks/BlockHopper.h @@ -8,11 +8,11 @@ class cBlockHopperHandler : - public cMetaRotater + public cMetaRotator { public: cBlockHopperHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockLadder.h b/src/Blocks/BlockLadder.h index 12408759e..a605edf3f 100644 --- a/src/Blocks/BlockLadder.h +++ b/src/Blocks/BlockLadder.h @@ -9,11 +9,11 @@ class cBlockLadderHandler : - public cMetaRotater + public cMetaRotator { public: cBlockLadderHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h index ea8405597..1072b7e71 100644 --- a/src/Blocks/BlockStairs.h +++ b/src/Blocks/BlockStairs.h @@ -2,17 +2,17 @@ #pragma once #include "BlockHandler.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockStairsHandler : - public cMetaRotater + public cMetaRotator { public: cBlockStairsHandler(BLOCKTYPE a_BlockType) : - cMetaRotater(a_BlockType) + cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index d32c77629..8ddec8de1 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -2,17 +2,17 @@ #include "BlockHandler.h" #include "../Chunk.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockTorchHandler : - public cMetaRotater + public cMetaRotator { public: cBlockTorchHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 708583e70..0b57acc7b 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -1,7 +1,7 @@ #pragma once #include "BlockHandler.h" -#include "MetaRotater.h" +#include "MetaRotator.h" diff --git a/src/Blocks/MetaRotator.h b/src/Blocks/MetaRotator.h index dde88e6db..899c583e1 100644 --- a/src/Blocks/MetaRotator.h +++ b/src/Blocks/MetaRotator.h @@ -1,4 +1,4 @@ -// MetaRotater.h +// MetaRotator.h // Provides a mixin for rotations and reflections @@ -21,15 +21,15 @@ Inherit from this class providing your base class as Base, the BitMask for the d */ template -class cMetaRotater : public Base +class cMetaRotator : public Base { public: - cMetaRotater(BLOCKTYPE a_BlockType) : + cMetaRotator(BLOCKTYPE a_BlockType) : Base(a_BlockType) {} - virtual ~cMetaRotater() {} + virtual ~cMetaRotator() {} virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override; virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override; @@ -42,7 +42,7 @@ public: template -NIBBLETYPE cMetaRotater::MetaRotateCW(NIBBLETYPE a_Meta) +NIBBLETYPE cMetaRotator::MetaRotateCW(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); switch (a_Meta & BitMask) @@ -64,7 +64,7 @@ NIBBLETYPE cMetaRotater -NIBBLETYPE cMetaRotater::MetaRotateCCW(NIBBLETYPE a_Meta) +NIBBLETYPE cMetaRotator::MetaRotateCCW(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); switch (a_Meta & BitMask) @@ -86,7 +86,7 @@ NIBBLETYPE cMetaRotater -NIBBLETYPE cMetaRotater::MetaMirrorXY(NIBBLETYPE a_Meta) +NIBBLETYPE cMetaRotator::MetaMirrorXY(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); switch (a_Meta & BitMask) @@ -103,7 +103,7 @@ NIBBLETYPE cMetaRotater -NIBBLETYPE cMetaRotater::MetaMirrorYZ(NIBBLETYPE a_Meta) +NIBBLETYPE cMetaRotator::MetaMirrorYZ(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); switch (a_Meta & BitMask) From d5c7fc6bd65bfabf8d95b6f2c4cbdf5dd2b447b7 Mon Sep 17 00:00:00 2001 From: narroo Date: Tue, 25 Mar 2014 17:35:48 -0400 Subject: [PATCH 026/145] Added a comment about the behavior of doors under mirros. Simply put, the current implementation of MetaMirror causes glitchy behavior. The door class itself needs to be edited. (I've got an idea on that....) --- src/Blocks/BlockDoor.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index c027daed2..100f48e6c 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -143,7 +143,10 @@ NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta) { // Top bit (0x08) contains door panel type (Top/Bottom panel) Only Bottom panels contain position data // Return a_Meta if panel is a top panel (0x08 bit is set to 1) - LOG("Test MirrorXY"); + + // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored + // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time, + // so the function can only see either the hinge position or orientation, but not both, at any given time. if (a_Meta & 0x08) return a_Meta; // Holds open/closed meta data. 0x0C == 1100. @@ -166,7 +169,10 @@ NIBBLETYPE cBlockDoorHandler::MetaMirrorYZ(NIBBLETYPE a_Meta) { // Top bit (0x08) contains door panel type (Top/Bottom panel) Only Bottom panels contain position data // Return a_Meta if panel is a top panel (0x08 bit is set to 1) - LOG("Test MirrorYZ"); + + // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored + // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time, + // so the function can only see either the hinge position or orientation, but not both, at any given time. if (a_Meta & 0x08) return a_Meta; // Holds open/closed meta data. 0x0C == 1100. From 9032ff96c7c6db4264eedda95de7ea55f155bc47 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 25 Mar 2014 23:35:50 +0100 Subject: [PATCH 027/145] Removed unused constants. DeadlockDetect reads the value from the ini file, and world lighting has a separate queue now. --- src/DeadlockDetect.cpp | 5 +---- src/World.cpp | 3 --- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/DeadlockDetect.cpp b/src/DeadlockDetect.cpp index 4dc7bfde6..322084dc4 100644 --- a/src/DeadlockDetect.cpp +++ b/src/DeadlockDetect.cpp @@ -7,7 +7,7 @@ #include "DeadlockDetect.h" #include "Root.h" #include "World.h" -# include +#include @@ -16,9 +16,6 @@ /// Number of milliseconds per cycle const int CYCLE_MILLISECONDS = 100; -/// When the number of cycles for the same world age hits this value, it is considered a deadlock -const int NUM_CYCLES_LIMIT = 200; // 200 = twenty seconds - diff --git a/src/World.cpp b/src/World.cpp index 3f157157a..e39a605bb 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -60,9 +60,6 @@ -/// Up to this many m_SpreadQueue elements are handled each world tick -const int MAX_LIGHTING_SPREAD_PER_TICK = 10; - const int TIME_SUNSET = 12000; const int TIME_NIGHT_START = 13187; const int TIME_NIGHT_END = 22812; From 1b00b62a4b8f27e14e31e251020321e41a284b21 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 25 Mar 2014 23:49:58 +0100 Subject: [PATCH 028/145] Ignoring the default GalExports folder. --- MCServer/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/MCServer/.gitignore b/MCServer/.gitignore index 64f062ef7..69826ef06 100644 --- a/MCServer/.gitignore +++ b/MCServer/.gitignore @@ -6,6 +6,7 @@ MCServer MCServer_debug CommLogs/ +GalExports/ logs players world* From 90415ff79886f63cacced59f202228ddac69765a Mon Sep 17 00:00:00 2001 From: narroo Date: Wed, 26 Mar 2014 08:54:17 -0400 Subject: [PATCH 029/145] Fixed Minor typos. --- src/Blocks/BlockDoor.cpp | 7 +++++-- src/Blocks/BlockRail.h | 12 ++++++------ src/Blocks/BlockSlab.h | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index 100f48e6c..479c68153 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -146,7 +146,8 @@ NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta) // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time, - // so the function can only see either the hinge position or orientation, but not both, at any given time. + // so the function can only see either the hinge position or orientation, but not both, at any given time. The class itself + // needs extra datamembers. if (a_Meta & 0x08) return a_Meta; // Holds open/closed meta data. 0x0C == 1100. @@ -172,7 +173,9 @@ NIBBLETYPE cBlockDoorHandler::MetaMirrorYZ(NIBBLETYPE a_Meta) // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time, - // so the function can only see either the hinge position or orientation, but not both, at any given time. + // so the function can only see either the hinge position or orientation, but not both, at any given time.The class itself + // needs extra datamembers. + if (a_Meta & 0x08) return a_Meta; // Holds open/closed meta data. 0x0C == 1100. diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h index f56ec7152..477707a91 100644 --- a/src/Blocks/BlockRail.h +++ b/src/Blocks/BlockRail.h @@ -453,8 +453,8 @@ public: case 0x02: return 0x04 + OtherMeta; // Asc. East -> Asc. North case 0x04: return 0x03 + OtherMeta; // Asc. North -> Asc. West - case 0x03: return 0x05 + OtherMeta; // Asc. West -> Asc. South - case 0x05: return 0x02 + OtherMeta; // Asc. South -> Asc. East + case 0x03: return 0x05 + OtherMeta; // Asc. West -> Asc. South + case 0x05: return 0x02 + OtherMeta; // Asc. South -> Asc. East } } else @@ -489,8 +489,8 @@ public: case 0x02: return 0x05 + OtherMeta; // Asc. East -> Asc. South case 0x05: return 0x03 + OtherMeta; // Asc. South -> Asc. West - case 0x03: return 0x04 + OtherMeta; // Asc. West -> Asc. North - case 0x04: return 0x02 + OtherMeta; // Asc. North -> Asc. East + case 0x03: return 0x04 + OtherMeta; // Asc. West -> Asc. North + case 0x04: return 0x02 + OtherMeta; // Asc. North -> Asc. East } } else @@ -521,7 +521,7 @@ public: switch (a_Meta & 0x07) { case 0x05: return 0x04 + OtherMeta; // Asc. South -> Asc. North - case 0x04: return 0x05 + OtherMeta; // Asc. North -> Asc. South + case 0x04: return 0x05 + OtherMeta; // Asc. North -> Asc. South } } else @@ -552,7 +552,7 @@ public: switch (a_Meta & 0x07) { case 0x02: return 0x03 + OtherMeta; // Asc. East -> Asc. West - case 0x03: return 0x02 + OtherMeta; // Asc. West -> Asc. East + case 0x03: return 0x02 + OtherMeta; // Asc. West -> Asc. East } } else diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index b18bf7ef3..77e8b8e55 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -186,7 +186,7 @@ public: virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override { - NIBBLETYPE OtherMeta = a_Meta & 0x07; // Contains unrelate meta data. + 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; From 6553c8ff447a1e006095dc7e5aad76b37c410038 Mon Sep 17 00:00:00 2001 From: narroo Date: Wed, 26 Mar 2014 13:25:10 -0400 Subject: [PATCH 030/145] Altered the rotates for cBlockSignHandler. The functions as a whole is still unfinished though; no wall sign or mirroring support yet. --- src/Blocks/BlockSign.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Blocks/BlockSign.h b/src/Blocks/BlockSign.h index 82d9a2fcc..24346b930 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; + return (++a_Meta) & 0x0F; } virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override { - return --a_Meta; + return (--a_Meta) & 0x0F; } } ; From 8c2c4f2463fcc429d336019fa0fd39098eb7d97f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 26 Mar 2014 22:01:01 +0100 Subject: [PATCH 031/145] Prefabs support connectors, rotations and merge strategy. --- src/Generating/Prefab.cpp | 65 +++++++++++++++++++++++++++++++++++++-- src/Generating/Prefab.h | 10 +++++- 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index 824800119..ded4f6c41 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -17,13 +17,14 @@ uses a prefabricate in a cBlockArea for drawing itself. cPrefab::cPrefab(const cPrefab::sDef & a_Def) : m_Size(a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), m_HitBox(0, 0, 0, a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), - m_AllowedRotations(7), // TODO: All rotations allowed (not in the definition yet) - m_MergeStrategy(cBlockArea::msImprint) + m_AllowedRotations(a_Def.m_AllowedRotations), + m_MergeStrategy(a_Def.m_MergeStrategy) { m_BlockArea.Create(m_Size); CharMap cm; ParseCharMap(cm, a_Def.m_CharMap); ParseBlockImage(cm, a_Def.m_Image); + ParseConnectors(a_Def.m_Connectors); } @@ -42,6 +43,22 @@ void cPrefab::Draw(cBlockArea & a_Dest, const cPlacedPiece * a_Placement) +bool cPrefab::HasConnectorType(int a_ConnectorType) const +{ + for (cConnectors::const_iterator itr = m_Connectors.begin(), end = m_Connectors.end(); itr != end; ++itr) + { + if (itr->m_Type == a_ConnectorType) + { + return true; + } + } // for itr - m_Connectors[] + return false; +} + + + + + void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) { // Initialize the charmap to all-invalid values: @@ -102,6 +119,50 @@ void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockIma +void cPrefab::ParseConnectors(const char * a_ConnectorsDef) +{ + AStringVector Lines = StringSplitAndTrim(a_ConnectorsDef, "\n"); + for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) + { + if (itr->empty()) + { + continue; + } + // Split into components: "Type: X, Y, Z: Face": + AStringVector Defs = StringSplitAndTrim(*itr, ":"); + if (Defs.size() != 3) + { + LOGWARNING("Bad prefab Connector definition line: \"%s\", skipping.", itr->c_str()); + continue; + } + AStringVector Coords = StringSplitAndTrim(Defs[1], ","); + if (Coords.size() != 3) + { + LOGWARNING("Bad prefab Connector coords definition: \"%s\", skipping.", Defs[1].c_str()); + continue; + } + + // Check that the BlockFace is within range: + int BlockFace = atoi(Defs[2].c_str()); + if ((BlockFace < 0) || (BlockFace >= 6)) + { + LOGWARNING("Bad prefab Connector Blockface: \"%s\", skipping.", Defs[2].c_str()); + continue; + } + + // Add the connector: + m_Connectors.push_back(cPiece::cConnector( + atoi(Coords[0].c_str()), atoi(Coords[1].c_str()), atoi(Coords[2].c_str()), // Connector pos + atoi(Defs[0].c_str()), // Connector type + (eBlockFace)BlockFace + )); + } // for itr - Lines[] +} + + + + + cPiece::cConnectors cPrefab::GetConnectors(void) const { return m_Connectors; diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index 6596b906b..3733166ab 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -33,13 +33,18 @@ public: int m_SizeZ; const char * m_CharMap; const char * m_Image; - // TODO: Connectors + const char * m_Connectors; + int m_AllowedRotations; + cBlockArea::eMergeStrategy m_MergeStrategy; }; cPrefab(const sDef & a_Def); /** Draws the prefab into the specified block area, according to the placement stored in the PlacedPiece. */ void Draw(cBlockArea & a_Dest, const cPlacedPiece * a_Placement); + + /** Returns true if the prefab has any connector of the specified type. */ + bool HasConnectorType(int a_ConnectorType) const; protected: /** Maps letters in the sDef::m_Image onto a number, BlockType * 16 | BlockMeta */ @@ -76,6 +81,9 @@ protected: /** Parses the Image in the definition into m_BlockArea's block types and metas, using the specified CharMap. */ void ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockImage); + + /** Parses the connectors definition text into m_Connectors member. */ + void ParseConnectors(const char * a_ConnectorsDef); }; From bbebb3a2cdbd888e63e4a40b1bcc730105c11377 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 27 Mar 2014 18:13:52 +0100 Subject: [PATCH 032/145] Fixed chunk neighbor-getting for long distances. This fixes a server hang when teleporting to coords too far away. --- src/Chunk.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 957d7d575..bd4cb9937 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -2510,6 +2510,17 @@ cChunk * cChunk::GetNeighborChunk(int a_BlockX, int a_BlockZ) cChunk * cChunk::GetRelNeighborChunk(int a_RelX, int a_RelZ) { + // If the relative coords are too far away, use the parent's chunk lookup instead: + if ((a_RelX < 128) || (a_RelX > 128) || (a_RelZ < -128) || (a_RelZ > 128)) + { + int BlockX = m_PosX * cChunkDef::Width + a_RelX; + int BlockZ = m_PosZ * cChunkDef::Width + a_RelZ; + int BlockY, ChunkX, ChunkZ; + AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); + return m_ChunkMap->GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + } + + // Walk the neighbors: bool ReturnThis = true; if (a_RelX < 0) { From 7b585290fccd3dc074b1f9feef0af754ab3dd632 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 27 Mar 2014 23:03:57 +0100 Subject: [PATCH 033/145] cPrefab can draw itself into a cChunkDesc. --- src/Generating/Prefab.cpp | 11 +++++++---- src/Generating/Prefab.h | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index ded4f6c41..145c875a1 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -9,6 +9,7 @@ uses a prefabricate in a cBlockArea for drawing itself. #include "Globals.h" #include "Prefab.h" #include "../WorldStorage/SchematicFileSerializer.h" +#include "ChunkDesc.h" @@ -16,7 +17,7 @@ uses a prefabricate in a cBlockArea for drawing itself. cPrefab::cPrefab(const cPrefab::sDef & a_Def) : m_Size(a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), - m_HitBox(0, 0, 0, a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), + m_HitBox(0, 0, 0, a_Def.m_SizeX - 1, a_Def.m_SizeY - 1, a_Def.m_SizeZ - 1), m_AllowedRotations(a_Def.m_AllowedRotations), m_MergeStrategy(a_Def.m_MergeStrategy) { @@ -31,11 +32,13 @@ cPrefab::cPrefab(const cPrefab::sDef & a_Def) : -void cPrefab::Draw(cBlockArea & a_Dest, const cPlacedPiece * a_Placement) +void cPrefab::Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const { Vector3i Placement = a_Placement->GetCoords(); - Placement.Move(a_Dest.GetOrigin() * (-1)); - a_Dest.Merge(m_BlockArea, Placement, m_MergeStrategy); + int ChunkStartX = a_Dest.GetChunkX() * cChunkDef::Width; + int ChunkStartZ = a_Dest.GetChunkZ() * cChunkDef::Width; + Placement.Move(-ChunkStartX, 0, -ChunkStartZ); + a_Dest.WriteBlockArea(m_BlockArea, Placement.x, Placement.y, Placement.z, m_MergeStrategy); } diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index 3733166ab..ec95c909b 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -40,8 +40,8 @@ public: cPrefab(const sDef & a_Def); - /** Draws the prefab into the specified block area, according to the placement stored in the PlacedPiece. */ - void Draw(cBlockArea & a_Dest, const cPlacedPiece * a_Placement); + /** Draws the prefab into the specified chunk, according to the placement stored in the PlacedPiece. */ + void Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const; /** Returns true if the prefab has any connector of the specified type. */ bool HasConnectorType(int a_ConnectorType) const; From 7089c5e2671d2bf7781ab2eab7129bb5bd25b1a1 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 14:01:22 +0100 Subject: [PATCH 034/145] Add new leaves to all classes. --- src/Blocks/BlockLeaves.h | 2 +- src/ChunkMap.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index a6d3373c1..954b993d6 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -87,7 +87,7 @@ public: return; } - if ((Meta & 0x8) != 0) + if ((Meta & 0x8) == 0) { // These leaves have been checked for decay lately and nothing around them changed return; diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index e695f0ab2..da5dd90e4 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1384,6 +1384,13 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) } break; } + case E_BLOCK_NEW_LEAVES: + { + if (itr->BlockType == E_BLOCK_NEW_LOG) + { + Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); + } + } } } // for itr - a_Blocks[] } From c4a8336e847d2f4731dd9d899d6af200631f8aef Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 14:38:41 +0100 Subject: [PATCH 035/145] Add HOOK_BLOCK_SPREAD --- src/Bindings/Plugin.h | 1 + src/Bindings/PluginLua.cpp | 21 +++++++++++++++++++++ src/Bindings/PluginLua.h | 1 + src/Bindings/PluginManager.cpp | 21 +++++++++++++++++++++ src/Bindings/PluginManager.h | 2 ++ src/Simulator/FireSimulator.cpp | 14 +++++++++++--- 6 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 949e4693a..4c6d5a938 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -46,6 +46,7 @@ public: * On all these functions, return true if you want to override default behavior and not call other plugins on that callback. * You can also return false, so default behavior is used. **/ + virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) = 0; virtual bool OnBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0; virtual bool OnChat (cPlayer * a_Player, AString & a_Message) = 0; virtual bool OnChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index cccbc3c93..cefeb4996 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -195,6 +195,26 @@ void cPluginLua::Tick(float a_Dt) +bool cPluginLua::OnBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + cCSLock Lock(m_CriticalSection); + bool res = false; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_BLOCK_SPREAD]; + for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) + { + m_LuaState.Call((int)(**itr), a_World, a_BlockX, a_BlockY, a_BlockZ, cLuaState::Return, res); + if (res) + { + return true; + } + } + return false; +} + + + + + bool cPluginLua::OnBlockToPickups(cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) { cCSLock Lock(m_CriticalSection); @@ -1430,6 +1450,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType) { switch (a_HookType) { + case cPluginManager::HOOK_BLOCK_SPREAD: return "OnBlockSpread"; case cPluginManager::HOOK_BLOCK_TO_PICKUPS: return "OnBlockToPickups"; case cPluginManager::HOOK_CHAT: return "OnChat"; case cPluginManager::HOOK_CHUNK_AVAILABLE: return "OnChunkAvailable"; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index a177f5288..5c2c9e57f 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -69,6 +69,7 @@ public: virtual void Tick(float a_Dt) override; + virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual bool OnBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) override; virtual bool OnChat (cPlayer * a_Player, AString & a_Message) override; virtual bool OnChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index b9cf160c4..142b4b5ad 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -205,6 +205,27 @@ void cPluginManager::Tick(float a_Dt) +bool cPluginManager::CallHookBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_BLOCK_SPREAD); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnBlockSpread(a_World, a_BlockX, a_BlockY, a_BlockZ)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookBlockToPickups( cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 44bc5a8d7..18d34a50d 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -58,6 +58,7 @@ public: // tolua_export // tolua_begin enum PluginHook { + HOOK_BLOCK_SPREAD, HOOK_BLOCK_TO_PICKUPS, HOOK_CHAT, HOOK_CHUNK_AVAILABLE, @@ -154,6 +155,7 @@ public: // tolua_export unsigned int GetNumPlugins() const; // tolua_export // Calls for individual hooks. Each returns false if the action is to continue or true if the plugin wants to abort + bool CallHookBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ); bool CallHookBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups); bool CallHookChat (cPlayer * a_Player, AString & a_Message); bool CallHookChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ); diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 26712e6e6..871a1ec5c 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -6,6 +6,8 @@ #include "../BlockID.h" #include "../Defines.h" #include "../Chunk.h" +#include "Root.h" +#include "PluginManager.h" @@ -315,9 +317,15 @@ void cFireSimulator::TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int */ if (CanStartFireInBlock(a_Chunk, x, y, z)) { - FLOG("FS: Starting new fire at {%d, %d, %d}.", - x + a_Chunk->GetPosX() * cChunkDef::Width, y, z + a_Chunk->GetPosZ() * cChunkDef::Width - ); + int a_PosX = x + a_Chunk->GetPosX() * cChunkDef::Width; + int a_PosZ = z + a_Chunk->GetPosZ() * cChunkDef::Width; + + if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, a_PosX, y, a_PosZ)) + { + return; + } + + FLOG("FS: Starting new fire at {%d, %d, %d}.", a_PosX, y, a_PosZ); a_Chunk->UnboundedRelSetBlock(x, y, z, E_BLOCK_FIRE, 0); } } // for y From 3774b1be6445257a28677fbdce17bab58c168df9 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 16:06:03 +0100 Subject: [PATCH 036/145] Add SpreadSource --- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 4 ++-- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 4 ++-- src/Bindings/PluginManager.h | 2 +- src/BlockID.h | 13 +++++++++++++ src/Blocks/BlockDirt.h | 5 ++++- src/Blocks/BlockMushroom.h | 3 +++ src/Blocks/BlockMycelium.h | 2 ++ src/Blocks/BlockVine.h | 5 ++++- src/Simulator/FireSimulator.cpp | 2 +- 11 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 4c6d5a938..057fa0304 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -46,7 +46,7 @@ public: * On all these functions, return true if you want to override default behavior and not call other plugins on that callback. * You can also return false, so default behavior is used. **/ - virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) = 0; + virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) = 0; virtual bool OnBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0; virtual bool OnChat (cPlayer * a_Player, AString & a_Message) = 0; virtual bool OnChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index cefeb4996..4f0e13f12 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -195,14 +195,14 @@ void cPluginLua::Tick(float a_Dt) -bool cPluginLua::OnBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +bool cPluginLua::OnBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_BLOCK_SPREAD]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_World, a_BlockX, a_BlockY, a_BlockZ, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), a_World, a_BlockX, a_BlockY, a_BlockZ, a_Source, cLuaState::Return, res); if (res) { return true; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 5c2c9e57f..f51056186 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -69,7 +69,7 @@ public: virtual void Tick(float a_Dt) override; - virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) override; virtual bool OnBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) override; virtual bool OnChat (cPlayer * a_Player, AString & a_Message) override; virtual bool OnChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 142b4b5ad..7d346c522 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -205,7 +205,7 @@ void cPluginManager::Tick(float a_Dt) -bool cPluginManager::CallHookBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +bool cPluginManager::CallHookBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) { HookMap::iterator Plugins = m_Hooks.find(HOOK_BLOCK_SPREAD); if (Plugins == m_Hooks.end()) @@ -214,7 +214,7 @@ bool cPluginManager::CallHookBlockSpread(cWorld * a_World, int a_BlockX, int a_B } for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnBlockSpread(a_World, a_BlockX, a_BlockY, a_BlockZ)) + if ((*itr)->OnBlockSpread(a_World, a_BlockX, a_BlockY, a_BlockZ, a_Source)) { return true; } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 18d34a50d..03f19e831 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -155,7 +155,7 @@ public: // tolua_export unsigned int GetNumPlugins() const; // tolua_export // Calls for individual hooks. Each returns false if the action is to continue or true if the plugin wants to abort - bool CallHookBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ); + bool CallHookBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source); bool CallHookBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups); bool CallHookChat (cPlayer * a_Player, AString & a_Message); bool CallHookChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ); diff --git a/src/BlockID.h b/src/BlockID.h index 8adefcfba..a1a445da4 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -866,6 +866,19 @@ enum eShrapnelLevel slAll } ; + + + + +enum eSpreadSource +{ + esFireSpread, + esGrassSpread, + esMushroomSpread, + esMycelSpread, + esVineSpread, +} ; + // tolua_end diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 544424a04..6240e5e3f 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -79,7 +79,10 @@ public: Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta); if ((cBlockInfo::IsOneHitDig(AboveDest) || cBlockInfo::IsTransparent(AboveDest)) && !IsBlockWater(AboveDest)) { - Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0); + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, BlockX * cChunkDef::Width, BlockY, BlockZ * cChunkDef::Width, esGrassSpread)) + { + Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0); + } } } // for i - repeat twice } diff --git a/src/Blocks/BlockMushroom.h b/src/Blocks/BlockMushroom.h index c30c1a401..135d418d7 100644 --- a/src/Blocks/BlockMushroom.h +++ b/src/Blocks/BlockMushroom.h @@ -17,6 +17,9 @@ public: } + // TODO: Add Mushroom Spread + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Reset meta to 0 diff --git a/src/Blocks/BlockMycelium.h b/src/Blocks/BlockMycelium.h index 7f897c72a..2a8ef5fca 100644 --- a/src/Blocks/BlockMycelium.h +++ b/src/Blocks/BlockMycelium.h @@ -16,6 +16,8 @@ public: { } + // TODO: Add Mycel Spread + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.push_back(cItem(E_BLOCK_DIRT, 1, 0)); diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 8041d9359..9d84b720e 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -175,7 +175,10 @@ public: a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block); if (Block == E_BLOCK_AIR) { - a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX * cChunkDef::Width, a_RelY - 1, a_RelZ * cChunkDef::Width, esVineSpread)) + { + a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); + } } } diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 871a1ec5c..932ccf6bd 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -320,7 +320,7 @@ void cFireSimulator::TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int int a_PosX = x + a_Chunk->GetPosX() * cChunkDef::Width; int a_PosZ = z + a_Chunk->GetPosZ() * cChunkDef::Width; - if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, a_PosX, y, a_PosZ)) + if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, a_PosX, y, a_PosZ, esFireSpread)) { return; } From 54d55b31ef9b17673212184ac523f6f2a964338d Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 16:12:16 +0100 Subject: [PATCH 037/145] Add documentation for new Block spread --- MCServer/Plugins/APIDump/APIDesc.lua | 9 +++++ .../Plugins/APIDump/Hooks/OnBlockSpread.lua | 40 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 74e7bf860..92b57865f 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1826,6 +1826,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); }, Constants = { + HOOK_BLOCK_SPREAD = { Notes = "Called when a block spreads based on world conditions" }, HOOK_BLOCK_TO_PICKUPS = { Notes = "Called when a block has been dug and is being converted to pickups. The server has provided the default pickups and the plugins may modify them." }, HOOK_CHAT = { Notes = "Called when a client sends a chat message that is not a command. The plugin may modify the chat message" }, HOOK_CHUNK_AVAILABLE = { Notes = "Called when a chunk is loaded or generated and becomes available in the {{cWorld|world}}." }, @@ -2767,6 +2768,14 @@ end data provided with the explosions, such as the exploding {{cCreeper|creeper}} entity or the {{Vector3i|coords}} of the exploding bed. ]], + }, + SpreadSource = + { + Include = "^es.*", + TextBefore = [[ + These constants are used to differentiate the various sources of spreads. They are used in + the {{OnBlockSpread|HOOK_BLOCK_SPREAD}} hook. + ]], } }, }, -- Globals diff --git a/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua b/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua new file mode 100644 index 000000000..1dde55f36 --- /dev/null +++ b/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua @@ -0,0 +1,40 @@ +return +{ + HOOK_BLOCK_SPREAD = + { + CalledWhen = "Called when a block spreads based on world conditions", + DefaultFnName = "OnBlockSpread", -- also used as pagename + Desc = [[ + This hook is called when a block spreads.

+

+ The explosion carries with it the type of its source - whether it's a creeper exploding, or TNT, + etc. It also carries the identification of the actual source. The exact type of the identification + depends on the source kind: + + + + + + + +
SourceNotes
esFireSpreadFire spreading
esGrassSpreadGrass spreading
esMushroomSpreadMushroom spreading
esMycelSpreadMycel spreading
esVineSpreadVine spreading

+ ]], + Params = + { + { Name = "World", Type = "{{cWorld}}", Notes = "The world in which the block resides" }, + { Name = "BlockX", Type = "number", Notes = "X-coord of the block" }, + { Name = "BlockY", Type = "number", Notes = "Y-coord of the block" }, + { Name = "BlockZ", Type = "number", Notes = "Z-coord of the block" }, + { Name = "Source", Type = "eSpreadSource", Notes = "Source of the spread. See the table above." }, + }, + Returns = [[ + If the function returns false or no value, the next plugin's callback is called, and finally + MCServer will process the spread. If the function + returns true, no other callback is called for this event and the spread will not occur. + ]], + }, -- HOOK_BLOCK_SPREAD +} + + + + From 09794e65bb8d752148250c40c710c08d0acf7ff8 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 16:15:22 +0100 Subject: [PATCH 038/145] Wrong if in BlockLeaves --- src/Blocks/BlockLeaves.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index 954b993d6..a6d3373c1 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -87,7 +87,7 @@ public: return; } - if ((Meta & 0x8) == 0) + if ((Meta & 0x8) != 0) { // These leaves have been checked for decay lately and nothing around them changed return; From 9c461124866cd16d04206f49da6650a2219de50f Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 22:28:12 +0100 Subject: [PATCH 039/145] Change SpreadSource prefix to ss --- src/BlockID.h | 10 +++++----- src/Blocks/BlockDirt.h | 2 +- src/Blocks/BlockVine.h | 2 +- src/Simulator/FireSimulator.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/BlockID.h b/src/BlockID.h index a1a445da4..2fec512e2 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -872,11 +872,11 @@ enum eShrapnelLevel enum eSpreadSource { - esFireSpread, - esGrassSpread, - esMushroomSpread, - esMycelSpread, - esVineSpread, + ssFireSpread, + ssGrassSpread, + ssMushroomSpread, + ssMycelSpread, + ssVineSpread, } ; // tolua_end diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 6240e5e3f..a1ab74257 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -79,7 +79,7 @@ public: Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta); if ((cBlockInfo::IsOneHitDig(AboveDest) || cBlockInfo::IsTransparent(AboveDest)) && !IsBlockWater(AboveDest)) { - if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, BlockX * cChunkDef::Width, BlockY, BlockZ * cChunkDef::Width, esGrassSpread)) + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, BlockX * cChunkDef::Width, BlockY, BlockZ * cChunkDef::Width, ssGrassSpread)) { Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0); } diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 9d84b720e..d096c81a8 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -175,7 +175,7 @@ public: a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block); if (Block == E_BLOCK_AIR) { - if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX * cChunkDef::Width, a_RelY - 1, a_RelZ * cChunkDef::Width, esVineSpread)) + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX * cChunkDef::Width, a_RelY - 1, a_RelZ * cChunkDef::Width, ssVineSpread)) { a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); } diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 932ccf6bd..e4d4a540d 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -320,7 +320,7 @@ void cFireSimulator::TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int int a_PosX = x + a_Chunk->GetPosX() * cChunkDef::Width; int a_PosZ = z + a_Chunk->GetPosZ() * cChunkDef::Width; - if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, a_PosX, y, a_PosZ, esFireSpread)) + if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, a_PosX, y, a_PosZ, ssFireSpread)) { return; } From 9ac3e3405a92d458bf3d09d0ec0f60031d31823d Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 22:28:53 +0100 Subject: [PATCH 040/145] Change SpreadSource documentation --- MCServer/Plugins/APIDump/APIDesc.lua | 2 +- MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 92b57865f..f8ad74226 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2771,7 +2771,7 @@ end }, SpreadSource = { - Include = "^es.*", + Include = "^ss.*", TextBefore = [[ These constants are used to differentiate the various sources of spreads. They are used in the {{OnBlockSpread|HOOK_BLOCK_SPREAD}} hook. diff --git a/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua b/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua index 1dde55f36..a2f7d7ef9 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua @@ -12,11 +12,11 @@ return depends on the source kind: - - - - - + + + + +
SourceNotes
esFireSpreadFire spreading
esGrassSpreadGrass spreading
esMushroomSpreadMushroom spreading
esMycelSpreadMycel spreading
esVineSpreadVine spreading
ssFireSpreadFire spreading
ssGrassSpreadGrass spreading
ssMushroomSpreadMushroom spreading
ssMycelSpreadMycel spreading
ssVineSpreadVine spreading

]], Params = From 327b70e769bd3bb826320027a1b7d56f6e386a6b Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 24 Mar 2014 20:01:57 +0100 Subject: [PATCH 041/145] Change documentation text --- MCServer/Plugins/APIDump/APIDesc.lua | 4 ++-- MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index f8ad74226..01f000182 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2773,8 +2773,8 @@ end { Include = "^ss.*", TextBefore = [[ - These constants are used to differentiate the various sources of spreads. They are used in - the {{OnBlockSpread|HOOK_BLOCK_SPREAD}} hook. + These constants are used to differentiate the various sources of spreads, such as grass growing. + They are used in the {{OnBlockSpread|HOOK_BLOCK_SPREAD}} hook. ]], } }, diff --git a/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua b/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua index a2f7d7ef9..ed0b5f46f 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua @@ -7,8 +7,8 @@ return Desc = [[ This hook is called when a block spreads.

- The explosion carries with it the type of its source - whether it's a creeper exploding, or TNT, - etc. It also carries the identification of the actual source. The exact type of the identification + The spread carries with it the type of its source - whether it's a block spreads. + It also carries the identification of the actual source. The exact type of the identification depends on the source kind: From 8301f479bba4c12579d56c2274b85033a336057c Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 27 Mar 2014 23:21:04 +0100 Subject: [PATCH 042/145] Fix merge conflicts --- src/ChunkMap.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index da5dd90e4..e695f0ab2 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1384,13 +1384,6 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) } break; } - case E_BLOCK_NEW_LEAVES: - { - if (itr->BlockType == E_BLOCK_NEW_LOG) - { - Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); - } - } } } // for itr - a_Blocks[] } From 7cc44d4d8b6b6142ab45f955890a92e395604142 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 13:34:32 +0100 Subject: [PATCH 043/145] Debuggers: Deactivated the chunk generator callback. --- MCServer/Plugins/Debuggers/Debuggers.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index fe3efa306..2cb014875 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -27,11 +27,13 @@ function Initialize(Plugin) PM:AddHook(cPluginManager.HOOK_CHAT, OnChat); PM:AddHook(cPluginManager.HOOK_PLAYER_RIGHT_CLICKING_ENTITY, OnPlayerRightClickingEntity); PM:AddHook(cPluginManager.HOOK_WORLD_TICK, OnWorldTick); - PM:AddHook(cPluginManager.HOOK_CHUNK_GENERATED, OnChunkGenerated); PM:AddHook(cPluginManager.HOOK_PLUGINS_LOADED, OnPluginsLoaded); PM:AddHook(cPluginManager.HOOK_PLUGIN_MESSAGE, OnPluginMessage); PM:AddHook(cPluginManager.HOOK_PLAYER_JOINED, OnPlayerJoined) + -- _X: Disabled so that the normal operation doesn't interfere with anything + -- PM:AddHook(cPluginManager.HOOK_CHUNK_GENERATED, OnChunkGenerated); + PM:BindCommand("/le", "debuggers", HandleListEntitiesCmd, "- Shows a list of all the loaded entities"); PM:BindCommand("/ke", "debuggers", HandleKillEntitiesCmd, "- Kills all the loaded entities"); PM:BindCommand("/wool", "debuggers", HandleWoolCmd, "- Sets all your armor to blue wool"); From a2c4def518b0021a7575c9a9517f4f824369fe6d Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 28 Mar 2014 14:59:40 +0100 Subject: [PATCH 044/145] Add missing ChunkDesc import. --- src/Generating/Prefab.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index ec95c909b..c80de21b2 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -16,7 +16,7 @@ declared in this file as well; the Gallery server exports areas in this format. #include "PieceGenerator.h" #include "../BlockArea.h" - +#include "ChunkDesc.h" From 910e770a18520a96a5823b24b4b6a41068499414 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 16:36:33 +0100 Subject: [PATCH 045/145] Fixed Prefab's rotations. --- src/Generating/Prefab.cpp | 32 ++++++++++++++++++++++++++++---- src/Generating/Prefab.h | 14 +++++++++++--- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index 145c875a1..1af1faec1 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -21,11 +21,33 @@ cPrefab::cPrefab(const cPrefab::sDef & a_Def) : m_AllowedRotations(a_Def.m_AllowedRotations), m_MergeStrategy(a_Def.m_MergeStrategy) { - m_BlockArea.Create(m_Size); + m_BlockArea[0].Create(m_Size); CharMap cm; ParseCharMap(cm, a_Def.m_CharMap); ParseBlockImage(cm, a_Def.m_Image); ParseConnectors(a_Def.m_Connectors); + + // 1 CCW rotation: + if ((m_AllowedRotations & 0x01) != 0) + { + m_BlockArea[1].CopyFrom(m_BlockArea[0]); + m_BlockArea[1].RotateCCW(); + } + + // 2 rotations are the same as mirroring twice; mirroring is faster because it has no reallocations + if ((m_AllowedRotations & 0x02) != 0) + { + m_BlockArea[2].CopyFrom(m_BlockArea[0]); + m_BlockArea[2].MirrorXY(); + m_BlockArea[2].MirrorYZ(); + } + + // 3 CCW rotations = 1 CW rotation: + if ((m_AllowedRotations & 0x04) != 0) + { + m_BlockArea[3].CopyFrom(m_BlockArea[0]); + m_BlockArea[3].RotateCW(); + } } @@ -38,7 +60,7 @@ void cPrefab::Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const int ChunkStartX = a_Dest.GetChunkX() * cChunkDef::Width; int ChunkStartZ = a_Dest.GetChunkZ() * cChunkDef::Width; Placement.Move(-ChunkStartX, 0, -ChunkStartZ); - a_Dest.WriteBlockArea(m_BlockArea, Placement.x, Placement.y, Placement.z, m_MergeStrategy); + a_Dest.WriteBlockArea(m_BlockArea[a_Placement->GetNumCCWRotations()], Placement.x, Placement.y, Placement.z, m_MergeStrategy); } @@ -112,7 +134,7 @@ void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockIma ASSERT(MappedValue != -1); // Using a letter not defined in the CharMap? BLOCKTYPE BlockType = MappedValue >> 4; NIBBLETYPE BlockMeta = MappedValue & 0x0f; - m_BlockArea.SetRelBlockTypeMeta(x, y, z, BlockType, BlockMeta); + m_BlockArea[0].SetRelBlockTypeMeta(x, y, z, BlockType, BlockMeta); } } } @@ -195,7 +217,9 @@ cCuboid cPrefab::GetHitBox(void) const bool cPrefab::CanRotateCCW(int a_NumRotations) const { - return ((m_AllowedRotations & (1 << (a_NumRotations % 4))) != 0); + // Either zero rotations + // Or the proper bit in m_AllowedRotations is set + return (a_NumRotations == 0) || ((m_AllowedRotations & (1 << ((a_NumRotations + 3) % 4))) != 0); } diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index ec95c909b..d6ab5658f 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -22,6 +22,13 @@ declared in this file as well; the Gallery server exports areas in this format. +// fwd: +class cChunkDesc; + + + + + class cPrefab : public cPiece { @@ -51,8 +58,9 @@ protected: typedef int CharMap[256]; - /** The cBlockArea that contains the block definitions for the prefab */ - cBlockArea m_BlockArea; + /** The cBlockArea that contains the block definitions for the prefab. + The index identifies the number of CCW rotations applied (0 = no rotation, 1 = 1 CCW rotation, ...). */ + cBlockArea m_BlockArea[4]; /** The size of the prefab */ Vector3i m_Size; @@ -79,7 +87,7 @@ protected: /** Parses the CharMap in the definition into a CharMap binary data used for translating the definition into BlockArea. */ void ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef); - /** Parses the Image in the definition into m_BlockArea's block types and metas, using the specified CharMap. */ + /** Parses the Image in the definition into m_BlockArea[0]'s block types and metas, using the specified CharMap. */ void ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockImage); /** Parses the connectors definition text into m_Connectors member. */ From 5b7215ec24c2b835a0f1342cf1479f757084d1e2 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 16:42:32 +0100 Subject: [PATCH 046/145] Initial NetherFortGen import. Simple fortresses of 2 different rooms will generate. --- src/CMakeLists.txt | 27 +- src/Generating/ComposableGenerator.cpp | 17 +- src/Generating/MineShafts.cpp | 2 +- src/Generating/NetherFortGen.cpp | 265 ++++++++++++++++ src/Generating/NetherFortGen.h | 86 ++++++ src/Generating/Prefabs/CMakeLists.txt | 13 + src/Generating/Prefabs/NetherFortPrefabs.cpp | 303 +++++++++++++++++++ src/Generating/Prefabs/NetherFortPrefabs.h | 15 + 8 files changed, 713 insertions(+), 15 deletions(-) create mode 100644 src/Generating/NetherFortGen.cpp create mode 100644 src/Generating/NetherFortGen.h create mode 100644 src/Generating/Prefabs/CMakeLists.txt create mode 100644 src/Generating/Prefabs/NetherFortPrefabs.cpp create mode 100644 src/Generating/Prefabs/NetherFortPrefabs.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 448dc4b70..ca874517e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,14 +6,14 @@ include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/jsoncpp/include") include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/polarssl/include") set(FOLDERS OSSupport HTTPServer Items Blocks Protocol Generating) -set(FOLDERS ${FOLDERS} WorldStorage Mobs Entities Simulator UI BlockEntities) +set(FOLDERS ${FOLDERS} WorldStorage Mobs Entities Simulator UI BlockEntities Generating/Prefabs) if (NOT MSVC) - #Bindings needs to reference other folders so are done here + # Bindings need to reference other folders, so they are done here instead - #lib dependecies are not included + # lib dependencies are not included set(BINDING_DEPENDECIES tolua @@ -104,7 +104,6 @@ if (NOT MSVC) Bindings/PluginLua Bindings/PluginManager Bindings/WebPlugin - Bindings/WebPlugin ) target_link_libraries(Bindings lua sqlite tolualib) @@ -138,6 +137,7 @@ if (NOT MSVC) else () + # MSVC-specific handling: Put all files into one project, separate by the folders: # Generate the Bindings if they don't exist: if (NOT EXISTS "${PROJECT_SOURCE_DIR}/Bindings/Bindings.cpp") @@ -149,6 +149,14 @@ else () ) endif() + # Get all files in this folder: + file(GLOB_RECURSE SOURCE + "*.cpp" + "*.h" + "*.pkg" + ) + source_group("" FILES ${SOURCE}) + # Add all subfolders as solution-folders: list(APPEND FOLDERS "Resources") list(APPEND FOLDERS "Bindings") @@ -159,23 +167,16 @@ else () "${PATH}/*.rc" "${PATH}/*.pkg" ) - source_group("${PATH}" FILES ${FOLDER_FILES}) + string(REPLACE "/" "\\" PROJECT_PATH ${PATH}) + source_group("${PROJECT_PATH}" FILES ${FOLDER_FILES}) endfunction(includefolder) foreach(folder ${FOLDERS}) includefolder(${folder}) endforeach(folder) - file(GLOB_RECURSE SOURCE - "*.cpp" - "*.h" - "*.pkg" - ) - include_directories("${PROJECT_SOURCE_DIR}") - source_group("" FILES ${SOURCE}) - # Precompiled headers (1st part) SET_SOURCE_FILES_PROPERTIES( Globals.cpp PROPERTIES COMPILE_FLAGS "/Yc\"Globals.h\"" diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 6c00b5905..339f5709a 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -21,6 +21,7 @@ #include "DistortedHeightmap.h" #include "EndGen.h" #include "MineShafts.h" +#include "NetherFortGen.h" #include "Noise3DGenerator.h" #include "POCPieceGenerator.h" #include "Ravines.h" @@ -191,9 +192,11 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, a_ChunkDesc.GetHeightMap()); } + bool ShouldUpdateHeightmap = false; if (a_ChunkDesc.IsUsingDefaultComposition()) { m_CompositionGen->ComposeTerrain(a_ChunkDesc); + ShouldUpdateHeightmap = true; } if (a_ChunkDesc.IsUsingDefaultFinish()) @@ -202,6 +205,12 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a { (*itr)->GenFinish(a_ChunkDesc); } // for itr - m_FinishGens[] + ShouldUpdateHeightmap = true; + } + + if (ShouldUpdateHeightmap) + { + a_ChunkDesc.UpdateHeightmap(); } } @@ -349,7 +358,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200); int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200); m_FinishGens.push_back(new cStructGenMineShafts( - Seed, GridSize, MaxSystemSize, + Seed, GridSize, MaxSystemSize, ChanceCorridor, ChanceCrossing, ChanceStaircase )); } @@ -361,6 +370,12 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { m_FinishGens.push_back(new cFinishGenNetherClumpFoliage(Seed)); } + else if (NoCaseCompare(*itr, "NetherForts") == 0) + { + int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512); + int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 6); + m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxDepth)); + } else if (NoCaseCompare(*itr, "OreNests") == 0) { m_FinishGens.push_back(new cStructGenOreNests(Seed)); diff --git a/src/Generating/MineShafts.cpp b/src/Generating/MineShafts.cpp index 28dc37567..231295c3f 100644 --- a/src/Generating/MineShafts.cpp +++ b/src/Generating/MineShafts.cpp @@ -1340,7 +1340,7 @@ void cStructGenMineShafts::GetMineShaftSystemsForChunk( BaseX -= NEIGHBORHOOD_SIZE / 2; BaseZ -= NEIGHBORHOOD_SIZE / 2; - // Walk the cache, move each cave system that we want into a_Caves: + // Walk the cache, move each cave system that we want into a_Mineshafts: int StartX = BaseX * m_GridSize; int EndX = (BaseX + NEIGHBORHOOD_SIZE + 1) * m_GridSize; int StartZ = BaseZ * m_GridSize; diff --git a/src/Generating/NetherFortGen.cpp b/src/Generating/NetherFortGen.cpp new file mode 100644 index 000000000..25658da46 --- /dev/null +++ b/src/Generating/NetherFortGen.cpp @@ -0,0 +1,265 @@ + +// NetherFortGen.cpp + +// Implements the cNetherFortGen class representing the nether fortress generator + +#include "Globals.h" +#include "NetherFortGen.h" +#include "Prefabs/NetherFortPrefabs.h" + + + + + +static const int NEIGHBORHOOD_SIZE = 3; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cNetherFortGen::cNetherFort: + +class cNetherFortGen::cNetherFort +{ +public: + cNetherFortGen & m_ParentGen; + int m_BlockX, m_BlockZ; + int m_GridSize; + int m_Seed; + cPlacedPieces m_Pieces; + + cNetherFort(cNetherFortGen & a_ParentGen, int a_BlockX, int a_BlockZ, int a_GridSize, int a_MaxDepth, int a_Seed) : + m_ParentGen(a_ParentGen), + m_BlockX(a_BlockX), + m_BlockZ(a_BlockZ), + m_GridSize(a_GridSize), + m_Seed(a_Seed) + { + // TODO: Proper Y-coord placement + int BlockY = 64; + + // Generate pieces: + cBFSPieceGenerator pg(m_ParentGen, a_Seed); + pg.PlacePieces(a_BlockX, BlockY, a_BlockZ, a_MaxDepth, m_Pieces); + } + + + /** Carves the system into the chunk data */ + void ProcessChunk(cChunkDesc & a_Chunk) + { + for (cPlacedPieces::const_iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr) + { + const cPrefab & Prefab = (const cPrefab &)((*itr)->GetPiece()); + Prefab.Draw(a_Chunk, *itr); + } // for itr - m_PlacedPieces[] + } +}; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cNetherFortGen: + +cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth) : + m_Seed(a_Seed), + m_Noise(a_Seed), + m_GridSize(a_GridSize), + m_MaxDepth(a_MaxDepth) +{ + // Initialize the prefabs: + for (size_t i = 0; i < g_NetherFortPrefabs1Count; i++) + { + cPrefab * Prefab = new cPrefab(g_NetherFortPrefabs1[i]); + m_AllPieces.push_back(Prefab); + if (Prefab->HasConnectorType(0)) + { + m_OuterPieces.push_back(Prefab); + } + if (Prefab->HasConnectorType(1)) + { + m_InnerPieces.push_back(Prefab); + } + } + + // Initialize the starting piece prefabs: + for (size_t i = 0; i < g_NetherFortStartingPrefabs1Count; i++) + { + m_StartingPieces.push_back(new cPrefab(g_NetherFortStartingPrefabs1[i])); + } + + // DEBUG: Try one round of placement: + cPlacedPieces Pieces; + cBFSPieceGenerator pg(*this, a_Seed); + pg.PlacePieces(0, 64, 0, a_MaxDepth, Pieces); +} + + + + + +cNetherFortGen::~cNetherFortGen() +{ + ClearCache(); + for (cPieces::iterator itr = m_AllPieces.begin(), end = m_AllPieces.end(); itr != end; ++itr) + { + delete *itr; + } // for itr - m_AllPieces[] + m_AllPieces.clear(); +} + + + + + +void cNetherFortGen::ClearCache(void) +{ + // TODO +} + + + + + +void cNetherFortGen::GetFortsForChunk(int a_ChunkX, int a_ChunkZ, cNetherForts & a_Forts) +{ + int BaseX = a_ChunkX * cChunkDef::Width / m_GridSize; + int BaseZ = a_ChunkZ * cChunkDef::Width / m_GridSize; + if (BaseX < 0) + { + --BaseX; + } + if (BaseZ < 0) + { + --BaseZ; + } + BaseX -= NEIGHBORHOOD_SIZE / 2; + BaseZ -= NEIGHBORHOOD_SIZE / 2; + + // Walk the cache, move each cave system that we want into a_Forts: + int StartX = BaseX * m_GridSize; + int EndX = (BaseX + NEIGHBORHOOD_SIZE + 1) * m_GridSize; + int StartZ = BaseZ * m_GridSize; + int EndZ = (BaseZ + NEIGHBORHOOD_SIZE + 1) * m_GridSize; + for (cNetherForts::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;) + { + if ( + ((*itr)->m_BlockX >= StartX) && ((*itr)->m_BlockX < EndX) && + ((*itr)->m_BlockZ >= StartZ) && ((*itr)->m_BlockZ < EndZ) + ) + { + // want + a_Forts.push_back(*itr); + itr = m_Cache.erase(itr); + } + else + { + // don't want + ++itr; + } + } // for itr - m_Cache[] + + // Create those forts that haven't been in the cache: + for (int x = 0; x < NEIGHBORHOOD_SIZE; x++) + { + int RealX = (BaseX + x) * m_GridSize; + for (int z = 0; z < NEIGHBORHOOD_SIZE; z++) + { + int RealZ = (BaseZ + z) * m_GridSize; + bool Found = false; + for (cNetherForts::const_iterator itr = a_Forts.begin(), end = a_Forts.end(); itr != end; ++itr) + { + if (((*itr)->m_BlockX == RealX) && ((*itr)->m_BlockZ == RealZ)) + { + Found = true; + break; + } + } // for itr - a_Mineshafts + if (!Found) + { + a_Forts.push_back(new cNetherFort(*this, RealX, RealZ, m_GridSize, m_MaxDepth, m_Seed)); + } + } // for z + } // for x + + // Copy a_Forts into m_Cache to the beginning: + cNetherForts FortsCopy (a_Forts); + m_Cache.splice(m_Cache.begin(), FortsCopy, FortsCopy.begin(), FortsCopy.end()); + + // Trim the cache if it's too long: + if (m_Cache.size() > 100) + { + cNetherForts::iterator itr = m_Cache.begin(); + std::advance(itr, 100); + for (cNetherForts::iterator end = m_Cache.end(); itr != end; ++itr) + { + delete *itr; + } + itr = m_Cache.begin(); + std::advance(itr, 100); + m_Cache.erase(itr, m_Cache.end()); + } +} + + + + + +void cNetherFortGen::GenFinish(cChunkDesc & a_ChunkDesc) +{ + int ChunkX = a_ChunkDesc.GetChunkX(); + int ChunkZ = a_ChunkDesc.GetChunkZ(); + cNetherForts Forts; + GetFortsForChunk(ChunkX, ChunkZ, Forts); + for (cNetherForts::const_iterator itr = Forts.begin(); itr != Forts.end(); ++itr) + { + (*itr)->ProcessChunk(a_ChunkDesc); + } // for itr - Forts[] +} + + + + + +cPieces cNetherFortGen::GetPiecesWithConnector(int a_ConnectorType) +{ + switch (a_ConnectorType) + { + case 0: return m_OuterPieces; + case 1: return m_InnerPieces; + default: return cPieces(); + } +} + + + + + +cPieces cNetherFortGen::GetStartingPieces(void) +{ + return m_StartingPieces; +} + + + + + +void cNetherFortGen::PiecePlaced(const cPiece & a_Piece) +{ + UNUSED(a_Piece); +} + + + + + +void cNetherFortGen::Reset(void) +{ + // Nothing needed +} + + + + diff --git a/src/Generating/NetherFortGen.h b/src/Generating/NetherFortGen.h new file mode 100644 index 000000000..10ba01396 --- /dev/null +++ b/src/Generating/NetherFortGen.h @@ -0,0 +1,86 @@ + +// NetherFortGen.h + +// Declares the cNetherFortGen class representing the nether fortress generator + + + + + +#pragma once + +#include "ComposableGenerator.h" +#include "PieceGenerator.h" + + + + + +class cNetherFortGen : + public cFinishGen, + public cPiecePool +{ +public: + cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth); + + virtual ~cNetherFortGen(); + +protected: + class cNetherFort; // fwd: NetherFortGen.cpp + typedef std::list cNetherForts; + + + /** The seed used for generating*/ + int m_Seed; + + /** The noise used for generating */ + cNoise m_Noise; + + /** Average spacing between the fortresses*/ + int m_GridSize; + + /** Maximum depth of the piece-generator tree */ + int m_MaxDepth; + + /** Cache of the most recently used systems. MoveToFront used. */ + cNetherForts m_Cache; + + /** All the pieces that are allowed for building. + This is the list that's used for memory allocation and deallocation for the pieces. */ + cPieces m_AllPieces; + + /** The pieces that are used as starting pieces. + This list is not shared and the pieces need deallocation. */ + cPieces m_StartingPieces; + + /** The pieces that have an "outer" connector. + The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */ + cPieces m_OuterPieces; + + /** The pieces that have an "inner" connector. + The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */ + cPieces m_InnerPieces; + + + /** Clears everything from the cache. + Also invalidates the forst returned by GetFortsForChunk(). */ + void ClearCache(void); + + /** Returns all forts that *may* intersect the given chunk. + The returned forts live within m_Cache.They are valid until the next call + to this function (which may delete some of the pointers). */ + void GetFortsForChunk(int a_ChunkX, int a_ChunkZ, cNetherForts & a_Forts); + + // cFinishGen overrides: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; + + // cPiecePool overrides: + virtual cPieces GetPiecesWithConnector(int a_ConnectorType) override; + virtual cPieces GetStartingPieces(void) override; + virtual void PiecePlaced(const cPiece & a_Piece) override; + virtual void Reset(void) override; +} ; + + + + diff --git a/src/Generating/Prefabs/CMakeLists.txt b/src/Generating/Prefabs/CMakeLists.txt new file mode 100644 index 000000000..1e60447e7 --- /dev/null +++ b/src/Generating/Prefabs/CMakeLists.txt @@ -0,0 +1,13 @@ + +cmake_minimum_required (VERSION 2.6) +project (MCServer) + +include_directories ("${PROJECT_SOURCE_DIR}/../../") + +file(GLOB SOURCE + "*.cpp" +) + +add_library(Generating_Prefabs ${SOURCE}) + +target_link_libraries(Generating_Prefabs OSSupport iniFile Blocks) diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp new file mode 100644 index 000000000..ea3a298c0 --- /dev/null +++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp @@ -0,0 +1,303 @@ + +// NetherFortPrefabs.cpp + +// Defines all the prefabs for nether forts + +#include "Globals.h" +#include "NetherFortPrefabs.h" + + + + + +/* +The nether fortress has two types of connectors, Outer and Inner. Outer is Type 0, Inner is Type 1. +*/ + + + + + +const cPrefab::sDef g_NetherFortPrefabs1[] = +{ + // BalconyCorridor: + // The data has been exported from gallery Nether, area index 37, ID 288 + { + // Size: + 13, 7, 9, // SizeX = 13, SizeY = 7, SizeZ = 9 + + // Block definitions: + "a:112: 0\n" /* netherbrick */ + "b: 0: 0\n" /* air */ + "c:114: 4\n" /* netherbrickstairs */ + "d:114: 7\n" /* netherbrickstairs */ + "e:114: 5\n" /* netherbrickstairs */ + "f: 44: 6\n" /* step */ + "g:113: 0\n" /* netherbrickfence */ + "h:114: 2\n" /* netherbrickstairs */ + "i:114: 3\n" /* netherbrickstairs */ + "j:114: 0\n" /* netherbrickstairs */ + "k:114: 1\n" /* netherbrickstairs */, + + // Block data: + // Level 1 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "bbbbaaaaabbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + + // Level 2 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaabaaabaaaa" + "bbcdaaaaadebb" + "bbbcdddddebbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + + // Level 3 + "aaaaaaaaaaaaa" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "aaaabfffbaaaa" + "bbaaaaaaaaabb" + "bbaaaaaaaaabb" + "bbaaaaaaaaabb" + "bbaaaaaaaaabb" + + // Level 4 + "agagagagagaga" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "agaabbbbbaaga" + "bbaaabbbaaabb" + "bbgbbbbbbbgbb" + "bbgbbbbbbbgbb" + "bbgggggggggbb" + + // Level 5 + "agagagagagaga" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "agaabbbbbaaga" + "bbaaabbbaaabb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + + // Level 6 + "agagagagagaga" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "agaabbbbbaaga" + "bbaaabbbaaabb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + + // Level 7 + "hhhhhhhhhhhhh" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "iijaaaaaaaiii" + "bbjiiiiiiikbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb", + + // Connections: + "1: 0, 2, 2: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 12, 2, 2: 5\n" /* Type 1, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msImprint, + }, +} ; // g_NetherFortPrefabs1 + + + + + +const cPrefab::sDef g_NetherFortStartingPrefabs1[] = +{ + // CentralRoom: + // The data has been exported from gallery Nether, area index 22, ID 164 + { + // Size: + 13, 9, 13, // SizeX = 13, SizeY = 9, SizeZ = 13 + + // Block definitions: + "a:112: 0\n" /* netherbrick */ + "b: 0: 0\n" /* air */ + "c: 10: 0\n" /* lava */ + "d:113: 0\n" /* netherbrickfence */, + + // Block data: + // Level 1 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 2 + "aaaaabbbaaaaa" + "aaaaabbbaaaaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aabbbaaabbbaa" + "aabbbacabbbaa" + "aabbbaaabbbaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aaaaabbbaaaaa" + "aaaaabbbaaaaa" + + // Level 3 + "aaaaabbbaaaaa" + "aaadabbbadaaa" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "aaadabbbadaaa" + "aaaaabbbaaaaa" + + // Level 4 + "aaaaabbbaaaaa" + "aaadabbbadaaa" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "aaadabbbadaaa" + "aaaaabbbaaaaa" + + // Level 5 + "adadabbbadada" + "daaaabbbaaaad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "daaaabbbaaaad" + "adadabbbadada" + + // Level 6 + "adadaaaaadada" + "daaaaaaaaaaad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "daaaaaaaaaaad" + "adadaaaaadada" + + // Level 7 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 8 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 9 + "dadadadadadad" + "abbbbbbbbbbba" + "dbbbbbbbbbbbd" + "abbbbbbbbbbba" + "dbbbbbbbbbbbd" + "abbbbbbbbbbba" + "dbbbbbbbbbbbd" + "abbbbbbbbbbba" + "dbbbbbbbbbbbd" + "abbbbbbbbbbba" + "dbbbbbbbbbbbd" + "abbbbbbbbbbba" + "dadadadadadad", + + // Connections: + "0: 6, 1, 0: 2\n" /* Type 0, BLOCK_FACE_ZM */ + "1: 6, 1, 12: 3\n" /* Type 1, BLOCK_FACE_ZP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msImprint, + }, +} ; // g_NetherFortStartingPrefabs1 + +const size_t g_NetherFortPrefabs1Count = ARRAYCOUNT(g_NetherFortPrefabs1); +const size_t g_NetherFortStartingPrefabs1Count = ARRAYCOUNT(g_NetherFortStartingPrefabs1); + + + + diff --git a/src/Generating/Prefabs/NetherFortPrefabs.h b/src/Generating/Prefabs/NetherFortPrefabs.h new file mode 100644 index 000000000..37a91689d --- /dev/null +++ b/src/Generating/Prefabs/NetherFortPrefabs.h @@ -0,0 +1,15 @@ + +// NetherFortPrefabs.h + +// Declares the data used for nether fortress prefabs + +#include "../Prefab.h" + + + + + +extern const cPrefab::sDef g_NetherFortPrefabs1[]; +extern const cPrefab::sDef g_NetherFortStartingPrefabs1[]; +extern const size_t g_NetherFortPrefabs1Count; +extern const size_t g_NetherFortStartingPrefabs1Count; From 1802234b4ab58d1afc258a40341e54484c045899 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 16:44:12 +0100 Subject: [PATCH 047/145] Fixed compilation after last PR merge. --- src/Simulator/FireSimulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index e4d4a540d..470dfc791 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -7,7 +7,7 @@ #include "../Defines.h" #include "../Chunk.h" #include "Root.h" -#include "PluginManager.h" +#include "../Bindings/PluginManager.h" From ae0954f1d443822f7f6693f0dd42d5601a50f835 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 17:05:43 +0100 Subject: [PATCH 048/145] Sponged the netherfort balcony prefab. This is a preparation for the msSpongePrint merge strategy, used for imprinting most prefabs. It will carve out even air, but will ignore sponge blocks. --- src/Generating/Prefabs/NetherFortPrefabs.cpp | 61 ++++++++++---------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp index ea3a298c0..29df15c1f 100644 --- a/src/Generating/Prefabs/NetherFortPrefabs.cpp +++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp @@ -28,7 +28,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // Block definitions: "a:112: 0\n" /* netherbrick */ - "b: 0: 0\n" /* air */ + "b: 19: 0\n" /* sponge */ "c:114: 4\n" /* netherbrickstairs */ "d:114: 7\n" /* netherbrickstairs */ "e:114: 5\n" /* netherbrickstairs */ @@ -37,7 +37,8 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = "h:114: 2\n" /* netherbrickstairs */ "i:114: 3\n" /* netherbrickstairs */ "j:114: 0\n" /* netherbrickstairs */ - "k:114: 1\n" /* netherbrickstairs */, + "k:114: 1\n" /* netherbrickstairs */ + "l: 0: 0\n" /* air */, // Block data: // Level 1 @@ -56,7 +57,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = "aaaaaaaaaaaaa" "aaaaaaaaaaaaa" "aaaaaaaaaaaaa" - "aaaabaaabaaaa" + "aaaalaaalaaaa" "bbcdaaaaadebb" "bbbcdddddebbb" "bbbbbbbbbbbbb" @@ -64,10 +65,10 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // Level 3 "aaaaaaaaaaaaa" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "aaaabfffbaaaa" + "lllllllllllll" + "lllllllllllll" + "lllllllllllll" + "aaaalffflaaaa" "bbaaaaaaaaabb" "bbaaaaaaaaabb" "bbaaaaaaaaabb" @@ -75,36 +76,36 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // Level 4 "agagagagagaga" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "agaabbbbbaaga" - "bbaaabbbaaabb" - "bbgbbbbbbbgbb" - "bbgbbbbbbbgbb" + "lllllllllllll" + "lllllllllllll" + "lllllllllllll" + "agaalllllaaga" + "bbaaalllaaabb" + "bbglllllllgbb" + "bbglllllllgbb" "bbgggggggggbb" // Level 5 "agagagagagaga" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "agaabbbbbaaga" - "bbaaabbbaaabb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" + "lllllllllllll" + "lllllllllllll" + "lllllllllllll" + "agaalllllaaga" + "bbaaalllaaabb" + "bblllllllllbb" + "bblllllllllbb" + "bblllllllllbb" // Level 6 "agagagagagaga" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "agaabbbbbaaga" - "bbaaabbbaaabb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" + "lllllllllllll" + "lllllllllllll" + "lllllllllllll" + "agaalllllaaga" + "bbaaalllaaabb" + "bblllllllllbb" + "bblllllllllbb" + "bblllllllllbb" // Level 7 "hhhhhhhhhhhhh" From 3c84a995a90122279cdb2f8cd60491e4d33c297f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 17:09:47 +0100 Subject: [PATCH 049/145] Fixed a memory leak in NetherFortGen. --- src/Generating/NetherFortGen.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Generating/NetherFortGen.cpp b/src/Generating/NetherFortGen.cpp index 25658da46..d111c7cee 100644 --- a/src/Generating/NetherFortGen.cpp +++ b/src/Generating/NetherFortGen.cpp @@ -29,6 +29,7 @@ public: int m_Seed; cPlacedPieces m_Pieces; + cNetherFort(cNetherFortGen & a_ParentGen, int a_BlockX, int a_BlockZ, int a_GridSize, int a_MaxDepth, int a_Seed) : m_ParentGen(a_ParentGen), m_BlockX(a_BlockX), @@ -43,6 +44,12 @@ public: cBFSPieceGenerator pg(m_ParentGen, a_Seed); pg.PlacePieces(a_BlockX, BlockY, a_BlockZ, a_MaxDepth, m_Pieces); } + + + ~cNetherFort() + { + cPieceGenerator::FreePieces(m_Pieces); + } /** Carves the system into the chunk data */ From 113343d336e28613f344aa43cf654baa177463f6 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 17:35:05 +0100 Subject: [PATCH 050/145] NetherFort: Added BalconyTee2 prefab. --- src/Generating/Prefabs/NetherFortPrefabs.cpp | 187 ++++++++++++++++--- 1 file changed, 158 insertions(+), 29 deletions(-) diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp index 29df15c1f..6d6b11cdd 100644 --- a/src/Generating/Prefabs/NetherFortPrefabs.cpp +++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp @@ -20,6 +20,7 @@ The nether fortress has two types of connectors, Outer and Inner. Outer is Type const cPrefab::sDef g_NetherFortPrefabs1[] = { + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // BalconyCorridor: // The data has been exported from gallery Nether, area index 37, ID 288 { @@ -38,7 +39,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = "i:114: 3\n" /* netherbrickstairs */ "j:114: 0\n" /* netherbrickstairs */ "k:114: 1\n" /* netherbrickstairs */ - "l: 0: 0\n" /* air */, + ".: 0: 0\n" /* air */, // Block data: // Level 1 @@ -57,7 +58,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = "aaaaaaaaaaaaa" "aaaaaaaaaaaaa" "aaaaaaaaaaaaa" - "aaaalaaalaaaa" + "aaaa.aaa.aaaa" "bbcdaaaaadebb" "bbbcdddddebbb" "bbbbbbbbbbbbb" @@ -65,10 +66,10 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // Level 3 "aaaaaaaaaaaaa" - "lllllllllllll" - "lllllllllllll" - "lllllllllllll" - "aaaalffflaaaa" + "............." + "............." + "............." + "aaaa.fff.aaaa" "bbaaaaaaaaabb" "bbaaaaaaaaabb" "bbaaaaaaaaabb" @@ -76,36 +77,36 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // Level 4 "agagagagagaga" - "lllllllllllll" - "lllllllllllll" - "lllllllllllll" - "agaalllllaaga" - "bbaaalllaaabb" - "bbglllllllgbb" - "bbglllllllgbb" + "............." + "............." + "............." + "agaa.....aaga" + "bbaaa...aaabb" + "bbg.......gbb" + "bbg.......gbb" "bbgggggggggbb" // Level 5 "agagagagagaga" - "lllllllllllll" - "lllllllllllll" - "lllllllllllll" - "agaalllllaaga" - "bbaaalllaaabb" - "bblllllllllbb" - "bblllllllllbb" - "bblllllllllbb" + "............." + "............." + "............." + "agaa.....aaga" + "bbaaa...aaabb" + "bb.........bb" + "bb.........bb" + "bb.........bb" // Level 6 "agagagagagaga" - "lllllllllllll" - "lllllllllllll" - "lllllllllllll" - "agaalllllaaga" - "bbaaalllaaabb" - "bblllllllllbb" - "bblllllllllbb" - "bblllllllllbb" + "............." + "............." + "............." + "agaa.....aaga" + "bbaaa...aaabb" + "bb.........bb" + "bb.........bb" + "bb.........bb" // Level 7 "hhhhhhhhhhhhh" @@ -125,9 +126,136 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // AllowedRotations: 7, /* 1, 2, 3 CCW rotations */ + // Merge strategy: + cBlockArea::msImprint, + }, // BalconyCorridor + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BalconyTee2: + // The data has been exported from gallery Nether, area index 38, ID 289 + { + // Size: + 13, 7, 11, // SizeX = 13, SizeY = 7, SizeZ = 11 + + // Block definitions: + "a: 19: 0\n" /* sponge */ + "b:112: 0\n" /* netherbrick */ + "c:114: 4\n" /* netherbrickstairs */ + "d:114: 7\n" /* netherbrickstairs */ + "e:114: 5\n" /* netherbrickstairs */ + "f: 44: 6\n" /* step */ + "g:113: 0\n" /* netherbrickfence */ + "h:114: 0\n" /* netherbrickstairs */ + "i:114: 1\n" /* netherbrickstairs */ + "j:114: 2\n" /* netherbrickstairs */ + "k:114: 3\n" /* netherbrickstairs */ + ".: 0: 0\n" /* air */, + + // Block data: + // Level 1 + "aaaabbbbbaaaa" + "aaaabbbbbaaaa" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "aaaabbbbbaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 2 + "aaaabbbbbaaaa" + "aaaabbbbbaaaa" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbb.bbb.bbbb" + "aacdbbbbbdeaa" + "aaacdddddeaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 3 + "aaaab...baaaa" + "aaaab...baaaa" + "bbbbb...bbbbb" + "............." + "............." + "............." + "bbbb.fff.bbbb" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + + // Level 4 + "aaaab...baaaa" + "aaaag...gaaaa" + "bgbgb...bgbgb" + "............." + "............." + "............." + "bgbb.....bbgb" + "aabbb...bbbaa" + "aag.......gaa" + "aag.......gaa" + "aagggggggggaa" + + // Level 5 + "aaaab...baaaa" + "aaaag...gaaaa" + "bgbgb...bgbgb" + "............." + "............." + "............." + "bgbb.....bbgb" + "aabbb...bbbaa" + "aa.........aa" + "aa.........aa" + "aa.........aa" + + // Level 6 + "aaaab...baaaa" + "aaaag...gaaaa" + "bgbgb...bgbgb" + "............." + "............." + "............." + "bgbb.....bbgb" + "aabbb...bbbaa" + "aa.........aa" + "aa.........aa" + "aa.........aa" + + // Level 7 + "aaaahbbbiaaaa" + "aaaahbbbiaaaa" + "jjjjjbbbjjjjj" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "kkhbbbbbbbkkk" + "aahkkkkkkkiaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa", + + // Connections: + "1: 0, 2, 4: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 12, 2, 4: 5\n" /* Type 1, BLOCK_FACE_XP */ + "1: 6, 2, 0: 2\n" /* Type 1, BLOCK_FACE_ZM */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + // Merge strategy: cBlockArea::msImprint, }, + } ; // g_NetherFortPrefabs1 @@ -136,6 +264,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = const cPrefab::sDef g_NetherFortStartingPrefabs1[] = { + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CentralRoom: // The data has been exported from gallery Nether, area index 22, ID 164 { From 8557549cfac260867112be96e24b2c0e059db47e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 18:03:37 +0100 Subject: [PATCH 051/145] Implemented the msSpongePrint merge strategy. Similar to msImprint, but allows prefabs to carve out air pockets, too. The sponge block is used as the NOP block. --- MCServer/Plugins/APIDump/APIDesc.lua | 24 ++++++++++--- src/BlockArea.cpp | 38 +++++++++++++++++--- src/BlockArea.h | 13 +++++-- src/Generating/Prefabs/NetherFortPrefabs.cpp | 6 ++-- 4 files changed, 68 insertions(+), 13 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 01f000182..6f8a14421 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -258,12 +258,11 @@ g_APIDesc =

-

- Special strategies: -

+

Special strategies

+

For each strategy, evaluate the table rows from top downwards, the first match wins.

- msLake (evaluate top-down, first match wins): + msLake - used for merging areas with lava and water lakes, in the appropriate generator.

SourceNotes
@@ -293,6 +292,23 @@ g_APIDesc =
area block Notes A * A Everything else is left as it is
+ + +

+ msSpongePrint - used for most prefab-generators to merge the prefabs. Similar to + msImprint, but uses the sponge block as the NOP block instead, so that the prefabs may carve out air + pockets, too. +

+ + + + + + + + + +
area block Notes
this Src result
A sponge A Sponge is the NOP block
* B B Everything else overwrites anything
]], }, -- Merge strategies }, -- AdditionalInfo diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index f6d54e41c..2b950378a 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -54,7 +54,7 @@ template void InternalMergeBlocks( /// Combinator used for cBlockArea::msOverwrite merging -static void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) +static inline void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { a_DstType = a_SrcType; a_DstMeta = a_SrcMeta; @@ -65,7 +65,7 @@ static void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, /// Combinator used for cBlockArea::msFillAir merging -static void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) +static inline void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { if (a_DstType == E_BLOCK_AIR) { @@ -80,7 +80,7 @@ static void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, N /// Combinator used for cBlockArea::msImprint merging -static void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) +static inline void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { if (a_SrcType != E_BLOCK_AIR) { @@ -95,7 +95,7 @@ static void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, N /// Combinator used for cBlockArea::msLake merging -static void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) +static inline void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { // Sponge is the NOP block if (a_SrcType == E_BLOCK_SPONGE) @@ -158,6 +158,21 @@ static void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBB +/** Combinator used for cBlockArea::msSpongePrint merging */ +static inline void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) +{ + // Sponge overwrites nothing, everything else overwrites anything + if (a_SrcType != E_BLOCK_SPONGE) + { + a_DstType = a_SrcType; + a_DstMeta = a_SrcMeta; + } +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cBlockArea: @@ -680,6 +695,21 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R break; } // case msLake + case msSpongePrint: + { + InternalMergeBlocks( + m_BlockTypes, a_Src.GetBlockTypes(), + DstMetas, SrcMetas, + SizeX, SizeY, SizeZ, + SrcOffX, SrcOffY, SrcOffZ, + DstOffX, DstOffY, DstOffZ, + a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), + m_Size.x, m_Size.y, m_Size.z, + MergeCombinatorSpongePrint + ); + break; + } // case msSpongePrint + default: { LOGWARNING("Unknown block area merge strategy: %d", a_Strategy); diff --git a/src/BlockArea.h b/src/BlockArea.h index d28325d7d..d37f0d182 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -51,6 +51,7 @@ public: msFillAir, msImprint, msLake, + msSpongePrint, } ; cBlockArea(void); @@ -127,8 +128,8 @@ public: - msFillAir overwrites only those blocks that were air - msImprint overwrites with only those blocks that are non-air - Special strategies: - msLake (evaluate top-down, first match wins): + Special strategies (evaluate top-down, first match wins): + msLake: | area block | | | this | Src | result | +----------+--------+--------+ @@ -143,6 +144,14 @@ public: | mycelium | stone | stone | ... and mycelium | A | stone | A | ... but nothing else | A | * | A | Everything else is left as it is + + msSpongePrint: + Used for most generators, it allows carving out air pockets, too, and uses the Sponge as the NOP block + | area block | | + | this | Src | result | + +----------+--------+--------+ + | A | sponge | A | Sponge is the NOP block + | * | B | B | Everything else overwrites anything */ void Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy); diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp index 6d6b11cdd..31eaa5078 100644 --- a/src/Generating/Prefabs/NetherFortPrefabs.cpp +++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp @@ -127,7 +127,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = 7, /* 1, 2, 3 CCW rotations */ // Merge strategy: - cBlockArea::msImprint, + cBlockArea::msSpongePrint, }, // BalconyCorridor @@ -253,7 +253,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = 7, /* 1, 2, 3 CCW rotations */ // Merge strategy: - cBlockArea::msImprint, + cBlockArea::msSpongePrint, }, } ; // g_NetherFortPrefabs1 @@ -421,7 +421,7 @@ const cPrefab::sDef g_NetherFortStartingPrefabs1[] = 7, /* 1, 2, 3 CCW rotations */ // Merge strategy: - cBlockArea::msImprint, + cBlockArea::msSpongePrint, }, } ; // g_NetherFortStartingPrefabs1 From 773ce7fde692e86531e1e92f42776e316b793d83 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 21:35:45 +0100 Subject: [PATCH 052/145] Fixed non-virtual destructors warnings. --- src/Bindings/PluginManager.h | 2 ++ src/Blocks/BroadcastInterface.h | 3 ++- src/Blocks/WorldInterface.h | 3 ++- src/ForEachChunkProvider.h | 2 ++ src/Globals.h | 10 +++++-- src/HTTPServer/HTTPServer.h | 4 ++- src/Inventory.h | 2 ++ src/ItemGrid.h | 46 +++++++++++++++++---------------- src/OSSupport/ListenThread.h | 20 +++++++------- src/RCONServer.h | 2 +- src/UI/WindowOwner.h | 4 +++ 11 files changed, 61 insertions(+), 37 deletions(-) diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 03f19e831..7895be959 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -128,6 +128,8 @@ public: // tolua_export class cCommandEnumCallback { public: + virtual ~cCommandEnumCallback() {} + /** Called for each command; return true to abort enumeration For console commands, a_Permission is not used (set to empty string) */ diff --git a/src/Blocks/BroadcastInterface.h b/src/Blocks/BroadcastInterface.h index 01966ffbd..b1b450690 100644 --- a/src/Blocks/BroadcastInterface.h +++ b/src/Blocks/BroadcastInterface.h @@ -4,7 +4,8 @@ class cBroadcastInterface { public: - + virtual ~cBroadcastInterface() {} + virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0; virtual void BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL) = 0; virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) = 0; diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index 580339d32..bfbb053d9 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -9,7 +9,8 @@ class cItems; class cWorldInterface { public: - + virtual ~cWorldInterface() {} + virtual Int64 GetTimeOfDay(void) const = 0; virtual Int64 GetWorldAge(void) const = 0; diff --git a/src/ForEachChunkProvider.h b/src/ForEachChunkProvider.h index 6017173ee..7a6e8c5c6 100644 --- a/src/ForEachChunkProvider.h +++ b/src/ForEachChunkProvider.h @@ -24,6 +24,8 @@ class cBlockArea; class cForEachChunkProvider { public: + virtual ~cForEachChunkProvider() {} + /** Calls the callback for each chunk in the specified range. */ virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) = 0; diff --git a/src/Globals.h b/src/Globals.h index 3e62832b7..a1cee5c2f 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -264,11 +264,17 @@ template class SizeChecker; #define assert_test(x) ( !!(x) || (assert(!#x), exit(1), 0)) #endif -/// A generic interface used mainly in ForEach() functions + + + + +/** A generic interface used mainly in ForEach() functions */ template class cItemCallback { public: - /// Called for each item in the internal list; return true to stop the loop, or false to continue enumerating + virtual ~cItemCallback() {} + + /** Called for each item in the internal list; return true to stop the loop, or false to continue enumerating */ virtual bool Item(Type * a_Type) = 0; } ; diff --git a/src/HTTPServer/HTTPServer.h b/src/HTTPServer/HTTPServer.h index 24baf8c95..383abb4b6 100644 --- a/src/HTTPServer/HTTPServer.h +++ b/src/HTTPServer/HTTPServer.h @@ -37,6 +37,8 @@ public: class cCallbacks { public: + virtual ~cCallbacks() {} + /** Called when a new request arrives over a connection and its headers have been parsed. The request body needn't have arrived yet. */ @@ -50,7 +52,7 @@ public: } ; cHTTPServer(void); - ~cHTTPServer(); + virtual ~cHTTPServer(); /// Initializes the server on the specified ports bool Initialize(const AString & a_PortsIPv4, const AString & a_PortsIPv6); diff --git a/src/Inventory.h b/src/Inventory.h index fd2089a13..1ad7c4776 100644 --- a/src/Inventory.h +++ b/src/Inventory.h @@ -52,6 +52,8 @@ public: cInventory(cPlayer & a_Owner); + virtual ~cInventory() {} + // tolua_begin /// Removes all items from the entire inventory diff --git a/src/ItemGrid.h b/src/ItemGrid.h index b344e3daf..c34d5e9e2 100644 --- a/src/ItemGrid.h +++ b/src/ItemGrid.h @@ -20,11 +20,13 @@ class cItemGrid public: // tolua_end - /// This class is used as a callback for when a slot changes + /** This class is used as a callback for when a slot changes */ class cListener { public: - /// Called whenever a slot changes + virtual ~cListener() {} + + /** Called whenever a slot changes */ virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) = 0; } ; typedef std::vector cListeners; @@ -38,12 +40,12 @@ public: int GetHeight (void) const { return m_Height; } int GetNumSlots(void) const { return m_NumSlots; } - /// Converts XY coords into slot number; returns -1 on invalid coords + /** Converts XY coords into slot number; returns -1 on invalid coords */ int GetSlotNum(int a_X, int a_Y) const; // tolua_end - /// Converts slot number into XY coords; sets coords to -1 on invalid slot number. Exported in ManualBindings.cpp + /** Converts slot number into XY coords; sets coords to -1 on invalid slot number. Exported in ManualBindings.cpp */ void GetSlotCoords(int a_SlotNum, int & a_X, int & a_Y) const; // tolua_begin @@ -62,16 +64,16 @@ public: void EmptySlot(int a_X, int a_Y); void EmptySlot(int a_SlotNum); - /// Returns true if the specified slot is empty or the slot doesn't exist + /** Returns true if the specified slot is empty or the slot doesn't exist */ bool IsSlotEmpty(int a_SlotNum) const; - /// Returns true if the specified slot is empty or the slot doesn't exist + /** Returns true if the specified slot is empty or the slot doesn't exist */ bool IsSlotEmpty(int a_X, int a_Y) const; - /// Sets all items as empty + /** Sets all items as empty */ void Clear(void); - /// Returns number of items out of a_ItemStack that can fit in the storage + /** Returns number of items out of a_ItemStack that can fit in the storage */ int HowManyCanFit(const cItem & a_ItemStack, bool a_AllowNewStacks = true); /** Adds as many items out of a_ItemStack as can fit. @@ -117,37 +119,37 @@ public: */ cItem RemoveOneItem(int a_X, int a_Y); - /// Returns the number of items of type a_Item that are stored + /** Returns the number of items of type a_Item that are stored */ int HowManyItems(const cItem & a_Item); - /// Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack + /** Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack */ bool HasItems(const cItem & a_ItemStack); - /// Returns the index of the first empty slot; -1 if all full + /** Returns the index of the first empty slot; -1 if all full */ int GetFirstEmptySlot(void) const; - /// Returns the index of the first non-empty slot; -1 if all empty + /** Returns the index of the first non-empty slot; -1 if all empty */ int GetFirstUsedSlot(void) const; - /// Returns the index of the last empty slot; -1 if all full + /** Returns the index of the last empty slot; -1 if all full */ int GetLastEmptySlot(void) const; - /// Returns the index of the last used slot; -1 if all empty + /** Returns the index of the last used slot; -1 if all empty */ int GetLastUsedSlot(void) const; - /// Returns the index of the first empty slot following a_StartFrom (a_StartFrom is not checked) + /** Returns the index of the first empty slot following a_StartFrom (a_StartFrom is not checked) */ int GetNextEmptySlot(int a_StartFrom) const; - /// Returns the index of the first used slot following a_StartFrom (a_StartFrom is not checked) + /** Returns the index of the first used slot following a_StartFrom (a_StartFrom is not checked) */ int GetNextUsedSlot(int a_StartFrom) const; - /// Copies the contents into a cItems object; preserves the original a_Items contents + /** Copies the contents into a cItems object; preserves the original a_Items contents */ void CopyToItems(cItems & a_Items) const; - /// Adds the specified damage to the specified item; returns true if the item broke (but the item is left intact) + /** Adds the specified damage to the specified item; returns true if the item broke (but the item is left intact) */ bool DamageItem(int a_SlotNum, short a_Amount); - /// Adds the specified damage to the specified item; returns true if the item broke (but the item is left intact) + /** Adds the specified damage to the specified item; returns true if the item broke (but the item is left intact) */ bool DamageItem(int a_X, int a_Y, short a_Amount); // tolua_end @@ -159,10 +161,10 @@ public: */ void GenerateRandomLootWithBooks(const cLootProbab * a_LootProbabs, size_t a_CountLootProbabs, int a_NumSlots, int a_Seed); - /// Adds a callback that gets called whenever a slot changes. Must not be called from within the listener callback! + /** Adds a callback that gets called whenever a slot changes. Must not be called from within the listener callback! */ void AddListener(cListener & a_Listener); - /// Removes a slot-change-callback. Must not be called from within the listener callback! + /** Removes a slot-change-callback. Must not be called from within the listener callback! */ void RemoveListener(cListener & a_Listener); // tolua_begin @@ -177,7 +179,7 @@ protected: cCriticalSection m_CSListeners; ///< CS that guards the m_Listeners against multi-thread access bool m_IsInTriggerListeners; ///< Set to true while TriggerListeners is running, to detect attempts to manipulate listener list while triggerring - /// Calls all m_Listeners for the specified slot number + /** Calls all m_Listeners for the specified slot number */ void TriggerListeners(int a_SlotNum); /** Adds up to a_Num items out of a_ItemStack, as many as can fit, in specified slot diff --git a/src/OSSupport/ListenThread.h b/src/OSSupport/ListenThread.h index 4e337d814..b2d806c82 100644 --- a/src/OSSupport/ListenThread.h +++ b/src/OSSupport/ListenThread.h @@ -29,43 +29,45 @@ class cListenThread : typedef cIsThread super; public: - /// Used as the callback for connection events + /** Used as the callback for connection events */ class cCallback { public: - /// This callback is called whenever a socket connection is accepted + virtual ~cCallback() {} + + /** This callback is called whenever a socket connection is accepted */ virtual void OnConnectionAccepted(cSocket & a_Socket) = 0; } ; cListenThread(cCallback & a_Callback, cSocket::eFamily a_Family, const AString & a_ServiceName = ""); ~cListenThread(); - /// Creates all the sockets, returns trus if successful, false if not. + /** Creates all the sockets, returns trus if successful, false if not. */ bool Initialize(const AString & a_PortsString); bool Start(void); void Stop(void); - /// Call before Initialize() to set the "reuse" flag on the sockets + /** Call before Initialize() to set the "reuse" flag on the sockets */ void SetReuseAddr(bool a_Reuse = true); protected: typedef std::vector cSockets; - /// The callback which to notify of incoming connections + /** The callback which to notify of incoming connections */ cCallback & m_Callback; - /// Socket address family to use + /** Socket address family to use */ cSocket::eFamily m_Family; - /// Sockets that are being monitored + /** Sockets that are being monitored */ cSockets m_Sockets; - /// If set to true, the SO_REUSEADDR socket option is set to true + /** If set to true, the SO_REUSEADDR socket option is set to true */ bool m_ShouldReuseAddr; - /// Name of the service that's listening on the ports; for logging purposes only + /** Name of the service that's listening on the ports; for logging purposes only */ AString m_ServiceName; diff --git a/src/RCONServer.h b/src/RCONServer.h index 0e89800a2..88aac4b5f 100644 --- a/src/RCONServer.h +++ b/src/RCONServer.h @@ -29,7 +29,7 @@ class cRCONServer : { public: cRCONServer(cServer & a_Server); - ~cRCONServer(); + virtual ~cRCONServer(); void Initialize(cIniFile & a_IniFile); diff --git a/src/UI/WindowOwner.h b/src/UI/WindowOwner.h index d41abf66d..e3c73edc4 100644 --- a/src/UI/WindowOwner.h +++ b/src/UI/WindowOwner.h @@ -33,6 +33,10 @@ public: { } + virtual ~cWindowOwner() + { + } + void CloseWindow(void) { m_Window = NULL; From 0f1087b7d51d998ac311c16588c599938934f2bd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 22:04:59 +0100 Subject: [PATCH 053/145] Added Prefabs to *nix builds. --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ca874517e..30e9dbfd4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -232,7 +232,7 @@ endif () if (NOT MSVC) target_link_libraries(${EXECUTABLE} OSSupport HTTPServer Bindings Items Blocks) - target_link_libraries(${EXECUTABLE} Protocol Generating WorldStorage) + target_link_libraries(${EXECUTABLE} Protocol Generating Generating_Prefabs WorldStorage) target_link_libraries(${EXECUTABLE} Mobs Entities Simulator UI BlockEntities) endif () if (WIN32) From efc89b2c430c94de03bdb519470d7cb6c3b5d661 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 28 Mar 2014 22:22:29 +0100 Subject: [PATCH 054/145] Add tall flower handler. --- src/Blocks/BlockBigFlower.h | 97 +++++++++++++++++++++++++++++++++++++ src/Blocks/BlockHandler.cpp | 2 + 2 files changed, 99 insertions(+) create mode 100644 src/Blocks/BlockBigFlower.h diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h new file mode 100644 index 000000000..46f16c4a2 --- /dev/null +++ b/src/Blocks/BlockBigFlower.h @@ -0,0 +1,97 @@ + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockBigFlowerHandler : + public cBlockHandler +{ +public: + typedef cBlockHandler super; + + cBlockBigFlowerHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + if (Meta & 0x8) + { + super::DropBlock(a_ChunkInterface, a_WorldInterface, a_BlockPluginInterface, a_Digger, a_BlockX, a_BlockY - 1, a_BlockZ); + } + else + { + super::DropBlock(a_ChunkInterface, a_WorldInterface, a_BlockPluginInterface, a_Digger, a_BlockX, a_BlockY, a_BlockZ); + } + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + NIBBLETYPE Meta = a_BlockMeta & 0x7; + + if ((Meta == 2) || (Meta == 3)) + { + return; + } + + a_Pickups.push_back(cItem(E_BLOCK_BIG_FLOWER, 1, Meta)); + } + + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override + { + return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR)); + } + + + virtual void OnPlacedByPlayer( + 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, + BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta + ) override + { + int Meta = (((int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 0.5) & 0x3) + 2) % 4; + a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, 0x8 | Meta); + } + + + virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + + if (OldMeta & 0x8) + { + // Was upper part of door + if (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) == m_BlockType) + { + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); + } + } + else + { + // Was lower part + if (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) == m_BlockType) + { + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, E_BLOCK_AIR, 0); + } + } + } + + + virtual const char * GetStepSound(void) override + { + return "step.grass"; + } +} ; + + + + diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 4f74e2f45..09e00e77d 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -8,6 +8,7 @@ #include "../Chunk.h" #include "BlockAnvil.h" #include "BlockBed.h" +#include "BlockBigFlower.h" #include "BlockBrewingStand.h" #include "BlockButton.h" #include "BlockCactus.h" @@ -89,6 +90,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_ACTIVATOR_RAIL: return new cBlockRailHandler (a_BlockType); case E_BLOCK_ANVIL: return new cBlockAnvilHandler (a_BlockType); case E_BLOCK_BED: return new cBlockBedHandler (a_BlockType); + case E_BLOCK_BIG_FLOWER: return new cBlockBigFlowerHandler (a_BlockType); case E_BLOCK_BIRCH_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_BREWING_STAND: return new cBlockBrewingStandHandler (a_BlockType); case E_BLOCK_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); From f2f6096ee5b92b21924348975c923f74dd23786b Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 28 Mar 2014 22:24:54 +0100 Subject: [PATCH 055/145] door -> flower --- src/Blocks/BlockBigFlower.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h index 46f16c4a2..fabc4c4ed 100644 --- a/src/Blocks/BlockBigFlower.h +++ b/src/Blocks/BlockBigFlower.h @@ -69,7 +69,7 @@ public: if (OldMeta & 0x8) { - // Was upper part of door + // Was upper part of flower if (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) == m_BlockType) { a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); From a78bacac3cb915a82b73bf8fe0ccc0a153190df9 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 28 Mar 2014 23:14:58 +0100 Subject: [PATCH 056/145] Add tallgrass drop to big flowers. Add tallgrass drop, when a players break a tallgrass with the shear. --- src/Blocks/BlockBigFlower.h | 43 ++++++++++++++++++++++++++++++++++--- src/Blocks/BlockTallGrass.h | 24 ++++++++++++++++----- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h index fabc4c4ed..194a79a67 100644 --- a/src/Blocks/BlockBigFlower.h +++ b/src/Blocks/BlockBigFlower.h @@ -44,10 +44,47 @@ public: a_Pickups.push_back(cItem(E_BLOCK_BIG_FLOWER, 1, Meta)); } - + + + virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + if (Meta & 0x8) + { + Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ); + } + + NIBBLETYPE FlowerMeta = Meta & 0x7; + if (!a_Player->IsGameModeCreative()) + { + if (((FlowerMeta == 2) || (FlowerMeta == 3)) && (a_Player->GetEquippedItem().m_ItemType == E_ITEM_SHEARS)) + { + MTRand r1; + if (r1.randInt(10) == 5) + { + cItems Pickups; + if (FlowerMeta == 2) + { + Pickups.Add(E_BLOCK_TALL_GRASS, 2, 1); + } + else if (FlowerMeta == 3) + { + Pickups.Add(E_BLOCK_TALL_GRASS, 2, 2); + } + a_WorldInterface.SpawnItemPickups(Pickups, a_BlockX, a_BlockY, a_BlockZ); + } + a_Player->UseEquippedItem(); + } + } + } + + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR)); + return ( + a_RelY > 0 + && a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR + ); } @@ -59,7 +96,7 @@ public: ) override { int Meta = (((int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 0.5) & 0x3) + 2) % 4; - a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, 0x8 | Meta); + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY + 1, a_BlockZ, m_BlockType, 0x8 | Meta); } diff --git a/src/Blocks/BlockTallGrass.h b/src/Blocks/BlockTallGrass.h index b8af1f1da..ba1f2e0f6 100644 --- a/src/Blocks/BlockTallGrass.h +++ b/src/Blocks/BlockTallGrass.h @@ -15,14 +15,14 @@ public: : cBlockHandler(a_BlockType) { } - - + + virtual bool DoesIgnoreBuildCollision(void) override { return true; } - - + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Drop seeds, sometimes @@ -34,11 +34,25 @@ public: } + virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + + if ((!a_Player->IsGameModeCreative()) && (a_Player->GetEquippedItem().m_ItemType == E_ITEM_SHEARS)) + { + cItems Pickups; + Pickups.Add(E_BLOCK_TALL_GRASS, 1, Meta); + a_WorldInterface.SpawnItemPickups(Pickups, a_BlockX, a_BlockY, a_BlockZ); + } + a_Player->UseEquippedItem(); + } + + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR)); } - + virtual const char * GetStepSound(void) override { From 76f0d167b15de08a810a1348614e8b8c2b6f2e60 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 23:39:40 +0100 Subject: [PATCH 057/145] NetherFortGen: Added several more prefabs. Also extended the defauls MaxDepth value to 12. --- src/Generating/ComposableGenerator.cpp | 2 +- src/Generating/Prefabs/NetherFortPrefabs.cpp | 783 ++++++++++++++++++- 2 files changed, 783 insertions(+), 2 deletions(-) diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 339f5709a..2e886336f 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -373,7 +373,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) else if (NoCaseCompare(*itr, "NetherForts") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512); - int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 6); + int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12); m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxDepth)); } else if (NoCaseCompare(*itr, "OreNests") == 0) diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp index 31eaa5078..24bde1baf 100644 --- a/src/Generating/Prefabs/NetherFortPrefabs.cpp +++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp @@ -254,8 +254,789 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // Merge strategy: cBlockArea::msSpongePrint, - }, + }, // BalconyTee2 + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BlazePlatform + // The data has been exported from gallery Nether, area index 26, ID 276 + { + // Size: + 10, 7, 7, // SizeX = 10, SizeY = 7, SizeZ = 7 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b: 52: 0\n" /* mobspawner */ + "c:113: 0\n" /* netherbrickfence */, + + // Block data: + // Level 1 + ".........." + "aaaaaaaaaa" + "aaaaaaaaaa" + "aaaaaaaaaa" + "aaaaaaaaaa" + "aaaaaaaaaa" + ".........." + + // Level 2 + ".........." + "aaaaaaaaaa" + "..aaaaaaaa" + "..aaaaaaaa" + "..aaaaaaaa" + "aaaaaaaaaa" + ".........." + + // Level 3 + "....aaaaaa" + "aaaaaaaaaa" + "...aaaaaaa" + "...aaaaaaa" + "...aaaaaaa" + "aaaaaaaaaa" + "....aaaaaa" + + // Level 4 + "....aaaaaa" + "..aaa....a" + ".........a" + "......b..a" + ".........a" + "..aaa....a" + "....aaaaaa" + + // Level 5 + "....cccccc" + "...cc....c" + ".........c" + ".........c" + ".........c" + "...cc....c" + "....cccccc" + + // Level 6 + ".........." + ".........c" + ".........c" + ".........c" + ".........c" + ".........c" + ".........." + + // Level 7 + ".........." + ".........." + ".........c" + ".........c" + ".........c" + ".........." + "..........", + + // Connections: + "0: 0, 1, 3: 4\n" /* Type 0, BLOCK_FACE_XM */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // BlazePlatform + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BlazePlatformOverhang: + // The data has been exported from gallery Nether, area index 20, ID 162 + { + // Size: + 14, 9, 7, // SizeX = 14, SizeY = 9, SizeZ = 7 + + // Block definitions: + ".: 0: 0\n" /* 0 */ + "a:112: 0\n" /* netherbrick */ + "b:114: 5\n" /* netherbrickstairs */ + "c: 44:14\n" /* step */ + "d:114: 6\n" /* netherbrickstairs */ + "e:114: 7\n" /* netherbrickstairs */ + "f:114: 0\n" /* netherbrickstairs */ + "g:114: 4\n" /* netherbrickstairs */ + "h:113: 0\n" /* netherbrickfence */ + "i: 52: 0\n" /* mobspawner */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "mmmmmmmmmmmmmm" + "mmmmmmmmmmmmmm" + "aammmmmmmmmmmm" + "aammmmmmmmmmmm" + "aammmmmmmmmmmm" + "mmmmmmmmmmmmmm" + "mmmmmmmmmmmmmm" + + // Level 2 + "mmmmmmmmmmmmmm" + "mmmmmmmmmmmmmm" + "aabcmmmmmmmmmm" + "aabcmmmmmmmmmm" + "aabcmmmmmmmmmm" + "mmmmmmmmmmmmmm" + "mmmmmmmmmmmmmm" + + // Level 3 + "mmmmmmmmmmmmmm" + "mmmmmmmmmmmmmm" + "aaaaabmmmmmmmm" + "aaaaabmmmmmmmm" + "aaaaabmmmmmmmm" + "mmmmmmmmmmmmmm" + "mmmmmmmmmmmmmm" + + // Level 4 + "mmmmmmmmmmmmmm" + "dddddddmmmmmmm" + "aaaaaabmmmmmmm" + "aaaaaabmmmmmmm" + "aaaaaabmmmmmmm" + "eeeeeeemmmmmmm" + "mmmmmmmmmmmmmm" + + // Level 5 + "mmmmmmmmmmmmmm" + "aaaaaaadmmmmmm" + "aaaaaaabmmmmmm" + "aaaaaaabmmmmmm" + "aaaaaaabmmmmmm" + "aaaaaaaemmmmmm" + "mmmmmmmmmmmmmm" + + // Level 6 + "mmmmmmmmmmmmmm" + "aaaaaaaabddddm" + "......faaaaabm" + "......faaaaabm" + "......faaaaabm" + "aaaaaaaaabeebm" + "mmmmmmmmmmmmmm" + + // Level 7 + "mmmmmmmmgdddbm" + "......aaaaaaad" + ".......faaaaab" + ".......faaaaab" + ".......faaaaab" + "......aaaaaaae" + "mmmmmmmmgeeebm" + + // Level 8 + "mmmmmmmmaaaaam" + "......haa...aa" + ".............a" + "..........i..a" + ".............a" + "......haa...aa" + "mmmmmmmmaaaaam" + + // Level 9 + "mmmmmmmmhhhhhm" + "......hhh...hh" + ".............h" + ".............h" + ".............h" + "......hhh...hh" + "mmmmmmmmhhhhhm", + + // Connections: + "0: 0, 5, 3: 4\n" /* Type 0, BLOCK_FACE_XM */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // BlazePlatformOverhang + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BridgeCrossing: + // The data has been exported from gallery Nether, area index 17, ID 159 + { + // Size: + 15, 8, 15, // SizeX = 15, SizeY = 8, SizeZ = 15 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:114: 7\n" /* netherbrickstairs */ + "c:114: 5\n" /* netherbrickstairs */ + "d:114: 4\n" /* netherbrickstairs */ + "e:114: 6\n" /* netherbrickstairs */ + "f: 44:14\n" /* step */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "aammmmmmmmmmmaa" + "aammmmmmmmmmmaa" + "aammmmmmmmmmmaa" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + + // Level 2 + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + "mmmmmmbbbmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "aacmmmmmmmmmdaa" + "aacmmmmmmmmmdaa" + "aacmmmmmmmmmdaa" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmeeemmmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + + // Level 3 + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + "mmmmmmbbbmmmmmm" + "mmmmmmfffmmmmmm" + "mmmmmmmmmmmmmmm" + "aaacfmmmmmfdaaa" + "aaacfmmmmmfdaaa" + "aaacfmmmmmfdaaa" + "mmmmmmmmmmmmmmm" + "mmmmmmfffmmmmmm" + "mmmmmmeeemmmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + + // Level 4 + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + "eeeeeeaaaeeeeee" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "bbbbbdaaacbbbbb" + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + + // Level 5 + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + + // Level 6 + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "aaaaaa...aaaaaa" + "..............." + "..............." + "..............." + "aaaaaa...aaaaaa" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + + // Level 7 + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "..............." + "..............." + "..............." + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + + // Level 8 + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "..............." + "..............." + "..............." + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm", + + // Connections: + "0: 0, 5, 7: 4\n" /* Type 0, BLOCK_FACE_XM */ + "0: 7, 5, 0: 2\n" /* Type 0, BLOCK_FACE_ZM */ + "0: 14, 5, 7: 5\n" /* Type 0, BLOCK_FACE_XP */ + "0: 7, 5, 14: 3\n" /* Type 0, BLOCK_FACE_ZP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // BridgeCrossing + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BridgeCrumble1: + // The data has been exported from gallery Nether, area index 19, ID 161 + { + // Size: + 9, 6, 5, // SizeX = 9, SizeY = 6, SizeZ = 5 + + // Block definitions: + ".: 19: 0\n" /* sponge */ + "a:112: 0\n" /* netherbrick */ + "b:114: 5\n" /* netherbrickstairs */ + "c: 44:14\n" /* step */ + "d:114: 6\n" /* netherbrickstairs */ + "e:114: 7\n" /* netherbrickstairs */, + + // Block data: + // Level 1 + "........." + "aa......." + "aa......." + "aa......." + "........." + + // Level 2 + "........." + "aab......" + "aab......" + "aab......" + "........." + + // Level 3 + "........." + "aaabc...." + "aaabc...." + "aaabc...." + "........." + + // Level 4 + "ddddddd.." + "aaaaaaaa." + "aaaaaaaaa" + "aaaaaaa.." + "eeeee...." + + // Level 5 + "aaaaaaaaa" + "aaaaa...." + "aaaaaa..." + "aaaaaa..." + "aaaaaaaa." + + // Level 6 + "aaaaaa..." + "........." + "........." + "........." + "aaaaaaa..", + + // Connections: + "0: 0, 5, 2: 4\n" /* Type 0, BLOCK_FACE_XM */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // BridgeCrumble1 + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BridgeCrumble2 + // The data has been exported from gallery Nether, area index 18, ID 160 + { + // Size: + 13, 6, 5, // SizeX = 13, SizeY = 6, SizeZ = 5 + + // Block definitions: + ".: 19: 0\n" /* sponge */ + "a:112: 0\n" /* netherbrick */ + "b:114: 5\n" /* netherbrickstairs */ + "c: 44:14\n" /* step */ + "d:114: 6\n" /* netherbrickstairs */ + "e:114: 7\n" /* netherbrickstairs */, + + // Block data: + // Level 1 + "............." + "aa..........." + "aa..........." + "aa..........." + "............." + + // Level 2 + "............." + "aab.........." + "aab.........." + "aab.........." + "............." + + // Level 3 + "............." + "aaabc........" + "aaabc........" + "aaabc........" + "............." + + // Level 4 + "ddddddddd...." + "aaaaaaaaaaaaa" + "aaaaaaaaa...." + "aaaaaaaaaaaa." + "eeeeeeeee...." + + // Level 5 + "aaaaaaaaaaaa." + "aaaaaaaaaa..." + "aaaaaaaaaaa.." + "aaaaaaaaa...." + "aaaaaaaaaaaaa" + + // Level 6 + "aaaaaaaaa...." + "............." + "............." + "............." + "aaaaaaaaaa...", + + // Connections: + "0: 0, 5, 2: 4\n" /* Type 0, BLOCK_FACE_XM */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // BridgeCrumble2 + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BridgeSegment: + // The data has been exported from gallery Nether, area index 16, ID 158 + { + // Size: + 15, 8, 5, // SizeX = 15, SizeY = 8, SizeZ = 5 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:114: 5\n" /* netherbrickstairs */ + "c:114: 4\n" /* netherbrickstairs */ + "d: 44:14\n" /* step */ + "e:114: 6\n" /* netherbrickstairs */ + "f:114: 7\n" /* netherbrickstairs */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "mmmmmmmmmmmmmmm" + "aammmmmmmmmmmaa" + "aammmmmmmmmmmaa" + "aammmmmmmmmmmaa" + "mmmmmmmmmmmmmmm" + + // Level 2 + "mmmmmmmmmmmmmmm" + "aabmmmmmmmmmcaa" + "aabmmmmmmmmmcaa" + "aabmmmmmmmmmcaa" + "mmmmmmmmmmmmmmm" + + // Level 3 + "mmmmmmmmmmmmmmm" + "aaabdmmmmmdcaaa" + "aaabdmmmmmdcaaa" + "aaabdmmmmmdcaaa" + "mmmmmmmmmmmmmmm" + + // Level 4 + "eeeeeeeeeeeeeee" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "fffffffffffffff" + + // Level 5 + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + + // Level 6 + "aaaaaaaaaaaaaaa" + "..............." + "..............." + "..............." + "aaaaaaaaaaaaaaa" + + // Level 7 + "mmmmmmmmmmmmmmm" + "..............." + "..............." + "..............." + "mmmmmmmmmmmmmmm" + + // Level 8 + "mmmmmmmmmmmmmmm" + "..............." + "..............." + "..............." + "mmmmmmmmmmmmmmm", + + // Connections: + "0: 0, 5, 2: 4\n" /* Type 0, BLOCK_FACE_XM */ + "0: 14, 5, 2: 5\n" /* Type 0, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // BridgeSegment + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Corridor13: + // The data has been exported from gallery Nether, area index 35, ID 286 + { + // Size: + 13, 6, 5, // SizeX = 13, SizeY = 6, SizeZ = 5 + + // Block definitions: + "a:112: 0\n" /* netherbrick */ + ".: 0: 0\n" /* air */ + "c:113: 0\n" /* netherbrickfence */ + "d:114: 2\n" /* netherbrickstairs */ + "e:114: 3\n" /* netherbrickstairs */, + + // Block data: + // Level 1 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 2 + "aaaaaaaaaaaaa" + "............." + "............." + "............." + "aaaaaaaaaaaaa" + + // Level 3 + "acacacacacaca" + "............." + "............." + "............." + "acacacacacaca" + + // Level 4 + "acacacacacaca" + "............." + "............." + "............." + "acacacacacaca" + + // Level 5 + "acacacacacaca" + "............." + "............." + "............." + "acacacacacaca" + + // Level 6 + "ddddddddddddd" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "eeeeeeeeeeeee", + + // Connections: + "1: 0, 1, 2: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 12, 1, 2: 5\n" /* Type 1, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // Corridor13 + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // CorridorStairs: + // The data has been exported from gallery Nether, area index 12, ID 42 + { + // Size: + 9, 13, 5, // SizeX = 9, SizeY = 13, SizeZ = 5 + + // Block definitions: + ".: 0: 0\n" /* 0 */ + "a:112: 0\n" /* netherbrick */ + "b:114: 0\n" /* netherbrickstairs */ + "c:113: 0\n" /* netherbrickfence */ + "d:114: 2\n" /* netherbrickstairs */ + "e:114: 3\n" /* netherbrickstairs */ + "f: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "aaaaaaaaa" + "aaaaaaaaa" + "aaaaaaaaa" + "aaaaaaaaa" + "aaaaaaaaa" + + // Level 2 + "aaaaaaaaa" + ".baaaaaaa" + ".baaaaaaa" + ".baaaaaaa" + "aaaaaaaaa" + + // Level 3 + "acaaaaaaa" + "..baaaaaa" + "..baaaaaa" + "..baaaaaa" + "acaaaaaaa" + + // Level 4 + "acaaaaaaa" + "...baaaaa" + "...baaaaa" + "...baaaaa" + "acaaaaaaa" + + // Level 5 + "acacaaaaa" + "....baaaa" + "....baaaa" + "....baaaa" + "acacaaaaa" + + // Level 6 + "aaacaaaaa" + ".....baaa" + ".....baaa" + ".....baaa" + "aaacaaaaa" + + // Level 7 + "daacacaaa" + "a.....baa" + "a.....baa" + "a.....baa" + "eaacacaaa" + + // Level 8 + "fdaaacaaa" + "fa.....ba" + "fa.....ba" + "fa.....ba" + "feaaacaaa" + + // Level 9 + "ffdaacaca" + "ffa......" + "ffa......" + "ffa......" + "ffeaacaca" + + // Level 10 + "fffdaaaca" + "fffa....." + "fffa....." + "fffa....." + "fffeaaaca" + + // Level 11 + "ffffdaaca" + "ffffa...." + "ffffa...." + "ffffa...." + "ffffeaaca" + + // Level 12 + "fffffdaaa" + "fffffa..." + "fffffa..." + "fffffa..." + "fffffeaaa" + + // Level 13 + "ffffffddd" + "ffffffaaa" + "ffffffaaa" + "ffffffaaa" + "ffffffeee", + + // Connections: + "1: 0, 1, 2: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 8, 8, 2: 5\n" /* Type 1, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // CorridorStairs } ; // g_NetherFortPrefabs1 From 283a66bcae5f26d2b5038ba0959314a687c4d8b6 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 22:51:30 +0000 Subject: [PATCH 058/145] Some fixes to lilypads * Fixed placement on lava * Fixed placement on side of blocks * Fixed placement through blocks + Added washing-away of pads + Added ice as a block that fully occupies its voxel --- src/BlockInfo.cpp | 3 +- src/Blocks/BlockLilypad.h | 66 ++----------------- src/Items/ItemHandler.cpp | 2 + src/Items/ItemLilypad.h | 106 +++++++++++++++++++++++++++++++ src/Simulator/FluidSimulator.cpp | 1 + 5 files changed, 116 insertions(+), 62 deletions(-) create mode 100644 src/Items/ItemLilypad.h diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 7d438ba3e..6fb5aa5b3 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -365,7 +365,7 @@ void cBlockInfo::Initialize(void) ms_Info[E_BLOCK_WOODEN_SLAB ].m_IsSolid = false; - // Torch placeable blocks: + // 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; @@ -397,6 +397,7 @@ void cBlockInfo::Initialize(void) 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; diff --git a/src/Blocks/BlockLilypad.h b/src/Blocks/BlockLilypad.h index 3db280d80..2dd4ec768 100644 --- a/src/Blocks/BlockLilypad.h +++ b/src/Blocks/BlockLilypad.h @@ -2,10 +2,7 @@ #pragma once #include "BlockHandler.h" -#include "../Entities/Player.h" -#include "Vector3.h" -#include "../LineBlockTracer.h" - +#include "Entities/Pickup.h" @@ -13,69 +10,16 @@ class cBlockLilypadHandler : public cBlockHandler { - typedef cBlockHandler super; - public: cBlockLilypadHandler(BLOCKTYPE a_BlockType) : cBlockHandler(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 + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - if (a_BlockFace > 0) - { - return false; - } - - class cCallbacks : - public cBlockTracer::cCallbacks - { - public: - cCallbacks(void) : - m_HasHitFluid(false) - { - } - - virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override - { - if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType)) - { - if ((a_BlockMeta != 0) || (a_EntryFace == BLOCK_FACE_NONE)) // The hit block should be a source. The FACE_NONE check is for AddFaceDir below - { - return false; - } - m_HasHitFluid = true; - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, (eBlockFace)a_EntryFace); - m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ); - return true; - } - return false; - } - - Vector3i m_Pos; - bool m_HasHitFluid; - - } Callbacks; - - cLineBlockTracer Tracer(*a_Player->GetWorld(), Callbacks); - Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector()); - Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5); - - Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z); - - if (Callbacks.m_HasHitFluid) - { - a_Player->GetWorld()->SetBlock(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z, E_BLOCK_LILY_PAD, 0); - } - - return false; + // Reset meta to zero + a_Pickups.push_back(cItem(E_BLOCK_LILY_PAD, 1, 0)); } }; diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 454fabdd7..337b3a83c 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -27,6 +27,7 @@ #include "ItemHoe.h" #include "ItemLeaves.h" #include "ItemLighter.h" +#include "ItemLilypad.h" #include "ItemMap.h" #include "ItemMinecart.h" #include "ItemNetherWart.h" @@ -115,6 +116,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_FISHING_ROD: return new cItemFishingRodHandler(a_ItemType); case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType); case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType); + case E_BLOCK_LILY_PAD: return new cItemLilypadHandler(a_ItemType); case E_ITEM_MAP: return new cItemMapHandler(); case E_ITEM_ITEM_FRAME: return new cItemItemFrameHandler(a_ItemType); case E_ITEM_NETHER_WART: return new cItemNetherWartHandler(a_ItemType); diff --git a/src/Items/ItemLilypad.h b/src/Items/ItemLilypad.h new file mode 100644 index 000000000..8496b9f31 --- /dev/null +++ b/src/Items/ItemLilypad.h @@ -0,0 +1,106 @@ + +#pragma once + +#include "ItemHandler.h" +#include "../Entities/Player.h" +#include "Vector3.h" +#include "../LineBlockTracer.h" +#include "BlockInfo.h" + + + + + +class cItemLilypadHandler : + public cItemHandler +{ + typedef cItemHandler super; + +public: + cItemLilypadHandler(BLOCKTYPE a_BlockType) + : cItemHandler(a_BlockType) + { + + } + + virtual bool IsPlaceable(void) override + { + return false; // Set as not placeable so OnItemUse is called + } + + virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override + { + if (a_BlockFace > BLOCK_FACE_NONE) + { + // Clicked on the side of a submerged block; vanilla allows placement, so should we + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LILY_PAD, 0); + if (!a_Player->IsGameModeCreative()) + a_Player->GetInventory().RemoveOneEquippedItem(); + return true; + } + + class cCallbacks : + public cBlockTracer::cCallbacks + { + public: + cCallbacks(cWorld * a_World) : + m_HasHitFluid(false), + m_World(a_World) + { + } + + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override + { + if (IsBlockWater(a_BlockType)) + { + if ((a_BlockMeta != 0) || (a_EntryFace == BLOCK_FACE_NONE)) // The hit block should be a source. The FACE_NONE check is clicking whilst submerged + { + return false; + } + a_EntryFace = BLOCK_FACE_YP; // Always place pad at top of water block + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, (eBlockFace)a_EntryFace); + BLOCKTYPE Block = m_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); + if ( + !IsBlockWater(Block) && + cBlockInfo::FullyOccupiesVoxel(Block) + ) + { + // Can't place lilypad on air/in another block! + return true; + } + m_HasHitFluid = true; + m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ); + return true; + } + return false; + } + + Vector3i m_Pos; + bool m_HasHitFluid; + cWorld * m_World; + + }; + + cCallbacks Callbacks(a_World); + cLineBlockTracer Tracer(*a_Player->GetWorld(), Callbacks); + Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector()); + Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5); + + Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z); + + if (Callbacks.m_HasHitFluid) + { + a_World->SetBlock(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z, E_BLOCK_LILY_PAD, 0); + if (!a_Player->IsGameModeCreative()) + a_Player->GetInventory().RemoveOneEquippedItem(); + return true; + } + + return false; + } +}; + + + + diff --git a/src/Simulator/FluidSimulator.cpp b/src/Simulator/FluidSimulator.cpp index 61c93ed73..7779573d7 100644 --- a/src/Simulator/FluidSimulator.cpp +++ b/src/Simulator/FluidSimulator.cpp @@ -36,6 +36,7 @@ bool cFluidSimulator::CanWashAway(BLOCKTYPE a_BlockType) case E_BLOCK_COBWEB: case E_BLOCK_CROPS: case E_BLOCK_DEAD_BUSH: + case E_BLOCK_LILY_PAD: case E_BLOCK_RAIL: case E_BLOCK_REDSTONE_TORCH_OFF: case E_BLOCK_REDSTONE_TORCH_ON: From 8ece214920cc9cbec2c04cfa046b451a2553e279 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 22:51:39 +0000 Subject: [PATCH 059/145] Fixed a potential crash --- src/Chunk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 957d7d575..ea961733f 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -884,7 +884,7 @@ void cChunk::ApplyWeatherToTop() FastSetBlock(X, Height, Z, E_BLOCK_SNOW, TopMeta - 1); } } - else if (cBlockInfo::IsSnowable(TopBlock)) + else if (cBlockInfo::IsSnowable(TopBlock) && (Height + 1 < cChunkDef::Height)) { SetBlock(X, Height + 1, Z, E_BLOCK_SNOW, 0); } From aee1f8f9d13c501a53e3636596c09dbce0f289bb Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 22:52:04 +0000 Subject: [PATCH 060/145] Fixed block interaction rate check --- src/ClientHandle.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 2c47faa65..443c248b0 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -941,6 +941,8 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e } return; } + + m_NumBlockChangeInteractionsThisTick++; if (!CheckBlockInteractionsRate()) { @@ -1053,8 +1055,8 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e cBlockSlabHandler::IsAnySlabType(EquippedBlock) && // Is the player placing another slab? ((ClickedBlockMeta & 0x07) == EquippedBlockDamage) && // Is it the same slab type? ( - (a_BlockFace == BLOCK_FACE_TOP) || // Clicking the top of a bottom slab - (a_BlockFace == BLOCK_FACE_BOTTOM) // Clicking the bottom of a top slab + (a_BlockFace == BLOCK_FACE_TOP) || // Clicking the top of a bottom slab + (a_BlockFace == BLOCK_FACE_BOTTOM) // Clicking the bottom of a top slab ) ) { From 79aa082b048ba1c4a0407d1faa8fb96a33dd4415 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 22:52:23 +0000 Subject: [PATCH 061/145] Fixed infinite minecart items --- src/Items/ItemMinecart.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Items/ItemMinecart.h b/src/Items/ItemMinecart.h index bcaa5635a..bf6f70eed 100644 --- a/src/Items/ItemMinecart.h +++ b/src/Items/ItemMinecart.h @@ -72,6 +72,9 @@ public: } } // switch (m_ItemType) Minecart->Initialize(a_World); + + if (!a_Player->IsGameModeCreative()) + a_Player->GetInventory().RemoveOneEquippedItem(); return true; } From 6eacf1aa922b9dd2193a835e6a45ddf71fbbb729 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 23:07:50 +0000 Subject: [PATCH 062/145] Fixed a minor ini key duplication bug --- src/Root.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Root.cpp b/src/Root.cpp index 3555afb45..ba4398b35 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -304,6 +304,7 @@ void cRoot::LoadWorlds(cIniFile & IniFile) { if (IniFile.GetKeyComment("Worlds", 0) != " World=secondworld") { + IniFile.DeleteKeyComment("Worlds", 0); IniFile.AddKeyComment("Worlds", " World=secondworld"); } } From 6dea7993f2a563a8b3a0746feeb2174922631526 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 23:25:11 +0000 Subject: [PATCH 063/145] Fixed #721 and FS439 --- src/Entities/Player.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 863aaa799..646aad50f 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1489,6 +1489,7 @@ bool cPlayer::MoveToWorld(const char * a_WorldName) // Add player to all the necessary parts of the new world SetWorld(World); + m_ClientHandle->StreamChunks(); World->AddEntity(this); World->AddPlayer(this); From 519bd0b989fb931fd0925bad6a5cb1a9e223d85f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 23:51:52 +0000 Subject: [PATCH 064/145] Curly brackets --- src/Items/ItemLilypad.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Items/ItemLilypad.h b/src/Items/ItemLilypad.h index 8496b9f31..5a29abe94 100644 --- a/src/Items/ItemLilypad.h +++ b/src/Items/ItemLilypad.h @@ -1,4 +1,3 @@ - #pragma once #include "ItemHandler.h" @@ -36,7 +35,9 @@ public: AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LILY_PAD, 0); if (!a_Player->IsGameModeCreative()) + { a_Player->GetInventory().RemoveOneEquippedItem(); + } return true; } @@ -93,7 +94,9 @@ public: { a_World->SetBlock(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z, E_BLOCK_LILY_PAD, 0); if (!a_Player->IsGameModeCreative()) + { a_Player->GetInventory().RemoveOneEquippedItem(); + } return true; } From fb16554322e3995f065135b481fffd58a5b2551e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 29 Mar 2014 01:21:56 +0000 Subject: [PATCH 065/145] Fixed players not updating after world change Addendum to 6dea7993f2a563a8b3a0746feeb2174922631526 --- src/ClientHandle.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 46c10ae82..eb05ebdb7 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1606,10 +1606,8 @@ void cClientHandle::MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket) m_Protocol->SendUnloadChunk(itr->m_ChunkX, itr->m_ChunkZ); } // for itr - Chunks[] - // Do NOT stream new chunks, the new world runs its own tick thread and may deadlock - // Instead, the chunks will be streamed when the client is moved to the new world's Tick list, - // by setting state to csAuthenticated - m_State = csAuthenticated; + // StreamChunks() called in cPlayer::MoveToWorld() after new world has been set + // Meanwhile here, we set last streamed values to bogus ones so everything is resent m_LastStreamedChunkX = 0x7fffffff; m_LastStreamedChunkZ = 0x7fffffff; m_HasSentPlayerChunk = false; From aefabfcafa1103b0bea80b40508748635def67a0 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 29 Mar 2014 10:25:40 +0000 Subject: [PATCH 066/145] Removed leftover clienthandle code --- src/ClientHandle.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 443c248b0..27c6b1226 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -933,7 +933,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType); BlockHandler->OnCancelRightClick(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - if (a_BlockFace != BLOCK_FACE_NONE) + if (a_BlockFace > BLOCK_FACE_NONE) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); @@ -962,7 +962,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e ); // Let's send the current world block to the client, so that it can immediately "let the user know" that they haven't placed the block - if (a_BlockFace > -1) + if (a_BlockFace > BLOCK_FACE_NONE) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); @@ -990,7 +990,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemType); - if (ItemHandler->IsPlaceable() && ((a_BlockFace > -1) || (Equipped.m_ItemType == E_BLOCK_LILY_PAD))) + if (ItemHandler->IsPlaceable() && (a_BlockFace > BLOCK_FACE_NONE)) { HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); } @@ -1029,7 +1029,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler) { BLOCKTYPE EquippedBlock = (BLOCKTYPE)(m_Player->GetEquippedItem().m_ItemType); - if ((a_BlockFace < 0) && (EquippedBlock != E_BLOCK_LILY_PAD)) + if (a_BlockFace < 0) { // Clicked in air return; @@ -1087,10 +1087,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e } else { - if (EquippedBlock != E_BLOCK_LILY_PAD) - { - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - } + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) { @@ -1111,7 +1108,6 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e else { if ( - (EquippedBlock != E_BLOCK_LILY_PAD) && !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision() && !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(m_Player, PlaceMeta) ) @@ -1144,7 +1140,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e // The actual block placement: World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta); - if (m_Player->GetGameMode() != gmCreative) + if (!m_Player->IsGameModeCreative()) { m_Player->GetInventory().RemoveOneEquippedItem(); } From 0f6688fe9e2df97a6979be452efa789245acfadb Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 12:24:26 +0100 Subject: [PATCH 067/145] Updated the android files --- Android/jni/Android.mk | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Android/jni/Android.mk b/Android/jni/Android.mk index 3542e588b..ce142d446 100644 --- a/Android/jni/Android.mk +++ b/Android/jni/Android.mk @@ -5,7 +5,7 @@ LOCAL_MODULE := mcserver -LOCAL_SRC_FILES := $(shell find ../CryptoPP ../lua ../jsoncpp ../zlib ../src ../tolua++ ../iniFile ../expat ../md5 ../sqlite ../luaexpat '(' -name '*.cpp' -o -name '*.c' ')') +LOCAL_SRC_FILES := $(shell find ../lib/polarssl ../lib/lua ../lib/jsoncpp ../lib/zlib ../src ../lib/tolua++ ../lib/iniFile ../lib/expat ../lib/md5 ../lib/sqlite ../lib/luaexpat '(' -name '*.cpp' -o -name '*.c' ')') LOCAL_SRC_FILES := $(filter-out %SquirrelFunctions.cpp %SquirrelBindings.cpp %cPlugin_Squirrel.cpp %cSquirrelCommandBinder.cpp %minigzip.c %lua.c %tolua.c %toluabind.c %LeakFinder.cpp %StackWalker.cpp %example.c,$(LOCAL_SRC_FILES)) LOCAL_SRC_FILES := $(patsubst %.cpp,../%.cpp,$(LOCAL_SRC_FILES)) LOCAL_SRC_FILES := $(patsubst %.c,../%.c,$(LOCAL_SRC_FILES)) @@ -24,17 +24,17 @@ LOCAL_C_INCLUDES := ../src \ ../src/packets \ ../src/items \ ../src/blocks \ - ../tolua++/src/lib \ - ../lua/src \ - ../zlib-1.2.7 \ - ../iniFile \ - ../tolua++/include \ - ../jsoncpp/include \ - ../jsoncpp/src/lib_json \ - ../expat/ \ - ../md5/ \ - ../sqlite/ \ - ../luaexpat/ \ + ../lib/tolua++/src/lib \ + ../lib/lua/src \ + ../lib/zlib-1.2.7 \ + ../lib/iniFile \ + ../lib/tolua++/include \ + ../lib/jsoncpp/include \ + ../lib/jsoncpp/src/lib_json \ + ../lib/expat/ \ + ../lib/md5/ \ + ../lib/sqlite/ \ + ../lib/luaexpat/ \ .. \ From 736c7950a2b56d2f5296b4cc3695857dced65d51 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 29 Mar 2014 13:11:49 +0100 Subject: [PATCH 068/145] Add "a_RelY < cChunkDef::Height" to BlockBigFlower --- src/Blocks/BlockBigFlower.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h index 194a79a67..98d6502ab 100644 --- a/src/Blocks/BlockBigFlower.h +++ b/src/Blocks/BlockBigFlower.h @@ -84,6 +84,7 @@ public: return ( a_RelY > 0 && a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR + && a_RelY < cChunkDef::Height ); } From 515e4bdb13de8fc749fb3f0910beb18974895d6c Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 29 Mar 2014 13:18:26 +0000 Subject: [PATCH 069/145] Compare for inequality in FACE_NONE checks --- src/ClientHandle.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 27c6b1226..37672b7f0 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -933,7 +933,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType); BlockHandler->OnCancelRightClick(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - if (a_BlockFace > BLOCK_FACE_NONE) + if (a_BlockFace != BLOCK_FACE_NONE) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); @@ -962,7 +962,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e ); // Let's send the current world block to the client, so that it can immediately "let the user know" that they haven't placed the block - if (a_BlockFace > BLOCK_FACE_NONE) + if (a_BlockFace != BLOCK_FACE_NONE) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); @@ -990,7 +990,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemType); - if (ItemHandler->IsPlaceable() && (a_BlockFace > BLOCK_FACE_NONE)) + if (ItemHandler->IsPlaceable() && (a_BlockFace != BLOCK_FACE_NONE)) { HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); } From 4492bd58f1dc93e5c5d6c1b9ff64d7ed44accee3 Mon Sep 17 00:00:00 2001 From: narroo Date: Sat, 29 Mar 2014 10:00:44 -0400 Subject: [PATCH 070/145] Added in MetaMirrorXY and MetaMirrorYZ to cBlockSignHandler. --- src/Blocks/BlockSign.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Blocks/BlockSign.h b/src/Blocks/BlockSign.h index 24346b930..6c0becfd6 100644 --- a/src/Blocks/BlockSign.h +++ b/src/Blocks/BlockSign.h @@ -83,6 +83,25 @@ public: { return (--a_Meta) & 0x0F; } + + virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override + { + // Mirrors signs over the XY plane (North-South Mirroring) + + // 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; + } + + + virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override + { + // Mirrors signs over the YZ plane (East-West Mirroring) + + // There are 16 meta values which correspond to different directions. + // These values are equated to angles on a circle; 0x10 = 360 degrees. + return 0x10 - a_Meta; + } } ; From 339d55511127981335193d07037719a4b26c4600 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 15:26:41 +0100 Subject: [PATCH 071/145] Added HOOK_PROJECTILE_HIT_ENTITY --- src/Bindings/Plugin.h | 1 + src/Bindings/PluginLua.cpp | 20 ++++++++++++++++++++ src/Bindings/PluginLua.h | 1 + src/Bindings/PluginManager.cpp | 21 +++++++++++++++++++++ src/Bindings/PluginManager.h | 5 +++++ src/Entities/ProjectileEntity.cpp | 6 ++++++ 6 files changed, 54 insertions(+) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 057fa0304..75b04d12f 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -90,6 +90,7 @@ public: virtual bool OnPluginsLoaded (void) = 0; virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; + virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) = 0; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) = 0; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 4f0e13f12..d4e4b3ee8 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1108,6 +1108,26 @@ bool cPluginLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a +bool cPluginLua::OnProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity & a_HitEntity) +{ + cCSLock Lock(m_CriticalSection); + bool res = false; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PROJECTILE_HIT_ENTITY]; + for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) + { + m_LuaState.Call((int)(**itr), &a_Projectile, &a_HitEntity, cLuaState::Return, res); + if (res) + { + return true; + } + } + return false; +} + + + + + bool cPluginLua::OnSpawnedEntity(cWorld & a_World, cEntity & a_Entity) { cCSLock Lock(m_CriticalSection); diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index f51056186..1533b1a66 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -113,6 +113,7 @@ public: virtual bool OnPluginsLoaded (void) override; virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) override; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) override; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 7d346c522..aa2c09a3d 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1154,6 +1154,27 @@ bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCrafti +bool cPluginManager::CallHookProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity & a_HitEntity) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_PROJECTILE_HIT_ENTITY); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnProjectileHitEntity(a_Projectile, a_HitEntity)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookSpawnedEntity(cWorld & a_World, cEntity & a_Entity) { HookMap::iterator Plugins = m_Hooks.find(HOOK_SPAWNED_ENTITY); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 7895be959..c5071ee83 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -18,6 +18,9 @@ class cChunkDesc; // fwd: Entities/Entity.h class cEntity; +// fwd: Entities/ProjectileEntity.h +class cProjectileEntity; + // fwd: Mobs/Monster.h class cMonster; @@ -102,6 +105,7 @@ public: // tolua_export HOOK_PLUGINS_LOADED, HOOK_POST_CRAFTING, HOOK_PRE_CRAFTING, + HOOK_PROJECTILE_HIT_ENTITY, HOOK_SPAWNED_ENTITY, HOOK_SPAWNED_MONSTER, HOOK_SPAWNING_ENTITY, @@ -201,6 +205,7 @@ public: // tolua_export bool CallHookPluginsLoaded (void); bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); + bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity); bool CallHookSpawnedEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawnedMonster (cWorld & a_World, cMonster & a_Monster); bool CallHookSpawningEntity (cWorld & a_World, cEntity & a_Entity); diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index f4ab825f2..bc359e1da 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -4,6 +4,7 @@ // Implements the cProjectileEntity class representing the common base class for projectiles, as well as individual projectile types #include "Globals.h" +#include "../Bindings/PluginManager.h" #include "ProjectileEntity.h" #include "../ClientHandle.h" #include "Player.h" @@ -148,6 +149,11 @@ public: // TODO: Some entities don't interact with the projectiles (pickups, falling blocks) // TODO: Allow plugins to interfere about which entities can be hit + if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, *a_Entity)) + { + // A plugin disagreed. + return false; + } if (LineCoeff < m_MinCoeff) { From a6ef40cb6efa1b8da549c81c7e1137d523240c17 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 15:43:03 +0100 Subject: [PATCH 072/145] Fixed error when the hook gets called. --- src/Bindings/LuaState.cpp | 12 ++++++++++++ src/Bindings/LuaState.h | 2 ++ src/Entities/ProjectileEntity.cpp | 1 - 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 47380b8a7..13eb17f7d 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -479,6 +479,18 @@ void cLuaState::Push(cEntity * a_Entity) +void cLuaState::Push(cProjectileEntity * a_ProjectileEntity) +{ + ASSERT(IsValid()); + + tolua_pushusertype(m_LuaState, a_ProjectileEntity, "cProjectileEntity"); + m_NumCurrentFunctionArgs += 1; +} + + + + + void cLuaState::Push(cMonster * a_Monster) { ASSERT(IsValid()); diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index f0047b362..b9ca2f29b 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -38,6 +38,7 @@ extern "C" class cWorld; class cPlayer; class cEntity; +class cProjectileEntity; class cMonster; class cItem; class cItems; @@ -183,6 +184,7 @@ public: void Push(cPlayer * a_Player); void Push(const cPlayer * a_Player); void Push(cEntity * a_Entity); + void Push(cProjectileEntity * a_ProjectileEntity); void Push(cMonster * a_Monster); void Push(cItem * a_Item); void Push(cItems * a_Items); diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index bc359e1da..07cb34f35 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -148,7 +148,6 @@ public: } // TODO: Some entities don't interact with the projectiles (pickups, falling blocks) - // TODO: Allow plugins to interfere about which entities can be hit if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, *a_Entity)) { // A plugin disagreed. From ec4638a228edcf4c745088838e972ea07edc7cba Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 16:00:45 +0100 Subject: [PATCH 073/145] Added HOOK_PROJECTILE_HIT_BLOCK. --- src/Bindings/Plugin.h | 1 + src/Bindings/PluginLua.cpp | 20 ++++++++++++++++++++ src/Bindings/PluginLua.h | 1 + src/Bindings/PluginManager.cpp | 21 +++++++++++++++++++++ src/Bindings/PluginManager.h | 2 ++ src/Entities/ProjectileEntity.cpp | 5 +++++ 6 files changed, 50 insertions(+) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 75b04d12f..df0bd4dcc 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -90,6 +90,7 @@ public: virtual bool OnPluginsLoaded (void) = 0; virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; + virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile) = 0; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) = 0; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index d4e4b3ee8..7e69e0f4b 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1108,6 +1108,26 @@ bool cPluginLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a +bool cPluginLua::OnProjectileHitBlock(cProjectileEntity & a_Projectile) +{ + cCSLock Lock(m_CriticalSection); + bool res = false; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PROJECTILE_HIT_BLOCK]; + for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) + { + m_LuaState.Call((int)(**itr), &a_Projectile, cLuaState::Return, res); + if (res) + { + return true; + } + } + return false; +} + + + + + bool cPluginLua::OnProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity & a_HitEntity) { cCSLock Lock(m_CriticalSection); diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 1533b1a66..59542d23a 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -113,6 +113,7 @@ public: virtual bool OnPluginsLoaded (void) override; virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile) override; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) override; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index aa2c09a3d..6a5356c0b 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1154,6 +1154,27 @@ bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCrafti +bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_PROJECTILE_HIT_BLOCK); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnProjectileHitBlock(a_Projectile)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity & a_HitEntity) { HookMap::iterator Plugins = m_Hooks.find(HOOK_PROJECTILE_HIT_ENTITY); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index c5071ee83..512bc1351 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -105,6 +105,7 @@ public: // tolua_export HOOK_PLUGINS_LOADED, HOOK_POST_CRAFTING, HOOK_PRE_CRAFTING, + HOOK_PROJECTILE_HIT_BLOCK, HOOK_PROJECTILE_HIT_ENTITY, HOOK_SPAWNED_ENTITY, HOOK_SPAWNED_MONSTER, @@ -205,6 +206,7 @@ public: // tolua_export bool CallHookPluginsLoaded (void); bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); + bool CallHookProjectileHitBlock (cProjectileEntity & a_Projectile); bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity); bool CallHookSpawnedEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawnedMonster (cWorld & a_World, cMonster & a_Monster); diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index 07cb34f35..b724c9c55 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -67,6 +67,11 @@ protected: eBlockFace Face; if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face)) { + if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile)) + { + return true; + } + Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff; m_Projectile->OnHitSolidBlock(Intersection, Face); return true; From 379d403443e5ecf3e66cf151391f5a8c4bd4d5c6 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 16:08:39 +0100 Subject: [PATCH 074/145] Documented both hooks. --- .../APIDump/Hooks/OnProjectileHitBlock.lua | 24 ++++++++++++++++++ .../APIDump/Hooks/OnProjectileHitEntity.lua | 25 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua create mode 100644 MCServer/Plugins/APIDump/Hooks/OnProjectileHitEntity.lua diff --git a/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua new file mode 100644 index 000000000..1588d420c --- /dev/null +++ b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua @@ -0,0 +1,24 @@ +return +{ + HOOK_PROJECTILE_HIT_BLOCK = + { + CalledWhen = "A projectile hits a solid block.", + DefaultFnName = "OnProjectileHitBlock", -- also used as pagename + Desc = [[ + This hook is called when a {{cProjectileEntity|projectile}} hits a solid block.. + ]], + Params = + { + { Name = "ProjectileEntity", Type = "{{cProjectileEntity}}", Notes = "The projectile that hit an entity." }, + }, + Returns = [[ + If the function returns false or no value, the next plugin's callback is called. If the function + returns true, no other callback is called for this event and the projectile flies through block.. + ]], + }, -- HOOK_PROJECTILE_HIT_BLOCK +} + + + + + diff --git a/MCServer/Plugins/APIDump/Hooks/OnProjectileHitEntity.lua b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitEntity.lua new file mode 100644 index 000000000..dd949fb46 --- /dev/null +++ b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitEntity.lua @@ -0,0 +1,25 @@ +return +{ + HOOK_PROJECTILE_HIT_ENTITY = + { + CalledWhen = "A projectile hits another entity.", + DefaultFnName = "OnProjectileHitEntity", -- also used as pagename + Desc = [[ + This hook is called when a {{cProjectileEntity|projectile}} hits another entity. + ]], + Params = + { + { Name = "ProjectileEntity", Type = "{{cProjectileEntity}}", Notes = "The projectile that hit an entity." }, + { Name = "Entity", Type = "{{cEntity}}", Notes = "The entity wich was hit." }, + }, + Returns = [[ + If the function returns false or no value, the next plugin's callback is called. If the function + returns true, no other callback is called for this event and the projectile flies through the entity. + ]], + }, -- HOOK_PROJECTILE_HIT_ENTITY +} + + + + + From 98a12127ceaa0834bfea66fa6f9e381b1f8f4357 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 17:05:24 +0100 Subject: [PATCH 075/145] Fixed the OnProjectileHitBlock hook not stopping projectiles. --- src/Entities/ProjectileEntity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index b724c9c55..a9735a53c 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -69,7 +69,7 @@ protected: { if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile)) { - return true; + return false; } Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff; From 782c111b815b3a49a340e1f1133e1c15ac76e551 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 29 Mar 2014 22:29:34 +0100 Subject: [PATCH 076/145] Renamed lua dll for tolua++.exe. Fixes #843. --- src/Bindings/{lua5.1.dll => lua51.dll} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Bindings/{lua5.1.dll => lua51.dll} (100%) diff --git a/src/Bindings/lua5.1.dll b/src/Bindings/lua51.dll similarity index 100% rename from src/Bindings/lua5.1.dll rename to src/Bindings/lua51.dll From d64d9145d1d84caaf21a906d5924c3855988fa33 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 29 Mar 2014 22:56:16 +0100 Subject: [PATCH 077/145] cPrefab now uses a struct for block type definition in CharMap. As suggested by worktycho in 7b585290fccd3dc074b1f9feef0af754ab3dd632, instead of packing the two values into a single int, they're packed into a struct. Also added a test code for the prefab parsing in SELF_TEST. --- src/Generating/Prefab.cpp | 103 ++++++++++++++++++++++++++++++++++---- src/Generating/Prefab.h | 9 +++- 2 files changed, 102 insertions(+), 10 deletions(-) diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index 1af1faec1..a9e0a839d 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -15,6 +15,92 @@ uses a prefabricate in a cBlockArea for drawing itself. +#ifdef SELF_TEST + +// Create one static prefab to test the parser: +static const cPrefab::sDef g_TestPrefabDef = +{ + // Size: + 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7 + + // Block definitions: + ".: 0: 0\n" /* 0 */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */, + + // Block data: + // Level 1 + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + + // Level 2 + "aa...aa" + "a.....a" + "......." + "......." + "......." + "a.....a" + "aa...aa" + + // Level 3 + "aa...aa" + "a.....a" + "......." + "......." + "......." + "a.....a" + "aa...aa" + + // Level 4 + "aa...aa" + "a.....a" + "......." + "......." + "......." + "a.....a" + "aa...aa" + + // Level 5 + "aabbbaa" + "a.....a" + "b.....b" + "b.....b" + "b.....b" + "a.....a" + "aabbbaa" + + // Level 6 + "aaaaaaa" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "aaaaaaa", + + // Connections: + "0: 0, 3, 2: 4\n" + "0: 2, 3, 0: 2\n", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msImprint +}; + +static cPrefab g_TestPrefab(g_TestPrefabDef); +#endif + + + + + cPrefab::cPrefab(const cPrefab::sDef & a_Def) : m_Size(a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), m_HitBox(0, 0, 0, a_Def.m_SizeX - 1, a_Def.m_SizeY - 1, a_Def.m_SizeZ - 1), @@ -89,7 +175,8 @@ void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) // Initialize the charmap to all-invalid values: for (size_t i = 0; i < ARRAYCOUNT(a_CharMapOut); i++) { - a_CharMapOut[i] = -1; + a_CharMapOut[i].m_BlockType = 0; + a_CharMapOut[i].m_BlockMeta = 16; // Mark unassigned entries with a meta that is impossible otherwise } // Process the lines in the definition: @@ -104,15 +191,15 @@ void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) continue; } unsigned char Src = (unsigned char)CharDef[0][0]; - BLOCKTYPE BlockType = (BLOCKTYPE)atoi(CharDef[1].c_str()); + ASSERT(a_CharMapOut[Src].m_BlockMeta == 16); // This letter has not been assigned yet? + a_CharMapOut[Src].m_BlockType = (BLOCKTYPE)atoi(CharDef[1].c_str()); NIBBLETYPE BlockMeta = 0; if ((NumElements >= 3) && !CharDef[2].empty()) { BlockMeta = (NIBBLETYPE)atoi(CharDef[2].c_str()); ASSERT((BlockMeta >= 0) && (BlockMeta <= 15)); } - ASSERT(a_CharMapOut[Src] == -1); // Any duplicates letter-wise? - a_CharMapOut[Src] = (BlockType << 4) | BlockMeta; + a_CharMapOut[Src].m_BlockMeta = BlockMeta; } // for itr - Lines[] } @@ -130,11 +217,9 @@ void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockIma const unsigned char * BlockImage = (const unsigned char *)a_BlockImage + y * m_Size.x * m_Size.z + z * m_Size.x; for (int x = 0; x < m_Size.x; x++) { - int MappedValue = a_CharMap[BlockImage[x]]; - ASSERT(MappedValue != -1); // Using a letter not defined in the CharMap? - BLOCKTYPE BlockType = MappedValue >> 4; - NIBBLETYPE BlockMeta = MappedValue & 0x0f; - m_BlockArea[0].SetRelBlockTypeMeta(x, y, z, BlockType, BlockMeta); + const sBlockTypeDef & MappedValue = a_CharMap[BlockImage[x]]; + ASSERT(MappedValue.m_BlockMeta != 16); // Using a letter not defined in the CharMap? + m_BlockArea[0].SetRelBlockTypeMeta(x, y, z, MappedValue.m_BlockType, MappedValue.m_BlockMeta); } } } diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index 0b254c03b..04c4f09da 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -53,8 +53,15 @@ public: bool HasConnectorType(int a_ConnectorType) const; protected: + /** Packs complete definition of a single block, for per-letter assignment. */ + struct sBlockTypeDef + { + BLOCKTYPE m_BlockType; + NIBBLETYPE m_BlockMeta; + }; + /** Maps letters in the sDef::m_Image onto a number, BlockType * 16 | BlockMeta */ - typedef int CharMap[256]; + typedef sBlockTypeDef CharMap[256]; /** The cBlockArea that contains the block definitions for the prefab. From 597bdd9f8010c455c1c4ce83dc2ed5e227666a1c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 00:12:19 +0100 Subject: [PATCH 078/145] NetherForts have a minimum number of pieces. The fort will generate a different image if it has less than the minimum; the max depth affects the minimum number of pieces. --- src/Generating/NetherFortGen.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Generating/NetherFortGen.cpp b/src/Generating/NetherFortGen.cpp index d111c7cee..09c992e22 100644 --- a/src/Generating/NetherFortGen.cpp +++ b/src/Generating/NetherFortGen.cpp @@ -41,8 +41,11 @@ public: int BlockY = 64; // Generate pieces: - cBFSPieceGenerator pg(m_ParentGen, a_Seed); - pg.PlacePieces(a_BlockX, BlockY, a_BlockZ, a_MaxDepth, m_Pieces); + for (int i = 0; m_Pieces.size() < (size_t)(a_MaxDepth * a_MaxDepth / 16 + a_MaxDepth); i++) + { + cBFSPieceGenerator pg(m_ParentGen, a_Seed + 1); + pg.PlacePieces(a_BlockX, BlockY, a_BlockZ, a_MaxDepth, m_Pieces); + } } From 475fc4b1ab76955dc1e3625e75549dc86f0ca860 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 00:12:54 +0100 Subject: [PATCH 079/145] Fixed chest rotator. --- src/Blocks/BlockChest.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h index 30588d8fc..7abf01301 100644 --- a/src/Blocks/BlockChest.h +++ b/src/Blocks/BlockChest.h @@ -11,11 +11,11 @@ class cBlockChestHandler : - public cMetaRotater + public cMetaRotater { public: cBlockChestHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } From 6b29edc1582940a08c0d28822a4ea4c95c55d2e0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 00:20:06 +0100 Subject: [PATCH 080/145] Re-fixed nether fort piece count check. --- src/Generating/NetherFortGen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Generating/NetherFortGen.cpp b/src/Generating/NetherFortGen.cpp index 09c992e22..02779a8a3 100644 --- a/src/Generating/NetherFortGen.cpp +++ b/src/Generating/NetherFortGen.cpp @@ -41,9 +41,9 @@ public: int BlockY = 64; // Generate pieces: - for (int i = 0; m_Pieces.size() < (size_t)(a_MaxDepth * a_MaxDepth / 16 + a_MaxDepth); i++) + for (int i = 0; m_Pieces.size() < (size_t)(a_MaxDepth * a_MaxDepth / 8 + a_MaxDepth); i++) { - cBFSPieceGenerator pg(m_ParentGen, a_Seed + 1); + cBFSPieceGenerator pg(m_ParentGen, a_Seed + i); pg.PlacePieces(a_BlockX, BlockY, a_BlockZ, a_MaxDepth, m_Pieces); } } From 3eb531a8c81fa4df014dc32b1aba42508910b481 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 00:20:28 +0100 Subject: [PATCH 081/145] Added asserts for critical data in cPrefab. --- src/Generating/Prefab.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index a9e0a839d..131b6acb2 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -172,6 +172,8 @@ bool cPrefab::HasConnectorType(int a_ConnectorType) const void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) { + ASSERT(a_CharMapDef != NULL); + // Initialize the charmap to all-invalid values: for (size_t i = 0; i < ARRAYCOUNT(a_CharMapOut); i++) { @@ -231,6 +233,8 @@ void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockIma void cPrefab::ParseConnectors(const char * a_ConnectorsDef) { + ASSERT(a_ConnectorsDef != NULL); + AStringVector Lines = StringSplitAndTrim(a_ConnectorsDef, "\n"); for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) { From ceabb372f083c9f45ab1c05154c780c5092961ec Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 00:33:59 +0100 Subject: [PATCH 082/145] Added all current NetherFort prefabs. --- src/Generating/Prefabs/NetherFortPrefabs.cpp | 1550 +++++++++++++++++- 1 file changed, 1547 insertions(+), 3 deletions(-) diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp index 24bde1baf..5e8685e32 100644 --- a/src/Generating/Prefabs/NetherFortPrefabs.cpp +++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp @@ -353,7 +353,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = 14, 9, 7, // SizeX = 14, SizeY = 9, SizeZ = 7 // Block definitions: - ".: 0: 0\n" /* 0 */ + ".: 0: 0\n" /* air */ "a:112: 0\n" /* netherbrick */ "b:114: 5\n" /* netherbrickstairs */ "c: 44:14\n" /* step */ @@ -850,6 +850,200 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = }, // BridgeSegment + // BridgeTee: + // The data has been exported from gallery Nether, area index 39, ID 290 + { + // Size: + 15, 8, 10, // SizeX = 15, SizeY = 8, SizeZ = 10 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:114: 5\n" /* netherbrickstairs */ + "c:114: 4\n" /* netherbrickstairs */ + "d:114: 6\n" /* netherbrickstairs */ + "e: 44:14\n" /* step */ + "f:114: 7\n" /* netherbrickstairs */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "mmmmmmmmmmmmmmm" + "aammmmmmmmmmmaa" + "aammmmmmmmmmmaa" + "aammmmmmmmmmmaa" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + + // Level 2 + "mmmmmmmmmmmmmmm" + "aabmmmmmmmmmcaa" + "aabmmmmmmmmmcaa" + "aabmmmmmmmmmcaa" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmdddmmmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + + // Level 3 + "mmmmmmmmmmmmmmm" + "aaabemmmmmecaaa" + "aaabemmmmmecaaa" + "aaabemmmmmecaaa" + "mmmmmmmmmmmmmmm" + "mmmmmmeeemmmmmm" + "mmmmmmdddmmmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + + // Level 4 + "ddddddddddddddd" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "fffffcaaabfffff" + "mmmmmcaaabmmmmm" + "mmmmmcaaabmmmmm" + "mmmmmcaaabmmmmm" + "mmmmmcaaabmmmmm" + "mmmmmcaaabmmmmm" + + // Level 5 + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + + // Level 6 + "aaaaaaaaaaaaaaa" + "..............." + "..............." + "..............." + "aaaaaa...aaaaaa" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + + // Level 7 + "mmmmmmmmmmmmmmm" + "..............." + "..............." + "..............." + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + + // Level 8 + "mmmmmmmmmmmmmmm" + "..............." + "..............." + "..............." + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm", + + // Connections: + "0: 0, 5, 2: 4\n" /* Type 0, BLOCK_FACE_XM */ + "0: 14, 5, 2: 5\n" /* Type 0, BLOCK_FACE_XP */ + "0: 7, 5, 9: 3\n" /* Type 0, BLOCK_FACE_ZP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // BridgeTee + + + // Corridor11: + // The data has been exported from gallery Nether, area index 36, ID 287 + { + // Size: + 11, 6, 5, // SizeX = 11, SizeY = 6, SizeZ = 5 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "c:114: 2\n" /* netherbrickstairs */ + "d:114: 3\n" /* netherbrickstairs */, + + // Block data: + // Level 1 + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + + // Level 2 + "aaaaaaaaaaa" + "..........." + "..........." + "..........." + "aaaaaaaaaaa" + + // Level 3 + "abababababa" + "..........." + "..........." + "..........." + "abababababa" + + // Level 4 + "abababababa" + "..........." + "..........." + "..........." + "abababababa" + + // Level 5 + "abababababa" + "..........." + "..........." + "..........." + "abababababa" + + // Level 6 + "ccccccccccc" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "ddddddddddd", + + // Connections: + "1: 0, 1, 2: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 10, 1, 2: 5\n" /* Type 1, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // Corridor11 + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Corridor13: // The data has been exported from gallery Nether, area index 35, ID 286 @@ -919,6 +1113,221 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = }, // Corridor13 + // CorridorCorner5: + // The data has been exported from gallery Nether, area index 10, ID 40 + { + // Size: + 11, 6, 11, // SizeX = 11, SizeY = 6, SizeZ = 11 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "c:114: 2\n" /* netherbrickstairs */ + "d:114: 0\n" /* netherbrickstairs */ + "e:114: 3\n" /* netherbrickstairs */ + "f:114: 1\n" /* netherbrickstairs */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + + // Level 2 + "aaaaaaaaaaa" + "a.........." + "a.........." + "a.........." + "a...aaaaaaa" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + + // Level 3 + "abababababa" + "b.........." + "a.........." + "b.........." + "a...abababa" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + + // Level 4 + "abababababa" + "b.........." + "a.........." + "b.........." + "a...abababa" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + + // Level 5 + "abababababa" + "b.........." + "a.........." + "b.........." + "a...abababa" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + + // Level 6 + "ccccccccccc" + "daaaaaaaaaa" + "daaaaaaaaaa" + "daaaaaaaaaa" + "daaaeeeeeee" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm", + + // Connections: + "1: 10, 1, 2: 5\n" /* Type 1, BLOCK_FACE_XP */ + "1: 2, 1, 10: 3\n" /* Type 1, BLOCK_FACE_ZP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // CorridorCorner5 + + + // CorridorCorner5: + // The data has been exported from gallery Nether, area index 10, ID 40 + { + // Size: + 11, 6, 11, // SizeX = 11, SizeY = 6, SizeZ = 11 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "c:114: 2\n" /* netherbrickstairs */ + "d:114: 0\n" /* netherbrickstairs */ + "e:114: 3\n" /* netherbrickstairs */ + "f:114: 1\n" /* netherbrickstairs */ + "g: 54: 5\n" /* chest */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + + // Level 2 + "aaaaaaaaaaa" + "ag........." + "a.........." + "a.........." + "a...aaaaaaa" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + + // Level 3 + "abababababa" + "b.........." + "a.........." + "b.........." + "a...abababa" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + + // Level 4 + "abababababa" + "b.........." + "a.........." + "b.........." + "a...abababa" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + + // Level 5 + "abababababa" + "b.........." + "a.........." + "b.........." + "a...abababa" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + + // Level 6 + "ccccccccccc" + "daaaaaaaaaa" + "daaaaaaaaaa" + "daaaaaaaaaa" + "daaaeeeeeee" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm", + + // Connections: + "1: 10, 1, 2: 5\n" /* Type 1, BLOCK_FACE_XP */ + "1: 2, 1, 10: 3\n" /* Type 1, BLOCK_FACE_ZP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // CorridorCorner5Chest + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CorridorStairs: // The data has been exported from gallery Nether, area index 12, ID 42 @@ -927,7 +1336,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = 9, 13, 5, // SizeX = 9, SizeY = 13, SizeZ = 5 // Block definitions: - ".: 0: 0\n" /* 0 */ + ".: 0: 0\n" /* air */ "a:112: 0\n" /* netherbrick */ "b:114: 0\n" /* netherbrickstairs */ "c:113: 0\n" /* netherbrickfence */ @@ -1037,6 +1446,1141 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // Merge strategy: cBlockArea::msSpongePrint, }, // CorridorStairs + + + // LavaStaircase: + // The data has been exported from gallery Nether, area index 28, ID 278 + { + // Size: + 15, 11, 15, // SizeX = 15, SizeY = 11, SizeZ = 15 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "c: 11: 0\n" /* lava */, + + // Block data: + // Level 1 + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + + // Level 2 + "aaaaaaaa...aaaa" + "aaaaa.........a" + "aaaaa.........a" + "aaaaab........a" + "accca...aaaa..a" + "accca...acca..a" + "acccaaaaacca..a" + "acccccccccca..a" + "acccaaaaacca..a" + "accca...acca..a" + "accca...aaaa..a" + "aaaaab........a" + "aaaaa.........a" + "aaaaa.........a" + "aaaaaaaa...aaaa" + + // Level 3 + "aaaaaaaa...aaaa" + "aaaa..........a" + "aaaa..........a" + "aaaabb........a" + "aaaa..........a" + "a.............a" + "a.............a" + "a.............a" + "a.............a" + "a.............a" + "aaaa..........a" + "aaaabb........a" + "aaaa..........a" + "aaaa..........a" + "aaaaaaaa...aaaa" + + // Level 4 + "aaaaaaaa...aaaa" + "a.............a" + "a.............a" + "a..bb.........a" + "aaaa..........a" + "aaaa..........a" + "a.............a" + "a.............a" + "a.............a" + "aaaa..........a" + "aaaa..........a" + "a..bb.........a" + "a.............a" + "a.............a" + "aaaaaaaa...aaaa" + + // Level 5 + "aaaaaaaabbbaaaa" + "a.............a" + "a.............a" + "a..b..........a" + "a..b..........a" + "aaaa..........a" + "aaaa..........a" + "a.............a" + "aaaa..........a" + "aaaa..........a" + "a..b..........a" + "a..b..........a" + "a.............a" + "a.............a" + "aaaaaaaabbbaaaa" + + // Level 6 + "aaaaaaaaaaaaaaa" + "a.............a" + "a.............a" + "a.............a" + "a..b..........a" + "a..b..........a" + "aaaa..........a" + "aaaa..........a" + "aaaa..........a" + "a..b..........a" + "a..b..........a" + "a.............a" + "a.............a" + "a.............a" + "aaaaaaaaaaaaaaa" + + // Level 7 + "aaaaaaaaaaaaaaa" + "a.............a" + "a.............a" + "a.............a" + "a.............a" + "a..b..........a" + "...b..........a" + "...b..........a" + "...b..........a" + "a..b..........a" + "a.............a" + "a.............a" + "a.............a" + "a.............a" + "aaaaaaaaaaaaaaa" + + // Level 8 + "aababababababaa" + "a.............a" + "b.............b" + "a.............a" + "b.............b" + "a.............a" + "..............b" + "..............a" + "..............b" + "a.............a" + "b.............b" + "a.............a" + "b.............b" + "a.............a" + "aababababababaa" + + // Level 9 + "aababababababaa" + "a.............a" + "b.............b" + "a.............a" + "b.............b" + "a.............a" + "..............b" + "..............a" + "..............b" + "a.............a" + "b.............b" + "a.............a" + "b.............b" + "a.............a" + "aababababababaa" + + // Level 10 + "aababababababaa" + "a.............a" + "b.............b" + "a.............a" + "b.............b" + "a.............a" + "..............b" + "..............a" + "..............b" + "a.............a" + "b.............b" + "a.............a" + "b.............b" + "a.............a" + "aababababababaa" + + // Level 11 + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa", + + // Connections: + "1: 0, 6, 7: 4\n" /* Type 1, BLOCK_FACE_XM */ + "0: 9, 1, 0: 2\n" /* Type 0, BLOCK_FACE_ZM */ + "0: 9, 1, 14: 3\n" /* Type 0, BLOCK_FACE_ZP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // LavaStaircase + + + // LavaStaircaseBig: + // The data has been exported from gallery Nether, area index 31, ID 282 + { + // Size: + 12, 15, 15, // SizeX = 12, SizeY = 15, SizeZ = 15 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b: 10: 0\n" /* lava */ + "c:113: 0\n" /* netherbrickfence */, + + // Block data: + // Level 1 + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + + // Level 2 + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "abbbbbaaaaaa" + "abbbbbbaaaaa" + "abbbbbba...." + "abbbbbba...." + "abbbbbba...." + "abbbbbbaaaaa" + "abbbbb.aaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + + // Level 3 + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "abbbbbaaaaaa" + "abbbbbba...a" + "abbbbbba...." + "abbbbbba...." + "abbbbbba...." + "abbbbbba...a" + "abbbbb.aaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + + // Level 4 + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "abbbbbaa...a" + "abbbbbba...a" + "abbbbbba...." + "abbbbbba...." + "abbbbbba...." + "abbbbbba...a" + "abbbbbaa...a" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + + // Level 5 + "aaaaaaaaaaaa" + "aaaaa......a" + "aaaaa......a" + "aaaaacc....a" + "a.....cc...a" + "a......c...a" + "a......c...." + "a......c...." + "a......c...." + "a......c...a" + "a.....cc...a" + "aaaaacc....a" + "aaaaa......a" + "aaaaa......a" + "aaaaaaaaaaaa" + + // Level 6 + "aaaaaaaaaaaa" + "aaaa.......a" + "aaaa.......a" + "aaaacc.....a" + "aaaa.......a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "aaaa.......a" + "aaaacc.....a" + "aaaa.......a" + "aaaa.......a" + "aaaaaaaaaaaa" + + // Level 7 + "aaaaaaaaaaaa" + "a..........a" + "a..........a" + "a..cc......a" + "aaaa.......a" + "aaaa.......a" + "a..........a" + "a..........a" + "a..........a" + "aaaa.......a" + "aaaa.......a" + "a..cc......a" + "a..........a" + "a..........a" + "aaaaaaaaaaaa" + + // Level 8 + "aaaaaaaaaaaa" + "a..........a" + "a..........a" + "a..c.......a" + "a..c.......a" + "aaaa.......a" + "aaaa.......a" + "a..........a" + "aaaa.......a" + "aaaa.......a" + "a..c.......a" + "a..c.......a" + "a..........a" + "a..........a" + "aaaaaaaaaaaa" + + // Level 9 + "aaaaaaaaaaaa" + "a..........a" + "a..........a" + "a..........a" + "a..c.......a" + "a..c.......a" + "aaaa.......a" + "aaaa.......a" + "aaaa.......a" + "a..c.......a" + "a..c.......a" + "a..........a" + "a..........a" + "a..........a" + "aaaaaaaaaaaa" + + // Level 10 + "aaaaaaaaaaaa" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..c.......a" + "...c.......a" + "...c.......a" + "...c.......a" + "a..c.......a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "aaaaaaaaaaaa" + + // Level 11 + "aaaaaaaaaaaa" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "...........a" + "...........a" + "...........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "aaaaaaaaaaaa" + + // Level 12 + "aaaaaaaaaaaa" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "...........a" + "...........a" + "...........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "aaaaaaaaaaaa" + + // Level 13 + "aaaaaaaaaaaa" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "...........a" + "...........a" + "...........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "aaaaaaaaaaaa" + + // Level 14 + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + + // Level 15 + "aaaaaaaaaaaa" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "aaaaaaaaaaaa", + + // Connections: + "1: 0, 9, 7: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 11, 1, 7: 5\n" /* Type 1, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // LavaStaircaseBig + + + // MidStaircase: + // The data has been exported from gallery Nether, area index 23, ID 165 + { + // Size: + 13, 8, 13, // SizeX = 13, SizeY = 8, SizeZ = 13 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b: 88: 0\n" /* soulsand */ + "c:115: 7\n" /* netherwartblock */ + "d:114: 3\n" /* netherbrickstairs */ + "e:114: 0\n" /* netherbrickstairs */ + "f:114: 1\n" /* netherbrickstairs */ + "g:114: 2\n" /* netherbrickstairs */ + "h: 10: 0\n" /* lava */ + "i:113: 0\n" /* netherbrickfence */, + + // Block data: + // Level 1 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaabbbbbaaaa" + "aaaabbbbbaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaabbbbbaaaa" + "aaaabbbbbaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 2 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaacccccaaaa" + "addecccccfdda" + "...eaaaaad..." + "...eaaaaa...." + "...eaaaaag..." + "agggcccccfgga" + "aaaacccccaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 3 + "aaaaaaaaaaaaa" + "aha.......aha" + "aaa.......aaa" + "a...........a" + "a...........a" + "....eaaaa...." + "....eaaaa...." + "....eaaaa...." + "a...........a" + "a...........a" + "aaa.......aaa" + "aha.......aha" + "aaaaaaaaaaaaa" + + // Level 4 + "aaaiiaaaiiaaa" + "a...........a" + "a...........a" + "a...........a" + "a...........a" + ".....eaaa...." + ".....eaaa...." + ".....eaaa...." + "a...........a" + "a...........a" + "a...........a" + "a...........a" + "aaaiiaaaiiaaa" + + // Level 5 + "aaaiiaaaiiaaa" + "a...........a" + "a...........a" + "a...........a" + "a...........a" + "......eaa...." + "......eaa...." + "......eaa...." + "a...........a" + "a...........a" + "a...........a" + "a...........a" + "aaaiiaaaiiaaa" + + // Level 6 + "aaaaaaaaaaaaa" + "a...........a" + "a...........a" + "a...........a" + "a...........a" + "a......ea...a" + "a......ea...a" + "a......ea...a" + "a...........a" + "a...........a" + "a...........a" + "a...........a" + "aaaaaaaaaaaaa" + + // Level 7 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaa....eaaaa" + "aaaa....eaaaa" + "aaaa....eaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 8 + "iaiaiaiaiaiai" + "a...........a" + "i...........i" + "a...........a" + "i...........i" + "a............" + "i............" + "a............" + "i...........i" + "a...........a" + "i...........i" + "a...........a" + "iaiaiaiaiaiai", + + // Connections: + "1: 0, 1, 6: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 12, 1, 6: 5\n" /* Type 1, BLOCK_FACE_XP */ + "1: 12, 7, 6: 5\n" /* Type 1, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // MidStaircase + + + // StairsToOpen1: + // The data has been exported from gallery Nether, area index 27, ID 277 + { + // Size: + 7, 10, 7, // SizeX = 7, SizeY = 10, SizeZ = 7 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + + // Level 2 + "aa...aa" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "aaaaaaa" + "aaaaaaa" + + // Level 3 + "aa...aa" + "a.....a" + "b.....b" + "a.....a" + "b.....b" + "a.aaaaa" + "aabaaba" + + // Level 4 + "aa...aa" + "a.....a" + "b.....b" + "a.....a" + "b.....b" + "a..aaaa" + "aabaaba" + + // Level 5 + "aabbbaa" + "a.....a" + "b.....b" + "a.....a" + "b.....b" + "a...aaa" + "aabaaba" + + // Level 6 + "aaaaaaa" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "a....aa" + "aaaaaaa" + + // Level 7 + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "a.....a" + "aaaaaaa" + + // Level 8 + "aaaaaaa" + "a.....a" + "a......" + "a......" + "a......" + "a.....a" + "aaaaaaa" + + // Level 9 + "mmmmmmm" + "m.....m" + "m......" + "m......" + "m......" + "m.....m" + "mmmmmmm" + + // Level 10 + "mmmmmmm" + "m.....m" + "m......" + "m......" + "m......" + "m.....m" + "mmmmmmm", + + // Connections: + "0: 3, 1, 0: 2\n" /* Type 0, BLOCK_FACE_ZM */ + "0: 6, 7, 3: 5\n" /* Type 0, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // StairsToOpen1 + + + // StairsToOpen2: + // The data has been exported from gallery Nether, area index 8, ID 35 + { + // Size: + 7, 10, 7, // SizeX = 7, SizeY = 10, SizeZ = 7 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + + // Level 2 + "aa...aa" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "aaaaaaa" + "aaaaaaa" + + // Level 3 + "aa...aa" + "a.....a" + "b.....b" + "a.....a" + "b.....b" + "a.aaaaa" + "aabaaba" + + // Level 4 + "aa...aa" + "a.....a" + "b.....b" + "a.....a" + "b.....b" + "a..aaaa" + "aabaaba" + + // Level 5 + "aabbbaa" + "a.....a" + "b.....b" + "a.....a" + "b.....b" + "a...aaa" + "aabaaba" + + // Level 6 + "aaaaaaa" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "a....aa" + "aaaaaaa" + + // Level 7 + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "a.....a" + "aaaaaaa" + + // Level 8 + "aaaaaaa" + "a.....a" + "......a" + "......a" + "......a" + "a.....a" + "aaaaaaa" + + // Level 9 + "mmmmmmm" + "m.....m" + "......m" + "......m" + "......m" + "m.....m" + "mmmmmmm" + + // Level 10 + "mmmmmmm" + "m.....m" + "......m" + "......m" + "......m" + "m.....m" + "mmmmmmm", + + // Connections: + "0: 3, 1, 0: 2\n" /* Type 0, BLOCK_FACE_ZM */ + "0: 0, 7, 3: 4\n" /* Type 0, BLOCK_FACE_XM */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // StairsToOpen2 + + + // Tee2x4: + // The data has been exported from gallery Nether, area index 40, ID 291 + { + // Size: + 13, 6, 7, // SizeX = 13, SizeY = 6, SizeZ = 7 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "c:114: 0\n" /* netherbrickstairs */ + "d:114: 1\n" /* netherbrickstairs */ + "e:114: 2\n" /* netherbrickstairs */ + "f:114: 3\n" /* netherbrickstairs */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "mmmmaaaaammmm" + "mmmmaaaaammmm" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 2 + "mmmma...ammmm" + "mmmma...ammmm" + "aaaaa...aaaaa" + "............." + "............." + "............." + "aaaaaaaaaaaaa" + + // Level 3 + "mmmma...ammmm" + "mmmmb...bmmmm" + "ababa...ababa" + "............." + "............." + "............." + "ababababababa" + + // Level 4 + "mmmma...ammmm" + "mmmmb...bmmmm" + "ababa...ababa" + "............." + "............." + "............." + "ababababababa" + + // Level 5 + "mmmma...ammmm" + "mmmmb...bmmmm" + "ababa...ababa" + "............." + "............." + "............." + "ababababababa" + + // Level 6 + "mmmmcaaadmmmm" + "mmmmcaaadmmmm" + "eeeecaaadeeee" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "fffffffffffff", + + // Connections: + "1: 0, 1, 4: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 6, 1, 0: 2\n" /* Type 1, BLOCK_FACE_ZM */ + "1: 12, 1, 4: 5\n" /* Type 1, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // Tee2x4 + + + // Tee4x4: + // The data has been exported from gallery Nether, area index 41, ID 292 + { + // Size: + 13, 6, 9, // SizeX = 13, SizeY = 6, SizeZ = 9 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "c:114: 0\n" /* netherbrickstairs */ + "d:114: 1\n" /* netherbrickstairs */ + "e:114: 2\n" /* netherbrickstairs */ + "f:114: 3\n" /* netherbrickstairs */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "mmmmaaaaammmm" + "mmmmaaaaammmm" + "mmmmaaaaammmm" + "mmmmaaaaammmm" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 2 + "mmmma...ammmm" + "mmmma...ammmm" + "mmmma...ammmm" + "mmmma...ammmm" + "aaaaa...aaaaa" + "............." + "............." + "............." + "aaaaaaaaaaaaa" + + // Level 3 + "mmmma...ammmm" + "mmmmb...bmmmm" + "mmmma...ammmm" + "mmmmb...bmmmm" + "ababa...ababa" + "............." + "............." + "............." + "ababababababa" + + // Level 4 + "mmmma...ammmm" + "mmmmb...bmmmm" + "mmmma...ammmm" + "mmmmb...bmmmm" + "ababa...ababa" + "............." + "............." + "............." + "ababababababa" + + // Level 5 + "mmmma...ammmm" + "mmmmb...bmmmm" + "mmmma...ammmm" + "mmmmb...bmmmm" + "ababa...ababa" + "............." + "............." + "............." + "ababababababa" + + // Level 6 + "mmmmcaaadmmmm" + "mmmmcaaadmmmm" + "mmmmcaaadmmmm" + "mmmmcaaadmmmm" + "eeeecaaadeeee" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "fffffffffffff", + + // Connections: + "1: 0, 1, 6: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 12, 1, 6: 5\n" /* Type 1, BLOCK_FACE_XP */ + "1: 6, 1, 0: 2\n" /* Type 1, BLOCK_FACE_ZM */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // Tee4x4 + + // Turret: + // The data has been exported from gallery Nether, area index 7, ID 34 + { + // Size: + 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */, + + // Block data: + // Level 1 + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + + // Level 2 + "aa...aa" + "a.....a" + "......." + "......." + "......." + "a.....a" + "aa...aa" + + // Level 3 + "aa...aa" + "a.....a" + "......." + "......." + "......." + "a.....a" + "aa...aa" + + // Level 4 + "aa...aa" + "a.....a" + "......." + "......." + "......." + "a.....a" + "aa...aa" + + // Level 5 + "aabbbaa" + "a.....a" + "b.....b" + "b.....b" + "b.....b" + "a.....a" + "aabbbaa" + + // Level 6 + "aaaaaaa" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "aaaaaaa", + + // Connections: + "0: 0, 1, 3: 4\n" /* Type 0, BLOCK_FACE_XM */ + "0: 3, 1, 0: 2\n" /* Type 0, BLOCK_FACE_ZM */ + "0: 6, 1, 3: 5\n" /* Type 0, BLOCK_FACE_XP */ + "0: 3, 1, 6: 3\n" /* Type 0, BLOCK_FACE_ZP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // Turret + } ; // g_NetherFortPrefabs1 @@ -1120,7 +2664,7 @@ const cPrefab::sDef g_NetherFortStartingPrefabs1[] = "aaaaabbbaaaaa" // Level 5 - "adadabbbadada" + "adadadddadada" "daaaabbbaaaad" "aabbbbbbbbbaa" "dabbbbbbbbbad" From a87bd5788f7e3e489282b3f69e0bb0ba1ddbafd8 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 30 Mar 2014 13:07:28 +0100 Subject: [PATCH 083/145] Another curly --- src/Items/ItemMinecart.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Items/ItemMinecart.h b/src/Items/ItemMinecart.h index bf6f70eed..25500aeb9 100644 --- a/src/Items/ItemMinecart.h +++ b/src/Items/ItemMinecart.h @@ -1,4 +1,3 @@ - // ItemMinecart.h // Declares the various minecart ItemHandlers @@ -74,7 +73,9 @@ public: Minecart->Initialize(a_World); if (!a_Player->IsGameModeCreative()) + { a_Player->GetInventory().RemoveOneEquippedItem(); + } return true; } From 451a3e97c3748bcccb2ea2aef224b53bd8cbba9b Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 30 Mar 2014 19:25:17 +0300 Subject: [PATCH 084/145] Apache license --- LICENSE | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 196 insertions(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 566c55b46..69b3c7390 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,199 @@ - Copyright MCServer Contributors +MCServer: A performant C++ Minecraft Server +www: http://mc-server.org/ + +Copyright 2014 MCServer Team + +------ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From b64a1daf6cc5a80ace34d348e9f8bb4b679a7651 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 18:47:57 +0200 Subject: [PATCH 085/145] APIDump: Added article: Setting up ZeroBrane Studio. Fixes #824. --- MCServer/Plugins/APIDump/APIDesc.lua | 1 + .../Plugins/APIDump/SettingUpZeroBrane.html | 45 ++++++++++++++++++ MCServer/Plugins/APIDump/Static/zbs_logo.png | Bin 0 -> 1306 bytes .../Plugins/APIDump/Static/zbs_workspace.png | Bin 0 -> 72631 bytes 4 files changed, 46 insertions(+) create mode 100644 MCServer/Plugins/APIDump/SettingUpZeroBrane.html create mode 100644 MCServer/Plugins/APIDump/Static/zbs_logo.png create mode 100644 MCServer/Plugins/APIDump/Static/zbs_workspace.png diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 01f000182..83d544173 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2845,6 +2845,7 @@ end -- No sorting is provided for these, they will be output in the same order as defined here { FileName = "Writing-a-MCServer-plugin.html", Title = "Writing a MCServer plugin" }, { FileName = "SettingUpDecoda.html", Title = "Setting up the Decoda Lua IDE" }, + { FileName = "SettingUpZeroBrane.html", Title = "Setting up the ZeroBrane Studio Lua IDE" }, { FileName = "WebWorldThreads.html", Title = "Webserver vs World threads" }, } } ; diff --git a/MCServer/Plugins/APIDump/SettingUpZeroBrane.html b/MCServer/Plugins/APIDump/SettingUpZeroBrane.html new file mode 100644 index 000000000..0fb89e49d --- /dev/null +++ b/MCServer/Plugins/APIDump/SettingUpZeroBrane.html @@ -0,0 +1,45 @@ + + + + + MCServer - Setting up ZeroBrane Studio + + + + + + + +
+

Setting up the ZeroBrane Studio IDE

+

+ This article will explain how to set up ZeroBrane Studio, an IDE for writing Lua code, so that you can develop MCServer plugins with the comfort of an IDE.

+ +

About ZeroBrane Studio

+ +

To quickly introduce ZeroBrane Studio, it is an IDE for writing Lua code. It has the basic features expected of an IDE - it allows you to manage groups of files as a project, you can edit multiple files in a tabbed editor, the code is syntax-highlighted. Code completion, symbol browsing, and more. It also features a Lua debugger that allows you to debug your Lua code within any application that uses Lua and can load Lua packages. It is written using the multiplatform WxWidgets toolkit, and runs on multiple platforms, including Windows, Linux and MacOS.

+

Here's a screenshot of a default ZBS window with the debugger stepping through the code (scaled down):
+

+

As you can see, you can set breakpoints in the code, inspect variables' values, view the Lua call-stacks.

+

ZBS is open-source, the sources are on GitHub: https://github.com/pkulchenko/ZeroBraneStudio. The project's homepage is at http://studio.zerobrane.com/. + +

First-time setup

+

Since ZBS is a universal Lua IDE, you need to first set it up so that it is ready for MCS plugin development. For that, you need to download one file, mcserver.lua from the ZBS's plugin repository. Place that file in the "packages" folder inside your ZBS's folder. Note that there are other useful plugins in the repository and you may want to have a look there later on to further customize your ZBS. To install them, simply save them into the same folder.

+

After you download the mcserver.lua file, you need to restart ZBS in order for the plugin to load. If there are no errors, you should see two new items in the Project -> Lua Interpreter submenu: "MCServer - debug mode" and "MCServer - release mode". The only difference between the two is which filename they use to launch MCServer - mcserver_debug(.exe) for the debug option and "mcserver(.exe)" for the release option. If you built your own MCServer executable and you built it in debug mode, you should select the debug mode option. In all other cases, including if you downloaded the already-compiled MCServer executable from the internet, you should select the release mode option.

+

For a first time user, it might be a bit overwhelming that there are no GUI settings in the ZBS, yet the IDE is very configurable. There are two files that you edit in order to change settings, either system-wide (all users of the computer share those settings) or user-wide (the settings are only for a specific user of the computer). Those files are regular Lua sources and you can quickly locate them and edit them from within the IDE itself, select Edit -> Preferences -> Settings: XYZ from the menu, with XYZ being either System or User.

+

There is a documentation on most of the settings on ZBS's webpage, have a look at http://studio.zerobrane.com/documentation.html, especially the Preferences section. Personally I recommend setting editor.usetabs to true and possibly adjusting the editor.tabwidth, turn off the editor.smartindent feature and for debugging the option debugger.alloweditting should be set to true unless you feel like punishing yourself.

+ +

Project management

+

ZBS works with projects, it considers all files and subfolder in a specific folder to be a project. There's no need for a special project file nor for adding individual files to the workspace, all files are added automatically. To open a MCS plugin as the project, click the triple-dot button in the Project pane, or select Project -> Project directory -> Choose... from the menu. Browse and select the MCS plugin's folder. ZBS will load all the files in the plugin's folder and you can start editting code.

+

Note that although ZBS allows you to work with subfolders in your plugins (and you should, especially with larger plugins), the current mcserver ZBS plugin will not be able to start debugging unless you have a file open in the editor that is at the root level of the MCS plugin's folder.

+ +

Debugging

+

You are now ready to debug your code. Before doing that, though, don't forget to save your project files. If you haven't done so already, enable your plugin in the settings.ini file. If you want the program to break at a certain line, it is best to set the breakpoint before starting the program. Set the cursor on the line and hit F9 (or use menu Project -> Toggle Breakpoint) to toggle a breakpoint on that line. Finally, hit F5, or select menu Project -> Start Debugging to launch MCServer under the debugger. The MCServer window comes up and loads your plugin. If the window doesn't come up, inspect the Output pane in ZBS, there are usually two reasons for failure:

    +
  • Your code in the currently open file has a hard syntax error. These are reported as "Compilation error" in the Output pane, double-click the line to go to the error
  • +
  • ZBS cannot find the MCServer executable. Make sure you are editting a file two levels down the folder hierarchy from the MCS executable and that the MCS executable is named properly (mcserver[.exe] or mcserver_debug[.exe]). Also make sure you have selected the right Interpreter (menu Project -> Lua Interpreter).
  • +

+

Once running, if the execution hits a breakpoint, the ZBS window will come up and a green arrow is displayed next to the breakpoint line. You can step through the code using F10 (Step Into) and Shift+F10 (Step Over). You can also use the Watch window to inspect variable values, or simply hover your mouse over a variable to display its value in the tooltip. Use the Remote console pane to execute commands directly *inside* the MCServer's plugin context.

+

You can also use the Project -> Break menu item to break into the debugger as soon as possible. You can also set breakpoints while the MCS plugin is running. Note that due to the way in which the debugger is implemented, MCS may execute some more Lua code before the break / breakpoint comes into effect. If MCS is not executing any Lua code in your plugin, it will not break until the plugin code kicks in again. This may result in missed breakpoints and delays before the Break command becomes effective. Therefore it's best to set breakpoints before running the program, or while the program is waiting in another breakpoint.

+
+ + diff --git a/MCServer/Plugins/APIDump/Static/zbs_logo.png b/MCServer/Plugins/APIDump/Static/zbs_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c8d6d62785b9738d1064efba9c89daa74d9d9819 GIT binary patch literal 1306 zcmV+#1?BpQP)~O>PoxAeptYU^ zZUmk`f$LRklUnP66)&x7Xme(R1S~)Zlu{kz-<yTh+_ieb7RC4sXu@tx!l-$ z^$*&+>+2+Qm%lcVIE_el%Oy@6-P%u)COvt?R#P zZfVA?=jO5>tELL-ZlJ|bAz%yeGw^ia(=))2z}ETFv*sfGhGeLe@&Lk8n?Md&0CX2K zvGc`D>?a@%JQB?ozO{rl06fq09!Q3%RL5&l${kY5#Y*c{j^hNA@I3Gaa1bZ~F9Y$Q zeQRs$^J}};fA6~P70-2djEsDJq~Su8NTfCa!@yG-E@-W9PJb(AVnnlrzG${^4)_rG zAet?liDnC%eHq?i>+*tuOdKhC92~Y?@0Y+%ui>TB+ozlcSfkQX6gCE=041pd|N4 zvxVWHL~l(_7L-yOM~)r6q_s}om5Lx@yk@^J~&`KSaQkJBYNGY|DQW=KvmnkLE zvak#T)3PuOlTgUQvMfx~!t-1lX9~yha9s!2ad2F>)$=^*x~@>3N2O9Rq?A2MslI%E ze8mg~G&rYE=gL(84PfCvdW0~7o6P6O72wQv1WLfRcsyy>tUyA5)^q8!x~h)T-k!FB zZGfr;AmVGgNeEHx$W}`ABSaf8r0)O;2GClA)(in{TI+tmM&FBA2+`!nh|~hGWR@fm zN~uN1jvd`+8pgz-LkD_=5ZkK?iV#9<-<$ok*EG$E!GSOKA?2bvg>6YK0QL;p{2nrT zV&oRUSBDM&Ff}!`tNN#Mxx5QtZ}t-a4h{|60>)=K8oL&NbO3P>$o!ynPw(rPrWvXB z8VZFXZ@v9)_4520IU)R5_X5c0#?A<60bbEs2dP`x*|jDLux{N3h6cYxN;yN*Qp!Ca z@BWDX&2Iv*enU?bSQ*F?p|wr}E&2TTnOU1pTU#O`rM&Ie0fdy=FbrWxIbd4W71JpF{F$LVuiS9_i(T-QZ;9;H&rn3%|`y1k%WE|(&a$c$nopx0+c z*J+u{faQ1Tu98zjrTFaG@ARx~REYbvY%zn`fD)^BUlTwo)j=*dCV-_tH?R{J0WPBT zHNX2+`<{L;0oQ*6_~x^=d;P=f-~W634J2aYBm#Pw QwEzGB07*qoM6N<$f)2-J8vpq-j*ck-0bx1* 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

}TqN=}1|b#M7b&P9Ho_WSS9Ekgs&VFp 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 Pz`sYbPi0CU82bM&aVlkH literal 0 HcmV?d00001 From a5c0600e6c69c329fcafc2f9138b9439cf5f65ce Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 20:02:30 +0200 Subject: [PATCH 086/145] Fixed a few clang warnings. --- src/Blocks/BlockPluginInterface.h | 6 ++++++ src/Item.h | 2 +- src/LightingThread.h | 6 +++--- src/World.h | 6 +++--- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Blocks/BlockPluginInterface.h b/src/Blocks/BlockPluginInterface.h index 7428c9a7a..3a36c40b1 100644 --- a/src/Blocks/BlockPluginInterface.h +++ b/src/Blocks/BlockPluginInterface.h @@ -1,8 +1,14 @@ #pragma once +/** This interface is used to decouple block handlers from the cPluginManager dependancy through cWorld. +The block handlers call this interface, which is then implemented by the specific classes that +the caller provides. +*/ class cBlockPluginInterface { public: + virtual ~cBlockPluginInterface() {} + virtual bool CallHookBlockToPickups(cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0; }; diff --git a/src/Item.h b/src/Item.h index 4bdfb12dd..910ecb382 100644 --- a/src/Item.h +++ b/src/Item.h @@ -209,7 +209,7 @@ public: void Add (const cItem & a_Item) {push_back(a_Item); } void Delete(int a_Idx); void Clear (void) {clear(); } - int Size (void) {return size(); } + size_t Size (void) {return size(); } void Set (int a_Idx, short a_ItemType, char a_ItemCount, short a_ItemDamage); void Add (short a_ItemType, char a_ItemCount, short a_ItemDamage) diff --git a/src/LightingThread.h b/src/LightingThread.h index 198f27248..3209ad9b2 100644 --- a/src/LightingThread.h +++ b/src/LightingThread.h @@ -160,14 +160,14 @@ protected: inline void PropagateLight( NIBBLETYPE * a_Light, - int a_SrcIdx, int a_DstIdx, + unsigned int a_SrcIdx, unsigned int a_DstIdx, int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut ) { ASSERT(a_SrcIdx >= 0); - ASSERT(a_SrcIdx < (int)ARRAYCOUNT(m_SkyLight)); + ASSERT(a_SrcIdx < ARRAYCOUNT(m_SkyLight)); ASSERT(a_DstIdx >= 0); - ASSERT(a_DstIdx < (int)ARRAYCOUNT(m_BlockTypes)); + ASSERT(a_DstIdx < ARRAYCOUNT(m_BlockTypes)); if (a_Light[a_SrcIdx] <= a_Light[a_DstIdx] + cBlockInfo::GetSpreadLightFalloff(m_BlockTypes[a_DstIdx])) { diff --git a/src/World.h b/src/World.h index bb2eb0b21..b3ee94a27 100644 --- a/src/World.h +++ b/src/World.h @@ -646,9 +646,9 @@ public: // Various queues length queries (cannot be const, they lock their CS): inline int GetGeneratorQueueLength (void) { return m_Generator.GetQueueLength(); } // tolua_export - inline int GetLightingQueueLength (void) { return m_Lighting.GetQueueLength(); } // tolua_export - inline int GetStorageLoadQueueLength(void) { return m_Storage.GetLoadQueueLength(); } // tolua_export - inline int GetStorageSaveQueueLength(void) { return m_Storage.GetSaveQueueLength(); } // tolua_export + inline size_t GetLightingQueueLength (void) { return m_Lighting.GetQueueLength(); } // tolua_export + inline size_t GetStorageLoadQueueLength(void) { return m_Storage.GetLoadQueueLength(); } // tolua_export + inline size_t GetStorageSaveQueueLength(void) { return m_Storage.GetSaveQueueLength(); } // tolua_export void InitializeSpawn(void); From 8288e53c0be9f4f746a045d5ce8fca6bf6799824 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 23:13:13 +0200 Subject: [PATCH 087/145] Fixed a few Clang warnings in BlockHandlers. --- src/Blocks/BlockAnvil.h | 10 +++++----- src/Blocks/BlockCauldron.h | 2 +- src/Blocks/BlockCrops.h | 12 ++++++------ src/Blocks/BlockDirt.h | 10 +++++----- src/Blocks/BlockFire.h | 22 ++++++++++++---------- src/Blocks/BlockLeaves.h | 19 ++++++++++--------- src/Blocks/BlockMobHead.h | 4 ++-- src/Blocks/BlockNetherWart.h | 15 ++++++++------- src/Blocks/BlockRail.h | 1 + src/Blocks/BlockStems.h | 3 ++- src/Blocks/BlockVine.h | 4 ++-- 11 files changed, 54 insertions(+), 48 deletions(-) diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h index 9f5f84be0..57d10ebce 100644 --- a/src/Blocks/BlockAnvil.h +++ b/src/Blocks/BlockAnvil.h @@ -33,16 +33,16 @@ public: a_BlockType = m_BlockType; int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 0.5) & 0x3; - int RawMeta = a_BlockMeta >> 2; + NIBBLETYPE RawMeta = a_BlockMeta >> 2; Direction++; Direction %= 4; switch (Direction) { - case 0: a_BlockMeta = 0x2 | RawMeta << 2; break; - case 1: a_BlockMeta = 0x3 | RawMeta << 2; break; - case 2: a_BlockMeta = 0x0 | RawMeta << 2; break; - case 3: a_BlockMeta = 0x1 | RawMeta << 2; break; + case 0: a_BlockMeta = 0x2 | (RawMeta << 2); break; + case 1: a_BlockMeta = 0x3 | (RawMeta << 2); break; + case 2: a_BlockMeta = 0x0 | (RawMeta << 2); break; + case 3: a_BlockMeta = 0x1 | (RawMeta << 2); break; default: { return false; diff --git a/src/Blocks/BlockCauldron.h b/src/Blocks/BlockCauldron.h index 2e1032d2b..41b79b6c3 100644 --- a/src/Blocks/BlockCauldron.h +++ b/src/Blocks/BlockCauldron.h @@ -23,7 +23,7 @@ public: virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { - char Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); switch (a_Player->GetEquippedItem().m_ItemType) { case E_ITEM_WATER_BUCKET: diff --git a/src/Blocks/BlockCrops.h b/src/Blocks/BlockCrops.h index ffc2b3f8b..8606cf3f3 100644 --- a/src/Blocks/BlockCrops.h +++ b/src/Blocks/BlockCrops.h @@ -2,7 +2,7 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" +#include "../FastRandom.h" @@ -21,7 +21,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_Meta) override { - MTRand rand; + cFastRandom rand; if (a_Meta == 0x7) { @@ -31,18 +31,18 @@ public: case E_BLOCK_CROPS: { a_Pickups.push_back(cItem(E_ITEM_WHEAT, 1, 0)); - a_Pickups.push_back(cItem(E_ITEM_SEEDS, 1 + (int)(rand.randInt(2) + rand.randInt(2)) / 2, 0)); // [1 .. 3] with high preference of 2 + a_Pickups.push_back(cItem(E_ITEM_SEEDS, (char)(1 + (rand.NextInt(3) + rand.NextInt(3)) / 2), 0)); // [1 .. 3] with high preference of 2 break; } case E_BLOCK_CARROTS: { - a_Pickups.push_back(cItem(E_ITEM_CARROT, 1 + (int)(rand.randInt(2) + rand.randInt(2)) / 2, 0)); // [1 .. 3] with high preference of 2 + a_Pickups.push_back(cItem(E_ITEM_CARROT, (char)(1 + (rand.NextInt(3) + rand.NextInt(3)) / 2), 0)); // [1 .. 3] with high preference of 2 break; } case E_BLOCK_POTATOES: { - a_Pickups.push_back(cItem(E_ITEM_POTATO, 1 + (int)(rand.randInt(2) + rand.randInt(2)) / 2, 0)); // [1 .. 3] with high preference of 2 - if (rand.randInt(20) == 0) + a_Pickups.push_back(cItem(E_ITEM_POTATO, (char)(1 + (rand.NextInt(3) + rand.NextInt(3)) / 2), 0)); // [1 .. 3] with high preference of 2 + if (rand.NextInt(21) == 0) { // With a 5% chance, drop a poisonous potato as well a_Pickups.push_back(cItem(E_ITEM_POISONOUS_POTATO, 1, 0)); diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index a1ab74257..aa24b8668 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -2,7 +2,7 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" +#include "../FastRandom.h" @@ -44,12 +44,12 @@ public: } // Grass spreads to adjacent dirt blocks: - MTRand rand; // TODO: Replace with cFastRandom + cFastRandom rand; for (int i = 0; i < 2; i++) // Pick two blocks to grow to { - int OfsX = rand.randInt(2) - 1; // [-1 .. 1] - int OfsY = rand.randInt(4) - 3; // [-3 .. 1] - int OfsZ = rand.randInt(2) - 1; // [-1 .. 1] + int OfsX = rand.NextInt(3, a_RelX) - 1; // [-1 .. 1] + int OfsY = rand.NextInt(5, a_RelY) - 3; // [-3 .. 1] + int OfsZ = rand.NextInt(3, a_RelZ) - 1; // [-1 .. 1] BLOCKTYPE DestBlock; NIBBLETYPE DestMeta; diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h index a25b87858..c8f158e7e 100644 --- a/src/Blocks/BlockFire.h +++ b/src/Blocks/BlockFire.h @@ -17,25 +17,27 @@ public: } /// Portal boundary and direction variables - int XZP, XZM, Dir; // For wont of a better name... + // 2014_03_30 _X: What are these used for? Why do we need extra variables? + int XZP, XZM; + NIBBLETYPE Dir; virtual void OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override { /* PORTAL FINDING ALGORITH ======================= - -Get clicked base block - -Trace upwards to find first obsidian block; aborts if anything other than obsidian or air is encountered. - Uses this value as a reference (the 'ceiling') - -For both directions (if one fails, try the other), BASE (clicked) block: - -Go in one direction, only stop if a non obsidian block is encountered (abort) OR a portal border is encountered (FindObsidianCeiling returns -1) - -If a border was encountered, go the other direction and repeat above - -Write borders to XZP and XZM, write direction portal faces to Dir - -Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir + - Get clicked base block + - Trace upwards to find first obsidian block; aborts if anything other than obsidian or air is encountered. + Uses this value as a reference (the 'ceiling') + - For both directions (if one fails, try the other), BASE (clicked) block: + - Go in one direction, only stop if a non obsidian block is encountered (abort) OR a portal border is encountered (FindObsidianCeiling returns -1) + - If a border was encountered, go the other direction and repeat above + - Write borders to XZP and XZM, write direction portal faces to Dir + - 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); // Brought to you by Aperture Science + FindAndSetPortalFrame(a_BlockX, a_BlockY, 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/BlockLeaves.h b/src/Blocks/BlockLeaves.h index a6d3373c1..8af14686e 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -1,6 +1,6 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" +#include "../FastRandom.h" #include "../World.h" #include "../BlockArea.h" @@ -37,16 +37,18 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - MTRand rand; + cFastRandom rand; // Only the first 2 bits contain the display information, the others are for growing - if (rand.randInt(5) == 0) + if (rand.NextInt(6) == 0) { a_Pickups.push_back(cItem(E_BLOCK_SAPLING, 1, a_BlockMeta & 3)); } - if ((a_BlockMeta & 3) == E_META_SAPLING_APPLE) + + // 1 % chance of dropping an apple, if the leaves' type is Apple Leaves + if ((a_BlockMeta & 3) == E_META_LEAVES_APPLE) { - if (rand.rand(100) == 0) + if (rand.NextInt(101) == 0) { a_Pickups.push_back(cItem(E_ITEM_RED_APPLE, 1, 0)); } @@ -58,11 +60,10 @@ public: { cBlockHandler::OnDestroyed(a_ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ); - //0.5% chance of dropping an apple + // 0.5% chance of dropping an apple, if the leaves' type is Apple Leaves: NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - //check if Oak (0x1 and 0x2 bit not set) - MTRand rand; - if(!(Meta & 3) && rand.randInt(200) == 100) + cFastRandom rand; + if (((Meta & 3) == E_META_LEAVES_APPLE) && (rand.NextInt(201) == 100)) { cItems Drops; Drops.push_back(cItem(E_ITEM_RED_APPLE, 1, 0)); diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 6aa01f986..080843a73 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -62,8 +62,8 @@ public: } public: - cCallback (cPlayer * a_Player, NIBBLETYPE a_OldBlockMeta, NIBBLETYPE a_NewBlockMeta) : - m_Player(a_Player), + cCallback (cPlayer * a_CBPlayer, NIBBLETYPE a_OldBlockMeta, NIBBLETYPE a_NewBlockMeta) : + m_Player(a_CBPlayer), m_OldBlockMeta(a_OldBlockMeta), m_NewBlockMeta(a_NewBlockMeta) {} diff --git a/src/Blocks/BlockNetherWart.h b/src/Blocks/BlockNetherWart.h index 923180e19..812cf906f 100644 --- a/src/Blocks/BlockNetherWart.h +++ b/src/Blocks/BlockNetherWart.h @@ -2,14 +2,13 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" +#include "../FastRandom.h" #include "../World.h" -/// Common class that takes care of carrots, potatoes and wheat class cBlockNetherWartHandler : public cBlockHandler { @@ -22,12 +21,12 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_Meta) override { - MTRand rand; + cFastRandom rand; if (a_Meta == 0x7) { - // Is fully grown, drop the entire produce: - a_Pickups.push_back(cItem(E_ITEM_NETHER_WART, 1 + (int)(rand.randInt(2) + rand.randInt(2)) / 2, 0)); + // Fully grown, drop the entire produce: + a_Pickups.push_back(cItem(E_ITEM_NETHER_WART, (char)(1 + (rand.NextInt(3) + rand.NextInt(3))) / 2, 0)); } else { @@ -35,18 +34,20 @@ public: } } + virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override { - NIBBLETYPE Meta = a_Chunk.GetMeta (a_RelX, a_RelY, a_RelZ); - + NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); if (Meta < 7) { a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_NETHER_WART, ++Meta); } } + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { + // Needs to be placed on top of a Soulsand block: return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_SOULSAND)); } } ; diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h index 477707a91..ad78d290a 100644 --- a/src/Blocks/BlockRail.h +++ b/src/Blocks/BlockRail.h @@ -431,6 +431,7 @@ public: } break; } + default: break; } return true; } diff --git a/src/Blocks/BlockStems.h b/src/Blocks/BlockStems.h index 705436345..b726a0901 100644 --- a/src/Blocks/BlockStems.h +++ b/src/Blocks/BlockStems.h @@ -17,9 +17,10 @@ public: { } + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - int ItemType = (m_BlockType == E_BLOCK_MELON_STEM) ? E_ITEM_MELON_SEEDS : E_ITEM_PUMPKIN_SEEDS; + short ItemType = (m_BlockType == E_BLOCK_MELON_STEM) ? E_ITEM_MELON_SEEDS : E_ITEM_PUMPKIN_SEEDS; a_Pickups.push_back(cItem(ItemType, 1, 0)); } diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index e14218633..e796a45ae 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -83,7 +83,7 @@ public: static const struct { int x, z; - int Bit; + NIBBLETYPE Bit; } Coords[] = { { 0, 1, 1}, // south, ZP @@ -91,7 +91,7 @@ public: { 0, -1, 4}, // north, ZM { 1, 0, 8}, // east, XP } ; - int res = 0; + NIBBLETYPE res = 0; for (size_t i = 0; i < ARRAYCOUNT(Coords); i++) { BLOCKTYPE BlockType; From 43844fc0f04ffd326af4ebc9e46ec220e27d1309 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 31 Mar 2014 13:28:38 +0200 Subject: [PATCH 088/145] cCompositeChat has a MessageType param in the constructor. This should make it easier to use. --- src/CompositeChat.cpp | 4 ++-- src/CompositeChat.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index a917ee70f..94f8a5901 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -112,8 +112,8 @@ cCompositeChat::cCompositeChat(void) : -cCompositeChat::cCompositeChat(const AString & a_ParseText) : - m_MessageType(mtCustom) +cCompositeChat::cCompositeChat(const AString & a_ParseText, eMessageType a_MessageType) : + m_MessageType(a_MessageType) { ParseText(a_ParseText); } diff --git a/src/CompositeChat.h b/src/CompositeChat.h index 27319490d..d5f4ebb24 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -117,7 +117,7 @@ public: /** Creates a new chat message and parses the text into parts. Recognizes "http:" and "https:" links and @color-codes. Uses ParseText() for the actual parsing. */ - cCompositeChat(const AString & a_ParseText); + cCompositeChat(const AString & a_ParseText, eMessageType a_MessageType = mtCustom); ~cCompositeChat(); From f38a009b3cc5caf25d11496fda5caf75531127d0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 31 Mar 2014 18:25:00 +0200 Subject: [PATCH 089/145] APIDump: Renamed the ZBS API dump file to mcserver_api.lua. This is to avoid confusion with ZBS, where two "mcserver.lua" files were present. --- MCServer/Plugins/APIDump/main_APIDump.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MCServer/Plugins/APIDump/main_APIDump.lua b/MCServer/Plugins/APIDump/main_APIDump.lua index 7455c3cd2..52199740b 100644 --- a/MCServer/Plugins/APIDump/main_APIDump.lua +++ b/MCServer/Plugins/APIDump/main_APIDump.lua @@ -1408,9 +1408,9 @@ end --- Dumps the entire API table into a file in the ZBS format local function DumpAPIZBS(a_API) LOG("Dumping ZBS API description...") - local f, err = io.open("mcserver.lua", "w") + local f, err = io.open("mcserver_api.lua", "w") if (f == nil) then - LOG("Cannot open mcserver.lua for writing, ZBS API will not be dumped. " .. err) + LOG("Cannot open mcserver_lua.lua for writing, ZBS API will not be dumped. " .. err) return end From 55d0db1606f947c1b232e6329345fe7493805dcc Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 31 Mar 2014 18:34:27 +0200 Subject: [PATCH 090/145] APIDump: Added code completion support file to ZBS tutorial. --- MCServer/Plugins/APIDump/SettingUpZeroBrane.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/SettingUpZeroBrane.html b/MCServer/Plugins/APIDump/SettingUpZeroBrane.html index 0fb89e49d..4ebbcb6e6 100644 --- a/MCServer/Plugins/APIDump/SettingUpZeroBrane.html +++ b/MCServer/Plugins/APIDump/SettingUpZeroBrane.html @@ -25,7 +25,8 @@

First-time setup

Since ZBS is a universal Lua IDE, you need to first set it up so that it is ready for MCS plugin development. For that, you need to download one file, mcserver.lua from the ZBS's plugin repository. Place that file in the "packages" folder inside your ZBS's folder. Note that there are other useful plugins in the repository and you may want to have a look there later on to further customize your ZBS. To install them, simply save them into the same folder.

-

After you download the mcserver.lua file, you need to restart ZBS in order for the plugin to load. If there are no errors, you should see two new items in the Project -> Lua Interpreter submenu: "MCServer - debug mode" and "MCServer - release mode". The only difference between the two is which filename they use to launch MCServer - mcserver_debug(.exe) for the debug option and "mcserver(.exe)" for the release option. If you built your own MCServer executable and you built it in debug mode, you should select the debug mode option. In all other cases, including if you downloaded the already-compiled MCServer executable from the internet, you should select the release mode option.

+

Next you should install the code-completion support specific for MCServer. You should repeat this step from time to time, because the API evolves in time so new functions and classes are added to it quite often. You should have an APIDump plugin in your MCServer installation. Enable the APIDump plugin in the server settings, it's very cheap to keep it enabled and it doesn't cost any performance during normal gameplay. To generate the code-completion support file, enter the api command into the server console. This will create a new file, "mcserver_api.lua", next to the MCS executable. Move that file into the "api/lua" subfolder inside your ZBS's folder.

+

After you download the mcserver.lua file and install the completion support, you need to restart ZBS in order for the plugin to load. If there are no errors, you should see two new items in the Project -> Lua Interpreter submenu: "MCServer - debug mode" and "MCServer - release mode". The only difference between the two is which filename they use to launch MCServer - mcserver_debug(.exe) for the debug option and "mcserver(.exe)" for the release option. If you built your own MCServer executable and you built it in debug mode, you should select the debug mode option. In all other cases, including if you downloaded the already-compiled MCServer executable from the internet, you should select the release mode option.

For a first time user, it might be a bit overwhelming that there are no GUI settings in the ZBS, yet the IDE is very configurable. There are two files that you edit in order to change settings, either system-wide (all users of the computer share those settings) or user-wide (the settings are only for a specific user of the computer). Those files are regular Lua sources and you can quickly locate them and edit them from within the IDE itself, select Edit -> Preferences -> Settings: XYZ from the menu, with XYZ being either System or User.

There is a documentation on most of the settings on ZBS's webpage, have a look at http://studio.zerobrane.com/documentation.html, especially the Preferences section. Personally I recommend setting editor.usetabs to true and possibly adjusting the editor.tabwidth, turn off the editor.smartindent feature and for debugging the option debugger.alloweditting should be set to true unless you feel like punishing yourself.

From c4e07631c803debf1047a5607c96d9bf5c1e5f95 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 31 Mar 2014 19:47:18 +0200 Subject: [PATCH 091/145] Added new merge strategy "msDifference" --- src/BlockArea.cpp | 34 ++++++++++++++++++++++++++++++++++ src/BlockArea.h | 1 + 2 files changed, 35 insertions(+) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 2b950378a..17d3cbb00 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -173,6 +173,25 @@ static inline void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a +/** Combinator used for cBlockArea::msDifference merging */ +static inline void MergeCombinatorDifference(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) +{ + if ((a_DstType == a_SrcType) && (a_DstMeta == a_SrcMeta)) + { + a_DstType = E_BLOCK_AIR; + a_DstMeta = 0; + } + else + { + a_DstType = a_SrcType; + a_DstMeta = a_SrcMeta; + } +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cBlockArea: @@ -709,6 +728,21 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R ); break; } // case msSpongePrint + + case msDifference: + { + InternalMergeBlocks( + m_BlockTypes, a_Src.GetBlockTypes(), + DstMetas, SrcMetas, + SizeX, SizeY, SizeZ, + SrcOffX, SrcOffY, SrcOffZ, + DstOffX, DstOffY, DstOffZ, + a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), + m_Size.x, m_Size.y, m_Size.z, + MergeCombinatorDifference + ); + break; + } // case msDifference default: { diff --git a/src/BlockArea.h b/src/BlockArea.h index d37f0d182..0bb272fd9 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -52,6 +52,7 @@ public: msImprint, msLake, msSpongePrint, + msDifference, } ; cBlockArea(void); From f7df8e133b66aafcf35f0590a0ac525a7d2f9278 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 31 Mar 2014 19:58:19 +0200 Subject: [PATCH 092/145] Documented msDifference --- MCServer/Plugins/APIDump/APIDesc.lua | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 6f8a14421..532b4b665 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -230,22 +230,22 @@ g_APIDesc =

- + - + - + - + - + - +
area blockresultarea blockresult
this Src msOverwrite msFillAir msImprint this Src msOverwrite msFillAir msImprint msDifference
air air air air air air air air air air air
A air air A A A air air A A air
air B B B B air B B B B B
A B B A B A B B A B B
@@ -255,6 +255,8 @@ g_APIDesc =
  • msOverwrite completely overwrites all blocks with the Src's blocks
  • msFillAir overwrites only those blocks that were air
  • msImprint overwrites with only those blocks that are non-air
  • +
  • msSpongePrint Sponge overwrites nothing, everything else overwrites anything
  • +
  • msDifference changes all the blocks wich are the same to air. Otherwise the source block gets placed.
  • From a8bc27f8728a0c1f222871cbd3f5534646e59085 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 31 Mar 2014 20:05:48 +0200 Subject: [PATCH 093/145] Fixed typo --- MCServer/Plugins/APIDump/APIDesc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 532b4b665..1b020501c 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -256,7 +256,7 @@ g_APIDesc =
  • msFillAir overwrites only those blocks that were air
  • msImprint overwrites with only those blocks that are non-air
  • msSpongePrint Sponge overwrites nothing, everything else overwrites anything
  • -
  • msDifference changes all the blocks wich are the same to air. Otherwise the source block gets placed.
  • +
  • msDifference changes all the blocks which are the same to air. Otherwise the source block gets placed.
  • From b19022fc7ea4cb6bd1bc6f4b212478e65b5fa5a1 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 31 Mar 2014 20:13:08 +0200 Subject: [PATCH 094/145] Added extra table which should make it more clear what msDifference does. --- MCServer/Plugins/APIDump/APIDesc.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 1b020501c..657ac6aa6 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -247,6 +247,9 @@ g_APIDesc = A B B A B B + + A A A A B air +

    @@ -255,7 +258,6 @@ g_APIDesc =

  • msOverwrite completely overwrites all blocks with the Src's blocks
  • msFillAir overwrites only those blocks that were air
  • msImprint overwrites with only those blocks that are non-air
  • -
  • msSpongePrint Sponge overwrites nothing, everything else overwrites anything
  • msDifference changes all the blocks which are the same to air. Otherwise the source block gets placed.
  • From 0836fe9a84e59b083db368205cbf6496355378bf Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 31 Mar 2014 20:33:33 +0100 Subject: [PATCH 095/145] Fixed a few Y too high/low asserts --- src/Blocks/BlockFluid.h | 5 +++-- src/MobSpawner.cpp | 12 +++++++----- src/Mobs/Monster.cpp | 10 +++++----- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h index 37885e4de..361b97c60 100644 --- a/src/Blocks/BlockFluid.h +++ b/src/Blocks/BlockFluid.h @@ -93,8 +93,8 @@ public: // Check if it's fuel: BLOCKTYPE BlockType; if ( - !a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) || - !cFireSimulator::IsFuel(BlockType) + ((a_RelY + y < 0) || (a_RelY + y > cChunkDef::Height)) || + (!a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) || !cFireSimulator::IsFuel(BlockType)) ) { return false; @@ -119,6 +119,7 @@ public: for (size_t i = 0; i < ARRAYCOUNT(CrossCoords); i++) { if ( + ((RelY + CrossCoords[i].y >= 0) && (RelY + CrossCoords[i].y <= cChunkDef::Height)) && a_Chunk.UnboundedRelGetBlockType(RelX + CrossCoords[i].x, RelY + CrossCoords[i].y, RelZ + CrossCoords[i].z, BlockType) && (BlockType == E_BLOCK_AIR) ) diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index a0d0f5c54..216681b48 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -129,6 +129,11 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R BLOCKTYPE TargetBlock = E_BLOCK_AIR; if (m_AllowedTypes.find(a_MobType) != m_AllowedTypes.end() && a_Chunk->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, TargetBlock)) { + if ((a_RelY + 1 > cChunkDef::Height) || (a_RelY - 1 < 0)) + { + return false; + } + NIBBLETYPE BlockLight = a_Chunk->GetBlockLight(a_RelX, a_RelY, a_RelZ); NIBBLETYPE SkyLight = a_Chunk->GetSkyLight(a_RelX, a_RelY, a_RelZ); BLOCKTYPE BlockAbove = a_Chunk->GetBlock(a_RelX, a_RelY + 1, a_RelZ); @@ -212,11 +217,8 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R return false; } HaveFloor = ( - HaveFloor || - ( - a_Chunk->UnboundedRelGetBlockType(a_RelX + x, a_RelY - 1, a_RelZ + z, TargetBlock) && - !cBlockInfo::IsTransparent(TargetBlock) - ) + a_Chunk->UnboundedRelGetBlockType(a_RelX + x, a_RelY - 1 /* Checked at start of function */, a_RelZ + z, TargetBlock) && + !cBlockInfo::IsTransparent(TargetBlock) ); } } diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index d3e0f1c26..83003006e 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -111,9 +111,9 @@ void cMonster::SpawnOn(cClientHandle & a_Client) void cMonster::TickPathFinding() { - int PosX = (int)floor(GetPosX()); - int PosY = (int)floor(GetPosY()); - int PosZ = (int)floor(GetPosZ()); + const int PosX = (int)floor(GetPosX()); + const int PosY = (int)floor(GetPosY()); + const int PosZ = (int)floor(GetPosZ()); m_FinalDestination.y = (double)FindFirstNonAirBlockPosition(m_FinalDestination.x, m_FinalDestination.z); @@ -133,9 +133,9 @@ void cMonster::TickPathFinding() for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) { - if ((gCrossCoords[i].x + PosX == PosX) && (gCrossCoords[i].z + PosZ == PosZ)) + if ((PosY - 1 < 0) || (PosY + 1 > cChunkDef::Height) || (PosY + 2 > cChunkDef::Height)) { - continue; + break; } if (IsCoordinateInTraversedList(Vector3i(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ))) From ee07b7ae3ec9cd283fe61aede067e7fc9e4bcb49 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 31 Mar 2014 20:34:11 +0100 Subject: [PATCH 096/145] Simplified and fixed slabs, fixes #835 --- src/Blocks/BlockSlab.h | 43 ++++++++++-------------------------------- src/ClientHandle.cpp | 2 +- src/ClientHandle.h | 4 ++-- 3 files changed, 13 insertions(+), 36 deletions(-) diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index 77e8b8e55..3f0fef0c7 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -11,6 +11,7 @@ #include "BlockHandler.h" #include "../Items/ItemHandler.h" +#include "Root.h" @@ -38,41 +39,9 @@ public: ) override { a_BlockType = m_BlockType; - BLOCKTYPE Type = (BLOCKTYPE) (a_Player->GetEquippedItem().m_ItemType); NIBBLETYPE Meta = (NIBBLETYPE) a_Player->GetEquippedItem().m_ItemDamage; - // HandlePlaceBlock wants a cItemHandler pointer thing, so let's give it one - cItemHandler * ItemHandler = cItemHandler::GetItemHandler(GetDoubleSlabType(Type)); - - // Check if the block at the coordinates is a slab. Eligibility for combining has already been processed in ClientHandle - if (IsAnySlabType(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ))) - { - // Call the function in ClientHandle that places a block when the client sends the packet, - // so that plugins may interfere with the placement. - - if ((a_BlockFace == BLOCK_FACE_TOP) || (a_BlockFace == BLOCK_FACE_BOTTOM)) - { - // Top and bottom faces need no parameter modification - a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); - } - else - { - // The other faces need to distinguish between top and bottom cursor positions - if (a_CursorY > 7) - { - // Edit the call to use BLOCK_FACE_BOTTOM, otherwise it places incorrectly - a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_TOP, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); - } - else - { - // Edit the call to use BLOCK_FACE_TOP, otherwise it places incorrectly - a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_BOTTOM, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); - } - } - return false; // Cancel the event, because dblslabs were already placed, nothing else needed - } - - // Place the single-slab with correct metas: + // Set the correct metadata based on player equipped item (i.e. a_BlockMeta not initialised yet) switch (a_BlockFace) { case BLOCK_FACE_TOP: @@ -104,6 +73,14 @@ public: } } } // switch (a_BlockFace) + + // Check if the block at the coordinates is a single slab. Eligibility for combining has already been processed in ClientHandle + // Changed to-be-placed to a double slab if we are clicking on a single slab, as opposed to placing one for the first time + if (IsAnySlabType(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ))) + { + a_BlockType = GetDoubleSlabType(m_BlockType); + } + return true; } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 5ed5f1085..23ba4dbab 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1064,7 +1064,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e // If clicked top face and slab occupies the top voxel, we want a slab to be placed above it (therefore increment Y) // Else if clicked bottom face and slab occupies the bottom voxel, decrement Y for the same reason // Don't touch coordinates if anything else because a dblslab opportunity is present - if((ClickedBlockMeta & 0x08) && (a_BlockFace == BLOCK_FACE_TOP)) + if ((ClickedBlockMeta & 0x08) && (a_BlockFace == BLOCK_FACE_TOP)) { ++a_BlockY; } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 8366caa16..5496e61a7 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -230,10 +230,10 @@ public: /** Called when the player moves into a different world; queues sreaming the new chunks */ void MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket); +private: + /** Handles the block placing packet when it is a real block placement (not block-using, item-using or eating) */ void HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler); - -private: /** The type used for storing the names of registered plugin channels. */ typedef std::set cChannels; From fc940b6da4fd446e718879a19790af03dadfe2f4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 31 Mar 2014 21:36:19 +0100 Subject: [PATCH 097/145] Realised suggestions --- src/Blocks/BlockFluid.h | 5 ++++- src/MobSpawner.cpp | 13 ++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h index 361b97c60..1200997ff 100644 --- a/src/Blocks/BlockFluid.h +++ b/src/Blocks/BlockFluid.h @@ -94,7 +94,10 @@ public: BLOCKTYPE BlockType; if ( ((a_RelY + y < 0) || (a_RelY + y > cChunkDef::Height)) || - (!a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) || !cFireSimulator::IsFuel(BlockType)) + ( + !a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) || + !cFireSimulator::IsFuel(BlockType) + ) ) { return false; diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index 216681b48..05da5d01c 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -205,7 +205,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R case cMonster::mtSpider: { bool CanSpawn = true; - bool HaveFloor = false; + bool HasFloor = false; for (int x = 0; x < 2; ++x) { for(int z = 0; z < 2; ++z) @@ -216,13 +216,16 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R { return false; } - HaveFloor = ( - a_Chunk->UnboundedRelGetBlockType(a_RelX + x, a_RelY - 1 /* Checked at start of function */, a_RelZ + z, TargetBlock) && - !cBlockInfo::IsTransparent(TargetBlock) + HasFloor = ( + HasFloor || + ( + a_Chunk->UnboundedRelGetBlockType(a_RelX + x, a_RelY - 1, a_RelZ + z, TargetBlock) && + !cBlockInfo::IsTransparent(TargetBlock) + ) ); } } - return CanSpawn && HaveFloor && (SkyLight <= 7) && (BlockLight <= 7); + return CanSpawn && HasFloor && (SkyLight <= 7) && (BlockLight <= 7); } case cMonster::mtCreeper: From 8126d9e66ef1ac90db2660ae357c9aa1c14c7126 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 31 Mar 2014 22:51:14 +0200 Subject: [PATCH 098/145] Console logging supports cCompositeChat as its parameters. --- MCServer/Plugins/Debuggers/Debuggers.lua | 9 +++++ src/Bindings/ManualBindings.cpp | 46 +++++++++++++++++------- src/CompositeChat.cpp | 29 +++++++++++++++ src/CompositeChat.h | 5 +++ src/Protocol/Protocol125.cpp | 23 +----------- 5 files changed, 78 insertions(+), 34 deletions(-) diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index 2cb014875..2619bd6c4 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -75,6 +75,15 @@ function Initialize(Plugin) -- TestPluginCalls(); TestBlockAreasString() + + --[[ + -- Test cCompositeChat usage in console-logging: + LOGINFO(cCompositeChat("This is a simple message with some @2 color formatting @4 and http://links.to .") + :AddSuggestCommandPart("(Suggested command)", "cmd") + :AddRunCommandPart("(Run command)", "cmd") + :SetMessageType(mtInfo) + ) + --]] return true end; diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 20bbc48f2..95cd5e904 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -115,10 +115,35 @@ static int tolua_StringSplitAndTrim(lua_State * tolua_S) -static int tolua_LOG(lua_State* tolua_S) +/** Retrieves the log message from the first param on the Lua stack. +Can take either a string or a cCompositeChat. +*/ +static AString GetLogMessage(lua_State * tolua_S) { - const char* str = tolua_tocppstring(tolua_S,1,0); - cMCLogger::GetInstance()->LogSimple( str, 0 ); + tolua_Error err; + if (tolua_isusertype(tolua_S, 1, "cCompositeChat", false, &err)) + { + return ((cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL))->ExtractText(); + } + else + { + size_t len = 0; + const char * str = lua_tolstring(tolua_S, 1, &len); + if (str != NULL) + { + return AString(str, len); + } + } + return ""; +} + + + + + +static int tolua_LOG(lua_State * tolua_S) +{ + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 0); return 0; } @@ -126,10 +151,9 @@ static int tolua_LOG(lua_State* tolua_S) -static int tolua_LOGINFO(lua_State* tolua_S) +static int tolua_LOGINFO(lua_State * tolua_S) { - const char* str = tolua_tocppstring(tolua_S,1,0); - cMCLogger::GetInstance()->LogSimple( str, 1 ); + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 1); return 0; } @@ -137,10 +161,9 @@ static int tolua_LOGINFO(lua_State* tolua_S) -static int tolua_LOGWARN(lua_State* tolua_S) +static int tolua_LOGWARN(lua_State * tolua_S) { - const char* str = tolua_tocppstring(tolua_S,1,0); - cMCLogger::GetInstance()->LogSimple( str, 2 ); + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 2); return 0; } @@ -148,10 +171,9 @@ static int tolua_LOGWARN(lua_State* tolua_S) -static int tolua_LOGERROR(lua_State* tolua_S) +static int tolua_LOGERROR(lua_State * tolua_S) { - const char* str = tolua_tocppstring(tolua_S,1,0); - cMCLogger::GetInstance()->LogSimple( str, 3 ); + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 3); return 0; } diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index 94f8a5901..918e4f90e 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -314,6 +314,35 @@ void cCompositeChat::UnderlineUrls(void) +AString cCompositeChat::ExtractText(void) const +{ + AString Msg; + for (cParts::const_iterator itr = m_Parts.begin(), end = m_Parts.end(); itr != end; ++itr) + { + switch ((*itr)->m_PartType) + { + case ptText: + case ptClientTranslated: + case ptRunCommand: + case ptSuggestCommand: + { + Msg.append((*itr)->m_Text); + break; + } + case ptUrl: + { + Msg.append(((cUrlPart *)(*itr))->m_Url); + break; + } + } // switch (PartType) + } // for itr - m_Parts[] + return Msg; +} + + + + + void cCompositeChat::AddStyle(AString & a_Style, const AString & a_AddStyle) { if (a_AddStyle.empty()) diff --git a/src/CompositeChat.h b/src/CompositeChat.h index d5f4ebb24..0f56cde9b 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -164,6 +164,11 @@ public: /** Returns the message type set previously by SetMessageType(). */ eMessageType GetMessageType(void) const { return m_MessageType; } + /** Returns the text from the parts that comprises the human-readable data. + Used for older protocols that don't support composite chat + and for console-logging. */ + AString ExtractText(void) const; + // tolua_end const cParts & GetParts(void) const { return m_Parts; } diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 69f4934d8..ea844c044 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -239,32 +239,11 @@ void cProtocol125::SendChat(const AString & a_Message) void cProtocol125::SendChat(const cCompositeChat & a_Message) { // This version doesn't support composite messages, just extract each part's text and use it: - AString Msg; - const cCompositeChat::cParts & Parts = a_Message.GetParts(); - for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr) - { - switch ((*itr)->m_PartType) - { - case cCompositeChat::ptText: - case cCompositeChat::ptClientTranslated: - case cCompositeChat::ptRunCommand: - case cCompositeChat::ptSuggestCommand: - { - Msg.append((*itr)->m_Text); - break; - } - case cCompositeChat::ptUrl: - { - Msg.append(((cCompositeChat::cUrlPart *)(*itr))->m_Url); - break; - } - } // switch (PartType) - } // for itr - Parts[] // Send the message: cCSLock Lock(m_CSPacket); WriteByte (PACKET_CHAT); - WriteString(Msg); + WriteString(a_Message.ExtractText()); Flush(); } From 58f255032176c5e4e3a0f5e6ffea76128355ee61 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 31 Mar 2014 23:05:31 +0200 Subject: [PATCH 099/145] APIDump: Documented the cCompositeChat support in logging functions. --- MCServer/Plugins/APIDump/APIDesc.lua | 30 +++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index eceb19bd7..b1b660bb0 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2663,11 +2663,31 @@ end ItemToFullString = {Params = "{{cItem|cItem}}", Return = "string", Notes = "Returns the string representation of the item, in the format 'ItemTypeText:ItemDamage * Count'"}, ItemToString = {Params = "{{cItem|cItem}}", Return = "string", Notes = "Returns the string representation of the item type"}, ItemTypeToString = {Params = "ItemType", Return = "string", Notes = "Returns the string representation of ItemType "}, - LOG = {Params = "string", Notes = "Logs a text into the server console using 'normal' severity (gray text) "}, - LOGERROR = {Params = "string", Notes = "Logs a text into the server console using 'error' severity (black text on red background)"}, - LOGINFO = {Params = "string", Notes = "Logs a text into the server console using 'info' severity (yellow text)"}, - LOGWARN = {Params = "string", Notes = "Logs a text into the server console using 'warning' severity (red text); OBSOLETE, use LOGWARNING() instead"}, - LOGWARNING = {Params = "string", Notes = "Logs a text into the server console using 'warning' severity (red text)"}, + LOG = + { + {Params = "string", Notes = "Logs a text into the server console using 'normal' severity (gray text) "}, + {Params = "{{cCompositeChat|CompositeChat}}", Notes = "Logs the {{cCompositeChat}}'s human-readable text into the server console using 'normal' severity (gray text) "}, + }, + LOGERROR = + { + {Params = "string", Notes = "Logs a text into the server console using 'error' severity (black text on red background)"}, + {Params = "{{cCompositeChat|CompositeChat}}", Notes = "Logs the {{cCompositeChat}}'s human-readable text into the server console using 'error' severity (black text on red background)"}, + }, + LOGINFO = + { + {Params = "string", Notes = "Logs a text into the server console using 'info' severity (yellow text)"}, + {Params = "{{cCompositeChat|CompositeChat}}", Notes = "Logs the {{cCompositeChat}}'s human-readable text into the server console using 'info' severity (yellow text)"}, + }, + LOGWARN = + { + {Params = "string", Notes = "Logs a text into the server console using 'warning' severity (red text); OBSOLETE, use LOGWARNING() instead"}, + {Params = "{{cCompositeChat|CompositeChat}}", Notes = "Logs the {{cCompositeChat}}'s human-readable text into the server console using 'warning' severity (red text); OBSOLETE, use LOGWARNING() instead"}, + }, + LOGWARNING = + { + {Params = "string", Notes = "Logs a text into the server console using 'warning' severity (red text)"}, + {Params = "{{cCompositeChat|CompositeChat}}", Notes = "Logs the {{cCompositeChat}}'s human-readable text into the server console using 'warning' severity (red text)"}, + }, MirrorBlockFaceY = { Params = "{{Globals#BlockFaces|eBlockFace}}", Return = "{{Globals#BlockFaces|eBlockFace}}", Notes = "Returns the {{Globals#BlockFaces|eBlockFace}} that corresponds to the given {{Globals#BlockFaces|eBlockFace}} after mirroring it around the Y axis (or rotating 180 degrees around it)." }, NoCaseCompare = {Params = "string, string", Return = "number", Notes = "Case-insensitive string comparison; returns 0 if the strings are the same"}, NormalizeAngleDegrees = { Params = "AngleDegrees", Return = "AngleDegrees", Notes = "Returns the angle, wrapped into the [-180, +180) range." }, From ef48b30baaed9c6ad1782047d4e2d60d6248ad89 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 31 Mar 2014 22:37:05 +0100 Subject: [PATCH 100/145] Final realisation of suggestions --- src/Mobs/Monster.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 83003006e..aa6071515 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -130,14 +130,16 @@ void cMonster::TickPathFinding() { 0, 1}, { 0,-1}, } ; + + if ((PosY - 1 < 0) || (PosY + 2 > cChunkDef::Height) /* PosY + 1 will never be true if PosY + 2 is not */) + { + // Too low/high, can't really do anything + FinishPathFinding(); + return; + } for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) { - if ((PosY - 1 < 0) || (PosY + 1 > cChunkDef::Height) || (PosY + 2 > cChunkDef::Height)) - { - break; - } - if (IsCoordinateInTraversedList(Vector3i(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ))) { continue; From 7aa6a3b86663ef28295ffb914f66a8f0359a353f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 09:32:14 +0200 Subject: [PATCH 101/145] LOG() API reads the LogLevel from the cCompositeChat's MessageType. --- MCServer/Plugins/APIDump/APIDesc.lua | 4 ++-- src/Bindings/ManualBindings.cpp | 17 ++++++++++---- src/CompositeChat.cpp | 23 +++++++++++++++++++ src/CompositeChat.h | 4 ++++ src/MCLogger.cpp | 24 ++++++++++++++------ src/MCLogger.h | 33 ++++++++++++++++++---------- 6 files changed, 81 insertions(+), 24 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index b1b660bb0..28e7744ed 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2665,8 +2665,8 @@ end ItemTypeToString = {Params = "ItemType", Return = "string", Notes = "Returns the string representation of ItemType "}, LOG = { - {Params = "string", Notes = "Logs a text into the server console using 'normal' severity (gray text) "}, - {Params = "{{cCompositeChat|CompositeChat}}", Notes = "Logs the {{cCompositeChat}}'s human-readable text into the server console using 'normal' severity (gray text) "}, + {Params = "string", Notes = "Logs a text into the server console using 'normal' severity (gray text)"}, + {Params = "{{cCompositeChat|CompositeChat}}", Notes = "Logs the {{cCompositeChat}}'s human-readable text into the server console. The severity is converted from the CompositeChat's MessageType."}, }, LOGERROR = { diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 95cd5e904..9d1a367df 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -143,7 +143,16 @@ static AString GetLogMessage(lua_State * tolua_S) static int tolua_LOG(lua_State * tolua_S) { - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 0); + // If the param is a cCompositeChat, read the log level from it: + cMCLogger::eLogLevel LogLevel = cMCLogger::llRegular; + tolua_Error err; + if (tolua_isusertype(tolua_S, 1, "cCompositeChat", false, &err)) + { + LogLevel = cCompositeChat::MessageTypeToLogLevel(((cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL))->GetMessageType()); + } + + // Log the message: + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel); return 0; } @@ -153,7 +162,7 @@ static int tolua_LOG(lua_State * tolua_S) static int tolua_LOGINFO(lua_State * tolua_S) { - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 1); + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llInfo); return 0; } @@ -163,7 +172,7 @@ static int tolua_LOGINFO(lua_State * tolua_S) static int tolua_LOGWARN(lua_State * tolua_S) { - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 2); + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llWarning); return 0; } @@ -173,7 +182,7 @@ static int tolua_LOGWARN(lua_State * tolua_S) static int tolua_LOGERROR(lua_State * tolua_S) { - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 3); + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llError); return 0; } diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index 918e4f90e..c70ef1070 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -343,6 +343,29 @@ AString cCompositeChat::ExtractText(void) const +cMCLogger::eLogLevel cCompositeChat::MessageTypeToLogLevel(eMessageType a_MessageType) +{ + switch (a_MessageType) + { + case mtCustom: return cMCLogger::llRegular; + case mtFailure: return cMCLogger::llWarning; + case mtInformation: return cMCLogger::llInfo; + case mtSuccess: return cMCLogger::llRegular; + case mtWarning: return cMCLogger::llWarning; + case mtFatal: return cMCLogger::llError; + case mtDeath: return cMCLogger::llRegular; + case mtPrivateMessage: return cMCLogger::llRegular; + case mtJoin: return cMCLogger::llRegular; + case mtLeave: return cMCLogger::llRegular; + } + ASSERT(!"Unhandled MessageType"); + return cMCLogger::llError; +} + + + + + void cCompositeChat::AddStyle(AString & a_Style, const AString & a_AddStyle) { if (a_AddStyle.empty()) diff --git a/src/CompositeChat.h b/src/CompositeChat.h index 0f56cde9b..5b9c5f612 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -173,6 +173,10 @@ public: const cParts & GetParts(void) const { return m_Parts; } + /** Converts the MessageType to a LogLevel value. + Used by the logging bindings when logging a cCompositeChat object. */ + static cMCLogger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType); + protected: /** All the parts that */ cParts m_Parts; diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp index 4f3e5dc0f..509833f37 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -93,25 +93,35 @@ void cMCLogger::InitLog(const AString & a_FileName) -void cMCLogger::LogSimple(const char* a_Text, int a_LogType /* = 0 */ ) +void cMCLogger::LogSimple(const char * a_Text, eLogLevel a_LogLevel) { - switch( a_LogType ) + switch (a_LogLevel) { - case 0: + case llRegular: + { LOG("%s", a_Text); break; - case 1: + } + case llInfo: + { LOGINFO("%s", a_Text); break; - case 2: + } + case llWarning: + { LOGWARN("%s", a_Text); break; - case 3: + } + case llError: + { LOGERROR("%s", a_Text); break; + } default: - LOG("(#%d#: %s", a_LogType, a_Text); + { + LOG("(#%d#: %s", (int)a_LogLevel, a_Text); break; + } } } diff --git a/src/MCLogger.h b/src/MCLogger.h index 996e60329..c0150c124 100644 --- a/src/MCLogger.h +++ b/src/MCLogger.h @@ -10,25 +10,36 @@ class cLog; -class cMCLogger // tolua_export -{ // tolua_export -public: // tolua_export - /// Creates a logger with the default filename, "logs/LOG_.log" +// tolua_begin +class cMCLogger +{ +public: + enum eLogLevel + { + llRegular, + llInfo, + llWarning, + llError, + }; + // tolua_end + + /** Creates a logger with the default filename, "logs/LOG_.log" */ cMCLogger(void); - /// Creates a logger with the specified filename inside "logs" folder + /** Creates a logger with the specified filename inside "logs" folder */ cMCLogger(const AString & a_FileName); // tolua_export ~cMCLogger(); // tolua_export - void Log(const char* a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - void Info(const char* a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - void Warn(const char* a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - void Error(const char* a_Format, va_list a_ArgList) FORMATSTRING(2, 0); + void Log (const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); + void Info (const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); + void Warn (const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); + void Error(const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - void LogSimple(const char* a_Text, int a_LogType = 0 ); // tolua_export + /** Logs the simple text message at the specified log level. */ + void LogSimple(const char * a_Text, eLogLevel a_LogLevel = llRegular); // tolua_export - static cMCLogger* GetInstance(); + static cMCLogger * GetInstance(); private: enum eColorScheme { From e610262fb10c6fafd3c3ff5f2c4f83ada9220e6d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 09:44:11 +0200 Subject: [PATCH 102/145] Attempt at disabling the useless clang warnings. Ref.: #846, #847 --- SetFlags.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/SetFlags.cmake b/SetFlags.cmake index bbd8254ad..d90ad8b48 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -198,6 +198,7 @@ macro(set_exe_flags) add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=shadow") add_flags_cxx("-Wno-error=exit-time-destructors -Wno-error=missing-variable-declarations") add_flags_cxx("-Wno-error=global-constructors -Wno-implicit-fallthrough") + add_flags_cxx("-Wno-weak-vtables -Wno-switch-enum") endif() endif() From 7cc322332baa22475674f93b9ec76e1546d7e941 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 13:38:40 +0200 Subject: [PATCH 103/145] Removed an unneeded code branch. --- src/MCLogger.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp index 509833f37..80fa7b173 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -117,11 +117,6 @@ void cMCLogger::LogSimple(const char * a_Text, eLogLevel a_LogLevel) LOGERROR("%s", a_Text); break; } - default: - { - LOG("(#%d#: %s", (int)a_LogLevel, a_Text); - break; - } } } From aa7552309abb6943f8ba0ac3d8013689655e74b2 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 14:23:11 +0200 Subject: [PATCH 104/145] Simplified the anvil placement code. --- src/Blocks/BlockAnvil.h | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h index 57d10ebce..93a796ef7 100644 --- a/src/Blocks/BlockAnvil.h +++ b/src/Blocks/BlockAnvil.h @@ -18,11 +18,13 @@ public: { } + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.push_back(cItem(E_BLOCK_ANVIL, 1, a_BlockMeta >> 2)); } + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -31,27 +33,23 @@ public: ) override { a_BlockType = m_BlockType; - - int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 0.5) & 0x3; - NIBBLETYPE RawMeta = a_BlockMeta >> 2; - - Direction++; - Direction %= 4; + NIBBLETYPE HighBits = a_BlockMeta & 0x0c; // Only highest two bits are preserved + int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 1.5) & 0x3; switch (Direction) { - case 0: a_BlockMeta = 0x2 | (RawMeta << 2); break; - case 1: a_BlockMeta = 0x3 | (RawMeta << 2); break; - case 2: a_BlockMeta = 0x0 | (RawMeta << 2); break; - case 3: a_BlockMeta = 0x1 | (RawMeta << 2); break; + case 0: a_BlockMeta = 0x2 | HighBits; break; + case 1: a_BlockMeta = 0x3 | HighBits; break; + case 2: a_BlockMeta = 0x0 | HighBits; break; + case 3: a_BlockMeta = 0x1 | HighBits; break; default: { return false; } } - return true; } + virtual bool IsUseable() override { return true; From 45150e97541aa8dfda7f0fdba75acf2ec616654d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 14:58:05 +0200 Subject: [PATCH 105/145] Fixed clang warnings in cFile. We only support 32-bit filesizes (files < 2 GiB). --- src/OSSupport/File.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index 17070030f..75ea198a8 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -152,7 +152,7 @@ int cFile::Read (void * iBuffer, int iNumBytes) return -1; } - return fread(iBuffer, 1, iNumBytes, m_File); // fread() returns the portion of Count parameter actually read, so we need to send iNumBytes as Count + return (int)fread(iBuffer, 1, (size_t)iNumBytes, m_File); // fread() returns the portion of Count parameter actually read, so we need to send iNumBytes as Count } @@ -168,7 +168,7 @@ int cFile::Write(const void * iBuffer, int iNumBytes) return -1; } - int res = fwrite(iBuffer, 1, iNumBytes, m_File); // fwrite() returns the portion of Count parameter actually written, so we need to send iNumBytes as Count + int res = (int)fwrite(iBuffer, 1, (size_t)iNumBytes, m_File); // fwrite() returns the portion of Count parameter actually written, so we need to send iNumBytes as Count return res; } @@ -189,7 +189,7 @@ int cFile::Seek (int iPosition) { return -1; } - return ftell(m_File); + return (int)ftell(m_File); } @@ -206,7 +206,7 @@ int cFile::Tell (void) const return -1; } - return ftell(m_File); + return (int)ftell(m_File); } @@ -222,7 +222,7 @@ int cFile::GetSize(void) const return -1; } - int CurPos = ftell(m_File); + int CurPos = Tell(); if (CurPos < 0) { return -1; @@ -231,8 +231,8 @@ int cFile::GetSize(void) const { return -1; } - int res = ftell(m_File); - if (fseek(m_File, CurPos, SEEK_SET) != 0) + int res = Tell(); + if (fseek(m_File, (size_t)CurPos, SEEK_SET) != 0) { return -1; } @@ -255,7 +255,7 @@ int cFile::ReadRestOfFile(AString & a_Contents) int DataSize = GetSize() - Tell(); // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly - a_Contents.assign(DataSize, '\0'); + a_Contents.assign((size_t)DataSize, '\0'); return Read((void *)a_Contents.data(), DataSize); } @@ -350,7 +350,7 @@ int cFile::GetSize(const AString & a_FileName) struct stat st; if (stat(a_FileName.c_str(), &st) == 0) { - return st.st_size; + return (int)st.st_size; } return -1; } @@ -456,7 +456,7 @@ int cFile::Printf(const char * a_Fmt, ...) va_start(args, a_Fmt); AppendVPrintf(buf, a_Fmt, args); va_end(args); - return Write(buf.c_str(), buf.length()); + return Write(buf.c_str(), (int)buf.length()); } From 42e30b6513c8f905d419dd6621ad11959eea9dc9 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 14:55:46 +0200 Subject: [PATCH 106/145] Fixed clang warnings in BlockHandlers. --- src/Blocks/BlockMobHead.h | 2 +- src/Blocks/BlockSlab.h | 1 + src/Blocks/BlockStairs.h | 4 ++-- src/Blocks/BlockVine.h | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 080843a73..c4f41ba34 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -70,7 +70,7 @@ public: }; cCallback Callback(a_Player, a_BlockMeta, static_cast(a_BlockFace)); - a_BlockMeta = a_BlockFace; + a_BlockMeta = (NIBBLETYPE)a_BlockFace; cWorld * World = (cWorld *) &a_WorldInterface; World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index 77e8b8e55..4f94d45f6 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -103,6 +103,7 @@ public: a_BlockMeta = Meta & 0x7; break; } } + case BLOCK_FACE_NONE: return false; } // switch (a_BlockFace) return true; } diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h index 1072b7e71..09ff254a6 100644 --- a/src/Blocks/BlockStairs.h +++ b/src/Blocks/BlockStairs.h @@ -30,9 +30,7 @@ public: UNUSED(a_BlockY); UNUSED(a_BlockZ); UNUSED(a_CursorX); - UNUSED(a_CursorY); UNUSED(a_CursorZ); - UNUSED(a_BlockMeta); a_BlockType = m_BlockType; a_BlockMeta = RotationToMetaData(a_Player->GetYaw()); switch (a_BlockFace) @@ -51,10 +49,12 @@ public: } break; } + case BLOCK_FACE_NONE: return false; } return true; } + virtual const char * GetStepSound(void) override { if ( diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index e796a45ae..7bb9dc484 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -197,14 +197,14 @@ public: virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override { // Bits 2 and 4 stay, bits 1 and 3 swap - return ((a_Meta & 0x0a) | ((a_Meta & 0x01) << 2) | ((a_Meta & 0x04) >> 2)); + return (NIBBLETYPE)((a_Meta & 0x0a) | ((a_Meta & 0x01) << 2) | ((a_Meta & 0x04) >> 2)); } virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override { // Bits 1 and 3 stay, bits 2 and 4 swap - return ((a_Meta & 0x05) | ((a_Meta & 0x02) << 2) | ((a_Meta & 0x08) >> 2)); + return (NIBBLETYPE)((a_Meta & 0x05) | ((a_Meta & 0x02) << 2) | ((a_Meta & 0x08) >> 2)); } } ; From b9a090d835c9434570166b7cddcb8b6d7e2628e4 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 15:00:30 +0200 Subject: [PATCH 107/145] Fixed clang warnings in cGZipFile. --- src/OSSupport/GZipFile.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OSSupport/GZipFile.cpp b/src/OSSupport/GZipFile.cpp index b13e519e0..7a8433f4f 100644 --- a/src/OSSupport/GZipFile.cpp +++ b/src/OSSupport/GZipFile.cpp @@ -78,7 +78,7 @@ int cGZipFile::ReadRestOfFile(AString & a_Contents) while ((NumBytesRead = gzread(m_File, Buffer, sizeof(Buffer))) > 0) { TotalBytes += NumBytesRead; - a_Contents.append(Buffer, NumBytesRead); + a_Contents.append(Buffer, (size_t)NumBytesRead); } // NumBytesRead is < 0 on error return (NumBytesRead >= 0) ? TotalBytes : NumBytesRead; @@ -102,7 +102,7 @@ bool cGZipFile::Write(const char * a_Contents, int a_Size) return false; } - return (gzwrite(m_File, a_Contents, a_Size) != 0); + return (gzwrite(m_File, a_Contents, (unsigned int)a_Size) != 0); } From 2672b14c036f74548f970349aa08b6cb02600688 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 16:00:20 +0200 Subject: [PATCH 108/145] More cFile warning fixes. --- src/OSSupport/File.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index 75ea198a8..7f0f0ad2f 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -232,7 +232,7 @@ int cFile::GetSize(void) const return -1; } int res = Tell(); - if (fseek(m_File, (size_t)CurPos, SEEK_SET) != 0) + if (fseek(m_File, (long)CurPos, SEEK_SET) != 0) { return -1; } From 0d916a3e2f8947af6bc7da6e19d23522ba014f6d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 16:10:08 +0200 Subject: [PATCH 109/145] Removed the exit-time-destructors flag from clang. We don't care about exit-time destructors, at least for now. --- SetFlags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index d90ad8b48..c5a3a0697 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -198,7 +198,7 @@ macro(set_exe_flags) add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=shadow") add_flags_cxx("-Wno-error=exit-time-destructors -Wno-error=missing-variable-declarations") add_flags_cxx("-Wno-error=global-constructors -Wno-implicit-fallthrough") - add_flags_cxx("-Wno-weak-vtables -Wno-switch-enum") + add_flags_cxx("-Wno-weak-vtables -Wno-switch-enum -Wno-exit-time-destructors") endif() endif() From 1795cca5522476006d33d0c276e27a50659c867a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 16:36:00 +0200 Subject: [PATCH 110/145] Rewritten HTTPServer to use size_t for data lengths. --- src/HTTPServer/EnvelopeParser.cpp | 4 ++-- src/HTTPServer/EnvelopeParser.h | 29 +++++++++++++---------- src/HTTPServer/HTTPConnection.cpp | 14 +++++------ src/HTTPServer/HTTPConnection.h | 4 ++-- src/HTTPServer/HTTPFormParser.cpp | 2 +- src/HTTPServer/HTTPFormParser.h | 4 ++-- src/HTTPServer/HTTPMessage.cpp | 28 +++++++++++----------- src/HTTPServer/HTTPMessage.h | 14 ++++++----- src/HTTPServer/HTTPServer.cpp | 6 ++--- src/HTTPServer/HTTPServer.h | 10 ++++---- src/HTTPServer/MultipartParser.cpp | 8 +++---- src/HTTPServer/MultipartParser.h | 38 ++++++++++++++++-------------- src/HTTPServer/NameValueParser.cpp | 8 +++---- src/HTTPServer/NameValueParser.h | 4 ++-- src/WebAdmin.cpp | 4 ++-- src/WebAdmin.h | 10 ++++---- 16 files changed, 97 insertions(+), 90 deletions(-) diff --git a/src/HTTPServer/EnvelopeParser.cpp b/src/HTTPServer/EnvelopeParser.cpp index 8dbe05f14..fd4f3836d 100644 --- a/src/HTTPServer/EnvelopeParser.cpp +++ b/src/HTTPServer/EnvelopeParser.cpp @@ -20,7 +20,7 @@ cEnvelopeParser::cEnvelopeParser(cCallbacks & a_Callbacks) : -int cEnvelopeParser::Parse(const char * a_Data, int a_Size) +size_t cEnvelopeParser::Parse(const char * a_Data, size_t a_Size) { if (!m_IsInHeaders) { @@ -55,7 +55,7 @@ int cEnvelopeParser::Parse(const char * a_Data, int a_Size) { // An error has occurred m_IsInHeaders = false; - return -1; + return AString::npos; } Last = idxCRLF + 2; idxCRLF = m_IncomingData.find("\r\n", idxCRLF + 2); diff --git a/src/HTTPServer/EnvelopeParser.h b/src/HTTPServer/EnvelopeParser.h index 6430fbebf..9b6c7f369 100644 --- a/src/HTTPServer/EnvelopeParser.h +++ b/src/HTTPServer/EnvelopeParser.h @@ -19,7 +19,9 @@ public: class cCallbacks { public: - /// Called when a full header line is parsed + virtual ~cCallbacks() {} + + /** Called when a full header line is parsed */ virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) = 0; } ; @@ -27,40 +29,41 @@ public: cEnvelopeParser(cCallbacks & a_Callbacks); /** Parses the incoming data. - Returns the number of bytes consumed from the input. The bytes not consumed are not part of the envelope header + Returns the number of bytes consumed from the input. The bytes not consumed are not part of the envelope header. + Returns AString::npos on error */ - int Parse(const char * a_Data, int a_Size); + size_t Parse(const char * a_Data, size_t a_Size); - /// Makes the parser forget everything parsed so far, so that it can be reused for parsing another datastream + /** Makes the parser forget everything parsed so far, so that it can be reused for parsing another datastream */ void Reset(void); - /// Returns true if more input is expected for the envelope header + /** Returns true if more input is expected for the envelope header */ bool IsInHeaders(void) const { return m_IsInHeaders; } - /// Sets the IsInHeaders flag; used by cMultipartParser to simplify the parser initial conditions + /** Sets the IsInHeaders flag; used by cMultipartParser to simplify the parser initial conditions */ void SetIsInHeaders(bool a_IsInHeaders) { m_IsInHeaders = a_IsInHeaders; } public: - /// Callbacks to call for the various events + /** Callbacks to call for the various events */ cCallbacks & m_Callbacks; - /// Set to true while the parser is still parsing the envelope headers. Once set to true, the parser will not consume any more data. + /** Set to true while the parser is still parsing the envelope headers. Once set to true, the parser will not consume any more data. */ bool m_IsInHeaders; - /// Buffer for the incoming data until it is parsed + /** Buffer for the incoming data until it is parsed */ AString m_IncomingData; - /// Holds the last parsed key; used for line-wrapped values + /** Holds the last parsed key; used for line-wrapped values */ AString m_LastKey; - /// Holds the last parsed value; used for line-wrapped values + /** Holds the last parsed value; used for line-wrapped values */ AString m_LastValue; - /// Notifies the callback of the key/value stored in m_LastKey/m_LastValue, then erases them + /** Notifies the callback of the key/value stored in m_LastKey/m_LastValue, then erases them */ void NotifyLast(void); - /// Parses one line of header data. Returns true if successful + /** Parses one line of header data. Returns true if successful */ bool ParseLine(const char * a_Data, size_t a_Size); } ; diff --git a/src/HTTPServer/HTTPConnection.cpp b/src/HTTPServer/HTTPConnection.cpp index 78b7ce4d9..b8635d893 100644 --- a/src/HTTPServer/HTTPConnection.cpp +++ b/src/HTTPServer/HTTPConnection.cpp @@ -67,7 +67,7 @@ void cHTTPConnection::Send(const cHTTPResponse & a_Response) -void cHTTPConnection::Send(const void * a_Data, int a_Size) +void cHTTPConnection::Send(const void * a_Data, size_t a_Size) { ASSERT(m_State == wcsSendingResp); AppendPrintf(m_OutgoingData, "%x\r\n", a_Size); @@ -155,8 +155,8 @@ void cHTTPConnection::DataReceived(const char * a_Data, int a_Size) m_CurrentRequest = new cHTTPRequest; } - int BytesConsumed = m_CurrentRequest->ParseHeaders(a_Data, a_Size); - if (BytesConsumed < 0) + size_t BytesConsumed = m_CurrentRequest->ParseHeaders(a_Data, a_Size); + if (BytesConsumed == AString::npos) { delete m_CurrentRequest; m_CurrentRequest = NULL; @@ -174,16 +174,16 @@ void cHTTPConnection::DataReceived(const char * a_Data, int a_Size) m_State = wcsRecvBody; m_HTTPServer.NewRequest(*this, *m_CurrentRequest); m_CurrentRequestBodyRemaining = m_CurrentRequest->GetContentLength(); - if (m_CurrentRequestBodyRemaining < 0) + if (m_CurrentRequestBodyRemaining == AString::npos) { // The body length was not specified in the request, assume zero m_CurrentRequestBodyRemaining = 0; } // Process the rest of the incoming data into the request body: - if (a_Size > BytesConsumed) + if (a_Size > (int)BytesConsumed) { - DataReceived(a_Data + BytesConsumed, a_Size - BytesConsumed); + DataReceived(a_Data + BytesConsumed, a_Size - (int)BytesConsumed); } else { @@ -197,7 +197,7 @@ void cHTTPConnection::DataReceived(const char * a_Data, int a_Size) ASSERT(m_CurrentRequest != NULL); if (m_CurrentRequestBodyRemaining > 0) { - int BytesToConsume = std::min(m_CurrentRequestBodyRemaining, a_Size); + size_t BytesToConsume = std::min(m_CurrentRequestBodyRemaining, (size_t)a_Size); m_HTTPServer.RequestBody(*this, *m_CurrentRequest, a_Data, BytesToConsume); m_CurrentRequestBodyRemaining -= BytesToConsume; } diff --git a/src/HTTPServer/HTTPConnection.h b/src/HTTPServer/HTTPConnection.h index 5b8103554..0ad409c51 100644 --- a/src/HTTPServer/HTTPConnection.h +++ b/src/HTTPServer/HTTPConnection.h @@ -51,7 +51,7 @@ public: void Send(const cHTTPResponse & a_Response); /** Sends the data as the response (may be called multiple times) */ - void Send(const void * a_Data, int a_Size); + void Send(const void * a_Data, size_t a_Size); /** Sends the data as the response (may be called multiple times) */ void Send(const AString & a_Data) { Send(a_Data.data(), a_Data.size()); } @@ -87,7 +87,7 @@ protected: /** Number of bytes that remain to read for the complete body of the message to be received. Valid only in wcsRecvBody */ - int m_CurrentRequestBodyRemaining; + size_t m_CurrentRequestBodyRemaining; // cSocketThreads::cCallback overrides: diff --git a/src/HTTPServer/HTTPFormParser.cpp b/src/HTTPServer/HTTPFormParser.cpp index e661ea6f9..14d97bb7d 100644 --- a/src/HTTPServer/HTTPFormParser.cpp +++ b/src/HTTPServer/HTTPFormParser.cpp @@ -243,7 +243,7 @@ void cHTTPFormParser::OnPartHeader(const AString & a_Key, const AString & a_Valu -void cHTTPFormParser::OnPartData(const char * a_Data, int a_Size) +void cHTTPFormParser::OnPartData(const char * a_Data, size_t a_Size) { if (m_CurrentPartName.empty()) { diff --git a/src/HTTPServer/HTTPFormParser.h b/src/HTTPServer/HTTPFormParser.h index a554ca5a4..b8e6d246c 100644 --- a/src/HTTPServer/HTTPFormParser.h +++ b/src/HTTPServer/HTTPFormParser.h @@ -40,7 +40,7 @@ public: virtual void OnFileStart(cHTTPFormParser & a_Parser, const AString & a_FileName) = 0; /// Called when more file data has come for the current file in the form data - virtual void OnFileData(cHTTPFormParser & a_Parser, const char * a_Data, int a_Size) = 0; + virtual void OnFileData(cHTTPFormParser & a_Parser, const char * a_Data, size_t a_Size) = 0; /// Called when the current file part has ended in the form data virtual void OnFileEnd(cHTTPFormParser & a_Parser) = 0; @@ -103,7 +103,7 @@ protected: // cMultipartParser::cCallbacks overrides: virtual void OnPartStart (void) override; virtual void OnPartHeader(const AString & a_Key, const AString & a_Value) override; - virtual void OnPartData (const char * a_Data, int a_Size) override; + virtual void OnPartData (const char * a_Data, size_t a_Size) override; virtual void OnPartEnd (void) override; } ; diff --git a/src/HTTPServer/HTTPMessage.cpp b/src/HTTPServer/HTTPMessage.cpp index 98627eb8e..4a3611050 100644 --- a/src/HTTPServer/HTTPMessage.cpp +++ b/src/HTTPServer/HTTPMessage.cpp @@ -25,7 +25,7 @@ cHTTPMessage::cHTTPMessage(eKind a_Kind) : m_Kind(a_Kind), - m_ContentLength(-1) + m_ContentLength(AString::npos) { } @@ -81,23 +81,23 @@ cHTTPRequest::cHTTPRequest(void) : -int cHTTPRequest::ParseHeaders(const char * a_Data, int a_Size) +size_t cHTTPRequest::ParseHeaders(const char * a_Data, size_t a_Size) { if (!m_IsValid) { - return -1; + return AString::npos; } if (m_Method.empty()) { // The first line hasn't been processed yet - int res = ParseRequestLine(a_Data, a_Size); - if ((res < 0) || (res == a_Size)) + size_t res = ParseRequestLine(a_Data, a_Size); + if ((res == AString::npos) || (res == a_Size)) { return res; } - int res2 = m_EnvelopeParser.Parse(a_Data + res, a_Size - res); - if (res2 < 0) + size_t res2 = m_EnvelopeParser.Parse(a_Data + res, a_Size - res); + if (res2 == AString::npos) { m_IsValid = false; return res2; @@ -107,8 +107,8 @@ int cHTTPRequest::ParseHeaders(const char * a_Data, int a_Size) if (m_EnvelopeParser.IsInHeaders()) { - int res = m_EnvelopeParser.Parse(a_Data, a_Size); - if (res < 0) + size_t res = m_EnvelopeParser.Parse(a_Data, a_Size); + if (res == AString::npos) { m_IsValid = false; } @@ -138,7 +138,7 @@ AString cHTTPRequest::GetBareURL(void) const -int cHTTPRequest::ParseRequestLine(const char * a_Data, int a_Size) +size_t cHTTPRequest::ParseRequestLine(const char * a_Data, size_t a_Size) { m_IncomingHeaderData.append(a_Data, a_Size); size_t IdxEnd = m_IncomingHeaderData.size(); @@ -158,7 +158,7 @@ int cHTTPRequest::ParseRequestLine(const char * a_Data, int a_Size) if (LineStart >= IdxEnd) { m_IsValid = false; - return -1; + return AString::npos; } int NumSpaces = 0; @@ -186,7 +186,7 @@ int cHTTPRequest::ParseRequestLine(const char * a_Data, int a_Size) { // Too many spaces in the request m_IsValid = false; - return -1; + return AString::npos; } } NumSpaces += 1; @@ -198,13 +198,13 @@ int cHTTPRequest::ParseRequestLine(const char * a_Data, int a_Size) { // LF too early, without a CR, without two preceeding spaces or too soon after the second space m_IsValid = false; - return -1; + return AString::npos; } // Check that there's HTTP/version at the end if (strncmp(a_Data + URLEnd + 1, "HTTP/1.", 7) != 0) { m_IsValid = false; - return -1; + return AString::npos; } m_Method = m_IncomingHeaderData.substr(LineStart, MethodEnd - LineStart); m_URL = m_IncomingHeaderData.substr(MethodEnd + 1, URLEnd - MethodEnd - 1); diff --git a/src/HTTPServer/HTTPMessage.h b/src/HTTPServer/HTTPMessage.h index ab3338db7..d4d96f7cb 100644 --- a/src/HTTPServer/HTTPMessage.h +++ b/src/HTTPServer/HTTPMessage.h @@ -42,7 +42,7 @@ public: void SetContentLength(int a_ContentLength) { m_ContentLength = a_ContentLength; } const AString & GetContentType (void) const { return m_ContentType; } - int GetContentLength(void) const { return m_ContentLength; } + size_t GetContentLength(void) const { return m_ContentLength; } protected: typedef std::map cNameValueMap; @@ -54,8 +54,10 @@ protected: /** Type of the content; parsed by AddHeader(), set directly by SetContentLength() */ AString m_ContentType; - /** Length of the content that is to be received. -1 when the object is created, parsed by AddHeader() or set directly by SetContentLength() */ - int m_ContentLength; + /** Length of the content that is to be received. + AString::npos when the object is created. + Parsed by AddHeader() or set directly by SetContentLength() */ + size_t m_ContentLength; } ; @@ -72,9 +74,9 @@ public: cHTTPRequest(void); /** Parses the request line and then headers from the received data. - Returns the number of bytes consumed or a negative number for error + Returns the number of bytes consumed or AString::npos number for error */ - int ParseHeaders(const char * a_Data, int a_Size); + size_t ParseHeaders(const char * a_Data, size_t a_Size); /** Returns true if the request did contain a Content-Length header */ bool HasReceivedContentLength(void) const { return (m_ContentLength >= 0); } @@ -145,7 +147,7 @@ protected: /** Parses the incoming data for the first line (RequestLine) Returns the number of bytes consumed, or -1 for an error */ - int ParseRequestLine(const char * a_Data, int a_Size); + size_t ParseRequestLine(const char * a_Data, size_t a_Size); // cEnvelopeParser::cCallbacks overrides: virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) override; diff --git a/src/HTTPServer/HTTPServer.cpp b/src/HTTPServer/HTTPServer.cpp index 4e9195a00..eaf8405a3 100644 --- a/src/HTTPServer/HTTPServer.cpp +++ b/src/HTTPServer/HTTPServer.cpp @@ -38,7 +38,7 @@ class cDebugCallbacks : } - virtual void OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size) override + virtual void OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size) override { UNUSED(a_Connection); @@ -100,7 +100,7 @@ class cDebugCallbacks : } - virtual void OnFileData(cHTTPFormParser & a_Parser, const char * a_Data, int a_Size) override + virtual void OnFileData(cHTTPFormParser & a_Parser, const char * a_Data, size_t a_Size) override { // TODO } @@ -242,7 +242,7 @@ void cHTTPServer::NewRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Re -void cHTTPServer::RequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size) +void cHTTPServer::RequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size) { m_Callbacks->OnRequestBody(a_Connection, a_Request, a_Data, a_Size); } diff --git a/src/HTTPServer/HTTPServer.h b/src/HTTPServer/HTTPServer.h index 383abb4b6..8eff7d879 100644 --- a/src/HTTPServer/HTTPServer.h +++ b/src/HTTPServer/HTTPServer.h @@ -44,8 +44,9 @@ public: */ virtual void OnRequestBegun(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) = 0; - /// Called when another part of request body has arrived. - virtual void OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size) = 0; + /** Called when another part of request body has arrived. + May be called multiple times for a single request. */ + virtual void OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size) = 0; /// Called when the request body has been fully received in previous calls to OnRequestBody() virtual void OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) = 0; @@ -90,8 +91,9 @@ protected: /// Called by cHTTPConnection when it finishes parsing the request header void NewRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request); - /// Called by cHTTPConenction when it receives more data for the request body - void RequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size); + /** Called by cHTTPConenction when it receives more data for the request body. + May be called multiple times for a single request. */ + void RequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size); /// Called by cHTTPConnection when it detects that the request has finished (all of its body has been received) void RequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & a_Request); diff --git a/src/HTTPServer/MultipartParser.cpp b/src/HTTPServer/MultipartParser.cpp index 14c2c00fa..309495dd7 100644 --- a/src/HTTPServer/MultipartParser.cpp +++ b/src/HTTPServer/MultipartParser.cpp @@ -97,8 +97,6 @@ cMultipartParser::cMultipartParser(const AString & a_ContentType, cCallbacks & a m_EnvelopeParser(*this), m_HasHadData(false) { - static AString s_Multipart = "multipart/"; - // Check that the content type is multipart: AString ContentType(a_ContentType); if (strncmp(ContentType.c_str(), "multipart/", 10) != 0) @@ -146,7 +144,7 @@ cMultipartParser::cMultipartParser(const AString & a_ContentType, cCallbacks & a -void cMultipartParser::Parse(const char * a_Data, int a_Size) +void cMultipartParser::Parse(const char * a_Data, size_t a_Size) { // Skip parsing if invalid if (!m_IsValid) @@ -160,8 +158,8 @@ void cMultipartParser::Parse(const char * a_Data, int a_Size) { if (m_EnvelopeParser.IsInHeaders()) { - int BytesConsumed = m_EnvelopeParser.Parse(m_IncomingData.data(), m_IncomingData.size()); - if (BytesConsumed < 0) + size_t BytesConsumed = m_EnvelopeParser.Parse(m_IncomingData.data(), m_IncomingData.size()); + if (BytesConsumed == AString::npos) { m_IsValid = false; return; diff --git a/src/HTTPServer/MultipartParser.h b/src/HTTPServer/MultipartParser.h index d853929ed..a7395c1cb 100644 --- a/src/HTTPServer/MultipartParser.h +++ b/src/HTTPServer/MultipartParser.h @@ -22,50 +22,52 @@ public: class cCallbacks { public: - /// Called when a new part starts + virtual ~cCallbacks() {} + + /** Called when a new part starts */ virtual void OnPartStart(void) = 0; - /// Called when a complete header line is received for a part + /** Called when a complete header line is received for a part */ virtual void OnPartHeader(const AString & a_Key, const AString & a_Value) = 0; - /// Called when body for a part is received - virtual void OnPartData(const char * a_Data, int a_Size) = 0; + /** Called when body for a part is received */ + virtual void OnPartData(const char * a_Data, size_t a_Size) = 0; - /// Called when the current part ends + /** Called when the current part ends */ virtual void OnPartEnd(void) = 0; } ; - /// Creates the parser, expects to find the boundary in a_ContentType + /** Creates the parser, expects to find the boundary in a_ContentType */ cMultipartParser(const AString & a_ContentType, cCallbacks & a_Callbacks); - /// Parses more incoming data - void Parse(const char * a_Data, int a_Size); + /** Parses more incoming data */ + void Parse(const char * a_Data, size_t a_Size); protected: - /// The callbacks to call for various parsing events + /** The callbacks to call for various parsing events */ cCallbacks & m_Callbacks; - /// True if the data parsed so far is valid; if false, further parsing is skipped + /** True if the data parsed so far is valid; if false, further parsing is skipped */ bool m_IsValid; - /// Parser for each part's envelope + /** Parser for each part's envelope */ cEnvelopeParser m_EnvelopeParser; - /// Buffer for the incoming data until it is parsed + /** Buffer for the incoming data until it is parsed */ AString m_IncomingData; - /// The boundary, excluding both the initial "--" and the terminating CRLF + /** The boundary, excluding both the initial "--" and the terminating CRLF */ AString m_Boundary; - /// Set to true if some data for the current part has already been signalized to m_Callbacks. Used for proper CRLF inserting. + /** Set to true if some data for the current part has already been signalized to m_Callbacks. Used for proper CRLF inserting. */ bool m_HasHadData; - /// Parse one line of incoming data. The CRLF has already been stripped from a_Data / a_Size - void ParseLine(const char * a_Data, int a_Size); + /** Parse one line of incoming data. The CRLF has already been stripped from a_Data / a_Size */ + void ParseLine(const char * a_Data, size_t a_Size); - /// Parse one line of incoming data in the headers section of a part. The CRLF has already been stripped from a_Data / a_Size - void ParseHeaderLine(const char * a_Data, int a_Size); + /** Parse one line of incoming data in the headers section of a part. The CRLF has already been stripped from a_Data / a_Size */ + void ParseHeaderLine(const char * a_Data, size_t a_Size); // cEnvelopeParser overrides: virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) override; diff --git a/src/HTTPServer/NameValueParser.cpp b/src/HTTPServer/NameValueParser.cpp index 9ea8594ae..3f6c17dda 100644 --- a/src/HTTPServer/NameValueParser.cpp +++ b/src/HTTPServer/NameValueParser.cpp @@ -24,7 +24,7 @@ public: // Now try parsing char-by-char, to debug transitions across datachunk boundaries: cNameValueParser Parser2; - for (int i = 0; i < sizeof(Data) - 1; i++) + for (size_t i = 0; i < sizeof(Data) - 1; i++) { Parser2.Parse(Data + i, 1); } @@ -82,7 +82,7 @@ cNameValueParser::cNameValueParser(bool a_AllowsKeyOnly) : -cNameValueParser::cNameValueParser(const char * a_Data, int a_Size, bool a_AllowsKeyOnly) : +cNameValueParser::cNameValueParser(const char * a_Data, size_t a_Size, bool a_AllowsKeyOnly) : m_State(psKeySpace), m_AllowsKeyOnly(a_AllowsKeyOnly) { @@ -93,12 +93,12 @@ cNameValueParser::cNameValueParser(const char * a_Data, int a_Size, bool a_Allow -void cNameValueParser::Parse(const char * a_Data, int a_Size) +void cNameValueParser::Parse(const char * a_Data, size_t a_Size) { ASSERT(m_State != psFinished); // Calling Parse() after Finish() is wrong! int Last = 0; - for (int i = 0; i < a_Size;) + for (size_t i = 0; i < a_Size;) { switch (m_State) { diff --git a/src/HTTPServer/NameValueParser.h b/src/HTTPServer/NameValueParser.h index 07dc0b942..9794614fa 100644 --- a/src/HTTPServer/NameValueParser.h +++ b/src/HTTPServer/NameValueParser.h @@ -21,10 +21,10 @@ public: cNameValueParser(bool a_AllowsKeyOnly = true); /// Creates an empty parser, then parses the data given. Doesn't call Finish(), so more data can be parsed later - cNameValueParser(const char * a_Data, int a_Size, bool a_AllowsKeyOnly = true); + cNameValueParser(const char * a_Data, size_t a_Size, bool a_AllowsKeyOnly = true); /// Parses the data given - void Parse(const char * a_Data, int a_Size); + void Parse(const char * a_Data, size_t a_Size); /// Notifies the parser that no more data will be coming. Returns true if the parser state is valid bool Finish(void); diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index 402cd3035..cd141f7eb 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -490,7 +490,7 @@ void cWebAdmin::OnRequestBegun(cHTTPConnection & a_Connection, cHTTPRequest & a_ -void cWebAdmin::OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size) +void cWebAdmin::OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size) { UNUSED(a_Connection); cRequestData * Data = (cRequestData *)(a_Request.GetUserData()); @@ -537,7 +537,7 @@ void cWebAdmin::OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cWebAdmin::cWebadminRequestData -void cWebAdmin::cWebadminRequestData::OnBody(const char * a_Data, int a_Size) +void cWebAdmin::cWebadminRequestData::OnBody(const char * a_Data, size_t a_Size) { m_Form.Parse(a_Data, a_Size); } diff --git a/src/WebAdmin.h b/src/WebAdmin.h index a2a07a543..d5e45828f 100644 --- a/src/WebAdmin.h +++ b/src/WebAdmin.h @@ -151,7 +151,7 @@ protected: virtual ~cRequestData() {} // Force a virtual destructor in all descendants /** Called when a new chunk of body data is received */ - virtual void OnBody(const char * a_Data, int a_Size) = 0; + virtual void OnBody(const char * a_Data, size_t a_Size) = 0; } ; /** The body handler for requests in the "/webadmin" and "/~webadmin" paths */ @@ -169,14 +169,14 @@ protected: } // cRequestData overrides: - virtual void OnBody(const char * a_Data, int a_Size) override; + virtual void OnBody(const char * a_Data, size_t a_Size) override; // cHTTPFormParser::cCallbacks overrides. Files are ignored: - virtual void OnFileStart(cHTTPFormParser &, const AString & a_FileName) override + virtual void OnFileStart(cHTTPFormParser &, const AString & a_FileName) override { UNUSED(a_FileName); } - virtual void OnFileData(cHTTPFormParser &, const char * a_Data, int a_Size) override + virtual void OnFileData(cHTTPFormParser &, const char * a_Data, size_t a_Size) override { UNUSED(a_Data); UNUSED(a_Size); @@ -216,7 +216,7 @@ protected: // cHTTPServer::cCallbacks overrides: virtual void OnRequestBegun (cHTTPConnection & a_Connection, cHTTPRequest & a_Request) override; - virtual void OnRequestBody (cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size) override; + virtual void OnRequestBody (cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size) override; virtual void OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) override; } ; // tolua_export From 1229795ff0fd82412e780fffc9f37a2d6eed5522 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 20:50:10 +0200 Subject: [PATCH 111/145] cBlockArea: Added the msMask merge strategy. --- MCServer/Plugins/APIDump/APIDesc.lua | 23 ++++++++++++++++++--- src/BlockArea.cpp | 30 ++++++++++++++++++++++++++++ src/BlockArea.h | 9 +++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 28e7744ed..9bcd6edde 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -200,6 +200,8 @@ g_APIDesc = msFillAir = { Notes = "Dst is overwritten by Src only where Src has air blocks" }, msImprint = { Notes = "Src overwrites Dst anywhere where Dst has non-air blocks" }, msLake = { Notes = "Special mode for merging lake images" }, + msSpongePrint = { Notes = "Similar to msImprint, sponge block doesn't overwrite anything, all other blocks overwrite everything"}, + msMask = { Notes = "The blocks that are exactly the same are kept in Dst, all differing blocks are replaced by air"}, }, ConstantGroups = { @@ -293,7 +295,6 @@ g_APIDesc = -

    msSpongePrint - used for most prefab-generators to merge the prefabs. Similar to msImprint, but uses the sponge block as the NOP block instead, so that the prefabs may carve out air @@ -306,10 +307,26 @@ g_APIDesc = A sponge A Sponge is the NOP block - * B B Everything else overwrites anything + * B B Everything else overwrites anything - ]], + +

    + msMask - the blocks that are the same in the other area are kept, all the + differing blocks are replaced with air. Meta is used in the comparison, too, two blocks of the + same type but different meta are considered different and thus replaced with air. +

    + + + + + + + + + +
    area block Notes
    this Src result
    A A A Same blocks are kept
    A non-A air Differing blocks are replaced with air
    +]], }, -- Merge strategies }, -- AdditionalInfo }, -- cBlockArea diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 2b950378a..543dbe04d 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -173,6 +173,21 @@ static inline void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a +/** Combinator used for cBlockArea::msMask merging */ +static inline void MergeCombinatorMask(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) +{ + // If the blocks are the same, keep the dest; otherwise replace with air + if ((a_SrcType != a_DstType) || (a_SrcMeta != a_DstMeta)) + { + a_DstType = E_BLOCK_AIR; + a_DstMeta = 0; + } +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cBlockArea: @@ -710,6 +725,21 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R break; } // case msSpongePrint + case msMask: + { + InternalMergeBlocks( + m_BlockTypes, a_Src.GetBlockTypes(), + DstMetas, SrcMetas, + SizeX, SizeY, SizeZ, + SrcOffX, SrcOffY, SrcOffZ, + DstOffX, DstOffY, DstOffZ, + a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), + m_Size.x, m_Size.y, m_Size.z, + MergeCombinatorMask + ); + break; + } // case msMask + default: { LOGWARNING("Unknown block area merge strategy: %d", a_Strategy); diff --git a/src/BlockArea.h b/src/BlockArea.h index d37f0d182..34a0ef926 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -52,6 +52,7 @@ public: msImprint, msLake, msSpongePrint, + msMask, } ; cBlockArea(void); @@ -152,6 +153,14 @@ public: +----------+--------+--------+ | A | sponge | A | Sponge is the NOP block | * | B | B | Everything else overwrites anything + + msMask: + Combines two areas, the blocks that are the same are kept, differing ones are reset to air + | area block | | + | this | Src | result | + +------+-------+--------+ + | A | A | A | Same blocks are kept + | A | non-A | air | Everything else is replaced with air */ void Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy); From 21e0607e49745f0a431fa045967cc45679ab22de Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 1 Apr 2014 21:12:48 +0200 Subject: [PATCH 112/145] APIDump: Gave msDifference it's own table. --- MCServer/Plugins/APIDump/APIDesc.lua | 30 +++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 657ac6aa6..b01be6118 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -230,25 +230,25 @@ g_APIDesc =

    - + - + - + - + - + - + - +
    area blockresultarea blockresult
    this Src msOverwrite msFillAir msImprint msDifference this Src msOverwrite msFillAir msImprint
    air air air air air air air air air air air
    A air air A A air A air air A A
    air B B B B B air B B B B
    A B B A B B A B B A B
    A A A A B air A A A A A
    @@ -258,13 +258,25 @@ g_APIDesc =
  • msOverwrite completely overwrites all blocks with the Src's blocks
  • msFillAir overwrites only those blocks that were air
  • msImprint overwrites with only those blocks that are non-air
  • -
  • msDifference changes all the blocks which are the same to air. Otherwise the source block gets placed.
  • Special strategies

    For each strategy, evaluate the table rows from top downwards, the first match wins.

    - + +

    + msDifference - changes all the blocks which are the same to air. Otherwise the source block gets placed. +

    + + + + + + + +
    area block Notes
    * B B The blocks are different so we use block B
    B B Air The blocks are the same so we get air.
    + +

    msLake - used for merging areas with lava and water lakes, in the appropriate generator.

    From bcf5021feb3bbb8069b80e3b892f0c80db35a4c6 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 22:47:39 +0200 Subject: [PATCH 113/145] Exported the Base64 encoding and decoding functions to Lua API. --- src/Bindings/ManualBindings.cpp | 46 +++++++++++++++++++++++++++++++++ src/StringUtils.h | 4 +-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 9d1a367df..51b9f3e27 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -190,6 +190,50 @@ static int tolua_LOGERROR(lua_State * tolua_S) +static int tolua_Base64Encode(lua_State * tolua_S) +{ + cLuaState L(tolua_S); + if ( + !L.CheckParamString(1) || + !L.CheckParamEnd(2) + ) + { + return 0; + } + + AString Src; + L.GetStackValue(1, Src); + AString res = Base64Encode(Src); + L.Push(res); + return 1; +} + + + + + +static int tolua_Base64Decode(lua_State * tolua_S) +{ + cLuaState L(tolua_S); + if ( + !L.CheckParamString(1) || + !L.CheckParamEnd(2) + ) + { + return 0; + } + + AString Src; + L.GetStackValue(1, Src); + AString res = Base64Decode(Src); + L.Push(res); + return 1; +} + + + + + cPluginLua * GetLuaPlugin(lua_State * L) { // Get the plugin identification out of LuaState: @@ -2869,6 +2913,8 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "LOGWARN", tolua_LOGWARN); tolua_function(tolua_S, "LOGWARNING", tolua_LOGWARN); tolua_function(tolua_S, "LOGERROR", tolua_LOGERROR); + tolua_function(tolua_S, "Base64Encode", tolua_Base64Encode); + tolua_function(tolua_S, "Base64Decode", tolua_Base64Decode); tolua_beginmodule(tolua_S, "cFile"); tolua_function(tolua_S, "GetFolderContents", tolua_cFile_GetFolderContents); diff --git a/src/StringUtils.h b/src/StringUtils.h index 4feff7553..da395e5b5 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -79,10 +79,10 @@ extern AString URLDecode(const AString & a_String); // Cannot export to Lua aut extern AString ReplaceAllCharOccurrences(const AString & a_String, char a_From, char a_To); // Needn't export to Lua, since Lua doesn't have chars anyway /// Decodes a Base64-encoded string into the raw data -extern AString Base64Decode(const AString & a_Base64String); +extern AString Base64Decode(const AString & a_Base64String); // Exported manually due to embedded NULs and extra parameter /// Encodes a string into Base64 -extern AString Base64Encode(const AString & a_Input); +extern AString Base64Encode(const AString & a_Input); // Exported manually due to embedded NULs and extra parameter /// Reads two bytes from the specified memory location and interprets them as BigEndian short extern short GetBEShort(const char * a_Mem); From 3301c5be1ff9d26d3189c031eb28e5f46c9edccd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 2 Apr 2014 11:56:10 +0200 Subject: [PATCH 114/145] Fixed StringCompression's GZIP handling for larger strings. --- src/StringCompression.cpp | 8 +++++--- src/StringCompression.h | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/StringCompression.cpp b/src/StringCompression.cpp index 5b9a3bb0a..2a85649a1 100644 --- a/src/StringCompression.cpp +++ b/src/StringCompression.cpp @@ -53,7 +53,7 @@ int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed -int CompressStringGZIP(const char * a_Data, int a_Length, AString & a_Compressed) +int CompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Compressed) { // Compress a_Data into a_Compressed using GZIP; return Z_XXX error constants same as zlib's compress2() @@ -83,6 +83,7 @@ int CompressStringGZIP(const char * a_Data, int a_Length, AString & a_Compressed { // Some data has been compressed. Consume the buffer and continue compressing a_Compressed.append(Buffer, sizeof(Buffer) - strm.avail_out); + strm.next_out = (Bytef *)Buffer; strm.avail_out = sizeof(Buffer); if (strm.avail_in == 0) { @@ -116,7 +117,7 @@ int CompressStringGZIP(const char * a_Data, int a_Length, AString & a_Compressed -extern int UncompressStringGZIP(const char * a_Data, int a_Length, AString & a_Uncompressed) +extern int UncompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Uncompressed) { // Uncompresses a_Data into a_Uncompressed using GZIP; returns Z_OK for success or Z_XXX error constants same as zlib @@ -139,13 +140,14 @@ extern int UncompressStringGZIP(const char * a_Data, int a_Length, AString & a_U for (;;) { - res = inflate(&strm, Z_FINISH); + res = inflate(&strm, Z_NO_FLUSH); switch (res) { case Z_OK: { // Some data has been uncompressed. Consume the buffer and continue uncompressing a_Uncompressed.append(Buffer, sizeof(Buffer) - strm.avail_out); + strm.next_out = (Bytef *)Buffer; strm.avail_out = sizeof(Buffer); if (strm.avail_in == 0) { diff --git a/src/StringCompression.h b/src/StringCompression.h index 3f4e12d2d..c3a9eca91 100644 --- a/src/StringCompression.h +++ b/src/StringCompression.h @@ -16,10 +16,10 @@ extern int CompressString(const char * a_Data, int a_Length, AString & a_Compres extern int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed, int a_UncompressedSize); /// Compresses a_Data into a_Compressed using GZIP; returns Z_OK for success or Z_XXX error constants same as zlib -extern int CompressStringGZIP(const char * a_Data, int a_Length, AString & a_Compressed); +extern int CompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Compressed); /// Uncompresses a_Data into a_Uncompressed using GZIP; returns Z_OK for success or Z_XXX error constants same as zlib -extern int UncompressStringGZIP(const char * a_Data, int a_Length, AString & a_Uncompressed); +extern int UncompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Uncompressed); From bcd7f9669ba98f4ecb71ba728d72836ff14b3c0f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 2 Apr 2014 11:56:27 +0200 Subject: [PATCH 115/145] Added schematic string serializer self-test. --- src/WorldStorage/SchematicFileSerializer.cpp | 33 ++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp index d8531d965..9d594a084 100644 --- a/src/WorldStorage/SchematicFileSerializer.cpp +++ b/src/WorldStorage/SchematicFileSerializer.cpp @@ -14,6 +14,39 @@ +#ifdef SELF_TEST + +static class cSchematicStringSelfTest +{ +public: + cSchematicStringSelfTest(void) + { + cBlockArea ba; + ba.Create(21, 256, 21); + ba.RelLine(0, 0, 0, 9, 8, 7, cBlockArea::baTypes | cBlockArea::baMetas, E_BLOCK_WOODEN_STAIRS, 1); + AString Schematic; + if (!cSchematicFileSerializer::SaveToSchematicString(ba, Schematic)) + { + assert_test(!"Schematic failed to save!"); + } + cBlockArea ba2; + if (!cSchematicFileSerializer::LoadFromSchematicString(ba2, Schematic)) + { + assert_test(!"Schematic failed to load!"); + } + } +} g_SelfTest; + +#endif + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cSchematicFileSerializer: + bool cSchematicFileSerializer::LoadFromSchematicFile(cBlockArea & a_BlockArea, const AString & a_FileName) { // Un-GZip the contents: From 67d7ad86896e90b799a0479a86a6e764c7fe36da Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 2 Apr 2014 11:58:19 +0200 Subject: [PATCH 116/145] Debuggers: Added a Base64 API roundtrip test. --- MCServer/Plugins/Debuggers/Debuggers.lua | 27 ++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index 2619bd6c4..064d5d772 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -69,12 +69,13 @@ function Initialize(Plugin) LOG("Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion()) - -- TestBlockAreas(); - -- TestSQLiteBindings(); - -- TestExpatBindings(); - -- TestPluginCalls(); + -- TestBlockAreas() + -- TestSQLiteBindings() + -- TestExpatBindings() + -- TestPluginCalls() TestBlockAreasString() + TestStringBase64() --[[ -- Test cCompositeChat usage in console-logging: @@ -252,6 +253,24 @@ end +function TestStringBase64() + -- Create a binary string: + local s = "" + for i = 0, 255 do + s = s .. string.char(i) + end + + -- Roundtrip through Base64: + local Base64 = Base64Encode(s) + local UnBase64 = Base64Decode(Base64) + + assert(UnBase64 == s) +end + + + + + function TestSQLiteBindings() LOG("Testing SQLite bindings..."); From 93bb5369a89eeda9c456574d8a72ebcac095ddd0 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 2 Apr 2014 05:06:38 -0700 Subject: [PATCH 117/145] Fixed Comparison to -1 in HTTPMessage.h --- src/HTTPServer/HTTPMessage.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HTTPServer/HTTPMessage.h b/src/HTTPServer/HTTPMessage.h index d4d96f7cb..c2d310839 100644 --- a/src/HTTPServer/HTTPMessage.h +++ b/src/HTTPServer/HTTPMessage.h @@ -79,7 +79,7 @@ public: size_t ParseHeaders(const char * a_Data, size_t a_Size); /** Returns true if the request did contain a Content-Length header */ - bool HasReceivedContentLength(void) const { return (m_ContentLength >= 0); } + bool HasReceivedContentLength(void) const { return (m_ContentLength != AString::npos); } /** Returns the method used in the request */ const AString & GetMethod(void) const { return m_Method; } From 7ece0cc8369a7600ea8667188e83a2cb9ef6570b Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 2 Apr 2014 05:10:08 -0700 Subject: [PATCH 118/145] Fixed format string in HTTPConnection --- src/HTTPServer/HTTPConnection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HTTPServer/HTTPConnection.cpp b/src/HTTPServer/HTTPConnection.cpp index b8635d893..6d238f028 100644 --- a/src/HTTPServer/HTTPConnection.cpp +++ b/src/HTTPServer/HTTPConnection.cpp @@ -70,7 +70,7 @@ void cHTTPConnection::Send(const cHTTPResponse & a_Response) void cHTTPConnection::Send(const void * a_Data, size_t a_Size) { ASSERT(m_State == wcsSendingResp); - AppendPrintf(m_OutgoingData, "%x\r\n", a_Size); + AppendPrintf(m_OutgoingData, SIZE_T_FMT "\r\n", a_Size); m_OutgoingData.append((const char *)a_Data, a_Size); m_OutgoingData.append("\r\n"); m_HTTPServer.NotifyConnectionWrite(*this); From 1f5a4a39f2cd9f63a7e5695689042d3c43b2e83b Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 2 Apr 2014 06:36:25 -0700 Subject: [PATCH 119/145] Fixed All signedness warnings in HTTPServer.cpp --- src/ClientHandle.cpp | 2 +- src/ClientHandle.h | 2 +- src/HTTPServer/HTTPConnection.cpp | 6 +++--- src/HTTPServer/HTTPConnection.h | 2 +- src/HTTPServer/HTTPFormParser.cpp | 4 ++-- src/HTTPServer/HTTPFormParser.h | 7 +++++-- src/HTTPServer/HTTPMessage.h | 2 +- src/OSSupport/SocketThreads.h | 2 +- src/RCONServer.cpp | 2 +- src/RCONServer.h | 2 +- 10 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 5ed5f1085..4513cfb38 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -2633,7 +2633,7 @@ void cClientHandle::PacketError(unsigned char a_PacketType) -void cClientHandle::DataReceived(const char * a_Data, int a_Size) +void cClientHandle::DataReceived(const char * a_Data, size_t a_Size) { // Data is received from the client, store it in the buffer to be processed by the Tick thread: m_TimeSinceLastPacket = 0; diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 8366caa16..3fb653012 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -362,7 +362,7 @@ private: void HandleCommandBlockMessage(const char * a_Data, unsigned int a_Length); // cSocketThreads::cCallback overrides: - virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client + virtual void DataReceived (const char * a_Data, size_t a_Size) override; // Data is received from the client virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client virtual void SocketClosed (void) override; // The socket has been closed for any reason }; // tolua_export diff --git a/src/HTTPServer/HTTPConnection.cpp b/src/HTTPServer/HTTPConnection.cpp index 6d238f028..44a3d3f88 100644 --- a/src/HTTPServer/HTTPConnection.cpp +++ b/src/HTTPServer/HTTPConnection.cpp @@ -144,7 +144,7 @@ void cHTTPConnection::Terminate(void) -void cHTTPConnection::DataReceived(const char * a_Data, int a_Size) +void cHTTPConnection::DataReceived(const char * a_Data, size_t a_Size) { switch (m_State) { @@ -181,9 +181,9 @@ void cHTTPConnection::DataReceived(const char * a_Data, int a_Size) } // Process the rest of the incoming data into the request body: - if (a_Size > (int)BytesConsumed) + if (a_Size > BytesConsumed) { - DataReceived(a_Data + BytesConsumed, a_Size - (int)BytesConsumed); + DataReceived(a_Data + BytesConsumed, a_Size - BytesConsumed); } else { diff --git a/src/HTTPServer/HTTPConnection.h b/src/HTTPServer/HTTPConnection.h index 0ad409c51..fc11f1ba6 100644 --- a/src/HTTPServer/HTTPConnection.h +++ b/src/HTTPServer/HTTPConnection.h @@ -91,7 +91,7 @@ protected: // cSocketThreads::cCallback overrides: - virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client + virtual void DataReceived (const char * a_Data, size_t a_Size) override; // Data is received from the client virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client virtual void SocketClosed (void) override; // The socket has been closed for any reason } ; diff --git a/src/HTTPServer/HTTPFormParser.cpp b/src/HTTPServer/HTTPFormParser.cpp index 14d97bb7d..9ddfb82f1 100644 --- a/src/HTTPServer/HTTPFormParser.cpp +++ b/src/HTTPServer/HTTPFormParser.cpp @@ -52,7 +52,7 @@ cHTTPFormParser::cHTTPFormParser(cHTTPRequest & a_Request, cCallbacks & a_Callba -cHTTPFormParser::cHTTPFormParser(eKind a_Kind, const char * a_Data, int a_Size, cCallbacks & a_Callbacks) : +cHTTPFormParser::cHTTPFormParser(eKind a_Kind, const char * a_Data, size_t a_Size, cCallbacks & a_Callbacks) : m_Callbacks(a_Callbacks), m_Kind(a_Kind), m_IsValid(true) @@ -64,7 +64,7 @@ cHTTPFormParser::cHTTPFormParser(eKind a_Kind, const char * a_Data, int a_Size, -void cHTTPFormParser::Parse(const char * a_Data, int a_Size) +void cHTTPFormParser::Parse(const char * a_Data, size_t a_Size) { if (!m_IsValid) { diff --git a/src/HTTPServer/HTTPFormParser.h b/src/HTTPServer/HTTPFormParser.h index b8e6d246c..01d103bb8 100644 --- a/src/HTTPServer/HTTPFormParser.h +++ b/src/HTTPServer/HTTPFormParser.h @@ -36,6 +36,9 @@ public: class cCallbacks { public: + + virtual ~cCallbacks() {}; + /// Called when a new file part is encountered in the form data virtual void OnFileStart(cHTTPFormParser & a_Parser, const AString & a_FileName) = 0; @@ -51,10 +54,10 @@ public: cHTTPFormParser(cHTTPRequest & a_Request, cCallbacks & a_Callbacks); /// Creates a parser with the specified content type that reads data from a string - cHTTPFormParser(eKind a_Kind, const char * a_Data, int a_Size, cCallbacks & a_Callbacks); + cHTTPFormParser(eKind a_Kind, const char * a_Data, size_t a_Size, cCallbacks & a_Callbacks); /// Adds more data into the parser, as the request body is received - void Parse(const char * a_Data, int a_Size); + void Parse(const char * a_Data, size_t a_Size); /** Notifies that there's no more data incoming and the parser should finish its parsing. Returns true if parsing successful diff --git a/src/HTTPServer/HTTPMessage.h b/src/HTTPServer/HTTPMessage.h index c2d310839..dab942136 100644 --- a/src/HTTPServer/HTTPMessage.h +++ b/src/HTTPServer/HTTPMessage.h @@ -39,7 +39,7 @@ public: void AddHeader(const AString & a_Key, const AString & a_Value); void SetContentType (const AString & a_ContentType) { m_ContentType = a_ContentType; } - void SetContentLength(int a_ContentLength) { m_ContentLength = a_ContentLength; } + void SetContentLength(size_t a_ContentLength) { m_ContentLength = a_ContentLength; } const AString & GetContentType (void) const { return m_ContentType; } size_t GetContentLength(void) const { return m_ContentLength; } diff --git a/src/OSSupport/SocketThreads.h b/src/OSSupport/SocketThreads.h index b2eb5950f..679e374e1 100644 --- a/src/OSSupport/SocketThreads.h +++ b/src/OSSupport/SocketThreads.h @@ -64,7 +64,7 @@ public: virtual ~cCallback() {} /** Called when data is received from the remote party */ - virtual void DataReceived(const char * a_Data, int a_Size) = 0; + virtual void DataReceived(const char * a_Data, size_t a_Size) = 0; /** Called when data can be sent to remote party The function is supposed to *set* outgoing data to a_Data (overwrite) */ diff --git a/src/RCONServer.cpp b/src/RCONServer.cpp index 72f2d9ba9..d7083ff2b 100644 --- a/src/RCONServer.cpp +++ b/src/RCONServer.cpp @@ -169,7 +169,7 @@ cRCONServer::cConnection::cConnection(cRCONServer & a_RCONServer, cSocket & a_So -void cRCONServer::cConnection::DataReceived(const char * a_Data, int a_Size) +void cRCONServer::cConnection::DataReceived(const char * a_Data, size_t a_Size) { // Append data to the buffer: m_Buffer.append(a_Data, a_Size); diff --git a/src/RCONServer.h b/src/RCONServer.h index 88aac4b5f..b964852ab 100644 --- a/src/RCONServer.h +++ b/src/RCONServer.h @@ -65,7 +65,7 @@ protected: // cSocketThreads::cCallback overrides: - virtual void DataReceived(const char * a_Data, int a_Size) override; + virtual void DataReceived(const char * a_Data, size_t a_Size) override; virtual void GetOutgoingData(AString & a_Data) override; virtual void SocketClosed(void) override; From 26c3bc4076a455fd61b56c34215771bddb548e1d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 2 Apr 2014 16:39:42 +0200 Subject: [PATCH 120/145] Fixed more virtual destructors for interfaces. --- src/BlockTracer.h | 3 +++ src/HTTPServer/EnvelopeParser.h | 3 +++ src/HTTPServer/HTTPFormParser.h | 3 +++ src/HTTPServer/MultipartParser.h | 3 +++ 4 files changed, 12 insertions(+) diff --git a/src/BlockTracer.h b/src/BlockTracer.h index 40d80da1a..a18c8df4d 100644 --- a/src/BlockTracer.h +++ b/src/BlockTracer.h @@ -28,6 +28,9 @@ public: class cCallbacks abstract { public: + // Force a virtual destructor in descendants: + virtual ~cCallbacks() {} + /** Called on each block encountered along the path, including the first block (path start) When this callback returns true, the tracing is aborted. */ diff --git a/src/HTTPServer/EnvelopeParser.h b/src/HTTPServer/EnvelopeParser.h index 6430fbebf..866bed11d 100644 --- a/src/HTTPServer/EnvelopeParser.h +++ b/src/HTTPServer/EnvelopeParser.h @@ -19,6 +19,9 @@ public: class cCallbacks { public: + // Force a virtual destructor in descendants: + virtual ~cCallbacks() {} + /// Called when a full header line is parsed virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) = 0; } ; diff --git a/src/HTTPServer/HTTPFormParser.h b/src/HTTPServer/HTTPFormParser.h index a554ca5a4..f2a509cb8 100644 --- a/src/HTTPServer/HTTPFormParser.h +++ b/src/HTTPServer/HTTPFormParser.h @@ -36,6 +36,9 @@ public: class cCallbacks { public: + // Force a virtual destructor in descendants: + virtual ~cCallbacks() {} + /// Called when a new file part is encountered in the form data virtual void OnFileStart(cHTTPFormParser & a_Parser, const AString & a_FileName) = 0; diff --git a/src/HTTPServer/MultipartParser.h b/src/HTTPServer/MultipartParser.h index d853929ed..77695fe4a 100644 --- a/src/HTTPServer/MultipartParser.h +++ b/src/HTTPServer/MultipartParser.h @@ -22,6 +22,9 @@ public: class cCallbacks { public: + // Force a virtual destructor in descendants: + virtual ~cCallbacks() {} + /// Called when a new part starts virtual void OnPartStart(void) = 0; From 5c6d4745990a0aa90d0c6c01da65d6e8dfa32bfc Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 2 Apr 2014 16:40:13 +0200 Subject: [PATCH 121/145] Fixed boat placement code. --- src/Items/ItemBoat.h | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Items/ItemBoat.h b/src/Items/ItemBoat.h index a28ec8e22..42f4ffc8f 100644 --- a/src/Items/ItemBoat.h +++ b/src/Items/ItemBoat.h @@ -39,12 +39,20 @@ public: public cBlockTracer::cCallbacks { public: - Vector3d Pos; - virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override + Vector3d m_Pos; + bool m_HasFound; + + cCallbacks(void) : + m_HasFound(false) { - if (a_BlockType != E_BLOCK_AIR) + } + + virtual bool OnNextBlock(int a_CBBlockX, int a_CBBlockY, int a_CBBlockZ, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, char a_CBEntryFace) override + { + if (a_CBBlockType != E_BLOCK_AIR) { - Pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ); + m_Pos.Set(a_CBBlockX, a_CBBlockY, a_CBBlockZ); + m_HasFound = true; return true; } return false; @@ -57,15 +65,15 @@ public: Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z); - double x = Callbacks.Pos.x; - double y = Callbacks.Pos.y; - double z = Callbacks.Pos.z; - - if ((x == 0) && (y == 0) && (z == 0)) + if (!Callbacks.m_HasFound) { return false; } + double x = Callbacks.m_Pos.x; + double y = Callbacks.m_Pos.y; + double z = Callbacks.m_Pos.z; + cBoat * Boat = new cBoat(x + 0.5, y + 1, z + 0.5); Boat->Initialize(a_World); From 43af11ee3808fa9836fc9467cacd73b78118c3c2 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 2 Apr 2014 20:03:42 +0100 Subject: [PATCH 122/145] Removed extra brackets --- src/Blocks/BlockFluid.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h index 1200997ff..1f0c3833c 100644 --- a/src/Blocks/BlockFluid.h +++ b/src/Blocks/BlockFluid.h @@ -1,4 +1,3 @@ - #pragma once #include "BlockHandler.h" @@ -94,10 +93,8 @@ public: BLOCKTYPE BlockType; if ( ((a_RelY + y < 0) || (a_RelY + y > cChunkDef::Height)) || - ( - !a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) || - !cFireSimulator::IsFuel(BlockType) - ) + !a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) || + !cFireSimulator::IsFuel(BlockType) ) { return false; From da267649a183e84280da7eadcb391952fb6a0d1d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 2 Apr 2014 20:04:41 +0100 Subject: [PATCH 123/145] With eXtra line! --- src/Blocks/BlockFluid.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h index 1f0c3833c..d486d642d 100644 --- a/src/Blocks/BlockFluid.h +++ b/src/Blocks/BlockFluid.h @@ -1,3 +1,4 @@ + #pragma once #include "BlockHandler.h" From 12b82de502888103710c1aeae0217a3dcb640637 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 3 Apr 2014 09:26:44 +0200 Subject: [PATCH 124/145] Removed the bindings to set old g_BlockXXX arrays. Those were supposed to be read-only; there's no point in writing to them anyway. Also fixed MSVC type warnings in the code. --- src/Bindings/DeprecatedBindings.cpp | 380 ++++++---------------------- 1 file changed, 74 insertions(+), 306 deletions(-) diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index fbc008be6..d51ba2da3 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -21,20 +21,22 @@ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockLightValue static int tolua_get_AllToLua_g_BlockLightValue(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + { tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushnumber(tolua_S,(lua_Number)cBlockInfo::GetLightValue(tolua_index)); + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) + { + tolua_error(tolua_S, "array indexing out of range.", NULL); + } + tolua_pushnumber(tolua_S,(lua_Number)cBlockInfo::GetLightValue((BLOCKTYPE)BlockType)); return 1; } #endif //#ifndef TOLUA_DISABLE @@ -43,37 +45,11 @@ static int tolua_get_AllToLua_g_BlockLightValue(lua_State* tolua_S) -/* set function: g_BlockLightValue */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockLightValue -static int tolua_set_AllToLua_g_BlockLightValue(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_LightValue = ((unsigned char) tolua_tonumber(tolua_S,3,0)); - return 0; -} -#endif //#ifndef TOLUA_DISABLE - - - - - /* get function: g_BlockSpreadLightFalloff */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockSpreadLightFalloff static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -81,12 +57,12 @@ static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushnumber(tolua_S,(lua_Number)cBlockInfo::GetSpreadLightFalloff(tolua_index)); + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) + { + tolua_error(tolua_S, "array indexing out of range.", NULL); + } + tolua_pushnumber(tolua_S, (lua_Number)cBlockInfo::GetSpreadLightFalloff((BLOCKTYPE)BlockType)); return 1; } #endif //#ifndef TOLUA_DISABLE @@ -95,37 +71,11 @@ static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) -/* set function: g_BlockSpreadLightFalloff */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockSpreadLightFalloff -static int tolua_set_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_SpreadLightFalloff = ((unsigned char) tolua_tonumber(tolua_S,3,0)); - return 0; -} -#endif //#ifndef TOLUA_DISABLE - - - - - /* get function: g_BlockTransparent */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockTransparent static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -133,12 +83,12 @@ static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushboolean(tolua_S, cBlockInfo::IsTransparent(tolua_index)); + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) + { + tolua_error(tolua_S, "array indexing out of range.", NULL); + } + tolua_pushboolean(tolua_S, cBlockInfo::IsTransparent((BLOCKTYPE)BlockType)); return 1; } #endif //#ifndef TOLUA_DISABLE @@ -147,37 +97,11 @@ static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) -/* set function: g_BlockTransparent */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockTransparent -static int tolua_set_AllToLua_g_BlockTransparent(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_Transparent = (tolua_toboolean(tolua_S,3,0) != 0); - return 0; -} -#endif //#ifndef TOLUA_DISABLE - - - - - /* get function: g_BlockOneHitDig */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockOneHitDig static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -185,12 +109,12 @@ static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsOneHitDig(tolua_index)); + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) + { + tolua_error(tolua_S, "array indexing out of range.", NULL); + } + tolua_pushboolean(tolua_S, cBlockInfo::IsOneHitDig((BLOCKTYPE)BlockType)); return 1; } #endif //#ifndef TOLUA_DISABLE @@ -199,37 +123,11 @@ static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) -/* set function: g_BlockOneHitDig */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockOneHitDig -static int tolua_set_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_OneHitDig = (tolua_toboolean(tolua_S,3,0) != 0); - return 0; -} -#endif //#ifndef TOLUA_DISABLE - - - - - /* get function: g_BlockPistonBreakable */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockPistonBreakable static int tolua_get_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -237,12 +135,12 @@ static int tolua_get_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsPistonBreakable(tolua_index)); + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) + { + tolua_error(tolua_S, "array indexing out of range.", NULL); + } + tolua_pushboolean(tolua_S, cBlockInfo::IsPistonBreakable((BLOCKTYPE)BlockType)); return 1; } #endif //#ifndef TOLUA_DISABLE @@ -251,37 +149,11 @@ static int tolua_get_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) -/* set function: g_BlockPistonBreakable */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockPistonBreakable -static int tolua_set_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_PistonBreakable = (tolua_toboolean(tolua_S,3,0) != 0); - return 0; -} -#endif //#ifndef TOLUA_DISABLE - - - - - /* get function: g_BlockIsSnowable */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockIsSnowable static int tolua_get_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -289,12 +161,12 @@ static int tolua_get_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsSnowable(tolua_index)); + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) + { + tolua_error(tolua_S, "array indexing out of range.", NULL); + } + tolua_pushboolean(tolua_S, cBlockInfo::IsSnowable((BLOCKTYPE)BlockType)); return 1; } #endif //#ifndef TOLUA_DISABLE @@ -303,37 +175,11 @@ static int tolua_get_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) -/* set function: g_BlockIsSnowable */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockIsSnowable -static int tolua_set_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_IsSnowable = (tolua_toboolean(tolua_S,3,0) != 0); - return 0; -} -#endif //#ifndef TOLUA_DISABLE - - - - - /* get function: g_BlockRequiresSpecialTool */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockRequiresSpecialTool static int tolua_get_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -341,12 +187,12 @@ static int tolua_get_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushboolean(tolua_S,(bool)cBlockInfo::RequiresSpecialTool(tolua_index)); + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) + { + tolua_error(tolua_S, "array indexing out of range.", NULL); + } + tolua_pushboolean(tolua_S, cBlockInfo::RequiresSpecialTool((BLOCKTYPE)BlockType)); return 1; } #endif //#ifndef TOLUA_DISABLE @@ -355,37 +201,11 @@ static int tolua_get_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) -/* set function: g_BlockRequiresSpecialTool */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockRequiresSpecialTool -static int tolua_set_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_RequiresSpecialTool = (tolua_toboolean(tolua_S,3,0) != 0); - return 0; -} -#endif //#ifndef TOLUA_DISABLE - - - - - /* get function: g_BlockIsSolid */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockIsSolid static int tolua_get_AllToLua_g_BlockIsSolid(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -393,12 +213,12 @@ static int tolua_get_AllToLua_g_BlockIsSolid(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsSolid(tolua_index)); + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) + { + tolua_error(tolua_S, "array indexing out of range.", NULL); + } + tolua_pushboolean(tolua_S, (bool)cBlockInfo::IsSolid((BLOCKTYPE)BlockType)); return 1; } #endif //#ifndef TOLUA_DISABLE @@ -407,37 +227,11 @@ static int tolua_get_AllToLua_g_BlockIsSolid(lua_State* tolua_S) -/* set function: g_BlockIsSolid */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockIsSolid -static int tolua_set_AllToLua_g_BlockIsSolid(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_IsSolid = (tolua_toboolean(tolua_S,3,0) != 0); - return 0; -} -#endif //#ifndef TOLUA_DISABLE - - - - - /* get function: g_BlockFullyOccupiesVoxel */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockFullyOccupiesVoxel static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -445,12 +239,12 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushboolean(tolua_S,(bool)cBlockInfo::FullyOccupiesVoxel(tolua_index)); + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) + { + tolua_error(tolua_S, "array indexing out of range.", NULL); + } + tolua_pushboolean(tolua_S, (bool)cBlockInfo::FullyOccupiesVoxel((BLOCKTYPE)BlockType)); return 1; } #endif //#ifndef TOLUA_DISABLE @@ -459,45 +253,19 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) -/* set function: g_BlockFullyOccupiesVoxel */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockFullyOccupiesVoxel -static int tolua_set_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE - { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); - } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_FullyOccupiesVoxel = (tolua_toboolean(tolua_S,3,0) != 0); - return 0; -} -#endif //#ifndef TOLUA_DISABLE - - - - - void DeprecatedBindings::Bind(lua_State * tolua_S) { tolua_beginmodule(tolua_S, NULL); - tolua_array(tolua_S, "g_BlockLightValue", tolua_get_AllToLua_g_BlockLightValue, tolua_set_AllToLua_g_BlockLightValue); - tolua_array(tolua_S, "g_BlockSpreadLightFalloff", tolua_get_AllToLua_g_BlockSpreadLightFalloff, tolua_set_AllToLua_g_BlockSpreadLightFalloff); - tolua_array(tolua_S, "g_BlockTransparent", tolua_get_AllToLua_g_BlockTransparent, tolua_set_AllToLua_g_BlockTransparent); - tolua_array(tolua_S, "g_BlockOneHitDig", tolua_get_AllToLua_g_BlockOneHitDig, tolua_set_AllToLua_g_BlockOneHitDig); - tolua_array(tolua_S, "g_BlockPistonBreakable", tolua_get_AllToLua_g_BlockPistonBreakable, tolua_set_AllToLua_g_BlockPistonBreakable); - tolua_array(tolua_S, "g_BlockIsSnowable", tolua_get_AllToLua_g_BlockIsSnowable, tolua_set_AllToLua_g_BlockIsSnowable); - tolua_array(tolua_S, "g_BlockRequiresSpecialTool", tolua_get_AllToLua_g_BlockRequiresSpecialTool, tolua_set_AllToLua_g_BlockRequiresSpecialTool); - tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, tolua_set_AllToLua_g_BlockIsSolid); - tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, tolua_set_AllToLua_g_BlockFullyOccupiesVoxel); + tolua_array(tolua_S, "g_BlockLightValue", tolua_get_AllToLua_g_BlockLightValue, NULL); + tolua_array(tolua_S, "g_BlockSpreadLightFalloff", tolua_get_AllToLua_g_BlockSpreadLightFalloff, NULL); + tolua_array(tolua_S, "g_BlockTransparent", tolua_get_AllToLua_g_BlockTransparent, NULL); + tolua_array(tolua_S, "g_BlockOneHitDig", tolua_get_AllToLua_g_BlockOneHitDig, NULL); + tolua_array(tolua_S, "g_BlockPistonBreakable", tolua_get_AllToLua_g_BlockPistonBreakable, NULL); + tolua_array(tolua_S, "g_BlockIsSnowable", tolua_get_AllToLua_g_BlockIsSnowable, NULL); + tolua_array(tolua_S, "g_BlockRequiresSpecialTool", tolua_get_AllToLua_g_BlockRequiresSpecialTool, NULL); + tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, NULL); + tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, NULL); tolua_endmodule(tolua_S); } From 25529ba62f949b98ed30e905ee4921c737d7df87 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 3 Apr 2014 09:27:17 +0200 Subject: [PATCH 125/145] Fixed a few MSVC type warnings. --- src/BlockArea.cpp | 2 +- src/BlockEntities/CommandBlockEntity.cpp | 2 +- src/Globals.h | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 60e4f11e5..40cca8882 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -530,7 +530,7 @@ void cBlockArea::DumpToRawFile(const AString & a_FileName) f.Write(&SizeX, 4); f.Write(&SizeY, 4); f.Write(&SizeZ, 4); - unsigned char DataTypes = GetDataTypes(); + unsigned char DataTypes = (unsigned char)GetDataTypes(); f.Write(&DataTypes, 1); int NumBlocks = GetBlockCount(); if (HasBlockTypes()) diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index d395997a6..96ca0ac37 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -160,7 +160,7 @@ bool cCommandBlockEntity::LoadFromJson(const Json::Value & a_Value) m_Command = a_Value.get("Command", "").asString(); m_LastOutput = a_Value.get("LastOutput", "").asString(); - m_Result = a_Value.get("SuccessCount", 0).asInt(); + m_Result = (NIBBLETYPE)a_Value.get("SuccessCount", 0).asInt(); return true; } diff --git a/src/Globals.h b/src/Globals.h index a1cee5c2f..26a0d87a9 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -29,6 +29,9 @@ // Disabling this warning, because we know what we're doing when we're doing this: #pragma warning(disable: 4355) // 'this' used in initializer list + + // Disabled because it's useless: + #pragma warning(disable: 4512) // 'class': assignment operator could not be generated - reported for each class that has a reference-type member // 2014_01_06 xoft: Disabled this warning because MSVC is stupid and reports it in obviously wrong places // #pragma warning(3 : 4244) // Conversion from 'type1' to 'type2', possible loss of data From 1b78bef4b355c84ee86688eb4f802e5f8a8ccd78 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 2 Apr 2014 17:57:14 +0200 Subject: [PATCH 126/145] Removed unneeded asserts. --- src/LightingThread.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/LightingThread.h b/src/LightingThread.h index 3209ad9b2..770ae809f 100644 --- a/src/LightingThread.h +++ b/src/LightingThread.h @@ -164,9 +164,7 @@ protected: int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut ) { - ASSERT(a_SrcIdx >= 0); ASSERT(a_SrcIdx < ARRAYCOUNT(m_SkyLight)); - ASSERT(a_DstIdx >= 0); ASSERT(a_DstIdx < ARRAYCOUNT(m_BlockTypes)); if (a_Light[a_SrcIdx] <= a_Light[a_DstIdx] + cBlockInfo::GetSpreadLightFalloff(m_BlockTypes[a_DstIdx])) From e304bd08a2363f43bf845b2b370c18a60d1b66d1 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 3 Apr 2014 21:44:03 +0200 Subject: [PATCH 127/145] Documented the units and range for entity rotations. --- MCServer/Plugins/APIDump/APIDesc.lua | 6 +++--- src/Entities/Entity.h | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 451b7364a..b0086d740 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -777,14 +777,14 @@ end GetMass = { Params = "", Return = "number", Notes = "Returns the mass of the entity. Currently unused." }, GetMaxHealth = { Params = "", Return = "number", Notes = "Returns the maximum number of hitpoints this entity is allowed to have." }, GetParentClass = { Params = "", Return = "string", Notes = "Returns the name of the direct parent class for this entity" }, - GetPitch = { Params = "", Return = "number", Notes = "Returns the pitch (nose-down rotation) of the entity" }, + GetPitch = { Params = "", Return = "number", Notes = "Returns the pitch (nose-down rotation) of the entity. Measured in degrees, values range from -90 to +90." }, GetPosition = { Params = "", Return = "{{Vector3d}}", Notes = "Returns the entity's pivot position as a 3D vector" }, GetPosX = { Params = "", Return = "number", Notes = "Returns the X-coord of the entity's pivot" }, GetPosY = { Params = "", Return = "number", Notes = "Returns the Y-coord of the entity's pivot" }, GetPosZ = { Params = "", Return = "number", Notes = "Returns the Z-coord of the entity's pivot" }, GetRawDamageAgainst = { Params = "ReceiverEntity", Return = "number", Notes = "Returns the raw damage that this entity's equipment would cause when attacking the ReceiverEntity. This includes this entity's weapon {{cEnchantments|enchantments}}, but excludes the receiver's armor or potion effects. See {{TakeDamageInfo}} for more information on attack damage." }, GetRoll = { Params = "", Return = "number", Notes = "Returns the roll (sideways rotation) of the entity. Currently unused." }, - GetRot = { Params = "", Return = "{{Vector3f}}", Notes = "Returns the entire rotation vector (Yaw, Pitch, Roll)" }, + GetRot = { Params = "", Return = "{{Vector3f}}", Notes = "(OBSOLETE) Returns the entire rotation vector (Yaw, Pitch, Roll)" }, GetSpeed = { Params = "", Return = "{{Vector3d}}", Notes = "Returns the complete speed vector of the entity" }, GetSpeedX = { Params = "", Return = "number", Notes = "Returns the X-part of the speed vector" }, GetSpeedY = { Params = "", Return = "number", Notes = "Returns the Y-part of the speed vector" }, @@ -792,7 +792,7 @@ end GetUniqueID = { Params = "", Return = "number", Notes = "Returns the ID that uniquely identifies the entity within the running server. Note that this ID is not persisted to the data files." }, GetWidth = { Params = "", Return = "number", Notes = "Returns the width (X and Z size) of the entity." }, GetWorld = { Params = "", Return = "{{cWorld}}", Notes = "Returns the world where the entity resides" }, - GetYaw = { Params = "", Return = "number", Notes = "Returns the yaw (direction) of the entity." }, + GetYaw = { Params = "", Return = "number", Notes = "Returns the yaw (direction) of the entity. Measured in degrees, values range from -180 to +180." }, Heal = { Params = "Hitpoints", Return = "", Notes = "Heals the specified number of hitpoints. Hitpoints is expected to be a positive number." }, IsA = { Params = "ClassName", Return = "bool", Notes = "Returns true if the entity class is a descendant of the specified class name, or the specified class itself" }, IsBoat = { Params = "", Return = "bool", Notes = "Returns true if the entity is a {{cBoat|boat}}." }, diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index e41f74b09..6e3f8292b 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -159,7 +159,7 @@ public: cWorld * GetWorld(void) const { return m_World; } - double GetHeadYaw (void) const { return m_HeadYaw; } + double GetHeadYaw (void) const { return m_HeadYaw; } // In degrees double GetHeight (void) const { return m_Height; } double GetMass (void) const { return m_Mass; } const Vector3d & GetPosition (void) const { return m_Pos; } @@ -167,9 +167,9 @@ public: double GetPosY (void) const { return m_Pos.y; } double GetPosZ (void) const { return m_Pos.z; } const Vector3d & GetRot (void) const { return m_Rot; } // OBSOLETE, use individual GetYaw(), GetPitch, GetRoll() components - double GetYaw (void) const { return m_Rot.x; } - double GetPitch (void) const { return m_Rot.y; } - double GetRoll (void) const { return m_Rot.z; } + double GetYaw (void) const { return m_Rot.x; } // In degrees, [-180, +180) + double GetPitch (void) const { return m_Rot.y; } // In degrees, [-180, +180), but normal client clips to [-90, +90] + double GetRoll (void) const { return m_Rot.z; } // In degrees, unused in current client Vector3d GetLookVector(void) const; const Vector3d & GetSpeed (void) const { return m_Speed; } double GetSpeedX (void) const { return m_Speed.x; } @@ -189,9 +189,9 @@ public: void SetPosition(double a_PosX, double a_PosY, double a_PosZ); void SetPosition(const Vector3d & a_Pos) { SetPosition(a_Pos.x, a_Pos.y, a_Pos.z); } void SetRot (const Vector3f & a_Rot); // OBSOLETE, use individual SetYaw(), SetPitch(), SetRoll() components - void SetYaw (double a_Yaw); - void SetPitch (double a_Pitch); - void SetRoll (double a_Roll); + void SetYaw (double a_Yaw); // In degrees, normalizes to [-180, +180) + void SetPitch (double a_Pitch); // In degrees, normalizes to [-180, +180) + void SetRoll (double a_Roll); // In degrees, normalizes to [-180, +180) void SetSpeed (double a_SpeedX, double a_SpeedY, double a_SpeedZ); void SetSpeed (const Vector3d & a_Speed) { SetSpeed(a_Speed.x, a_Speed.y, a_Speed.z); } void SetSpeedX (double a_SpeedX); From e2fb507be2157194dc435e30c856ffb4e6ad4ed6 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 3 Apr 2014 21:52:50 +0200 Subject: [PATCH 128/145] APIDump: Added angular specifics. --- MCServer/Plugins/APIDump/APIDesc.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index b0086d740..b3b7dd11c 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -777,7 +777,7 @@ end GetMass = { Params = "", Return = "number", Notes = "Returns the mass of the entity. Currently unused." }, GetMaxHealth = { Params = "", Return = "number", Notes = "Returns the maximum number of hitpoints this entity is allowed to have." }, GetParentClass = { Params = "", Return = "string", Notes = "Returns the name of the direct parent class for this entity" }, - GetPitch = { Params = "", Return = "number", Notes = "Returns the pitch (nose-down rotation) of the entity. Measured in degrees, values range from -90 to +90." }, + GetPitch = { Params = "", Return = "number", Notes = "Returns the pitch (nose-down rotation) of the entity. Measured in degrees, normal values range from -90 to +90. +90 means looking down, 0 means looking straight ahead, -90 means looking up." }, GetPosition = { Params = "", Return = "{{Vector3d}}", Notes = "Returns the entity's pivot position as a 3D vector" }, GetPosX = { Params = "", Return = "number", Notes = "Returns the X-coord of the entity's pivot" }, GetPosY = { Params = "", Return = "number", Notes = "Returns the Y-coord of the entity's pivot" }, @@ -792,7 +792,7 @@ end GetUniqueID = { Params = "", Return = "number", Notes = "Returns the ID that uniquely identifies the entity within the running server. Note that this ID is not persisted to the data files." }, GetWidth = { Params = "", Return = "number", Notes = "Returns the width (X and Z size) of the entity." }, GetWorld = { Params = "", Return = "{{cWorld}}", Notes = "Returns the world where the entity resides" }, - GetYaw = { Params = "", Return = "number", Notes = "Returns the yaw (direction) of the entity. Measured in degrees, values range from -180 to +180." }, + GetYaw = { Params = "", Return = "number", Notes = "Returns the yaw (direction) of the entity. Measured in degrees, values range from -180 to +180. 0 means ZP, 90 means XM, -180 means ZM, -90 means XP." }, Heal = { Params = "Hitpoints", Return = "", Notes = "Heals the specified number of hitpoints. Hitpoints is expected to be a positive number." }, IsA = { Params = "ClassName", Return = "bool", Notes = "Returns true if the entity class is a descendant of the specified class name, or the specified class itself" }, IsBoat = { Params = "", Return = "bool", Notes = "Returns true if the entity is a {{cBoat|boat}}." }, From 0fb40da8776482a90a86a46760ae8c9560963a73 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 3 Apr 2014 21:53:18 +0200 Subject: [PATCH 129/145] Change CanBeAt() from big flower --- src/Blocks/BlockBigFlower.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h index 98d6502ab..39fd3cac8 100644 --- a/src/Blocks/BlockBigFlower.h +++ b/src/Blocks/BlockBigFlower.h @@ -81,11 +81,7 @@ public: virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return ( - a_RelY > 0 - && a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR - && a_RelY < cChunkDef::Height - ); + return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR) && (a_RelY < cChunkDef::Height) && ((a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == E_BLOCK_AIR) || (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == E_BLOCK_BIG_FLOWER))); } From 446a6515029e66b1f76358dcee1ccfe59c432bdd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 4 Apr 2014 08:55:48 +0200 Subject: [PATCH 130/145] ProtoProxy: Fixed a few Clang and MSVC warnings. --- Tools/ProtoProxy/Connection.cpp | 10 +++++++--- Tools/ProtoProxy/Connection.h | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index f02b503f1..d9b8e3dd1 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -387,6 +387,8 @@ bool cConnection::RelayFromServer(void) return CLIENTSEND(Buffer, res); } } + ASSERT(!"Unhandled server state while relaying from server"); + return false; } @@ -423,6 +425,8 @@ bool cConnection::RelayFromClient(void) return SERVERSEND(Buffer, res); } } + ASSERT(!"Unhandled server state while relaying from client"); + return false; } @@ -438,11 +442,11 @@ double cConnection::GetRelativeTime(void) -bool cConnection::SendData(SOCKET a_Socket, const char * a_Data, int a_Size, const char * a_Peer) +bool cConnection::SendData(SOCKET a_Socket, const char * a_Data, size_t a_Size, const char * a_Peer) { - DataLog(a_Data, a_Size, "Sending data to %s, %d bytes", a_Peer, a_Size); + DataLog(a_Data, a_Size, "Sending data to %s, %u bytes", a_Peer, (unsigned)a_Size); - int res = send(a_Socket, a_Data, a_Size, 0); + int res = send(a_Socket, a_Data, (int)a_Size, 0); if (res <= 0) { Log("%s closed the socket: %d, %d; aborting connection", a_Peer, res, SocketError); diff --git a/Tools/ProtoProxy/Connection.h b/Tools/ProtoProxy/Connection.h index 70b759d0f..9e04994b7 100644 --- a/Tools/ProtoProxy/Connection.h +++ b/Tools/ProtoProxy/Connection.h @@ -103,7 +103,7 @@ protected: double GetRelativeTime(void); /// Sends data to the specified socket. If sending fails, prints a fail message using a_Peer and returns false. - bool SendData(SOCKET a_Socket, const char * a_Data, int a_Size, const char * a_Peer); + bool SendData(SOCKET a_Socket, const char * a_Data, size_t a_Size, const char * a_Peer); /// Sends data to the specified socket. If sending fails, prints a fail message using a_Peer and returns false. bool SendData(SOCKET a_Socket, cByteBuffer & a_Data, const char * a_Peer); From 402d85d896c793644681c4bb2934a7e0abb5ed8c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 4 Apr 2014 09:56:57 +0200 Subject: [PATCH 131/145] Fixed Clang warnings in itemhandlers. --- src/Blocks/BlockSign.h | 4 ++-- src/Items/ItemEmptyMap.h | 2 +- src/Items/ItemFishingRod.h | 4 ++-- src/Items/ItemHandler.cpp | 6 +++--- src/Items/ItemLilypad.h | 23 ++++++++++++----------- src/Items/ItemMap.h | 2 +- 6 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/Blocks/BlockSign.h b/src/Blocks/BlockSign.h index 6c0becfd6..9d6fede21 100644 --- a/src/Blocks/BlockSign.h +++ b/src/Blocks/BlockSign.h @@ -31,7 +31,7 @@ public: } - static char RotationToMetaData(double a_Rotation) + static NIBBLETYPE RotationToMetaData(double a_Rotation) { a_Rotation += 180 + (180 / 16); // So it's not aligned with axis if (a_Rotation > 360) @@ -45,7 +45,7 @@ public: } - static char DirectionToMetaData(eBlockFace a_Direction) + static NIBBLETYPE DirectionToMetaData(eBlockFace a_Direction) { switch (a_Direction) { diff --git a/src/Items/ItemEmptyMap.h b/src/Items/ItemEmptyMap.h index f0b1e1424..953673382 100644 --- a/src/Items/ItemEmptyMap.h +++ b/src/Items/ItemEmptyMap.h @@ -55,7 +55,7 @@ public: return true; } - a_Player->GetInventory().AddItem(cItem(E_ITEM_MAP, 1, NewMap->GetID()), true, true); + a_Player->GetInventory().AddItem(cItem(E_ITEM_MAP, 1, (short)(NewMap->GetID() & 0x7fff)), true, true); return true; } diff --git a/src/Items/ItemFishingRod.h b/src/Items/ItemFishingRod.h index 15acbd9fe..0431b88b7 100644 --- a/src/Items/ItemFishingRod.h +++ b/src/Items/ItemFishingRod.h @@ -123,7 +123,7 @@ public: } case 2: { - Drops.Add(cItem(E_ITEM_FISHING_ROD, 1, a_World->GetTickRandomNumber(50))); // Fishing rod with durability. TODO: Enchantments on it + Drops.Add(cItem(E_ITEM_FISHING_ROD, 1, (short)a_World->GetTickRandomNumber(50))); // Fishing rod with durability. TODO: Enchantments on it break; } case 3: @@ -152,7 +152,7 @@ public: } else if (Junk <= 4) { - Drops.Add(cItem(E_ITEM_BOW, 1, a_World->GetTickRandomNumber(64))); + Drops.Add(cItem(E_ITEM_BOW, 1, (short)a_World->GetTickRandomNumber(64))); } else if (Junk <= 9) { diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 337b3a83c..1e77717e3 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -506,13 +506,13 @@ bool cItemHandler::GetPlacementBlockTypeMeta( { ASSERT(m_ItemType < 256); // Items with IDs above 255 should all be handled by specific handlers - if (m_ItemType > 256) + if (m_ItemType >= 256) { - LOGERROR("%s: Item %d has no valid block!", __FUNCTION__, m_ItemType); + LOGERROR("%s: Item %d is not eligible for direct block placement!", __FUNCTION__, m_ItemType); return false; } - cBlockHandler * BlockH = BlockHandler(m_ItemType); + cBlockHandler * BlockH = BlockHandler((BLOCKTYPE)m_ItemType); cChunkInterface ChunkInterface(a_World->GetChunkMap()); return BlockH->GetPlacementBlockTypeMeta( ChunkInterface, a_Player, diff --git a/src/Items/ItemLilypad.h b/src/Items/ItemLilypad.h index 5a29abe94..8fc1d8543 100644 --- a/src/Items/ItemLilypad.h +++ b/src/Items/ItemLilypad.h @@ -16,17 +16,19 @@ class cItemLilypadHandler : typedef cItemHandler super; public: - cItemLilypadHandler(BLOCKTYPE a_BlockType) - : cItemHandler(a_BlockType) + cItemLilypadHandler(int a_ItemType): + super(a_ItemType) { } + virtual bool IsPlaceable(void) override { return false; // Set as not placeable so OnItemUse is called } + virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override { if (a_BlockFace > BLOCK_FACE_NONE) @@ -45,23 +47,22 @@ public: public cBlockTracer::cCallbacks { public: - cCallbacks(cWorld * a_World) : + cCallbacks(cWorld * a_CBWorld) : m_HasHitFluid(false), - m_World(a_World) + m_World(a_CBWorld) { } - virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override + virtual bool OnNextBlock(int a_CBBlockX, int a_CBBlockY, int a_CBBlockZ, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, char a_CBEntryFace) override { - if (IsBlockWater(a_BlockType)) + if (IsBlockWater(a_CBBlockType)) { - if ((a_BlockMeta != 0) || (a_EntryFace == BLOCK_FACE_NONE)) // The hit block should be a source. The FACE_NONE check is clicking whilst submerged + if ((a_CBBlockMeta != 0) || (a_CBEntryFace == BLOCK_FACE_NONE)) // The hit block should be a source. The FACE_NONE check is clicking whilst submerged { return false; } - a_EntryFace = BLOCK_FACE_YP; // Always place pad at top of water block - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, (eBlockFace)a_EntryFace); - BLOCKTYPE Block = m_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); + AddFaceDirection(a_CBBlockX, a_CBBlockY, a_CBBlockZ, BLOCK_FACE_YP); // Always place pad at top of water block + BLOCKTYPE Block = m_World->GetBlock(a_CBBlockX, a_CBBlockY, a_CBBlockZ); if ( !IsBlockWater(Block) && cBlockInfo::FullyOccupiesVoxel(Block) @@ -71,7 +72,7 @@ public: return true; } m_HasHitFluid = true; - m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ); + m_Pos.Set(a_CBBlockX, a_CBBlockY, a_CBBlockZ); return true; } return false; diff --git a/src/Items/ItemMap.h b/src/Items/ItemMap.h index e8ff9da88..056fe0fe7 100644 --- a/src/Items/ItemMap.h +++ b/src/Items/ItemMap.h @@ -29,7 +29,7 @@ public: virtual void OnUpdate(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item) { - cMap * Map = a_World->GetMapManager().GetMapData(a_Item.m_ItemDamage); + cMap * Map = a_World->GetMapManager().GetMapData((unsigned)a_Item.m_ItemDamage); if (Map == NULL) { From 8825d30aabbee8cb2e452dc5a17deb6f9b6892a7 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 4 Apr 2014 10:13:25 +0200 Subject: [PATCH 132/145] Fixed some Clang warnings in protocols. --- src/ClientHandle.cpp | 4 ++-- src/ClientHandle.h | 2 +- src/Endianness.h | 31 ++++++++++++++++------------- src/Protocol/Protocol.h | 27 +++++++++++++++---------- src/Protocol/Protocol125.cpp | 2 +- src/Protocol/Protocol125.h | 2 +- src/Protocol/Protocol132.cpp | 2 +- src/Protocol/Protocol132.h | 2 +- src/Protocol/Protocol14x.cpp | 12 +++++------ src/Protocol/Protocol17x.cpp | 4 ++-- src/Protocol/Protocol17x.h | 2 +- src/Protocol/ProtocolRecognizer.cpp | 2 +- src/Protocol/ProtocolRecognizer.h | 2 +- 13 files changed, 51 insertions(+), 43 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 23ba4dbab..daf2c4da8 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1532,7 +1532,7 @@ void cClientHandle::HandleTabCompletion(const AString & a_Text) -void cClientHandle::SendData(const char * a_Data, int a_Size) +void cClientHandle::SendData(const char * a_Data, size_t a_Size) { if (m_HasSentDC) { @@ -1547,7 +1547,7 @@ void cClientHandle::SendData(const char * a_Data, int a_Size) if (m_OutgoingDataOverflow.empty()) { // No queued overflow data; if this packet fits into the ringbuffer, put it in, otherwise put it in the overflow buffer: - int CanFit = m_OutgoingData.GetFreeSpace(); + size_t CanFit = m_OutgoingData.GetFreeSpace(); if (CanFit > a_Size) { CanFit = a_Size; diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 5496e61a7..d83a323f9 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -225,7 +225,7 @@ public: */ bool HandleLogin(int a_ProtocolVersion, const AString & a_Username); - void SendData(const char * a_Data, int a_Size); + void SendData(const char * a_Data, size_t a_Size); /** Called when the player moves into a different world; queues sreaming the new chunks */ void MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket); diff --git a/src/Endianness.h b/src/Endianness.h index 86eb369f5..6a2593077 100644 --- a/src/Endianness.h +++ b/src/Endianness.h @@ -1,12 +1,14 @@ #pragma once +#define ntohll(x) ((((UInt64)ntohl((u_long)x)) << 32) + ntohl(x >> 32)) + // Changes endianness -inline unsigned long long HostToNetwork8(const void* a_Value ) +inline UInt64 HostToNetwork8(const void * a_Value) { unsigned long long __HostToNetwork8; memcpy( &__HostToNetwork8, a_Value, sizeof( __HostToNetwork8 ) ); @@ -18,7 +20,7 @@ inline unsigned long long HostToNetwork8(const void* a_Value ) -inline unsigned int HostToNetwork4(const void* a_Value ) +inline UInt32 HostToNetwork4(const void* a_Value ) { unsigned int __HostToNetwork4; memcpy( &__HostToNetwork4, a_Value, sizeof( __HostToNetwork4 ) ); @@ -30,11 +32,10 @@ inline unsigned int HostToNetwork4(const void* a_Value ) -inline double NetworkToHostDouble8(const void* a_Value ) +inline double NetworkToHostDouble8(const void * a_Value) { -#define ntohll(x) ((((unsigned long long)ntohl((u_long)x)) << 32) + ntohl(x >> 32)) - unsigned long long buf = 0;//(*(unsigned long long*)a_Value); - memcpy( &buf, a_Value, 8 ); + UInt64 buf = 0; + memcpy(&buf, a_Value, 8); buf = ntohll(buf); double x; memcpy(&x, &buf, sizeof(double)); @@ -45,23 +46,25 @@ inline double NetworkToHostDouble8(const void* a_Value ) -inline long long NetworkToHostLong8(const void * a_Value ) +inline Int64 NetworkToHostLong8(const void * a_Value) { - unsigned long long buf = *(unsigned long long*)a_Value; + UInt64 buf; + memcpy(&buf, &a_Value, 8); buf = ntohll(buf); - return *reinterpret_cast(&buf); + return *reinterpret_cast(&buf); } -inline float NetworkToHostFloat4(const void* a_Value ) +inline float NetworkToHostFloat4(const void * a_Value) { - u_long buf = *(u_long*)a_Value; - buf = ntohl( buf ); - float x = 0; - memcpy( &x, &buf, sizeof(float) ); + UInt32 buf; + float x; + memcpy(&buf, &a_Value, 4); + buf = ntohl(buf); + memcpy(&x, &buf, sizeof(float)); return x; } diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index d3383bf0d..8294fa8b7 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -132,7 +132,7 @@ protected: cCriticalSection m_CSPacket; //< Each SendXYZ() function must acquire this CS in order to send the whole packet at once /// A generic data-sending routine, all outgoing packet data needs to be routed through this so that descendants may override it - virtual void SendData(const char * a_Data, int a_Size) = 0; + virtual void SendData(const char * a_Data, size_t a_Size) = 0; /// Called after writing each packet, enables descendants to flush their buffers virtual void Flush(void) {}; @@ -143,10 +143,15 @@ protected: SendData((const char *)&a_Value, 1); } + void WriteChar(char a_Value) + { + SendData(&a_Value, 1); + } + void WriteShort(short a_Value) { - a_Value = htons(a_Value); - SendData((const char *)&a_Value, 2); + u_short Value = htons((u_short)a_Value); + SendData((const char *)&Value, 2); } /* @@ -159,8 +164,8 @@ protected: void WriteInt(int a_Value) { - a_Value = htonl(a_Value); - SendData((const char *)&a_Value, 4); + u_long Value = htonl((u_long)a_Value); + SendData((const char *)&Value, 4); } void WriteUInt(unsigned int a_Value) @@ -171,19 +176,19 @@ protected: void WriteInt64 (Int64 a_Value) { - a_Value = HostToNetwork8(&a_Value); - SendData((const char *)&a_Value, 8); + UInt64 Value = HostToNetwork8(&a_Value); + SendData((const char *)Value, 8); } void WriteFloat (float a_Value) { - unsigned int val = HostToNetwork4(&a_Value); + UInt32 val = HostToNetwork4(&a_Value); SendData((const char *)&val, 4); } void WriteDouble(double a_Value) { - unsigned long long val = HostToNetwork8(&a_Value); + UInt64 val = HostToNetwork8(&a_Value); SendData((const char *)&val, 8); } @@ -191,7 +196,7 @@ protected: { AString UTF16; UTF8ToRawBEUTF16(a_Value.c_str(), a_Value.length(), UTF16); - WriteShort((unsigned short)(UTF16.size() / 2)); + WriteShort((short)(UTF16.size() / 2)); SendData(UTF16.data(), UTF16.size()); } @@ -224,7 +229,7 @@ protected: void WriteVarUTF8String(const AString & a_String) { - WriteVarInt(a_String.size()); + WriteVarInt((UInt32)a_String.size()); SendData(a_String.data(), a_String.size()); } } ; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index fe6280218..0fa5c6de7 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -1156,7 +1156,7 @@ AString cProtocol125::GetAuthServerID(void) -void cProtocol125::SendData(const char * a_Data, int a_Size) +void cProtocol125::SendData(const char * a_Data, size_t a_Size) { m_Client->SendData(a_Data, a_Size); } diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index aca24c03a..08d3ebbe9 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -125,7 +125,7 @@ protected: AString m_Username; ///< Stored in ParseHandshake(), compared to Login username - virtual void SendData(const char * a_Data, int a_Size) override; + virtual void SendData(const char * a_Data, size_t a_Size) override; /// Sends the Handshake packet void SendHandshake(const AString & a_ConnectionHash); diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp index be9c503ed..ce5d134ea 100644 --- a/src/Protocol/Protocol132.cpp +++ b/src/Protocol/Protocol132.cpp @@ -605,7 +605,7 @@ int cProtocol132::ParseTabCompletion(void) -void cProtocol132::SendData(const char * a_Data, int a_Size) +void cProtocol132::SendData(const char * a_Data, size_t a_Size) { m_DataToSend.append(a_Data, a_Size); } diff --git a/src/Protocol/Protocol132.h b/src/Protocol/Protocol132.h index 0702fbf5a..b280c8a41 100644 --- a/src/Protocol/Protocol132.h +++ b/src/Protocol/Protocol132.h @@ -87,7 +87,7 @@ protected: /// The ServerID used for session authentication; set in StartEncryption(), used in GetAuthServerID() AString m_AuthServerID; - virtual void SendData(const char * a_Data, int a_Size) override; + virtual void SendData(const char * a_Data, size_t a_Size) override; // DEBUG: virtual void Flush(void) override; diff --git a/src/Protocol/Protocol14x.cpp b/src/Protocol/Protocol14x.cpp index 232b2718e..f694af1eb 100644 --- a/src/Protocol/Protocol14x.cpp +++ b/src/Protocol/Protocol14x.cpp @@ -103,9 +103,9 @@ void cProtocol142::SendPickupSpawn(const cPickup & a_Pickup) WriteInt (a_Pickup.GetUniqueID()); WriteItem (a_Pickup.GetItem()); WriteVectorI((Vector3i)(a_Pickup.GetPosition() * 32)); - WriteByte ((char)(a_Pickup.GetSpeed().x * 8)); - WriteByte ((char)(a_Pickup.GetSpeed().y * 8)); - WriteByte ((char)(a_Pickup.GetSpeed().z * 8)); + WriteChar ((char)(a_Pickup.GetSpeed().x * 8)); + WriteChar ((char)(a_Pickup.GetSpeed().y * 8)); + WriteChar ((char)(a_Pickup.GetSpeed().z * 8)); Flush(); } @@ -119,7 +119,7 @@ void cProtocol142::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_Src WriteByte(PACKET_SOUND_PARTICLE_EFFECT); WriteInt (a_EffectID); WriteInt (a_SrcX); - WriteByte(a_SrcY); + WriteByte((Byte)a_SrcY); WriteInt (a_SrcZ); WriteInt (a_Data); WriteBool(0); @@ -218,7 +218,7 @@ void cProtocol146::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, cCSLock Lock(m_CSPacket); WriteByte(PACKET_SPAWN_OBJECT); WriteInt (a_Entity.GetUniqueID()); - WriteByte(a_ObjectType); + WriteChar(a_ObjectType); WriteInt ((int)(a_Entity.GetPosX() * 32)); WriteInt ((int)(a_Entity.GetPosY() * 32)); WriteInt ((int)(a_Entity.GetPosZ() * 32)); @@ -243,7 +243,7 @@ void cProtocol146::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleTyp cCSLock Lock(m_CSPacket); WriteByte (PACKET_SPAWN_OBJECT); WriteInt (a_Vehicle.GetUniqueID()); - WriteByte (a_VehicleType); + WriteChar (a_VehicleType); WriteInt ((int)(a_Vehicle.GetPosX() * 32)); WriteInt ((int)(a_Vehicle.GetPosY() * 32)); WriteInt ((int)(a_Vehicle.GetPosZ() * 32)); diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index c678fc9a0..b987294b0 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1988,14 +1988,14 @@ void cProtocol172::WritePacket(cByteBuffer & a_Packet) -void cProtocol172::SendData(const char * a_Data, int a_Size) +void cProtocol172::SendData(const char * a_Data, size_t a_Size) { if (m_IsEncrypted) { Byte Encrypted[8192]; // Larger buffer, we may be sending lots of data (chunks) while (a_Size > 0) { - size_t NumBytes = ((size_t)a_Size > sizeof(Encrypted)) ? sizeof(Encrypted) : (size_t)a_Size; + size_t NumBytes = (a_Size > sizeof(Encrypted)) ? sizeof(Encrypted) : a_Size; m_Encryptor.ProcessData(Encrypted, (Byte *)a_Data, NumBytes); m_Client->SendData((const char *)Encrypted, NumBytes); a_Size -= NumBytes; diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 41163009e..bb6ee575a 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -287,7 +287,7 @@ protected: void WritePacket(cByteBuffer & a_Packet); /** Sends the data to the client, encrypting them if needed. */ - virtual void SendData(const char * a_Data, int a_Size) override; + virtual void SendData(const char * a_Data, size_t a_Size) override; void SendCompass(const cWorld & a_World); diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 3b9003e60..81f146370 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -794,7 +794,7 @@ AString cProtocolRecognizer::GetAuthServerID(void) -void cProtocolRecognizer::SendData(const char * a_Data, int a_Size) +void cProtocolRecognizer::SendData(const char * a_Data, size_t a_Size) { // This is used only when handling the server ping m_Client->SendData(a_Data, a_Size); diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index d7fb8fad2..072d7c2d2 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -133,7 +133,7 @@ public: virtual AString GetAuthServerID(void) override; - virtual void SendData(const char * a_Data, int a_Size) override; + virtual void SendData(const char * a_Data, size_t a_Size) override; protected: cProtocol * m_Protocol; //< The recognized protocol From 396abb5db6e46f214e27e4dba1099490bf03bb0a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 4 Apr 2014 10:19:21 +0200 Subject: [PATCH 133/145] Fixed silly Clang's warnings in FastNBT. --- src/WorldStorage/FastNBT.h | 56 +++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h index 1b8b09c21..5e5af3ca3 100644 --- a/src/WorldStorage/FastNBT.h +++ b/src/WorldStorage/FastNBT.h @@ -122,33 +122,33 @@ public: int GetRoot(void) const {return 0; } /** Returns the first child of the specified tag, or -1 if none / not applicable. */ - int GetFirstChild (int a_Tag) const { return m_Tags[a_Tag].m_FirstChild; } + int GetFirstChild (int a_Tag) const { return m_Tags[(size_t)a_Tag].m_FirstChild; } /** Returns the last child of the specified tag, or -1 if none / not applicable. */ - int GetLastChild (int a_Tag) const { return m_Tags[a_Tag].m_LastChild; } + int GetLastChild (int a_Tag) const { return m_Tags[(size_t)a_Tag].m_LastChild; } /** Returns the next sibling of the specified tag, or -1 if none. */ - int GetNextSibling(int a_Tag) const { return m_Tags[a_Tag].m_NextSibling; } + int GetNextSibling(int a_Tag) const { return m_Tags[(size_t)a_Tag].m_NextSibling; } /** Returns the previous sibling of the specified tag, or -1 if none. */ - int GetPrevSibling(int a_Tag) const { return m_Tags[a_Tag].m_PrevSibling; } + int GetPrevSibling(int a_Tag) const { return m_Tags[(size_t)a_Tag].m_PrevSibling; } /** Returns the length of the tag's data, in bytes. Not valid for Compound or List tags! */ int GetDataLength (int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type != TAG_List); - ASSERT(m_Tags[a_Tag].m_Type != TAG_Compound); - return m_Tags[a_Tag].m_DataLength; + ASSERT(m_Tags[(size_t)a_Tag].m_Type != TAG_List); + ASSERT(m_Tags[(size_t)a_Tag].m_Type != TAG_Compound); + return m_Tags[(size_t)a_Tag].m_DataLength; } /** Returns the data stored in this tag. Not valid for Compound or List tags! */ const char * GetData(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type != TAG_List); - ASSERT(m_Tags[a_Tag].m_Type != TAG_Compound); - return m_Data + m_Tags[a_Tag].m_DataStart; + ASSERT(m_Tags[(size_t)a_Tag].m_Type != TAG_List); + ASSERT(m_Tags[(size_t)a_Tag].m_Type != TAG_Compound); + return m_Data + m_Tags[(size_t)a_Tag].m_DataStart; } /** Returns the direct child tag of the specified name, or -1 if no such tag. */ @@ -163,47 +163,47 @@ public: /** Returns the child tag of the specified path (Name1\Name2\Name3...), or -1 if no such tag. */ int FindTagByPath(int a_Tag, const AString & a_Path) const; - eTagType GetType(int a_Tag) const { return m_Tags[a_Tag].m_Type; } + eTagType GetType(int a_Tag) const { return m_Tags[(size_t)a_Tag].m_Type; } /** Returns the children type for a List tag; undefined on other tags. If list empty, returns TAG_End. */ eTagType GetChildrenType(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type == TAG_List); - return (m_Tags[a_Tag].m_FirstChild < 0) ? TAG_End : m_Tags[m_Tags[a_Tag].m_FirstChild].m_Type; + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_List); + return (m_Tags[(size_t)a_Tag].m_FirstChild < 0) ? TAG_End : m_Tags[(size_t)m_Tags[(size_t)a_Tag].m_FirstChild].m_Type; } /** Returns the value stored in a Byte tag. Not valid for any other tag type. */ inline unsigned char GetByte(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Byte); - return (unsigned char)(m_Data[m_Tags[a_Tag].m_DataStart]); + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_Byte); + return (unsigned char)(m_Data[(size_t)m_Tags[(size_t)a_Tag].m_DataStart]); } /** Returns the value stored in a Short tag. Not valid for any other tag type. */ inline Int16 GetShort(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Short); - return GetBEShort(m_Data + m_Tags[a_Tag].m_DataStart); + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_Short); + return GetBEShort(m_Data + m_Tags[(size_t)a_Tag].m_DataStart); } /** Returns the value stored in an Int tag. Not valid for any other tag type. */ inline Int32 GetInt(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Int); - return GetBEInt(m_Data + m_Tags[a_Tag].m_DataStart); + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_Int); + return GetBEInt(m_Data + m_Tags[(size_t)a_Tag].m_DataStart); } /** Returns the value stored in a Long tag. Not valid for any other tag type. */ inline Int64 GetLong(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Long); - return NetworkToHostLong8(m_Data + m_Tags[a_Tag].m_DataStart); + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_Long); + return NetworkToHostLong8(m_Data + m_Tags[(size_t)a_Tag].m_DataStart); } /** Returns the value stored in a Float tag. Not valid for any other tag type. */ inline float GetFloat(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type == TAG_Float); + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_Float); // Cause a compile-time error if sizeof(float) != 4 // If your platform produces a compiler error here, you'll need to add code that manually decodes 32-bit floats @@ -212,7 +212,7 @@ public: UNUSED(Check1); UNUSED(Check2); - Int32 i = GetBEInt(m_Data + m_Tags[a_Tag].m_DataStart); + Int32 i = GetBEInt(m_Data + m_Tags[(size_t)a_Tag].m_DataStart); float f; memcpy(&f, &i, sizeof(f)); return f; @@ -228,16 +228,16 @@ public: UNUSED(Check1); UNUSED(Check2); - ASSERT(m_Tags[a_Tag].m_Type == TAG_Double); - return NetworkToHostDouble8(m_Data + m_Tags[a_Tag].m_DataStart); + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_Double); + return NetworkToHostDouble8(m_Data + m_Tags[(size_t)a_Tag].m_DataStart); } /** Returns the value stored in a String tag. Not valid for any other tag type. */ inline AString GetString(int a_Tag) const { - ASSERT(m_Tags[a_Tag].m_Type == TAG_String); + ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_String); AString res; - res.assign(m_Data + m_Tags[a_Tag].m_DataStart, m_Tags[a_Tag].m_DataLength); + res.assign(m_Data + m_Tags[(size_t)a_Tag].m_DataStart, m_Tags[(size_t)a_Tag].m_DataLength); return res; } @@ -245,7 +245,7 @@ public: inline AString GetName(int a_Tag) const { AString res; - res.assign(m_Data + m_Tags[a_Tag].m_NameStart, m_Tags[a_Tag].m_NameLength); + res.assign(m_Data + m_Tags[(size_t)a_Tag].m_NameStart, m_Tags[(size_t)a_Tag].m_NameLength); return res; } From 5dee19648d8b3b068698fd1c9cb62e9038bf0e2c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 4 Apr 2014 10:31:50 +0200 Subject: [PATCH 134/145] More Clang warning fixes in the protocols. --- src/Protocol/Protocol132.cpp | 65 ++++++++++++++++++++---------------- src/StringUtils.cpp | 2 +- src/StringUtils.h | 2 +- 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp index ce5d134ea..ce5942a5c 100644 --- a/src/Protocol/Protocol132.cpp +++ b/src/Protocol/Protocol132.cpp @@ -115,7 +115,7 @@ void cProtocol132::DataReceived(const char * a_Data, size_t a_Size) Byte Decrypted[512]; while (a_Size > 0) { - int NumBytes = (a_Size > (int)sizeof(Decrypted)) ? (int)sizeof(Decrypted) : a_Size; + size_t NumBytes = (a_Size > sizeof(Decrypted)) ? sizeof(Decrypted) : a_Size; m_Decryptor.ProcessData(Decrypted, (Byte *)a_Data, NumBytes); super::DataReceived((const char *)Decrypted, NumBytes); a_Size -= NumBytes; @@ -139,8 +139,8 @@ void cProtocol132::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, cha WriteInt (a_BlockX); WriteShort((short)a_BlockY); WriteInt (a_BlockZ); - WriteByte (a_Byte1); - WriteByte (a_Byte2); + WriteChar (a_Byte1); + WriteChar (a_Byte2); WriteShort(a_BlockType); Flush(); } @@ -157,7 +157,7 @@ void cProtocol132::SendBlockBreakAnim(int a_entityID, int a_BlockX, int a_BlockY WriteInt (a_BlockX); WriteInt (a_BlockY); WriteInt (a_BlockZ); - WriteByte (stage); + WriteChar (stage); Flush(); } @@ -259,7 +259,7 @@ void cProtocol132::SendLogin(const cPlayer & a_Player, const cWorld & a_World) WriteByte (PACKET_LOGIN); WriteInt (a_Player.GetUniqueID()); // EntityID of the player WriteString("default"); // Level type - WriteByte ((int)a_Player.GetGameMode()); + WriteByte ((Byte)a_Player.GetGameMode()); WriteByte ((Byte)(a_World.GetDimension())); WriteByte (2); // TODO: Difficulty WriteByte (0); // Unused, used to be world height @@ -283,8 +283,8 @@ void cProtocol132::SendPlayerSpawn(const cPlayer & a_Player) WriteInt ((int)(a_Player.GetPosX() * 32)); WriteInt ((int)(a_Player.GetPosY() * 32)); WriteInt ((int)(a_Player.GetPosZ() * 32)); - WriteByte ((char)((a_Player.GetYaw() / 360.f) * 256)); - WriteByte ((char)((a_Player.GetPitch() / 360.f) * 256)); + WriteChar ((char)((a_Player.GetYaw() / 360.f) * 256)); + WriteChar ((char)((a_Player.GetPitch() / 360.f) * 256)); WriteShort (HeldItem.IsEmpty() ? 0 : HeldItem.m_ItemType); // Player metadata: just use a default metadata value, since the client doesn't like starting without any metadata: WriteByte (0); // Index 0, byte (flags) @@ -306,7 +306,7 @@ void cProtocol132::SendSoundEffect(const AString & a_SoundName, int a_SrcX, int WriteInt (a_SrcY); WriteInt (a_SrcZ); WriteFloat (a_Volume); - WriteByte ((char)(a_Pitch * 63.0f)); + WriteChar ((char)(a_Pitch * 63.0f)); Flush(); } @@ -320,7 +320,7 @@ void cProtocol132::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_Src WriteByte(PACKET_SOUND_PARTICLE_EFFECT); WriteInt (a_EffectID); WriteInt (a_SrcX); - WriteByte(a_SrcY); + WriteByte((Byte)a_SrcY); WriteInt (a_SrcZ); WriteInt (a_Data); Flush(); @@ -335,7 +335,7 @@ void cProtocol132::SendSpawnMob(const cMonster & a_Mob) cCSLock Lock(m_CSPacket); WriteByte (PACKET_SPAWN_MOB); WriteInt (a_Mob.GetUniqueID()); - WriteByte (a_Mob.GetMobType()); + WriteByte ((Byte)a_Mob.GetMobType()); WriteVectorI((Vector3i)(a_Mob.GetPosition() * 32)); WriteByte ((Byte)((a_Mob.GetYaw() / 360.f) * 256)); WriteByte ((Byte)((a_Mob.GetPitch() / 360.f) * 256)); @@ -411,12 +411,12 @@ void cProtocol132::SendWholeInventory(const cWindow & a_Window) const cInventory & Inventory = m_Client->GetPlayer()->GetInventory(); int BaseOffset = a_Window.GetNumSlots() - (cInventory::invNumSlots - cInventory::invInventoryOffset); // Number of non-inventory slots char WindowID = a_Window.GetWindowID(); - for (int i = 0; i < cInventory::invInventoryCount; i++) + for (short i = 0; i < cInventory::invInventoryCount; i++) { SendInventorySlot(WindowID, BaseOffset + i, Inventory.GetInventorySlot(i)); } // for i - Inventory[] BaseOffset += cInventory::invInventoryCount; - for (int i = 0; i < cInventory::invHotbarCount; i++) + for (short i = 0; i < cInventory::invHotbarCount; i++) { SendInventorySlot(WindowID, BaseOffset + i, Inventory.GetHotbarSlot(i)); } // for i - Hotbar[] @@ -527,21 +527,30 @@ int cProtocol132::ParseClientStatuses(void) int cProtocol132::ParseEncryptionKeyResponse(void) { + // Read the encryption key: HANDLE_PACKET_READ(ReadBEShort, short, EncKeyLength); + if (EncKeyLength > MAX_ENC_LEN) + { + LOGD("Too long encryption key"); + m_Client->Kick("Hacked client"); + return PARSE_OK; + } AString EncKey; - if (!m_ReceivedData.ReadString(EncKey, EncKeyLength)) + if (!m_ReceivedData.ReadString(EncKey, (size_t)EncKeyLength)) { return PARSE_INCOMPLETE; } + + // Read the encryption nonce: HANDLE_PACKET_READ(ReadBEShort, short, EncNonceLength); AString EncNonce; - if (!m_ReceivedData.ReadString(EncNonce, EncNonceLength)) + if (!m_ReceivedData.ReadString(EncNonce, (size_t)EncNonceLength)) { return PARSE_INCOMPLETE; } - if ((EncKeyLength > MAX_ENC_LEN) || (EncNonceLength > MAX_ENC_LEN)) + if (EncNonceLength > MAX_ENC_LEN) { - LOGD("Too long encryption"); + LOGD("Too long encryption nonce"); m_Client->Kick("Hacked client"); return PARSE_OK; } @@ -623,23 +632,23 @@ void cProtocol132::Flush(void) LOGD("Flushing empty"); return; } - const char * a_Data = m_DataToSend.data(); - int a_Size = m_DataToSend.size(); + const char * Data = m_DataToSend.data(); + size_t Size = m_DataToSend.size(); if (m_IsEncrypted) { Byte Encrypted[8192]; // Larger buffer, we may be sending lots of data (chunks) - while (a_Size > 0) + while (Size > 0) { - int NumBytes = (a_Size > (int)sizeof(Encrypted)) ? (int)sizeof(Encrypted) : a_Size; - m_Encryptor.ProcessData(Encrypted, (Byte *)a_Data, NumBytes); + size_t NumBytes = (Size > sizeof(Encrypted)) ? sizeof(Encrypted) : Size; + m_Encryptor.ProcessData(Encrypted, (Byte *)Data, NumBytes); super::SendData((const char *)Encrypted, NumBytes); - a_Size -= NumBytes; - a_Data += NumBytes; + Size -= NumBytes; + Data += NumBytes; } } else { - super::SendData(a_Data, a_Size); + super::SendData(Data, Size); } m_DataToSend.clear(); } @@ -665,7 +674,7 @@ void cProtocol132::WriteItem(const cItem & a_Item) } WriteShort(ItemType); - WriteByte (a_Item.m_ItemCount); + WriteChar (a_Item.m_ItemCount); WriteShort(a_Item.m_ItemDamage); if (a_Item.m_Enchantments.IsEmpty()) @@ -681,7 +690,7 @@ void cProtocol132::WriteItem(const cItem & a_Item) Writer.Finish(); AString Compressed; CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed); - WriteShort(Compressed.size()); + WriteShort((short)Compressed.size()); SendData(Compressed.data(), Compressed.size()); } @@ -717,8 +726,8 @@ int cProtocol132::ParseItem(cItem & a_Item) // Read the metadata AString Metadata; - Metadata.resize(MetadataLength); - if (!m_ReceivedData.ReadBuf((void *)Metadata.data(), MetadataLength)) + Metadata.resize((size_t)MetadataLength); + if (!m_ReceivedData.ReadBuf((void *)Metadata.data(), (size_t)MetadataLength)) { return PARSE_INCOMPLETE; } diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index ad622d707..f46730150 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -531,7 +531,7 @@ AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a format binary data this way: 00001234: 31 32 33 34 35 36 37 38 39 30 61 62 63 64 65 66 1234567890abcdef */ -AString & CreateHexDump(AString & a_Out, const void * a_Data, int a_Size, int a_LineLength) +AString & CreateHexDump(AString & a_Out, const void * a_Data, size_t a_Size, int a_LineLength) { ASSERT(a_LineLength <= 120); // Due to using a fixed size line buffer; increase line[]'s size to lift this max char line[512]; diff --git a/src/StringUtils.h b/src/StringUtils.h index da395e5b5..ce24e89bc 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -64,7 +64,7 @@ extern AString & RawBEToUTF8(const char * a_RawData, int a_NumShorts, AString & extern AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a_UTF16); /// Creates a nicely formatted HEX dump of the given memory block. Max a_BytesPerLine is 120 -extern AString & CreateHexDump(AString & a_Out, const void * a_Data, int a_Size, int a_BytesPerLine); +extern AString & CreateHexDump(AString & a_Out, const void * a_Data, size_t a_Size, int a_BytesPerLine); /// Returns a copy of a_Message with all quotes and backslashes escaped by a backslash extern AString EscapeString(const AString & a_Message); // tolua_export From e1f75ab6d0862d77bf91b588d54acf63fdf20c63 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 4 Apr 2014 10:42:17 +0200 Subject: [PATCH 135/145] Fixed CreateHexDump's signedness. --- src/Protocol/Protocol.h | 2 +- src/StringUtils.cpp | 18 +++++++++--------- src/StringUtils.h | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 8294fa8b7..ae06f2f9e 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -216,7 +216,7 @@ protected: { // A 32-bit integer can be encoded by at most 5 bytes: unsigned char b[5]; - int idx = 0; + size_t idx = 0; do { b[idx] = (a_Value & 0x7f) | ((a_Value > 0x7f) ? 0x80 : 0x00); diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index f46730150..a69d8750f 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -531,20 +531,20 @@ AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a format binary data this way: 00001234: 31 32 33 34 35 36 37 38 39 30 61 62 63 64 65 66 1234567890abcdef */ -AString & CreateHexDump(AString & a_Out, const void * a_Data, size_t a_Size, int a_LineLength) +AString & CreateHexDump(AString & a_Out, const void * a_Data, size_t a_Size, size_t a_BytesPerLine) { - ASSERT(a_LineLength <= 120); // Due to using a fixed size line buffer; increase line[]'s size to lift this max + ASSERT(a_BytesPerLine <= 120); // Due to using a fixed size line buffer; increase line[]'s size to lift this max char line[512]; char * p; char * q; - a_Out.reserve(a_Size / a_LineLength * (18 + 6 * a_LineLength)); - for (int i = 0; i < a_Size; i += a_LineLength) + a_Out.reserve(a_Size / a_BytesPerLine * (18 + 6 * a_BytesPerLine)); + for (size_t i = 0; i < a_Size; i += a_BytesPerLine) { - int k = a_Size - i; - if (k > a_LineLength) + size_t k = a_Size - i; + if (k > a_BytesPerLine) { - k = a_LineLength; + k = a_BytesPerLine; } #ifdef _MSC_VER // MSVC provides a "secure" version of sprintf() @@ -555,8 +555,8 @@ AString & CreateHexDump(AString & a_Out, const void * a_Data, size_t a_Size, int // Remove the terminating NULL / leftover garbage in line, after the sprintf-ed value memset(line + Count, 32, sizeof(line) - Count); p = line + 10; - q = p + 2 + a_LineLength * 3 + 1; - for (int j = 0; j < k; j++) + q = p + 2 + a_BytesPerLine * 3 + 1; + for (size_t j = 0; j < k; j++) { unsigned char c = ((unsigned char *)a_Data)[i + j]; p[0] = HEX(c >> 4); diff --git a/src/StringUtils.h b/src/StringUtils.h index ce24e89bc..b69e47d3c 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -64,7 +64,7 @@ extern AString & RawBEToUTF8(const char * a_RawData, int a_NumShorts, AString & extern AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a_UTF16); /// Creates a nicely formatted HEX dump of the given memory block. Max a_BytesPerLine is 120 -extern AString & CreateHexDump(AString & a_Out, const void * a_Data, size_t a_Size, int a_BytesPerLine); +extern AString & CreateHexDump(AString & a_Out, const void * a_Data, size_t a_Size, size_t a_BytesPerLine); /// Returns a copy of a_Message with all quotes and backslashes escaped by a backslash extern AString EscapeString(const AString & a_Message); // tolua_export From 3590f97e00e570df7a18d953212f33d947f3896c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 4 Apr 2014 11:19:57 +0200 Subject: [PATCH 136/145] Fixed CreateHexDump's format string. --- src/StringUtils.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index a69d8750f..33b04505f 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -548,9 +548,9 @@ AString & CreateHexDump(AString & a_Out, const void * a_Data, size_t a_Size, siz } #ifdef _MSC_VER // MSVC provides a "secure" version of sprintf() - int Count = sprintf_s(line, sizeof(line), "%08x:", i); + int Count = sprintf_s(line, sizeof(line), "%08x:", (unsigned)i); #else - int Count = sprintf(line, "%08x:", i); + int Count = sprintf(line, "%08x:", (unsigned)i); #endif // Remove the terminating NULL / leftover garbage in line, after the sprintf-ed value memset(line + Count, 32, sizeof(line) - Count); From 4be894f0601fcfa182fda045b07b196e5dcd9343 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 4 Apr 2014 11:47:46 +0200 Subject: [PATCH 137/145] More Clang warning fixes in the protocols. --- src/Protocol/ChunkDataSerializer.cpp | 4 +- src/Protocol/Protocol125.cpp | 139 ++++++++++++++------------- src/Protocol/Protocol16x.cpp | 8 +- src/Protocol/Protocol17x.cpp | 2 +- src/Protocol/Protocol17x.h | 4 +- src/Protocol/ProtocolRecognizer.cpp | 6 +- 6 files changed, 82 insertions(+), 81 deletions(-) diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp index 78318a5ee..ebe61631b 100644 --- a/src/Protocol/ChunkDataSerializer.cpp +++ b/src/Protocol/ChunkDataSerializer.cpp @@ -105,7 +105,7 @@ void cChunkDataSerializer::Serialize29(AString & a_Data) a_Data.append((const char *)&BitMap1, sizeof(short)); a_Data.append((const char *)&BitMap2, sizeof(short)); - Int32 CompressedSizeBE = htonl(CompressedSize); + UInt32 CompressedSizeBE = htonl((UInt32)CompressedSize); a_Data.append((const char *)&CompressedSizeBE, sizeof(CompressedSizeBE)); Int32 UnusedInt32 = 0; @@ -163,7 +163,7 @@ void cChunkDataSerializer::Serialize39(AString & a_Data) a_Data.append((const char *)&BitMap1, sizeof(short)); a_Data.append((const char *)&BitMap2, sizeof(short)); - Int32 CompressedSizeBE = htonl(CompressedSize); + UInt32 CompressedSizeBE = htonl((UInt32)CompressedSize); a_Data.append((const char *)&CompressedSizeBE, sizeof(CompressedSizeBE)); // Unlike 29, 39 doesn't have the "unused" int diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 0fa5c6de7..231ae410f 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -161,8 +161,8 @@ void cProtocol125::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, cha WriteInt (a_BlockX); WriteShort((short)a_BlockY); WriteInt (a_BlockZ); - WriteByte (a_Byte1); - WriteByte (a_Byte2); + WriteChar (a_Byte1); + WriteChar (a_Byte2); Flush(); } @@ -209,12 +209,12 @@ void cProtocol125::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV WriteByte (PACKET_MULTI_BLOCK); WriteInt (a_ChunkX); WriteInt (a_ChunkZ); - WriteShort((unsigned short)a_Changes.size()); - WriteUInt (sizeof(int) * a_Changes.size()); + WriteShort((short)a_Changes.size()); + WriteUInt ((UInt32)(sizeof(int) * a_Changes.size())); for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr) { - unsigned int Coords = itr->y | (itr->z << 8) | (itr->x << 12); - unsigned int Blocks = itr->BlockMeta | (itr->BlockType << 4); + UInt32 Coords = ((UInt32)itr->y) | ((UInt32)(itr->z << 8)) | ((UInt32)(itr->x << 12)); + UInt32 Blocks = ((UInt32)itr->BlockMeta) | ((UInt32)(itr->BlockType << 4)); WriteUInt(Coords << 16 | Blocks); } Flush(); @@ -325,8 +325,8 @@ void cProtocol125::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, in cCSLock Lock(m_CSPacket); WriteByte (PACKET_ENTITY_EFFECT); WriteInt (a_Entity.GetUniqueID()); - WriteByte (a_EffectID); - WriteByte (a_Amplifier); + WriteByte ((Byte)a_EffectID); + WriteByte ((Byte)a_Amplifier); WriteShort(a_Duration); Flush(); } @@ -357,7 +357,7 @@ void cProtocol125::SendEntityHeadLook(const cEntity & a_Entity) cCSLock Lock(m_CSPacket); WriteByte(PACKET_ENT_HEAD_LOOK); WriteInt (a_Entity.GetUniqueID()); - WriteByte((char)((a_Entity.GetHeadYaw() / 360.f) * 256)); + WriteChar((char)((a_Entity.GetHeadYaw() / 360.f) * 256)); Flush(); } @@ -372,8 +372,8 @@ void cProtocol125::SendEntityLook(const cEntity & a_Entity) cCSLock Lock(m_CSPacket); WriteByte(PACKET_ENT_LOOK); WriteInt (a_Entity.GetUniqueID()); - WriteByte((char)((a_Entity.GetYaw() / 360.f) * 256)); - WriteByte((char)((a_Entity.GetPitch() / 360.f) * 256)); + WriteChar((char)((a_Entity.GetYaw() / 360.f) * 256)); + WriteChar((char)((a_Entity.GetPitch() / 360.f) * 256)); Flush(); } @@ -421,9 +421,9 @@ void cProtocol125::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char cCSLock Lock(m_CSPacket); WriteByte(PACKET_ENT_REL_MOVE); WriteInt (a_Entity.GetUniqueID()); - WriteByte(a_RelX); - WriteByte(a_RelY); - WriteByte(a_RelZ); + WriteChar(a_RelX); + WriteChar(a_RelY); + WriteChar(a_RelZ); Flush(); } @@ -438,11 +438,11 @@ void cProtocol125::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, cCSLock Lock(m_CSPacket); WriteByte(PACKET_ENT_REL_MOVE_LOOK); WriteInt (a_Entity.GetUniqueID()); - WriteByte(a_RelX); - WriteByte(a_RelY); - WriteByte(a_RelZ); - WriteByte((char)((a_Entity.GetYaw() / 360.f) * 256)); - WriteByte((char)((a_Entity.GetPitch() / 360.f) * 256)); + WriteChar(a_RelX); + WriteChar(a_RelY); + WriteChar(a_RelZ); + WriteChar((char)((a_Entity.GetYaw() / 360.f) * 256)); + WriteChar((char)((a_Entity.GetPitch() / 360.f) * 256)); Flush(); } @@ -455,7 +455,7 @@ void cProtocol125::SendEntityStatus(const cEntity & a_Entity, char a_Status) cCSLock Lock(m_CSPacket); WriteByte(PACKET_ENT_STATUS); WriteInt (a_Entity.GetUniqueID()); - WriteByte(a_Status); + WriteChar(a_Status); Flush(); } @@ -488,7 +488,7 @@ void cProtocol125::SendExplosion(double a_BlockX, double a_BlockY, double a_Bloc WriteDouble (a_BlockY); WriteDouble (a_BlockZ); WriteFloat (a_Radius); - WriteInt (a_BlocksAffected.size()); + WriteInt ((Int32)a_BlocksAffected.size()); int BlockX = (int)a_BlockX; int BlockY = (int)a_BlockY; int BlockZ = (int)a_BlockZ; @@ -513,7 +513,7 @@ void cProtocol125::SendGameMode(eGameMode a_GameMode) cCSLock Lock(m_CSPacket); WriteByte(PACKET_CHANGE_GAME_STATE); WriteByte(3); - WriteByte((char)a_GameMode); + WriteChar((char)a_GameMode); Flush(); } @@ -538,7 +538,7 @@ void cProtocol125::SendHealth(void) cCSLock Lock(m_CSPacket); WriteByte (PACKET_UPDATE_HEALTH); WriteShort((short)m_Client->GetPlayer()->GetHealth()); - WriteShort(m_Client->GetPlayer()->GetFoodLevel()); + WriteShort((short)m_Client->GetPlayer()->GetFoodLevel()); WriteFloat((float)m_Client->GetPlayer()->GetFoodSaturationLevel()); Flush(); } @@ -551,7 +551,7 @@ void cProtocol125::SendInventorySlot(char a_WindowID, short a_SlotNum, const cIt { cCSLock Lock(m_CSPacket); WriteByte (PACKET_INVENTORY_SLOT); - WriteByte (a_WindowID); + WriteChar (a_WindowID); WriteShort(a_SlotNum); WriteItem (a_Item); Flush(); @@ -600,17 +600,14 @@ void cProtocol125::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colo WriteByte (PACKET_ITEM_DATA); WriteShort(E_ITEM_MAP); - WriteShort(a_ID); - WriteShort(3 + a_Length); + WriteShort((short)a_ID); + WriteShort((short)(3 + a_Length)); WriteByte(0); - WriteByte(a_X); - WriteByte(a_Y); + WriteChar((char)a_X); + WriteChar((char)a_Y); - for (unsigned int i = 0; i < a_Length; ++i) - { - WriteByte(a_Colors[i]); - } + SendData((const char *)a_Colors, a_Length); Flush(); } @@ -625,16 +622,16 @@ void cProtocol125::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decor WriteByte (PACKET_ITEM_DATA); WriteShort(E_ITEM_MAP); - WriteShort(a_ID); - WriteShort(1 + (3 * a_Decorators.size())); + WriteShort((short)a_ID); + WriteShort((short)(1 + (3 * a_Decorators.size()))); WriteByte(1); for (cMapDecoratorList::const_iterator it = a_Decorators.begin(); it != a_Decorators.end(); ++it) { - WriteByte((it->GetType() << 4) | (it->GetRot() & 0xf)); - WriteByte(it->GetPixelX()); - WriteByte(it->GetPixelZ()); + WriteByte((Byte)(it->GetType() << 4) | (it->GetRot() & 0xf)); + WriteByte((Byte)it->GetPixelX()); + WriteByte((Byte)it->GetPixelZ()); } Flush(); @@ -651,7 +648,7 @@ void cProtocol125::SendPickupSpawn(const cPickup & a_Pickup) WriteByte (PACKET_PICKUP_SPAWN); WriteInt (a_Pickup.GetUniqueID()); WriteShort (a_Pickup.GetItem().m_ItemType); - WriteByte (a_Pickup.GetItem().m_ItemCount); + WriteChar (a_Pickup.GetItem().m_ItemCount); WriteShort (a_Pickup.GetItem().m_ItemDamage); WriteVectorI((Vector3i)(a_Pickup.GetPosition() * 32)); WriteByte ((char)(a_Pickup.GetSpeed().x * 8)); @@ -669,7 +666,7 @@ void cProtocol125::SendEntityAnimation(const cEntity & a_Entity, char a_Animatio cCSLock Lock(m_CSPacket); WriteByte(PACKET_ANIMATION); WriteInt (a_Entity.GetUniqueID()); - WriteByte(a_Animation); + WriteChar(a_Animation); Flush(); } @@ -763,8 +760,8 @@ void cProtocol125::SendPlayerSpawn(const cPlayer & a_Player) WriteInt ((int)(a_Player.GetPosX() * 32)); WriteInt ((int)(a_Player.GetPosY() * 32)); WriteInt ((int)(a_Player.GetPosZ() * 32)); - WriteByte ((char)((a_Player.GetYaw() / 360.f) * 256)); - WriteByte ((char)((a_Player.GetPitch() / 360.f) * 256)); + WriteChar ((char)((a_Player.GetYaw() / 360.f) * 256)); + WriteChar ((char)((a_Player.GetPitch() / 360.f) * 256)); WriteShort (HeldItem.IsEmpty() ? 0 : HeldItem.m_ItemType); Flush(); } @@ -790,9 +787,9 @@ void cProtocol125::SendPluginMessage(const AString & a_Channel, const AString & void cProtocol125::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) { cCSLock Lock(m_CSPacket); - WriteByte (PACKET_REMOVE_ENTITY_EFFECT); - WriteInt (a_Entity.GetUniqueID()); - WriteByte (a_EffectID); + WriteByte(PACKET_REMOVE_ENTITY_EFFECT); + WriteInt (a_Entity.GetUniqueID()); + WriteChar((char)a_EffectID); Flush(); } @@ -806,7 +803,7 @@ void cProtocol125::SendRespawn(void) WriteByte (PACKET_RESPAWN); WriteInt ((int)(m_Client->GetPlayer()->GetWorld()->GetDimension())); WriteByte (2); // TODO: Difficulty; 2 = Normal - WriteByte ((char)m_Client->GetPlayer()->GetGameMode()); + WriteChar ((char)m_Client->GetPlayer()->GetGameMode()); WriteShort (256); // Current world height WriteString("default"); } @@ -837,7 +834,7 @@ void cProtocol125::SendExperienceOrb(const cExpOrb & a_ExpOrb) WriteInt((int) a_ExpOrb.GetPosX()); WriteInt((int) a_ExpOrb.GetPosY()); WriteInt((int) a_ExpOrb.GetPosZ()); - WriteShort(a_ExpOrb.GetReward()); + WriteShort((short)a_ExpOrb.GetReward()); Flush(); } @@ -878,7 +875,7 @@ void cProtocol125::SendSpawnMob(const cMonster & a_Mob) cCSLock Lock(m_CSPacket); WriteByte (PACKET_SPAWN_MOB); WriteInt (a_Mob.GetUniqueID()); - WriteByte (a_Mob.GetMobType()); + WriteByte ((Byte)a_Mob.GetMobType()); WriteVectorI((Vector3i)(a_Mob.GetPosition() * 32)); WriteByte (0); WriteByte (0); @@ -903,7 +900,7 @@ void cProtocol125::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, cCSLock Lock(m_CSPacket); WriteByte(PACKET_SPAWN_OBJECT); WriteInt (a_Entity.GetUniqueID()); - WriteByte(a_ObjectType); + WriteChar(a_ObjectType); WriteInt ((int)(a_Entity.GetPosX() * 32)); WriteInt ((int)(a_Entity.GetPosY() * 32)); WriteInt ((int)(a_Entity.GetPosZ() * 32)); @@ -928,7 +925,7 @@ void cProtocol125::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleTyp cCSLock Lock(m_CSPacket); WriteByte (PACKET_SPAWN_OBJECT); WriteInt (a_Vehicle.GetUniqueID()); - WriteByte (a_VehicleType); + WriteChar (a_VehicleType); WriteInt ((int)(a_Vehicle.GetPosX() * 32)); WriteInt ((int)(a_Vehicle.GetPosY() * 32)); WriteInt ((int)(a_Vehicle.GetPosZ() * 32)); @@ -966,8 +963,8 @@ void cProtocol125::SendTeleportEntity(const cEntity & a_Entity) WriteInt ((int)(floor(a_Entity.GetPosX() * 32))); WriteInt ((int)(floor(a_Entity.GetPosY() * 32))); WriteInt ((int)(floor(a_Entity.GetPosZ() * 32))); - WriteByte ((char)((a_Entity.GetYaw() / 360.f) * 256)); - WriteByte ((char)((a_Entity.GetPitch() / 360.f) * 256)); + WriteChar ((char)((a_Entity.GetYaw() / 360.f) * 256)); + WriteChar ((char)((a_Entity.GetPitch() / 360.f) * 256)); Flush(); } @@ -1042,7 +1039,7 @@ void cProtocol125::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_Bloc WriteInt (a_Entity.GetUniqueID()); WriteByte(0); // Unknown byte only 0 has been observed WriteInt (a_BlockX); - WriteByte(a_BlockY); + WriteByte((Byte)a_BlockY); WriteInt (a_BlockZ); Flush(); } @@ -1086,7 +1083,7 @@ void cProtocol125::SendWholeInventory(const cWindow & a_Window) cCSLock Lock(m_CSPacket); cItems Slots; a_Window.GetSlots(*(m_Client->GetPlayer()), Slots); - SendWindowSlots(a_Window.GetWindowID(), Slots.size(), &(Slots[0])); + SendWindowSlots(a_Window.GetWindowID(), (int)Slots.size(), &(Slots[0])); } @@ -1103,7 +1100,7 @@ void cProtocol125::SendWindowClose(const cWindow & a_Window) cCSLock Lock(m_CSPacket); WriteByte(PACKET_WINDOW_CLOSE); - WriteByte(a_Window.GetWindowID()); + WriteChar(a_Window.GetWindowID()); Flush(); } @@ -1120,10 +1117,10 @@ void cProtocol125::SendWindowOpen(const cWindow & a_Window) } cCSLock Lock(m_CSPacket); WriteByte (PACKET_WINDOW_OPEN); - WriteByte (a_Window.GetWindowID()); - WriteByte (a_Window.GetWindowType()); + WriteChar (a_Window.GetWindowID()); + WriteByte ((Byte)a_Window.GetWindowType()); WriteString(a_Window.GetWindowTitle()); - WriteByte (a_Window.GetNumNonInventorySlots()); + WriteByte ((Byte)a_Window.GetNumNonInventorySlots()); Flush(); } @@ -1135,7 +1132,7 @@ void cProtocol125::SendWindowProperty(const cWindow & a_Window, short a_Property { cCSLock Lock(m_CSPacket); WriteByte (PACKET_WINDOW_PROPERTY); - WriteByte (a_Window.GetWindowID()); + WriteChar (a_Window.GetWindowID()); WriteShort(a_Property); WriteShort(a_Value); Flush(); @@ -1527,7 +1524,7 @@ int cProtocol125::ParsePluginMessage(void) HANDLE_PACKET_READ(ReadBEUTF16String16, AString, ChannelName); HANDLE_PACKET_READ(ReadBEShort, short, Length); AString Data; - if (!m_ReceivedData.ReadString(Data, Length)) + if (!m_ReceivedData.ReadString(Data, (size_t)Length)) { m_ReceivedData.CheckValid(); return PARSE_INCOMPLETE; @@ -1688,7 +1685,7 @@ void cProtocol125::SendPreChunk(int a_ChunkX, int a_ChunkZ, bool a_ShouldLoad) void cProtocol125::SendWindowSlots(char a_WindowID, int a_NumItems, const cItem * a_Items) { WriteByte (PACKET_INVENTORY_WHOLE); - WriteByte (a_WindowID); + WriteChar (a_WindowID); WriteShort((short)a_NumItems); for (int j = 0; j < a_NumItems; j++) @@ -1718,7 +1715,7 @@ void cProtocol125::WriteItem(const cItem & a_Item) return; } - WriteByte (a_Item.m_ItemCount); + WriteChar (a_Item.m_ItemCount); WriteShort(a_Item.m_ItemDamage); if (cItem::IsEnchantable(a_Item.m_ItemType)) @@ -1765,7 +1762,7 @@ int cProtocol125::ParseItem(cItem & a_Item) } // TODO: Enchantment not implemented yet! - if (!m_ReceivedData.SkipRead(EnchantNumBytes)) + if (!m_ReceivedData.SkipRead((size_t)EnchantNumBytes)) { return PARSE_INCOMPLETE; } @@ -1850,7 +1847,7 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) case cMonster::mtCreeper: { WriteByte(0x10); - WriteByte(((const cCreeper &)a_Mob).IsBlowing() ? 1 : -1); // Blowing up? + WriteChar(((const cCreeper &)a_Mob).IsBlowing() ? 1 : -1); // Blowing up? WriteByte(0x11); WriteByte(((const cCreeper &)a_Mob).IsCharged() ? 1 : 0); // Lightning-charged? break; @@ -1920,9 +1917,9 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) WriteByte(0x10); Byte SheepMetadata = 0; - SheepMetadata = ((const cSheep &)a_Mob).GetFurColor(); // Fur colour + SheepMetadata = (Byte)((const cSheep &)a_Mob).GetFurColor(); - if (((const cSheep &)a_Mob).IsSheared()) // Is sheared? + if (((const cSheep &)a_Mob).IsSheared()) { SheepMetadata |= 0x16; } @@ -1954,7 +1951,7 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) case cMonster::mtWither: { WriteByte(0x54); // Int at index 20 - WriteInt(((const cWither &)a_Mob).GetNumInvulnerableTicks()); + WriteInt((Int32)((const cWither &)a_Mob).GetNumInvulnerableTicks()); WriteByte(0x66); // Float at index 6 WriteFloat((float)(a_Mob.GetHealth())); break; @@ -1965,11 +1962,11 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) WriteByte(0x10); if (a_Mob.GetMobType() == cMonster::mtSlime) { - WriteByte(((const cSlime &)a_Mob).GetSize()); // Size of slime - HEWGE, meh, cute BABBY SLIME + WriteByte((Byte)((const cSlime &)a_Mob).GetSize()); // Size of slime - HEWGE, meh, cute BABBY SLIME } else { - WriteByte(((const cMagmaCube &)a_Mob).GetSize()); // Size of slime - HEWGE, meh, cute BABBY SLIME + WriteByte((Byte)((const cMagmaCube &)a_Mob).GetSize()); // Size of slime - HEWGE, meh, cute BABBY SLIME } break; } @@ -2008,7 +2005,7 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) WriteInt(Flags); WriteByte(0x13); - WriteByte(((const cHorse &)a_Mob).GetHorseType()); // Type of horse (donkey, chestnut, etc.) + WriteByte((Byte)((const cHorse &)a_Mob).GetHorseType()); // Type of horse (donkey, chestnut, etc.) WriteByte(0x54); int Appearance = 0; @@ -2020,6 +2017,10 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) WriteInt(((const cHorse &)a_Mob).GetHorseArmour()); // Horshey armour break; } + default: + { + break; + } } } diff --git a/src/Protocol/Protocol16x.cpp b/src/Protocol/Protocol16x.cpp index ecb24254f..bf7d9a0b1 100644 --- a/src/Protocol/Protocol16x.cpp +++ b/src/Protocol/Protocol16x.cpp @@ -119,7 +119,7 @@ void cProtocol161::SendHealth(void) cCSLock Lock(m_CSPacket); WriteByte (PACKET_UPDATE_HEALTH); WriteFloat((float)m_Client->GetPlayer()->GetHealth()); - WriteShort(m_Client->GetPlayer()->GetFoodLevel()); + WriteShort((short)m_Client->GetPlayer()->GetFoodLevel()); WriteFloat((float)m_Client->GetPlayer()->GetFoodSaturationLevel()); Flush(); } @@ -163,10 +163,10 @@ void cProtocol161::SendWindowOpen(const cWindow & a_Window) } cCSLock Lock(m_CSPacket); WriteByte (PACKET_WINDOW_OPEN); - WriteByte (a_Window.GetWindowID()); - WriteByte (a_Window.GetWindowType()); + WriteChar (a_Window.GetWindowID()); + WriteByte ((Byte)a_Window.GetWindowType()); WriteString(a_Window.GetWindowTitle()); - WriteByte (a_Window.GetNumNonInventorySlots()); + WriteByte ((Byte)a_Window.GetNumNonInventorySlots()); WriteByte (1); // Use title if (a_Window.GetWindowType() == cWindow::wtAnimalChest) { diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index b987294b0..cbc138990 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1236,7 +1236,7 @@ void cProtocol172::SendWindowProperty(const cWindow & a_Window, short a_Property -void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) +void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) { // Write the incoming data into the comm log file: if (g_ShouldLogCommIn) diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index bb6ee575a..91186b270 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -196,7 +196,7 @@ protected: m_Out.WriteVarUTF8String(a_Value); } - void WriteBuf(const char * a_Data, int a_Size) + void WriteBuf(const char * a_Data, size_t a_Size) { m_Out.Write(a_Data, a_Size); } @@ -243,7 +243,7 @@ protected: /** Adds the received (unencrypted) data to m_ReceivedData, parses complete packets */ - void AddReceivedData(const char * a_Data, int a_Size); + void AddReceivedData(const char * a_Data, size_t a_Size); /** Reads and handles the packet. The packet length and type have already been read. Returns true if the packet was understood, false if it was an unknown packet diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 81f146370..3f7d7b254 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -854,7 +854,7 @@ bool cProtocolRecognizer::TryRecognizeProtocol(void) // This must be a lengthed protocol, try if it has the entire initial handshake packet: m_Buffer.ResetRead(); UInt32 PacketLen; - UInt32 ReadSoFar = m_Buffer.GetReadableSpace(); + UInt32 ReadSoFar = (UInt32)m_Buffer.GetReadableSpace(); if (!m_Buffer.ReadVarInt(PacketLen)) { // Not enough bytes for the packet length, keep waiting @@ -931,7 +931,7 @@ bool cProtocolRecognizer::TryRecognizeLengthlessProtocol(void) bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRemaining) { UInt32 PacketType; - UInt32 NumBytesRead = m_Buffer.GetReadableSpace(); + UInt32 NumBytesRead = (UInt32)m_Buffer.GetReadableSpace(); if (!m_Buffer.ReadVarInt(PacketType)) { return false; @@ -962,7 +962,7 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema m_Buffer.ReadBEShort(ServerPort); m_Buffer.ReadVarInt(NextState); m_Buffer.CommitRead(); - m_Protocol = new cProtocol172(m_Client, ServerAddress, ServerPort, NextState); + m_Protocol = new cProtocol172(m_Client, ServerAddress, (UInt16)ServerPort, NextState); return true; } } From bc227299d0a1111da8bf7b61165649b2f9345e5d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 4 Apr 2014 12:08:14 +0200 Subject: [PATCH 138/145] Fixed format string mismatch. --- src/Protocol/Protocol17x.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index cbc138990..a4319df37 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1258,7 +1258,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) AString Hex; CreateHexDump(Hex, a_Data, a_Size, 16); m_CommLogFile.Printf("Incoming data: %d (0x%x) bytes: \n%s\n", - a_Size, a_Size, Hex.c_str() + (unsigned)a_Size, (unsigned)a_Size, Hex.c_str() ); m_CommLogFile.Flush(); } From 4b4c3f2a204d353e1fa793d1a2b08838221a8616 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 4 Apr 2014 12:28:38 +0200 Subject: [PATCH 139/145] Changed cNoise seed to signed. --- src/Noise.cpp | 2 +- src/Noise.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Noise.cpp b/src/Noise.cpp index a97ea70c6..32922c8f3 100644 --- a/src/Noise.cpp +++ b/src/Noise.cpp @@ -425,7 +425,7 @@ void cCubicCell3D::Move(int a_NewFloorX, int a_NewFloorY, int a_NewFloorZ) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cNoise: -cNoise::cNoise(unsigned int a_Seed) : +cNoise::cNoise(int a_Seed) : m_Seed(a_Seed) { } diff --git a/src/Noise.h b/src/Noise.h index ea72c64e9..62004503f 100644 --- a/src/Noise.h +++ b/src/Noise.h @@ -25,7 +25,7 @@ class cNoise { public: - cNoise(unsigned int a_Seed); + cNoise(int a_Seed); cNoise(const cNoise & a_Noise); // The following functions, if not marked INLINE, are about 20 % slower @@ -47,14 +47,14 @@ public: NOISE_DATATYPE CubicNoise3D (NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOISE_DATATYPE a_Z) const; - void SetSeed(unsigned int a_Seed) { m_Seed = a_Seed; } + void SetSeed(int a_Seed) { m_Seed = a_Seed; } INLINE static NOISE_DATATYPE CubicInterpolate (NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_C, NOISE_DATATYPE a_D, NOISE_DATATYPE a_Pct); INLINE static NOISE_DATATYPE CosineInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct); INLINE static NOISE_DATATYPE LinearInterpolate(NOISE_DATATYPE a_A, NOISE_DATATYPE a_B, NOISE_DATATYPE a_Pct); private: - unsigned int m_Seed; + int m_Seed; } ; From 87f39e9e287aa1a7e513036f5004ec24ac789f40 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 4 Apr 2014 13:19:25 +0200 Subject: [PATCH 140/145] Explicit change record size. --- src/Protocol/Protocol125.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 231ae410f..bf946ef19 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -210,7 +210,7 @@ void cProtocol125::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV WriteInt (a_ChunkX); WriteInt (a_ChunkZ); WriteShort((short)a_Changes.size()); - WriteUInt ((UInt32)(sizeof(int) * a_Changes.size())); + WriteUInt ((UInt32)(4 * a_Changes.size())); for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr) { UInt32 Coords = ((UInt32)itr->y) | ((UInt32)(itr->z << 8)) | ((UInt32)(itr->x << 12)); From 1cab52f86799b98940da910e84e207b6037a5cd2 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 4 Apr 2014 23:06:47 +0200 Subject: [PATCH 141/145] Added cPlayer:SendRotation() API function. --- src/Entities/Player.cpp | 11 +++++++++++ src/Entities/Player.h | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 646aad50f..7f2e5b4c2 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1124,6 +1124,17 @@ void cPlayer::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ) +void cPlayer::SendRotation(double a_YawDegrees, double a_PitchDegrees) +{ + SetYaw(a_YawDegrees); + SetPitch(a_PitchDegrees); + m_ClientHandle->SendPlayerMoveLook(); +} + + + + + Vector3d cPlayer::GetThrowStartPos(void) const { Vector3d res = GetEyePosition(); diff --git a/src/Entities/Player.h b/src/Entities/Player.h index ea32dbfb9..05377a117 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -129,6 +129,12 @@ public: // tolua_begin + /** Sends the "look" packet to the player, forcing them to set their rotation to the specified values. + a_YawDegrees is clipped to range [-180, +180), + a_PitchDegrees is clipped to range [-180, +180) but the client only uses [-90, +90] + */ + void SendRotation(double a_YawDegrees, double a_PitchDegrees); + /** Returns the position where projectiles thrown by this player should start, player eye position + adjustment */ Vector3d GetThrowStartPos(void) const; From 43e3a55a70b7ec79046ea0de4f1912177ea3eb25 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 5 Apr 2014 12:09:14 +0200 Subject: [PATCH 142/145] Added more API documentation to cCompositeChat. --- MCServer/Plugins/APIDump/APIDesc.lua | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index b3b7dd11c..59dd93137 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -551,7 +551,22 @@ end {{cPlayer}}:SendMessage(), {{cWorld}}:BroadcastChat() and {{cRoot}}:BroadcastChat().

    Note that most of the functions in this class are so-called modifiers - they modify the object and - then return the object itself, so that they can be chained one after another. + then return the object itself, so that they can be chained one after another. See the Chaining + example below for details.

    +

    + Each part of the composite chat message takes a "Style" parameter, this is a string that describes + the formatting. It uses the following strings, concatenated together: + + + + + + + + +
    StringStyle
    bBold text
    iItalic text
    uUnderlined text
    sStrikethrough text
    oObfuscated text
    @Xcolor X (X is 0 - 9 or a - f, same as dye meta
    + The following picture, taken from MineCraft Wiki, illustrates the color codes:

    + ]], Functions = { @@ -565,6 +580,7 @@ end AddTextPart = { Params = "Text, [Style]", Return = "self", Notes = "Adds a regular text. Chaining." }, AddUrlPart = { Params = "Text, Url, [Style]", Return = "self", Notes = "Adds a text which, when clicked, opens up a browser at the specified URL. Chaining." }, Clear = { Params = "", Return = "", Notes = "Removes all parts from this object" }, + ExtractText = { Params = "", Return = "string", Notes = "Returns the text from the parts that comprises the human-readable data. Used for older protocols that don't support composite chat and for console-logging." }, GetMessageType = { Params = "", Return = "MessageType", Notes = "Returns the MessageType (mtXXX constant) that is associated with this message. When sent to a player, the message will be formatted according to this message type and the player's settings (adding \"[INFO]\" prefix etc.)" }, ParseText = { Params = "Text", Return = "self", Notes = "Adds text, while recognizing http and https URLs and old-style formatting codes (\"@2\"). Chaining." }, SetMessageType = { Params = "MessageType", Return = "self", Notes = "Sets the MessageType (mtXXX constant) that is associated with this message. When sent to a player, the message will be formatted according to this message type and the player's settings (adding \"[INFO]\" prefix etc.) Chaining." }, From d43c5a9c474bd6e4fbd74f09cca9b9bdbbd88b71 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 5 Apr 2014 22:25:40 +0200 Subject: [PATCH 143/145] Removed debugging log from entity physics handling. --- src/Entities/ProjectileEntity.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index a9735a53c..e86bb48bd 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -371,13 +371,14 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) SetYawFromSpeed(); SetPitchFromSpeed(); - // DEBUG: + /* LOGD("Projectile %d: pos {%.02f, %.02f, %.02f}, speed {%.02f, %.02f, %.02f}, rot {%.02f, %.02f}", m_UniqueID, GetPosX(), GetPosY(), GetPosZ(), GetSpeedX(), GetSpeedY(), GetSpeedZ(), GetYaw(), GetPitch() ); + */ } From 22794e720883dea9f80d22ab13221cb345bdc186 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 5 Apr 2014 22:26:10 +0200 Subject: [PATCH 144/145] Fixed double projectile spawning. Two spawn packets were sent per projectile. --- src/World.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/World.cpp b/src/World.cpp index e39a605bb..c188fd522 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2993,7 +2993,6 @@ int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProje delete Projectile; return -1; } - BroadcastSpawnEntity(*Projectile); return Projectile->GetUniqueID(); } From 143a5e61fc8e704f3df776d089217f031bc47779 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 5 Apr 2014 22:34:05 +0200 Subject: [PATCH 145/145] Fixed Endiannes conversion routines for floats and doubles. This bug has been introduced in 8825d30aabbee8cb2e452dc5a17deb6f9b6892a7. This change fixes #854. --- src/Endianness.h | 4 ++-- src/Entities/Entity.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Endianness.h b/src/Endianness.h index 6a2593077..78f9a5d99 100644 --- a/src/Endianness.h +++ b/src/Endianness.h @@ -49,7 +49,7 @@ inline double NetworkToHostDouble8(const void * a_Value) inline Int64 NetworkToHostLong8(const void * a_Value) { UInt64 buf; - memcpy(&buf, &a_Value, 8); + memcpy(&buf, a_Value, 8); buf = ntohll(buf); return *reinterpret_cast(&buf); } @@ -62,7 +62,7 @@ inline float NetworkToHostFloat4(const void * a_Value) { UInt32 buf; float x; - memcpy(&buf, &a_Value, 4); + memcpy(&buf, a_Value, 4); buf = ntohl(buf); memcpy(&x, &buf, sizeof(float)); return x; diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 221cbbea7..8ef45f1a5 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1469,7 +1469,7 @@ void cEntity::SteerVehicle(float a_Forward, float a_Sideways) Vector3d cEntity::GetLookVector(void) const { Matrix4d m; - m.Init(Vector3f(), 0, m_Rot.x, -m_Rot.y); + m.Init(Vector3d(), 0, m_Rot.x, -m_Rot.y); Vector3d Look = m.Transform(Vector3d(0, 0, 1)); return Look; }