summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml14
-rwxr-xr-xCIbuild.sh11
-rw-r--r--CMakeLists.txt11
-rw-r--r--CONTRIBUTORS1
-rw-r--r--GETTING-STARTED.md24
-rw-r--r--MCServer/Plugins/APIDump/APIDesc.lua16
-rw-r--r--MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua5
-rw-r--r--MCServer/Plugins/APIDump/InfoFile.html246
-rw-r--r--MCServer/Plugins/ChunkWorx/chunkworx_web.lua2
-rw-r--r--MCServer/Plugins/Debuggers/Debuggers.lua14
-rw-r--r--MCServer/Plugins/Handy/handy_functions.lua4
-rw-r--r--MCServer/furnace.txt42
-rw-r--r--README.md2
-rw-r--r--SetFlags.cmake83
-rw-r--r--Tools/AnvilStats/AnvilStats.sln45
-rw-r--r--Tools/AnvilStats/BiomeMap.cpp35
-rw-r--r--Tools/AnvilStats/BiomeMap.h2
-rw-r--r--Tools/AnvilStats/Globals.h22
-rw-r--r--Tools/AnvilStats/SpringStats.cpp2
-rw-r--r--Tools/MCADefrag/Globals.h1
-rw-r--r--docs/Generator.html529
-rw-r--r--docs/img/biomalheights.jpgbin0 -> 77747 bytes
-rw-r--r--docs/img/biomeheights.jpgbin0 -> 16432 bytes
-rw-r--r--docs/img/biomeheightsavg.jpgbin0 -> 14946 bytes
-rw-r--r--docs/img/biomes.jpgbin0 -> 12833 bytes
-rw-r--r--docs/img/distortedvoronoibiomes.pngbin0 -> 6012 bytes
-rw-r--r--docs/img/finishers.jpgbin0 -> 14701 bytes
-rw-r--r--docs/img/gaussprobability.jpgbin0 -> 12994 bytes
-rw-r--r--docs/img/jittergrid.jpgbin0 -> 18522 bytes
-rw-r--r--docs/img/jittergridlocality.jpgbin0 -> 15026 bytes
-rw-r--r--docs/img/multistepmapbiomes.pngbin0 -> 11103 bytes
-rw-r--r--docs/img/multistepmapdistance.jpgbin0 -> 16536 bytes
-rw-r--r--docs/img/multistepmapgrid.jpgbin0 -> 22910 bytes
-rw-r--r--docs/img/perlin.jpgbin0 -> 24105 bytes
-rw-r--r--docs/img/perlincompositor1.jpgbin0 -> 15457 bytes
-rw-r--r--docs/img/perlincompositor2.jpgbin0 -> 29005 bytes
-rw-r--r--docs/img/perlincompositor3.jpgbin0 -> 21119 bytes
-rw-r--r--docs/img/perlinheightmap.jpgbin0 -> 53543 bytes
-rw-r--r--docs/img/perlinrivers1.jpgbin0 -> 20688 bytes
-rw-r--r--docs/img/perlinrivers2.jpgbin0 -> 28926 bytes
-rw-r--r--docs/img/perlinrivers3.jpgbin0 -> 28791 bytes
-rw-r--r--docs/img/roofprobability.jpgbin0 -> 16679 bytes
-rw-r--r--docs/img/smallfoliageclumps.jpgbin0 -> 15867 bytes
-rw-r--r--docs/img/temperaturehumiditydecisionhills.jpgbin0 -> 32979 bytes
-rw-r--r--docs/img/temperaturehumiditydecisionsimple.jpgbin0 -> 18201 bytes
-rw-r--r--docs/img/terraincomposition.jpgbin0 -> 15748 bytes
-rw-r--r--docs/img/terrainheight.jpgbin0 -> 11009 bytes
-rw-r--r--docs/img/twolevelbiomes.pngbin0 -> 33816 bytes
-rw-r--r--docs/img/twolevellargeareas.jpgbin0 -> 17419 bytes
-rw-r--r--docs/img/twolevelsmallareas.jpgbin0 -> 23550 bytes
-rw-r--r--docs/img/twolevelsmallgrid.jpgbin0 -> 39141 bytes
-rw-r--r--docs/img/voronoi.pngbin0 -> 19306 bytes
-rw-r--r--docs/img/voronoijitterbiomes.pngbin0 -> 4268 bytes
-rw-r--r--lib/cmake-coverage/CodeCoverage.cmake160
-rw-r--r--lib/cmake-coverage/LICENSE23
-rw-r--r--lib/jsoncpp/src/lib_json/json_reader.cpp2
-rw-r--r--lib/lua/CMakeLists.txt6
-rw-r--r--lib/polarssl.cmake8
-rw-r--r--lib/sqlite/CMakeLists.txt4
-rw-r--r--lib/tolua++/src/bin/basic_lua.h139
-rw-r--r--lib/tolua++/src/bin/declaration_lua.h2
-rw-r--r--lib/tolua++/src/bin/lua/_driver.lua93
-rw-r--r--lib/tolua++/src/bin/lua/basic.lua2
-rw-r--r--lib/tolua++/src/bin/lua/compat-5.1.lua9
-rw-r--r--lib/tolua++/src/bin/lua/declaration.lua2
-rw-r--r--lib/tolua++/src/bin/lua/feature.lua2
-rw-r--r--src/AllocationPool.h109
-rw-r--r--src/Bindings/.gitignore1
-rw-r--r--src/Bindings/AllToLua_lua.bat.bat27
-rw-r--r--src/Bindings/LuaState.cpp147
-rw-r--r--src/Bindings/LuaState.h44
-rw-r--r--src/Bindings/ManualBindings.cpp36
-rw-r--r--src/Bindings/Plugin.h2
-rw-r--r--src/Bindings/PluginLua.cpp4
-rw-r--r--src/Bindings/PluginLua.h2
-rw-r--r--src/Bindings/PluginManager.cpp468
-rw-r--r--src/Bindings/PluginManager.h2
-rw-r--r--src/Bindings/lua51.dllbin167424 -> 0 bytes
-rw-r--r--src/Bindings/tolua++.exebin200704 -> 0 bytes
-rw-r--r--src/BiomeDef.h2
-rw-r--r--src/BlockArea.cpp142
-rw-r--r--src/BlockArea.h8
-rw-r--r--src/BlockEntities/DispenserEntity.cpp90
-rw-r--r--src/BlockEntities/DispenserEntity.h26
-rw-r--r--src/BlockID.h1
-rw-r--r--src/BlockInfo.cpp2
-rw-r--r--src/Blocks/BlockDoor.cpp2
-rw-r--r--src/Blocks/BlockDoor.h104
-rw-r--r--src/Blocks/BlockDropSpenser.h4
-rw-r--r--src/Blocks/BlockFurnace.h4
-rw-r--r--src/Blocks/BlockHandler.cpp8
-rw-r--r--src/Blocks/BlockMobHead.h2
-rw-r--r--src/Blocks/BlockPiston.cpp177
-rw-r--r--src/Blocks/BlockPiston.h134
-rw-r--r--src/Blocks/BlockPressurePlate.h38
-rw-r--r--src/ByteBuffer.cpp1
-rw-r--r--src/CMakeLists.txt195
-rw-r--r--src/Chunk.cpp220
-rw-r--r--src/Chunk.h53
-rw-r--r--src/ChunkData.cpp595
-rw-r--r--src/ChunkData.h133
-rw-r--r--src/ChunkDataCallback.h127
-rw-r--r--src/ChunkDef.h130
-rw-r--r--src/ChunkMap.cpp64
-rw-r--r--src/ChunkMap.h36
-rw-r--r--src/ChunkSender.h1
-rw-r--r--src/ClientHandle.cpp45
-rw-r--r--src/ClientHandle.h7
-rw-r--r--src/Entities/Entity.cpp48
-rw-r--r--src/Entities/Entity.h45
-rw-r--r--src/Entities/FallingBlock.cpp5
-rw-r--r--src/Entities/ItemFrame.cpp4
-rw-r--r--src/Entities/Player.cpp57
-rw-r--r--src/Entities/Player.h13
-rw-r--r--src/Entities/ProjectileEntity.cpp4
-rw-r--r--src/Generating/BioGen.cpp2
-rw-r--r--src/Generating/Caves.cpp10
-rw-r--r--src/Generating/Caves.h4
-rw-r--r--src/Generating/CompoGen.cpp14
-rw-r--r--src/Generating/ComposableGenerator.cpp45
-rw-r--r--src/Generating/GridStructGen.cpp58
-rw-r--r--src/Generating/GridStructGen.h49
-rw-r--r--src/Generating/HeiGen.cpp66
-rw-r--r--src/Generating/HeiGen.h21
-rw-r--r--src/Generating/MineShafts.cpp16
-rw-r--r--src/Generating/MineShafts.h4
-rw-r--r--src/Generating/NetherFortGen.cpp15
-rw-r--r--src/Generating/NetherFortGen.h4
-rw-r--r--src/Generating/POCPieceGenerator.cpp5
-rw-r--r--src/Generating/PieceGenerator.cpp59
-rw-r--r--src/Generating/PieceGenerator.h46
-rw-r--r--src/Generating/Prefab.cpp64
-rw-r--r--src/Generating/Prefab.h36
-rw-r--r--src/Generating/PrefabPiecePool.cpp37
-rw-r--r--src/Generating/PrefabPiecePool.h8
-rw-r--r--src/Generating/Prefabs/AlchemistVillagePrefabs.cpp3184
-rw-r--r--src/Generating/Prefabs/AlchemistVillagePrefabs.h15
-rw-r--r--src/Generating/Prefabs/JapaneseVillagePrefabs.cpp3200
-rw-r--r--src/Generating/Prefabs/JapaneseVillagePrefabs.h15
-rw-r--r--src/Generating/Prefabs/NetherFortPrefabs.cpp102
-rw-r--r--src/Generating/Prefabs/PlainsVillagePrefabs.cpp6114
-rw-r--r--src/Generating/Prefabs/PlainsVillagePrefabs.h15
-rw-r--r--src/Generating/Prefabs/RainbowRoadPrefabs.cpp1406
-rw-r--r--src/Generating/Prefabs/RainbowRoadPrefabs.h15
-rw-r--r--src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp1651
-rw-r--r--src/Generating/Prefabs/SandFlatRoofVillagePrefabs.h15
-rw-r--r--src/Generating/Prefabs/SandVillagePrefabs.cpp2133
-rw-r--r--src/Generating/Prefabs/SandVillagePrefabs.h15
-rw-r--r--src/Generating/Prefabs/UnderwaterBasePrefabs.cpp2274
-rw-r--r--src/Generating/Prefabs/UnderwaterBasePrefabs.h15
-rw-r--r--src/Generating/RainbowRoadsGen.cpp116
-rw-r--r--src/Generating/RainbowRoadsGen.h47
-rw-r--r--src/Generating/Ravines.cpp12
-rw-r--r--src/Generating/Ravines.h2
-rw-r--r--src/Generating/UnderwaterBaseGen.cpp143
-rw-r--r--src/Generating/UnderwaterBaseGen.h50
-rw-r--r--src/Generating/VillageGen.cpp444
-rw-r--r--src/Generating/VillageGen.h57
-rw-r--r--src/Globals.h70
-rw-r--r--src/GroupManager.cpp2
-rw-r--r--src/Items/ItemBoat.h2
-rw-r--r--src/Items/ItemBow.h2
-rw-r--r--src/Items/ItemFishingRod.h2
-rw-r--r--src/Items/ItemItemFrame.h2
-rw-r--r--src/Items/ItemMinecart.h2
-rw-r--r--src/Items/ItemPainting.h2
-rw-r--r--src/LightingThread.cpp103
-rw-r--r--src/LightingThread.h11
-rw-r--r--src/MobProximityCounter.cpp4
-rw-r--r--src/MobProximityCounter.h4
-rw-r--r--src/Mobs/Bat.cpp3
-rw-r--r--src/Mobs/Blaze.cpp5
-rw-r--r--src/Mobs/CaveSpider.cpp1
-rw-r--r--src/Mobs/Creeper.cpp10
-rw-r--r--src/Mobs/Ghast.cpp2
-rw-r--r--src/Mobs/Monster.cpp18
-rw-r--r--src/Mobs/Skeleton.cpp2
-rw-r--r--src/Mobs/Wither.cpp2
-rw-r--r--src/Mobs/Wither.h2
-rw-r--r--src/Noise.cpp170
-rw-r--r--src/Noise.h64
-rw-r--r--src/OSSupport/IsThread.cpp21
-rw-r--r--src/OSSupport/IsThread.h4
-rw-r--r--src/Piston.cpp297
-rw-r--r--src/Piston.h110
-rw-r--r--src/PolarSSL++/AesCfb128Decryptor.h1
-rw-r--r--src/PolarSSL++/CallbackSslContext.cpp3
-rw-r--r--src/Protocol/Protocol.h2
-rw-r--r--src/Protocol/Protocol125.cpp15
-rw-r--r--src/Protocol/Protocol125.h6
-rw-r--r--src/Protocol/Protocol132.cpp2
-rw-r--r--src/Protocol/Protocol16x.cpp4
-rw-r--r--src/Protocol/Protocol16x.h2
-rw-r--r--src/Protocol/Protocol17x.cpp18
-rw-r--r--src/Protocol/Protocol17x.h6
-rw-r--r--src/Protocol/ProtocolRecognizer.cpp4
-rw-r--r--src/Protocol/ProtocolRecognizer.h2
-rw-r--r--src/Server.cpp8
-rw-r--r--src/Simulator/FireSimulator.cpp10
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator.cpp407
-rw-r--r--src/Simulator/IncrementalRedstoneSimulator.h8
-rw-r--r--src/Simulator/SandSimulator.cpp2
-rw-r--r--src/StringUtils.h3
-rw-r--r--src/UI/SlotArea.cpp138
-rw-r--r--src/UI/SlotArea.h1
-rw-r--r--src/UI/Window.cpp1
-rw-r--r--src/Vector3.h2
-rw-r--r--src/World.cpp183
-rw-r--r--src/World.h81
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp3
-rw-r--r--src/WorldStorage/NBTChunkSerializer.h4
-rw-r--r--src/WorldStorage/WSSAnvil.cpp2
-rw-r--r--src/WorldStorage/WSSCompact.cpp10
-rw-r--r--src/WorldStorage/WSSCompact.h5
-rw-r--r--src/main.cpp4
-rw-r--r--tests/CMakeLists.txt7
-rw-r--r--tests/ChunkData/ArraytoCoord.cpp103
-rw-r--r--tests/ChunkData/CMakeLists.txt29
-rw-r--r--tests/ChunkData/Coordinates.cpp156
-rw-r--r--tests/ChunkData/Copies.cpp147
-rw-r--r--tests/ChunkData/CopyBlocks.cpp89
-rw-r--r--tests/ChunkData/creatable.cpp22
-rwxr-xr-xuploadCoverage.sh9
224 files changed, 26942 insertions, 2010 deletions
diff --git a/.gitignore b/.gitignore
index c544f394d..859ef28ea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,6 +48,7 @@ world_nether
CMakeFiles/
cmake_install.cmake
CMakeCache.txt
+CTestTestfile.cmake
Makefile
*.a
diff --git a/.travis.yml b/.travis.yml
index 0ab25ae3b..5260cfd17 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,8 +2,15 @@ language: cpp
compiler:
- gcc
- clang
+
+before_install:
+ - if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ]; then sudo pip install cpp_coveralls; fi
+
# Build MCServer
-script: cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1 && make -j 2 && cd MCServer/ && (echo stop | $MCSERVER_PATH)
+script: ./CIbuild.sh
+
+after_success:
+ - ./uploadCoverage.sh
env:
- TRAVIS_MCSERVER_BUILD_TYPE=RELEASE MCSERVER_PATH=./MCServer
@@ -11,6 +18,11 @@ env:
- TRAVIS_MCSERVER_BUILD_TYPE=RELEASE TRAVIS_MCSERVER_FORCE32=1 MCSERVER_PATH=./MCServer
- TRAVIS_MCSERVER_BUILD_TYPE=DEBUG TRAVIS_MCSERVER_FORCE32=1 MCSERVER_PATH=./MCServer_debug
+matrix:
+ include:
+ - compiler: gcc
+ env: TRAVIS_MCSERVER_BUILD_TYPE=COVERAGE MCSERVER_PATH=./MCServer
+
# Notification Settings
notifications:
email:
diff --git a/CIbuild.sh b/CIbuild.sh
new file mode 100755
index 000000000..683c1fc74
--- /dev/null
+++ b/CIbuild.sh
@@ -0,0 +1,11 @@
+ #!/usr/bin/env bash
+
+set -e
+
+cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1;
+make -j 2;
+make -j 2 test;
+cd MCServer/;
+if [ "$TRAVIS_MCSERVER_BUILD_TYPE" != "COVERAGE" ]
+ then echo stop | $MCSERVER_PATH;
+fi
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9a860920c..56dea1a34 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 2.6)
+cmake_minimum_required (VERSION 2.8.2)
# Without this, the MSVC variable isn't defined for MSVC builds ( http://www.cmake.org/pipermail/cmake/2011-November/047130.html )
enable_language(CXX C)
@@ -14,6 +14,10 @@ if(DEFINED ENV{TRAVIS_MCSERVER_FORCE32})
set(FORCE32 $ENV{TRAVIS_MCSERVER_FORCE32})
endif()
+if(DEFINED ENV{TRAVIS_BUILD_WITH_COVERAGE})
+ set(BUILD_WITH_COVERAGE $ENV{TRAVIS_BUILD_WITH_COVERAGE})
+endif()
+
# This has to be done before any flags have been set up.
if(${BUILD_TOOLS})
add_subdirectory(Tools/MCADefrag/)
@@ -69,3 +73,8 @@ set_exe_flags()
add_subdirectory (src)
+if(${SELF_TEST})
+ enable_testing()
+ add_subdirectory (tests)
+endif()
+
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 8b10525da..b7f94a717 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -27,5 +27,4 @@ UltraCoderRU
worktycho
xoft
-
Please add yourself to this list if you contribute to MCServer.
diff --git a/GETTING-STARTED.md b/GETTING-STARTED.md
index 1ac6fe989..d78b2f84f 100644
--- a/GETTING-STARTED.md
+++ b/GETTING-STARTED.md
@@ -3,14 +3,14 @@ Hello! Thanks for wanting to work on this project :smile:, and I hope that this
Minecraft Basics
----------------
-If you don't play Minecraft or don't have a great knowledge of the basic systems, you should get to know them. The [Minecraft Wiki](http://minecraft.gamepedia.com/Minecraft_Wiki) is quite useful for this task, although some youtubers are also fairly good at teaching the basics and just playing is quite good too.
+If you don't play Minecraft or don't have a great knowledge of the basic systems, you should get to know them. The [Minecraft Wiki](http://minecraft.gamepedia.com/Minecraft_Wiki) is quite useful for this task, although some youtubers are also fairly good at teaching the basics and just playing is quite good too. It is possible to contribute without knowing minecraft in detail though.
I'd say that the important topics are:
* Differnt types of blocks and how they act.
* Mobs, what they do and how.
* Redstone, pistons, and automation.
-* Farming
+* Farming.
* Fighting, health and the hunger system.
Useful Resources
@@ -39,7 +39,7 @@ You'll also need CMake to generate the makefile to build from.
**Windows:**
-If you use Windows, your best bet is the MSVC2008 (available as a free download in the Express edition from MS) or MSVS2013 (ditto), solution files for both are currently in the repo.
+If you use Windows, your best bet is the MSVC2008 (available as a free download in the Express edition from MS) or MSVS2013 (ditto), solution files for which can be generated with cmake. You'll also need cmake to generate the project files.
Setting up the Repo
-------------------
@@ -85,7 +85,7 @@ Basically, the process is:
**Windows:**
-You need to first execute the `src/Bindings/AllToLua.bat` script file, then just open the solution file in your MSVC of choice and build.
+You need to first generate a project file with `cmake . -DCMAKE_BUILD_TYPE=DEBUG` then execute the `src/Bindings/AllToLua.bat` script file, then just open the solution file in your MSVC of choice and build.
How to Run
----------
@@ -99,18 +99,18 @@ There are a few fairly easy issues for you to get started with, as well as some
**Easy**:
- * #288
- * #385
- * #402
- * #380
- * #503
- * #491
+ * #140
+ * #493
+ * #577
+ * #381
+ * #752
* Clean up some of the compiler warnings. (Check [Travis CI](http://travis-ci.org/mc-server/MCServer) for a list of them.) With clang, there are over 10000 lines of warnings to clean up.
**More Difficult**:
- * #17
- * #398
+ * #133
+ * #134
+ * #215
You may also want to write some plugins. They are written in lua, with excellent API documentation available via [APIDump](http://mc-server.xoft.cz/LuaAPI). The [Core](https://github.com/mc-server/Core) plugin should also help quite a bit here.
diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua
index 1423d64bc..19ca971e2 100644
--- a/MCServer/Plugins/APIDump/APIDesc.lua
+++ b/MCServer/Plugins/APIDump/APIDesc.lua
@@ -114,6 +114,7 @@ g_APIDesc =
GetBlockSkyLight = { Params = "BlockX, BlockY, BlockZ", Return = "NIBBLETYPE", Notes = "Returns the skylight at the specified absolute coords" },
GetBlockType = { Params = "BlockX, BlockY, BlockZ", Return = "BLOCKTYPE", Notes = "Returns the block type at the specified absolute coords" },
GetBlockTypeMeta = { Params = "BlockX, BlockY, BlockZ", Return = "BLOCKTYPE, NIBBLETYPE", Notes = "Returns the block type and meta at the specified absolute coords" },
+ GetCoordRange = {Params = "", Return = "MaxX, MaxY, MaxZ", Notes = "Returns the maximum relative coords in all 3 axes. See also GetSize()." },
GetDataTypes = { Params = "", Return = "number", Notes = "Returns the mask of datatypes that the object is currently holding" },
GetOrigin = { Params = "", Return = "OriginX, OriginY, OriginZ", Notes = "Returns the origin coords of where the area was read from." },
GetOriginX = { Params = "", Return = "number", Notes = "Returns the origin x-coord" },
@@ -124,7 +125,7 @@ g_APIDesc =
GetRelBlockSkyLight = { Params = "RelBlockX, RelBlockY, RelBlockZ", Return = "NIBBLETYPE", Notes = "Returns the skylight at the specified relative coords" },
GetRelBlockType = { Params = "RelBlockX, RelBlockY, RelBlockZ", Return = "BLOCKTYPE", Notes = "Returns the block type at the specified relative coords" },
GetRelBlockTypeMeta = { Params = "RelBlockX, RelBlockY, RelBlockZ", Return = "BLOCKTYPE, NIBBLETYPE", Notes = "Returns the block type and meta at the specified relative coords" },
- GetSize = { Params = "", Return = "SizeX, SizeY, SizeZ", Notes = "Returns the size of the area in all 3 axes." },
+ GetSize = { Params = "", Return = "SizeX, SizeY, SizeZ", Notes = "Returns the size of the area in all 3 axes. See also GetCoordRange()." },
GetSizeX = { Params = "", Return = "number", Notes = "Returns the size of the held data in the x-axis" },
GetSizeY = { Params = "", Return = "number", Notes = "Returns the size of the held data in the y-axis" },
GetSizeZ = { Params = "", Return = "number", Notes = "Returns the size of the held data in the z-axis" },
@@ -1969,7 +1970,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
BroadcastChatSuccess = { Params = "Message", Return = "", Notes = "Prepends Green [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For success messages." },
BroadcastChatWarning = { Params = "Message", Return = "", Notes = "Prepends Rose [WARN] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For concerning events, such as plugin reload etc." },
CreateAndInitializeWorld = { Params = "WorldName", Return = "{{cWorld|cWorld}}", Notes = "Creates a new world and initializes it. If there is a world whith the same name it returns nil." },
- FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "", Notes = "Calls the given callback function for the given player." },
+ FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "", Notes = "Calls the given callback function for all players with names partially (or fully) matching the name string provided." },
ForEachPlayer = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each player. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cPlayer|cPlayer}})</pre>" },
ForEachWorld = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each world. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cWorld|cWorld}})</pre>" },
GetCraftingRecipes = { Params = "", Return = "{{cCraftingRecipe|cCraftingRecipe}}", Notes = "Returns the CraftingRecipes object" },
@@ -2294,10 +2295,14 @@ end
IsGameModeCreative = { Params = "", Return = "bool", Notes = "Returns true if the current gamemode is gmCreative." },
IsGameModeSurvival = { Params = "", Return = "bool", Notes = "Returns true if the current gamemode is gmSurvival." },
IsPVPEnabled = { Params = "", Return = "bool", Notes = "Returns whether PVP is enabled in the world settings." },
- IsWeatherRain = { Params = "", Return = "bool", Notes = "Returns true if the current weather is rain." },
- IsWeatherStorm = { Params = "", Return = "bool", Notes = "Returns true if the current weather is a storm." },
+ IsWeatherRain = { Params = "", Return = "bool", Notes = "Returns true if the current world is raining." },
+ IsWeatherRainAt = { Params = "BlockX, BlockZ", Return = "bool", Notes = "Returns true if the specified location is raining (takes into account biomes)." },
+ IsWeatherStorm = { Params = "", Return = "bool", Notes = "Returns true if the current world is stormy." },
+ IsWeatherStormAt = { Params = "BlockX, BlockZ", Return = "bool", Notes = "Returns true if the specified location is stormy (takes into account biomes)." },
IsWeatherSunny = { Params = "", Return = "bool", Notes = "Returns true if the current weather is sunny." },
- IsWeatherWet = { Params = "", Return = "bool", Notes = "Returns true if the current weather has any precipitation (rain or storm)." },
+ IsWeatherSunnyAt = { Params = "BlockX, BlockZ", Return = "bool", Notes = "Returns true if the current weather is sunny at the specified location (takes into account biomes)." },
+ IsWeatherWet = { Params = "", Return = "bool", Notes = "Returns true if the current world has any precipitation (rain or storm)." },
+ IsWeatherWetAt = { Params = "BlockX, BlockZ", Return = "bool", Notes = "Returns true if the specified location has any precipitation (rain or storm) (takes into account biomes)." },
QueueBlockForTick = { Params = "BlockX, BlockY, BlockZ, TicksToWait", Return = "", Notes = "Queues the specified block to be ticked after the specified number of gameticks." },
QueueSaveAllChunks = { Params = "", Return = "", Notes = "Queues all chunks to be saved in the world storage thread" },
QueueSetBlock = { Params = "BlockX, BlockY, BlockZ, BlockType, BlockMeta, TickDelay", Return = "", Notes = "Queues the block to be set to the specified blocktype and meta after the specified amount of game ticks. Uses SetBlock() for the actual setting, so simulators are woken up and block entities are handled correctly." },
@@ -2929,6 +2934,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 = "InfoFile.html", Title = "Using the Info.lua file" },
{ FileName = "SettingUpDecoda.html", Title = "Setting up the Decoda Lua IDE" },
{ FileName = "SettingUpZeroBrane.html", Title = "Setting up the ZeroBrane Studio Lua IDE" },
{ FileName = "UsingChunkStays.html", Title = "Using ChunkStays" },
diff --git a/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua
index 1588d420c..72cf85821 100644
--- a/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua
+++ b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua
@@ -10,6 +10,11 @@ return
Params =
{
{ Name = "ProjectileEntity", Type = "{{cProjectileEntity}}", Notes = "The projectile that hit an entity." },
+ { Name = "BlockX", Type = "number", Notes = "The X-coord where the projectile hit." },
+ { Name = "BlockY", Type = "number", Notes = "The Y-coord where the projectile hit." },
+ { Name = "BlockZ", Type = "number", Notes = "The Z-coord where the projectile hit." },
+ { Name = "BlockFace", Type = "number", Notes = "The side of the block where the projectile hit." },
+ { Name = "BlockHitPos", Type = "Vector3d", Notes = "The exact position where the projectile hit." },
},
Returns = [[
If the function returns false or no value, the next plugin's callback is called. If the function
diff --git a/MCServer/Plugins/APIDump/InfoFile.html b/MCServer/Plugins/APIDump/InfoFile.html
new file mode 100644
index 000000000..3fff06d20
--- /dev/null
+++ b/MCServer/Plugins/APIDump/InfoFile.html
@@ -0,0 +1,246 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>MCServer - Info.lua file</title>
+ <link rel="stylesheet" type="text/css" href="main.css" />
+ <link rel="stylesheet" type="text/css" href="prettify.css" />
+ <script src="prettify.js"></script>
+ <script src="lang-lua.js"></script>
+ <meta charset="UTF-8">
+ </head>
+ <body>
+ <div id="content">
+ <h1>Info.lua file</h1>
+ <h2>Contents</h2>
+ <ul>
+ <li><a href="#Introduction">Introduction</a></li>
+ <li><a href="#Overall">The overall structure</a></li>
+ <li><a href="#AdditionalInformation">AdditionalInformation table</a></li>
+ <li><a href="#Commands">Commands table</a></li>
+ <li><a href="#ConsoleCommands">ConsoleCommands table</a></li>
+ <li><a href="#Permissions">Permissions table</a></li>
+ <li><a href="#Using">Using the file in code</a></li>
+ <li><a href="#Examples">Examples</a></li>
+ </ul>
+
+
+ <hr />
+ <a name="Introduction"><h2>Introduction</h2></a>
+
+ <p>For a long time MCServer plugins were plagued by poor documentation. The plugins worked, people who wrote them knew how to use them, but for anyone new to the plugin it was a terrible ordeal learning how to use it. Most of the times, the plugin authors only wrote what commands the plugin supported, sometimes not even that. Then, there was a call to action to put an end to this, to make documenting the plugins easy and at the same time centralized. Thus, the Info.lua file was born.</p>
+
+ <p>Most plugins have some parts that are the same across all the plugins. These are commands, console commands and their permissions. If a plugin implemented a command, it would practically copy &amp; paste the same code over and over again. So it makes sense to extract only unique information, centralize it and automate all the parts around it. This was another reason for the Info.lua file - it is a central hub of commands, console commands and their permissions.</p>
+
+ <p>Last, but not least, we want to make a plugin repository on the web in the future, a repository that would store plugins, their descriptions, comments. It makes sense that the centralized information can be parsed by the repository automatically, so that advanced things, such as searching for a plugin based on a command, or determining whether two plugins collide command-wise, are possible.</p>
+
+ <p>After this file format has been devised, a tool has been written that allows for an easy generation of the documentation for the plugin in various formats. It outputs the documentation in a format that is perfect for pasting into the forum. It generates documentation in a Markup format to use in README.md on GitHub and similar sites. The clever thing is that you don't need to keep all those formats in sync manually - you edit the Info.lua file and this tool will re-generate the documentation for you.</p>
+
+ <p>So to sum up, the Info.lua file contains the plugins' commands, console commands, their permissions and possibly the overall plugin documentation, in a structured manner that can be parsed by a program, yet is human readable and editable.</p>
+
+
+ <hr />
+ <a name="Overall"><h2>The overall structure</h2></a>
+
+ <p>The file consist of a declaration of a single Lua table, g_PluginInfo. This table contains all the information, structured, as its members. Each member can be a structure by itself. The entire file is a valid Lua source file, so any tool that syntax-checks Lua source can syntax-check this file. The file is somewhat forward- and backward- compatible, in the sense that it can be extended in any way without breaking.</p>
+ <p>Here's a skeleton of the file:</p>
+<pre class="prettyprint lang-lua">
+g_PluginInfo =
+{
+ Name = "Example Plugin",
+ Date = "2014-06-12",
+ Description = "This is an example plugin that shows how to use the Info.lua file",
+
+ -- The following members will be documented in greater detail later:
+ AdditionalInformation = {},
+ Commands = {},
+ ConsoleCommands = {},
+ Permissions = {},
+}
+</pre>
+ <p>As you can see, the structure is pretty straightforward. Note that the order of the elements inside the table is not important (Lua property).</p>
+
+ <p>The first few elements are for book-keeping. They declare the plugin's name, the date in ISO-format, representing the version of the plugin, and the description. The idea is that the description sums up what the plugin is all about, within some two or three sentences.</p>
+
+
+ <hr />
+ <a name="AdditionalInformation"><h2>AdditionalInformation table</h2></a>
+
+ <p>This table is used for more detailed description of the plugin. If there is any non-trivial setup process, dependencies, describe them here. This is where the description should get detailed. Don't worry about using several paragraphs of text here, if it makes the plugin easier to understand.</p>
+
+ <p>The table should have the following layout:</p>
+<pre class="prettyprint lang-lua">
+AdditionalInformation =
+{
+ {
+ Title = "Chapter 1",
+ Contents = "Describe one big aspect of the plugin here",
+ },
+ {
+ Title = "Chapter 2",
+ Contents = "Describe another big topic",
+ },
+}
+</pre>
+ <p>The idea here is that the tool that is used to generate the documentation from the Info.lua file will create a linkified table of contents and then each of the information elements' contents. This information should be all that is needed to successfully configure, run and manage the plugin.</p>
+
+
+ <hr />
+ <a name="Commands"><h2>Commands table</h2></a>
+
+ <p>The commands table lists all the commands that the plugin implements, together with their handler functions, required permissions, help strings and further information. The table supports recursion, which allows plugins to create multi-word commands easily (such as "//schematic load" and "//schematic save"), each having its own separate handler.</p>
+
+ <p>The table uses structure similar to the following:</p>
+<pre class="prettyprint lang-lua">
+Commands =
+{
+ ["/cmd1"] =
+ {
+ HelpString = "Performs the first action",
+ Permission = "firstplugin.cmds.1",
+ Alias = "/c1",
+ Handler = HandleCmd1,
+ ParameterCombinations =
+ {
+ {
+ Params = "x y z",
+ Help = "Performs the first action at the specified coordinates",
+ },
+ {
+ Params = "-p",
+ Help = "Performs the first action at the player's coordinates",
+ }
+ },
+ },
+ ["/cmd2"] =
+ {
+ Alias = {"/c2", "//c2" },
+ Subcommands =
+ {
+ sub1 = -- This declares a "/cmd2 sub1" command
+ {
+ HelpString = "Performs the second action's first subcommand",
+ Permission = "firstplugin.cmds.2.1",
+ Alias = "1",
+ Handler = HandleCmd2Sub1,
+ ParameterCombinations =
+ {
+ {
+ Params = "x y z",
+ Help = "Performs the second action's first subcommand at the specified coordinates",
+ },
+ {
+ Params = "-p",
+ Help = "Performs the second action's first subcommand at the player's coordinates",
+ }
+ },
+ },
+ sub2 = -- Declares a "/cmd2 sub2" command
+ {
+ HelpString = "Performs the second action's second subcommand",
+ Permission = "firstplugin.cmds.2.2",
+ Handler = HandleCmd2Sub2,
+ },
+ },
+ },
+}
+</pre>
+
+ <p>Although it may seem overwhelming at first, there is a "method to this madness". Each element of the Commands table defines one command. Most commands start with a slash, so the special Lua syntax for table elements with non-standard names needs to be applied (<code>["/cmd1"] =</code>). The command can either specify subcommands, or a handler function (specifying both is UndefinedBehavior). Subcommands uses the same structure as the entire Commands table, recursively.</p>
+
+ <p>The permission element specifies that the command is only available with the specified permission. Note that the permission for subcommand's parent isn't checked when the subcommand is called. This means that specifying the permission for a command that has subcommands has no effect whatsoever, but is discouraged because we may add processing for that in the future.</p>
+
+ <p>The ParameterCombinations table is used only for generating the documentation, it lists the various combinations of parameters that the command supports. It's worth specifying even if the command supports only one combination, because that combination will get documented this way.</p>
+
+ <p>The Alias member specifies any possible aliases for the command. Each alias is registered separately and if there is a subcommand table, it is applied to all aliases, just as one would expect. You can specify either a single string as the value (if there's only one alias), or a table of strings for multiple aliases. Commands with no aliases do not need to specify this member at all.</p>
+
+
+ <hr />
+ <a name="ConsoleCommands"><h2>ConsoleCommands table</h2>
+
+ <p>This table serves a purpose similar to that of the Commands table, only these commands are provided for the server console. Therefore, there are no permissions specified for these commands. Since most console commands don't use a leading slash, the command names don't need the special syntax. Also, the handler function doesn't receive the Player parameter.</p>
+
+ <p>Here's an example of a ConsoleCommands table:</p>
+<pre class="prettyprint lang-lua">
+ConsoleCommands =
+{
+ concmd =
+ {
+ HelpString = "Performs the console action",
+ Subcommands =
+ {
+ sub1 =
+ {
+ HelpString = "Performs the console action's first subcommand",
+ Handler = HandleConCmdSub1,
+ ParameterCombinations =
+ {
+ {
+ Params = "x y z",
+ Help = "Performs the console action's first subcommand at the specified coordinates",
+ },
+ },
+ },
+ sub2 =
+ {
+ HelpString = "Performs the console action's second subcommand",
+ Handler = HandleConCmdSub2,
+ },
+ },
+ },
+}
+</pre>
+
+
+ <hr />
+ <a name="Permissions"><h2>Permissions table</h2></a>
+
+ <p>The purpose of this table is to document permissions that the plugin uses. The documentation generator automatically collects the permissions specified in the Command table; the Permissions table adds a description for these permissions and may declare other permissions that aren't specifically included in the Command table.</p>
+
+<pre class="prettyprint lang-lua">
+Permissions =
+{
+ ["firstplugin.cmd.1.1"] =
+ {
+ Description = "Allows the players to build high towers using the first action.",
+ RecommendedGroups = "players",
+ },
+ ["firstplugin.cmd.2.1"] =
+ {
+ Description = "Allows the players to kill entities using the second action. Note that this may be misused to kill other players, too.",
+ RecommendedGroups = "admins, mods",
+ },
+}
+</pre>
+
+ <p>The RecommendedGroup element lists, in plain English, the intended groups for which the permission should be enabled on a typical server. Plugin authors are advised to create reasonable defaults, prefering security to openness, so that admins using these settings blindly don't expose their servers to malicious users.</p>
+
+
+ <hr />
+ <a name="Using"><h2>Using the file in code</h2></a>
+
+ <p>Just writing the Info.lua file and saving it to the plugin folder is not enough for it to actually be used. Your plugin needs to include the following boilerplate code, preferably in its Initialize() function:</p>
+<pre class="prettyprint lang-lua">
+-- Use the InfoReg shared library to process the Info.lua file:
+dofile(cPluginManager:GetPluginsPath() .. "/InfoReg.lua")
+RegisterPluginInfoCommands()
+RegisterPluginInfoConsoleCommands()
+</pre>
+
+ <p>Of course, if your plugin doesn't have any console commands, it doesn't need to call the RegisterPluginInfoConsoleCommands() function, and similarly if it doesn't have any in-game commands, it doesn't need to call the RegisterPluginInfoCommands() function.</p>
+
+
+ <hr />
+ <a name="Examples"><h2>Examples</h2></a>
+
+ <p>There are several plugins that already implement this approach. You can visit them for inspiration and to see what the generated documentation looks like:</p>
+ <ul>
+ <li>Gallery plugin: <a href="https://github.com/mc-server/Gallery/blob/master/Info.lua">Info.lua</a>, <a href="http://forum.mc-server.org/showthread.php?tid=1306">Forum</a> documentation</li>
+ <li>WorldEdit plugin: <a href="https://github.com/mc-server/WorldEdit/blob/master/Info.lua">Info.lua</a>, <a href="http://forum.mc-server.org/showthread.php?tid=870">Forum</a> and <a href="https://github.com/mc-server/WorldEdit">MarkDown</a> documentation</li>
+ </ul>
+
+ <script>
+ prettyPrint();
+ </script>
+ </div>
+ </body>
+</html>
diff --git a/MCServer/Plugins/ChunkWorx/chunkworx_web.lua b/MCServer/Plugins/ChunkWorx/chunkworx_web.lua
index 6c5eab676..9aec38b12 100644
--- a/MCServer/Plugins/ChunkWorx/chunkworx_web.lua
+++ b/MCServer/Plugins/ChunkWorx/chunkworx_web.lua
@@ -43,7 +43,7 @@ function HandleRequest_Generation( Request )
local Content = ""
if (Request.PostParams["AGHRRRR"] ~= nil) then
GENERATION_STATE = 0
- WW_instance:SaveAllChunks()
+ WW_instance:QueueSaveAllChunks()
WW_instance:QueueUnloadUnusedChunks()
LOGERROR("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": works ABORTED by admin")
end
diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua
index 064d5d772..534426d25 100644
--- a/MCServer/Plugins/Debuggers/Debuggers.lua
+++ b/MCServer/Plugins/Debuggers/Debuggers.lua
@@ -29,7 +29,8 @@ function Initialize(Plugin)
PM:AddHook(cPluginManager.HOOK_WORLD_TICK, OnWorldTick);
PM:AddHook(cPluginManager.HOOK_PLUGINS_LOADED, OnPluginsLoaded);
PM:AddHook(cPluginManager.HOOK_PLUGIN_MESSAGE, OnPluginMessage);
- PM:AddHook(cPluginManager.HOOK_PLAYER_JOINED, OnPlayerJoined)
+ PM:AddHook(cPluginManager.HOOK_PLAYER_JOINED, OnPlayerJoined);
+ PM:AddHook(cPluginManager.HOOK_PROJECTILE_HIT_BLOCK, OnProjectileHitBlock);
-- _X: Disabled so that the normal operation doesn't interfere with anything
-- PM:AddHook(cPluginManager.HOOK_CHUNK_GENERATED, OnChunkGenerated);
@@ -1379,3 +1380,14 @@ end
+
+function OnProjectileHitBlock(a_Projectile, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_BlockHitPos)
+ local BlockX, BlockY, BlockZ = AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)
+ local World = a_Projectile:GetWorld()
+
+ World:SetBlock(BlockX, BlockY, BlockZ, E_BLOCK_FIRE, 0)
+end
+
+
+
+
diff --git a/MCServer/Plugins/Handy/handy_functions.lua b/MCServer/Plugins/Handy/handy_functions.lua
index c142ffd08..af43f663a 100644
--- a/MCServer/Plugins/Handy/handy_functions.lua
+++ b/MCServer/Plugins/Handy/handy_functions.lua
@@ -6,7 +6,7 @@ function GetHandyVersion()
return HANDY_VERSION
end
-- Checks if handy is in proper version
-function CheckForRequiedVersion( inVersion )
+function CheckForRequiredVersion( inVersion )
if( inVersion > HANDY_VERSION ) then return false end
return true
end
@@ -213,4 +213,4 @@ end
function BoolToString( inValue )
if( inValue == true ) then return 1 end
return 0
-end \ No newline at end of file
+end
diff --git a/MCServer/furnace.txt b/MCServer/furnace.txt
index 31d265ce7..1e98583ba 100644
--- a/MCServer/furnace.txt
+++ b/MCServer/furnace.txt
@@ -61,18 +61,30 @@
#--------------------------
# Fuels
-! 263:1 = 1600 # 1 Coal -> 80 sec
-! 263:1:1 = 1600 # 1 Charcoal -> 80 sec
-! 42:126:1 = 150 # 1 Halfslab -> 7.5 seconds
-! 5:1 = 300 # 1 Planks -> 15 sec
-! 280:1 = 100 # 1 Stick -> 5 sec
-! 85:1 = 300 # 1 Fence -> 15 sec
-! 53:1 = 300 # 1 Wooden Stairs -> 15 sec
-! 58:1 = 300 # 1 Crafting Table -> 15 sec
-! 47:1 = 300 # 1 Bookshelf -> 15 sec
-! 54:1 = 300 # 1 Chest -> 15 sec
-! 84:1 = 300 # 1 Jukebox -> 15 sec
-! 327:1 = 200000 # 1 Lava Bucket -> 1000 sec
-! 17:1 = 300 # 1 Wood -> 15 sec
-! 6:1 = 100 # 1 Sapling -> 5 sec
-! 173:1 = 7400 # 1 Coal Block -> 370 sec, based on https://github.com/minetest/common/commit/e0f5a6fd6936052756e27a05a2bfdd6aa86b38e1 which is a clone of MC \ No newline at end of file
+! 263:1 = 1600 # 1 Coal -> 80 sec
+! 263:1:1 = 1600 # 1 Charcoal -> 80 sec
+! 126:1 = 15 # 1 Halfslab -> 7.5 sec
+! 5:1 = 300 # 1 Planks -> 15 sec
+! 280:1 = 100 # 1 Stick -> 5 sec
+! 85:1 = 300 # 1 Fence -> 15 sec
+! 53:1 = 300 # 1 Wooden Stairs -> 15 sec
+! 58:1 = 300 # 1 Crafting Table -> 15 sec
+! 47:1 = 300 # 1 Bookshelf -> 15 sec
+! 54:1 = 300 # 1 Chest -> 15 sec
+! 84:1 = 300 # 1 Jukebox -> 15 sec
+! 327:1 = 20000 # 1 Lava Bucket -> 1000 sec
+! 17:1 = 300 # 1 Wood -> 15 sec
+! 6:1 = 100 # 1 Sapling -> 5 sec
+! 173:1 = 16000 # 1 Coal Block -> 800 sec
+! 369:1 = 2400 # 1 Blaze Rod -> 120 sec
+! 25:1 = 300 # 1 Note Block -> 15 sec
+! 151:1 = 300 # 1 Daylight Sensor -> 15 sec
+! 107:1 = 300 # 1 Fence Gate -> 15 sec
+! 167:1 = 300 # 1 Trapdoor -> 15 sec
+! 146:1 = 300 # 1 Trapped Chest -> 15 sec
+! 72:1 = 300 # 1 Pressure Plate -> 15 sec
+! 270:1 = 200 # 1 Wooden Pickaxe -> 10 sec
+! 271:1 = 200 # 1 Wooden Axe -> 10 sec
+! 269:1 = 200 # 1 Wooden Shovel -> 10 sec
+! 290:1 = 200 # 1 Wooden Hoe -> 10 sec
+! 268:1 = 200 # 1 Wooden Sword -> 10 sec
diff --git a/README.md b/README.md
index e6d9492f0..b0f1cde35 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-MCServer [![Build Status](http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer) [![Support via Gittip](http://img.shields.io/gittip/mcs_team.svg)](https://www.gittip.com/mcs_team) [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74)
+MCServer [![Build Status](http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer) [![Coverity Scan Build Status](https://scan.coverity.com/projects/1930/badge.svg)](https://scan.coverity.com/projects/1930) [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74)
========
MCServer is a Minecraft server that is written in C++ and designed to be efficient with memory and CPU, as well as having a flexible Lua Plugin API.
diff --git a/SetFlags.cmake b/SetFlags.cmake
index fe867f9af..6e2417a51 100644
--- a/SetFlags.cmake
+++ b/SetFlags.cmake
@@ -1,32 +1,41 @@
macro (add_flags_lnk FLAGS)
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}")
- set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FLAGS}")
- set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${FLAGS}")
- set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLAGS}")
- set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${FLAGS}")
- set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${FLAGS}")
- set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLAGS}")
- set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} ${FLAGS}")
- set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} ${FLAGS}")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}")
+ set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FLAGS}")
+ set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_COVERAGE} ${FLAGS}")
+ set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${FLAGS}")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLAGS}")
+ set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${FLAGS}")
+ set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_COVERAGE} ${FLAGS}")
+ set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${FLAGS}")
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLAGS}")
+ set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} ${FLAGS}")
+ set(CMAKE_MODULE_LINKER_FLAGS_COVERAGE "${CMAKE_MODULE_LINKER_FLAGS_COVERAGE} ${FLAGS}")
+ set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} ${FLAGS}")
endmacro()
macro(add_flags_cxx FLAGS)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAGS}")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAGS}")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${FLAGS}")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${FLAGS}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}")
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAGS}")
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAGS}")
+ set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} ${FLAGS}")
+ set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_COVERAGE} ${FLAGS}")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${FLAGS}")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${FLAGS}")
endmacro()
macro(set_flags)
# Add the preprocessor macros used for distinguishing between debug and release builds (CMake does this automatically for MSVC):
if (NOT MSVC)
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNDEBUG")
+ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/lib/cmake-coverage/")
+ include(CodeCoverage)
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
+ set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -D_DEBUG")
+ set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_COVERAGE} -D_DEBUG")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNDEBUG")
endif()
if(MSVC)
@@ -42,9 +51,10 @@ macro(set_flags)
elseif(APPLE)
#on os x clang adds pthread for us but we need to add it for gcc
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
+ set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++11")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
add_flags_cxx("-stdlib=libc++")
add_flags_lnk("-stdlib=libc++")
else()
@@ -57,6 +67,7 @@ macro(set_flags)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
+ set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++11")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
endif()
@@ -97,10 +108,12 @@ macro(set_lib_flags)
string(REPLACE "/W3" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
string(REPLACE "/W3" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
else()
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -w")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -w")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -w")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -w")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -w")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -w")
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -w")
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -w")
+ set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -w")
+ set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_COVERAGE} -w")
endif()
# On Unix we use two dynamic loading libraries dl and ltdl.
@@ -128,7 +141,7 @@ macro(enable_profile)
# Declare the profiling configurations:
SET(CMAKE_CXX_FLAGS_DEBUGPROFILE
- "${CMAKE_CXX_FLAGS_DEBUG} ${PCXX_ROFILING}"
+ "${CMAKE_CXX_FLAGS_DEBUG} ${CXX_PROFILING}"
CACHE STRING "Flags used by the C++ compiler during profile builds."
FORCE )
SET(CMAKE_C_FLAGS_DEBUGPROFILE
@@ -171,7 +184,11 @@ macro(enable_profile)
CMAKE_EXE_LINKER_FLAGS_RELEASEPROFILE
CMAKE_SHARED_LINKER_FLAGS_RELEASEPROFILE )
# The configuration types need to be set after their respective c/cxx/linker flags and before the project directive
- set(CMAKE_CONFIGURATION_TYPES "Debug;Release;DebugProfile;ReleaseProfile" CACHE STRING "" FORCE)
+ if(MSVC)
+ set(CMAKE_CONFIGURATION_TYPES "Debug;Release;DebugProfile;ReleaseProfile" CACHE STRING "" FORCE)
+ else()
+ set(CMAKE_CONFIGURATION_TYPES "Debug;Release;DebugProfile;ReleaseProfile;Coverage" CACHE STRING "" FORCE)
+ endif()
endmacro()
macro(set_exe_flags)
@@ -180,10 +197,12 @@ macro(set_exe_flags)
# We do not do that for MSVC since MSVC produces an awful lot of warnings for its own STL headers;
# the important warnings are turned on using #pragma in Globals.h
if (NOT MSVC)
- string(REPLACE "-w" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
- string(REPLACE "-w" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
- string(REPLACE "-w" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
- string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
+ string(REPLACE "-w" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
+ string(REPLACE "-w" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
+ string(REPLACE "-w" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
+ string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
+ string(REPLACE "-w" "" CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE}")
+ string(REPLACE "-w" "" CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_COVERAGE}")
add_flags_cxx("-Wall -Wextra -Wno-unused-parameter -Wno-error=switch")
# we support non-IEEE 754 fpus so can make no guarentees about error
diff --git a/Tools/AnvilStats/AnvilStats.sln b/Tools/AnvilStats/AnvilStats.sln
index 6e2481d84..46bed8969 100644
--- a/Tools/AnvilStats/AnvilStats.sln
+++ b/Tools/AnvilStats/AnvilStats.sln
@@ -1,32 +1,53 @@
-
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual C++ Express 2008
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AnvilStats", "AnvilStats.vcproj", "{CF996A5E-0A86-4004-9710-682B06B5AEBA}"
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2013 for Windows Desktop
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AnvilStats", "AnvilStats.vcxproj", "{CF996A5E-0A86-4004-9710-682B06B5AEBA}"
ProjectSection(ProjectDependencies) = postProject
- {EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA} = {EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}
+ {B61007AC-B557-4B67-A765-E468C0C3A821} = {B61007AC-B557-4B67-A765-E468C0C3A821}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\VC2008\zlib.vcproj", "{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\lib\zlib\zlib.vcxproj", "{B61007AC-B557-4B67-A765-E468C0C3A821}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
+ DebugProfile|Win32 = DebugProfile|Win32
+ MinSizeRel|Win32 = MinSizeRel|Win32
Release profiled|Win32 = Release profiled|Win32
Release|Win32 = Release|Win32
+ ReleaseProfile|Win32 = ReleaseProfile|Win32
+ RelWithDebInfo|Win32 = RelWithDebInfo|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Debug|Win32.ActiveCfg = Debug|Win32
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Debug|Win32.Build.0 = Debug|Win32
+ {CF996A5E-0A86-4004-9710-682B06B5AEBA}.DebugProfile|Win32.ActiveCfg = Debug|Win32
+ {CF996A5E-0A86-4004-9710-682B06B5AEBA}.DebugProfile|Win32.Build.0 = Debug|Win32
+ {CF996A5E-0A86-4004-9710-682B06B5AEBA}.MinSizeRel|Win32.ActiveCfg = Release|Win32
+ {CF996A5E-0A86-4004-9710-682B06B5AEBA}.MinSizeRel|Win32.Build.0 = Release|Win32
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release profiled|Win32.ActiveCfg = Release profiled|Win32
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release profiled|Win32.Build.0 = Release profiled|Win32
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release|Win32.ActiveCfg = Release|Win32
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release|Win32.Build.0 = Release|Win32
- {EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Debug|Win32.ActiveCfg = Debug|Win32
- {EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Debug|Win32.Build.0 = Debug|Win32
- {EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release profiled|Win32.ActiveCfg = Release profiled|Win32
- {EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release profiled|Win32.Build.0 = Release profiled|Win32
- {EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release|Win32.ActiveCfg = Release|Win32
- {EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release|Win32.Build.0 = Release|Win32
+ {CF996A5E-0A86-4004-9710-682B06B5AEBA}.ReleaseProfile|Win32.ActiveCfg = Release|Win32
+ {CF996A5E-0A86-4004-9710-682B06B5AEBA}.ReleaseProfile|Win32.Build.0 = Release|Win32
+ {CF996A5E-0A86-4004-9710-682B06B5AEBA}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
+ {CF996A5E-0A86-4004-9710-682B06B5AEBA}.RelWithDebInfo|Win32.Build.0 = Release|Win32
+ {B61007AC-B557-4B67-A765-E468C0C3A821}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B61007AC-B557-4B67-A765-E468C0C3A821}.Debug|Win32.Build.0 = Debug|Win32
+ {B61007AC-B557-4B67-A765-E468C0C3A821}.DebugProfile|Win32.ActiveCfg = DebugProfile|Win32
+ {B61007AC-B557-4B67-A765-E468C0C3A821}.DebugProfile|Win32.Build.0 = DebugProfile|Win32
+ {B61007AC-B557-4B67-A765-E468C0C3A821}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
+ {B61007AC-B557-4B67-A765-E468C0C3A821}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
+ {B61007AC-B557-4B67-A765-E468C0C3A821}.Release profiled|Win32.ActiveCfg = Release|Win32
+ {B61007AC-B557-4B67-A765-E468C0C3A821}.Release profiled|Win32.Build.0 = Release|Win32
+ {B61007AC-B557-4B67-A765-E468C0C3A821}.Release|Win32.ActiveCfg = Release|Win32
+ {B61007AC-B557-4B67-A765-E468C0C3A821}.Release|Win32.Build.0 = Release|Win32
+ {B61007AC-B557-4B67-A765-E468C0C3A821}.ReleaseProfile|Win32.ActiveCfg = ReleaseProfile|Win32
+ {B61007AC-B557-4B67-A765-E468C0C3A821}.ReleaseProfile|Win32.Build.0 = ReleaseProfile|Win32
+ {B61007AC-B557-4B67-A765-E468C0C3A821}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
+ {B61007AC-B557-4B67-A765-E468C0C3A821}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Tools/AnvilStats/BiomeMap.cpp b/Tools/AnvilStats/BiomeMap.cpp
index 6505299ba..de8fc4ad7 100644
--- a/Tools/AnvilStats/BiomeMap.cpp
+++ b/Tools/AnvilStats/BiomeMap.cpp
@@ -5,38 +5,7 @@
#include "Globals.h"
#include "BiomeMap.h"
-
-
-
-
-
-static const int g_BiomePalette[] =
-{
- // ARGB:
- 0xff0000ff, /* Ocean */
- 0xff00cf3f, /* Plains */
- 0xffffff00, /* Desert */
- 0xff7f7f7f, /* Extreme Hills */
- 0xff00cf00, /* Forest */
- 0xff007f3f, /* Taiga */
- 0xff3f7f00, /* Swampland */
- 0xff003fff, /* River */
- 0xff7f0000, /* Hell */
- 0xff007fff, /* Sky */
- 0xff3f3fff, /* Frozen Ocean */
- 0xff3f3fff, /* Frozen River */
- 0xff7fffcf, /* Ice Plains */
- 0xff3fcf7f, /* Ice Mountains */
- 0xffcf00cf, /* Mushroom Island */
- 0xff7f00ff, /* Mushroom Island Shore */
- 0xffffff3f, /* Beach */
- 0xffcfcf00, /* Desert Hills */
- 0xff00cf3f, /* Forest Hills */
- 0xff006f1f, /* Taiga Hills */
- 0xff7f8f7f, /* Extreme Hills Edge */
- 0xff004f00, /* Jungle */
- 0xff003f00, /* Jungle Hills */
-} ;
+#include "../BiomeVisualiser/BiomeColors.h"
@@ -139,7 +108,7 @@ void cBiomeMap::StartNewRegion(int a_RegionX, int a_RegionZ)
unsigned char * BiomeRow = (unsigned char *)m_Biomes + z * 512;
for (int x = 0; x < 512; x++)
{
- RowData[x] = g_BiomePalette[BiomeRow[x]];
+ RowData[x] = g_BiomeColors[BiomeRow[x]];
}
f.Write(RowData, sizeof(RowData));
} // for z
diff --git a/Tools/AnvilStats/BiomeMap.h b/Tools/AnvilStats/BiomeMap.h
index c590a3c63..f662094a5 100644
--- a/Tools/AnvilStats/BiomeMap.h
+++ b/Tools/AnvilStats/BiomeMap.h
@@ -41,7 +41,7 @@ protected:
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) override { return false; }
virtual bool OnRealCoords(int a_ChunkX, int a_ChunkZ) override { return false; }
virtual bool OnLastUpdate(Int64 a_LastUpdate) override { return false; }
- virtual bool OnTerrainPopulated(bool a_Populated) override { return !a_Populated; } // If not populated, we don't want it!
+ virtual bool OnTerrainPopulated(bool a_Populated) override { return false; } // We don't care about "populated", the biomes are the same
virtual bool OnBiomes(const unsigned char * a_BiomeData) override;
void StartNewRegion(int a_RegionX, int a_RegionZ);
diff --git a/Tools/AnvilStats/Globals.h b/Tools/AnvilStats/Globals.h
index c673ecb01..df1430cc4 100644
--- a/Tools/AnvilStats/Globals.h
+++ b/Tools/AnvilStats/Globals.h
@@ -24,6 +24,15 @@
#define ALIGN_8
#define ALIGN_16
+ #define FORMATSTRING(formatIndex, va_argsIndex)
+
+ // MSVC has its own custom version of zu format
+ #define SIZE_T_FMT "%Iu"
+ #define SIZE_T_FMT_PRECISION(x) "%" #x "Iu"
+ #define SIZE_T_FMT_HEX "%Ix"
+
+ #define NORETURN __declspec(noreturn)
+
#elif defined(__GNUC__)
// TODO: Can GCC explicitly mark classes as abstract (no instances can be created)?
@@ -40,6 +49,14 @@
// Some portability macros :)
#define stricmp strcasecmp
+ #define FORMATSTRING(formatIndex, va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex)))
+
+ #define SIZE_T_FMT "%zu"
+ #define SIZE_T_FMT_PRECISION(x) "%" #x "zu"
+ #define SIZE_T_FMT_HEX "%zx"
+
+ #define NORETURN __attribute((__noreturn__))
+
#else
#error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler"
@@ -194,6 +211,8 @@ typedef unsigned short UInt16;
/// Faster than (int)floorf((float)x / (float)div)
#define FAST_FLOOR_DIV( x, div ) ( (x) < 0 ? (((int)x / div) - 1) : ((int)x / div) )
+#define TOLUA_TEMPLATE_BIND(...)
+
// Own version of assert() that writes failed assertions to the log for review
#ifdef _DEBUG
#define ASSERT( x ) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), assert(0), 0 ) )
@@ -204,6 +223,8 @@ typedef unsigned short UInt16;
// Pretty much the same as ASSERT() but stays in Release builds
#define VERIFY( x ) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), exit(1), 0 ) )
+typedef unsigned char Byte;
+
@@ -227,3 +248,4 @@ public:
+
diff --git a/Tools/AnvilStats/SpringStats.cpp b/Tools/AnvilStats/SpringStats.cpp
index 637cf20b6..51b7f9d5d 100644
--- a/Tools/AnvilStats/SpringStats.cpp
+++ b/Tools/AnvilStats/SpringStats.cpp
@@ -109,7 +109,7 @@ bool cSpringStats::OnSectionsFinished(void)
int Base = BaseY + z * 16;
for (int x = 1; x < 15; x++)
{
- if (cChunkDef::GetNibble(m_BlockMetas, Base + x) != 0)
+ if (cChunkDef::GetNibble(m_BlockMetas, x, y, z) != 0)
{
// Not a source block
continue;
diff --git a/Tools/MCADefrag/Globals.h b/Tools/MCADefrag/Globals.h
index f70a90d17..6593187e6 100644
--- a/Tools/MCADefrag/Globals.h
+++ b/Tools/MCADefrag/Globals.h
@@ -240,6 +240,7 @@ template <typename Type> class cItemCallback
public:
/// 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;
+ virtual ~cItemCallback() {};
} ;
diff --git a/docs/Generator.html b/docs/Generator.html
new file mode 100644
index 000000000..90a92c553
--- /dev/null
+++ b/docs/Generator.html
@@ -0,0 +1,529 @@
+<html>
+<head>
+<title>Generating terrain in MCServer</title>
+</head>
+<body>
+<h1>Generating terrain in MCServer</h1>
+<p>This article explains the principles behind the terrain generator in MCServer. It is not strictly
+specific to MCServer, though, it can be viewed as a generic guide to various terrain-generating algorithms,
+with specific implementation notes regarding MCServer.</p>
+
+<p>Contents:
+<ul>
+<li><a href="#preface">Preface: How it's done in real life</a></li>
+<li><a href="#expectedprops">Expected properties</a></li>
+<li><a href="#reversingflow">Reversing the flow</a></li>
+<li><a href="#composablegen">The ComposableGenerator pipeline</a></li>
+<li><a href="#coherentnoise">Using coherent noise</a></li>
+<li><a href="#biomegen">Generating biomes</a></li>
+<li><a href="#heightgen">Terrain height</a></li>
+<li><a href="#compositiongen">Terrain composition</a></li>
+<li><a href="#finishgen">Finishers</a></li>
+<li><a href="#makefaster">Making it all faster</a></li>
+<li><a href="#GPU">Executing on a GPU</a></li>
+</ul>
+</p>
+
+
+<hr />
+
+<a name="preface"><h2>Preface: How it's done in real life</h2></a>
+<p>The nature has many complicated geological, physical and biological processes working on all scales from
+microscopic to planet-wide scale, that have shaped the terrain into what we see today. The tectonic plates
+collide, push mountain ranges up and ocean trenches down. Erosion dulls the sharp shapes. Plantlife takes
+over to further change the overall look of the world.</p>
+
+<p>Generally speaking, the processes take what's there and change it. Unlike computer generating, which
+usually creates a finished terrain from scratch, or maybe with only a few iterations. It would be unfeasible
+for software to emulate all the natural processes in enough detail to provide world generation for a game,
+mainly because in the nature everything interacts with everything. If a mountain range rises, it changes the
+way that the precipitation is carried by the wind to the lands beyond the mountains, thus changing the
+erosion rate there and the vegetation type. </p>
+
+
+<hr />
+
+<a name="expectedprops"><h2>Expected properties</h2></a>
+<p>For a MineCraft-like game terrain generator we need the generator to have several properties:
+<ul>
+<li>The generator must be able to generate terrain in small chunks. This means it must be possible to
+generate each of the chunks separately, without dependencies on the neighboring chunks. Note that this
+doesn't mean chunks cannot coordinate together, it means that "a tree in one chunk cannot ask if there's
+a building in the neighbor chunk", simply because the neighbor chunk may not be generated yet.</li>
+<li>The generated chunk needs to be the same if re-generated. This property is not exactly required, but it
+makes available several techniques that wouldn't be possible otherwise.</li>
+<li>The generator needs to be reasonably fast. For a server application this means at least some 20 chunks
+per second for chunks close to each other, and 5 chunks per second for distant chunks. The reason for this
+distinction will be discussed later.</li>
+</ul>
+</p>
+
+
+<hr />
+
+<a name="reversingflow"><h2>Reversing the flow</h2></a>
+<p>As already mentioned, the nature works basically by generating raw terrain composition, then "applying"
+erosion, vegetation and finally this leads to biomes being formed. Let's now try a somewhat inverse
+approach: First generate biomes, then fit them with appropriate terrain, and finally cover in vegetation
+and all the other stuff.</p>
+
+<p>Splitting the parts like this suddenly makes it possible to create a generator with the required
+properties. We can generate a reasonable biome map chunk-wise, independently of all the other data. Once we
+have the biomes, we can compose the terrain for the chunk by using the biome data for the chunk, and
+possibly even for neighboring chunks. Note that we're not breaking the first property, the biomes can be
+generated separately so a neighboring chunk's biome map can be generated without the need for the entire
+neighboring chunk to be present. Similarly, once we have the terrain composition for a chunk, we can
+generate all the vegetation and structures in it, and those can again use the terrain composition in
+neighboring chunks.</p>
+
+
+<hr />
+
+<a name="composablegen"><h2>The ComposableGenerator pipeline</h2></a>
+<p>This leads us directly to the main pipeline that is used for generating terrain in MCServer. For
+technical reasons, the terrain composition step is further subdivided into Height generation and Composition
+generation, and the structures are really called Finishers. For each chunk the generator generates, in this
+sequence:
+<ul>
+<li>Biomes</li>
+<li>Terrain height</li>
+<li>Terrain composition</li>
+<li>Finishers</li>
+</ul>
+</p>
+
+<img src="img/biomes.jpg" />
+<img src="img/terrainheight.jpg" />
+<img src="img/terraincomposition.jpg" />
+<img src="img/finishers.jpg" />
+<p>The beautiful thing about this is that the individual components can be changed independently. You can
+have 5 biome generators and 3 height generators and you can let the users mix'n'match.
+</p>
+
+
+<hr />
+
+<a name="coherentnoise"><h2>Using coherent noise for the generation</h2></a>
+<p>For a great tutorial on coherent noise, see the <a href="http://libnoise.sourceforge.net/">LibNoise
+documentation</a>.</p>
+<p>Coherent noise is a type of noise that has three important properties that we can use to our advantage:
+<ul>
+<li>The noise is smooth</li>
+<li>The noise is algorithmically generated, which means that the same data is generated when the same
+parameters are given to the noise functions.</li>
+<li>The noise can be seamlessly extended in any direction</li>
+</ul></p>
+
+<p>We'll be mostly using Perlin noise in this article. It is the easiest one to visualise and use and is one
+of the most useful kinds of coherent noises. Here's an example of a Perlin noise generated in 2 dimensions:</p>
+<img src="img/perlin.jpg" />
+
+<p>It comes only naturally that such a 2D noise can be used as a terrain height map directly:</p>
+<img src="img/perlinheightmap.jpg" />
+
+<p>However, this is not the only use for this noise, and 2 dimensions is not the limit - this noise can be
+generated for any number of dimensions.</p>
+
+
+
+<hr />
+
+<a name="biomegen"><h2>Generating biomes</h2></a>
+<p>The easiest way to generate biomes is to not generate them at all - simply assign a single constant biome
+to everywhere. And indeed there are times when this kind of "generator" is useful - for the MineCraft's Flat
+world type, or for testing purposes, or for tematic maps. In MCServer, this is exactly what the Constant
+biome generator does.</p>
+
+<p>Of course, there are more interesting test scenarios for which multiple biomes must be generated as easy
+as possible. For these special needs, there's a CheckerBoard biome generator. As the name suggests, it
+generates a grid of alternating biomes.</p>
+
+<h3>Voronoi diagram</h3>
+<p>Those two generators were more of a technicality, we need to make something more interesting if we're
+going for a natural look. The Voronoi generator is the first step towards such a change. Recall that a
+<a href="http://en.wikipedia.org/wiki/Voronoi_diagram">Voronoi diagram</a> is a construct that creates a
+set of areas where each point in an area is closer to the appropriate seed of the area than the seeds of any
+other area:</p>
+<img src="img/voronoi.png" />
+
+<p>To generate biomes using this approach, you select random "seeds", assign a biome to each one, and then
+for each "column" of the world you find the seed that is the nearest to that column, and use that seed's
+biome.</p>
+
+<p>The overall shape of a Voronoi diagram is governed by the placement of the seeds. In extreme cases, a
+seed could affect the entire diagram, which is what we don't want - we need our locality, so that we can
+generate a chunk's worth of biome data. We also don't want the too much irregular diagrams that are produced
+when the seeds are in small clusters. We need our seeds to come in random, yet somewhat uniform fashion.</p>
+
+<p>Luckily, we have just the tool: Grid with jitter. Originally used in antialiasing techniques, they can be
+successfully applied as a source of the seeds for a Voronoi diagram. Simply take a regular 2D grid of seeds
+with the grid distance being N, and move each seed along the X and Y axis by a random distance, usually in
+the range [-N / 2, +N / 2]:</p>
+<img src="img/jittergrid.jpg" />
+
+<p>Such a grid is the ideal seed source for a Voronoi biome generator, because not
+only are the Voronoi cells "reasonable", but the seed placement's effect on the diagram is localized - each
+pixel in the diagram depends on at most 4 x 4 seeds around it. In the following picture, the seed for the
+requested point (blue) must be within the indicated circle. Even the second-nearest seed, which we will need
+later, is inside that circle.</p>
+<img src="img/jittergridlocality.jpg" />
+
+<p>Calculating the jitter for each cell can be done easily by using a 2D Perlin noise for each coord. We
+calculate the noise's value at [X, Z], which gives us a number in the range [-1; 1]. We then multiply the
+number by N / 2, this gives us the required range of [-N / 2, +N / 2]. Adding this number to the X coord
+gives us the seed's X position. We use another Perlin noise and the same calculation for the Z coord of the
+seed.</p>
+
+<p>Here's an example of a biome map generated using the Voronoi + jitter grid, as implemented by the Voronoi
+biome generator in MCServer:</p>
+<img src="img/voronoijitterbiomes.png" />
+
+<h3>Distorted Voronoi</h3>
+<p>The biomes are starting to look interesting, but now they have straight-line borders, which looks rather
+weird and the players will most likely notice very soon. We need to somehow distort the borders to make them
+look more natural. By far the easiest way to achieve that is to use a little trick: When the generator is
+asked for the biome at column [X, Z], instead of calculating the Voronoi biome for column [X, Z], we first
+calculate a random offset for each coord, and add it to the coordinates. So the generator actually responds
+with the biome for [X + rndX, Z + rndZ].</p>
+
+<p>In order to keep the property that generating for the second time gives us the same result, we need the
+"random offset" to be replicatable - same output for the same input. This is where we use yet another Perlin
+noise - just like with the jitter for the Voronoi grid, we add a value from a separate noise to each
+coordinate before sending the coordinates down to the Voronoi generator:</p>
+<code>
+DistortedVoronoiBiome(X, Z) := VoronoiBiome(X + PerlinX(X, Z), Z + PerlinZ(X, Z))
+</code>
+
+<p>The following image shows the effects of the change, as generated by MCServer's DistortedVoronoi biome
+generator. It is actually using the very same Voronoi map as the previous image, the only change has been
+the addition of the distortion:</p>
+<img src="img/distortedvoronoibiomes.png" />
+
+<p>As you can see, this already looks reasonable enough, it could be considered natural biomes, if it
+weren't for several drawbacks:
+<ul>
+<li>There's no way to limit the neighbors. A desert biome can neighbor a tundra biome. </li>
+<li>All the biomes are considered equal. There's no way to make oceans larger. A mushroom biome is
+generated right next to other land biomes.</li>
+</ul></p>
+
+<h3>Adding relativity</h3>
+<p>Our next goal is to remove the first defect of the distorted Voronoi generator: unrelated biomes
+generating next to each other. It is highly unlikely to find a jungle biome next to a desert biome, so we
+want to have as few of those borders as possible. We could further improve on the selection of
+biome-to-seed in the Voronoi generator. Or we can try a completely different idea altogether.</p>
+
+<p>Recall how we talked about the nature, where the biomes are formed by the specific conditions of a place.
+What if we could make a similar dependency, but without the terrain? It turns out this is possible rather
+easily - instead of depending on the terrain, we choose two completely artificial measures. Let's call them
+Temperature and Humidity. If we knew the temperature of the place, we know what set of biomes are possible
+for such temperatures - we won't place deserts in the cold and tundra in the hot anymore. Similarly, the
+humidity will help us sort out the desert vs jungle issue. But how do we get a temperature and humidity?
+Once again, the Perlin noise comes to the rescue. We can use a simple 2D Perlin noise as the temperature
+map, and another one as the humidity map.</p>
+
+<p>What we need next is a decision of what biome to generate in certain temperature and humidity
+combinations. The fastest way for a computer is to have a 2D array, where the temperature is one dimension
+and humidity the other, and the values in the array specify the biome to generate:</p>
+<img src="img/temperaturehumiditydecisionsimple.jpg" />
+
+<p>We can even "misuse" the above diagram to include the hill variants of the biomes and have those hills
+neighbor each other properly, simply by declaring some of the decision diagram's parts as hills:</p>
+<img src="img/temperaturehumiditydecisionhills.jpg" />
+
+<p>The problem with this approach is that there are biomes that should not depend on temperature or
+humidity, they generate across all of their values. Biomes like Oceans, Rivers and Mushroom. We could
+either add them somewhere into the decision diagram, or we can make the generator use a multi-step decision:
+<ul>
+<li>Decide whether the point is in the ocean, land or mushroom</li>
+<li>If it's land, decide if it's real land or river.</li>
+<li>If it's real land, use a TemperatureHumidity approach to generate land-biomes</li>
+</ul>
+</p>
+
+<p>This is the approach implemented in MCServer's MultiStepMap biome generator. It generates biome maps like
+this:</p>
+<img src="img/multistepmapbiomes.png" />
+
+<p>To decide whether the point is in the ocean, land or mushroom, the generator first chooses seeds in a grid
+that will be later fed to a DistortedVoronoi algorithm, the seeds get the "ocean" and "land" values. Then it
+considers all the "ocean" seeds that are surrounded by 8 other "ocean" seeds and turns a random few of them
+into "mushroom". This special seed processing makes the mushroom biomes mostly surrounded by ocean. The
+following image shows an example seeds grid that the generator might consider, only the two framed cells are
+allowed to change into mushroom. L = land, O = ocean:</p>
+<img src="img/multistepmapgrid.jpg" />
+
+<p>Next, the generator calculates the DistortedVoronoi for the seeds. For the areas that are calculated as
+mushroom, the distance to the nearest-seed is used to further shrink the mushroom biome and then to
+distinguish between mushroom and mushroom-shore (image depicts a Voronoi cell for illustration purposes, it
+works similarly with DistortedVoronoi). O = ocean, M = mushroom, MS = mushroom shore:</p>
+<img src="img/multistepmapdistance.jpg" />
+
+<a name="perlinrivers">
+<p>The rivers are added only to the areas that have been previously marked as land. A simple 2D Perlin noise
+is used as the base, where its value is between 0 and a configured threshold value, a river is created. This
+creates the rivers in a closed-loop-like shapes, occasionally splitting two branches off:</p>
+<img src="img/perlinrivers1.jpg" />
+<img src="img/perlinrivers2.jpg" />
+<img src="img/perlinrivers3.jpg" />
+</a>
+
+<p>For the leftover land biomes, the two Perlin noises, representing temperature and humidity, are used to
+generate the biomes, as described earlier. Additionally, the temperature map is used to turn the Ocean biome
+into FrozenOcean, and the River biome into FrozenRiver, wherever the temperature drops below a threshold.</p>
+
+<h3>Two-level Voronoi</h3>
+<p>The 1.7 MineCraft update brought a completely new terrain generation, which has sparked renewed interest
+in the biome generation. A new, potentially simpler way of generating biomes was found, the two-level
+DistortedVoronoi generator.</p>
+
+<p>The main idea behind it all is that we create large areas of similar biomes. There are several groups of
+related biomes that can be generated near each other: Desert biomes, Ice biomes, Forest biomes, Mesa biomes.
+Technically, the Ocean biomes were added as yet another group, so that the oceans will generate in
+approximately the size of the larger areas, too.</p>
+
+<p>For each column a DistortedVoronoi is used to select, which large area to use. This in turn results in
+the list of biomes from which to choose. Another DistortedVoronoi, this time with a smaller grid size, is
+used to select one biome out of that list. Additionally, the smaller DistortedVoronoi calculates not only
+the nearest seed's distance, but also the distance to the second-nearest seed; the ratio between these two
+is used as an indicator whether the column is in the "inside" or on the "outskirt" of the smaller Voronoi
+cell. This allows us to give certain biomes an "edge" biome - the Mushroom biome has a MushroomShore edge,
+the ExtremeHills biome have an ExtremeHillsEdge biome on the edge, etc.</p>
+
+<p>The images below illustrate the process with regular Voronoi diagrams, for clarity purposes. The real
+generator uses distortion before querying the small areas.</p>
+<img src="img/twolevellargeareas.jpg" /><br />
+<img src="img/twolevelsmallgrid.jpg" /><br />
+<img src="img/twolevelsmallareas.jpg" /><br />
+
+<p>The following image shows an example output of a TwoLevel biome generator in MCServer:</p>
+<img src="img/twolevelbiomes.png" />
+
+<p>Note that rivers are currently not implemented in this generator in MCServer, but they could be added
+using the same approach as in MultiStepMap - by using a thresholded 2D Perlin noise.</p>
+
+
+<hr />
+
+<a name="heightgen"><h2>Terrain height</h2></a>
+<p>As with biomes, the easiest way to generate terrain height is not generating at all - assigning a constant
+height value to all columns. This is again useful either for internal tests, and for worlds like MineCraft's
+Flat world.</p>
+
+<p>For a somewhat more realistic landscape, we will employ the good old 2D Perlin noise. We can use it
+directly as a heightmap - each value we get from the noise is stretched into the desired range (usually from
+40 to 120 blocks for regular MineCraft worlds) and used as the height value. However, this doesn't play too
+well with the biomes we've just generated. If the biome says "ocean" and the Perlin noise says "mountain",
+the end result will be unpleasant.</p>
+
+<p>So we want a height generator that is biome-aware. The easiest way of doing this is to have a separate
+generator for each biome. Simply use the biome map to select which generator to use, then ask the appropriate
+generator for the height value. Again, this doesn't work too well - imagine an ExtremeHills biome right next
+to an Ocean biome. If no extra care is taken, the border between these two will be a high wall. The following
+image shows a 2D representation (for simplification purposes) of the problem:</p>
+<img src="img/biomeheights.jpg" />
+
+<p>This requires some further processing. What we need is for the terrain height to be dependent not only on
+the immediate biome for that column, but also on the close surroundings of the column. This is exactly the
+kind of task that averaging is designed for. If we take the area of 9x9 biomes centered around the queried
+column, generate height for each of the biomes therein, sum them up and divide by 81 (the number of biomes
+summed), we will be effectively making a 9-long running average over the terrain, and all the borders will
+suddenly become smooth. The following image shows the situation from the previous paragraph after applying
+the averaging process: </p>
+<img src="img/biomeheightsavg.jpg" />
+
+<p>The approach used in MCServer's Biomal generator is based on this idea, with two slight modifications.
+Instead of using a separate generator for each biome, one generator is used with a different set of input
+parameters for each biomes. These input parameters modify the overall amplitude and frequency of the Perlin
+noise that the generator produces, thus modifying the final terrain with regards to biomes. Additionally, the
+averaging process is weighted - columns closer to the queried column get a more powerful weight in the sum
+than the columns further away. The following image shows the output of MCServer's Biomal terrain height
+generator (each block type represents a different biome - ocean in the front (stone), plains and ice plains
+behind it (lapis, whitewool), extreme hills back right (soulsand), desert hills back left (mossy
+cobble)):</p>
+<a name="biomalheights"><img src="img/biomalheights.jpg" /></a>
+
+<p>One key observation about this whole approach is that in order for it to work, the biomes must be
+available for columns outside the currently generated chunk, otherwise the columns at the chunk's edge would
+not be able to properly average their height. This requirement can be fulfilled only by biome generators that
+adhere to the second <a href="#expectedproperties">Expected property</a> - that re-generating will produce
+the same data. If the biome generator returned different data for the same chunk each time it was invoked, it
+would become impossible to apply the averaging.</p>
+
+<p>(TODO: height with variations (N/A in MCS yet)</p>
+
+
+<hr />
+
+<a name="compositiongen"><h2>Terrain composition</h2></a>
+<p>As with the other generators, the composition generator category has its easy and debugging items, too.
+There's the "special" composition of "all the blocks are the same type", which fills the entire column, from
+the bottom to the height, with a single blocktype. This generator is useful when testing the generators in
+the other categories, to speed up the generation by leaving out unnecessary calculations. Another special
+compositor is a similar one, that fills all blocks with the same type, but the type varies for each biome.
+This way it's easy to see the generated biomes and possibly the heights for those biomes, as shown in the
+previous section on the <a href="#biomalheights">height averaging screenshot</a>.</p>
+
+<p>For a natural look, we need to put together a more complicated algorithm. The standard set forth in
+MineCraft is that the top of the world is covered in grass, then there are a few blocks of dirt and finally
+stone. This basic layout is then varied for different biomes - deserts have sand and sandstone instead of the
+grass and dirt layer. Mushroom biomes have mycelium in place of the grass. This per-biome dependency is
+trivial to implement - when compositing, simply use the appropriate layout for the column's biome.</p>
+
+<p>The next change concerns oceans. The generated heightmap doesn't include any waterlevel indication
+whatsoever. So it's up to the terrain compositor to actually decide where to place water. We do this by
+configuration - simply have a value in the config file specifying the sealevel height. The compositor then
+has to add water above any column which has a height lower than that. Additionally, the water needs to
+override per-biome layout selection - we don't want grass blocks to generate under water when the terrain
+height in the plains biome drops below the sealevel accidentally.</p>
+
+<p>The final feature in the compositor is the decision between multiple composition layouts within a single
+biome. A megataiga biome contains patches of non-grass dirt and podzol blocks, and the ocean floor can be
+made of dirt, gravel, sand or clay. A simple 2D Perlin noise can be used to select the layout to use for a
+specific column - simply threshold the noise's value by as many thresholds as there are layout variations,
+and use the layout corresponding to the threshold:</p>
+<img src="img/perlincompositor1.jpg" />
+<img src="img/perlincompositor2.jpg" />
+<img src="img/perlincompositor3.jpg" />
+
+<h3>Nether composition</h3>
+<p>So far we've been discussing only the Overworld generator. But MineCraft contains more than that. The
+Nether has a completely different look and feel, and quite different processes are required to generate that.
+Recall that MineCraft's Nether is 128 blocks high, with bedrock both at the top and the bottom. Between these
+two, the terrain looks more like a cavern than a surface. Not surprisingly, the Nether doesn't need a
+complicated height generator, it can use the flat height. However, the terrain composition must take an
+altogether different approach.</p>
+
+<p>The very first idea is to use the Perlin noise, but generate it in 3D, rather than 2D. Then, for each
+block, evaluate the noise value, if below 0, make it air, if not, make it netherrack.
+
+<p>To make it so that the bedrock at the top and at the bottom is never revealed, we can add a value
+increasing the more the Y coord gets towards the bottom or the top. This way the thresholding then guarantees
+that there will be no air anywhere near the bedrock.</p>
+
+<p>(TODO)</p>
+
+
+<hr />
+
+<a name="finishgen"><h2>Finishers</h2></a>
+<p>Finishers are a vast category of various additions to the terrain generator. They range from very easy
+ones, such as generating snow on top of the terrain in cold biomes, through medium ones, such as growing
+patches of flowers, complicated ones, such as placing trees and generating caves, all the way to very
+complicated ones such as villages and nether fortresses. There is no formal distinction between all these
+"categories", the only thing they have in common is that they take a chunk of blocks and modify it in some
+way.</p>
+
+<h3>Snow</h3>
+<p>Snow is probably the easiest of the finishers. It generates a block of snow on top of each block that is
+on top of the terrain and is not marked as non-snowable. It checks the chunk's heightmap to determine the top
+block, then checks whether the block supports snow on its top. Rails, levers and tall grass don't support
+snow, for example.</p>
+
+<h3>Ice</h3>
+<p>Another example of an easy finisher. This scans through the world and turn each water block on the surface
+into an ice block if the biome is cold. This means that any water block that is under any kind of other
+block, such as under a tree's leaves, will still stay water. Thus an additional improvement could be made by
+scanning down from the surface block through blocks that we deem as non-surface, such as leaves, torches,
+ladders, fences etc. Note that MCServer currently implements only the easy solution.</p>
+
+<h3>Bottom lava</h3>
+<p>Most worlds in MineCraft have lava lakes at their bottom. Generating these is pretty straightforward: Use
+the user-configured depth and replace all the air blocks below this depth with lava blocks. Note however,
+that this makes this generator dependent on the order in which the finishers are applied. If the mineshafts
+generate before bottom lava, the mineshafts that are below the lava level will get filled with lava. On the
+other hand, if bottom lava is generated before the mineshafts, it is possible for a mineshaft to "drill
+through" a lake of lava. MCServer doesn't try to solve this and instead lets the admin choose whichever they
+prefer.</p>
+
+<h3>Specific foliage</h3>
+<p>There are generators for specific kinds of foliage. The dead bushes in the desert biome and lilypads in
+the swamp biome both share the same generating pattern. They are both specific to a single biome and they
+both require a specific block underneath them in order to generate. Their implementation is simple: pick
+several random columns in the chunk. If the column is of the correct biome and has the correct top block,
+add the foliage block on top.</p>
+
+<p>In order to generate the same set of coordinates when the chunk is re-generated, we use the Perlin noise's
+basis functions (the ones providing the random values for Perlin cell vertices). These basically work as a
+hash function for the coorinates - the same input coordinates generate the same output value. We use the
+chunk's coordinates as two of the coords, and the iteration number as the third coordinate, to generate a
+random number. We then check the biome and the top block at those coordinates, if they allow, we generate the
+foliage block on top.</p>
+
+<p>Another example of specific foliage is the tall grass in the plains biome. There are quite a lot of these
+tall grass blocks, it would be inefficient to generate them using the random-coords approach described above.
+Instead, we will use a 2D Perlin noise again, with a threshold defining where to put the grass and where
+not.</p>
+
+<h3>Small foliage</h3>
+<p>For the flowers, grass, mushrooms in caves etc. we want to use a slightly different algorithm. These
+foliage blocks are customarily generated in small "clumps" - there are several blocks of the same type near
+together. To generate these, we first select random coords, using the coord hash functions, for a center of a
+clump. Then we select the type of block to generate. Finally, we loop over adding a random (coord hash)
+number to the clump center coords to get the block where to generate the foliage block:</p>
+<img src="img/smallfoliageclumps.jpg" />
+
+<p>In order to make the clump more "round" and "centered", we want the offsets to be closer to the clump
+center more often. This is done using a thing called Gaussian function distribution. Instead of having each
+random number generate with the same probability, we want higher probability for the numbers around zero,
+like this:</p>
+<img src="img/gaussprobability.jpg" />
+
+<p>Instead of doing complicated calculations to match this shape exactly, we will use a much easier shape.
+By adding together two random numbers in the same range, we get the probability distribution that has a
+"roof" shape, enough for our needs:</p>
+<img src="img/roofprobability.jpg" />
+
+<p>(For the curious, there is a proof that adding together infinitely many uniform-distributed random numbers
+produces random numbers with the Gaussian distribution.)</p>
+
+<p>This scheme can be used to produce clumps of flowers, when we select the 2D coords of the clump center on
+the top surface of the terrain. We simply generate the 2D coords of the foliage blocks and use the terrain
+height to find the third coord. If we want to generate clumps of mushrooms in the caves, however, we need to
+generate the clump center coords in 3D and either use 3 offsets for the mushrooms, or use 2 offsets plus
+searching for the closest opening Y-wise in the terrain.</p>
+
+<p>Note that the clumps generated by this scheme may overlap several chunks. Therefore it's crucial to
+actually check the surrounding chunks if their clumps overlap into the currently generated chunk, and apply
+those as well, otherwise there will be visible cuts in the foliage along the chunks borders.</p>
+
+<h3>Springs</h3>
+<p>Water and lava springs are essential for making the underground quite a lot more interesting. They are
+rather easy to generate, but a bit more difficult to get right. Generating simply means that a few random
+locations (obtained by our familiar coord hashing) are checked and if the block type in there is stone. Then
+we see all the horizontal neighbors of the block, plus the block underneath. If all of them except one are
+stone, and the one left is air, our block is suitable for turning into a spring. If there were more air
+neighbors, the spring would look somewhat unnatural; if there were no air neighbors, the spring won't flow
+anywhere, so it would be rather useless.</p>
+
+<p>The difficult part about springs is the amount of them to generate. There should be a few springs on the
+surface, perhaps a bit more in the mountaineous biomes. There should be quite a few more springs underground,
+but there should definitely be more water springs than lava springs in the upper levels of the terrain, while
+there should be more lava springs and almost no water springs near the bottom. To accomodate this, the
+MCServer team has made a tool that scanned through MineCraft's terrain and counted the amount of both types
+of springs in relation to their height. Two curves have been found for the distribution of each type of the
+spring:</p>
+<img src="http://mc-server.xoft.cz/img/vanilla_springs_huge.png" />
+
+<p>MCServer uses an approximation of the above curves to choose the height at which to generate the
+spring.</p>
+
+<!--
+<h3>Caves</h3>
+<p>Caves are definitely one of the main things people notice about MineCraft terrain. There are quite a lot
+of different algorithms available to generate terrain with caves.
+-->
+
+<hr />
+
+<a name="makefaster"><h2>Making it all faster</h2></a>
+<p>(TODO)</p>
+
+<a name="GPU"><h2>Executing on a GPU</h2></a>
+<p>Much of the terain generation consists of doing the same thing for every single column or block in a chunk. This
+sort of computation is much faster on a GPU as GPUs are massively parallel. High end GPUs can execute up to 30,000
+threads simultaneously, which would allow them to generate every block in half a chunk in parallel or every column
+in over 100 chunks in parallel. A naive comparison suggests that a 800MHz GPU with 15,000 threads can execute parallel
+code 250 times faster than a 3GHz CPU with 128 bit SIMD. Obviously we want to harness that power.</p>
+</body>
+</html>
diff --git a/docs/img/biomalheights.jpg b/docs/img/biomalheights.jpg
new file mode 100644
index 000000000..a01faef87
--- /dev/null
+++ b/docs/img/biomalheights.jpg
Binary files differ
diff --git a/docs/img/biomeheights.jpg b/docs/img/biomeheights.jpg
new file mode 100644
index 000000000..9dda27b0e
--- /dev/null
+++ b/docs/img/biomeheights.jpg
Binary files differ
diff --git a/docs/img/biomeheightsavg.jpg b/docs/img/biomeheightsavg.jpg
new file mode 100644
index 000000000..c8217cafc
--- /dev/null
+++ b/docs/img/biomeheightsavg.jpg
Binary files differ
diff --git a/docs/img/biomes.jpg b/docs/img/biomes.jpg
new file mode 100644
index 000000000..59c23b870
--- /dev/null
+++ b/docs/img/biomes.jpg
Binary files differ
diff --git a/docs/img/distortedvoronoibiomes.png b/docs/img/distortedvoronoibiomes.png
new file mode 100644
index 000000000..d56dff347
--- /dev/null
+++ b/docs/img/distortedvoronoibiomes.png
Binary files differ
diff --git a/docs/img/finishers.jpg b/docs/img/finishers.jpg
new file mode 100644
index 000000000..06f7485c3
--- /dev/null
+++ b/docs/img/finishers.jpg
Binary files differ
diff --git a/docs/img/gaussprobability.jpg b/docs/img/gaussprobability.jpg
new file mode 100644
index 000000000..77da24748
--- /dev/null
+++ b/docs/img/gaussprobability.jpg
Binary files differ
diff --git a/docs/img/jittergrid.jpg b/docs/img/jittergrid.jpg
new file mode 100644
index 000000000..f8066aa72
--- /dev/null
+++ b/docs/img/jittergrid.jpg
Binary files differ
diff --git a/docs/img/jittergridlocality.jpg b/docs/img/jittergridlocality.jpg
new file mode 100644
index 000000000..64414c878
--- /dev/null
+++ b/docs/img/jittergridlocality.jpg
Binary files differ
diff --git a/docs/img/multistepmapbiomes.png b/docs/img/multistepmapbiomes.png
new file mode 100644
index 000000000..d32ac3d8e
--- /dev/null
+++ b/docs/img/multistepmapbiomes.png
Binary files differ
diff --git a/docs/img/multistepmapdistance.jpg b/docs/img/multistepmapdistance.jpg
new file mode 100644
index 000000000..9f7cfd11b
--- /dev/null
+++ b/docs/img/multistepmapdistance.jpg
Binary files differ
diff --git a/docs/img/multistepmapgrid.jpg b/docs/img/multistepmapgrid.jpg
new file mode 100644
index 000000000..51dd81c46
--- /dev/null
+++ b/docs/img/multistepmapgrid.jpg
Binary files differ
diff --git a/docs/img/perlin.jpg b/docs/img/perlin.jpg
new file mode 100644
index 000000000..499fcdeae
--- /dev/null
+++ b/docs/img/perlin.jpg
Binary files differ
diff --git a/docs/img/perlincompositor1.jpg b/docs/img/perlincompositor1.jpg
new file mode 100644
index 000000000..0d8f93cd9
--- /dev/null
+++ b/docs/img/perlincompositor1.jpg
Binary files differ
diff --git a/docs/img/perlincompositor2.jpg b/docs/img/perlincompositor2.jpg
new file mode 100644
index 000000000..11fc5b51d
--- /dev/null
+++ b/docs/img/perlincompositor2.jpg
Binary files differ
diff --git a/docs/img/perlincompositor3.jpg b/docs/img/perlincompositor3.jpg
new file mode 100644
index 000000000..46a2583ba
--- /dev/null
+++ b/docs/img/perlincompositor3.jpg
Binary files differ
diff --git a/docs/img/perlinheightmap.jpg b/docs/img/perlinheightmap.jpg
new file mode 100644
index 000000000..d941a2fc6
--- /dev/null
+++ b/docs/img/perlinheightmap.jpg
Binary files differ
diff --git a/docs/img/perlinrivers1.jpg b/docs/img/perlinrivers1.jpg
new file mode 100644
index 000000000..b11373fa7
--- /dev/null
+++ b/docs/img/perlinrivers1.jpg
Binary files differ
diff --git a/docs/img/perlinrivers2.jpg b/docs/img/perlinrivers2.jpg
new file mode 100644
index 000000000..bbbcaa276
--- /dev/null
+++ b/docs/img/perlinrivers2.jpg
Binary files differ
diff --git a/docs/img/perlinrivers3.jpg b/docs/img/perlinrivers3.jpg
new file mode 100644
index 000000000..3cf043e6e
--- /dev/null
+++ b/docs/img/perlinrivers3.jpg
Binary files differ
diff --git a/docs/img/roofprobability.jpg b/docs/img/roofprobability.jpg
new file mode 100644
index 000000000..e7a155113
--- /dev/null
+++ b/docs/img/roofprobability.jpg
Binary files differ
diff --git a/docs/img/smallfoliageclumps.jpg b/docs/img/smallfoliageclumps.jpg
new file mode 100644
index 000000000..4cc6cbc00
--- /dev/null
+++ b/docs/img/smallfoliageclumps.jpg
Binary files differ
diff --git a/docs/img/temperaturehumiditydecisionhills.jpg b/docs/img/temperaturehumiditydecisionhills.jpg
new file mode 100644
index 000000000..c755df158
--- /dev/null
+++ b/docs/img/temperaturehumiditydecisionhills.jpg
Binary files differ
diff --git a/docs/img/temperaturehumiditydecisionsimple.jpg b/docs/img/temperaturehumiditydecisionsimple.jpg
new file mode 100644
index 000000000..cbb1271b5
--- /dev/null
+++ b/docs/img/temperaturehumiditydecisionsimple.jpg
Binary files differ
diff --git a/docs/img/terraincomposition.jpg b/docs/img/terraincomposition.jpg
new file mode 100644
index 000000000..3d03e101d
--- /dev/null
+++ b/docs/img/terraincomposition.jpg
Binary files differ
diff --git a/docs/img/terrainheight.jpg b/docs/img/terrainheight.jpg
new file mode 100644
index 000000000..bcbafcfaf
--- /dev/null
+++ b/docs/img/terrainheight.jpg
Binary files differ
diff --git a/docs/img/twolevelbiomes.png b/docs/img/twolevelbiomes.png
new file mode 100644
index 000000000..a3104733f
--- /dev/null
+++ b/docs/img/twolevelbiomes.png
Binary files differ
diff --git a/docs/img/twolevellargeareas.jpg b/docs/img/twolevellargeareas.jpg
new file mode 100644
index 000000000..9d5d5ac8a
--- /dev/null
+++ b/docs/img/twolevellargeareas.jpg
Binary files differ
diff --git a/docs/img/twolevelsmallareas.jpg b/docs/img/twolevelsmallareas.jpg
new file mode 100644
index 000000000..14afbc42a
--- /dev/null
+++ b/docs/img/twolevelsmallareas.jpg
Binary files differ
diff --git a/docs/img/twolevelsmallgrid.jpg b/docs/img/twolevelsmallgrid.jpg
new file mode 100644
index 000000000..6c75e0b28
--- /dev/null
+++ b/docs/img/twolevelsmallgrid.jpg
Binary files differ
diff --git a/docs/img/voronoi.png b/docs/img/voronoi.png
new file mode 100644
index 000000000..e61e183ef
--- /dev/null
+++ b/docs/img/voronoi.png
Binary files differ
diff --git a/docs/img/voronoijitterbiomes.png b/docs/img/voronoijitterbiomes.png
new file mode 100644
index 000000000..42f0b7e40
--- /dev/null
+++ b/docs/img/voronoijitterbiomes.png
Binary files differ
diff --git a/lib/cmake-coverage/CodeCoverage.cmake b/lib/cmake-coverage/CodeCoverage.cmake
new file mode 100644
index 000000000..edf927fec
--- /dev/null
+++ b/lib/cmake-coverage/CodeCoverage.cmake
@@ -0,0 +1,160 @@
+#
+# 2012-01-31, Lars Bilke
+# - Enable Code Coverage
+#
+# 2013-09-17, Joakim Söderberg
+# - Added support for Clang.
+# - Some additional usage instructions.
+#
+# USAGE:
+# 1. Copy this file into your cmake modules path.
+#
+# 2. Add the following line to your CMakeLists.txt:
+# INCLUDE(CodeCoverage)
+#
+# 3. Set compiler flags to turn off optimization and enable coverage:
+# SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
+# SET(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
+#
+# 3. Use the function SETUP_TARGET_FOR_COVERAGE to create a custom make target
+# which runs your test executable and produces a lcov code coverage report:
+# Example:
+# SETUP_TARGET_FOR_COVERAGE(
+# my_coverage_target # Name for custom target.
+# test_driver # Name of the test driver executable that runs the tests.
+# # NOTE! This should always have a ZERO as exit code
+# # otherwise the coverage generation will not complete.
+# coverage # Name of output directory.
+# )
+#
+# 4. Build a Debug build:
+# cmake -DCMAKE_BUILD_TYPE=Debug ..
+# make
+# make my_coverage_target
+#
+#
+
+# Check prereqs
+FIND_PROGRAM( GCOV_PATH gcov )
+FIND_PROGRAM( LCOV_PATH lcov )
+FIND_PROGRAM( GENHTML_PATH genhtml )
+FIND_PROGRAM( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/tests)
+
+IF(NOT GCOV_PATH)
+MESSAGE(FATAL_ERROR "gcov not found! Aborting...")
+ENDIF() # NOT GCOV_PATH
+
+IF(NOT CMAKE_COMPILER_IS_GNUCXX)
+# Clang version 3.0.0 and greater now supports gcov as well.
+MESSAGE(WARNING "Compiler is not GNU gcc! Clang Version 3.0.0 and greater supports gcov as well, but older versions don't.")
+
+IF(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+MESSAGE(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
+ENDIF()
+ENDIF() # NOT CMAKE_COMPILER_IS_GNUCXX
+
+SET(CMAKE_CXX_FLAGS_COVERAGE
+ "-g -O0 --coverage -fprofile-arcs -ftest-coverage"
+ CACHE STRING "Flags used by the C++ compiler during coverage builds."
+ FORCE )
+SET(CMAKE_C_FLAGS_COVERAGE
+ "-g -O0 --coverage -fprofile-arcs -ftest-coverage"
+ CACHE STRING "Flags used by the C compiler during coverage builds."
+ FORCE )
+SET(CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ ""
+ CACHE STRING "Flags used for linking binaries during coverage builds."
+ FORCE )
+SET(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
+ ""
+ CACHE STRING "Flags used by the shared libraries linker during coverage builds."
+ FORCE )
+MARK_AS_ADVANCED(
+ CMAKE_CXX_FLAGS_COVERAGE
+ CMAKE_C_FLAGS_COVERAGE
+ CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
+
+IF ( NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "Coverage"))
+ MESSAGE( WARNING "Code coverage results with an optimized (non-Debug) build may be misleading" )
+ENDIF() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug"
+
+
+# Param _targetname The name of new the custom make target
+# Param _testrunner The name of the target which runs the tests.
+# MUST return ZERO always, even on errors.
+# If not, no coverage report will be created!
+# Param _outputname lcov output is generated as _outputname.info
+# HTML report is generated in _outputname/index.html
+# Optional fourth parameter is passed as arguments to _testrunner
+# Pass them in list form, e.g.: "-j;2" for -j 2
+FUNCTION(SETUP_TARGET_FOR_COVERAGE _targetname _testrunner _outputname)
+
+IF(NOT LCOV_PATH)
+MESSAGE(FATAL_ERROR "lcov not found! Aborting...")
+ENDIF() # NOT LCOV_PATH
+
+IF(NOT GENHTML_PATH)
+MESSAGE(FATAL_ERROR "genhtml not found! Aborting...")
+ENDIF() # NOT GENHTML_PATH
+
+# Setup target
+ADD_CUSTOM_TARGET(${_targetname}
+
+# Cleanup lcov
+${LCOV_PATH} --directory . --zerocounters
+
+# Run tests
+COMMAND ${_testrunner} ${ARGV3}
+
+# Capturing lcov counters and generating report
+COMMAND ${LCOV_PATH} --directory . --capture --output-file ${_outputname}.info
+COMMAND ${LCOV_PATH} --remove ${_outputname}.info 'tests/*' '/usr/*' --output-file ${_outputname}.info.cleaned
+COMMAND ${GENHTML_PATH} -o ${_outputname} ${_outputname}.info.cleaned
+COMMAND ${CMAKE_COMMAND} -E remove ${_outputname}.info ${_outputname}.info.cleaned
+
+WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
+)
+
+# Show info where to find the report
+ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD
+COMMAND ;
+COMMENT "Open ./${_outputname}/index.html in your browser to view the coverage report."
+)
+
+ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE
+
+# Param _targetname The name of new the custom make target
+# Param _testrunner The name of the target which runs the tests
+# Param _outputname cobertura output is generated as _outputname.xml
+# Optional fourth parameter is passed as arguments to _testrunner
+# Pass them in list form, e.g.: "-j;2" for -j 2
+FUNCTION(SETUP_TARGET_FOR_COVERAGE_COBERTURA _targetname _testrunner _outputname)
+
+IF(NOT PYTHON_EXECUTABLE)
+MESSAGE(FATAL_ERROR "Python not found! Aborting...")
+ENDIF() # NOT PYTHON_EXECUTABLE
+
+IF(NOT GCOVR_PATH)
+MESSAGE(FATAL_ERROR "gcovr not found! Aborting...")
+ENDIF() # NOT GCOVR_PATH
+
+ADD_CUSTOM_TARGET(${_targetname}
+
+# Run tests
+${_testrunner} ${ARGV3}
+
+# Running gcovr
+COMMAND ${GCOVR_PATH} -x -r ${CMAKE_SOURCE_DIR} -e '${CMAKE_SOURCE_DIR}/tests/' -o ${_outputname}.xml
+WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+COMMENT "Running gcovr to produce Cobertura code coverage report."
+)
+
+# Show info where to find the report
+ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD
+COMMAND ;
+COMMENT "Cobertura code coverage report saved in ${_outputname}.xml."
+)
+
+ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE_COBERTURA
diff --git a/lib/cmake-coverage/LICENSE b/lib/cmake-coverage/LICENSE
new file mode 100644
index 000000000..36b7cd93c
--- /dev/null
+++ b/lib/cmake-coverage/LICENSE
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/lib/jsoncpp/src/lib_json/json_reader.cpp b/lib/jsoncpp/src/lib_json/json_reader.cpp
index e9d6b88d2..fb8421de9 100644
--- a/lib/jsoncpp/src/lib_json/json_reader.cpp
+++ b/lib/jsoncpp/src/lib_json/json_reader.cpp
@@ -623,7 +623,7 @@ Reader::decodeDouble( Token &token )
const int bufferSize = 32;
int count;
int length = int(token.end_ - token.start_);
- if ( length <= bufferSize )
+ if ( length < bufferSize )
{
Char buffer[bufferSize];
memcpy( buffer, token.start_, length );
diff --git a/lib/lua/CMakeLists.txt b/lib/lua/CMakeLists.txt
index db112d557..6e5e0f565 100644
--- a/lib/lua/CMakeLists.txt
+++ b/lib/lua/CMakeLists.txt
@@ -20,6 +20,12 @@ endif()
# Lua needs to be linked dynamically on Windows and statically on *nix, so that LuaRocks work
if (WIN32)
+
+ #for compiliers other than msvc we need to tell lua that its building as a dll
+ if (NOT MSVC)
+ add_flags_cxx(-DLUA_BUILD_AS_DLL=1)
+ endif()
+
add_library(lua SHARED ${SOURCE})
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer)
diff --git a/lib/polarssl.cmake b/lib/polarssl.cmake
index d57cc9220..91f0fa145 100644
--- a/lib/polarssl.cmake
+++ b/lib/polarssl.cmake
@@ -1,5 +1,11 @@
if(NOT TARGET polarssl)
message("including polarssl")
- add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/polarssl/ ${CMAKE_CURRENT_BINARY_DIR}/lib/polarssl EXCLUDE_FROM_ALL )
+ if (SELF_TEST)
+ set(ENABLE_TESTING OFF CACHE BOOL "Disable tests")
+ set(ENABLE_PROGRAMS OFF CACHE BOOL "Disable programs")
+ add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/polarssl/ ${CMAKE_CURRENT_BINARY_DIR}/lib/polarssl)
+ else()
+ add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/polarssl/ ${CMAKE_CURRENT_BINARY_DIR}/lib/polarssl EXCLUDE_FROM_ALL)
+ endif()
endif()
diff --git a/lib/sqlite/CMakeLists.txt b/lib/sqlite/CMakeLists.txt
index 0815127ef..9add2280b 100644
--- a/lib/sqlite/CMakeLists.txt
+++ b/lib/sqlite/CMakeLists.txt
@@ -17,6 +17,10 @@ if (WIN32)
source_group("Sources" FILES ${SOURCE})
endif()
+# FreeBSD requires us to define this to get POSIX 2001 standard
+if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
+ add_flags_cxx(-D__POSIX_VISIBLE=200112)
+endif()
add_library(sqlite ${SOURCE})
diff --git a/lib/tolua++/src/bin/basic_lua.h b/lib/tolua++/src/bin/basic_lua.h
index effd79ee9..913ebeef8 100644
--- a/lib/tolua++/src/bin/basic_lua.h
+++ b/lib/tolua++/src/bin/basic_lua.h
@@ -688,73 +688,80 @@ static const unsigned char lua_basic_lua[] = {
0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x68,
0x6f, 0x6f, 0x6b, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x09, 0x72, 0x65,
0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e,
- 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a,
- 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x75, 0x73, 0x74,
- 0x6f, 0x6d, 0x20, 0x70, 0x75, 0x73, 0x68, 0x65, 0x72, 0x73, 0x0a, 0x0a,
- 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
- 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x69, 0x73,
+ 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x20,
+ 0x20, 0x2d, 0x2d, 0x20, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x61,
+ 0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20,
+ 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x65, 0x6e, 0x64,
+ 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, 0x69, 0x70,
+ 0x6c, 0x65, 0x2d, 0x64, 0x6f, 0x74, 0x2d, 0x70, 0x61, 0x72, 0x65, 0x6e,
+ 0x74, 0x68, 0x65, 0x73, 0x69, 0x73, 0x20, 0x64, 0x75, 0x65, 0x20, 0x74,
+ 0x6f, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x70, 0x61, 0x72, 0x73, 0x69, 0x6e,
+ 0x67, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x75,
+ 0x73, 0x74, 0x6f, 0x6d, 0x20, 0x70, 0x75, 0x73, 0x68, 0x65, 0x72, 0x73,
+ 0x0a, 0x0a, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f,
+ 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73,
+ 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75,
+ 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d,
+ 0x0a, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x75, 0x73, 0x68,
0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d,
- 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x3d,
- 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63,
- 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a,
- 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66,
- 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b,
- 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x73, 0x5f, 0x66,
- 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b,
- 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x66,
- 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b,
- 0x7d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68,
- 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x66, 0x75, 0x6e,
- 0x63, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20,
- 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f,
- 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b,
- 0x74, 0x5d, 0x0a, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x63,
- 0x6c, 0x61, 0x73, 0x73, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x69, 0x66,
- 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73,
- 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
- 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75,
- 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x74, 0x79,
- 0x70, 0x65, 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09,
- 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f,
- 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b,
- 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x62, 0x74, 0x79, 0x70, 0x65, 0x5d,
- 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72,
- 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66,
- 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f,
- 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
- 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
- 0x20, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74,
- 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x73,
- 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74,
- 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x75, 0x73, 0x68,
- 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20,
- 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75,
- 0x73, 0x68, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a,
- 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
- 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e,
- 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x72, 0x65,
- 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e,
+ 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x73,
+ 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d,
+ 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x6f,
+ 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d,
+ 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66,
+ 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x61, 0x72,
+ 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x66,
+ 0x75, 0x6e, 0x63, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61,
+ 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x67,
+ 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65,
+ 0x73, 0x5b, 0x74, 0x5d, 0x0a, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65,
+ 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09,
+ 0x69, 0x66, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, 0x61,
+ 0x73, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, 0x74, 0x68, 0x65,
+ 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
+ 0x66, 0x75, 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e,
+ 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
+ 0x09, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x67,
+ 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65,
+ 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x62, 0x74, 0x79, 0x70,
+ 0x65, 0x5d, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74,
+ 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a,
+ 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65,
+ 0x74, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75,
+ 0x72, 0x6e, 0x20, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72,
0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65,
- 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x6f,
- 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20,
- 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f,
- 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e,
- 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
- 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74,
- 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x5f,
- 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x74, 0x68, 0x65,
- 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22,
- 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e,
- 0x20, 0x74, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74,
- 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63,
- 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20,
- 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28,
- 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x73, 0x5f,
- 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x6f,
- 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x75,
- 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64,
- 0x0a
+ 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x75,
+ 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f,
+ 0x70, 0x75, 0x73, 0x68, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65,
+ 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x66,
+ 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09,
+ 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x74, 0x6f, 0x5f, 0x66,
+ 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20,
+ 0x6f, 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61,
+ 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f,
+ 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f,
+ 0x74, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a,
+ 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x69, 0x66,
+ 0x20, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x74,
+ 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
+ 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20,
+ 0x2e, 0x2e, 0x20, 0x74, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72,
+ 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75,
+ 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f,
+ 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73,
+ 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69,
+ 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29,
+ 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69,
+ 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65,
+ 0x6e, 0x64, 0x0a
};
-unsigned int lua_basic_lua_len = 9073;
+unsigned int lua_basic_lua_len = 9159;
diff --git a/lib/tolua++/src/bin/declaration_lua.h b/lib/tolua++/src/bin/declaration_lua.h
index 28deb4f60..a562a7779 100644
--- a/lib/tolua++/src/bin/declaration_lua.h
+++ b/lib/tolua++/src/bin/declaration_lua.h
@@ -1154,7 +1154,7 @@ static const unsigned char lua_declaration_lua[] = {
0x72, 0x6d, 0x3a, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65,
0x2a, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61,
0x6c, 0x20, 0x73, 0x31, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28,
- 0x73, 0x2c, 0x22, 0x28, 0x25, 0x62, 0x5c, 0x5b, 0x5c, 0x5d, 0x29, 0x22,
+ 0x73, 0x2c, 0x22, 0x28, 0x25, 0x62, 0x25, 0x5b, 0x25, 0x5d, 0x29, 0x22,
0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6e,
0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x73, 0x75,
0x62, 0x28, 0x6e, 0x2c, 0x27, 0x25, 0x2a, 0x27, 0x2c, 0x27, 0x5c, 0x31,
diff --git a/lib/tolua++/src/bin/lua/_driver.lua b/lib/tolua++/src/bin/lua/_driver.lua
new file mode 100644
index 000000000..21db96098
--- /dev/null
+++ b/lib/tolua++/src/bin/lua/_driver.lua
@@ -0,0 +1,93 @@
+
+-- Allow debugging by ZBS, if run under the IDE:
+local mobdebugfound, mobdebug = pcall(require, "mobdebug")
+if mobdebugfound then mobdebug.start() end
+
+-- The list of valid arguments that the ToLua scripts can process:
+local KnownArgs = {
+ ['v'] = true,
+ ['h'] = true,
+ ['p'] = true,
+ ['P'] = true,
+ ['o'] = true,
+ ['n'] = true,
+ ['H'] = true,
+ ['S'] = true,
+ ['1'] = true,
+ ['L'] = true,
+ ['D'] = true,
+ ['W'] = true,
+ ['C'] = true,
+ ['E'] = true,
+ ['t'] = true,
+ ['q'] = true,
+}
+
+
+
+
+
+-- The flags table used by ToLua scripts, to be filled from the cmdline params:
+flags = {}
+
+-- Te extra parameters used by ToLua scripts:
+_extra_parameters = {}
+
+-- ToLua version required by the scripts:
+TOLUA_VERSION = "tolua++-1.0.92"
+
+-- Lua version used by ToLua, required by the scripts:
+TOLUA_LUA_VERSION = "Lua 5.1"
+
+
+
+
+
+
+-- Process the cmdline params into the flags table:
+local args = arg or {}
+local argc = #args
+local i = 1
+while (i <= argc) do
+ local argv = args[i]
+ if (argv:sub(1, 1) == "-") then
+ if (KnownArgs[argv:sub(2)]) then
+ print("Setting flag \"" .. argv:sub(2) .. "\" to \"" .. args[i + 1] .. "\".")
+ flags[argv:sub(2)] = args[i + 1]
+ i = i + 1
+ else
+ print("Unknown option (" .. i .. "): " .. argv)
+ print("Aborting.")
+ os.exit(1)
+ end
+ else
+ print("Setting flag \"f\" to \"" .. argv .. "\".")
+ flags['f'] = argv
+ break
+ end
+ i = i + 1
+end
+
+-- Get the path where the scripts are located:
+path = args[0] or ""
+local index = path:find("/[^/]*$")
+if (index == nil) then
+ index = path:find("\\[^\\]*$")
+end
+if (index ~= nil) then
+ path = path:sub(1, index)
+end
+
+print("path is set to \"" .. path .. "\".")
+
+
+
+
+
+-- Call the ToLua processor:
+dofile(path .. "all.lua")
+
+
+
+
+
diff --git a/lib/tolua++/src/bin/lua/basic.lua b/lib/tolua++/src/bin/lua/basic.lua
index 4bff5276b..7b401d638 100644
--- a/lib/tolua++/src/bin/lua/basic.lua
+++ b/lib/tolua++/src/bin/lua/basic.lua
@@ -383,7 +383,7 @@ end
-- called to output an error message
function output_error_hook(...)
- return string.format(...)
+ return string.format(...) -- Note that this line must not end in the triple-dot-parenthesis due to pre-parsing
end
-- custom pushers
diff --git a/lib/tolua++/src/bin/lua/compat-5.1.lua b/lib/tolua++/src/bin/lua/compat-5.1.lua
index 7a2c60b69..c591592a6 100644
--- a/lib/tolua++/src/bin/lua/compat-5.1.lua
+++ b/lib/tolua++/src/bin/lua/compat-5.1.lua
@@ -18,17 +18,16 @@ local function pp_dofile(path)
local ret = file:read("*a")
file:close()
- ret = string.gsub(ret, "%.%.%.%s*%)", "...) local arg = {n=select('#', ...), ...};")
-
+ ret = string.gsub(ret, "%.%.%.%s*%)$", "...) local arg = {n=select('#', ...), ...};")
+
loaded = true
return ret
end
end
- local f = load(getfile, path)
+ local f, err = load(getfile, path)
if not f then
-
- error("error loading file "..path)
+ error("error loading file " .. path .. ": " .. err)
end
return f()
end
diff --git a/lib/tolua++/src/bin/lua/declaration.lua b/lib/tolua++/src/bin/lua/declaration.lua
index 26ceeba22..3ec6e144f 100644
--- a/lib/tolua++/src/bin/lua/declaration.lua
+++ b/lib/tolua++/src/bin/lua/declaration.lua
@@ -524,7 +524,7 @@ function Declaration (s,kind,is_parameter)
end
-- check the form: mod type* name
- local s1 = gsub(s,"(%b\[\])",function (n) return gsub(n,'%*','\1') end)
+ local s1 = gsub(s,"(%b%[%])",function (n) return gsub(n,'%*','\1') end)
t = split_c_tokens(s1,'%*')
if t.n == 2 then
t[2] = gsub(t[2],'\1','%*') -- restore * in dimension expression
diff --git a/lib/tolua++/src/bin/lua/feature.lua b/lib/tolua++/src/bin/lua/feature.lua
index 042b5d28e..14f01d325 100644
--- a/lib/tolua++/src/bin/lua/feature.lua
+++ b/lib/tolua++/src/bin/lua/feature.lua
@@ -132,7 +132,7 @@ function classFeature:cfuncname (n)
if not fname or fname == '' then
fname = self.name
end
- n = string.gsub(n..'_'.. (fname), "[<>:, \.%*&]", "_")
+ n = string.gsub(n..'_'.. (fname), "[<>:, %.%*&]", "_")
return n
end
diff --git a/src/AllocationPool.h b/src/AllocationPool.h
new file mode 100644
index 000000000..5d749a79e
--- /dev/null
+++ b/src/AllocationPool.h
@@ -0,0 +1,109 @@
+
+#pragma once
+
+#include <memory>
+
+template<class T>
+class cAllocationPool
+{
+public:
+ class cStarvationCallbacks
+ {
+ public:
+ virtual ~cStarvationCallbacks() {}
+
+ /** Is called when the reserve buffer starts to be used **/
+ virtual void OnStartUsingReserve() = 0;
+
+ /** Is called once the reserve buffer has returned to normal size **/
+ virtual void OnEndUsingReserve() = 0;
+
+ /** Is called when the allocation pool is unable to allocate memory. Will be repeatedly
+ called if it does not free sufficient memory **/
+ virtual void OnOutOfReserve() = 0;
+ };
+
+ virtual ~cAllocationPool() {}
+
+ /** Allocates a pointer to T **/
+ virtual T * Allocate() = 0;
+
+ /** Frees the pointer passed in a_ptr, invalidating it **/
+ virtual void Free(T * a_ptr) = 0;
+};
+
+/** Allocates memory storing unused elements in a linked list. Keeps at least NumElementsInReserve
+elements in the list unless malloc fails so that the program has a reserve to handle OOM.**/
+template<class T, size_t NumElementsInReserve>
+class cListAllocationPool : public cAllocationPool<T>
+{
+ public:
+
+ cListAllocationPool(std::auto_ptr<typename cAllocationPool<T>::cStarvationCallbacks> a_Callbacks) :
+ m_Callbacks(a_Callbacks)
+ {
+ for (size_t i = 0; i < NumElementsInReserve; i++)
+ {
+ void * space = malloc(sizeof(T));
+ if (space == NULL)
+ {
+ m_Callbacks->OnStartUsingReserve();
+ break;
+ }
+ m_FreeList.push_front(space);
+ }
+ }
+
+ virtual ~cListAllocationPool()
+ {
+ while (!m_FreeList.empty())
+ {
+ free (m_FreeList.front());
+ m_FreeList.pop_front();
+ }
+ }
+
+ virtual T * Allocate() override
+ {
+ if (m_FreeList.size() <= NumElementsInReserve)
+ {
+ void * space = malloc(sizeof(T));
+ if (space != NULL)
+ {
+ return new(space) T;
+ }
+ else if (m_FreeList.size() == NumElementsInReserve)
+ {
+ m_Callbacks->OnStartUsingReserve();
+ }
+ else if (m_FreeList.empty())
+ {
+ m_Callbacks->OnOutOfReserve();
+ // Try again until the memory is avalable
+ return Allocate();
+ }
+ }
+ // placement new, used to initalize the object
+ T * ret = new (m_FreeList.front()) T;
+ m_FreeList.pop_front();
+ return ret;
+ }
+ virtual void Free(T * a_ptr) override
+ {
+ if (a_ptr == NULL)
+ {
+ return;
+ }
+ // placement destruct.
+ a_ptr->~T();
+ m_FreeList.push_front(a_ptr);
+ if (m_FreeList.size() == NumElementsInReserve)
+ {
+ m_Callbacks->OnEndUsingReserve();
+ }
+ }
+
+ private:
+ std::list<void *> m_FreeList;
+ std::auto_ptr<typename cAllocationPool<T>::cStarvationCallbacks> m_Callbacks;
+};
diff --git a/src/Bindings/.gitignore b/src/Bindings/.gitignore
new file mode 100644
index 000000000..af8aa76fa
--- /dev/null
+++ b/src/Bindings/.gitignore
@@ -0,0 +1 @@
+lua51.dll
diff --git a/src/Bindings/AllToLua_lua.bat.bat b/src/Bindings/AllToLua_lua.bat.bat
new file mode 100644
index 000000000..81c738f32
--- /dev/null
+++ b/src/Bindings/AllToLua_lua.bat.bat
@@ -0,0 +1,27 @@
+
+:: AllToLua_Lua.bat
+:: This scripts updates the automatically-generates Lua bindings in Bindings.cpp / Bindings.h
+:: When called without any parameters, it will pause for a keypress at the end
+:: Call with any parameter to disable the wait (for buildserver use)
+:: This script assumes "lua" executable to be in PATH, it uses a pure-lua implementation of the ToLua processor
+
+@echo off
+
+
+
+
+
+:: Regenerate the files:
+echo Regenerating LUA bindings . . .
+lua ..\..\lib\tolua++\src\bin\lua\_driver.lua -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
+
+
+
+
+: Wait for keypress, if no param given:
+echo.
+if %ALLTOLUA_WAIT%N == N pause
+
+
+
+
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp
index a33459ad2..7a5ed1425 100644
--- a/src/Bindings/LuaState.cpp
+++ b/src/Bindings/LuaState.cpp
@@ -372,11 +372,11 @@ void cLuaState::Push(const AStringVector & a_Vector)
-void cLuaState::PushUserType(void * a_Object, const char * a_Type)
+void cLuaState::Push(const cCraftingGrid * a_Grid)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_Object, a_Type);
+ tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid");
m_NumCurrentFunctionArgs += 1;
}
@@ -384,11 +384,11 @@ void cLuaState::PushUserType(void * a_Object, const char * a_Type)
-void cLuaState::Push(int a_Value)
+void cLuaState::Push(const cCraftingRecipe * a_Recipe)
{
ASSERT(IsValid());
- tolua_pushnumber(m_LuaState, a_Value);
+ tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe");
m_NumCurrentFunctionArgs += 1;
}
@@ -396,11 +396,11 @@ void cLuaState::Push(int a_Value)
-void cLuaState::Push(double a_Value)
+void cLuaState::Push(const char * a_Value)
{
ASSERT(IsValid());
- tolua_pushnumber(m_LuaState, a_Value);
+ tolua_pushstring(m_LuaState, a_Value);
m_NumCurrentFunctionArgs += 1;
}
@@ -408,11 +408,11 @@ void cLuaState::Push(double a_Value)
-void cLuaState::Push(const char * a_Value)
+void cLuaState::Push(const cItems & a_Items)
{
ASSERT(IsValid());
- tolua_pushstring(m_LuaState, a_Value);
+ tolua_pushusertype(m_LuaState, (void *)&a_Items, "cItems");
m_NumCurrentFunctionArgs += 1;
}
@@ -420,11 +420,11 @@ void cLuaState::Push(const char * a_Value)
-void cLuaState::Push(bool a_Value)
+void cLuaState::Push(const cPlayer * a_Player)
{
ASSERT(IsValid());
- tolua_pushboolean(m_LuaState, a_Value ? 1 : 0);
+ tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer");
m_NumCurrentFunctionArgs += 1;
}
@@ -432,11 +432,11 @@ void cLuaState::Push(bool a_Value)
-void cLuaState::Push(cWorld * a_World)
+void cLuaState::Push(const HTTPRequest * a_Request)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_World, "cWorld");
+ tolua_pushusertype(m_LuaState, (void *)a_Request, "HTTPRequest");
m_NumCurrentFunctionArgs += 1;
}
@@ -444,11 +444,11 @@ void cLuaState::Push(cWorld * a_World)
-void cLuaState::Push(cPlayer * a_Player)
+void cLuaState::Push(const HTTPTemplateRequest * a_Request)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
+ tolua_pushusertype(m_LuaState, (void *)a_Request, "HTTPTemplateRequest");
m_NumCurrentFunctionArgs += 1;
}
@@ -456,11 +456,11 @@ void cLuaState::Push(cPlayer * a_Player)
-void cLuaState::Push(const cPlayer * a_Player)
+void cLuaState::Push(const Vector3d & a_Vector)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer");
+ tolua_pushusertype(m_LuaState, (void *)&a_Vector, "Vector3d");
m_NumCurrentFunctionArgs += 1;
}
@@ -468,11 +468,11 @@ void cLuaState::Push(const cPlayer * a_Player)
-void cLuaState::Push(cEntity * a_Entity)
+void cLuaState::Push(bool a_Value)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_Entity, "cEntity");
+ tolua_pushboolean(m_LuaState, a_Value ? 1 : 0);
m_NumCurrentFunctionArgs += 1;
}
@@ -480,11 +480,11 @@ void cLuaState::Push(cEntity * a_Entity)
-void cLuaState::Push(cProjectileEntity * a_ProjectileEntity)
+void cLuaState::Push(cBlockEntity * a_BlockEntity)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_ProjectileEntity, "cProjectileEntity");
+ tolua_pushusertype(m_LuaState, a_BlockEntity, "cBlockEntity");
m_NumCurrentFunctionArgs += 1;
}
@@ -492,11 +492,47 @@ void cLuaState::Push(cProjectileEntity * a_ProjectileEntity)
-void cLuaState::Push(cMonster * a_Monster)
+void cLuaState::Push(cChunkDesc * a_ChunkDesc)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_Monster, "cMonster");
+ tolua_pushusertype(m_LuaState, a_ChunkDesc, "cChunkDesc");
+ m_NumCurrentFunctionArgs += 1;
+}
+
+
+
+
+
+void cLuaState::Push(cClientHandle * a_Client)
+{
+ ASSERT(IsValid());
+
+ tolua_pushusertype(m_LuaState, a_Client, "cClientHandle");
+ m_NumCurrentFunctionArgs += 1;
+}
+
+
+
+
+
+void cLuaState::Push(cEntity * a_Entity)
+{
+ ASSERT(IsValid());
+
+ tolua_pushusertype(m_LuaState, a_Entity, "cEntity");
+ m_NumCurrentFunctionArgs += 1;
+}
+
+
+
+
+
+void cLuaState::Push(cHopperEntity * a_Hopper)
+{
+ ASSERT(IsValid());
+
+ tolua_pushusertype(m_LuaState, a_Hopper, "cHopperEntity");
m_NumCurrentFunctionArgs += 1;
}
@@ -528,11 +564,11 @@ void cLuaState::Push(cItems * a_Items)
-void cLuaState::Push(const cItems & a_Items)
+void cLuaState::Push(cMonster * a_Monster)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, (void *)&a_Items, "cItems");
+ tolua_pushusertype(m_LuaState, a_Monster, "cMonster");
m_NumCurrentFunctionArgs += 1;
}
@@ -540,11 +576,11 @@ void cLuaState::Push(const cItems & a_Items)
-void cLuaState::Push(cClientHandle * a_Client)
+void cLuaState::Push(cPickup * a_Pickup)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_Client, "cClientHandle");
+ tolua_pushusertype(m_LuaState, a_Pickup, "cPickup");
m_NumCurrentFunctionArgs += 1;
}
@@ -552,11 +588,11 @@ void cLuaState::Push(cClientHandle * a_Client)
-void cLuaState::Push(cPickup * a_Pickup)
+void cLuaState::Push(cPlayer * a_Player)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_Pickup, "cPickup");
+ tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
m_NumCurrentFunctionArgs += 1;
}
@@ -564,11 +600,11 @@ void cLuaState::Push(cPickup * a_Pickup)
-void cLuaState::Push(cChunkDesc * a_ChunkDesc)
+void cLuaState::Push(cPluginLua * a_Plugin)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_ChunkDesc, "cChunkDesc");
+ tolua_pushusertype(m_LuaState, a_Plugin, "cPluginLua");
m_NumCurrentFunctionArgs += 1;
}
@@ -576,11 +612,11 @@ void cLuaState::Push(cChunkDesc * a_ChunkDesc)
-void cLuaState::Push(const cCraftingGrid * a_Grid)
+void cLuaState::Push(cProjectileEntity * a_ProjectileEntity)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid");
+ tolua_pushusertype(m_LuaState, a_ProjectileEntity, "cProjectileEntity");
m_NumCurrentFunctionArgs += 1;
}
@@ -588,11 +624,11 @@ void cLuaState::Push(const cCraftingGrid * a_Grid)
-void cLuaState::Push(const cCraftingRecipe * a_Recipe)
+void cLuaState::Push(cTNTEntity * a_TNTEntity)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe");
+ tolua_pushusertype(m_LuaState, a_TNTEntity, "cTNTEntity");
m_NumCurrentFunctionArgs += 1;
}
@@ -600,11 +636,11 @@ void cLuaState::Push(const cCraftingRecipe * a_Recipe)
-void cLuaState::Push(TakeDamageInfo * a_TDI)
+void cLuaState::Push(cWebAdmin * a_WebAdmin)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_TDI, "TakeDamageInfo");
+ tolua_pushusertype(m_LuaState, a_WebAdmin, "cWebAdmin");
m_NumCurrentFunctionArgs += 1;
}
@@ -624,11 +660,11 @@ void cLuaState::Push(cWindow * a_Window)
-void cLuaState::Push(cPluginLua * a_Plugin)
+void cLuaState::Push(cWorld * a_World)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_Plugin, "cPluginLua");
+ tolua_pushusertype(m_LuaState, a_World, "cWorld");
m_NumCurrentFunctionArgs += 1;
}
@@ -636,11 +672,11 @@ void cLuaState::Push(cPluginLua * a_Plugin)
-void cLuaState::Push(const HTTPRequest * a_Request)
+void cLuaState::Push(double a_Value)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, (void *)a_Request, "HTTPRequest");
+ tolua_pushnumber(m_LuaState, a_Value);
m_NumCurrentFunctionArgs += 1;
}
@@ -648,11 +684,11 @@ void cLuaState::Push(const HTTPRequest * a_Request)
-void cLuaState::Push(cWebAdmin * a_WebAdmin)
+void cLuaState::Push(int a_Value)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_WebAdmin, "cWebAdmin");
+ tolua_pushnumber(m_LuaState, a_Value);
m_NumCurrentFunctionArgs += 1;
}
@@ -660,11 +696,11 @@ void cLuaState::Push(cWebAdmin * a_WebAdmin)
-void cLuaState::Push(const HTTPTemplateRequest * a_Request)
+void cLuaState::Push(TakeDamageInfo * a_TDI)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, (void *)a_Request, "HTTPTemplateRequest");
+ tolua_pushusertype(m_LuaState, a_TDI, "TakeDamageInfo");
m_NumCurrentFunctionArgs += 1;
}
@@ -672,11 +708,11 @@ void cLuaState::Push(const HTTPTemplateRequest * a_Request)
-void cLuaState::Push(cTNTEntity * a_TNTEntity)
+void cLuaState::Push(Vector3i * a_Vector)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_TNTEntity, "cTNTEntity");
+ tolua_pushusertype(m_LuaState, a_Vector, "Vector3i");
m_NumCurrentFunctionArgs += 1;
}
@@ -684,11 +720,11 @@ void cLuaState::Push(cTNTEntity * a_TNTEntity)
-void cLuaState::Push(Vector3i * a_Vector)
+void cLuaState::Push(Vector3d * a_Vector)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_Vector, "Vector3i");
+ tolua_pushusertype(m_LuaState, a_Vector, "Vector3d");
m_NumCurrentFunctionArgs += 1;
}
@@ -715,23 +751,12 @@ void cLuaState::Push(void * a_Ptr)
-void cLuaState::Push(cHopperEntity * a_Hopper)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_Hopper, "cHopperEntity");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-void cLuaState::Push(cBlockEntity * a_BlockEntity)
+void cLuaState::PushUserType(void * a_Object, const char * a_Type)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_BlockEntity, "cBlockEntity");
+ tolua_pushusertype(m_LuaState, a_Object, a_Type);
m_NumCurrentFunctionArgs += 1;
}
diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h
index b9ca2f29b..066390e39 100644
--- a/src/Bindings/LuaState.h
+++ b/src/Bindings/LuaState.h
@@ -173,38 +173,42 @@ public:
/** Returns true if a_FunctionName is a valid Lua function that can be called */
bool HasFunction(const char * a_FunctionName);
- // Push a value onto the stack
+ // Push a const value onto the stack (keep alpha-sorted):
void Push(const AString & a_String);
void Push(const AStringVector & a_Vector);
- void Push(int a_Value);
- void Push(double a_Value);
+ void Push(const cCraftingGrid * a_Grid);
+ void Push(const cCraftingRecipe * a_Recipe);
void Push(const char * a_Value);
- void Push(bool a_Value);
- void Push(cWorld * a_World);
- void Push(cPlayer * a_Player);
+ void Push(const cItems & a_Items);
void Push(const cPlayer * a_Player);
+ void Push(const HTTPRequest * a_Request);
+ void Push(const HTTPTemplateRequest * a_Request);
+ void Push(const Vector3d & a_Vector);
+
+ // Push a value onto the stack (keep alpha-sorted):
+ void Push(bool a_Value);
+ void Push(cBlockEntity * a_BlockEntity);
+ void Push(cChunkDesc * a_ChunkDesc);
+ void Push(cClientHandle * a_ClientHandle);
void Push(cEntity * a_Entity);
- void Push(cProjectileEntity * a_ProjectileEntity);
- void Push(cMonster * a_Monster);
+ void Push(cHopperEntity * a_Hopper);
void Push(cItem * a_Item);
void Push(cItems * a_Items);
- void Push(const cItems & a_Items);
- void Push(cClientHandle * a_ClientHandle);
+ void Push(cMonster * a_Monster);
void Push(cPickup * a_Pickup);
- void Push(cChunkDesc * a_ChunkDesc);
- void Push(const cCraftingGrid * a_Grid);
- void Push(const cCraftingRecipe * a_Recipe);
- void Push(TakeDamageInfo * a_TDI);
- void Push(cWindow * a_Window);
+ void Push(cPlayer * a_Player);
void Push(cPluginLua * a_Plugin);
- void Push(const HTTPRequest * a_Request);
- void Push(cWebAdmin * a_WebAdmin);
- void Push(const HTTPTemplateRequest * a_Request);
+ void Push(cProjectileEntity * a_ProjectileEntity);
void Push(cTNTEntity * a_TNTEntity);
+ void Push(cWebAdmin * a_WebAdmin);
+ void Push(cWindow * a_Window);
+ void Push(cWorld * a_World);
+ void Push(double a_Value);
+ void Push(int a_Value);
+ void Push(TakeDamageInfo * a_TDI);
+ void Push(Vector3d * a_Vector);
void Push(Vector3i * a_Vector);
void Push(void * a_Ptr);
- void Push(cHopperEntity * a_Hopper);
- void Push(cBlockEntity * a_BlockEntity);
/** Retrieve value at a_StackPos, if it is a valid bool. If not, a_Value is unchanged */
void GetStackValue(int a_StackPos, bool & a_Value);
diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp
index 10e560ac0..acfd6f4f8 100644
--- a/src/Bindings/ManualBindings.cpp
+++ b/src/Bindings/ManualBindings.cpp
@@ -2538,6 +2538,37 @@ static int tolua_cBlockArea_GetSize(lua_State * tolua_S)
+static int tolua_cBlockArea_GetCoordRange(lua_State * tolua_S)
+{
+ // function cBlockArea::GetCoordRange()
+ // Returns all three sizes of the area, miuns one, so that they represent the maximum coord value
+ // Exported manually because there's no direct C++ equivalent,
+ // plus tolua would generate extra input params for the outputs
+
+ cLuaState L(tolua_S);
+ if (!L.CheckParamUserType(1, "cBlockArea"))
+ {
+ return 0;
+ }
+
+ cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL);
+ if (self == NULL)
+ {
+ tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetSize'", NULL);
+ return 0;
+ }
+
+ // Push the three origin coords:
+ lua_pushnumber(tolua_S, self->GetSizeX() - 1);
+ lua_pushnumber(tolua_S, self->GetSizeY() - 1);
+ lua_pushnumber(tolua_S, self->GetSizeZ() - 1);
+ return 3;
+}
+
+
+
+
+
static int tolua_cBlockArea_LoadFromSchematicFile(lua_State * tolua_S)
{
// function cBlockArea::LoadFromSchematicFile
@@ -2864,8 +2895,8 @@ static int tolua_cCompositeChat_SetMessageType(lua_State * tolua_S)
}
// Set the type:
- int MessageType;
- L.GetStackValue(1, MessageType);
+ int MessageType = mtCustom;
+ L.GetStackValue(2, MessageType);
self->SetMessageType((eMessageType)MessageType);
// Cut away everything from the stack except for the cCompositeChat instance; return that:
@@ -2926,6 +2957,7 @@ void ManualBindings::Bind(lua_State * tolua_S)
tolua_beginmodule(tolua_S, "cBlockArea");
tolua_function(tolua_S, "GetBlockTypeMeta", tolua_cBlockArea_GetBlockTypeMeta);
+ tolua_function(tolua_S, "GetCoordRange", tolua_cBlockArea_GetCoordRange);
tolua_function(tolua_S, "GetOrigin", tolua_cBlockArea_GetOrigin);
tolua_function(tolua_S, "GetRelBlockTypeMeta", tolua_cBlockArea_GetRelBlockTypeMeta);
tolua_function(tolua_S, "GetSize", tolua_cBlockArea_GetSize);
diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h
index 0bd9270c4..c6461c861 100644
--- a/src/Bindings/Plugin.h
+++ b/src/Bindings/Plugin.h
@@ -90,7 +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 OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) = 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 59708bf59..04639da60 100644
--- a/src/Bindings/PluginLua.cpp
+++ b/src/Bindings/PluginLua.cpp
@@ -1113,14 +1113,14 @@ bool cPluginLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a
-bool cPluginLua::OnProjectileHitBlock(cProjectileEntity & a_Projectile)
+bool cPluginLua::OnProjectileHitBlock(cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos)
{
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);
+ m_LuaState.Call((int)(**itr), &a_Projectile, a_BlockX, a_BlockY, a_BlockZ, a_Face, a_BlockHitPos, cLuaState::Return, res);
if (res)
{
return true;
diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h
index 3357dd87b..598e031c0 100644
--- a/src/Bindings/PluginLua.h
+++ b/src/Bindings/PluginLua.h
@@ -113,7 +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 OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) 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 fc690d4de..9bcd8e3b7 100644
--- a/src/Bindings/PluginManager.cpp
+++ b/src/Bindings/PluginManager.cpp
@@ -14,6 +14,13 @@
#include "inifile/iniFile.h"
#include "../Entities/Player.h"
+#define FIND_HOOK(a_HookName) HookMap::iterator Plugins = m_Hooks.find(a_HookName);
+#define VERIFY_HOOK \
+ if (Plugins == m_Hooks.end()) \
+ { \
+ return false; \
+ }
+
@@ -192,7 +199,7 @@ void cPluginManager::Tick(float a_Dt)
ReloadPluginsNow();
}
- HookMap::iterator Plugins = m_Hooks.find(HOOK_TICK);
+ FIND_HOOK(HOOK_TICK);
if (Plugins != m_Hooks.end())
{
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
@@ -208,11 +215,9 @@ void cPluginManager::Tick(float a_Dt)
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())
- {
- return false;
- }
+ FIND_HOOK(HOOK_BLOCK_SPREAD);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnBlockSpread(a_World, a_BlockX, a_BlockY, a_BlockZ, a_Source))
@@ -233,11 +238,9 @@ bool cPluginManager::CallHookBlockToPickups(
cItems & a_Pickups
)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_BLOCK_TO_PICKUPS);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_BLOCK_TO_PICKUPS);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnBlockToPickups(a_World, a_Digger, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_Pickups))
@@ -275,11 +278,8 @@ bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message)
return true; // Cancel sending
}
- HookMap::iterator Plugins = m_Hooks.find(HOOK_CHAT);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_CHAT);
+ VERIFY_HOOK;
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
@@ -298,11 +298,9 @@ bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message)
bool cPluginManager::CallHookChunkAvailable(cWorld * a_World, int a_ChunkX, int a_ChunkZ)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_AVAILABLE);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_CHUNK_AVAILABLE);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnChunkAvailable(a_World, a_ChunkX, a_ChunkZ))
@@ -319,11 +317,9 @@ bool cPluginManager::CallHookChunkAvailable(cWorld * a_World, int a_ChunkX, int
bool cPluginManager::CallHookChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_GENERATED);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_CHUNK_GENERATED);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnChunkGenerated(a_World, a_ChunkX, a_ChunkZ, a_ChunkDesc))
@@ -340,11 +336,9 @@ bool cPluginManager::CallHookChunkGenerated(cWorld * a_World, int a_ChunkX, int
bool cPluginManager::CallHookChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_GENERATING);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_CHUNK_GENERATING);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnChunkGenerating(a_World, a_ChunkX, a_ChunkZ, a_ChunkDesc))
@@ -361,11 +355,9 @@ bool cPluginManager::CallHookChunkGenerating(cWorld * a_World, int a_ChunkX, int
bool cPluginManager::CallHookChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_ChunkZ)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_UNLOADED);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_CHUNK_UNLOADED);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnChunkUnloaded(a_World, a_ChunkX, a_ChunkZ))
@@ -382,11 +374,9 @@ bool cPluginManager::CallHookChunkUnloaded(cWorld * a_World, int a_ChunkX, int a
bool cPluginManager::CallHookChunkUnloading(cWorld * a_World, int a_ChunkX, int a_ChunkZ)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_UNLOADING);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_CHUNK_UNLOADING);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnChunkUnloading(a_World, a_ChunkX, a_ChunkZ))
@@ -403,11 +393,9 @@ bool cPluginManager::CallHookChunkUnloading(cWorld * a_World, int a_ChunkX, int
bool cPluginManager::CallHookCollectingPickup(cPlayer * a_Player, cPickup & a_Pickup)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_COLLECTING_PICKUP);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_COLLECTING_PICKUP);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnCollectingPickup(a_Player, &a_Pickup))
@@ -424,11 +412,9 @@ bool cPluginManager::CallHookCollectingPickup(cPlayer * a_Player, cPickup & a_Pi
bool cPluginManager::CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_CRAFTING_NO_RECIPE);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_CRAFTING_NO_RECIPE);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnCraftingNoRecipe(a_Player, a_Grid, a_Recipe))
@@ -445,11 +431,9 @@ bool cPluginManager::CallHookCraftingNoRecipe(const cPlayer * a_Player, const cC
bool cPluginManager::CallHookDisconnect(cClientHandle & a_Client, const AString & a_Reason)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_DISCONNECT);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_DISCONNECT);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnDisconnect(a_Client, a_Reason))
@@ -466,11 +450,9 @@ bool cPluginManager::CallHookDisconnect(cClientHandle & a_Client, const AString
bool cPluginManager::CallHookExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_EXECUTE_COMMAND);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_EXECUTE_COMMAND);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnExecuteCommand(a_Player, a_Split))
@@ -487,11 +469,9 @@ bool cPluginManager::CallHookExecuteCommand(cPlayer * a_Player, const AStringVec
bool cPluginManager::CallHookExploded(cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_EXPLODED);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_EXPLODED);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnExploded(a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData))
@@ -508,11 +488,9 @@ bool cPluginManager::CallHookExploded(cWorld & a_World, double a_ExplosionSize,
bool cPluginManager::CallHookExploding(cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_EXPLODING);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_EXPLODING);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnExploding(a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData))
@@ -529,11 +507,9 @@ bool cPluginManager::CallHookExploding(cWorld & a_World, double & a_ExplosionSiz
bool cPluginManager::CallHookHandshake(cClientHandle * a_ClientHandle, const AString & a_Username)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_HANDSHAKE);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_HANDSHAKE);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnHandshake(a_ClientHandle, a_Username))
@@ -550,11 +526,9 @@ bool cPluginManager::CallHookHandshake(cClientHandle * a_ClientHandle, const ASt
bool cPluginManager::CallHookHopperPullingItem(cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_HOPPER_PULLING_ITEM);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_HOPPER_PULLING_ITEM);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnHopperPullingItem(a_World, a_Hopper, a_DstSlotNum, a_SrcEntity, a_SrcSlotNum))
@@ -571,11 +545,9 @@ bool cPluginManager::CallHookHopperPullingItem(cWorld & a_World, cHopperEntity &
bool cPluginManager::CallHookHopperPushingItem(cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_HOPPER_PUSHING_ITEM);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_HOPPER_PUSHING_ITEM);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnHopperPushingItem(a_World, a_Hopper, a_SrcSlotNum, a_DstEntity, a_DstSlotNum))
@@ -592,11 +564,9 @@ bool cPluginManager::CallHookHopperPushingItem(cWorld & a_World, cHopperEntity &
bool cPluginManager::CallHookKilling(cEntity & a_Victim, cEntity * a_Killer)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_KILLING);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_KILLING);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnKilling(a_Victim, a_Killer))
@@ -613,11 +583,9 @@ bool cPluginManager::CallHookKilling(cEntity & a_Victim, cEntity * a_Killer)
bool cPluginManager::CallHookLogin(cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_LOGIN);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_LOGIN);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnLogin(a_Client, a_ProtocolVersion, a_Username))
@@ -634,11 +602,9 @@ bool cPluginManager::CallHookLogin(cClientHandle * a_Client, int a_ProtocolVersi
bool cPluginManager::CallHookPlayerAnimation(cPlayer & a_Player, int a_Animation)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_ANIMATION);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_ANIMATION);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerAnimation(a_Player, a_Animation))
@@ -655,11 +621,9 @@ bool cPluginManager::CallHookPlayerAnimation(cPlayer & a_Player, int a_Animation
bool cPluginManager::CallHookPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_BREAKING_BLOCK);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_BREAKING_BLOCK);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerBreakingBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_BlockType, a_BlockMeta))
@@ -676,11 +640,9 @@ bool cPluginManager::CallHookPlayerBreakingBlock(cPlayer & a_Player, int a_Block
bool cPluginManager::CallHookPlayerBrokenBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_BROKEN_BLOCK);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_BROKEN_BLOCK);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerBrokenBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_BlockType, a_BlockMeta))
@@ -697,11 +659,9 @@ bool cPluginManager::CallHookPlayerBrokenBlock(cPlayer & a_Player, int a_BlockX,
bool cPluginManager::CallHookPlayerDestroyed(cPlayer & a_Player)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_DESTROYED);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_DESTROYED);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerDestroyed(a_Player))
@@ -718,11 +678,9 @@ bool cPluginManager::CallHookPlayerDestroyed(cPlayer & a_Player)
bool cPluginManager::CallHookPlayerEating(cPlayer & a_Player)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_EATING);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_EATING);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerEating(a_Player))
@@ -739,11 +697,9 @@ bool cPluginManager::CallHookPlayerEating(cPlayer & a_Player)
bool cPluginManager::CallHookPlayerFished(cPlayer & a_Player, const cItems a_Reward)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_FISHED);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_FISHED);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerFished(a_Player, a_Reward))
@@ -760,11 +716,9 @@ bool cPluginManager::CallHookPlayerFished(cPlayer & a_Player, const cItems a_Rew
bool cPluginManager::CallHookPlayerFishing(cPlayer & a_Player, cItems a_Reward)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_FISHING);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_FISHING);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerFishing(a_Player, a_Reward))
@@ -781,11 +735,9 @@ bool cPluginManager::CallHookPlayerFishing(cPlayer & a_Player, cItems a_Reward)
bool cPluginManager::CallHookPlayerJoined(cPlayer & a_Player)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_JOINED);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_JOINED);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerJoined(a_Player))
@@ -802,11 +754,9 @@ bool cPluginManager::CallHookPlayerJoined(cPlayer & a_Player)
bool cPluginManager::CallHookPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_LEFT_CLICK);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_LEFT_CLICK);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerLeftClick(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status))
@@ -823,11 +773,9 @@ bool cPluginManager::CallHookPlayerLeftClick(cPlayer & a_Player, int a_BlockX, i
bool cPluginManager::CallHookPlayerMoving(cPlayer & a_Player)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_MOVING);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_MOVING);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerMoved(a_Player))
@@ -844,11 +792,9 @@ bool cPluginManager::CallHookPlayerMoving(cPlayer & a_Player)
bool cPluginManager::CallHookPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_PLACED_BLOCK);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_PLACED_BLOCK);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerPlacedBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta))
@@ -865,11 +811,9 @@ bool cPluginManager::CallHookPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX,
bool cPluginManager::CallHookPlayerPlacingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_PLACING_BLOCK);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_PLACING_BLOCK);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerPlacingBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta))
@@ -886,11 +830,9 @@ bool cPluginManager::CallHookPlayerPlacingBlock(cPlayer & a_Player, int a_BlockX
bool cPluginManager::CallHookPlayerRightClick(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_RIGHT_CLICK);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_RIGHT_CLICK);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerRightClick(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
@@ -907,11 +849,9 @@ bool cPluginManager::CallHookPlayerRightClick(cPlayer & a_Player, int a_BlockX,
bool cPluginManager::CallHookPlayerRightClickingEntity(cPlayer & a_Player, cEntity & a_Entity)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_RIGHT_CLICKING_ENTITY);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_RIGHT_CLICKING_ENTITY);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerRightClickingEntity(a_Player, a_Entity))
@@ -928,11 +868,9 @@ bool cPluginManager::CallHookPlayerRightClickingEntity(cPlayer & a_Player, cEnti
bool cPluginManager::CallHookPlayerShooting(cPlayer & a_Player)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_SHOOTING);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_SHOOTING);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerShooting(a_Player))
@@ -949,11 +887,9 @@ bool cPluginManager::CallHookPlayerShooting(cPlayer & a_Player)
bool cPluginManager::CallHookPlayerSpawned(cPlayer & a_Player)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_SPAWNED);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_SPAWNED);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerSpawned(a_Player))
@@ -970,11 +906,9 @@ bool cPluginManager::CallHookPlayerSpawned(cPlayer & a_Player)
bool cPluginManager::CallHookPlayerTossingItem(cPlayer & a_Player)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_TOSSING_ITEM);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_TOSSING_ITEM);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerTossingItem(a_Player))
@@ -991,11 +925,9 @@ bool cPluginManager::CallHookPlayerTossingItem(cPlayer & a_Player)
bool cPluginManager::CallHookPlayerUsedBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_USED_BLOCK);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_USED_BLOCK);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerUsedBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta))
@@ -1012,11 +944,9 @@ bool cPluginManager::CallHookPlayerUsedBlock(cPlayer & a_Player, int a_BlockX, i
bool cPluginManager::CallHookPlayerUsedItem(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_USED_ITEM);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_USED_ITEM);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerUsedItem(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
@@ -1033,11 +963,9 @@ bool cPluginManager::CallHookPlayerUsedItem(cPlayer & a_Player, int a_BlockX, in
bool cPluginManager::CallHookPlayerUsingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_USING_BLOCK);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_USING_BLOCK);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerUsingBlock(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, a_BlockType, a_BlockMeta))
@@ -1054,11 +982,9 @@ bool cPluginManager::CallHookPlayerUsingBlock(cPlayer & a_Player, int a_BlockX,
bool cPluginManager::CallHookPlayerUsingItem(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_USING_ITEM);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLAYER_USING_ITEM);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPlayerUsingItem(a_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))
@@ -1075,11 +1001,9 @@ bool cPluginManager::CallHookPlayerUsingItem(cPlayer & a_Player, int a_BlockX, i
bool cPluginManager::CallHookPluginMessage(cClientHandle & a_Client, const AString & a_Channel, const AString & a_Message)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLUGIN_MESSAGE);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLUGIN_MESSAGE);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPluginMessage(a_Client, a_Channel, a_Message))
@@ -1096,11 +1020,9 @@ bool cPluginManager::CallHookPluginMessage(cClientHandle & a_Client, const AStri
bool cPluginManager::CallHookPluginsLoaded(void)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PLUGINS_LOADED);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PLUGINS_LOADED);
+ VERIFY_HOOK;
+
bool res = false;
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
@@ -1115,11 +1037,9 @@ bool cPluginManager::CallHookPluginsLoaded(void)
bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_POST_CRAFTING);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPostCrafting(a_Player, a_Grid, a_Recipe))
@@ -1136,11 +1056,9 @@ bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraft
bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PRE_CRAFTING);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PRE_CRAFTING);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPreCrafting(a_Player, a_Grid, a_Recipe))
@@ -1155,16 +1073,14 @@ bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCrafti
-bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile)
+bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_PROJECTILE_HIT_BLOCK);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_PROJECTILE_HIT_BLOCK);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
- if ((*itr)->OnProjectileHitBlock(a_Projectile))
+ if ((*itr)->OnProjectileHitBlock(a_Projectile, a_BlockX, a_BlockY, a_BlockZ, a_Face, a_BlockHitPos))
{
return true;
}
@@ -1178,11 +1094,9 @@ bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile
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;
- }
+ FIND_HOOK(HOOK_PROJECTILE_HIT_ENTITY);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnProjectileHitEntity(a_Projectile, a_HitEntity))
@@ -1199,11 +1113,9 @@ bool cPluginManager::CallHookProjectileHitEntity(cProjectileEntity & a_Projectil
bool cPluginManager::CallHookSpawnedEntity(cWorld & a_World, cEntity & a_Entity)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_SPAWNED_ENTITY);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_SPAWNED_ENTITY);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnSpawnedEntity(a_World, a_Entity))
@@ -1219,11 +1131,9 @@ bool cPluginManager::CallHookSpawnedEntity(cWorld & a_World, cEntity & a_Entity)
bool cPluginManager::CallHookSpawnedMonster(cWorld & a_World, cMonster & a_Monster)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_SPAWNED_MONSTER);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_SPAWNED_MONSTER);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnSpawnedMonster(a_World, a_Monster))
@@ -1239,11 +1149,9 @@ bool cPluginManager::CallHookSpawnedMonster(cWorld & a_World, cMonster & a_Monst
bool cPluginManager::CallHookSpawningEntity(cWorld & a_World, cEntity & a_Entity)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_SPAWNING_ENTITY);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_SPAWNING_ENTITY);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnSpawningEntity(a_World, a_Entity))
@@ -1260,11 +1168,9 @@ bool cPluginManager::CallHookSpawningEntity(cWorld & a_World, cEntity & a_Entity
bool cPluginManager::CallHookSpawningMonster(cWorld & a_World, cMonster & a_Monster)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_SPAWNING_MONSTER);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_SPAWNING_MONSTER);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnSpawningMonster(a_World, a_Monster))
@@ -1281,11 +1187,9 @@ bool cPluginManager::CallHookSpawningMonster(cWorld & a_World, cMonster & a_Mons
bool cPluginManager::CallHookTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TDI)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_TAKE_DAMAGE);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_TAKE_DAMAGE);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnTakeDamage(a_Receiver, a_TDI))
@@ -1302,11 +1206,9 @@ bool cPluginManager::CallHookTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a
bool cPluginManager::CallHookUpdatingSign(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_UPDATING_SIGN);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_UPDATING_SIGN);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnUpdatingSign(a_World, a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, a_Player))
@@ -1323,11 +1225,9 @@ bool cPluginManager::CallHookUpdatingSign(cWorld * a_World, int a_BlockX, int a_
bool cPluginManager::CallHookUpdatedSign(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_UPDATED_SIGN);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_UPDATED_SIGN);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnUpdatedSign(a_World, a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4, a_Player))
@@ -1344,11 +1244,9 @@ bool cPluginManager::CallHookUpdatedSign(cWorld * a_World, int a_BlockX, int a_B
bool cPluginManager::CallHookWeatherChanged(cWorld & a_World)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_WEATHER_CHANGED);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_WEATHER_CHANGED);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnWeatherChanged(a_World))
@@ -1365,11 +1263,9 @@ bool cPluginManager::CallHookWeatherChanged(cWorld & a_World)
bool cPluginManager::CallHookWeatherChanging(cWorld & a_World, eWeather & a_NewWeather)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_WEATHER_CHANGING);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_WEATHER_CHANGING);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnWeatherChanging(a_World, a_NewWeather))
@@ -1386,11 +1282,9 @@ bool cPluginManager::CallHookWeatherChanging(cWorld & a_World, eWeather & a_NewW
bool cPluginManager::CallHookWorldStarted(cWorld & a_World)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_WORLD_STARTED);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_WORLD_STARTED);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnWorldStarted(a_World))
@@ -1407,11 +1301,9 @@ bool cPluginManager::CallHookWorldStarted(cWorld & a_World)
bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt, int a_LastTickDurationMSec)
{
- HookMap::iterator Plugins = m_Hooks.find(HOOK_WORLD_TICK);
- if (Plugins == m_Hooks.end())
- {
- return false;
- }
+ FIND_HOOK(HOOK_WORLD_TICK);
+ VERIFY_HOOK;
+
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnWorldTick(a_World, a_Dt, a_LastTickDurationMSec))
diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h
index 3b3091957..be40bd2f7 100644
--- a/src/Bindings/PluginManager.h
+++ b/src/Bindings/PluginManager.h
@@ -206,7 +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 CallHookProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos);
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/Bindings/lua51.dll b/src/Bindings/lua51.dll
deleted file mode 100644
index 515cf8b30..000000000
--- a/src/Bindings/lua51.dll
+++ /dev/null
Binary files differ
diff --git a/src/Bindings/tolua++.exe b/src/Bindings/tolua++.exe
deleted file mode 100644
index ba3a6b0c7..000000000
--- a/src/Bindings/tolua++.exe
+++ /dev/null
Binary files differ
diff --git a/src/BiomeDef.h b/src/BiomeDef.h
index 67916890d..f929596e9 100644
--- a/src/BiomeDef.h
+++ b/src/BiomeDef.h
@@ -10,7 +10,7 @@
#pragma once
-
+#include "StringUtils.h"
// tolua_begin
diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp
index aff0bf9c6..4fe6cd51e 100644
--- a/src/BlockArea.cpp
+++ b/src/BlockArea.cpp
@@ -9,7 +9,7 @@
#include "OSSupport/GZipFile.h"
#include "Blocks/BlockHandler.h"
#include "Cuboid.h"
-
+#include "ChunkData.h"
@@ -309,6 +309,14 @@ void cBlockArea::Clear(void)
void cBlockArea::Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
{
+ if ((a_SizeX < 0) || (a_SizeY < 0) || (a_SizeZ < 0))
+ {
+ LOGWARNING("Creating a cBlockArea with a negative size! Call to Create ignored. (%d, %d, %d)",
+ a_SizeX, a_SizeY, a_SizeZ
+ );
+ return;
+ }
+
Clear();
int BlockCount = a_SizeX * a_SizeY * a_SizeZ;
if ((a_DataTypes & baTypes) != 0)
@@ -1835,18 +1843,12 @@ bool cBlockArea::cChunkReader::Coords(int a_ChunkX, int a_ChunkZ)
-void cBlockArea::cChunkReader::BlockTypes(const BLOCKTYPE * a_BlockTypes)
+void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer)
{
- if (m_Area.m_BlockTypes == NULL)
- {
- // Don't want BlockTypes
- return;
- }
-
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)
+
+ // SizeX, SizeZ are the dimensions 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
// BaseX, BaseZ are the offsets of the area data within the current chunk from the chunk borders
int SizeX = cChunkDef::Width;
@@ -1884,71 +1886,95 @@ void cBlockArea::cChunkReader::BlockTypes(const BLOCKTYPE * a_BlockTypes)
{
SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_Origin.z + m_Area.m_Size.z);
}
-
- for (int y = 0; y < SizeY; y++)
+
+ // Copy the blocktypes:
+ if (m_Area.m_BlockTypes != NULL)
{
- int ChunkY = MinY + y;
- int AreaY = y;
- for (int z = 0; z < SizeZ; z++)
+ for (int y = 0; y < SizeY; y++)
{
- int ChunkZ = BaseZ + z;
- int AreaZ = OffZ + z;
- for (int x = 0; x < SizeX; x++)
+ int InChunkY = MinY + y;
+ int AreaY = y;
+ for (int z = 0; z < SizeZ; z++)
{
- int ChunkX = BaseX + x;
- int AreaX = OffX + x;
- m_Area.m_BlockTypes[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = cChunkDef::GetBlock(a_BlockTypes, ChunkX, ChunkY, ChunkZ);
- } // for x
- } // for z
- } // for y
-}
-
-
-
-
+ int InChunkZ = BaseZ + z;
+ int AreaZ = OffZ + z;
+ for (int x = 0; x < SizeX; x++)
+ {
+ int InChunkX = BaseX + x;
+ int AreaX = OffX + x;
+ m_Area.m_BlockTypes[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockBuffer.GetBlock(InChunkX, InChunkY, InChunkZ);
+ } // for x
+ } // for z
+ } // for y
+ }
-void cBlockArea::cChunkReader::BlockMeta(const NIBBLETYPE * a_BlockMetas)
-{
- if (m_Area.m_BlockMetas == NULL)
+ // Copy the block metas:
+ if (m_Area.m_BlockMetas != NULL)
{
- // Don't want metas
- return;
+ for (int y = 0; y < SizeY; y++)
+ {
+ int InChunkY = MinY + y;
+ int AreaY = y;
+ for (int z = 0; z < SizeZ; z++)
+ {
+ int InChunkZ = BaseZ + z;
+ int AreaZ = OffZ + z;
+ for (int x = 0; x < SizeX; x++)
+ {
+ int InChunkX = BaseX + x;
+ int AreaX = OffX + x;
+ m_Area.m_BlockMetas[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockBuffer.GetMeta(InChunkX, InChunkY, InChunkZ);
+ } // for x
+ } // for z
+ } // for y
}
- CopyNibbles(m_Area.m_BlockMetas, a_BlockMetas);
-}
-
-
-
-
-void cBlockArea::cChunkReader::BlockLight(const NIBBLETYPE * a_BlockLight)
-{
- if (m_Area.m_BlockLight == NULL)
+ // Copy the blocklight:
+ if (m_Area.m_BlockLight != NULL)
{
- // Don't want light
- return;
+ for (int y = 0; y < SizeY; y++)
+ {
+ int InChunkY = MinY + y;
+ int AreaY = y;
+ for (int z = 0; z < SizeZ; z++)
+ {
+ int InChunkZ = BaseZ + z;
+ int AreaZ = OffZ + z;
+ for (int x = 0; x < SizeX; x++)
+ {
+ int InChunkX = BaseX + x;
+ int AreaX = OffX + x;
+ m_Area.m_BlockLight[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockBuffer.GetBlockLight(InChunkX, InChunkY, InChunkZ);
+ } // for x
+ } // for z
+ } // for y
}
- CopyNibbles(m_Area.m_BlockLight, a_BlockLight);
-}
-
-
-
-
-void cBlockArea::cChunkReader::BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight)
-{
- if (m_Area.m_BlockSkyLight == NULL)
+ // Copy the skylight:
+ if (m_Area.m_BlockSkyLight != NULL)
{
- // Don't want skylight
- return;
+ for (int y = 0; y < SizeY; y++)
+ {
+ int InChunkY = MinY + y;
+ int AreaY = y;
+ for (int z = 0; z < SizeZ; z++)
+ {
+ int InChunkZ = BaseZ + z;
+ int AreaZ = OffZ + z;
+ for (int x = 0; x < SizeX; x++)
+ {
+ int InChunkX = BaseX + x;
+ int AreaX = OffX + x;
+ m_Area.m_BlockSkyLight[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockBuffer.GetSkyLight(InChunkX, InChunkY, InChunkZ);
+ } // for x
+ } // for z
+ } // for y
}
- CopyNibbles(m_Area.m_BlockSkyLight, a_BlockSkyLight);
}
-
void cBlockArea::CropBlockTypes(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY, int a_AddMinZ, int a_SubMaxZ)
{
int NewSizeX = GetSizeX() - a_AddMinX - a_SubMaxX;
diff --git a/src/BlockArea.h b/src/BlockArea.h
index 6dba0f12e..2bd26facd 100644
--- a/src/BlockArea.h
+++ b/src/BlockArea.h
@@ -14,6 +14,7 @@
#include "ForEachChunkProvider.h"
#include "Vector3.h"
+#include "ChunkDataCallback.h"
@@ -316,11 +317,8 @@ protected:
void CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLETYPE * a_ChunkSrc);
// cChunkDataCallback overrides:
- virtual bool Coords (int a_ChunkX, int a_ChunkZ) override;
- virtual void BlockTypes (const BLOCKTYPE * a_BlockTypes) override;
- virtual void BlockMeta (const NIBBLETYPE * a_BlockMetas) override;
- virtual void BlockLight (const NIBBLETYPE * a_BlockLight) override;
- virtual void BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) override;
+ virtual bool Coords(int a_ChunkX, int a_ChunkZ) override;
+ virtual void ChunkData(const cChunkData & a_BlockTypes) override;
} ;
typedef NIBBLETYPE * NIBBLEARRAY;
diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp
index 2a32f69d9..c02c68afa 100644
--- a/src/BlockEntities/DispenserEntity.cpp
+++ b/src/BlockEntities/DispenserEntity.cpp
@@ -6,6 +6,10 @@
#include "../Simulator/FluidSimulator.h"
#include "../Chunk.h"
+#include "../World.h"
+#include "../Entities/ArrowEntity.h"
+#include "../Entities/FireChargeEntity.h"
+#include "../Entities/ProjectileEntity.h"
@@ -33,7 +37,10 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
// Would dispense into / interact with a non-loaded chunk, ignore the tick
return;
}
+
BLOCKTYPE DispBlock = DispChunk->GetBlock(DispX, DispY, DispZ);
+ int BlockX = (DispX + DispChunk->GetPosX() * cChunkDef::Width);
+ int BlockZ = (DispZ + DispChunk->GetPosZ() * cChunkDef::Width);
// Dispense the item:
switch (m_Contents.GetSlot(a_SlotNum).m_ItemType)
@@ -69,7 +76,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
}
break;
} // E_ITEM_BUCKET
-
+
case E_ITEM_WATER_BUCKET:
{
LOGD("Dispensing water bucket in slot %d; DispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(DispBlock).c_str(), DispBlock);
@@ -83,7 +90,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
}
break;
}
-
+
case E_ITEM_LAVA_BUCKET:
{
LOGD("Dispensing lava bucket in slot %d; DispBlock is \"%s\" (%d).", a_SlotNum, ItemTypeToString(DispBlock).c_str(), DispBlock);
@@ -97,7 +104,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
}
break;
}
-
+
case E_ITEM_SPAWN_EGG:
{
double MobX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width);
@@ -108,7 +115,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
}
break;
}
-
+
case E_BLOCK_TNT:
{
// Spawn a primed TNT entity, if space allows:
@@ -128,7 +135,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
if (DispChunk->GetBlock(DispX, DispY, DispZ) == E_BLOCK_AIR)
{
DispChunk->SetBlock(DispX, DispY, DispZ, E_BLOCK_FIRE, 0);
-
+
bool ItemBroke = m_Contents.DamageItem(a_SlotNum, 1);
if (ItemBroke)
@@ -138,13 +145,41 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
}
break;
}
-
+
case E_ITEM_FIRE_CHARGE:
{
- // TODO: Spawn fireball entity
+ SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkFireCharge, GetShootVector(Meta) * 20);
+ m_Contents.ChangeSlotCount(a_SlotNum, -1);
+ break;
+ }
+
+ case E_ITEM_ARROW:
+ {
+ SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkArrow, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0));
+ m_Contents.ChangeSlotCount(a_SlotNum, -1);
+ break;
+ }
+
+ case E_ITEM_SNOWBALL:
+ {
+ SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkSnowball, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0));
+ m_Contents.ChangeSlotCount(a_SlotNum, -1);
+ break;
+ }
+
+ case E_ITEM_EGG:
+ {
+ SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkEgg, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0));
+ m_Contents.ChangeSlotCount(a_SlotNum, -1);
+ break;
+ }
+
+ case E_ITEM_FIREWORK_ROCKET:
+ {
+ // TODO: Add the fireworks entity
break;
}
-
+
default:
{
DropFromSlot(a_Chunk, a_SlotNum);
@@ -157,6 +192,34 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum)
+void cDispenserEntity::SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_ShootVector)
+{
+ m_World->CreateProjectile((double)a_BlockX + 0.5, (double)a_BlockY + 0.5, (double)a_BlockZ + 0.5, a_Kind, NULL, NULL, &a_ShootVector);
+}
+
+
+
+
+
+Vector3d cDispenserEntity::GetShootVector(NIBBLETYPE a_Meta)
+{
+ switch (a_Meta)
+ {
+ case E_META_DROPSPENSER_FACING_YP: return Vector3d( 0, 1, 0);
+ case E_META_DROPSPENSER_FACING_YM: return Vector3d( 0, -1, 0);
+ case E_META_DROPSPENSER_FACING_XM: return Vector3d(-1, 0, 0);
+ case E_META_DROPSPENSER_FACING_XP: return Vector3d( 1, 0, 0);
+ case E_META_DROPSPENSER_FACING_ZM: return Vector3d( 0, 0, -1);
+ case E_META_DROPSPENSER_FACING_ZP: return Vector3d( 0, 0, 1);
+ }
+ LOGWARNING("Unhandled dispenser meta: %d", a_Meta);
+ ASSERT(!"Unhandled dispenser facing");
+ return Vector3d(0, 1, 0);
+}
+
+
+
+
bool cDispenserEntity::ScoopUpLiquid(int a_SlotNum, short a_BucketItemType)
{
@@ -167,14 +230,14 @@ bool cDispenserEntity::ScoopUpLiquid(int a_SlotNum, short a_BucketItemType)
m_Contents.SetSlot(a_SlotNum, LiquidBucket);
return true;
}
-
+
// There are stacked buckets at the selected slot, see if a full bucket will fit somewhere else
if (m_Contents.HowManyCanFit(LiquidBucket) < 1)
{
// Cannot fit into m_Contents
return false;
}
-
+
m_Contents.ChangeSlotCount(a_SlotNum, -1);
m_Contents.AddItem(LiquidBucket);
return true;
@@ -195,7 +258,7 @@ bool cDispenserEntity::EmptyLiquidBucket(BLOCKTYPE a_BlockInFront, int a_SlotNum
// Not a suitable block in front
return false;
}
-
+
cItem EmptyBucket(E_ITEM_BUCKET, 1);
if (m_Contents.GetSlot(a_SlotNum).m_ItemCount == 1)
{
@@ -203,14 +266,14 @@ bool cDispenserEntity::EmptyLiquidBucket(BLOCKTYPE a_BlockInFront, int a_SlotNum
m_Contents.SetSlot(a_SlotNum, EmptyBucket);
return true;
}
-
+
// There are full buckets stacked at this slot, check if we can fit in the empty bucket
if (m_Contents.HowManyCanFit(EmptyBucket) < 1)
{
// The empty bucket wouldn't fit into m_Contents
return false;
}
-
+
// The empty bucket fits in, remove one full bucket and add the empty one
m_Contents.ChangeSlotCount(a_SlotNum, -1);
m_Contents.AddItem(EmptyBucket);
@@ -219,4 +282,3 @@ bool cDispenserEntity::EmptyLiquidBucket(BLOCKTYPE a_BlockInFront, int a_SlotNum
-
diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h
index fdfe4e5b4..b33d08342 100644
--- a/src/BlockEntities/DispenserEntity.h
+++ b/src/BlockEntities/DispenserEntity.h
@@ -12,27 +12,37 @@ class cDispenserEntity :
public cDropSpenserEntity
{
typedef cDropSpenserEntity super;
-
+
public:
// tolua_end
-
- /// Constructor used for normal operation
+
+ /** Constructor used for normal operation */
cDispenserEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
static const char * GetClassStatic(void) { return "cDispenserEntity"; }
+ // tolua_begin
+
+ /** Spawns a projectile of the given kind in front of the dispenser with the specified speed. */
+ void SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_Speed);
+
+ /** Returns a unit vector in the cardinal direction of where the dispenser is facing. */
+ Vector3d GetShootVector(NIBBLETYPE a_Meta);
+
+ // tolua_end
+
private:
// cDropSpenser overrides:
virtual void DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) override;
-
- /// If such a bucket can fit, adds it to m_Contents and returns true
+
+ /** If such a bucket can fit, adds it to m_Contents and returns true */
bool ScoopUpLiquid(int a_SlotNum, short a_BucketItemType);
-
- /// If the a_BlockInFront is liquidable and the empty bucket can fit, does the m_Contents processing and returns true
+
+ /** If the a_BlockInFront can be washed away by liquid and the empty bucket can fit,
+ does the m_Contents processing and returns true. Returns false otherwise. */
bool EmptyLiquidBucket(BLOCKTYPE a_BlockInFront, int a_SlotNum);
} ; // tolua_export
-
diff --git a/src/BlockID.h b/src/BlockID.h
index a227245aa..272fd319d 100644
--- a/src/BlockID.h
+++ b/src/BlockID.h
@@ -790,6 +790,7 @@ enum eDimension
dimNether = -1,
dimOverworld = 0,
dimEnd = 1,
+ dimNotSet = 255, // For things that need an "indeterminate" state, such as cProtocol's LastSentDimension
} ;
diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp
index e8d9a7ec4..564b3fcca 100644
--- a/src/BlockInfo.cpp
+++ b/src/BlockInfo.cpp
@@ -341,6 +341,8 @@ void cBlockInfo::Initialize(void)
ms_Info[E_BLOCK_DANDELION ].m_IsSolid = false;
ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSolid = false;
ms_Info[E_BLOCK_END_PORTAL ].m_IsSolid = false;
+ ms_Info[E_BLOCK_FENCE ].m_IsSolid = false;
+ ms_Info[E_BLOCK_FENCE_GATE ].m_IsSolid = false;
ms_Info[E_BLOCK_FIRE ].m_IsSolid = false;
ms_Info[E_BLOCK_FLOWER ].m_IsSolid = false;
ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false;
diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp
index 479c68153..fb2d6f2dc 100644
--- a/src/Blocks/BlockDoor.cpp
+++ b/src/Blocks/BlockDoor.cpp
@@ -62,7 +62,7 @@ void cBlockDoorHandler::OnCancelRightClick(cChunkInterface & a_ChunkInterface, c
a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player);
NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
- if (Meta & 8)
+ if (Meta & 0x8)
{
// Current block is top of the door
a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY - 1, a_BlockZ, a_Player);
diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h
index 797fe484c..049c4a334 100644
--- a/src/Blocks/BlockDoor.h
+++ b/src/Blocks/BlockDoor.h
@@ -20,12 +20,12 @@ 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;
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,
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
@@ -52,7 +52,7 @@ public:
return true;
}
-
+
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
a_Pickups.push_back(cItem((m_BlockType == E_BLOCK_WOODEN_DOOR) ? E_ITEM_WOODEN_DOOR : E_ITEM_IRON_DOOR, 1, 0));
@@ -77,8 +77,8 @@ public:
{
return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR));
}
-
-
+
+
bool CanReplaceBlock(BLOCKTYPE a_BlockType)
{
switch (a_BlockType)
@@ -99,7 +99,7 @@ public:
}
- /// Converts the player's yaw to placed door's blockmeta
+ /** Converts the player's yaw to placed door's blockmeta */
inline static NIBBLETYPE PlayerYawToMetaData(double a_Yaw)
{
ASSERT((a_Yaw >= -180) && (a_Yaw < 180));
@@ -111,67 +111,109 @@ public:
}
if ((a_Yaw >= 0) && (a_Yaw < 90))
{
- return 0x0;
+ return 0x00;
}
else if ((a_Yaw >= 180) && (a_Yaw < 270))
{
- return 0x2;
+ return 0x02;
}
else if ((a_Yaw >= 90) && (a_Yaw < 180))
{
- return 0x1;
+ return 0x01;
}
else
{
- return 0x3;
+ return 0x03;
}
}
- /// Returns true if the specified blocktype is any kind of door
+ /** Returns true if the specified blocktype is any kind of door */
inline static bool IsDoor(BLOCKTYPE a_Block)
{
return (a_Block == E_BLOCK_WOODEN_DOOR) || (a_Block == E_BLOCK_IRON_DOOR);
}
- /// Returns the metadata for the opposite door state (open vs closed)
- static NIBBLETYPE ChangeStateMetaData(NIBBLETYPE a_MetaData)
+ static NIBBLETYPE IsOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
- return a_MetaData ^ 4;
+ NIBBLETYPE Meta = GetCompleteDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
+ return ((Meta & 0x04) != 0);
}
- /// Changes the door at the specified coords from open to close or vice versa
- static void ChangeDoor(cChunkInterface & a_ChunkInterface, int a_X, int a_Y, int a_Z)
+ /** Returns the complete meta composed from the both parts of the door as (TopMeta << 4) | BottomMeta
+ The coords may point to either part of the door.
+ The returned value has bit 3 (0x08) set iff the coords point to the top part of the door.
+ Fails gracefully for (invalid) doors on the world's top and bottom. */
+ static NIBBLETYPE GetCompleteDoorMeta(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{
- NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_X, a_Y, a_Z);
-
- a_ChunkInterface.SetBlockMeta(a_X, a_Y, a_Z, ChangeStateMetaData(OldMetaData));
+ NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
- if (OldMetaData & 8)
+ if ((Meta & 0x08) != 0)
{
- // 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);
-
- if (IsDoor(BottomBlock) && !(BottomMeta & 8))
+ // The coords are pointing at the top part of the door
+ if (a_BlockX > 0)
{
- a_ChunkInterface.SetBlockMeta(a_X, a_Y - 1, a_Z, ChangeStateMetaData(BottomMeta));
+ NIBBLETYPE DownMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ);
+ return (NIBBLETYPE) ((DownMeta & 0x07) | 0x08 | (Meta << 4));
}
+ // This is the top part of the door at the bottommost layer of the world, there's no bottom:
+ return (NIBBLETYPE) (0x08 | (Meta << 4));
}
else
{
- // Current block is bottom of the door
- BLOCKTYPE TopBlock = a_ChunkInterface.GetBlock(a_X, a_Y + 1, a_Z);
- NIBBLETYPE TopMeta = a_ChunkInterface.GetBlockMeta(a_X, a_Y + 1, a_Z);
+ // The coords are pointing at the bottom part of the door
+ if (a_BlockY < cChunkDef::Height - 1)
+ {
+ NIBBLETYPE UpMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ);
+ return (NIBBLETYPE) (Meta | (UpMeta << 4));
+ }
+ // This is the bottom part of the door at the topmost layer of the world, there's no top:
+ return Meta;
+ }
+ }
- if (IsDoor(TopBlock) && (TopMeta & 8))
+
+ /** Sets the door to the specified state. If the door is already in that state, does nothing. */
+ static void SetOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open)
+ {
+ BLOCKTYPE Block = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ);
+ if (!IsDoor(Block))
+ {
+ return;
+ }
+
+ NIBBLETYPE Meta = GetCompleteDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
+ bool IsOpened = ((Meta & 0x04) != 0);
+ if (IsOpened == a_Open)
+ {
+ return;
+ }
+
+ // Change the door
+ NIBBLETYPE NewMeta = (Meta & 0x07) ^ 0x04; // Flip the "IsOpen" bit (0x04)
+ if ((Meta & 0x08) == 0)
+ {
+ // The block is the bottom part of the door
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, NewMeta);
+ }
+ else
+ {
+ // The block is the top part of the door, set the meta to the corresponding top part
+ if (a_BlockY > 0)
{
- a_ChunkInterface.SetBlockMeta(a_X, a_Y + 1, a_Z, ChangeStateMetaData(TopMeta));
+ a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ, NewMeta);
}
}
}
+
+
+ /** Changes the door at the specified coords from open to close or vice versa */
+ static void ChangeDoor(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
+ {
+ SetOpen(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, !IsOpen(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ));
+ }
} ;
diff --git a/src/Blocks/BlockDropSpenser.h b/src/Blocks/BlockDropSpenser.h
index 88b61a418..e2b3039fd 100644
--- a/src/Blocks/BlockDropSpenser.h
+++ b/src/Blocks/BlockDropSpenser.h
@@ -5,7 +5,7 @@
#pragma once
-#include "../Piston.h"
+#include "../Blocks/BlockPiston.h"
#include "MetaRotator.h"
@@ -32,7 +32,7 @@ public:
a_BlockType = m_BlockType;
// FIXME: Do not use cPiston class for dispenser placement!
- a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetYaw(), a_Player->GetPitch());
+ a_BlockMeta = cBlockPistonHandler::RotationPitchToMetaData(a_Player->GetYaw(), a_Player->GetPitch());
return true;
}
diff --git a/src/Blocks/BlockFurnace.h b/src/Blocks/BlockFurnace.h
index a7a807957..74582c3b3 100644
--- a/src/Blocks/BlockFurnace.h
+++ b/src/Blocks/BlockFurnace.h
@@ -3,7 +3,7 @@
#include "BlockEntity.h"
#include "../World.h"
-#include "../Piston.h"
+#include "../Blocks/BlockPiston.h"
#include "MetaRotator.h"
@@ -35,7 +35,7 @@ public:
a_BlockType = m_BlockType;
// FIXME: Do not use cPiston class for furnace placement!
- a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetYaw(), 0);
+ a_BlockMeta = cBlockPistonHandler::RotationPitchToMetaData(a_Player->GetYaw(), 0);
return true;
}
diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp
index bae396ea8..a7b89fcb7 100644
--- a/src/Blocks/BlockHandler.cpp
+++ b/src/Blocks/BlockHandler.cpp
@@ -57,6 +57,7 @@
#include "BlockPlanks.h"
#include "BlockPortal.h"
#include "BlockPumpkin.h"
+#include "BlockPressurePlate.h"
#include "BlockQuartz.h"
#include "BlockRail.h"
#include "BlockRedstone.h"
@@ -131,10 +132,12 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_GLOWSTONE: return new cBlockGlowstoneHandler (a_BlockType);
case E_BLOCK_GOLD_ORE: return new cBlockOreHandler (a_BlockType);
case E_BLOCK_GLASS: return new cBlockGlassHandler (a_BlockType);
+ case E_BLOCK_GLASS_PANE: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType);
case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType);
case E_BLOCK_HAY_BALE: return new cBlockHayBaleHandler (a_BlockType);
case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType);
+ case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType);
case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType);
case E_BLOCK_ICE: return new cBlockIceHandler (a_BlockType);
case E_BLOCK_INACTIVE_COMPARATOR: return new cBlockComparatorHandler (a_BlockType);
@@ -150,6 +153,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE 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_LIGHT_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType);
case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType);
case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType);
case E_BLOCK_MELON_STEM: return new cBlockStemsHandler (a_BlockType);
@@ -187,12 +191,15 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_SIGN_POST: return new cBlockSignHandler (a_BlockType);
case E_BLOCK_SNOW: return new cBlockSnowHandler (a_BlockType);
case E_BLOCK_SPRUCE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
+ case E_BLOCK_STAINED_GLASS: return new cBlockGlassHandler (a_BlockType);
+ case E_BLOCK_STAINED_GLASS_PANE: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_STATIONARY_LAVA: return new cBlockLavaHandler (a_BlockType);
case E_BLOCK_STATIONARY_WATER: return new cBlockFluidHandler (a_BlockType);
case E_BLOCK_STICKY_PISTON: return new cBlockPistonHandler (a_BlockType);
case E_BLOCK_STONE: return new cBlockStoneHandler (a_BlockType);
case E_BLOCK_STONE_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_STONE_BUTTON: return new cBlockButtonHandler (a_BlockType);
+ case E_BLOCK_STONE_PRESSURE_PLATE: return new cBlockPressurePlateHandler (a_BlockType);
case E_BLOCK_STONE_SLAB: return new cBlockSlabHandler (a_BlockType);
case E_BLOCK_SUGARCANE: return new cBlockSugarcaneHandler (a_BlockType);
case E_BLOCK_TALL_GRASS: return new cBlockTallGrassHandler (a_BlockType);
@@ -204,6 +211,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType);
case E_BLOCK_WOODEN_BUTTON: return new cBlockButtonHandler (a_BlockType);
case E_BLOCK_WOODEN_DOOR: return new cBlockDoorHandler (a_BlockType);
+ case E_BLOCK_WOODEN_PRESSURE_PLATE: return new cBlockPressurePlateHandler (a_BlockType);
case E_BLOCK_WOODEN_SLAB: return new cBlockSlabHandler (a_BlockType);
case E_BLOCK_WOODEN_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_WOOL: return new cBlockClothHandler (a_BlockType);
diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h
index 68996aa3f..301386568 100644
--- a/src/Blocks/BlockMobHead.h
+++ b/src/Blocks/BlockMobHead.h
@@ -113,7 +113,7 @@ public:
public:
cPlayerCallback(const Vector3f & a_Pos) : m_Pos(a_Pos) {}
- } PlayerCallback(Vector3f(a_BlockX, a_BlockY, a_BlockZ));
+ } PlayerCallback(Vector3f((float)a_BlockX, (float)a_BlockY, (float)a_BlockZ));
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA);
diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp
index 542eb33b5..faf639312 100644
--- a/src/Blocks/BlockPiston.cpp
+++ b/src/Blocks/BlockPiston.cpp
@@ -4,14 +4,14 @@
#include "../Item.h"
#include "../World.h"
#include "../Entities/Player.h"
-#include "../Piston.h"
+#include "BlockInServerPluginInterface.h"
#define AddPistonDir(x, y, z, dir, amount) \
- switch (dir) \
+ switch (dir & 0x07) \
{ \
case 0: (y) -= (amount); break; \
case 1: (y) += (amount); break; \
@@ -19,8 +19,16 @@
case 3: (z) += (amount); break; \
case 4: (x) -= (amount); break; \
case 5: (x) += (amount); break; \
+ default: \
+ { \
+ LOGWARNING("%s: invalid direction %d, ignoring", __FUNCTION__, dir & 0x07); \
+ break; \
+ } \
}
+#define PISTON_TICK_DELAY 1
+#define PISTON_MAX_PUSH_DISTANCE 12
+
@@ -40,7 +48,7 @@ void cBlockPistonHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorld
int newX = a_BlockX;
int newY = a_BlockY;
int newZ = a_BlockZ;
- AddPistonDir(newX, newY, newZ, OldMeta & ~(8), 1);
+ AddPistonDir(newX, newY, newZ, OldMeta, 1);
if (a_ChunkInterface.GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION)
{
@@ -60,7 +68,7 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta(
)
{
a_BlockType = m_BlockType;
- a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetYaw(), a_Player->GetPitch());
+ a_BlockMeta = RotationPitchToMetaData(a_Player->GetYaw(), a_Player->GetPitch());
return true;
}
@@ -68,6 +76,165 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta(
+int cBlockPistonHandler::FirstPassthroughBlock(int a_PistonX, int a_PistonY, int a_PistonZ, NIBBLETYPE pistonmeta, cWorld * a_World)
+{
+ // Examine each of the 12 blocks ahead of the piston:
+ for (int ret = 0; ret < PISTON_MAX_PUSH_DISTANCE; ret++)
+ {
+ BLOCKTYPE currBlock;
+ NIBBLETYPE currMeta;
+ AddPistonDir(a_PistonX, a_PistonY, a_PistonZ, pistonmeta, 1);
+ a_World->GetBlockTypeMeta(a_PistonX, a_PistonY, a_PistonZ, currBlock, currMeta);
+ if (CanBreakPush(currBlock))
+ {
+ // This block breaks when pushed, extend up to here
+ return ret;
+ }
+ if (!CanPush(currBlock, currMeta))
+ {
+ // This block cannot be pushed at all, the piston can't extend
+ return -1;
+ }
+ }
+ // There is no space for the blocks to move, piston can't extend
+ return -1;
+}
+
+
+
+
+
+void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World)
+{
+ BLOCKTYPE pistonBlock;
+ NIBBLETYPE pistonMeta;
+ a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta);
+
+ if (IsExtended(pistonMeta))
+ {
+ // Already extended, bail out
+ return;
+ }
+
+ int dist = FirstPassthroughBlock(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, a_World);
+ if (dist < 0)
+ {
+ // FirstPassthroughBlock says piston can't push anything, bail out
+ return;
+ }
+
+ a_World->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, 0, pistonMeta, pistonBlock);
+ a_World->BroadcastSoundEffect("tile.piston.out", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.7f);
+
+ // Drop the breakable block in the line, if appropriate:
+ AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, dist + 1); // "a_Block" now at the breakable / empty block
+ BLOCKTYPE currBlock;
+ NIBBLETYPE currMeta;
+ a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, currBlock, currMeta);
+ if (currBlock != E_BLOCK_AIR)
+ {
+ cBlockHandler * Handler = BlockHandler(currBlock);
+ if (Handler->DoesDropOnUnsuitable())
+ {
+ cChunkInterface ChunkInterface(a_World->GetChunkMap());
+ cBlockInServerPluginInterface PluginInterface(*a_World);
+ Handler->DropBlock(ChunkInterface, *a_World, PluginInterface, NULL, a_BlockX, a_BlockY, a_BlockZ);
+ }
+ }
+
+ // Push blocks, from the furthest to the nearest:
+ int oldx = a_BlockX, oldy = a_BlockY, oldz = a_BlockZ;
+ NIBBLETYPE currBlockMeta;
+ std::vector<Vector3i> ScheduledBlocks;
+ ScheduledBlocks.reserve(PISTON_MAX_PUSH_DISTANCE);
+
+ for (int i = dist + 1; i > 1; i--)
+ {
+ AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1);
+ a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, currBlock, currBlockMeta);
+ a_World->SetBlock(oldx, oldy, oldz, currBlock, currBlockMeta, false);
+ ScheduledBlocks.push_back(Vector3i(oldx, oldy, oldz));
+ oldx = a_BlockX;
+ oldy = a_BlockY;
+ oldz = a_BlockZ;
+ }
+
+ int extx = a_BlockX;
+ int exty = a_BlockY;
+ int extz = a_BlockZ;
+ ScheduledBlocks.push_back(Vector3i(extx, exty, extz));
+ AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1);
+ // "a_Block" now at piston body, "ext" at future extension
+
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta | 0x8);
+ a_World->SetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0), false);
+ a_World->ScheduleTask(PISTON_TICK_DELAY, new cWorld::cTaskSendBlockToAllPlayers(ScheduledBlocks));
+}
+
+
+
+
+
+void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World)
+{
+ BLOCKTYPE pistonBlock;
+ NIBBLETYPE pistonMeta;
+ a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta);
+
+ if (!IsExtended(pistonMeta))
+ {
+ // Already retracted, bail out
+ return;
+ }
+
+ // Check the extension:
+ AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 1);
+ if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_PISTON_EXTENSION)
+ {
+ LOGD("%s: Piston without an extension - still extending, or just in an invalid state?", __FUNCTION__);
+ return;
+ }
+
+ AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1);
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta & ~(8));
+ a_World->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, 1, pistonMeta & ~(8), pistonBlock);
+ a_World->BroadcastSoundEffect("tile.piston.in", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.7f);
+ AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 1);
+
+ // Retract the extension, pull block if appropriate
+ if (IsSticky(pistonBlock))
+ {
+ int tempx = a_BlockX, tempy = a_BlockY, tempz = a_BlockZ;
+ AddPistonDir(tempx, tempy, tempz, pistonMeta, 1);
+ BLOCKTYPE tempBlock;
+ NIBBLETYPE tempMeta;
+ a_World->GetBlockTypeMeta(tempx, tempy, tempz, tempBlock, tempMeta);
+ if (CanPull(tempBlock, tempMeta))
+ {
+ // Pull the block
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, tempBlock, tempMeta, false);
+ a_World->SetBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0, false);
+
+ std::vector<Vector3i> ScheduledBlocks;
+ ScheduledBlocks.push_back(Vector3i(a_BlockX, a_BlockY, a_BlockZ));
+ ScheduledBlocks.push_back(Vector3i(tempx, tempy, tempz));
+ a_World->ScheduleTask(PISTON_TICK_DELAY + 1, new cWorld::cTaskSendBlockToAllPlayers(ScheduledBlocks));
+ return;
+ }
+ }
+
+ // Retract without pulling
+ a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0, false);
+
+ std::vector<Vector3i> ScheduledBlocks;
+ ScheduledBlocks.push_back(Vector3i(a_BlockX, a_BlockY, a_BlockZ));
+ a_World->ScheduleTask(PISTON_TICK_DELAY + 1, new cWorld::cTaskSendBlockToAllPlayers(ScheduledBlocks));
+}
+
+
+
+
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cBlockPistonHeadHandler:
@@ -87,7 +254,7 @@ void cBlockPistonHeadHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInter
int newX = a_BlockX;
int newY = a_BlockY;
int newZ = a_BlockZ;
- AddPistonDir(newX, newY, newZ, OldMeta & ~(8), -1);
+ AddPistonDir(newX, newY, newZ, OldMeta, -1);
BLOCKTYPE Block = a_ChunkInterface.GetBlock(newX, newY, newZ);
if ((Block == E_BLOCK_STICKY_PISTON) || (Block == E_BLOCK_PISTON))
diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h
index 7632b5e5a..e6fa48e54 100644
--- a/src/Blocks/BlockPiston.h
+++ b/src/Blocks/BlockPiston.h
@@ -21,6 +21,138 @@ public:
int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override;
+
+ static NIBBLETYPE RotationPitchToMetaData(double a_Rotation, double a_Pitch)
+ {
+ if (a_Pitch >= 50)
+ {
+ return 0x1;
+ }
+ else if (a_Pitch <= -50)
+ {
+ return 0x0;
+ }
+ else
+ {
+ a_Rotation += 90 + 45; // So its not aligned with axis
+
+ if (a_Rotation > 360)
+ {
+ a_Rotation -= 360;
+ }
+ if ((a_Rotation >= 0) && (a_Rotation < 90))
+ {
+ return 0x4;
+ }
+ else if ((a_Rotation >= 180) && (a_Rotation < 270))
+ {
+ return 0x5;
+ }
+ else if ((a_Rotation >= 90) && (a_Rotation < 180))
+ {
+ return 0x2;
+ }
+ else
+ {
+ return 0x3;
+ }
+ }
+ }
+
+ static eBlockFace MetaDataToDirection(NIBBLETYPE a_MetaData)
+ {
+ switch (a_MetaData)
+ {
+ case 0x0: return BLOCK_FACE_YM;
+ case 0x1: return BLOCK_FACE_YP;
+ case 0x2: return BLOCK_FACE_ZM;
+ case 0x3: return BLOCK_FACE_ZP;
+ case 0x4: return BLOCK_FACE_XM;
+ case 0x5: return BLOCK_FACE_XP;
+ default:
+ {
+ ASSERT(!"Invalid Metadata");
+ return BLOCK_FACE_NONE;
+ }
+ }
+ }
+
+ static void ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+ static void RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
+
+private:
+
+ /// Returns true if the piston (specified by blocktype) is a sticky piston
+ static inline bool IsSticky(BLOCKTYPE a_BlockType) { return (a_BlockType == E_BLOCK_STICKY_PISTON); }
+
+ /// Returns true if the piston (with the specified meta) is extended
+ static inline bool IsExtended(NIBBLETYPE a_PistonMeta) { return ((a_PistonMeta & 0x8) != 0x0); }
+
+ /// Returns true if the specified block can be pushed by a piston (and left intact)
+ static inline bool CanPush(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+ {
+ switch (a_BlockType)
+ {
+ case E_BLOCK_ANVIL:
+ case E_BLOCK_BED:
+ case E_BLOCK_BEDROCK:
+ case E_BLOCK_BREWING_STAND:
+ case E_BLOCK_CHEST:
+ case E_BLOCK_COMMAND_BLOCK:
+ case E_BLOCK_DISPENSER:
+ case E_BLOCK_DROPPER:
+ case E_BLOCK_ENCHANTMENT_TABLE:
+ case E_BLOCK_END_PORTAL:
+ case E_BLOCK_END_PORTAL_FRAME:
+ case E_BLOCK_FURNACE:
+ case E_BLOCK_LIT_FURNACE:
+ case E_BLOCK_HOPPER:
+ case E_BLOCK_JUKEBOX:
+ case E_BLOCK_MOB_SPAWNER:
+ case E_BLOCK_NETHER_PORTAL:
+ case E_BLOCK_NOTE_BLOCK:
+ case E_BLOCK_OBSIDIAN:
+ case E_BLOCK_PISTON_EXTENSION:
+ {
+ return false;
+ }
+ case E_BLOCK_STICKY_PISTON:
+ case E_BLOCK_PISTON:
+ {
+ // A piston can only be pushed if retracted:
+ return !IsExtended(a_BlockMeta);
+ }
+ }
+ return true;
+ }
+
+ /// Returns true if the specified block can be pushed by a piston and broken / replaced
+ static inline bool CanBreakPush(BLOCKTYPE a_BlockType) { return cBlockInfo::IsPistonBreakable(a_BlockType); }
+
+ /// Returns true if the specified block can be pulled by a sticky piston
+ static inline bool CanPull(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+ {
+ switch (a_BlockType)
+ {
+ case E_BLOCK_LAVA:
+ case E_BLOCK_STATIONARY_LAVA:
+ case E_BLOCK_STATIONARY_WATER:
+ case E_BLOCK_WATER:
+ {
+ return false;
+ }
+ }
+
+ if (CanBreakPush(a_BlockType))
+ {
+ return false; // CanBreakPush returns true, but we need false to prevent pulling
+ }
+
+ return CanPush(a_BlockType, a_BlockMeta);
+ }
+
+ /// Returns how many blocks the piston has to push (where the first free space is); < 0 when unpushable
+ static int FirstPassthroughBlock(int a_PistonX, int a_PistonY, int a_PistonZ, NIBBLETYPE a_PistonMeta, cWorld * a_World);
} ;
@@ -40,7 +172,7 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
// No pickups
- // Also with 1.7, the item forms of these tecnical blocks have been removed, so giving someone this will crash their client...
+ // Also with 1.7, the item forms of these technical blocks have been removed, so giving someone this will crash their client...
}
} ;
diff --git a/src/Blocks/BlockPressurePlate.h b/src/Blocks/BlockPressurePlate.h
new file mode 100644
index 000000000..adec36eb6
--- /dev/null
+++ b/src/Blocks/BlockPressurePlate.h
@@ -0,0 +1,38 @@
+
+#pragma once
+
+#include "BlockHandler.h"
+
+
+
+
+class cBlockPressurePlateHandler :
+ public cBlockHandler
+{
+public:
+ cBlockPressurePlateHandler(BLOCKTYPE a_BlockType)
+ : cBlockHandler(a_BlockType)
+ {
+ }
+
+ virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
+ {
+ // Reset meta to 0
+ a_Pickups.push_back(cItem(m_BlockType, 1, 0));
+ }
+
+ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
+ {
+ if (a_RelY <= 0)
+ {
+ return false;
+ }
+
+ BLOCKTYPE BlockBelow = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ);
+ return ((BlockBelow == E_BLOCK_FENCE_GATE) || (BlockBelow == E_BLOCK_FENCE) || cBlockInfo::IsSolid(BlockBelow));
+ }
+} ;
+
+
+
+
diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp
index 4de89f7c1..d77f402fd 100644
--- a/src/ByteBuffer.cpp
+++ b/src/ByteBuffer.cpp
@@ -762,7 +762,6 @@ bool cByteBuffer::ReadUTF16String(AString & a_String, size_t a_NumChars)
// Reads 2 * a_NumChars bytes and interprets it as a UTF16 string, converting it into UTF8 string a_String
CHECK_THREAD;
CheckValid();
- ASSERT(a_NumChars >= 0);
AString RawData;
if (!ReadString(RawData, a_NumChars * 2))
{
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 900577526..335ce8315 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -8,98 +8,118 @@ include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/polarssl/include")
set(FOLDERS OSSupport HTTPServer Items Blocks Protocol Generating PolarSSL++)
set(FOLDERS ${FOLDERS} WorldStorage Mobs Entities Simulator UI BlockEntities Generating/Prefabs)
+set(BINDING_DEPENDECIES
+ tolua
+ ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/virtual_method_hooks.lua
+ ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/AllToLua.pkg
+ Bindings/LuaFunctions.h
+ Bindings/LuaWindow.h
+ Bindings/Plugin.h
+ Bindings/PluginLua.h
+ Bindings/PluginManager.h
+ Bindings/WebPlugin.h
+ BiomeDef.h
+ BlockArea.h
+ BlockEntities/BlockEntity.h
+ BlockEntities/BlockEntityWithItems.h
+ BlockEntities/ChestEntity.h
+ BlockEntities/DispenserEntity.h
+ BlockEntities/DropSpenserEntity.h
+ BlockEntities/DropperEntity.h
+ BlockEntities/FurnaceEntity.h
+ BlockEntities/HopperEntity.h
+ BlockEntities/JukeboxEntity.h
+ BlockEntities/NoteEntity.h
+ BlockEntities/SignEntity.h
+ BlockEntities/MobHeadEntity.h
+ BlockEntities/FlowerPotEntity.h
+ BlockID.h
+ BoundingBox.h
+ ChatColor.h
+ ChunkDef.h
+ ClientHandle.h
+ CraftingRecipes.h
+ Cuboid.h
+ Defines.h
+ Enchantments.h
+ Entities/Effects.h
+ Entities/Entity.h
+ Entities/Floater.h
+ Entities/Pawn.h
+ Entities/Painting.h
+ Entities/Pickup.h
+ Entities/Player.h
+ Entities/ProjectileEntity.h
+ Entities/ArrowEntity.h
+ Entities/ThrownEggEntity.h
+ Entities/ThrownEnderPearlEntity.h
+ Entities/ExpBottleEntity.h
+ Entities/ThrownSnowballEntity.h
+ Entities/FireChargeEntity.h
+ Entities/FireworkEntity.h
+ Entities/GhastFireballEntity.h
+ Entities/TNTEntity.h
+ Entities/ExpOrb.h
+ Entities/HangingEntity.h
+ Entities/ItemFrame.h
+ Generating/ChunkDesc.h
+ Group.h
+ Inventory.h
+ Item.h
+ ItemGrid.h
+ Mobs/Monster.h
+ OSSupport/File.h
+ Root.h
+ Server.h
+ StringUtils.h
+ Tracer.h
+ UI/Window.h
+ Vector3.h
+ WebAdmin.h
+ World.h
+)
-if (NOT MSVC)
+include_directories(Bindings)
+include_directories(.)
- # Bindings need to reference other folders, so they are done here instead
-
- # lib dependencies are not included
-
- set(BINDING_DEPENDECIES
- tolua
- ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/virtual_method_hooks.lua
- ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/AllToLua.pkg
- Bindings/LuaFunctions.h
- Bindings/LuaWindow.h
- Bindings/Plugin.h
- Bindings/PluginLua.h
- Bindings/PluginManager.h
- Bindings/WebPlugin.h
- BiomeDef.h
- BlockArea.h
- BlockEntities/BlockEntity.h
- BlockEntities/BlockEntityWithItems.h
- BlockEntities/ChestEntity.h
- BlockEntities/DispenserEntity.h
- BlockEntities/DropSpenserEntity.h
- BlockEntities/DropperEntity.h
- BlockEntities/FurnaceEntity.h
- BlockEntities/HopperEntity.h
- BlockEntities/JukeboxEntity.h
- BlockEntities/NoteEntity.h
- BlockEntities/SignEntity.h
- BlockEntities/MobHeadEntity.h
- BlockEntities/FlowerPotEntity.h
- BlockID.h
- BoundingBox.h
- ChatColor.h
- ChunkDef.h
- ClientHandle.h
- CraftingRecipes.h
- Cuboid.h
- Defines.h
- Enchantments.h
- Entities/Effects.h
- Entities/Entity.h
- Entities/Floater.h
- Entities/Pawn.h
- Entities/Painting.h
- Entities/Pickup.h
- Entities/Player.h
- Entities/ProjectileEntity.h
- Entities/ArrowEntity.h
- Entities/ThrownEggEntity.h
- Entities/ThrownEnderPearlEntity.h
- Entities/ExpBottleEntity.h
- Entities/ThrownSnowballEntity.h
- Entities/FireChargeEntity.h
- Entities/FireworkEntity.h
- Entities/GhastFireballEntity.h
- Entities/TNTEntity.h
- Entities/ExpOrb.h
- Entities/HangingEntity.h
- Entities/ItemFrame.h
- Generating/ChunkDesc.h
- Group.h
- Inventory.h
- Item.h
- ItemGrid.h
- Mobs/Monster.h
- OSSupport/File.h
- Root.h
- Server.h
- StringUtils.h
- Tracer.h
- UI/Window.h
- Vector3.h
- WebAdmin.h
- World.h
+if (WIN32)
+ ADD_CUSTOM_COMMAND(
+ # add any new generated bindings here
+ OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.h
+
+ # Copy the Lua DLL into the Bindings folder, so that tolua can run from there:
+ COMMAND copy /y ..\\..\\MCServer\\lua51.dll .
+
+ # Regenerate bindings:
+ COMMAND tolua -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/
+
+ # add any new generation dependencies here
+ DEPENDS ${BINDING_DEPENDECIES}
)
-
- include_directories(Bindings)
- include_directories(.)
-
+else ()
ADD_CUSTOM_COMMAND(
# add any new generated bindings here
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.h
-
- # command execuded to regerate bindings
+
+ # Regenerate bindings:
COMMAND tolua -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/
-
+
# add any new generation dependencies here
DEPENDS ${BINDING_DEPENDECIES}
)
+endif ()
+set_source_files_properties(Bindings/Bindings.cpp PROPERTIES GENERATED TRUE)
+set_source_files_properties(Bindings/Bindings.h PROPERTIES GENERATED TRUE)
+
+if (NOT MSVC)
+
+ # Bindings need to reference other folders, so they are done here instead
+
+ # lib dependencies are not included
+
+
#add cpp files here
add_library(Bindings
Bindings/Bindings
@@ -148,16 +168,6 @@ 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")
- message("Bindings.cpp not found, generating now")
- set(tolua_executable ${PROJECT_SOURCE_DIR}/Bindings/tolua++.exe)
- execute_process(
- COMMAND ${tolua_executable} -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
- WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/Bindings
- )
- endif()
-
# Get all files in this folder:
file(GLOB_RECURSE SOURCE
"*.cpp"
@@ -166,6 +176,9 @@ else ()
)
source_group("" FILES ${SOURCE})
+ LIST(APPEND SOURCE "Bindings/Bindings.cpp" "Bindings/Bindings.h")
+ source_group(Bindings FILES "Bindings/Bindings.cpp" "Bindings/Bindings.h")
+
# Add all subfolders as solution-folders:
list(APPEND FOLDERS "Resources")
list(APPEND FOLDERS "Bindings")
diff --git a/src/Chunk.cpp b/src/Chunk.cpp
index ca536e89a..4703e4536 100644
--- a/src/Chunk.cpp
+++ b/src/Chunk.cpp
@@ -64,7 +64,8 @@ sSetBlock::sSetBlock( int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_Bloc
cChunk::cChunk(
int a_ChunkX, int a_ChunkY, int a_ChunkZ,
cChunkMap * a_ChunkMap, cWorld * a_World,
- cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP
+ cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP,
+ cAllocationPool<cChunkData::sChunkSection> & a_Pool
) :
m_IsValid(false),
m_IsLightValid(false),
@@ -77,6 +78,7 @@ cChunk::cChunk(
m_PosZ(a_ChunkZ),
m_World(a_World),
m_ChunkMap(a_ChunkMap),
+ m_ChunkData(a_Pool),
m_BlockTickX(0),
m_BlockTickY(0),
m_BlockTickZ(0),
@@ -238,26 +240,12 @@ void cChunk::MarkLoadFailed(void)
void cChunk::GetAllData(cChunkDataCallback & a_Callback)
{
- a_Callback.HeightMap (&m_HeightMap);
- a_Callback.BiomeData (&m_BiomeMap);
+ a_Callback.HeightMap(&m_HeightMap);
+ a_Callback.BiomeData(&m_BiomeMap);
- COMPRESSED_BLOCKTYPE Blocks = m_BlockTypes;
- Blocks.resize(NumBlocks);
- a_Callback.BlockTypes (&Blocks[0]);
+ a_Callback.LightIsValid(m_IsLightValid);
- COMPRESSED_NIBBLETYPE Metas = m_BlockMeta;
- Metas.resize(NumBlocks / 2);
- a_Callback.BlockMeta (&Metas[0]);
-
- a_Callback.LightIsValid (m_IsLightValid);
-
- COMPRESSED_NIBBLETYPE BlockLights = m_BlockLight;
- BlockLights.resize(NumBlocks / 2);
- a_Callback.BlockLight (&BlockLights[0]);
-
- COMPRESSED_NIBBLETYPE BlockSkyLights = m_BlockSkyLight;
- BlockSkyLights.resize(NumBlocks / 2, 0xff);
- a_Callback.BlockSkyLight(&BlockSkyLights[0]);
+ a_Callback.ChunkData(m_ChunkData);
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
{
@@ -296,48 +284,10 @@ void cChunk::SetAllData(
CalculateHeightmap(a_BlockTypes);
}
- int IdxWhereNonEmptyStarts = 0;
- { // Blocktype compression
- unsigned char Highest = 0;
- int X = 0, Z = 0;
- m_BlockTypes.clear();
-
- for (int x = 0; x < Width; x++)
- {
- for (int z = 0; z < Width; z++)
- {
- unsigned char Height = m_HeightMap[x + z * Width];
- if (Height > Highest)
- {
- Highest = Height;
- X = x; Z = z;
- }
- }
- }
-
- IdxWhereNonEmptyStarts = MakeIndexNoCheck(X, Highest + 1, Z);
-
- m_BlockTypes.insert(m_BlockTypes.end(), &a_BlockTypes[0], &a_BlockTypes[IdxWhereNonEmptyStarts]);
- }
-
- { // Blockmeta compression
- m_BlockMeta.clear();
- m_BlockMeta.insert(m_BlockMeta.end(), &a_BlockMeta[0], &a_BlockMeta[IdxWhereNonEmptyStarts / 2]);
- }
-
- if (a_BlockLight != NULL)
- {
- // Compress blocklight
- m_BlockLight.clear();
- m_BlockLight.insert(m_BlockLight.end(), &a_BlockLight[0], &a_BlockLight[IdxWhereNonEmptyStarts / 2]);
- }
-
- if (a_BlockSkyLight != NULL)
- {
- // Compress skylight
- m_BlockSkyLight.clear();
- m_BlockSkyLight.insert(m_BlockSkyLight.end(), &a_BlockSkyLight[0], &a_BlockSkyLight[IdxWhereNonEmptyStarts / 2]);
- }
+ m_ChunkData.SetBlockTypes(a_BlockTypes);
+ m_ChunkData.SetMetas(a_BlockMeta);
+ m_ChunkData.SetBlockLight(a_BlockLight);
+ m_ChunkData.SetSkyLight(a_BlockSkyLight);
m_IsLightValid = (a_BlockLight != NULL) && (a_BlockSkyLight != NULL);
@@ -378,15 +328,9 @@ void cChunk::SetLight(
// TODO: We might get cases of wrong lighting when a chunk changes in the middle of a lighting calculation.
// Postponing until we see how bad it is :)
- { // Compress blocklight
- m_BlockLight.clear();
- m_BlockLight.insert(m_BlockLight.end(), &a_BlockLight[0], &a_BlockLight[m_BlockTypes.size() / 2]);
- }
+ m_ChunkData.SetBlockLight(a_BlockLight);
- { // Compress skylight
- m_BlockSkyLight.clear();
- m_BlockSkyLight.insert(m_BlockSkyLight.end(), &a_SkyLight[0], &a_SkyLight[m_BlockTypes.size() / 2]);
- }
+ m_ChunkData.SetSkyLight(a_SkyLight);
m_IsLightValid = true;
}
@@ -397,8 +341,7 @@ void cChunk::SetLight(
void cChunk::GetBlockTypes(BLOCKTYPE * a_BlockTypes)
{
- std::copy(m_BlockTypes.begin(), m_BlockTypes.end(), a_BlockTypes);
- std::fill_n(&a_BlockTypes[m_BlockTypes.size()], NumBlocks - m_BlockTypes.size(), E_BLOCK_AIR);
+ m_ChunkData.CopyBlockTypes(a_BlockTypes);
}
@@ -684,8 +627,7 @@ void cChunk::Tick(float a_Dt)
void cChunk::TickBlock(int a_RelX, int a_RelY, int a_RelZ)
{
- unsigned Index = MakeIndex(a_RelX, a_RelY, a_RelZ);
- cBlockHandler * Handler = BlockHandler(GetBlock(Index));
+ cBlockHandler * Handler = BlockHandler(GetBlock(a_RelX, a_RelY, a_RelZ));
ASSERT(Handler != NULL); // Happenned on server restart, FS #243
cChunkInterface ChunkInterface(this->GetWorld()->GetChunkMap());
cBlockInServerPluginInterface PluginInterface(*this->GetWorld());
@@ -810,19 +752,18 @@ void cChunk::CheckBlocks()
{
return;
}
- std::vector<unsigned int> ToTickBlocks;
+ std::vector<Vector3i> ToTickBlocks;
std::swap(m_ToTickBlocks, ToTickBlocks);
cChunkInterface ChunkInterface(m_World->GetChunkMap());
cBlockInServerPluginInterface PluginInterface(*m_World);
- for (std::vector<unsigned int>::const_iterator itr = ToTickBlocks.begin(), end = ToTickBlocks.end(); itr != end; ++itr)
+ for (std::vector<Vector3i>::const_iterator itr = ToTickBlocks.begin(), end = ToTickBlocks.end(); itr != end; ++itr)
{
- unsigned int index = (*itr);
- Vector3i BlockPos = IndexToCoordinate(index);
+ Vector3i Pos = (*itr);
- cBlockHandler * Handler = BlockHandler(GetBlock(index));
- Handler->Check(ChunkInterface, PluginInterface, BlockPos.x, BlockPos.y, BlockPos.z, *this);
+ cBlockHandler * Handler = BlockHandler(GetBlock(Pos));
+ Handler->Check(ChunkInterface, PluginInterface, Pos.x, Pos.y, Pos.z, *this);
} // for itr - ToTickBlocks[]
}
@@ -865,8 +806,7 @@ void cChunk::TickBlocks(void)
continue; // It's all air up here
}
- unsigned int Index = MakeIndexNoCheck(m_BlockTickX, m_BlockTickY, m_BlockTickZ);
- cBlockHandler * Handler = BlockHandler(GetBlock(Index));
+ cBlockHandler * Handler = BlockHandler(GetBlock(m_BlockTickX, m_BlockTickY, m_BlockTickZ));
ASSERT(Handler != NULL); // Happenned on server restart, FS #243
Handler->OnUpdate(ChunkInterface, *this->GetWorld(), PluginInterface, *this, m_BlockTickX, m_BlockTickY, m_BlockTickZ);
} // for i - tickblocks
@@ -1258,9 +1198,8 @@ bool cChunk::UnboundedRelGetBlockLights(int a_RelX, int a_RelY, int a_RelZ, NIBB
// The chunk is not available, bail out
return false;
}
- int idx = Chunk->MakeIndex(a_RelX, a_RelY, a_RelZ);
- a_BlockLight = Chunk->GetBlockLight(idx);
- a_SkyLight = Chunk->GetSkyLight(idx);
+ a_BlockLight = Chunk->GetBlockLight(a_RelX, a_RelY, a_RelZ);
+ a_SkyLight = Chunk->GetSkyLight(a_RelX, a_RelY, a_RelZ);
return true;
}
@@ -1450,7 +1389,7 @@ void cChunk::CalculateHeightmap(const BLOCKTYPE * a_BlockTypes)
int index = MakeIndex( x, y, z );
if (a_BlockTypes[index] != E_BLOCK_AIR)
{
- m_HeightMap[x + z * Width] = (unsigned char)y;
+ m_HeightMap[x + z * Width] = (HEIGHTTYPE)y;
break;
}
} // for y
@@ -1462,14 +1401,12 @@ void cChunk::CalculateHeightmap(const BLOCKTYPE * a_BlockTypes)
-void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients)
{
- FastSetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta);
-
- const int index = MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ);
+ FastSetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta, a_SendToClients);
// Tick this block and its neighbors:
- m_ToTickBlocks.push_back(index);
+ m_ToTickBlocks.push_back(Vector3i(a_RelX, a_RelY, a_RelZ));
QueueTickBlockNeighbors(a_RelX, a_RelY, a_RelZ);
// If there was a block entity, remove it:
@@ -1533,7 +1470,7 @@ void cChunk::QueueTickBlock(int a_RelX, int a_RelY, int a_RelZ)
return;
}
- m_ToTickBlocks.push_back(MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ));
+ m_ToTickBlocks.push_back(Vector3i(a_RelX, a_RelY, a_RelZ));
}
@@ -1565,43 +1502,41 @@ void cChunk::QueueTickBlockNeighbors(int a_RelX, int a_RelY, int a_RelZ)
-void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta)
+void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients)
{
ASSERT(!((a_RelX < 0) || (a_RelX >= Width) || (a_RelY < 0) || (a_RelY >= Height) || (a_RelZ < 0) || (a_RelZ >= Width)));
ASSERT(IsValid());
- const int index = MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ);
- const BLOCKTYPE OldBlockType = GetBlock(index);
- const BLOCKTYPE OldBlockMeta = GetNibble(m_BlockMeta, index);
+ const BLOCKTYPE OldBlockType = GetBlock(a_RelX, a_RelY, a_RelZ);
+ const BLOCKTYPE OldBlockMeta = m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ);
if ((OldBlockType == a_BlockType) && (OldBlockMeta == a_BlockMeta))
{
return;
}
MarkDirty();
+ m_IsRedstoneDirty = true;
- if ((size_t)index >= m_BlockTypes.size())
- {
- m_BlockTypes.resize(index + 1);
- }
- m_BlockTypes[index] = a_BlockType;
+ m_ChunkData.SetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType);
- // The client doesn't need to distinguish between stationary and nonstationary fluids:
- if (
- (OldBlockMeta != a_BlockMeta) || // Different meta always gets sent to the client
- !(
- ((OldBlockType == E_BLOCK_STATIONARY_WATER) && (a_BlockType == E_BLOCK_WATER)) || // Replacing stationary water with water
- ((OldBlockType == E_BLOCK_WATER) && (a_BlockType == E_BLOCK_STATIONARY_WATER)) || // Replacing water with stationary water
- ((OldBlockType == E_BLOCK_STATIONARY_LAVA) && (a_BlockType == E_BLOCK_LAVA)) || // Replacing stationary water with water
- ((OldBlockType == E_BLOCK_LAVA) && (a_BlockType == E_BLOCK_STATIONARY_LAVA)) // Replacing water with stationary water
+ if ( // Queue block to be sent only if ...
+ a_SendToClients && // ... we are told to do so AND ...
+ (
+ (OldBlockMeta != a_BlockMeta) || // ... the meta value is different OR ...
+ !( // ... the old and new blocktypes AREN'T liquids (because client doesn't need to distinguish betwixt them); see below for specifics:
+ ((OldBlockType == E_BLOCK_STATIONARY_WATER) && (a_BlockType == E_BLOCK_WATER)) || // Replacing stationary water with water
+ ((OldBlockType == E_BLOCK_WATER) && (a_BlockType == E_BLOCK_STATIONARY_WATER)) || // Replacing water with stationary water
+ ((OldBlockType == E_BLOCK_STATIONARY_LAVA) && (a_BlockType == E_BLOCK_LAVA)) || // Replacing stationary water with water
+ ((OldBlockType == E_BLOCK_LAVA) && (a_BlockType == E_BLOCK_STATIONARY_LAVA)) // Replacing water with stationary water
+ )
)
)
{
m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta));
}
- SetNibble(m_BlockMeta, index, a_BlockMeta);
+ m_ChunkData.SetMeta(a_RelX, a_RelY, a_RelZ, a_BlockMeta);
// ONLY recalculate lighting if it's necessary!
if (
@@ -1618,15 +1553,15 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT
{
if (a_BlockType != E_BLOCK_AIR)
{
- m_HeightMap[a_RelX + a_RelZ * Width] = (unsigned char)a_RelY;
+ m_HeightMap[a_RelX + a_RelZ * Width] = (HEIGHTTYPE)a_RelY;
}
else
{
for (int y = a_RelY - 1; y > 0; --y)
{
- if (GetBlock(MakeIndexNoCheck(a_RelX, y, a_RelZ)) != E_BLOCK_AIR)
+ if (GetBlock(a_RelX, y, a_RelZ) != E_BLOCK_AIR)
{
- m_HeightMap[a_RelX + a_RelZ * Width] = (unsigned char)y;
+ m_HeightMap[a_RelX + a_RelZ * Width] = (HEIGHTTYPE)y;
break;
}
} // for y - column in m_BlockData
@@ -1638,39 +1573,18 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT
-void cChunk::SetMeta(int a_BlockIdx, NIBBLETYPE a_Meta)
-{
- if (GetNibble(m_BlockMeta, a_BlockIdx) == a_Meta)
- {
- return;
- }
-
- MarkDirty();
- SetNibble(m_BlockMeta, a_BlockIdx, a_Meta);
- Vector3i Coords(IndexToCoordinate(a_BlockIdx));
-
- m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, Coords.x, Coords.y, Coords.z, GetBlock(a_BlockIdx), a_Meta));
-}
-
-
-
-
-
void cChunk::SendBlockTo(int a_RelX, int a_RelY, int a_RelZ, cClientHandle * a_Client)
{
- // The coords must be valid, because the upper level already does chunk lookup. No need to check them again.
- // There's an debug-time assert in MakeIndexNoCheck anyway
- unsigned int index = MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ);
if (a_Client == NULL)
{
// Queue the block for all clients in the chunk (will be sent in Tick())
- m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, GetBlock(index), GetMeta(index)));
+ m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, GetBlock(a_RelX, a_RelY, a_RelZ), GetMeta(a_RelX, a_RelY, a_RelZ)));
return;
}
Vector3i wp = PositionToWorldPosition(a_RelX, a_RelY, a_RelZ);
- a_Client->SendBlockChange(wp.x, wp.y, wp.z, GetBlock(index), GetMeta(index));
+ a_Client->SendBlockChange(wp.x, wp.y, wp.z, GetBlock(a_RelX, a_RelY, a_RelZ), GetMeta(a_RelX, a_RelY, a_RelZ));
// FS #268 - if a BlockEntity digging is cancelled by a plugin, the entire block entity must be re-sent to the client:
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), end = m_BlockEntities.end(); itr != end; ++itr)
@@ -2529,27 +2443,7 @@ BLOCKTYPE cChunk::GetBlock(int a_RelX, int a_RelY, int a_RelZ) const
return 0; // Clip
}
- return GetBlock(MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ));
-}
-
-
-
-
-
-BLOCKTYPE cChunk::GetBlock(int a_BlockIdx) const
-{
- if ((a_BlockIdx < 0) || (a_BlockIdx >= NumBlocks))
- {
- ASSERT(!"GetBlock(idx) out of bounds!");
- return 0;
- }
-
- if ((size_t)a_BlockIdx >= m_BlockTypes.size())
- {
- return E_BLOCK_AIR;
- }
-
- return m_BlockTypes[a_BlockIdx];
+ return m_ChunkData.GetBlock(a_RelX, a_RelY, a_RelZ);
}
@@ -2558,9 +2452,8 @@ BLOCKTYPE cChunk::GetBlock(int a_BlockIdx) const
void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta)
{
- int Idx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ);
- a_BlockType = GetBlock(Idx);
- a_BlockMeta = cChunkDef::GetNibble(m_BlockMeta, Idx);
+ a_BlockType = GetBlock(a_RelX, a_RelY, a_RelZ);
+ a_BlockMeta = m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ);
}
@@ -2569,11 +2462,10 @@ void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_
void cChunk::GetBlockInfo(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight)
{
- int Idx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ);
- a_BlockType = GetBlock(Idx);
- a_Meta = cChunkDef::GetNibble(m_BlockMeta, Idx);
- a_SkyLight = cChunkDef::GetNibble(m_BlockSkyLight, Idx);
- a_BlockLight = cChunkDef::GetNibble(m_BlockLight, Idx);
+ a_BlockType = GetBlock(a_RelX, a_RelY, a_RelZ);
+ a_Meta = m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ);
+ a_SkyLight = m_ChunkData.GetSkyLight(a_RelX, a_RelY, a_RelZ);
+ a_BlockLight = m_ChunkData.GetBlockLight(a_RelX, a_RelY, a_RelZ);
}
diff --git a/src/Chunk.h b/src/Chunk.h
index 84ec35496..7664a7afd 100644
--- a/src/Chunk.h
+++ b/src/Chunk.h
@@ -3,6 +3,7 @@
#include "Entities/Entity.h"
#include "ChunkDef.h"
+#include "ChunkData.h"
#include "Simulator/FireSimulator.h"
#include "Simulator/SandSimulator.h"
@@ -64,8 +65,10 @@ public:
cChunk(
int a_ChunkX, int a_ChunkY, int a_ChunkZ, // Chunk coords
cChunkMap * a_ChunkMap, cWorld * a_World, // Parent objects
- cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP // Neighbor chunks
+ cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP, // Neighbor chunks
+ cAllocationPool<cChunkData::sChunkSection> & a_Pool
);
+ cChunk(cChunk & other);
~cChunk();
bool IsValid(void) const {return m_IsValid; } // Returns true if the chunk block data is valid (loaded / generated)
@@ -139,7 +142,7 @@ public:
cWorld * GetWorld(void) const { return m_World; }
- void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta );
+ void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients = true);
// SetBlock() does a lot of work (heightmap, tickblocks, blockentities) so a BlockIdx version doesn't make sense
void SetBlock( const Vector3i & a_RelBlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) { SetBlock( a_RelBlockPos.x, a_RelBlockPos.y, a_RelBlockPos.z, a_BlockType, a_BlockMeta ); }
@@ -152,9 +155,9 @@ public:
/** Queues all 6 neighbors of the specified block for ticking (m_ToTickQueue). If any are outside the chunk, relays the checking to the proper neighboring chunk */
void QueueTickBlockNeighbors(int a_RelX, int a_RelY, int a_RelZ);
- void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta ); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc.
+ void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients = true); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc.
BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const;
- BLOCKTYPE GetBlock(int a_BlockIdx) const;
+ BLOCKTYPE GetBlock(Vector3i a_cords) const { return GetBlock(a_cords.x, a_cords.y, a_cords.z);}
void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta);
void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight);
@@ -320,15 +323,24 @@ public:
m_BlockTickZ = a_RelZ;
}
- inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const { return cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ); }
- inline NIBBLETYPE GetMeta(int a_BlockIdx) const { return cChunkDef::GetNibble(m_BlockMeta, a_BlockIdx); }
- inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta) { SetMeta(MakeIndex(a_RelX, a_RelY, a_RelZ), a_Meta); }
- void SetMeta(int a_BlockIdx, NIBBLETYPE a_Meta);
+ inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const
+ {
+ return m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ);
+ }
+ inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta)
+ {
+ bool hasChanged = m_ChunkData.SetMeta(a_RelX, a_RelY, a_RelZ, a_Meta);
+ if (hasChanged)
+ {
+ MarkDirty();
+ m_IsRedstoneDirty = true;
+
+ m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, GetBlock(a_RelX, a_RelY, a_RelZ), a_Meta));
+ }
+ }
- inline NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const {return cChunkDef::GetNibble(m_BlockLight, a_RelX, a_RelY, a_RelZ); }
- inline NIBBLETYPE GetSkyLight (int a_RelX, int a_RelY, int a_RelZ) const {return cChunkDef::GetNibble(m_BlockSkyLight, a_RelX, a_RelY, a_RelZ, true); }
- inline NIBBLETYPE GetBlockLight(int a_Idx) const {return cChunkDef::GetNibble(m_BlockLight, a_Idx); }
- inline NIBBLETYPE GetSkyLight (int a_Idx) const {return cChunkDef::GetNibble(m_BlockSkyLight, a_Idx, true); }
+ inline NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const {return m_ChunkData.GetBlockLight(a_RelX, a_RelY, a_RelZ); }
+ inline NIBBLETYPE GetSkyLight (int a_RelX, int a_RelY, int a_RelZ) const {return m_ChunkData.GetSkyLight(a_RelX, a_RelY, a_RelZ); }
/** Same as GetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
@@ -368,10 +380,13 @@ public:
cSandSimulatorChunkData & GetSandSimulatorData (void) { return m_SandSimulatorData; }
cRedstoneSimulatorChunkData * GetRedstoneSimulatorData(void) { return &m_RedstoneSimulatorData; }
+ cRedstoneSimulatorChunkData * GetRedstoneSimulatorQueuedData(void) { return &m_RedstoneSimulatorQueuedData; }
cIncrementalRedstoneSimulator::PoweredBlocksList * GetRedstoneSimulatorPoweredBlocksList(void) { return &m_RedstoneSimulatorPoweredBlocksList; }
cIncrementalRedstoneSimulator::LinkedBlocksList * GetRedstoneSimulatorLinkedBlocksList(void) { return &m_RedstoneSimulatorLinkedBlocksList; };
cIncrementalRedstoneSimulator::SimulatedPlayerToggleableList * GetRedstoneSimulatorSimulatedPlayerToggleableList(void) { return &m_RedstoneSimulatorSimulatedPlayerToggleableList; };
cIncrementalRedstoneSimulator::RepeatersDelayList * GetRedstoneSimulatorRepeatersDelayList(void) { return &m_RedstoneSimulatorRepeatersDelayList; };
+ bool IsRedstoneDirty(void) const { return m_IsRedstoneDirty; }
+ void SetIsRedstoneDirty(bool a_Flag) { m_IsRedstoneDirty = a_Flag; }
cBlockEntity * GetBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ);
cBlockEntity * GetBlockEntity(const Vector3i & a_BlockPos) { return GetBlockEntity(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z); }
@@ -403,8 +418,8 @@ private:
bool m_IsSaving; // True if the chunk is being saved
bool m_HasLoadFailed; // True if chunk failed to load and hasn't been generated yet since then
- std::vector<unsigned int> m_ToTickBlocks;
- sSetBlockVector m_PendingSendBlocks; ///< Blocks that have changed and need to be sent to all clients
+ std::vector<Vector3i> m_ToTickBlocks;
+ sSetBlockVector m_PendingSendBlocks; ///< Blocks that have changed and need to be sent to all clients
sSetBlockQueueVector m_SetBlockQueue; ///< Block changes that are queued to a specific tick
@@ -420,10 +435,7 @@ private:
cWorld * m_World;
cChunkMap * m_ChunkMap;
- COMPRESSED_BLOCKTYPE m_BlockTypes;
- COMPRESSED_NIBBLETYPE m_BlockMeta;
- COMPRESSED_NIBBLETYPE m_BlockLight;
- COMPRESSED_NIBBLETYPE m_BlockSkyLight;
+ cChunkData m_ChunkData;
cChunkDef::HeightMap m_HeightMap;
cChunkDef::BiomeMap m_BiomeMap;
@@ -442,13 +454,16 @@ private:
cSandSimulatorChunkData m_SandSimulatorData;
cRedstoneSimulatorChunkData m_RedstoneSimulatorData;
+ cRedstoneSimulatorChunkData m_RedstoneSimulatorQueuedData;
cIncrementalRedstoneSimulator::PoweredBlocksList m_RedstoneSimulatorPoweredBlocksList;
cIncrementalRedstoneSimulator::LinkedBlocksList m_RedstoneSimulatorLinkedBlocksList;
cIncrementalRedstoneSimulator::SimulatedPlayerToggleableList m_RedstoneSimulatorSimulatedPlayerToggleableList;
cIncrementalRedstoneSimulator::RepeatersDelayList m_RedstoneSimulatorRepeatersDelayList;
+ /** Indicates if simulate-once blocks should be updated by the redstone simulator */
+ bool m_IsRedstoneDirty;
- // pick up a random block of this chunk
+ // Pick up a random block of this chunk
void getRandomBlockCoords(int& a_X, int& a_Y, int& a_Z);
void getThreeRandomNumber(int& a_X, int& a_Y, int& a_Z,int a_MaxX, int a_MaxY, int a_MaxZ);
diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp
new file mode 100644
index 000000000..03b0224a6
--- /dev/null
+++ b/src/ChunkData.cpp
@@ -0,0 +1,595 @@
+
+// ChunkData.cpp
+
+// Implements the cChunkData class that represents the block's type, meta, blocklight and skylight storage for a chunk
+
+#include "Globals.h"
+#include "ChunkData.h"
+
+
+
+
+
+/** Returns true if all a_Array's elements between [0] and [a_NumElements - 1] are equal to a_Value. */
+template <typename T> inline bool IsAllValue(const T * a_Array, size_t a_NumElements, T a_Value)
+{
+ for (size_t i = 0; i < a_NumElements; i++)
+ {
+ if (a_Array[i] != a_Value)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+
+
+
+cChunkData::cChunkData(cAllocationPool<cChunkData::sChunkSection> & a_Pool) :
+#if __cplusplus < 201103L
+ // auto_ptr style interface for memory management
+ m_IsOwner(true),
+#endif
+ m_Pool(a_Pool)
+{
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ m_Sections[i] = NULL;
+ }
+}
+
+
+
+
+
+cChunkData::~cChunkData()
+{
+ #if __cplusplus < 201103L
+ // auto_ptr style interface for memory management
+ if (!m_IsOwner)
+ {
+ return;
+ }
+ #endif
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ Free(m_Sections[i]);
+ m_Sections[i] = NULL;
+ }
+}
+
+
+
+
+
+#if __cplusplus < 201103L
+ // auto_ptr style interface for memory management
+ cChunkData::cChunkData(const cChunkData & a_Other) :
+ m_IsOwner(true),
+ m_Pool(a_Other.m_Pool)
+ {
+ // Move contents and ownership from a_Other to this, pointer-wise:
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ m_Sections[i] = a_Other.m_Sections[i];
+ }
+ a_Other.m_IsOwner = false;
+ }
+
+
+
+
+
+ cChunkData & cChunkData::operator =(const cChunkData & a_Other)
+ {
+ // If assigning to self, no-op
+ if (&a_Other == this)
+ {
+ return *this;
+ }
+
+ // Free any currently held contents:
+ if (m_IsOwner)
+ {
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ Free(m_Sections[i]);
+ m_Sections[i] = NULL;
+ }
+ }
+
+ // Move contents and ownership from a_Other to this, pointer-wise:
+ m_IsOwner = true;
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ m_Sections[i] = a_Other.m_Sections[i];
+ }
+ a_Other.m_IsOwner = false;
+ ASSERT(&m_Pool == &a_Other.m_Pool);
+ return *this;
+ }
+
+#else
+
+ // unique_ptr style interface for memory management
+ cChunkData::cChunkData(cChunkData && other) :
+ m_Pool(other.m_Pool)
+ {
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ m_Sections[i] = other.m_Sections[i];
+ other.m_Sections[i] = NULL;
+ }
+ }
+
+
+
+
+
+ cChunkData & cChunkData::operator =(cChunkData && other)
+ {
+ if (&other != this)
+ {
+ ASSERT(&m_Pool == &other.m_Pool);
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ Free(m_Sections[i]);
+ m_Sections[i] = other.m_Sections[i];
+ other.m_Sections[i] = NULL;
+ }
+ }
+ return *this;
+ }
+#endif
+
+
+
+
+
+BLOCKTYPE cChunkData::GetBlock(int a_X, int a_Y, int a_Z) const
+{
+ ASSERT((a_X >= 0) && (a_X < cChunkDef::Width));
+ ASSERT((a_Y >= 0) && (a_Y < cChunkDef::Height));
+ ASSERT((a_Z >= 0) && (a_Z < cChunkDef::Width));
+ int Section = a_Y / SectionHeight;
+ if (m_Sections[Section] != NULL)
+ {
+ int Index = cChunkDef::MakeIndexNoCheck(a_X, a_Y - (Section * SectionHeight), a_Z);
+ return m_Sections[Section]->m_BlockTypes[Index];
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+
+
+
+void cChunkData::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Block)
+{
+ if (
+ (a_RelX >= cChunkDef::Width) || (a_RelX < 0) ||
+ (a_RelY >= cChunkDef::Height) || (a_RelY < 0) ||
+ (a_RelZ >= cChunkDef::Width) || (a_RelZ < 0)
+ )
+ {
+ ASSERT(!"cChunkData::SetMeta(): index out of range!");
+ return;
+ }
+
+ int Section = a_RelY / SectionHeight;
+ if (m_Sections[Section] == NULL)
+ {
+ if (a_Block == 0x00)
+ {
+ return;
+ }
+ m_Sections[Section] = Allocate();
+ if (m_Sections[Section] == NULL)
+ {
+ ASSERT(!"Failed to allocate a new section in Chunkbuffer");
+ return;
+ }
+ ZeroSection(m_Sections[Section]);
+ }
+ int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * SectionHeight), a_RelZ);
+ m_Sections[Section]->m_BlockTypes[Index] = a_Block;
+}
+
+
+
+
+
+NIBBLETYPE cChunkData::GetMeta(int a_RelX, int a_RelY, int a_RelZ) const
+{
+ if (
+ (a_RelX < cChunkDef::Width) && (a_RelX > -1) &&
+ (a_RelY < cChunkDef::Height) && (a_RelY > -1) &&
+ (a_RelZ < cChunkDef::Width) && (a_RelZ > -1))
+ {
+ int Section = a_RelY / SectionHeight;
+ if (m_Sections[Section] != NULL)
+ {
+ int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * SectionHeight), a_RelZ);
+ return (m_Sections[Section]->m_BlockMetas[Index / 2] >> ((Index & 1) * 4)) & 0x0f;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!");
+ return 0;
+}
+
+
+
+
+
+bool cChunkData::SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble)
+{
+ if (
+ (a_RelX >= cChunkDef::Width) || (a_RelX < 0) ||
+ (a_RelY >= cChunkDef::Height) || (a_RelY < 0) ||
+ (a_RelZ >= cChunkDef::Width) || (a_RelZ < 0)
+ )
+ {
+ ASSERT(!"cChunkData::SetMeta(): index out of range!");
+ return false;
+ }
+
+ int Section = a_RelY / SectionHeight;
+ if (m_Sections[Section] == NULL)
+ {
+ if ((a_Nibble & 0xf) == 0x00)
+ {
+ return false;
+ }
+ m_Sections[Section] = Allocate();
+ if (m_Sections[Section] == NULL)
+ {
+ ASSERT(!"Failed to allocate a new section in Chunkbuffer");
+ return false;
+ }
+ ZeroSection(m_Sections[Section]);
+ }
+ int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * SectionHeight), a_RelZ);
+ NIBBLETYPE oldval = m_Sections[Section]->m_BlockMetas[Index / 2] >> ((Index & 1) * 4) & 0xf;
+ m_Sections[Section]->m_BlockMetas[Index / 2] = static_cast<NIBBLETYPE>(
+ (m_Sections[Section]->m_BlockMetas[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble
+ ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set
+ );
+ return oldval != a_Nibble;
+}
+
+
+
+
+
+NIBBLETYPE cChunkData::GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const
+{
+ if (
+ (a_RelX < cChunkDef::Width) && (a_RelX > -1) &&
+ (a_RelY < cChunkDef::Height) && (a_RelY > -1) &&
+ (a_RelZ < cChunkDef::Width) && (a_RelZ > -1)
+ )
+ {
+ int Section = a_RelY / SectionHeight;
+ if (m_Sections[Section] != NULL)
+ {
+ int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * SectionHeight), a_RelZ);
+ return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!");
+ return 0;
+}
+
+
+
+
+
+NIBBLETYPE cChunkData::GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const
+{
+ if ((a_RelX < cChunkDef::Width) && (a_RelX > -1) && (a_RelY < cChunkDef::Height) && (a_RelY > -1) && (a_RelZ < cChunkDef::Width) && (a_RelZ > -1))
+ {
+ int Section = a_RelY / SectionHeight;
+ if (m_Sections[Section] != NULL)
+ {
+ int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * SectionHeight), a_RelZ);
+ return (m_Sections[Section]->m_BlockSkyLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f;
+ }
+ else
+ {
+ return 0xF;
+ }
+ }
+ ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!");
+ return 0;
+}
+
+
+
+
+
+cChunkData cChunkData::Copy(void) const
+{
+ cChunkData copy(m_Pool);
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ if (m_Sections[i] != NULL)
+ {
+ copy.m_Sections[i] = copy.Allocate();
+ *copy.m_Sections[i] = *m_Sections[i];
+ }
+ }
+ return copy;
+}
+
+
+
+
+
+void cChunkData::CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Length) const
+{
+ size_t ToSkip = a_Idx;
+
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ size_t StartPos = 0;
+ if (ToSkip > 0)
+ {
+ StartPos = std::min(ToSkip, +SectionBlockCount);
+ ToSkip -= StartPos;
+ }
+ if (StartPos < SectionBlockCount)
+ {
+ size_t ToCopy = std::min(+SectionBlockCount - StartPos, a_Length);
+ a_Length -= ToCopy;
+ if (m_Sections[i] != NULL)
+ {
+ BLOCKTYPE * blockbuffer = m_Sections[i]->m_BlockTypes;
+ memcpy(&a_Dest[(i * SectionBlockCount) + StartPos - a_Idx], blockbuffer + StartPos, sizeof(BLOCKTYPE) * ToCopy);
+ }
+ else
+ {
+ memset(&a_Dest[(i * SectionBlockCount) - a_Idx], 0, sizeof(BLOCKTYPE) * ToCopy);
+ }
+ }
+ }
+}
+
+
+
+
+
+void cChunkData::CopyMetas(NIBBLETYPE * a_Dest) const
+{
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ if (m_Sections[i] != NULL)
+ {
+ memcpy(&a_Dest[i * SectionBlockCount / 2], &m_Sections[i]->m_BlockMetas, sizeof(m_Sections[i]->m_BlockMetas));
+ }
+ else
+ {
+ memset(&a_Dest[i * SectionBlockCount / 2], 0, sizeof(m_Sections[i]->m_BlockMetas));
+ }
+ }
+}
+
+
+
+
+
+void cChunkData::CopyBlockLight(NIBBLETYPE * a_Dest) const
+{
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ if (m_Sections[i] != NULL)
+ {
+ memcpy(&a_Dest[i * SectionBlockCount / 2], &m_Sections[i]->m_BlockLight, sizeof(m_Sections[i]->m_BlockLight));
+ }
+ else
+ {
+ memset(&a_Dest[i * SectionBlockCount / 2], 0, sizeof(m_Sections[i]->m_BlockLight));
+ }
+ }
+}
+
+
+
+
+
+void cChunkData::CopySkyLight(NIBBLETYPE * a_Dest) const
+{
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ if (m_Sections[i] != NULL)
+ {
+ memcpy(&a_Dest[i * SectionBlockCount / 2], &m_Sections[i]->m_BlockSkyLight, sizeof(m_Sections[i]->m_BlockSkyLight));
+ }
+ else
+ {
+ memset(&a_Dest[i * SectionBlockCount / 2], 0xff, sizeof(m_Sections[i]->m_BlockSkyLight));
+ }
+ }
+}
+
+
+
+
+
+void cChunkData::SetBlockTypes(const BLOCKTYPE * a_Src)
+{
+ ASSERT(a_Src != NULL);
+
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ // If the section is already allocated, copy the data into it:
+ if (m_Sections[i] != NULL)
+ {
+ memcpy(m_Sections[i]->m_BlockTypes, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockTypes));
+ continue;
+ }
+
+ // The section doesn't exist, find out if it is needed:
+ if (IsAllValue(a_Src + i * SectionBlockCount, SectionBlockCount, (const BLOCKTYPE)0))
+ {
+ // No need for the section, the data is all-air
+ continue;
+ }
+
+ // Allocate the section and copy the data into it:
+ m_Sections[i] = Allocate();
+ memcpy(m_Sections[i]->m_BlockTypes, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockTypes));
+ memset(m_Sections[i]->m_BlockMetas, 0x00, sizeof(m_Sections[i]->m_BlockMetas));
+ memset(m_Sections[i]->m_BlockLight, 0x00, sizeof(m_Sections[i]->m_BlockLight));
+ memset(m_Sections[i]->m_BlockSkyLight, 0xff, sizeof(m_Sections[i]->m_BlockSkyLight));
+ } // for i - m_Sections[]
+}
+
+
+
+
+void cChunkData::SetMetas(const NIBBLETYPE * a_Src)
+{
+ ASSERT(a_Src != NULL);
+
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ // If the section is already allocated, copy the data into it:
+ if (m_Sections[i] != NULL)
+ {
+ memcpy(m_Sections[i]->m_BlockMetas, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockMetas));
+ continue;
+ }
+
+ // The section doesn't exist, find out if it is needed:
+ if (IsAllValue(a_Src + i * SectionBlockCount / 2, SectionBlockCount / 2, (NIBBLETYPE)0))
+ {
+ // No need for the section, the data is all zeroes
+ continue;
+ }
+
+ // Allocate the section and copy the data into it:
+ m_Sections[i] = Allocate();
+ memcpy(m_Sections[i]->m_BlockMetas, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockMetas));
+ memset(m_Sections[i]->m_BlockTypes, 0x00, sizeof(m_Sections[i]->m_BlockTypes));
+ memset(m_Sections[i]->m_BlockLight, 0x00, sizeof(m_Sections[i]->m_BlockLight));
+ memset(m_Sections[i]->m_BlockSkyLight, 0xff, sizeof(m_Sections[i]->m_BlockSkyLight));
+ } // for i - m_Sections[]
+}
+
+
+
+
+
+void cChunkData::SetBlockLight(const NIBBLETYPE * a_Src)
+{
+ if (a_Src == NULL)
+ {
+ return;
+ }
+
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ // If the section is already allocated, copy the data into it:
+ if (m_Sections[i] != NULL)
+ {
+ memcpy(m_Sections[i]->m_BlockLight, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockLight));
+ continue;
+ }
+
+ // The section doesn't exist, find out if it is needed:
+ if (IsAllValue(a_Src + i * SectionBlockCount / 2, SectionBlockCount / 2, (NIBBLETYPE)0))
+ {
+ // No need for the section, the data is all zeroes
+ continue;
+ }
+
+ // Allocate the section and copy the data into it:
+ m_Sections[i] = Allocate();
+ memcpy(m_Sections[i]->m_BlockLight, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockLight));
+ memset(m_Sections[i]->m_BlockTypes, 0x00, sizeof(m_Sections[i]->m_BlockTypes));
+ memset(m_Sections[i]->m_BlockMetas, 0x00, sizeof(m_Sections[i]->m_BlockMetas));
+ memset(m_Sections[i]->m_BlockSkyLight, 0xff, sizeof(m_Sections[i]->m_BlockSkyLight));
+ } // for i - m_Sections[]
+}
+
+
+
+
+void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src)
+{
+ if (a_Src == NULL)
+ {
+ return;
+ }
+
+ for (size_t i = 0; i < NumSections; i++)
+ {
+ // If the section is already allocated, copy the data into it:
+ if (m_Sections[i] != NULL)
+ {
+ memcpy(m_Sections[i]->m_BlockSkyLight, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockSkyLight));
+ continue;
+ }
+
+ // The section doesn't exist, find out if it is needed:
+ if (IsAllValue(a_Src + i * SectionBlockCount / 2, SectionBlockCount / 2, (NIBBLETYPE)0xff))
+ {
+ // No need for the section, the data is all zeroes
+ continue;
+ }
+
+ // Allocate the section and copy the data into it:
+ m_Sections[i] = Allocate();
+ memcpy(m_Sections[i]->m_BlockSkyLight, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockSkyLight));
+ memset(m_Sections[i]->m_BlockTypes, 0x00, sizeof(m_Sections[i]->m_BlockTypes));
+ memset(m_Sections[i]->m_BlockMetas, 0x00, sizeof(m_Sections[i]->m_BlockMetas));
+ memset(m_Sections[i]->m_BlockLight, 0x00, sizeof(m_Sections[i]->m_BlockLight));
+ } // for i - m_Sections[]
+}
+
+
+
+
+
+cChunkData::sChunkSection * cChunkData::Allocate(void)
+{
+ return m_Pool.Allocate();
+}
+
+
+
+
+
+void cChunkData::Free(cChunkData::sChunkSection * a_Section)
+{
+ m_Pool.Free(a_Section);
+}
+
+
+
+
+
+void cChunkData::ZeroSection(cChunkData::sChunkSection * a_Section) const
+{
+ memset(a_Section->m_BlockTypes, 0x00, sizeof(a_Section->m_BlockTypes));
+ memset(a_Section->m_BlockMetas, 0x00, sizeof(a_Section->m_BlockMetas));
+ memset(a_Section->m_BlockLight, 0x00, sizeof(a_Section->m_BlockLight));
+ memset(a_Section->m_BlockSkyLight, 0xff, sizeof(a_Section->m_BlockSkyLight));
+}
+
+
+
+
diff --git a/src/ChunkData.h b/src/ChunkData.h
new file mode 100644
index 000000000..fe8b068a2
--- /dev/null
+++ b/src/ChunkData.h
@@ -0,0 +1,133 @@
+
+// ChunkData.h
+
+// Declares the cChunkData class that represents the block's type, meta, blocklight and skylight storage for a chunk
+
+
+
+
+
+#pragma once
+
+
+#include <cstring>
+
+
+#include "ChunkDef.h"
+
+#include "AllocationPool.h"
+
+
+
+#if __cplusplus < 201103L
+// auto_ptr style interface for memory management
+#else
+// unique_ptr style interface for memory management
+#endif
+
+class cChunkData
+{
+private:
+
+ static const size_t SectionHeight = 16;
+ static const size_t NumSections = (cChunkDef::Height / SectionHeight);
+ static const size_t SectionBlockCount = SectionHeight * cChunkDef::Width * cChunkDef::Width;
+
+public:
+
+ struct sChunkSection;
+
+ cChunkData(cAllocationPool<cChunkData::sChunkSection> & a_Pool);
+ ~cChunkData();
+
+ #if __cplusplus < 201103L
+ // auto_ptr style interface for memory management
+ cChunkData(const cChunkData & a_Other);
+ cChunkData & operator =(const cChunkData & a_Other);
+ #else
+ // unique_ptr style interface for memory management
+ cChunkData(cChunkData && a_Other);
+ cChunkData & operator =(cChunkData && a_ther);
+ #endif
+
+ BLOCKTYPE GetBlock(int a_X, int a_Y, int a_Z) const;
+ void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Block);
+
+ NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const;
+ bool SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble);
+
+ NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const;
+
+ NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const;
+
+ /** Creates a (deep) copy of self. */
+ cChunkData Copy(void) const;
+
+ /** Copies the blocktype data into the specified flat array.
+ Optionally, only a part of the data is copied, as specified by the a_Idx and a_Length parameters. */
+ void CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx = 0, size_t a_Length = cChunkDef::NumBlocks) const;
+
+ /** Copies the metadata into the specified flat array. */
+ void CopyMetas(NIBBLETYPE * a_Dest) const;
+
+ /** Copies the block light data into the specified flat array. */
+ void CopyBlockLight(NIBBLETYPE * a_Dest) const;
+
+ /** Copies the skylight data into the specified flat array. */
+ void CopySkyLight (NIBBLETYPE * a_Dest) const;
+
+ /** Copies the blocktype data from the specified flat array into the internal representation.
+ Allocates sections that are needed for the operation.
+ Requires that a_Src is a valid pointer. */
+ void SetBlockTypes(const BLOCKTYPE * a_Src);
+
+ /** Copies the metadata from the specified flat array into the internal representation.
+ Allocates sectios that are needed for the operation.
+ Requires that a_Src is a valid pointer. */
+ void SetMetas(const NIBBLETYPE * a_Src);
+
+ /** Copies the blocklight data from the specified flat array into the internal representation.
+ Allocates sectios that are needed for the operation.
+ Allows a_Src to be NULL, in which case it doesn't do anything. */
+ void SetBlockLight(const NIBBLETYPE * a_Src);
+
+ /** Copies the skylight data from the specified flat array into the internal representation.
+ Allocates sectios that are needed for the operation.
+ Allows a_Src to be NULL, in which case it doesn't do anything. */
+ void SetSkyLight(const NIBBLETYPE * a_Src);
+
+ struct sChunkSection
+ {
+ BLOCKTYPE m_BlockTypes [SectionHeight * 16 * 16] ;
+ NIBBLETYPE m_BlockMetas [SectionHeight * 16 * 16 / 2];
+ NIBBLETYPE m_BlockLight [SectionHeight * 16 * 16 / 2];
+ NIBBLETYPE m_BlockSkyLight[SectionHeight * 16 * 16 / 2];
+ };
+
+private:
+ #if __cplusplus < 201103L
+ // auto_ptr style interface for memory management
+ mutable bool m_IsOwner;
+ #endif
+
+ sChunkSection * m_Sections[NumSections];
+
+ cAllocationPool<cChunkData::sChunkSection> & m_Pool;
+
+ /** Allocates a new section. Entry-point to custom allocators. */
+ sChunkSection * Allocate(void);
+
+ /** Frees the specified section, previously allocated using Allocate().
+ Note that a_Section may be NULL. */
+ void Free(sChunkSection * a_Section);
+
+ /** Sets the data in the specified section to their default values. */
+ void ZeroSection(sChunkSection * a_Section) const;
+
+};
+
+
+
+
+
+
diff --git a/src/ChunkDataCallback.h b/src/ChunkDataCallback.h
new file mode 100644
index 000000000..0c8b1098f
--- /dev/null
+++ b/src/ChunkDataCallback.h
@@ -0,0 +1,127 @@
+
+// ChunkDataCallback.h
+
+// Declares the cChunkDataCallback interface and several trivial descendants, for reading chunk data
+
+
+
+
+
+#pragma once
+
+#include "ChunkData.h"
+
+
+
+
+
+/** Interface class used for getting data out of a chunk using the GetAllData() function.
+Implementation must use the pointers immediately and NOT store any of them for later use
+The virtual methods are called in the same order as they're declared here.
+*/
+class cChunkDataCallback abstract
+{
+public:
+
+ virtual ~cChunkDataCallback() {}
+
+ /** Called before any other callbacks to inform of the current coords
+ (only in processes where multiple chunks can be processed, such as cWorld::ForEachChunkInRect()).
+ If false is returned, the chunk is skipped.
+ */
+ virtual bool Coords(int a_ChunkX, int a_ChunkZ) { UNUSED(a_ChunkX); UNUSED(a_ChunkZ); return true; };
+
+ /// Called once to provide heightmap data
+ virtual void HeightMap(const cChunkDef::HeightMap * a_HeightMap) {UNUSED(a_HeightMap); };
+
+ /// Called once to provide biome data
+ virtual void BiomeData(const cChunkDef::BiomeMap * a_BiomeMap) {UNUSED(a_BiomeMap); };
+
+ /// Called once to let know if the chunk lighting is valid. Return value is ignored
+ virtual void LightIsValid(bool a_IsLightValid) {UNUSED(a_IsLightValid); };
+
+ /// Called once to export block info
+ virtual void ChunkData(const cChunkData & a_Buffer) {UNUSED(a_Buffer); };
+
+ /// Called for each entity in the chunk
+ virtual void Entity(cEntity * a_Entity) {UNUSED(a_Entity); };
+
+ /// Called for each blockentity in the chunk
+ virtual void BlockEntity(cBlockEntity * a_Entity) {UNUSED(a_Entity); };
+} ;
+
+
+
+
+
+/** A simple implementation of the cChunkDataCallback interface that collects all block data into a buffer
+*/
+class cChunkDataCollector :
+ public cChunkDataCallback
+{
+public:
+
+ cChunkData m_BlockData;
+
+protected:
+
+ virtual void ChunkData(const cChunkData & a_BlockData) override
+ {
+ m_BlockData = a_BlockData.Copy();
+ }
+};
+
+
+
+
+
+/** A simple implementation of the cChunkDataCallback interface that collects all block data into a single buffer
+*/
+class cChunkDataArrayCollector :
+ public cChunkDataCallback
+{
+public:
+
+ // Must be unsigned char instead of BLOCKTYPE or NIBBLETYPE, because it houses both.
+ unsigned char m_BlockData[cChunkDef::BlockDataSize];
+
+protected:
+
+ virtual void ChunkData(const cChunkData & a_ChunkBuffer) override
+ {
+ a_ChunkBuffer.CopyBlockTypes(m_BlockData);
+ a_ChunkBuffer.CopyMetas(m_BlockData + cChunkDef::NumBlocks);
+ a_ChunkBuffer.CopyBlockLight(m_BlockData + 3 * cChunkDef::NumBlocks / 2);
+ a_ChunkBuffer.CopySkyLight(m_BlockData + 2 * cChunkDef::NumBlocks);
+ }
+};
+
+
+
+
+
+/** A simple implementation of the cChunkDataCallback interface that collects all block data into separate buffers */
+class cChunkDataSeparateCollector :
+ public cChunkDataCallback
+{
+public:
+
+ cChunkDef::BlockTypes m_BlockTypes;
+ cChunkDef::BlockNibbles m_BlockMetas;
+ cChunkDef::BlockNibbles m_BlockLight;
+ cChunkDef::BlockNibbles m_BlockSkyLight;
+
+protected:
+
+ virtual void ChunkData(const cChunkData & a_ChunkBuffer) override
+ {
+ a_ChunkBuffer.CopyBlockTypes(m_BlockTypes);
+ a_ChunkBuffer.CopyMetas(m_BlockMetas);
+ a_ChunkBuffer.CopyBlockLight(m_BlockLight);
+ a_ChunkBuffer.CopySkyLight(m_BlockSkyLight);
+ }
+} ;
+
+
+
+
diff --git a/src/ChunkDef.h b/src/ChunkDef.h
index 83f3c8f5f..f89e16ed1 100644
--- a/src/ChunkDef.h
+++ b/src/ChunkDef.h
@@ -330,136 +330,6 @@ private:
-/** Interface class used for getting data out of a chunk using the GetAllData() function.
-Implementation must use the pointers immediately and NOT store any of them for later use
-The virtual methods are called in the same order as they're declared here.
-*/
-class cChunkDataCallback abstract
-{
-public:
-
- virtual ~cChunkDataCallback() {}
-
- /** Called before any other callbacks to inform of the current coords
- (only in processes where multiple chunks can be processed, such as cWorld::ForEachChunkInRect()).
- If false is returned, the chunk is skipped.
- */
- virtual bool Coords(int a_ChunkX, int a_ChunkZ) { UNUSED(a_ChunkX); UNUSED(a_ChunkZ); return true; };
-
- /// Called once to provide heightmap data
- virtual void HeightMap(const cChunkDef::HeightMap * a_HeightMap) {UNUSED(a_HeightMap); };
-
- /// Called once to provide biome data
- virtual void BiomeData (const cChunkDef::BiomeMap * a_BiomeMap) {UNUSED(a_BiomeMap); };
-
- /// Called once to export block types
- virtual void BlockTypes (const BLOCKTYPE * a_Type) {UNUSED(a_Type); };
-
- /// Called once to export block meta
- virtual void BlockMeta (const NIBBLETYPE * a_Meta) {UNUSED(a_Meta); };
-
- /// Called once to let know if the chunk lighting is valid. Return value is used to control if BlockLight() and BlockSkyLight() are called next (if true)
- virtual bool LightIsValid(bool a_IsLightValid) {UNUSED(a_IsLightValid); return true; };
-
- /// Called once to export block light
- virtual void BlockLight (const NIBBLETYPE * a_BlockLight) {UNUSED(a_BlockLight); };
-
- /// Called once to export sky light
- virtual void BlockSkyLight(const NIBBLETYPE * a_SkyLight) {UNUSED(a_SkyLight); };
-
- /// Called for each entity in the chunk
- virtual void Entity(cEntity * a_Entity) {UNUSED(a_Entity); };
-
- /// Called for each blockentity in the chunk
- virtual void BlockEntity(cBlockEntity * a_Entity) {UNUSED(a_Entity); };
-} ;
-
-
-
-
-
-/** A simple implementation of the cChunkDataCallback interface that collects all block data into a single buffer
-*/
-class cChunkDataCollector :
- public cChunkDataCallback
-{
-public:
-
- // Must be unsigned char instead of BLOCKTYPE or NIBBLETYPE, because it houses both.
- unsigned char m_BlockData[cChunkDef::BlockDataSize];
-
-protected:
-
- virtual void BlockTypes(const BLOCKTYPE * a_BlockTypes) override
- {
- memcpy(m_BlockData, a_BlockTypes, sizeof(cChunkDef::BlockTypes));
- }
-
-
- virtual void BlockMeta(const NIBBLETYPE * a_BlockMeta) override
- {
- memcpy(m_BlockData + cChunkDef::NumBlocks, a_BlockMeta, cChunkDef::NumBlocks / 2);
- }
-
-
- virtual void BlockLight(const NIBBLETYPE * a_BlockLight) override
- {
- memcpy(m_BlockData + 3 * cChunkDef::NumBlocks / 2, a_BlockLight, cChunkDef::NumBlocks / 2);
- }
-
-
- virtual void BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) override
- {
- memcpy(m_BlockData + 2 * cChunkDef::NumBlocks, a_BlockSkyLight, cChunkDef::NumBlocks / 2);
- }
-} ;
-
-
-
-
-
-/** A simple implementation of the cChunkDataCallback interface that collects all block data into a separate buffers
-*/
-class cChunkDataSeparateCollector :
- public cChunkDataCallback
-{
-public:
-
- cChunkDef::BlockTypes m_BlockTypes;
- cChunkDef::BlockNibbles m_BlockMetas;
- cChunkDef::BlockNibbles m_BlockLight;
- cChunkDef::BlockNibbles m_BlockSkyLight;
-
-protected:
-
- virtual void BlockTypes(const BLOCKTYPE * a_BlockTypes) override
- {
- memcpy(m_BlockTypes, a_BlockTypes, sizeof(m_BlockTypes));
- }
-
-
- virtual void BlockMeta(const NIBBLETYPE * a_BlockMeta) override
- {
- memcpy(m_BlockMetas, a_BlockMeta, sizeof(m_BlockMetas));
- }
-
-
- virtual void BlockLight(const NIBBLETYPE * a_BlockLight) override
- {
- memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight));
- }
-
-
- virtual void BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) override
- {
- memcpy(m_BlockSkyLight, a_BlockSkyLight, sizeof(m_BlockSkyLight));
- }
-} ;
-
-
-
-
-
/** Interface class used for comparing clients of two chunks.
Used primarily for entity moving while both chunks are locked.
*/
diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp
index d7164a6a5..d2ccca94e 100644
--- a/src/ChunkMap.cpp
+++ b/src/ChunkMap.cpp
@@ -34,8 +34,15 @@
// cChunkMap:
cChunkMap::cChunkMap(cWorld * a_World )
- : m_World( a_World )
+ : m_World( a_World ),
+ m_Pool(
+ new cListAllocationPool<cChunkData::sChunkSection, 1600>(
+ std::auto_ptr<cAllocationPool<cChunkData::sChunkSection>::cStarvationCallbacks>(
+ new cStarvationCallbacks())
+ )
+ )
{
+
}
@@ -78,7 +85,7 @@ cChunkMap::cChunkLayer * cChunkMap::GetLayer(int a_LayerX, int a_LayerZ)
}
// Not found, create new:
- cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this);
+ cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this, *m_Pool);
if (Layer == NULL)
{
LOGERROR("cChunkMap: Cannot create new layer, server out of memory?");
@@ -219,9 +226,8 @@ bool cChunkMap::LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTY
return false;
}
- int Index = cChunkDef::MakeIndexNoCheck(a_BlockX, a_BlockY, a_BlockZ);
- a_BlockType = Chunk->GetBlock(Index);
- a_BlockMeta = Chunk->GetMeta(Index);
+ a_BlockType = Chunk->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
+ a_BlockMeta = Chunk->GetMeta(a_BlockX, a_BlockY, a_BlockZ);
return true;
}
@@ -242,8 +248,7 @@ bool cChunkMap::LockedGetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLO
return false;
}
- int Index = cChunkDef::MakeIndexNoCheck(a_BlockX, a_BlockY, a_BlockZ);
- a_BlockType = Chunk->GetBlock(Index);
+ a_BlockType = Chunk->GetBlock(a_BlockX, a_BlockY, a_BlockZ);
return true;
}
@@ -264,8 +269,7 @@ bool cChunkMap::LockedGetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIB
return false;
}
- int Index = cChunkDef::MakeIndexNoCheck(a_BlockX, a_BlockY, a_BlockZ);
- a_BlockMeta = Chunk->GetMeta(Index);
+ a_BlockMeta = Chunk->GetMeta(a_BlockX, a_BlockY, a_BlockZ);
return true;
}
@@ -1255,7 +1259,7 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP
-void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta)
+void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients)
{
cChunkInterface ChunkInterface(this);
if (a_BlockType == E_BLOCK_AIR)
@@ -1270,7 +1274,7 @@ void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a
cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ );
if ((Chunk != NULL) && Chunk->IsValid())
{
- Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta );
+ Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta, a_SendToClients);
m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, Chunk);
}
BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
@@ -1484,9 +1488,8 @@ bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure)
res = false;
continue;
}
- int idx = cChunkDef::MakeIndexNoCheck(itr->x, itr->y, itr->z);
- itr->BlockType = Chunk->GetBlock(idx);
- itr->BlockMeta = Chunk->GetMeta(idx);
+ itr->BlockType = Chunk->GetBlock(itr->x, itr->y, itr->z);
+ itr->BlockMeta = Chunk->GetMeta(itr->x, itr->y, itr->z);
}
return res;
}
@@ -1669,6 +1672,30 @@ void cChunkMap::AddEntity(cEntity * a_Entity)
+void cChunkMap::AddEntityIfNotPresent(cEntity * a_Entity)
+{
+ cCSLock Lock(m_CSLayers);
+ cChunkPtr Chunk = GetChunkNoGen(a_Entity->GetChunkX(), ZERO_CHUNK_Y, a_Entity->GetChunkZ());
+ if (
+ (Chunk == NULL) || // Chunk not present at all
+ (!Chunk->IsValid() && !a_Entity->IsPlayer()) // Chunk present, but no valid data; players need to spawn in such chunks (#953)
+ )
+ {
+ LOGWARNING("Entity at %p (%s, ID %d) spawning in a non-existent chunk, the entity is lost.",
+ a_Entity, a_Entity->GetClass(), a_Entity->GetUniqueID()
+ );
+ return;
+ }
+ if (!Chunk->HasEntity(a_Entity->GetUniqueID()))
+ {
+ Chunk->AddEntity(a_Entity);
+ }
+}
+
+
+
+
+
bool cChunkMap::HasEntity(int a_UniqueID)
{
cCSLock Lock(m_CSLayers);
@@ -2650,11 +2677,16 @@ void cChunkMap::QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ)
////////////////////////////////////////////////////////////////////////////////
// cChunkMap::cChunkLayer:
-cChunkMap::cChunkLayer::cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent)
+cChunkMap::cChunkLayer::cChunkLayer(
+ int a_LayerX, int a_LayerZ,
+ cChunkMap * a_Parent,
+ cAllocationPool<cChunkData::sChunkSection> & a_Pool
+)
: m_LayerX( a_LayerX )
, m_LayerZ( a_LayerZ )
, m_Parent( a_Parent )
, m_NumChunksLoaded( 0 )
+ , m_Pool(a_Pool)
{
memset(m_Chunks, 0, sizeof(m_Chunks));
}
@@ -2696,7 +2728,7 @@ cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkY, int a_Ch
cChunk * neixp = (LocalX < LAYER_SIZE - 1) ? m_Chunks[Index + 1] : m_Parent->FindChunk(a_ChunkX + 1, a_ChunkZ);
cChunk * neizm = (LocalZ > 0) ? m_Chunks[Index - LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX , a_ChunkZ - 1);
cChunk * neizp = (LocalZ < LAYER_SIZE - 1) ? m_Chunks[Index + LAYER_SIZE] : m_Parent->FindChunk(a_ChunkX , a_ChunkZ + 1);
- m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld(), neixm, neixp, neizm, neizp);
+ m_Chunks[Index] = new cChunk(a_ChunkX, 0, a_ChunkZ, m_Parent, m_Parent->GetWorld(), neixm, neixp, neizm, neizp, m_Pool);
}
return m_Chunks[Index];
}
diff --git a/src/ChunkMap.h b/src/ChunkMap.h
index adcf687c0..3ee0bab3c 100644
--- a/src/ChunkMap.h
+++ b/src/ChunkMap.h
@@ -5,7 +5,8 @@
#pragma once
-#include "ChunkDef.h"
+
+#include "ChunkDataCallback.h"
@@ -152,7 +153,7 @@ public:
NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ);
NIBBLETYPE GetBlockBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ);
void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockMeta);
- void SetBlock (cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta);
+ void SetBlock (cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients = true);
void QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, Int64 a_Tick, BLOCKTYPE a_PreviousBlockType = E_BLOCK_AIR);
bool GetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta);
bool GetBlockInfo (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight);
@@ -198,6 +199,10 @@ public:
/** Adds the entity to its appropriate chunk, takes ownership of the entity pointer */
void AddEntity(cEntity * a_Entity);
+ /** Adds the entity to its appropriate chunk, if the entity is not already added.
+ Takes ownership of the entity pointer */
+ void AddEntityIfNotPresent(cEntity * a_Entity);
+
/** Returns true if the entity with specified ID is present in the chunks */
bool HasEntity(int a_EntityID);
@@ -346,7 +351,11 @@ private:
class cChunkLayer
{
public:
- cChunkLayer(int a_LayerX, int a_LayerZ, cChunkMap * a_Parent);
+ cChunkLayer(
+ int a_LayerX, int a_LayerZ,
+ cChunkMap * a_Parent,
+ cAllocationPool<cChunkData::sChunkSection> & a_Pool
+ );
~cChunkLayer();
/** Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check */
@@ -390,6 +399,25 @@ private:
int m_LayerZ;
cChunkMap * m_Parent;
int m_NumChunksLoaded;
+
+ cAllocationPool<cChunkData::sChunkSection> & m_Pool;
+ };
+
+ class cStarvationCallbacks
+ : public cAllocationPool<cChunkData::sChunkSection>::cStarvationCallbacks
+ {
+ virtual void OnStartUsingReserve() override
+ {
+ LOG("Using backup memory buffer");
+ }
+ virtual void OnEndUsingReserve() override
+ {
+ LOG("Stoped using backup memory buffer");
+ }
+ virtual void OnOutOfReserve() override
+ {
+ LOG("Out of Memory");
+ }
};
typedef std::list<cChunkLayer *> cChunkLayerList;
@@ -422,6 +450,8 @@ private:
/** The cChunkStay descendants that are currently enabled in this chunkmap */
cChunkStays m_ChunkStays;
+ std::auto_ptr<cAllocationPool<cChunkData::sChunkSection> > m_Pool;
+
cChunkPtr GetChunk (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid
cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate
cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ); // Doesn't load, doesn't generate
diff --git a/src/ChunkSender.h b/src/ChunkSender.h
index a26f764a7..00565d7c3 100644
--- a/src/ChunkSender.h
+++ b/src/ChunkSender.h
@@ -27,6 +27,7 @@ Note that it may be called by world's BroadcastToChunk() if the client is still
#include "OSSupport/IsThread.h"
#include "ChunkDef.h"
+#include "ChunkDataCallback.h"
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 664bcf875..ade7e20ac 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -12,7 +12,6 @@
#include "BlockEntities/SignEntity.h"
#include "UI/Window.h"
#include "Item.h"
-#include "Piston.h"
#include "Mobs/Monster.h"
#include "ChatColor.h"
#include "OSSupport/Socket.h"
@@ -328,7 +327,7 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID)
// Send experience
m_Player->SendExperience();
- m_Player->Initialize(World);
+ m_Player->Initialize(*World);
m_State = csAuthenticated;
// Query player team
@@ -357,7 +356,7 @@ void cClientHandle::StreamChunks(void)
}
ASSERT(m_Player != NULL);
-
+
int ChunkPosX = FAST_FLOOR_DIV((int)m_Player->GetPosX(), cChunkDef::Width);
int ChunkPosZ = FAST_FLOOR_DIV((int)m_Player->GetPosZ(), cChunkDef::Width);
if ((ChunkPosX == m_LastStreamedChunkX) && (ChunkPosZ == m_LastStreamedChunkZ))
@@ -1094,18 +1093,25 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
cWorld * World = m_Player->GetWorld();
if (
- (Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) ||
- (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) ||
- (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6)
+ (a_BlockFace != BLOCK_FACE_NONE) && // The client is interacting with a specific block
+ (
+ (Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) || // The block is too far away
+ (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) ||
+ (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6)
+ )
)
{
- 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);
+ if (a_BlockY < cChunkDef::Height - 1)
{
- AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
- World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // 2 block high things
- m_Player->GetInventory().SendEquippedSlot();
}
+ if (a_BlockY > 0)
+ {
+ World->SendBlockTo(a_BlockX, a_BlockY - 1, a_BlockZ, m_Player); // 2 block high things
+ }
+ m_Player->GetInventory().SendEquippedSlot();
return;
}
@@ -1311,7 +1317,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e
if (!a_ItemHandler.GetPlacementBlockTypeMeta(World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta))
{
// Handler refused the placement, send that information back to the client:
- World->SendBlockTo(a_BlockX, a_BlockY, a_BlockY, m_Player);
+ World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
m_Player->GetInventory().SendEquippedSlot();
return;
}
@@ -1751,18 +1757,8 @@ void cClientHandle::SendData(const char * a_Data, size_t a_Size)
-void cClientHandle::MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket)
+void cClientHandle::RemoveFromWorld(void)
{
- UNUSED(a_World);
- ASSERT(m_Player != NULL);
-
- if (a_SendRespawnPacket)
- {
- SendRespawn();
- }
-
- cWorld * World = m_Player->GetWorld();
-
// Remove all associated chunks:
cChunkCoordsList Chunks;
{
@@ -1772,7 +1768,6 @@ void cClientHandle::MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket)
}
for (cChunkCoordsList::iterator itr = Chunks.begin(), end = Chunks.end(); itr != end; ++itr)
{
- World->RemoveChunkClient(itr->m_ChunkX, itr->m_ChunkZ, this);
m_Protocol->SendUnloadChunk(itr->m_ChunkX, itr->m_ChunkZ);
} // for itr - Chunks[]
@@ -2377,9 +2372,9 @@ void cClientHandle::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effec
-void cClientHandle::SendRespawn(void)
+void cClientHandle::SendRespawn(const cWorld & a_World)
{
- m_Protocol->SendRespawn();
+ m_Protocol->SendRespawn(a_World);
}
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index 659c67658..0d883f3af 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -149,7 +149,7 @@ public:
void SendPlayerSpawn (const cPlayer & a_Player);
void SendPluginMessage (const AString & a_Channel, const AString & a_Message); // Exported in ManualBindings.cpp
void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID);
- void SendRespawn (void);
+ void SendRespawn (const cWorld & a_World);
void SendExperience (void);
void SendExperienceOrb (const cExpOrb & a_ExpOrb);
void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode);
@@ -250,8 +250,9 @@ public:
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);
+ /** Called when the player moves into a different world.
+ Sends an UnloadChunk packet for each loaded chunk and resets the streamed chunks. */
+ void RemoveFromWorld(void);
/** Called when the player will enchant a Item */
void HandleEnchantItem(Byte & WindowID, Byte & Enchantment);
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 1226a2319..ee7ce06ac 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -129,9 +129,9 @@ const char * cEntity::GetParentClass(void) const
-bool cEntity::Initialize(cWorld * a_World)
+bool cEntity::Initialize(cWorld & a_World)
{
- if (cPluginManager::Get()->CallHookSpawningEntity(*a_World, *this))
+ if (cPluginManager::Get()->CallHookSpawningEntity(a_World, *this))
{
return false;
}
@@ -144,13 +144,13 @@ bool cEntity::Initialize(cWorld * a_World)
*/
m_IsInitialized = true;
- m_World = a_World;
+ m_World = &a_World;
m_World->AddEntity(this);
- cPluginManager::Get()->CallHookSpawnedEntity(*a_World, *this);
+ cPluginManager::Get()->CallHookSpawnedEntity(a_World, *this);
// Spawn the entity on the clients:
- a_World->BroadcastSpawnEntity(*this);
+ a_World.BroadcastSpawnEntity(*this);
return true;
}
@@ -179,14 +179,9 @@ void cEntity::WrapRotation(void)
void cEntity::WrapSpeed(void)
{
- // There shoudn't be a need for flipping the flag on because this function is called
- // after any update, so the flag is already turned on
- if (m_Speed.x > 78.0f) m_Speed.x = 78.0f;
- else if (m_Speed.x < -78.0f) m_Speed.x = -78.0f;
- if (m_Speed.y > 78.0f) m_Speed.y = 78.0f;
- else if (m_Speed.y < -78.0f) m_Speed.y = -78.0f;
- if (m_Speed.z > 78.0f) m_Speed.z = 78.0f;
- else if (m_Speed.z < -78.0f) m_Speed.z = -78.0f;
+ m_Speed.x = Clamp(m_Speed.x, -78.0, 78.0);
+ m_Speed.y = Clamp(m_Speed.y, -78.0, 78.0);
+ m_Speed.z = Clamp(m_Speed.z, -78.0, 78.0);
}
@@ -1076,6 +1071,17 @@ void cEntity::SetSwimState(cChunk & a_Chunk)
+void cEntity::DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
+{
+ m_Speed.Set(a_SpeedX, a_SpeedY, a_SpeedZ);
+
+ WrapSpeed();
+}
+
+
+
+
+
void cEntity::HandleAir(void)
{
// Ref.: http://www.minecraftwiki.net/wiki/Chunk_format
@@ -1428,9 +1434,7 @@ void cEntity::SetRoll(double a_Roll)
void cEntity::SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
{
- m_Speed.Set(a_SpeedX, a_SpeedY, a_SpeedZ);
-
- WrapSpeed();
+ DoSetSpeed(a_SpeedX, a_SpeedY, a_SpeedZ);
}
@@ -1438,9 +1442,7 @@ void cEntity::SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
void cEntity::SetSpeedX(double a_SpeedX)
{
- m_Speed.x = a_SpeedX;
-
- WrapSpeed();
+ SetSpeed(a_SpeedX, m_Speed.y, m_Speed.z);
}
@@ -1448,9 +1450,7 @@ void cEntity::SetSpeedX(double a_SpeedX)
void cEntity::SetSpeedY(double a_SpeedY)
{
- m_Speed.y = a_SpeedY;
-
- WrapSpeed();
+ SetSpeed(m_Speed.x, a_SpeedY, m_Speed.z);
}
@@ -1458,9 +1458,7 @@ void cEntity::SetSpeedY(double a_SpeedY)
void cEntity::SetSpeedZ(double a_SpeedZ)
{
- m_Speed.z = a_SpeedZ;
-
- WrapSpeed();
+ SetSpeed(m_Speed.x, m_Speed.y, a_SpeedZ);
}
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index 0c393c0f5..2df66e353 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -146,8 +146,9 @@ public:
cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, double a_Width, double a_Height);
virtual ~cEntity();
- /// Spawns the entity in the world; returns true if spawned, false if not (plugin disallowed)
- virtual bool Initialize(cWorld * a_World);
+ /** Spawns the entity in the world; returns true if spawned, false if not (plugin disallowed).
+ Adds the entity to the world. */
+ virtual bool Initialize(cWorld & a_World);
// tolua_begin
@@ -214,11 +215,22 @@ public:
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);
- void SetSpeedY (double a_SpeedY);
- void SetSpeedZ (double a_SpeedZ);
+
+ /** Sets the speed of the entity, measured in m / sec */
+ void SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ);
+
+ /** Sets the speed of the entity, measured in m / sec */
+ void SetSpeed(const Vector3d & a_Speed) { SetSpeed(a_Speed.x, a_Speed.y, a_Speed.z); }
+
+ /** Sets the speed in the X axis, leaving the other speed components intact. Measured in m / sec. */
+ void SetSpeedX(double a_SpeedX);
+
+ /** Sets the speed in the Y axis, leaving the other speed components intact. Measured in m / sec. */
+ void SetSpeedY(double a_SpeedY);
+
+ /** Sets the speed in the Z axis, leaving the other speed components intact. Measured in m / sec. */
+ void SetSpeedZ(double a_SpeedZ);
+
void SetWidth (double a_Width);
void AddPosX (double a_AddPosX);
@@ -421,10 +433,16 @@ public:
UNUSED(a_Killer);
}
+ /** Sets the internal world pointer to a new cWorld, doesn't update anything else. */
+ void SetWorld(cWorld * a_World) { m_World = a_World; }
+
protected:
static cCriticalSection m_CSCount;
static int m_EntityCount;
+ /** Measured in meter/second (m/s) */
+ Vector3d m_Speed;
+
int m_UniqueID;
int m_Health;
@@ -482,13 +500,15 @@ protected:
/// Time, in ticks, since the last damage dealt by the void. Reset to zero when moving out of the void.
int m_TicksSinceLastVoidDamage;
-
+
+ /** Does the actual speed-setting. The default implementation just sets the member variable value;
+ overrides can provide further processing, such as forcing players to move at the given speed. */
+ virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ);
+
virtual void Destroyed(void) {} // Called after the entity has been destroyed
- void SetWorld(cWorld * a_World) { m_World = a_World; }
-
/** Called in each tick to handle air-related processing i.e. drowning */
- virtual void HandleAir();
+ virtual void HandleAir(void);
/** Called once per tick to set IsSwimming and IsSubmerged */
virtual void SetSwimState(cChunk & a_Chunk);
@@ -504,9 +524,6 @@ private:
/** Measured in degrees, [-180, +180) */
double m_HeadYaw;
- /** Measured in meter/second (m/s) */
- Vector3d m_Speed;
-
/** Measured in degrees, [-180, +180) */
Vector3d m_Rot;
diff --git a/src/Entities/FallingBlock.cpp b/src/Entities/FallingBlock.cpp
index beb58f207..111c5fa84 100644
--- a/src/Entities/FallingBlock.cpp
+++ b/src/Entities/FallingBlock.cpp
@@ -55,9 +55,8 @@ void cFallingBlock::Tick(float a_Dt, cChunk & a_Chunk)
return;
}
- int idx = a_Chunk.MakeIndexNoCheck(BlockX - a_Chunk.GetPosX() * cChunkDef::Width, BlockY, BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width);
- BLOCKTYPE BlockBelow = a_Chunk.GetBlock(idx);
- NIBBLETYPE BelowMeta = a_Chunk.GetMeta(idx);
+ BLOCKTYPE BlockBelow = a_Chunk.GetBlock(BlockX - a_Chunk.GetPosX() * cChunkDef::Width, BlockY, BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width);
+ NIBBLETYPE BelowMeta = a_Chunk.GetMeta(BlockX - a_Chunk.GetPosX() * cChunkDef::Width, BlockY, BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width);
if (cSandSimulator::DoesBreakFallingThrough(BlockBelow, BelowMeta))
{
// Fallen onto a block that breaks this into pickups (e. g. half-slab)
diff --git a/src/Entities/ItemFrame.cpp b/src/Entities/ItemFrame.cpp
index 9dd909880..7bc7bda8d 100644
--- a/src/Entities/ItemFrame.cpp
+++ b/src/Entities/ItemFrame.cpp
@@ -55,6 +55,7 @@ void cItemFrame::KilledBy(cEntity * a_Killer)
{
if (m_Item.IsEmpty())
{
+ SetHealth(0);
super::KilledBy(a_Killer);
Destroy();
return;
@@ -69,8 +70,9 @@ void cItemFrame::KilledBy(cEntity * a_Killer)
}
SetHealth(GetMaxHealth());
- m_Item.Clear();
+ m_Item.Empty();
m_Rotation = 0;
+ SetInvulnerableTicks(0);
GetWorld()->BroadcastEntityMetadata(*this);
}
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 0dfdcfd8b..fdc0bb390 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -22,6 +22,12 @@
#include "inifile/iniFile.h"
#include "json/json.h"
+// 6000 ticks or 5 minutes
+#define PLAYER_INVENTORY_SAVE_INTERVAL 6000
+
+// 1000 = once per second
+#define PLAYER_LIST_TIME_MS 1000
+
@@ -64,6 +70,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
, m_BowCharge(0)
, m_FloaterID(-1)
, m_Team(NULL)
+ , m_TicksUntilNextSave(PLAYER_INVENTORY_SAVE_INTERVAL)
{
LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d",
a_PlayerName.c_str(), a_Client->GetIPString().c_str(),
@@ -250,7 +257,7 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
// Send Player List (Once per m_LastPlayerListTime/1000 ms)
cTimer t1;
- if (m_LastPlayerListTime + cPlayer::PLAYER_LIST_TIME_MS <= t1.GetNowTime())
+ if (m_LastPlayerListTime + PLAYER_LIST_TIME_MS <= t1.GetNowTime())
{
m_World->SendPlayerList(this);
m_LastPlayerListTime = t1.GetNowTime();
@@ -260,6 +267,16 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
{
m_LastGroundHeight = (float)GetPosY();
}
+
+ if (m_TicksUntilNextSave == 0)
+ {
+ SaveToDisk();
+ m_TicksUntilNextSave = PLAYER_INVENTORY_SAVE_INTERVAL;
+ }
+ else
+ {
+ m_TicksUntilNextSave--;
+ }
}
@@ -940,6 +957,8 @@ void cPlayer::Killed(cEntity * a_Victim)
void cPlayer::Respawn(void)
{
+ ASSERT(m_World != NULL);
+
m_Health = GetMaxHealth();
SetInvulnerableTicks(20);
@@ -952,7 +971,7 @@ void cPlayer::Respawn(void)
m_LifetimeTotalXp = 0;
// ToDo: send score to client? How?
- m_ClientHandle->SendRespawn();
+ m_ClientHandle->SendRespawn(*m_World);
// Extinguish the fire:
StopBurning();
@@ -1255,6 +1274,17 @@ Vector3d cPlayer::GetThrowSpeed(double a_SpeedCoeff) const
void cPlayer::ForceSetSpeed(const Vector3d & a_Speed)
{
SetSpeed(a_Speed);
+}
+
+
+
+
+
+void cPlayer::DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
+{
+ super::DoSetSpeed(a_SpeedX, a_SpeedY, a_SpeedZ);
+
+ // Send the speed to the client so he actualy moves
m_ClientHandle->SendEntityVelocity(*this);
}
@@ -1583,21 +1613,19 @@ bool cPlayer::MoveToWorld(const char * a_WorldName)
return false;
}
- eDimension OldDimension = m_World->GetDimension();
-
+ // Send the respawn packet:
+ if (m_ClientHandle != NULL)
+ {
+ m_ClientHandle->SendRespawn(*World);
+ }
+
// Remove all links to the old world
m_World->RemovePlayer(this);
- m_ClientHandle->RemoveFromAllChunks();
- m_World->RemoveEntity(this);
// If the dimension is different, we can send the respawn packet
// http://wiki.vg/Protocol#0x09 says "don't send if dimension is the same" as of 2013_07_02
- m_ClientHandle->MoveToWorld(*World, (OldDimension != World->GetDimension()));
- // Add player to all the necessary parts of the new world
- SetWorld(World);
- m_ClientHandle->StreamChunks();
- World->AddEntity(this);
+ // Queue adding player to the new world, including all the necessary adjustments to the object
World->AddPlayer(this);
return true;
@@ -1650,13 +1678,6 @@ bool cPlayer::LoadFromDisk()
{
LoadPermissionsFromDisk();
- // Log player permissions, cause it's what the cool kids do
- LOGINFO("Player %s has permissions:", GetName().c_str() );
- for( PermissionMap::iterator itr = m_ResolvedPermissions.begin(); itr != m_ResolvedPermissions.end(); ++itr )
- {
- if( itr->second ) LOG(" - %s", itr->first.c_str() );
- }
-
AString SourceFile;
Printf(SourceFile, "players/%s.json", GetName().c_str() );
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index b7cb27d6c..b2142a18b 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -194,7 +194,8 @@ public:
// Sets the current gamemode, doesn't check validity, doesn't send update packets to client
void LoginSetGameMode(eGameMode a_GameMode);
- /** Forces the player to move in the given direction. */
+ /** Forces the player to move in the given direction.
+ @deprecated Use SetSpeed instead. */
void ForceSetSpeed(const Vector3d & a_Speed); // tolua_export
/** Tries to move to a new position, with attachment-related checks (y == -999) */
@@ -328,6 +329,8 @@ public:
void SetVisible( bool a_bVisible ); // tolua_export
bool IsVisible(void) const { return m_bVisible; } // tolua_export
+ /** Moves the player to the specified world.
+ Returns true if successful, false on failure (world not found). */
bool MoveToWorld(const char * a_WorldName); // tolua_export
bool SaveToDisk(void);
@@ -459,7 +462,6 @@ protected:
cItem m_DraggingItem;
long long m_LastPlayerListTime;
- static const unsigned short PLAYER_LIST_TIME_MS = 1000; // 1000 = once per second
cClientHandle * m_ClientHandle;
@@ -510,6 +512,9 @@ protected:
+ /** Sets the speed and sends it to the client, so that they are forced to move so. */
+ virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override;
+
void ResolvePermissions(void);
void ResolveGroups(void);
@@ -537,6 +542,10 @@ protected:
Set by a right click on unoccupied bed, unset by a time fast forward or teleport */
bool m_bIsInBed;
+ /** How long till the player's inventory will be saved
+ Default save interval is #defined in PLAYER_INVENTORY_SAVE_INTERVAL */
+ unsigned int m_TicksUntilNextSave;
+
} ; // tolua_export
diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp
index 3e48d310c..95c494569 100644
--- a/src/Entities/ProjectileEntity.cpp
+++ b/src/Entities/ProjectileEntity.cpp
@@ -76,12 +76,12 @@ protected:
eBlockFace Face;
if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face))
{
- if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile))
+ Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff;
+ if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, a_BlockX, a_BlockY, a_BlockZ, Face, &Intersection))
{
return false;
}
- Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff;
m_Projectile->OnHitSolidBlock(Intersection, Face);
return true;
}
diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp
index 32a687201..47ba080c6 100644
--- a/src/Generating/BioGen.cpp
+++ b/src/Generating/BioGen.cpp
@@ -212,7 +212,7 @@ void cBioGenCache::InitializeBiomeGen(cIniFile & a_IniFile)
void cBiomeGenList::InitializeBiomes(const AString & a_Biomes)
{
- AStringVector Split = StringSplit(a_Biomes, ",");
+ AStringVector Split = StringSplitAndTrim(a_Biomes, ",");
// Convert each string in the list into biome:
for (AStringVector::const_iterator itr = Split.begin(); itr != Split.end(); ++itr)
diff --git a/src/Generating/Caves.cpp b/src/Generating/Caves.cpp
index 872e3341d..6aa7fd4cb 100644
--- a/src/Generating/Caves.cpp
+++ b/src/Generating/Caves.cpp
@@ -125,7 +125,7 @@ public:
int m_BlockX;
int m_BlockZ;
- cCaveSystem(int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise);
+ cCaveSystem(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise);
~cCaveSystem();
protected:
@@ -574,8 +574,8 @@ AString cCaveTunnel::ExportAsSVG(int a_Color, int a_OffsetX, int a_OffsetZ) cons
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cStructGenWormNestCaves::cCaveSystem:
-cStructGenWormNestCaves::cCaveSystem::cCaveSystem(int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise) :
- super(a_OriginX, a_OriginZ),
+cStructGenWormNestCaves::cCaveSystem::cCaveSystem(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise) :
+ super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_Size(a_Size)
{
int Num = 1 + a_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) % 3;
@@ -690,9 +690,9 @@ int cStructGenWormNestCaves::cCaveSystem::GetRadius(cNoise & a_Noise, int a_Orig
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cStructGenWormNestCaves:
-cGridStructGen::cStructurePtr cStructGenWormNestCaves::CreateStructure(int a_OriginX, int a_OriginZ)
+cGridStructGen::cStructurePtr cStructGenWormNestCaves::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
- return cStructurePtr(new cCaveSystem(a_OriginX, a_OriginZ, m_MaxOffset, m_Size, m_Noise));
+ return cStructurePtr(new cCaveSystem(a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxOffset, m_Size, m_Noise));
}
diff --git a/src/Generating/Caves.h b/src/Generating/Caves.h
index 254dcddbd..0e17acf9e 100644
--- a/src/Generating/Caves.h
+++ b/src/Generating/Caves.h
@@ -69,7 +69,7 @@ class cStructGenWormNestCaves :
typedef cGridStructGen super;
public:
cStructGenWormNestCaves(int a_Seed, int a_Size = 64, int a_Grid = 96, int a_MaxOffset = 128) :
- super(a_Seed, a_Grid, a_Grid, a_Size + a_MaxOffset, a_Size + a_MaxOffset, 100),
+ super(a_Seed, a_Grid, a_Grid, a_MaxOffset, a_MaxOffset, a_Size, a_Size, 100),
m_Noise(a_Seed),
m_Size(a_Size),
m_MaxOffset(a_MaxOffset),
@@ -86,7 +86,7 @@ protected:
int m_Grid; // average spacing of the nests
// cGridStructGen override:
- virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
+ virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ;
diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp
index 578bb2481..688d19c40 100644
--- a/src/Generating/CompoGen.cpp
+++ b/src/Generating/CompoGen.cpp
@@ -561,10 +561,16 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc)
// Interpolate the lowest floor:
for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++)
{
- FloorLo[INTERPOL_X * x + 17 * INTERPOL_Z * z] =
+ //*
+ FloorLo[INTERPOL_X * x + 17 * INTERPOL_Z * z] =
m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, 0, BaseZ + INTERPOL_Z * z) *
m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, 0, BaseZ + INTERPOL_Z * z) /
256;
+ //*/
+ /*
+ FloorLo[INTERPOL_X * x + 17 * INTERPOL_Z * z] =
+ m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, 0, BaseZ + INTERPOL_Z * z) / 256;
+ //*/
} // for x, z - FloorLo[]
LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo);
@@ -574,10 +580,16 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc)
// First update the high floor:
for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++)
{
+ //*
FloorHi[INTERPOL_X * x + 17 * INTERPOL_Z * z] =
m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) *
m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) /
256;
+ //*/
+ /*
+ FloorHi[INTERPOL_X * x + 17 * INTERPOL_Z * z] =
+ m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) / 256;
+ //*/
} // for x, z - FloorLo[]
LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorHi);
diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp
index 2e886336f..22941dcbe 100644
--- a/src/Generating/ComposableGenerator.cpp
+++ b/src/Generating/ComposableGenerator.cpp
@@ -24,7 +24,10 @@
#include "NetherFortGen.h"
#include "Noise3DGenerator.h"
#include "POCPieceGenerator.h"
+#include "RainbowRoadsGen.h"
#include "Ravines.h"
+#include "UnderwaterBaseGen.h"
+#include "VillageGen.h"
@@ -32,6 +35,7 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cTerrainCompositionGen:
+
cTerrainCompositionGen * cTerrainCompositionGen::CreateCompositionGen(cIniFile & a_IniFile, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed)
{
AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", "");
@@ -353,12 +357,13 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
else if (NoCaseCompare(*itr, "MineShafts") == 0)
{
int GridSize = a_IniFile.GetValueSetI("Generator", "MineShaftsGridSize", 512);
+ int MaxOffset = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxOffset", 256);
int MaxSystemSize = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxSystemSize", 160);
int ChanceCorridor = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor", 600);
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, MaxOffset, MaxSystemSize,
ChanceCorridor, ChanceCrossing, ChanceStaircase
));
}
@@ -372,9 +377,10 @@ 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", 12);
- m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxDepth));
+ int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512);
+ int MaxOffset = a_IniFile.GetValueSetI("Generator", "NetherFortMaxOffset", 128);
+ int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12);
+ m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxOffset, MaxDepth));
}
else if (NoCaseCompare(*itr, "OreNests") == 0)
{
@@ -388,6 +394,14 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
{
m_FinishGens.push_back(new cFinishGenPreSimulator);
}
+ else if (NoCaseCompare(*itr, "RainbowRoads") == 0)
+ {
+ int GridSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsGridSize", 512);
+ int MaxOffset = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxOffset", 128);
+ int MaxDepth = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxDepth", 30);
+ int MaxSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxSize", 260);
+ m_FinishGens.push_back(new cRainbowRoadsGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize));
+ }
else if (NoCaseCompare(*itr, "Ravines") == 0)
{
m_FinishGens.push_back(new cStructGenRavines(Seed, 128));
@@ -404,6 +418,24 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
{
m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen));
}
+ else if (NoCaseCompare(*itr, "UnderwaterBases") == 0)
+ {
+ int GridSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseGridSize", 1024);
+ int MaxOffset = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxOffset", 128);
+ int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7);
+ int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128);
+ m_FinishGens.push_back(new cUnderwaterBaseGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, *m_BiomeGen));
+ }
+ else if (NoCaseCompare(*itr, "Villages") == 0)
+ {
+ int GridSize = a_IniFile.GetValueSetI("Generator", "VillageGridSize", 384);
+ int MaxOffset = a_IniFile.GetValueSetI("Generator", "VillageMaxOffset", 128);
+ int MaxDepth = a_IniFile.GetValueSetI("Generator", "VillageMaxDepth", 2);
+ int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128);
+ int MinDensity = a_IniFile.GetValueSetI("Generator", "VillageMinDensity", 50);
+ int MaxDensity = a_IniFile.GetValueSetI("Generator", "VillageMaxDensity", 80);
+ m_FinishGens.push_back(new cVillageGen(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, *m_BiomeGen, *m_HeightGen));
+ }
else if (NoCaseCompare(*itr, "WaterLakes") == 0)
{
int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25);
@@ -415,7 +447,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
}
else if (NoCaseCompare(*itr, "WormNestCaves") == 0)
{
- m_FinishGens.push_back(new cStructGenWormNestCaves(Seed));
+ int Size = a_IniFile.GetValueSetI("Generator", "WormNestCavesSize", 64);
+ int Grid = a_IniFile.GetValueSetI("Generator", "WormNestCavesGrid", 96);
+ int MaxOffset = a_IniFile.GetValueSetI("Generator", "WormNestMaxOffset", 32);
+ m_FinishGens.push_back(new cStructGenWormNestCaves(Seed, Size, Grid, MaxOffset));
}
else
{
diff --git a/src/Generating/GridStructGen.cpp b/src/Generating/GridStructGen.cpp
index bfa6bccb1..2931df3eb 100644
--- a/src/Generating/GridStructGen.cpp
+++ b/src/Generating/GridStructGen.cpp
@@ -9,20 +9,51 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cEmptyStructure:
+
+/** A cStructure descendant representing an empty structure.
+Used when the generator descended from cGridStructGen doesn't return any structure, to keep at least the
+Origin coords so that the structure isn't queried over and over again. */
+class cEmptyStructure :
+ public cGridStructGen::cStructure
+{
+ typedef cGridStructGen::cStructure super;
+
+public:
+ cEmptyStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) :
+ super(a_GridX, a_GridZ, a_OriginX, a_OriginZ)
+ {
+ }
+
+protected:
+ virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override
+ {
+ // Do nothing
+ }
+} ;
+
+
+
+
+
cGridStructGen::cGridStructGen(
int a_Seed,
int a_GridSizeX, int a_GridSizeZ,
+ int a_MaxOffsetX, int a_MaxOffsetZ,
int a_MaxStructureSizeX, int a_MaxStructureSizeZ,
size_t a_MaxCacheSize
) :
- m_Seed(a_Seed),
+ m_Noise(a_Seed),
m_GridSizeX(a_GridSizeX),
m_GridSizeZ(a_GridSizeZ),
+ m_MaxOffsetX(a_MaxOffsetX),
+ m_MaxOffsetZ(a_MaxOffsetZ),
m_MaxStructureSizeX(a_MaxStructureSizeX),
m_MaxStructureSizeZ(a_MaxStructureSizeZ),
m_MaxCacheSize(a_MaxCacheSize)
{
- size_t NumStructuresPerQuery = (size_t)((m_MaxStructureSizeX / m_GridSizeX + 1) * (m_MaxStructureSizeZ / m_GridSizeZ + 1));
+ size_t NumStructuresPerQuery = (size_t)(((m_MaxStructureSizeX + m_MaxOffsetX) / m_GridSizeX + 1) * ((m_MaxStructureSizeZ + m_MaxOffsetZ) / m_GridSizeZ + 1));
if (NumStructuresPerQuery > m_MaxCacheSize)
{
m_MaxCacheSize = NumStructuresPerQuery * 4;
@@ -40,10 +71,10 @@ cGridStructGen::cGridStructGen(
void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructurePtrs & a_Structures)
{
// Calculate the min and max grid coords of the structures to be returned:
- int MinBlockX = a_ChunkX * cChunkDef::Width - m_MaxStructureSizeX;
- int MinBlockZ = a_ChunkZ * cChunkDef::Width - m_MaxStructureSizeZ;
- int MaxBlockX = a_ChunkX * cChunkDef::Width + m_MaxStructureSizeX + cChunkDef::Width - 1;
- int MaxBlockZ = a_ChunkZ * cChunkDef::Width + m_MaxStructureSizeZ + cChunkDef::Width - 1;
+ int MinBlockX = a_ChunkX * cChunkDef::Width - m_MaxStructureSizeX - m_MaxOffsetX;
+ int MinBlockZ = a_ChunkZ * cChunkDef::Width - m_MaxStructureSizeZ - m_MaxOffsetZ;
+ int MaxBlockX = a_ChunkX * cChunkDef::Width + m_MaxStructureSizeX + m_MaxOffsetX + cChunkDef::Width - 1;
+ int MaxBlockZ = a_ChunkZ * cChunkDef::Width + m_MaxStructureSizeZ + m_MaxOffsetZ + cChunkDef::Width - 1;
int MinGridX = MinBlockX / m_GridSizeX;
int MinGridZ = MinBlockZ / m_GridSizeZ;
int MaxGridX = (MaxBlockX + m_GridSizeX - 1) / m_GridSizeX;
@@ -75,14 +106,14 @@ void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructur
// Create those structures that haven't been in the cache:
for (int x = MinGridX; x < MaxGridX; x++)
{
- int OriginX = x * m_GridSizeX;
+ int GridX = x * m_GridSizeX;
for (int z = MinGridZ; z < MaxGridZ; z++)
{
- int OriginZ = z * m_GridSizeZ;
+ int GridZ = z * m_GridSizeZ;
bool Found = false;
for (cStructurePtrs::const_iterator itr = a_Structures.begin(), end = a_Structures.end(); itr != end; ++itr)
{
- if (((*itr)->m_OriginX == OriginX) && ((*itr)->m_OriginZ == OriginZ))
+ if (((*itr)->m_GridX == GridX) && ((*itr)->m_GridZ == GridZ))
{
Found = true;
break;
@@ -90,7 +121,14 @@ void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructur
} // for itr - a_Structures[]
if (!Found)
{
- a_Structures.push_back(CreateStructure(OriginX, OriginZ));
+ int OriginX = GridX + ((m_Noise.IntNoise2DInt(GridX + 3, GridZ + 5) / 7) % (m_MaxOffsetX * 2)) - m_MaxOffsetX;
+ int OriginZ = GridZ + ((m_Noise.IntNoise2DInt(GridX + 5, GridZ + 3) / 7) % (m_MaxOffsetZ * 2)) - m_MaxOffsetZ;
+ cStructurePtr Structure = CreateStructure(GridX, GridZ, OriginX, OriginZ);
+ if (Structure.get() == NULL)
+ {
+ Structure.reset(new cEmptyStructure(GridX, GridZ, OriginX, OriginZ));
+ }
+ a_Structures.push_back(Structure);
}
} // for z
} // for x
diff --git a/src/Generating/GridStructGen.h b/src/Generating/GridStructGen.h
index 234cc75c5..03131fce9 100644
--- a/src/Generating/GridStructGen.h
+++ b/src/Generating/GridStructGen.h
@@ -10,6 +10,7 @@
#pragma once
#include "ComposableGenerator.h"
+#include "../Noise.h"
@@ -19,7 +20,12 @@
Defines a grid in the XZ space with predefined cell size in each direction. Each cell then receives exactly
one structure (provided by the descendant class). The structure is placed within the cell, but doesn't need
to be bounded by the cell, it can be well outside the cell; the generator uses the MaxStructureSize parameter
-to determine how far away from the cell the structure can be at most.
+to determine how far away from the cell the structure can be at most. Each structure has an offset from the
+grid's center point, the offset is generated randomly from a range given to this class as a parameter.
+
+Each structure thus contains the coords of its grid center (m_GridX, m_GridZ) and the actual origin from
+which it's built (m_OriginX, m_OriginZ).
+
This class provides a cache for the structures generated for successive chunks and manages that cache. It
also provides the cFinishGen override that uses the cache to actually generate the structure into chunk data.
@@ -39,24 +45,21 @@ class cGridStructGen :
public cFinishGen
{
public:
- cGridStructGen(
- int a_Seed,
- int a_GridSizeX, int a_GridSizeZ,
- int a_MaxStructureSizeX, int a_MaxStructureSizeZ,
- size_t a_MaxCacheSize
- );
-
-protected:
/** Represents a single structure that occupies the grid point. Knows how to draw itself into a chunk. */
class cStructure
{
public:
- /** The origin (the coords of the gridpoint for which the structure is generated) */
+ /** The grid point for which the structure is generated. */
+ int m_GridX, m_GridZ;
+
+ /** The origin (the coords for which the structure is generated) */
int m_OriginX, m_OriginZ;
- /** Creates a structure that has its originset at the specified coords. */
- cStructure (int a_OriginX, int a_OriginZ) :
+ /** Creates a structure that has its origin set at the specified coords. */
+ cStructure (int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) :
+ m_GridX(a_GridX),
+ m_GridZ(a_GridZ),
m_OriginX(a_OriginX),
m_OriginZ(a_OriginZ)
{
@@ -75,15 +78,33 @@ protected:
typedef std::list<cStructurePtr> cStructurePtrs;
- /** Seed for generating the semi-random grid. */
+ cGridStructGen(
+ int a_Seed,
+ int a_GridSizeX, int a_GridSizeZ,
+ int a_MaxOffsetX, int a_MaxOffsetZ,
+ int a_MaxStructureSizeX, int a_MaxStructureSizeZ,
+ size_t a_MaxCacheSize
+ );
+
+protected:
+ /** Seed for generating grid offsets and also available for descendants. */
int m_Seed;
+ /** The noise used for generating grid offsets. */
+ cNoise m_Noise;
+
/** The size of each grid's cell in the X axis */
int m_GridSizeX;
/** The size of each grid's cell in the Z axis */
int m_GridSizeZ;
+ /** The maximum offset of the structure's origin from the grid midpoint, in X coord. */
+ int m_MaxOffsetX;
+
+ /** The maximum offset of the structure's origin from the grid midpoint, in Z coord. */
+ int m_MaxOffsetZ;
+
/** Maximum theoretical size of the structure in the X axis.
This limits the structures considered for a single chunk, so the lesser the number, the better performance.
Structures large than this may get cropped. */
@@ -115,7 +136,7 @@ protected:
// Functions for the descendants to override:
/** Create a new structure at the specified gridpoint */
- virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) = 0;
+ virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) = 0;
} ;
diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp
index 3621421c2..25ac912fd 100644
--- a/src/Generating/HeiGen.cpp
+++ b/src/Generating/HeiGen.cpp
@@ -47,6 +47,10 @@ cTerrainHeightGen * cTerrainHeightGen::CreateHeightGen(cIniFile &a_IniFile, cBio
{
res = new cEndGen(a_Seed);
}
+ else if (NoCaseCompare(HeightGenName, "Mountains") == 0)
+ {
+ res = new cHeiGenMountains(a_Seed);
+ }
else if (NoCaseCompare(HeightGenName, "Noise3D") == 0)
{
res = new cNoise3DComposable(a_Seed);
@@ -301,6 +305,68 @@ void cHeiGenClassic::InitializeHeightGen(cIniFile & a_IniFile)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cHeiGenMountains:
+
+cHeiGenMountains::cHeiGenMountains(int a_Seed) :
+ m_Seed(a_Seed),
+ m_Noise(a_Seed)
+{
+}
+
+
+
+
+
+void cHeiGenMountains::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap)
+{
+ NOISE_DATATYPE StartX = (NOISE_DATATYPE)(a_ChunkX * cChunkDef::Width);
+ NOISE_DATATYPE EndX = (NOISE_DATATYPE)(a_ChunkX * cChunkDef::Width + cChunkDef::Width - 1);
+ NOISE_DATATYPE StartZ = (NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width);
+ NOISE_DATATYPE EndZ = (NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width + cChunkDef::Width - 1);
+ NOISE_DATATYPE Workspace[16 * 16];
+ NOISE_DATATYPE Noise[16 * 16];
+ NOISE_DATATYPE PerlinNoise[16 * 16];
+ m_Noise.Generate2D(Noise, 16, 16, StartX, EndX, StartZ, EndZ, Workspace);
+ m_Perlin.Generate2D(PerlinNoise, 16, 16, StartX, EndX, StartZ, EndZ, Workspace);
+ for (int z = 0; z < cChunkDef::Width; z++)
+ {
+ int IdxZ = z * cChunkDef::Width;
+ for (int x = 0; x < cChunkDef::Width; x++)
+ {
+ int idx = IdxZ + x;
+ int hei = 100 - (int)((Noise[idx] + PerlinNoise[idx]) * 15);
+ if (hei < 10)
+ {
+ hei = 10;
+ }
+ if (hei > 250)
+ {
+ hei = 250;
+ }
+ cChunkDef::SetHeight(a_HeightMap, x , z, hei);
+ } // for x
+ } // for z
+}
+
+
+
+
+
+void cHeiGenMountains::InitializeHeightGen(cIniFile & a_IniFile)
+{
+ // TODO: Read the params from an INI file
+ m_Noise.AddOctave(0.1f, 0.1f);
+ m_Noise.AddOctave(0.05f, 0.5f);
+ m_Noise.AddOctave(0.02f, 1.5f);
+
+ m_Perlin.AddOctave(0.01f, 1.5f);
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cHeiGenBiomal:
const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[256] =
diff --git a/src/Generating/HeiGen.h b/src/Generating/HeiGen.h
index 1376f2a25..5c106c7d9 100644
--- a/src/Generating/HeiGen.h
+++ b/src/Generating/HeiGen.h
@@ -106,6 +106,27 @@ protected:
+class cHeiGenMountains :
+ public cTerrainHeightGen
+{
+public:
+ cHeiGenMountains(int a_Seed);
+
+protected:
+
+ int m_Seed;
+ cRidgedMultiNoise m_Noise;
+ cPerlinNoise m_Perlin;
+
+ // cTerrainHeightGen overrides:
+ virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override;
+ virtual void InitializeHeightGen(cIniFile & a_IniFile) override;
+} ;
+
+
+
+
+
class cHeiGenBiomal :
public cTerrainHeightGen
{
diff --git a/src/Generating/MineShafts.cpp b/src/Generating/MineShafts.cpp
index 81ae6481d..ab9b1aa29 100644
--- a/src/Generating/MineShafts.cpp
+++ b/src/Generating/MineShafts.cpp
@@ -248,7 +248,8 @@ public:
/** Creates and generates the entire system */
cMineShaftSystem(
- int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise,
+ int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ,
+ int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise,
int a_ProbLevelCorridor, int a_ProbLevelCrossing, int a_ProbLevelStaircase
);
@@ -278,10 +279,11 @@ public:
// cStructGenMineShafts::cMineShaftSystem:
cStructGenMineShafts::cMineShaftSystem::cMineShaftSystem(
- int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise,
+ int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ,
+ int a_GridSize, int a_MaxSystemSize, cNoise & a_Noise,
int a_ProbLevelCorridor, int a_ProbLevelCrossing, int a_ProbLevelStaircase
) :
- super(a_OriginX, a_OriginZ),
+ super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_GridSize(a_GridSize),
m_MaxRecursion(8), // TODO: settable
m_ProbLevelCorridor(a_ProbLevelCorridor),
@@ -1280,10 +1282,10 @@ void cMineShaftStaircase::ProcessChunk(cChunkDesc & a_ChunkDesc)
// cStructGenMineShafts:
cStructGenMineShafts::cStructGenMineShafts(
- int a_Seed, int a_GridSize, int a_MaxSystemSize,
+ int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxSystemSize,
int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase
) :
- super(a_Seed, a_GridSize, a_GridSize, a_MaxSystemSize, a_MaxSystemSize, 100),
+ super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSystemSize, a_MaxSystemSize, 100),
m_Noise(a_Seed),
m_GridSize(a_GridSize),
m_MaxSystemSize(a_MaxSystemSize),
@@ -1297,9 +1299,9 @@ cStructGenMineShafts::cStructGenMineShafts(
-cGridStructGen::cStructurePtr cStructGenMineShafts::CreateStructure(int a_OriginX, int a_OriginZ)
+cGridStructGen::cStructurePtr cStructGenMineShafts::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
- return cStructurePtr(new cMineShaftSystem(a_OriginX, a_OriginZ, m_GridSize, m_MaxSystemSize, m_Noise, m_ProbLevelCorridor, m_ProbLevelCrossing, m_ProbLevelStaircase));
+ return cStructurePtr(new cMineShaftSystem(a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_GridSize, m_MaxSystemSize, m_Noise, m_ProbLevelCorridor, m_ProbLevelCrossing, m_ProbLevelStaircase));
}
diff --git a/src/Generating/MineShafts.h b/src/Generating/MineShafts.h
index c29b6cdac..2850db571 100644
--- a/src/Generating/MineShafts.h
+++ b/src/Generating/MineShafts.h
@@ -23,7 +23,7 @@ class cStructGenMineShafts :
public:
cStructGenMineShafts(
- int a_Seed, int a_GridSize, int a_MaxSystemSize,
+ int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxSystemSize,
int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase
);
@@ -43,7 +43,7 @@ protected:
int m_ProbLevelStaircase; ///< Probability level of a branch object being the staircase, minus Crossing
// cGridStructGen overrides:
- virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
+ virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ;
diff --git a/src/Generating/NetherFortGen.cpp b/src/Generating/NetherFortGen.cpp
index 3867ec80c..23fa56048 100644
--- a/src/Generating/NetherFortGen.cpp
+++ b/src/Generating/NetherFortGen.cpp
@@ -26,8 +26,8 @@ public:
cPlacedPieces m_Pieces;
- cNetherFort(cNetherFortGen & a_ParentGen, int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxDepth, int a_Seed) :
- super(a_OriginX, a_OriginZ),
+ cNetherFort(cNetherFortGen & a_ParentGen, int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_GridSize, int a_MaxDepth, int a_Seed) :
+ super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_ParentGen(a_ParentGen),
m_GridSize(a_GridSize),
m_Seed(a_Seed)
@@ -108,8 +108,8 @@ cPrefabPiecePool cNetherFortGen::m_PiecePool(g_NetherFortPrefabs, g_NetherFortPr
-cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth) :
- super(a_Seed, a_GridSize, a_GridSize, a_MaxDepth * 10, a_MaxDepth * 10, 200),
+cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth) :
+ super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxDepth * 10, a_MaxDepth * 10, 200),
m_MaxDepth(a_MaxDepth)
{
/*
@@ -124,8 +124,11 @@ cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth) :
-cGridStructGen::cStructurePtr cNetherFortGen::CreateStructure(int a_OriginX, int a_OriginZ)
+cGridStructGen::cStructurePtr cNetherFortGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
- return cStructurePtr(new cNetherFort(*this, a_OriginX, a_OriginZ, m_GridSizeX, m_MaxDepth, m_Seed));
+ return cStructurePtr(new cNetherFort(*this, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_GridSizeX, m_MaxDepth, m_Seed));
}
+
+
+
diff --git a/src/Generating/NetherFortGen.h b/src/Generating/NetherFortGen.h
index f35801a3c..9b31aa0e2 100644
--- a/src/Generating/NetherFortGen.h
+++ b/src/Generating/NetherFortGen.h
@@ -23,7 +23,7 @@ class cNetherFortGen :
typedef cGridStructGen super;
public:
- cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth);
+ cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth);
protected:
friend class cNetherFortPerfTest; // fwd: NetherFortGen.cpp
@@ -37,7 +37,7 @@ protected:
// cGridStructGen overrides:
- virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
+ virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ;
diff --git a/src/Generating/POCPieceGenerator.cpp b/src/Generating/POCPieceGenerator.cpp
index 9ed4b565e..491f4d206 100644
--- a/src/Generating/POCPieceGenerator.cpp
+++ b/src/Generating/POCPieceGenerator.cpp
@@ -186,6 +186,11 @@ cPOCPieceGenerator::cPOCPieceGenerator(int a_Seed) :
cPOCPieceGenerator::~cPOCPieceGenerator()
{
cPieceGenerator::FreePieces(m_Pieces);
+ for (cPieces::iterator itr = m_AvailPieces.begin(), end = m_AvailPieces.end(); itr != end; ++itr)
+ {
+ delete *itr;
+ }
+ m_AvailPieces.clear();
}
diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp
index ce19c1c95..5de231f75 100644
--- a/src/Generating/PieceGenerator.cpp
+++ b/src/Generating/PieceGenerator.cpp
@@ -286,7 +286,8 @@ cPlacedPiece::cPlacedPiece(const cPlacedPiece * a_Parent, const cPiece & a_Piece
m_Parent(a_Parent),
m_Piece(&a_Piece),
m_Coords(a_Coords),
- m_NumCCWRotations(a_NumCCWRotations)
+ m_NumCCWRotations(a_NumCCWRotations),
+ m_HasBeenMovedToGround(false)
{
m_Depth = (m_Parent == NULL) ? 0 : (m_Parent->GetDepth() + 1);
m_HitBox = a_Piece.RotateMoveHitBox(a_NumCCWRotations, a_Coords.x, a_Coords.y, a_Coords.z);
@@ -297,6 +298,36 @@ cPlacedPiece::cPlacedPiece(const cPlacedPiece * a_Parent, const cPiece & a_Piece
+cPiece::cConnector cPlacedPiece::GetRotatedConnector(size_t a_Index) const
+{
+ cPiece::cConnectors Connectors = m_Piece->GetConnectors();
+ ASSERT(Connectors.size() >= a_Index);
+ return m_Piece->RotateMoveConnector(Connectors[a_Index], m_NumCCWRotations, m_Coords.x, m_Coords.y, m_Coords.z);
+}
+
+
+
+
+
+cPiece::cConnector cPlacedPiece::GetRotatedConnector(const cPiece::cConnector & a_Connector) const
+{
+ return m_Piece->RotateMoveConnector(a_Connector, m_NumCCWRotations, m_Coords.x, m_Coords.y, m_Coords.z);
+}
+
+
+
+
+
+void cPlacedPiece::MoveToGroundBy(int a_OffsetY)
+{
+ m_Coords.y += a_OffsetY;
+ m_HasBeenMovedToGround = true;
+}
+
+
+
+
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cPieceGenerator:
@@ -331,7 +362,31 @@ cPlacedPiece * cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockY, i
// Choose a random one of the starting pieces:
cPieces StartingPieces = m_PiecePool.GetStartingPieces();
- cPiece * StartingPiece = StartingPieces[rnd % StartingPieces.size()];
+ int Total = 0;
+ for (cPieces::const_iterator itr = StartingPieces.begin(), end = StartingPieces.end(); itr != end; ++itr)
+ {
+ Total += m_PiecePool.GetStartingPieceWeight(**itr);
+ }
+ cPiece * StartingPiece;
+ if (Total > 0)
+ {
+ int Chosen = rnd % Total;
+ StartingPiece = StartingPieces.front();
+ for (cPieces::const_iterator itr = StartingPieces.begin(), end = StartingPieces.end(); itr != end; ++itr)
+ {
+ Chosen -= m_PiecePool.GetStartingPieceWeight(**itr);
+ if (Chosen <= 0)
+ {
+ StartingPiece = *itr;
+ break;
+ }
+ }
+ }
+ else
+ {
+ // All pieces returned zero weight, but we need one to start. Choose with equal chance:
+ StartingPiece = StartingPieces[rnd % StartingPieces.size()];
+ }
rnd = rnd >> 16;
// Choose a random supported rotation:
diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h
index 16bec3bb4..fd8576706 100644
--- a/src/Generating/PieceGenerator.h
+++ b/src/Generating/PieceGenerator.h
@@ -110,6 +110,7 @@ public:
virtual cPieces GetStartingPieces(void) = 0;
/** Returns the relative weight with which the a_NewPiece is to be selected for placing under a_PlacedPiece through a_ExistingConnector.
+ a_ExistingConnector is the original connector, before any movement or rotation is applied to it.
This allows the pool to tweak the piece's chances, based on the previous pieces in the tree and the connector used.
The higher the number returned, the higher the chance the piece will be chosen. 0 means the piece will never be chosen.
*/
@@ -119,6 +120,15 @@ public:
const cPiece & a_NewPiece
) { return 1; }
+ /** Returns the relative weight with which the a_NewPiece is to be selected for placing as the first piece.
+ This allows the pool to tweak the piece's chances.
+ The higher the number returned, the higher the chance the piece will be chosen. 0 means the piece will not be chosen.
+ If all pieces return 0, a random piece is chosen, with all equal chances.
+ */
+ virtual int GetStartingPieceWeight(
+ const cPiece & a_NewPiece
+ ) { return 1; }
+
/** Called after a piece is placed, to notify the pool that it has been used.
The pool may adjust the pieces it will return the next time. */
virtual void PiecePlaced(const cPiece & a_Piece) = 0;
@@ -138,19 +148,41 @@ class cPlacedPiece
public:
cPlacedPiece(const cPlacedPiece * a_Parent, const cPiece & a_Piece, const Vector3i & a_Coords, int a_NumCCWRotations);
- const cPiece & GetPiece (void) const { return *m_Piece; }
- const Vector3i & GetCoords (void) const { return m_Coords; }
- int GetNumCCWRotations(void) const { return m_NumCCWRotations; }
- const cCuboid & GetHitBox (void) const { return m_HitBox; }
- int GetDepth (void) const { return m_Depth; }
+ const cPlacedPiece * GetParent (void) const { return m_Parent; }
+ const cPiece & GetPiece (void) const { return *m_Piece; }
+ const Vector3i & GetCoords (void) const { return m_Coords; }
+ int GetNumCCWRotations (void) const { return m_NumCCWRotations; }
+ const cCuboid & GetHitBox (void) const { return m_HitBox; }
+ int GetDepth (void) const { return m_Depth; }
+ bool HasBeenMovedToGround(void) const { return m_HasBeenMovedToGround; }
+
+ /** Returns the coords as a modifiable object. */
+ Vector3i & GetCoords(void) { return m_Coords; }
+
+ /** Returns the connector at the specified index, rotated in the actual placement.
+ Undefined behavior if a_Index is out of range. */
+ cPiece::cConnector GetRotatedConnector(size_t a_Index) const;
+
+ /** Returns a copy of the specified connector, modified to account for the translation and rotation for
+ this placement. */
+ cPiece::cConnector GetRotatedConnector(const cPiece::cConnector & a_Connector) const;
+
+ /** Moves the placed piece Y-wise by the specified offset.
+ Sets m_HasBeenMovedToGround to true, too.
+ Used eg. by village houses. */
+ void MoveToGroundBy(int a_OffsetY);
protected:
const cPlacedPiece * m_Parent;
const cPiece * m_Piece;
Vector3i m_Coords;
int m_NumCCWRotations;
- cCuboid m_HitBox;
- int m_Depth;
+ cCuboid m_HitBox; // Hitbox of the placed piece, in world coords
+ int m_Depth; // Depth in the generated piece tree
+
+ /** Set to true once the piece has been moved Y-wise.
+ Used eg. by village houses. */
+ bool m_HasBeenMovedToGround;
};
typedef std::vector<cPlacedPiece *> cPlacedPieces;
diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp
index 0f20603be..2ab1455b9 100644
--- a/src/Generating/Prefab.cpp
+++ b/src/Generating/Prefab.cpp
@@ -108,6 +108,9 @@ static const cPrefab::sDef g_TestPrefabDef =
// AddWeightIfSame:
1000,
+
+ // MoveToGround:
+ false,
};
static cPrefab g_TestPrefab(g_TestPrefabDef);
@@ -127,7 +130,8 @@ cPrefab::cPrefab(const cPrefab::sDef & a_Def) :
m_MergeStrategy(a_Def.m_MergeStrategy),
m_ShouldExtendFloor(a_Def.m_ShouldExtendFloor),
m_DefaultWeight(a_Def.m_DefaultWeight),
- m_AddWeightIfSame(a_Def.m_AddWeightIfSame)
+ m_AddWeightIfSame(a_Def.m_AddWeightIfSame),
+ m_MoveToGround(a_Def.m_MoveToGround)
{
m_BlockArea[0].Create(m_Size);
CharMap cm;
@@ -136,6 +140,34 @@ cPrefab::cPrefab(const cPrefab::sDef & a_Def) :
ParseConnectors(a_Def.m_Connectors);
ParseDepthWeight(a_Def.m_DepthWeight);
+ AddRotatedBlockAreas();
+}
+
+
+
+
+
+cPrefab::cPrefab(const cBlockArea & a_Image, int a_AllowedRotations) :
+ m_Size(a_Image.GetSize()),
+ m_AllowedRotations(a_AllowedRotations),
+ m_MergeStrategy(cBlockArea::msOverwrite),
+ m_ShouldExtendFloor(false),
+ m_DefaultWeight(1),
+ m_AddWeightIfSame(0),
+ m_MoveToGround(false)
+{
+ m_HitBox.p1.Set(0, 0, 0);
+ m_HitBox.p2.Set(m_Size.x - 1, m_Size.y - 1, m_Size.z - 1);
+ m_BlockArea[0].CopyFrom(a_Image);
+ AddRotatedBlockAreas();
+}
+
+
+
+
+
+void cPrefab::AddRotatedBlockAreas(void)
+{
// 1 CCW rotation:
if ((m_AllowedRotations & 0x01) != 0)
{
@@ -165,12 +197,20 @@ cPrefab::cPrefab(const cPrefab::sDef & a_Def) :
void cPrefab::Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const
{
+ Draw(a_Dest, a_Placement->GetCoords(), a_Placement->GetNumCCWRotations());
+}
+
+
+
+
+void cPrefab::Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumRotations) const
+{
// Draw the basic image:
- Vector3i Placement = a_Placement->GetCoords();
+ Vector3i Placement(a_Placement);
int ChunkStartX = a_Dest.GetChunkX() * cChunkDef::Width;
int ChunkStartZ = a_Dest.GetChunkZ() * cChunkDef::Width;
Placement.Move(-ChunkStartX, 0, -ChunkStartZ);
- const cBlockArea & Image = m_BlockArea[a_Placement->GetNumCCWRotations()];
+ const cBlockArea & Image = m_BlockArea[a_NumRotations];
a_Dest.WriteBlockArea(Image, Placement.x, Placement.y, Placement.z, m_MergeStrategy);
// If requested, draw the floor (from the bottom of the prefab down to the nearest non-air)
@@ -257,6 +297,24 @@ int cPrefab::GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cC
+void cPrefab::SetDefaultWeight(int a_DefaultWeight)
+{
+ m_DefaultWeight = a_DefaultWeight;
+}
+
+
+
+
+
+void cPrefab::AddConnector(int a_RelX, int a_RelY, int a_RelZ, eBlockFace a_Direction, int a_Type)
+{
+ m_Connectors.push_back(cConnector(a_RelX, a_RelY, a_RelZ, a_Type, a_Direction));
+}
+
+
+
+
+
void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef)
{
ASSERT(a_CharMapDef != NULL);
diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h
index 37db2ff16..8b4e4b4ef 100644
--- a/src/Generating/Prefab.h
+++ b/src/Generating/Prefab.h
@@ -82,19 +82,47 @@ public:
Can be positive or negative.
This is used e. g. to make nether bridges prefer spanning multiple segments or to penalize turrets next to each other. */
int m_AddWeightIfSame;
+
+ /** If true, the piece will be moved Y-wise so that its first connector is sitting on the terrain.
+ This is used e. g. for village houses. */
+ bool m_MoveToGround;
};
+
+ /** Creates a prefab from the provided definition. */
cPrefab(const sDef & a_Def);
+ /** Creates a prefab based on the given BlockArea and allowed rotations. */
+ cPrefab(const cBlockArea & a_Image, int a_AllowedRotations);
+
/** 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;
+ /** Draws the prefab into the specified chunks, according to the specified placement and rotations. */
+ void Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumRotations) const;
+
/** Returns true if the prefab has any connector of the specified type. */
bool HasConnectorType(int a_ConnectorType) const;
/** Returns the weight (chance) of this prefab generating as the next piece after the specified placed piece.
PiecePool implementations can use this for their GetPieceWeight() implementations. */
int GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector) const;
+
+ /** Sets the (unmodified) DefaultWeight property for this piece. */
+ void SetDefaultWeight(int a_DefaultWeight);
+
+ /** Returns the unmodified DefaultWeight property for the piece. */
+ int GetDefaultWeight(void) const { return m_DefaultWeight; }
+
+ /** Sets the AddWeightIfSame member, that is used to modify the weight when the previous piece is the same prefab */
+ void SetAddWeightIfSame(int a_AddWeightIfSame) { m_AddWeightIfSame = a_AddWeightIfSame; }
+
+ /** Adds the specified connector to the list of connectors this piece supports. */
+ void AddConnector(int a_RelX, int a_RelY, int a_RelZ, eBlockFace a_Direction, int a_Type);
+
+ /** Returns whether the prefab should be moved Y-wise to ground before drawing, rather than staying
+ at the coords governed by the connectors. */
+ bool ShouldMoveToGround(void) const { return m_MoveToGround; }
protected:
/** Packs complete definition of a single block, for per-letter assignment. */
@@ -149,6 +177,10 @@ protected:
Can be positive or negative.
This is used e. g. to make nether bridges prefer spanning multiple segments or to penalize turrets next to each other. */
int m_AddWeightIfSame;
+
+ /** If true, the piece will be moved Y-wise so that its first connector is sitting on the terrain.
+ This is used e. g. for village houses. */
+ bool m_MoveToGround;
// cPiece overrides:
@@ -157,6 +189,10 @@ protected:
virtual cCuboid GetHitBox(void) const override;
virtual bool CanRotateCCW(int a_NumRotations) const override;
+ /** Based on the m_AllowedRotations, adds rotated cBlockAreas to the m_BlockArea array.
+ To be called only from this class's constructor! */
+ void AddRotatedBlockAreas(void);
+
/** 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);
diff --git a/src/Generating/PrefabPiecePool.cpp b/src/Generating/PrefabPiecePool.cpp
index ed9340815..122b9d2af 100644
--- a/src/Generating/PrefabPiecePool.cpp
+++ b/src/Generating/PrefabPiecePool.cpp
@@ -26,6 +26,34 @@ cPrefabPiecePool::cPrefabPiecePool(
+cPrefabPiecePool::~cPrefabPiecePool()
+{
+ Clear();
+}
+
+
+
+
+
+void cPrefabPiecePool::Clear(void)
+{
+ m_PiecesByConnector.clear();
+ for (cPieces::iterator itr = m_AllPieces.begin(), end = m_AllPieces.end(); itr != end; ++itr)
+ {
+ delete *itr;
+ }
+ m_AllPieces.clear();
+ for (cPieces::iterator itr = m_StartingPieces.begin(), end = m_StartingPieces.end(); itr != end; ++itr)
+ {
+ delete *itr;
+ }
+ m_StartingPieces.clear();
+}
+
+
+
+
+
void cPrefabPiecePool::AddPieceDefs(const cPrefab::sDef * a_PieceDefs, size_t a_NumPieceDefs)
{
ASSERT(a_PieceDefs != NULL);
@@ -101,6 +129,15 @@ int cPrefabPiecePool::GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const c
+int cPrefabPiecePool::GetStartingPieceWeight(const cPiece & a_NewPiece)
+{
+ return ((const cPrefab &)a_NewPiece).GetDefaultWeight();
+}
+
+
+
+
+
void cPrefabPiecePool::PiecePlaced(const cPiece & a_Piece)
{
// Do nothing
diff --git a/src/Generating/PrefabPiecePool.h b/src/Generating/PrefabPiecePool.h
index c6a5ad360..b9c1f0483 100644
--- a/src/Generating/PrefabPiecePool.h
+++ b/src/Generating/PrefabPiecePool.h
@@ -34,6 +34,12 @@ public:
const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs
);
+ /** Destroys the pool, freeing all pieces. */
+ ~cPrefabPiecePool();
+
+ /** Removes and frees all pieces from this pool. */
+ void Clear(void);
+
/** Adds pieces from the specified definitions into m_AllPieces. Also adds the pieces into
the m_PiecesByConnector map.
May be called multiple times with different PieceDefs, will add all such pieces. */
@@ -44,7 +50,6 @@ public:
May be called multiple times with different PieceDefs, will add all such pieces. */
void AddStartingPieceDefs(const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs);
-
protected:
/** The type used to map a connector type to the list of pieces with that connector */
@@ -70,6 +75,7 @@ protected:
virtual cPieces GetPiecesWithConnector(int a_ConnectorType) override;
virtual cPieces GetStartingPieces(void) override;
virtual int GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, const cPiece & a_NewPiece) override;
+ virtual int GetStartingPieceWeight(const cPiece & a_NewPiece) override;
virtual void PiecePlaced(const cPiece & a_Piece) override;
virtual void Reset(void) override;
} ;
diff --git a/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp b/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp
new file mode 100644
index 000000000..eb0d30fdf
--- /dev/null
+++ b/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp
@@ -0,0 +1,3184 @@
+
+// AlchemistVillagePrefabs.cpp
+
+// Defines the prefabs in the group AlchemistVillage
+
+// NOTE: This file has been generated automatically by GalExport!
+// Any manual changes will be overwritten by the next automatic export!
+
+#include "Globals.h"
+#include "AlchemistVillagePrefabs.h"
+
+
+
+
+
+const cPrefab::sDef g_AlchemistVillagePrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // BarWithBasement:
+ // The data has been exported from the gallery Desert, area index 82, ID 598, created by STR_Warrior
+ {
+ // Size:
+ 11, 12, 10, // SizeX = 11, SizeY = 12, SizeZ = 10
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 11, 11, 10, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "A:171: 8\n" /* carpet */
+ "B:101: 0\n" /* ironbars */
+ "C: 64:12\n" /* wooddoorblock */
+ "D:128: 2\n" /* sandstonestairs */
+ "E: 24: 1\n" /* sandstone */
+ "F: 44: 9\n" /* step */
+ "G:126: 8\n" /* woodenslab */
+ "H:128: 7\n" /* sandstonestairs */
+ "I: 44: 1\n" /* step */
+ "J: 64: 7\n" /* wooddoorblock */
+ "K:128: 6\n" /* sandstonestairs */
+ "a: 1: 0\n" /* stone */
+ "b: 24: 0\n" /* sandstone */
+ "c: 12: 0\n" /* sand */
+ "d:134: 4\n" /* 134 */
+ "e: 5: 1\n" /* wood */
+ "f:134: 5\n" /* 134 */
+ "g: 65: 5\n" /* ladder */
+ "h: 17: 3\n" /* tree */
+ "i: 69:11\n" /* lever */
+ "j:134: 0\n" /* 134 */
+ "k:134: 1\n" /* 134 */
+ "l: 50: 4\n" /* torch */
+ "m: 19: 0\n" /* sponge */
+ "n: 5: 0\n" /* wood */
+ "o: 96:12\n" /* trapdoor */
+ "p: 24: 2\n" /* sandstone */
+ "q:128: 5\n" /* sandstonestairs */
+ "r:107: 6\n" /* fencegate */
+ "s:128: 4\n" /* sandstonestairs */
+ "t:134: 3\n" /* 134 */
+ "u: 85: 0\n" /* fence */
+ "v:134: 7\n" /* 134 */
+ "w:107: 5\n" /* fencegate */
+ "x: 64: 5\n" /* wooddoorblock */
+ "y: 65: 3\n" /* ladder */
+ "z: 50: 3\n" /* torch */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "aaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaa"
+ /* 2 */ "aabbbbbbbaa"
+ /* 3 */ "aabbbbbbbaa"
+ /* 4 */ "aabbbbbbbaa"
+ /* 5 */ "aabbbbbbbaa"
+ /* 6 */ "aabbbbbbbaa"
+ /* 7 */ "aabbbbbbbaa"
+ /* 8 */ "aaaaaaaaaaa"
+ /* 9 */ "aaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "ccccccccccc"
+ /* 1 */ "cbbbbbbbbbc"
+ /* 2 */ "cbdef.defbc"
+ /* 3 */ "cbdef.defbc"
+ /* 4 */ "cbdef.defbc"
+ /* 5 */ "cb.......bc"
+ /* 6 */ "cb.......bc"
+ /* 7 */ "cbg......bc"
+ /* 8 */ "cbbbbbbbbbc"
+ /* 9 */ "ccccccccccc"
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "ccccccccccc"
+ /* 1 */ "cbbbbbbbbbc"
+ /* 2 */ "cbeee.eeebc"
+ /* 3 */ "cbeee.eeebc"
+ /* 4 */ "cbehe.ehebc"
+ /* 5 */ "cb.i...i.bc"
+ /* 6 */ "cb.......bc"
+ /* 7 */ "cbg......bc"
+ /* 8 */ "cbbbbbbbbbc"
+ /* 9 */ "ccccccccccc"
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "ccccccccccc"
+ /* 1 */ "cbbbbbbbbbc"
+ /* 2 */ "cbjek.jekbc"
+ /* 3 */ "cbjek.jekbc"
+ /* 4 */ "cbjek.jekbc"
+ /* 5 */ "cb.......bc"
+ /* 6 */ "cb.......bc"
+ /* 7 */ "cbg..l...bc"
+ /* 8 */ "cbbbbbbbbbc"
+ /* 9 */ "ccccccccccc"
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "ccccccccccc"
+ /* 1 */ "ccccccccccc"
+ /* 2 */ "ccnnnnnnncc"
+ /* 3 */ "cnnnnnnnnnc"
+ /* 4 */ "cnnnnnnnnnc"
+ /* 5 */ "cnnnnnnnnnc"
+ /* 6 */ "cnnnnnnnnnc"
+ /* 7 */ "cnonnnnnnnc"
+ /* 8 */ "cnccccccccc"
+ /* 9 */ "ccccccccccc"
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "...p...p..."
+ /* 1 */ "..........."
+ /* 2 */ "pbbbqrsbbbp"
+ /* 3 */ "bkt.....ttb"
+ /* 4 */ "bku.....ujb"
+ /* 5 */ "b.........b"
+ /* 6 */ "bfvvd.....b"
+ /* 7 */ "b...w..kujb"
+ /* 8 */ "pxbbbbbbbbp"
+ /* 9 */ "..y........"
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "...p...p..."
+ /* 1 */ "..........."
+ /* 2 */ "pbbb...bbbp"
+ /* 3 */ "b..z...z..b"
+ /* 4 */ "b.A.....A.b"
+ /* 5 */ "B.........B"
+ /* 6 */ "b.........b"
+ /* 7 */ "b.......A.b"
+ /* 8 */ "pCbbBBBbbbp"
+ /* 9 */ "..y........"
+
+ // Level 7
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "...D...D..."
+ /* 1 */ "...E...b..."
+ /* 2 */ "pbbbqFsbbbp"
+ /* 3 */ "bGGGGGGGGGb"
+ /* 4 */ "bGGGGGGGGGb"
+ /* 5 */ "sGGGGGGGGGq"
+ /* 6 */ "bGGGGGGGGGb"
+ /* 7 */ "bGGGGGGGGGb"
+ /* 8 */ "pbbbHHHbbbp"
+ /* 9 */ "..y........"
+
+ // Level 8
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "bIIIIbIIIIb"
+ /* 3 */ "IpbbbbbbbpI"
+ /* 4 */ "Ib.......bI"
+ /* 5 */ "bb.......bb"
+ /* 6 */ "Ib.......bI"
+ /* 7 */ "IpJbbbbbbpI"
+ /* 8 */ "bI.IIbIIIIb"
+ /* 9 */ "..........."
+
+ // Level 9
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ ".pbbBBBbbp."
+ /* 4 */ ".b.......b."
+ /* 5 */ ".B.......B."
+ /* 6 */ ".b.......b."
+ /* 7 */ ".pCbBBBbbp."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+
+ // Level 10
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ ".pbbKKKbbp."
+ /* 4 */ ".bGGGGGGGb."
+ /* 5 */ ".sGGGGGGGq."
+ /* 6 */ ".bGGGGGGGb."
+ /* 7 */ ".pbbHHHbbp."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+
+ // Level 11
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ ".bIIIbIIIb."
+ /* 4 */ ".I.......I."
+ /* 5 */ ".b.......b."
+ /* 6 */ ".I.......I."
+ /* 7 */ ".bIIIbIIIb."
+ /* 8 */ "..........."
+ /* 9 */ "...........",
+
+ // Connectors:
+ "-1: 5, 5, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 70,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // BarWithBasement
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // BarWithoutBasement:
+ // The data has been exported from the gallery Desert, area index 81, ID 597, created by STR_Warrior
+ {
+ // Size:
+ 11, 8, 10, // SizeX = 11, SizeY = 8, SizeZ = 10
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 11, 7, 10, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "A:128: 7\n" /* sandstonestairs */
+ "B: 44: 1\n" /* step */
+ "C: 64: 3\n" /* wooddoorblock */
+ "D: 64: 8\n" /* wooddoorblock */
+ "E:128: 6\n" /* sandstonestairs */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c: 24: 2\n" /* sandstone */
+ "d: 24: 0\n" /* sandstone */
+ "e:128: 5\n" /* sandstonestairs */
+ "f:107: 6\n" /* fencegate */
+ "g:128: 4\n" /* sandstonestairs */
+ "h:134: 1\n" /* 134 */
+ "i:134: 3\n" /* 134 */
+ "j: 85: 0\n" /* fence */
+ "k:134: 0\n" /* 134 */
+ "l:134: 5\n" /* 134 */
+ "m: 19: 0\n" /* sponge */
+ "n:134: 7\n" /* 134 */
+ "o:134: 4\n" /* 134 */
+ "p:107: 5\n" /* fencegate */
+ "q: 64: 5\n" /* wooddoorblock */
+ "r: 65: 3\n" /* ladder */
+ "s: 50: 3\n" /* torch */
+ "t:171: 8\n" /* carpet */
+ "u:101: 0\n" /* ironbars */
+ "v: 64:12\n" /* wooddoorblock */
+ "w:128: 2\n" /* sandstonestairs */
+ "x: 24: 1\n" /* sandstone */
+ "y: 44: 9\n" /* step */
+ "z:126: 8\n" /* woodenslab */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "aaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaa"
+ /* 2 */ "aaaabbbaaaa"
+ /* 3 */ "abbbbbbbbba"
+ /* 4 */ "abbbbbbbbba"
+ /* 5 */ "abbbbbbbbba"
+ /* 6 */ "abbbbbbbbba"
+ /* 7 */ "abbbbbbbbba"
+ /* 8 */ "abaaaaaaaaa"
+ /* 9 */ "aaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "...c...c..."
+ /* 1 */ "..........."
+ /* 2 */ "cdddefgdddc"
+ /* 3 */ "dhi.....iid"
+ /* 4 */ "dhj.....jkd"
+ /* 5 */ "d.........d"
+ /* 6 */ "dlnno.....d"
+ /* 7 */ "d...p..hjkd"
+ /* 8 */ "cqddddddddc"
+ /* 9 */ "..r........"
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "...c...c..."
+ /* 1 */ "..........."
+ /* 2 */ "cddd...dddc"
+ /* 3 */ "d..s...s..d"
+ /* 4 */ "d.t.....t.d"
+ /* 5 */ "u.........u"
+ /* 6 */ "d.........d"
+ /* 7 */ "d.......t.d"
+ /* 8 */ "cvdduuudddc"
+ /* 9 */ "..r........"
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "...w...w..."
+ /* 1 */ "...x...d..."
+ /* 2 */ "cdddeygdddc"
+ /* 3 */ "dzzzzzzzzzd"
+ /* 4 */ "dzzzzzzzzzd"
+ /* 5 */ "gzzzzzzzzze"
+ /* 6 */ "dzzzzzzzzzd"
+ /* 7 */ "dzzzzzzzzzd"
+ /* 8 */ "cdddAAAdddc"
+ /* 9 */ "..r........"
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "dBBBBdBBBBd"
+ /* 3 */ "BcdddddddcB"
+ /* 4 */ "Bd.......dB"
+ /* 5 */ "dd.......dd"
+ /* 6 */ "Bd.......dB"
+ /* 7 */ "BcCddddddcB"
+ /* 8 */ "dB.BBdBBBBd"
+ /* 9 */ "..........."
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ ".cdduuuddc."
+ /* 4 */ ".d.......d."
+ /* 5 */ ".u.......u."
+ /* 6 */ ".d.......d."
+ /* 7 */ ".cDduuuddc."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ ".cddEEEddc."
+ /* 4 */ ".dzzzzzzzd."
+ /* 5 */ ".gzzzzzzze."
+ /* 6 */ ".dzzzzzzzd."
+ /* 7 */ ".cddAAAddc."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+
+ // Level 7
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ ".dBBBdBBBd."
+ /* 4 */ ".B.......B."
+ /* 5 */ ".d.......d."
+ /* 6 */ ".B.......B."
+ /* 7 */ ".dBBBdBBBd."
+ /* 8 */ "..........."
+ /* 9 */ "...........",
+
+ // Connectors:
+ "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 80,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // BarWithoutBasement
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // BlackSmith:
+ // The data has been exported from the gallery Desert, area index 97, ID 642, created by STR_Warrior
+ {
+ // Size:
+ 11, 5, 13, // SizeX = 11, SizeY = 5, SizeZ = 13
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 11, 4, 13, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c: 24: 0\n" /* sandstone */
+ "d: 24: 2\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f: 43: 0\n" /* doubleslab */
+ "g: 53: 5\n" /* woodstairs */
+ "h: 53: 4\n" /* woodstairs */
+ "i: 10: 0\n" /* lava */
+ "j: 54: 5\n" /* chest */
+ "k: 64:12\n" /* wooddoorblock */
+ "l: 50: 3\n" /* torch */
+ "m: 19: 0\n" /* sponge */
+ "n:101: 0\n" /* ironbars */
+ "o: 50: 1\n" /* torch */
+ "p: 50: 2\n" /* torch */
+ "q:128: 2\n" /* sandstonestairs */
+ "r: 44: 9\n" /* step */
+ "s:126: 8\n" /* woodenslab */
+ "t:128: 4\n" /* sandstonestairs */
+ "u:128: 5\n" /* sandstonestairs */
+ "v:128: 7\n" /* sandstonestairs */
+ "w: 44: 1\n" /* step */
+ "x: 43: 1\n" /* doubleslab */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "aaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaa"
+ /* 2 */ "aaaaaaaabaa"
+ /* 3 */ "acacacabbba"
+ /* 4 */ "acaccaabbba"
+ /* 5 */ "acccccabbba"
+ /* 6 */ "acaadddbbba"
+ /* 7 */ "aaacdddbbba"
+ /* 8 */ "aaaadddbbba"
+ /* 9 */ "abbbbbbbbba"
+ /* 10 */ "abbbbbbbbba"
+ /* 11 */ "abbbbbbbbba"
+ /* 12 */ "aaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "......d...d"
+ /* 1 */ "..........."
+ /* 2 */ "......dcecd"
+ /* 3 */ ".d....c...c"
+ /* 4 */ "..f...c...c"
+ /* 5 */ "......c...c"
+ /* 6 */ "....ddc...c"
+ /* 7 */ ".gh.dic...c"
+ /* 8 */ "dcccccd...c"
+ /* 9 */ "cj........c"
+ /* 10 */ "c.........c"
+ /* 11 */ "c.........c"
+ /* 12 */ "dcccccccccd"
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "......d...d"
+ /* 1 */ "..........."
+ /* 2 */ "......dckcd"
+ /* 3 */ ".d....c..lc"
+ /* 4 */ "......n...c"
+ /* 5 */ "......c...c"
+ /* 6 */ "....nnc...n"
+ /* 7 */ "....n.c...n"
+ /* 8 */ "dcccccd...n"
+ /* 9 */ "co........c"
+ /* 10 */ "n.........c"
+ /* 11 */ "c........pc"
+ /* 12 */ "dcccnnncccd"
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "......q...q"
+ /* 1 */ "......c...c"
+ /* 2 */ "......dcccd"
+ /* 3 */ ".drrrrcsssc"
+ /* 4 */ ".rsssstsssc"
+ /* 5 */ ".rsssscsssc"
+ /* 6 */ ".rssddcsssu"
+ /* 7 */ ".rssd.csssu"
+ /* 8 */ "dcccccdsssu"
+ /* 9 */ "csssssssssc"
+ /* 10 */ "tsssssssssc"
+ /* 11 */ "csssssssssc"
+ /* 12 */ "dcccvvvcccd"
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "......cwwwc"
+ /* 3 */ ".w.w.ww...w"
+ /* 4 */ "......w...w"
+ /* 5 */ ".w....w...w"
+ /* 6 */ "....xwx...w"
+ /* 7 */ ".w..w.w...c"
+ /* 8 */ "cwwwxwc...w"
+ /* 9 */ "w.........w"
+ /* 10 */ "w.........w"
+ /* 11 */ "w.........w"
+ /* 12 */ "cwwwwcwwwwc",
+
+ // Connectors:
+ "-1: 8, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 50,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // BlackSmith
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LargeHouse1:
+ // The data has been exported from the gallery Desert, area index 77, ID 577, created by STR_Warrior
+ {
+ // Size:
+ 15, 13, 11, // SizeX = 15, SizeY = 13, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ -1, 0, -1, // MinX, MinY, MinZ
+ 14, 12, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "A:128: 4\n" /* sandstonestairs */
+ "B:128: 5\n" /* sandstonestairs */
+ "C:128: 7\n" /* sandstonestairs */
+ "D: 44: 1\n" /* step */
+ "E:128: 2\n" /* sandstonestairs */
+ "F:128: 0\n" /* sandstonestairs */
+ "G: 87: 0\n" /* netherstone */
+ "H:128: 3\n" /* sandstonestairs */
+ "I: 51: 0\n" /* fire */
+ "J: 44: 9\n" /* step */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c: 24: 2\n" /* sandstone */
+ "d: 24: 0\n" /* sandstone */
+ "e: 85: 0\n" /* fence */
+ "f: 5: 1\n" /* wood */
+ "g: 64: 6\n" /* wooddoorblock */
+ "h: 64: 0\n" /* wooddoorblock */
+ "i: 61: 2\n" /* furnace */
+ "j:118: 0\n" /* cauldronblock */
+ "k:134: 4\n" /* 134 */
+ "l: 65: 2\n" /* ladder */
+ "m: 19: 0\n" /* sponge */
+ "n:101: 0\n" /* ironbars */
+ "o: 50: 1\n" /* torch */
+ "p:140: 0\n" /* flowerpotblock */
+ "q: 64:12\n" /* wooddoorblock */
+ "r: 50: 3\n" /* torch */
+ "s: 64: 8\n" /* wooddoorblock */
+ "t: 69:12\n" /* lever */
+ "u: 50: 4\n" /* torch */
+ "v:128: 6\n" /* sandstonestairs */
+ "w: 44:10\n" /* step */
+ "x:128: 1\n" /* sandstonestairs */
+ "y: 47: 0\n" /* bookshelf */
+ "z: 96:10\n" /* trapdoor */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "aaaaaaaaaaaaaaa"
+ /* 1 */ "aaaaabbbbbbbaaa"
+ /* 2 */ "aaaabbbbbbbbaaa"
+ /* 3 */ "aaaaabbbbbbbbaa"
+ /* 4 */ "aaaaabbbbbbbaaa"
+ /* 5 */ "aaaaabbbbbbbaaa"
+ /* 6 */ "aaaaabbbbbbbaaa"
+ /* 7 */ "aaaaabbbbbbbaaa"
+ /* 8 */ "aaaaabbbbbbbaaa"
+ /* 9 */ "aaaaabbbbbbbaaa"
+ /* 10 */ "aaaaaaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "....cdddddddc.."
+ /* 1 */ "eeeed......fd.c"
+ /* 2 */ "e...g.......d.."
+ /* 3 */ "e...d.......h.."
+ /* 4 */ "e...dijk..l.d.."
+ /* 5 */ "e...dddd.dddd.c"
+ /* 6 */ "eeeed.......d.."
+ /* 7 */ "mmmmd.......d.."
+ /* 8 */ "mmmmd.......d.."
+ /* 9 */ "mmmmd.......d.."
+ /* 10 */ "mmmmcdddddddc.."
+
+ // Level 2
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "....cddnnnddc.."
+ /* 1 */ "....do.....pd.c"
+ /* 2 */ "....q.......d.r"
+ /* 3 */ "....d.......s.."
+ /* 4 */ "....d.t...l.d.u"
+ /* 5 */ "....dddd.dddd.c"
+ /* 6 */ "....n..r.r..n.."
+ /* 7 */ "mmmmn.......n.."
+ /* 8 */ "mmmmn.......n.."
+ /* 9 */ "mmmmd.......d.."
+ /* 10 */ "mmmmcddnnnddc.."
+
+ // Level 3
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "....cddvvvddc.."
+ /* 1 */ "....dwwwwwwwddx"
+ /* 2 */ "....dwwwwwwwd.."
+ /* 3 */ "....dwwwwwwwd.."
+ /* 4 */ "....dyyywwzwd.."
+ /* 5 */ "....ddddddddddx"
+ /* 6 */ "....AwwwwwwwB.."
+ /* 7 */ "mmmmAwwwwwwwB.."
+ /* 8 */ "mmmmAwwwwwwwB.."
+ /* 9 */ "mmmmdwwwwwwwd.."
+ /* 10 */ "mmmmcddCCCddc.."
+
+ // Level 4
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "....dDDDdDDDd.."
+ /* 1 */ "....DcdddddcD.."
+ /* 2 */ "....Dd.....dD.."
+ /* 3 */ "....Dd.....dD.."
+ /* 4 */ "....Dd.....dD.."
+ /* 5 */ "....dcdd.ddcd.."
+ /* 6 */ "....D.......D.."
+ /* 7 */ "mmmmD.......D.."
+ /* 8 */ "mmmmD.......D.."
+ /* 9 */ "mmmmD.......D.."
+ /* 10 */ "mmmmdDDDdDDDd.."
+
+ // Level 5
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".....cddnddc..."
+ /* 2 */ ".....n.....n..."
+ /* 3 */ ".....n.....n..."
+ /* 4 */ ".....n.....n..."
+ /* 5 */ ".....cdd.ddc..."
+ /* 6 */ "..............."
+ /* 7 */ "..............."
+ /* 8 */ "..............."
+ /* 9 */ "..............."
+ /* 10 */ "..............."
+
+ // Level 6
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".....cddvddc..."
+ /* 2 */ ".....AwwwwwB..."
+ /* 3 */ ".....AwwwwwB..."
+ /* 4 */ ".....AwwwwwB..."
+ /* 5 */ ".....cdddddc..."
+ /* 6 */ "..............."
+ /* 7 */ "..............."
+ /* 8 */ "..............."
+ /* 9 */ "..............."
+ /* 10 */ "..............."
+
+ // Level 7
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".....dDDdDDd..."
+ /* 2 */ ".....D.ddd.D..."
+ /* 3 */ ".....d.ddd.d..."
+ /* 4 */ ".....D.ddd.D..."
+ /* 5 */ ".....dDDdDDd..."
+ /* 6 */ "..............."
+ /* 7 */ "..............."
+ /* 8 */ "..............."
+ /* 9 */ "..............."
+ /* 10 */ "..............."
+
+ // Level 8
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ ".......cEc....."
+ /* 3 */ ".......FGx....."
+ /* 4 */ ".......cHc....."
+ /* 5 */ "..............."
+ /* 6 */ "..............."
+ /* 7 */ "..............."
+ /* 8 */ "..............."
+ /* 9 */ "..............."
+ /* 10 */ "..............."
+
+ // Level 9
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ ".......c.c....."
+ /* 3 */ "........I......"
+ /* 4 */ ".......c.c....."
+ /* 5 */ "..............."
+ /* 6 */ "..............."
+ /* 7 */ "..............."
+ /* 8 */ "..............."
+ /* 9 */ "..............."
+ /* 10 */ "..............."
+
+ // Level 10
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ ".......cvc....."
+ /* 3 */ ".......A.B....."
+ /* 4 */ ".......cCc....."
+ /* 5 */ "..............."
+ /* 6 */ "..............."
+ /* 7 */ "..............."
+ /* 8 */ "..............."
+ /* 9 */ "..............."
+ /* 10 */ "..............."
+
+ // Level 11
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ ".......ddd....."
+ /* 3 */ ".......dJd....."
+ /* 4 */ ".......ddd....."
+ /* 5 */ "..............."
+ /* 6 */ "..............."
+ /* 7 */ "..............."
+ /* 8 */ "..............."
+ /* 9 */ "..............."
+ /* 10 */ "..............."
+
+ // Level 12
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ ".......D.D....."
+ /* 3 */ "..............."
+ /* 4 */ ".......D.D....."
+ /* 5 */ "..............."
+ /* 6 */ "..............."
+ /* 7 */ "..............."
+ /* 8 */ "..............."
+ /* 9 */ "..............."
+ /* 10 */ "...............",
+
+ // Connectors:
+ "-1: 14, 1, 3: 5\n" /* Type -1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 60,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // LargeHouse1
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LargeTower:
+ // The data has been exported from the gallery Desert, area index 80, ID 596, created by STR_Warrior
+ {
+ // Size:
+ 7, 11, 7, // SizeX = 7, SizeY = 11, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 7, 10, 7, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 0\n" /* sandstonestairs */
+ "e: 24: 2\n" /* sandstone */
+ "f: 24: 0\n" /* sandstone */
+ "g: 71: 3\n" /* irondoorblock */
+ "h:128: 1\n" /* sandstonestairs */
+ "i:128: 3\n" /* sandstonestairs */
+ "j: 77: 4\n" /* stonebutton */
+ "k: 71: 8\n" /* irondoorblock */
+ "l:128: 6\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */
+ "n:128: 4\n" /* sandstonestairs */
+ "o:128: 5\n" /* sandstonestairs */
+ "p: 50: 4\n" /* torch */
+ "q:128: 7\n" /* sandstonestairs */
+ "r: 85: 0\n" /* fence */
+ "s: 24: 1\n" /* sandstone */
+ "t: 44: 1\n" /* step */
+ "u: 89: 0\n" /* lightstone */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "aaabaaa"
+ /* 2 */ "aabbbaa"
+ /* 3 */ "aabbbaa"
+ /* 4 */ "aabbbaa"
+ /* 5 */ "aaaaaaa"
+ /* 6 */ "aaaaaaa"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "mc...cm"
+ /* 1 */ "defgfeh"
+ /* 2 */ ".f...f."
+ /* 3 */ ".f...f."
+ /* 4 */ ".f...f."
+ /* 5 */ "defffeh"
+ /* 6 */ "mi...im"
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "m.j...m"
+ /* 1 */ ".efkfe."
+ /* 2 */ ".f...f."
+ /* 3 */ ".f...f."
+ /* 4 */ ".f...f."
+ /* 5 */ ".efffe."
+ /* 6 */ "m.....m"
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "..lfl.."
+ /* 2 */ ".n...o."
+ /* 3 */ ".f...f."
+ /* 4 */ ".n.p.o."
+ /* 5 */ "..qfq.."
+ /* 6 */ "......."
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "..frf.."
+ /* 2 */ ".f...f."
+ /* 3 */ ".r...r."
+ /* 4 */ ".f...f."
+ /* 5 */ "..frf.."
+ /* 6 */ "......."
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "..frf.."
+ /* 2 */ ".f...f."
+ /* 3 */ ".r...r."
+ /* 4 */ ".f...f."
+ /* 5 */ "..frf.."
+ /* 6 */ "......."
+
+ // Level 6
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "..frf.."
+ /* 2 */ ".f...f."
+ /* 3 */ ".r...r."
+ /* 4 */ ".f...f."
+ /* 5 */ "..frf.."
+ /* 6 */ "......."
+
+ // Level 7
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "..cfc.."
+ /* 2 */ ".d...h."
+ /* 3 */ ".f...f."
+ /* 4 */ ".d...h."
+ /* 5 */ "..ifi.."
+ /* 6 */ "......."
+
+ // Level 8
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".ffsff."
+ /* 2 */ ".f...f."
+ /* 3 */ ".s...s."
+ /* 4 */ ".f...f."
+ /* 5 */ ".ffsff."
+ /* 6 */ "......."
+
+ // Level 9
+ /* z\x* 0123456 */
+ /* 0 */ "...l..."
+ /* 1 */ ".efffe."
+ /* 2 */ ".ftttf."
+ /* 3 */ "nftftfo"
+ /* 4 */ ".ftttf."
+ /* 5 */ ".efffe."
+ /* 6 */ "...q..."
+
+ // Level 10
+ /* z\x* 0123456 */
+ /* 0 */ "...t..."
+ /* 1 */ ".t...t."
+ /* 2 */ "......."
+ /* 3 */ "t..u..t"
+ /* 4 */ "......."
+ /* 5 */ ".t...t."
+ /* 6 */ "...t...",
+
+ // Connectors:
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // LargeTower
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LittleHouse:
+ // The data has been exported from the gallery Desert, area index 65, ID 551, created by STR_Warrior
+ {
+ // Size:
+ 5, 5, 7, // SizeX = 5, SizeY = 5, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 5, 4, 7, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c: 24: 2\n" /* sandstone */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 3\n" /* wooddoorblock */
+ "f: 61: 2\n" /* furnace */
+ "g: 65: 2\n" /* ladder */
+ "h: 64: 8\n" /* wooddoorblock */
+ "i:101: 0\n" /* ironbars */
+ "j: 50: 4\n" /* torch */
+ "k:128: 2\n" /* sandstonestairs */
+ "l:126: 8\n" /* woodenslab */
+ "m: 19: 0\n" /* sponge */
+ "n:128: 4\n" /* sandstonestairs */
+ "o:128: 5\n" /* sandstonestairs */
+ "p:128: 7\n" /* sandstonestairs */
+ "q: 44: 1\n" /* step */
+ "r: 96: 6\n" /* trapdoor */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aabaa"
+ /* 3 */ "abbba"
+ /* 4 */ "abbba"
+ /* 5 */ "abbba"
+ /* 6 */ "aaaaa"
+
+ // Level 1
+ /* z\x* 01234 */
+ /* 0 */ "c...c"
+ /* 1 */ "....."
+ /* 2 */ "cdedc"
+ /* 3 */ "d...d"
+ /* 4 */ "d...d"
+ /* 5 */ "df.gd"
+ /* 6 */ "cdddc"
+
+ // Level 2
+ /* z\x* 01234 */
+ /* 0 */ "c...c"
+ /* 1 */ "....."
+ /* 2 */ "cdhdc"
+ /* 3 */ "d...d"
+ /* 4 */ "i...i"
+ /* 5 */ "dj.gd"
+ /* 6 */ "cdidc"
+
+ // Level 3
+ /* z\x* 01234 */
+ /* 0 */ "k...k"
+ /* 1 */ "d...d"
+ /* 2 */ "cdddc"
+ /* 3 */ "dllld"
+ /* 4 */ "nlllo"
+ /* 5 */ "dllgd"
+ /* 6 */ "cdpdc"
+
+ // Level 4
+ /* z\x* 01234 */
+ /* 0 */ "....."
+ /* 1 */ "....."
+ /* 2 */ "dqdqd"
+ /* 3 */ "q...q"
+ /* 4 */ "d...d"
+ /* 5 */ "q..rq"
+ /* 6 */ "dqdqd",
+
+ // Connectors:
+ "-1: 2, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // LittleHouse
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LittleHouse2:
+ // The data has been exported from the gallery Desert, area index 72, ID 562, created by STR_Warrior
+ {
+ // Size:
+ 7, 5, 11, // SizeX = 7, SizeY = 5, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 7, 4, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c: 24: 2\n" /* sandstone */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 3\n" /* wooddoorblock */
+ "f: 65: 5\n" /* ladder */
+ "g: 85: 0\n" /* fence */
+ "h:101: 0\n" /* ironbars */
+ "i: 64: 8\n" /* wooddoorblock */
+ "j: 50: 3\n" /* torch */
+ "k:128: 2\n" /* sandstonestairs */
+ "l:128: 6\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */
+ "n:126: 8\n" /* woodenslab */
+ "o:128: 4\n" /* sandstonestairs */
+ "p:128: 5\n" /* sandstonestairs */
+ "q:128: 7\n" /* sandstonestairs */
+ "r: 44: 1\n" /* step */
+ "s: 96: 0\n" /* trapdoor */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "aaaaaaa"
+ /* 2 */ "aaaabaa"
+ /* 3 */ "abbbbba"
+ /* 4 */ "abbbbba"
+ /* 5 */ "abbbbba"
+ /* 6 */ "aabaaaa"
+ /* 7 */ "aaaaaaa"
+ /* 8 */ "aaaaaaa"
+ /* 9 */ "aaaaaaa"
+ /* 10 */ "aaaaaaa"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ ".c...c."
+ /* 1 */ "......."
+ /* 2 */ "cdddedc"
+ /* 3 */ "d.....d"
+ /* 4 */ "d.....d"
+ /* 5 */ "df....d"
+ /* 6 */ "cd.dddc"
+ /* 7 */ "g.....g"
+ /* 8 */ "g.....g"
+ /* 9 */ "g.....g"
+ /* 10 */ "ggggggg"
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ ".c...c."
+ /* 1 */ "......."
+ /* 2 */ "cdhdidc"
+ /* 3 */ "d..j..d"
+ /* 4 */ "h.....h"
+ /* 5 */ "df....d"
+ /* 6 */ "cd.dhdc"
+ /* 7 */ "......."
+ /* 8 */ "......."
+ /* 9 */ "......."
+ /* 10 */ "......."
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ ".k...k."
+ /* 1 */ ".d...d."
+ /* 2 */ "cdldddc"
+ /* 3 */ "dnnnnnd"
+ /* 4 */ "onnnnnp"
+ /* 5 */ "dfnnnnd"
+ /* 6 */ "cdddqdc"
+ /* 7 */ "......."
+ /* 8 */ "......."
+ /* 9 */ "......."
+ /* 10 */ "......."
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "......."
+ /* 2 */ "drrdrrd"
+ /* 3 */ "r.....r"
+ /* 4 */ "d.....d"
+ /* 5 */ "rs....r"
+ /* 6 */ "drrdrrd"
+ /* 7 */ "......."
+ /* 8 */ "......."
+ /* 9 */ "......."
+ /* 10 */ ".......",
+
+ // Connectors:
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // LittleHouse2
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LittleHouse3:
+ // The data has been exported from the gallery Desert, area index 66, ID 553, created by STR_Warrior
+ {
+ // Size:
+ 9, 5, 7, // SizeX = 9, SizeY = 5, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 9, 4, 7, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c: 24: 2\n" /* sandstone */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f: 65: 2\n" /* ladder */
+ "g: 64:12\n" /* wooddoorblock */
+ "h:101: 0\n" /* ironbars */
+ "i: 50: 4\n" /* torch */
+ "j:128: 2\n" /* sandstonestairs */
+ "k:126: 8\n" /* woodenslab */
+ "l:128: 4\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */
+ "n:128: 5\n" /* sandstonestairs */
+ "o:128: 7\n" /* sandstonestairs */
+ "p: 44: 1\n" /* step */
+ "q: 96: 2\n" /* trapdoor */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 012345678 */
+ /* 0 */ "aaaaaaaaa"
+ /* 1 */ "aaaaaaaaa"
+ /* 2 */ "aaaabaaaa"
+ /* 3 */ "abbbbbbba"
+ /* 4 */ "abbbbbbba"
+ /* 5 */ "abbbbbbba"
+ /* 6 */ "aaaaaaaaa"
+
+ // Level 1
+ /* z\x* 012345678 */
+ /* 0 */ "..c...c.."
+ /* 1 */ "........."
+ /* 2 */ "cdddedddc"
+ /* 3 */ "d.......d"
+ /* 4 */ "d.......d"
+ /* 5 */ "d......fd"
+ /* 6 */ "cdddddddc"
+
+ // Level 2
+ /* z\x* 012345678 */
+ /* 0 */ "..c...c.."
+ /* 1 */ "........."
+ /* 2 */ "cdddgdddc"
+ /* 3 */ "d.......d"
+ /* 4 */ "h.......h"
+ /* 5 */ "d.i....fd"
+ /* 6 */ "cddhhhddc"
+
+ // Level 3
+ /* z\x* 012345678 */
+ /* 0 */ "..j...j.."
+ /* 1 */ "..d...d.."
+ /* 2 */ "cdddddddc"
+ /* 3 */ "dkkkkkkkd"
+ /* 4 */ "lkkkkkkkn"
+ /* 5 */ "dkkkkkkfd"
+ /* 6 */ "cddoooddc"
+
+ // Level 4
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "dpppdpppd"
+ /* 3 */ "p.......p"
+ /* 4 */ "d.......d"
+ /* 5 */ "p......qp"
+ /* 6 */ "dpppdpppd",
+
+ // Connectors:
+ "-1: 4, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // LittleHouse3
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LittleHouse4:
+ // The data has been exported from the gallery Desert, area index 70, ID 560, created by STR_Warrior
+ {
+ // Size:
+ 5, 5, 11, // SizeX = 5, SizeY = 5, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 5, 4, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c: 24: 2\n" /* sandstone */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f: 65: 5\n" /* ladder */
+ "g:134: 3\n" /* 134 */
+ "h: 85: 0\n" /* fence */
+ "i:134: 2\n" /* 134 */
+ "j: 61: 2\n" /* furnace */
+ "k:134: 6\n" /* 134 */
+ "l:134: 4\n" /* 134 */
+ "m: 19: 0\n" /* sponge */
+ "n: 64:12\n" /* wooddoorblock */
+ "o: 50: 2\n" /* torch */
+ "p:101: 0\n" /* ironbars */
+ "q:171: 8\n" /* carpet */
+ "r:128: 2\n" /* sandstonestairs */
+ "s:126: 8\n" /* woodenslab */
+ "t:128: 4\n" /* sandstonestairs */
+ "u:128: 5\n" /* sandstonestairs */
+ "v:128: 7\n" /* sandstonestairs */
+ "w: 44: 1\n" /* step */
+ "x: 96: 1\n" /* trapdoor */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aabaa"
+ /* 3 */ "abbba"
+ /* 4 */ "abbba"
+ /* 5 */ "abbba"
+ /* 6 */ "abbba"
+ /* 7 */ "abbba"
+ /* 8 */ "abbba"
+ /* 9 */ "abbba"
+ /* 10 */ "aaaaa"
+
+ // Level 1
+ /* z\x* 01234 */
+ /* 0 */ "c...c"
+ /* 1 */ "....."
+ /* 2 */ "cdedc"
+ /* 3 */ "df..d"
+ /* 4 */ "d...d"
+ /* 5 */ "d..gd"
+ /* 6 */ "d..hd"
+ /* 7 */ "d..id"
+ /* 8 */ "d...d"
+ /* 9 */ "djkld"
+ /* 10 */ "cdddc"
+
+ // Level 2
+ /* z\x* 01234 */
+ /* 0 */ "c...c"
+ /* 1 */ "....."
+ /* 2 */ "cdndc"
+ /* 3 */ "df..d"
+ /* 4 */ "d..od"
+ /* 5 */ "p...p"
+ /* 6 */ "p..qp"
+ /* 7 */ "p...p"
+ /* 8 */ "d...d"
+ /* 9 */ "d...d"
+ /* 10 */ "cdpdc"
+
+ // Level 3
+ /* z\x* 01234 */
+ /* 0 */ "r...r"
+ /* 1 */ "d...d"
+ /* 2 */ "cdddc"
+ /* 3 */ "dfssd"
+ /* 4 */ "dsssd"
+ /* 5 */ "tsssu"
+ /* 6 */ "tsssu"
+ /* 7 */ "tsssu"
+ /* 8 */ "dsssd"
+ /* 9 */ "dsssd"
+ /* 10 */ "cdvdc"
+
+ // Level 4
+ /* z\x* 01234 */
+ /* 0 */ "....."
+ /* 1 */ "....."
+ /* 2 */ "dwdwd"
+ /* 3 */ "wx..w"
+ /* 4 */ "w...w"
+ /* 5 */ "w...w"
+ /* 6 */ "d...d"
+ /* 7 */ "w...w"
+ /* 8 */ "w...w"
+ /* 9 */ "w...w"
+ /* 10 */ "dwdwd",
+
+ // Connectors:
+ "-1: 2, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // LittleHouse4
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LittleHouse5:
+ // The data has been exported from the gallery Desert, area index 68, ID 558, created by STR_Warrior
+ {
+ // Size:
+ 9, 5, 9, // SizeX = 9, SizeY = 5, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 9, 4, 9, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c: 24: 2\n" /* sandstone */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f: 65: 2\n" /* ladder */
+ "g: 64:12\n" /* wooddoorblock */
+ "h:101: 0\n" /* ironbars */
+ "i: 50: 1\n" /* torch */
+ "j: 50: 4\n" /* torch */
+ "k:128: 2\n" /* sandstonestairs */
+ "l:126: 8\n" /* woodenslab */
+ "m: 19: 0\n" /* sponge */
+ "n:128: 6\n" /* sandstonestairs */
+ "o:128: 5\n" /* sandstonestairs */
+ "p:128: 4\n" /* sandstonestairs */
+ "q:128: 7\n" /* sandstonestairs */
+ "r: 44: 1\n" /* step */
+ "s: 96: 6\n" /* trapdoor */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 012345678 */
+ /* 0 */ "aaaaaaaaa"
+ /* 1 */ "aaaaaaaaa"
+ /* 2 */ "aaaaaabaa"
+ /* 3 */ "aaaaabbba"
+ /* 4 */ "aaaaabbba"
+ /* 5 */ "abbbbbbba"
+ /* 6 */ "abbbbbbba"
+ /* 7 */ "abbbbbbba"
+ /* 8 */ "aaaaaaaaa"
+
+ // Level 1
+ /* z\x* 012345678 */
+ /* 0 */ "mmmmc...c"
+ /* 1 */ "mmmm....."
+ /* 2 */ "mmmmcdedc"
+ /* 3 */ "mmmmd...d"
+ /* 4 */ "cdddd...d"
+ /* 5 */ "d.......d"
+ /* 6 */ "d.......d"
+ /* 7 */ "d......fd"
+ /* 8 */ "cdddddddc"
+
+ // Level 2
+ /* z\x* 012345678 */
+ /* 0 */ "mmmmc...c"
+ /* 1 */ "mmmm....."
+ /* 2 */ "mmmmcdgdc"
+ /* 3 */ "mmmmd...d"
+ /* 4 */ "cdhdd...h"
+ /* 5 */ "d.......h"
+ /* 6 */ "h.......d"
+ /* 7 */ "di....jfd"
+ /* 8 */ "cddhhhddc"
+
+ // Level 3
+ /* z\x* 012345678 */
+ /* 0 */ "mmmmk...k"
+ /* 1 */ "mmmmd...d"
+ /* 2 */ "mmmmcdddc"
+ /* 3 */ "mmmmdllld"
+ /* 4 */ "cdnddlllo"
+ /* 5 */ "dlllllllo"
+ /* 6 */ "pllllllld"
+ /* 7 */ "dllllllfd"
+ /* 8 */ "cddqqqddc"
+
+ // Level 4
+ /* z\x* 012345678 */
+ /* 0 */ "mmmm....."
+ /* 1 */ "mmmm....."
+ /* 2 */ "mmmmcrdrd"
+ /* 3 */ "mmmmr...r"
+ /* 4 */ "drrrd...d"
+ /* 5 */ "r.......r"
+ /* 6 */ "r.......r"
+ /* 7 */ "r......sr"
+ /* 8 */ "drrrdrrrd",
+
+ // Connectors:
+ "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // LittleHouse5
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LittleHouse6:
+ // The data has been exported from the gallery Desert, area index 69, ID 559, created by STR_Warrior
+ {
+ // Size:
+ 9, 5, 9, // SizeX = 9, SizeY = 5, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 9, 4, 9, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 12: 0\n" /* sand */
+ "b: 2: 0\n" /* grass */
+ "c: 5: 0\n" /* wood */
+ "d: 85: 0\n" /* fence */
+ "e: 24: 2\n" /* sandstone */
+ "f: 24: 0\n" /* sandstone */
+ "g: 64: 7\n" /* wooddoorblock */
+ "h: 38: 1\n" /* rose */
+ "i: 38: 2\n" /* rose */
+ "j: 38: 5\n" /* rose */
+ "k: 65: 2\n" /* ladder */
+ "l: 64:12\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */
+ "n:101: 0\n" /* ironbars */
+ "o: 50: 1\n" /* torch */
+ "p: 50: 4\n" /* torch */
+ "q:128: 2\n" /* sandstonestairs */
+ "r:126: 8\n" /* woodenslab */
+ "s:128: 6\n" /* sandstonestairs */
+ "t:128: 5\n" /* sandstonestairs */
+ "u:128: 4\n" /* sandstonestairs */
+ "v:128: 7\n" /* sandstonestairs */
+ "w: 44: 1\n" /* step */
+ "x: 96: 6\n" /* trapdoor */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 012345678 */
+ /* 0 */ "aaaaaaaaa"
+ /* 1 */ "abbbaaaaa"
+ /* 2 */ "abbbaacaa"
+ /* 3 */ "abbbaccca"
+ /* 4 */ "aaaaaccca"
+ /* 5 */ "accccccca"
+ /* 6 */ "accccccca"
+ /* 7 */ "accccccca"
+ /* 8 */ "aaaaaaaaa"
+
+ // Level 1
+ /* z\x* 012345678 */
+ /* 0 */ "dddde...e"
+ /* 1 */ "d........"
+ /* 2 */ "d...efgfe"
+ /* 3 */ "dhijf...f"
+ /* 4 */ "effff...f"
+ /* 5 */ "f.......f"
+ /* 6 */ "f.......f"
+ /* 7 */ "f......kf"
+ /* 8 */ "efffffffe"
+
+ // Level 2
+ /* z\x* 012345678 */
+ /* 0 */ "....e...e"
+ /* 1 */ "........."
+ /* 2 */ "....eflfe"
+ /* 3 */ "....f...f"
+ /* 4 */ "efnff...n"
+ /* 5 */ "f.......n"
+ /* 6 */ "n.......f"
+ /* 7 */ "fo....pkf"
+ /* 8 */ "effnnnffe"
+
+ // Level 3
+ /* z\x* 012345678 */
+ /* 0 */ "....q...q"
+ /* 1 */ "....f...f"
+ /* 2 */ "....efffe"
+ /* 3 */ "....frrrf"
+ /* 4 */ "efsffrrrt"
+ /* 5 */ "frrrrrrrt"
+ /* 6 */ "urrrrrrrf"
+ /* 7 */ "frrrrrrkf"
+ /* 8 */ "effvvvffe"
+
+ // Level 4
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "....ewfwf"
+ /* 3 */ "....w...w"
+ /* 4 */ "fwwwf...f"
+ /* 5 */ "w.......w"
+ /* 6 */ "w.......w"
+ /* 7 */ "w......xw"
+ /* 8 */ "fwwwfwwwf",
+
+ // Connectors:
+ "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // LittleHouse6
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LittleHouse7:
+ // The data has been exported from the gallery Desert, area index 73, ID 563, created by xoft
+ {
+ // Size:
+ 9, 5, 11, // SizeX = 9, SizeY = 5, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 9, 4, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c: 24: 2\n" /* sandstone */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f: 65: 2\n" /* ladder */
+ "g:101: 0\n" /* ironbars */
+ "h: 64:12\n" /* wooddoorblock */
+ "i: 50: 1\n" /* torch */
+ "j: 50: 2\n" /* torch */
+ "k:128: 2\n" /* sandstonestairs */
+ "l:128: 6\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */
+ "n:126: 8\n" /* woodenslab */
+ "o:128: 4\n" /* sandstonestairs */
+ "p:128: 5\n" /* sandstonestairs */
+ "q:128: 7\n" /* sandstonestairs */
+ "r: 44: 1\n" /* step */
+ "s: 96: 6\n" /* trapdoor */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 012345678 */
+ /* 0 */ "aaaaaaaaa"
+ /* 1 */ "aaaaaaaaa"
+ /* 2 */ "aaaaaabaa"
+ /* 3 */ "abbbbbbba"
+ /* 4 */ "abbbbbbba"
+ /* 5 */ "abbbbbbba"
+ /* 6 */ "aaaaabbba"
+ /* 7 */ "aaaaabbba"
+ /* 8 */ "aaaaabbba"
+ /* 9 */ "aaaaabbba"
+ /* 10 */ "aaaaaaaaa"
+
+ // Level 1
+ /* z\x* 012345678 */
+ /* 0 */ "....c...c"
+ /* 1 */ "........."
+ /* 2 */ "cdddddedc"
+ /* 3 */ "d.......d"
+ /* 4 */ "d.......d"
+ /* 5 */ "d.......d"
+ /* 6 */ "cdddd...d"
+ /* 7 */ "mmmmd...d"
+ /* 8 */ "mmmmd...d"
+ /* 9 */ "mmmmd..fd"
+ /* 10 */ "mmmmddddc"
+
+ // Level 2
+ /* z\x* 012345678 */
+ /* 0 */ "....c...c"
+ /* 1 */ "........."
+ /* 2 */ "cdgdddhdc"
+ /* 3 */ "d.......d"
+ /* 4 */ "g.......d"
+ /* 5 */ "di......g"
+ /* 6 */ "cdgdd...g"
+ /* 7 */ "mmmmd...g"
+ /* 8 */ "mmmmg..jd"
+ /* 9 */ "mmmmd..fd"
+ /* 10 */ "mmmmddgdc"
+
+ // Level 3
+ /* z\x* 012345678 */
+ /* 0 */ "....k...k"
+ /* 1 */ "....d...d"
+ /* 2 */ "cdldddddc"
+ /* 3 */ "dnnnnnnnd"
+ /* 4 */ "onnnnnnnd"
+ /* 5 */ "dnnnnnnnp"
+ /* 6 */ "cdqddnnnp"
+ /* 7 */ "mmmmdnnnp"
+ /* 8 */ "mmmmonnnd"
+ /* 9 */ "mmmmdnnfd"
+ /* 10 */ "mmmmddqdc"
+
+ // Level 4
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "drrrdrdrd"
+ /* 3 */ "r.......r"
+ /* 4 */ "r.......r"
+ /* 5 */ "r.......r"
+ /* 6 */ "drrrd...d"
+ /* 7 */ "mmmmr...r"
+ /* 8 */ "mmmmr...r"
+ /* 9 */ "mmmmr..sr"
+ /* 10 */ "mmmmdrrrd",
+
+ // Connectors:
+ "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // LittleHouse7
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LittleTower:
+ // The data has been exported from the gallery Desert, area index 79, ID 595, created by STR_Warrior
+ {
+ // Size:
+ 5, 8, 7, // SizeX = 5, SizeY = 8, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 5, 7, 7, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c: 24: 2\n" /* sandstone */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f: 65: 5\n" /* ladder */
+ "g: 64:12\n" /* wooddoorblock */
+ "h:101: 0\n" /* ironbars */
+ "i: 50: 4\n" /* torch */
+ "j:128: 2\n" /* sandstonestairs */
+ "k:126: 8\n" /* woodenslab */
+ "l:128: 4\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */
+ "n:128: 5\n" /* sandstonestairs */
+ "o:128: 7\n" /* sandstonestairs */
+ "p:128: 6\n" /* sandstonestairs */
+ "q: 44: 1\n" /* step */
+ "r: 96: 5\n" /* trapdoor */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aabaa"
+ /* 3 */ "abbba"
+ /* 4 */ "abbba"
+ /* 5 */ "abbba"
+ /* 6 */ "aaaaa"
+
+ // Level 1
+ /* z\x* 01234 */
+ /* 0 */ "c...c"
+ /* 1 */ "....."
+ /* 2 */ "cdedc"
+ /* 3 */ "df..d"
+ /* 4 */ "d...d"
+ /* 5 */ "d...d"
+ /* 6 */ "cdddc"
+
+ // Level 2
+ /* z\x* 01234 */
+ /* 0 */ "c...c"
+ /* 1 */ "....."
+ /* 2 */ "cdgdc"
+ /* 3 */ "df..d"
+ /* 4 */ "h...h"
+ /* 5 */ "d..id"
+ /* 6 */ "cdhdc"
+
+ // Level 3
+ /* z\x* 01234 */
+ /* 0 */ "j...j"
+ /* 1 */ "d...d"
+ /* 2 */ "cdddc"
+ /* 3 */ "dfkkd"
+ /* 4 */ "lkkkn"
+ /* 5 */ "dkkkd"
+ /* 6 */ "cdodc"
+
+ // Level 4
+ /* z\x* 01234 */
+ /* 0 */ "....."
+ /* 1 */ "....."
+ /* 2 */ "cdddc"
+ /* 3 */ "df..d"
+ /* 4 */ "d...d"
+ /* 5 */ "d...d"
+ /* 6 */ "cdddc"
+
+ // Level 5
+ /* z\x* 01234 */
+ /* 0 */ "....."
+ /* 1 */ "....."
+ /* 2 */ "cdhdc"
+ /* 3 */ "df..d"
+ /* 4 */ "h...h"
+ /* 5 */ "d..id"
+ /* 6 */ "cdhdc"
+
+ // Level 6
+ /* z\x* 01234 */
+ /* 0 */ "....."
+ /* 1 */ "....."
+ /* 2 */ "cdpdc"
+ /* 3 */ "dfkkd"
+ /* 4 */ "lkkkn"
+ /* 5 */ "dkkkd"
+ /* 6 */ "cdodc"
+
+ // Level 7
+ /* z\x* 01234 */
+ /* 0 */ "....."
+ /* 1 */ "....."
+ /* 2 */ "dqdqd"
+ /* 3 */ "qr..q"
+ /* 4 */ "d...d"
+ /* 5 */ "q...q"
+ /* 6 */ "dqdqd",
+
+ // Connectors:
+ "-1: 2, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // LittleTower
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MediumHouse1:
+ // The data has been exported from the gallery Desert, area index 71, ID 561, created by STR_Warrior
+ {
+ // Size:
+ 15, 8, 9, // SizeX = 15, SizeY = 8, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 15, 7, 9, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c: 24: 2\n" /* sandstone */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 3\n" /* wooddoorblock */
+ "f: 85: 0\n" /* fence */
+ "g: 64: 0\n" /* wooddoorblock */
+ "h: 65: 5\n" /* ladder */
+ "i: 64: 8\n" /* wooddoorblock */
+ "j:101: 0\n" /* ironbars */
+ "k: 50: 4\n" /* torch */
+ "l:128: 2\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */
+ "n:126: 8\n" /* woodenslab */
+ "o:128: 4\n" /* sandstonestairs */
+ "p:128: 7\n" /* sandstonestairs */
+ "q: 44: 1\n" /* step */
+ "r: 50: 3\n" /* torch */
+ "s:128: 6\n" /* sandstonestairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "aaaaaaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaaaaaa"
+ /* 2 */ "aaaaabaaaaaaaaa"
+ /* 3 */ "abbbbbbbbbaaaaa"
+ /* 4 */ "abbbbbbbbbaaaaa"
+ /* 5 */ "abbbbbbbbbbaaaa"
+ /* 6 */ "abbbbbbbbbaaaaa"
+ /* 7 */ "abbbbbbbbbaaaaa"
+ /* 8 */ "aaaaaaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "...c...c......."
+ /* 1 */ "..............."
+ /* 2 */ "cddddeddddcffff"
+ /* 3 */ "d.........d...f"
+ /* 4 */ "d.........d...f"
+ /* 5 */ "d.........g...f"
+ /* 6 */ "d.........d...f"
+ /* 7 */ "d.........dh..f"
+ /* 8 */ "cdddddddddcffff"
+
+ // Level 2
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "...c...c......."
+ /* 1 */ "..............."
+ /* 2 */ "cddddiddddc...."
+ /* 3 */ "d.........d...."
+ /* 4 */ "j.........d...."
+ /* 5 */ "j.........i...."
+ /* 6 */ "j.........d...."
+ /* 7 */ "d..k...k..dh..."
+ /* 8 */ "cdddjjjdddc...."
+
+ // Level 3
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "...l...l......."
+ /* 1 */ "...d...d......."
+ /* 2 */ "cdddddddddc...."
+ /* 3 */ "dnnnnnnnnnd...."
+ /* 4 */ "onnnnnnnnnd...."
+ /* 5 */ "onnnnnnnnnd...."
+ /* 6 */ "onnnnnnnnnd...."
+ /* 7 */ "dnnnnnnnnndh..."
+ /* 8 */ "cdddpppdddc...."
+
+ // Level 4
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "dqqqqdqqqqd...."
+ /* 3 */ "q..cdddc..q...."
+ /* 4 */ "q..d...d..q...."
+ /* 5 */ "d.........d...."
+ /* 6 */ "q..d...d..q...."
+ /* 7 */ "q..cdddc..q...."
+ /* 8 */ "dqqqqdqqqqd...."
+
+ // Level 5
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "..............."
+ /* 3 */ "...cdjdc......."
+ /* 4 */ "...dr..d......."
+ /* 5 */ "..............."
+ /* 6 */ "...d...d......."
+ /* 7 */ "...cdjdc......."
+ /* 8 */ "..............."
+
+ // Level 6
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "..............."
+ /* 3 */ "...cdsdc......."
+ /* 4 */ "...dnnnd......."
+ /* 5 */ "...dnnnd......."
+ /* 6 */ "...dnnnd......."
+ /* 7 */ "...cdpdc......."
+ /* 8 */ "..............."
+
+ // Level 7
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "..............."
+ /* 3 */ "...dqdqd......."
+ /* 4 */ "...q...q......."
+ /* 5 */ "...d...d......."
+ /* 6 */ "...q...q......."
+ /* 7 */ "...dqdqd......."
+ /* 8 */ "...............",
+
+ // Connectors:
+ "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 80,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // MediumHouse1
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MediumHouse2:
+ // The data has been exported from the gallery Desert, area index 74, ID 573, created by STR_Warrior
+ {
+ // Size:
+ 11, 9, 9, // SizeX = 11, SizeY = 9, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 11, 8, 9, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "A: 96: 3\n" /* trapdoor */
+ "B: 96: 6\n" /* trapdoor */
+ "C:128: 2\n" /* sandstonestairs */
+ "D:128: 0\n" /* sandstonestairs */
+ "E: 87: 0\n" /* netherstone */
+ "F:128: 1\n" /* sandstonestairs */
+ "G:128: 3\n" /* sandstonestairs */
+ "H: 51: 0\n" /* fire */
+ "I: 44: 9\n" /* step */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c: 24: 2\n" /* sandstone */
+ "d: 24: 0\n" /* sandstone */
+ "e: 65: 3\n" /* ladder */
+ "f: 85: 0\n" /* fence */
+ "g: 64: 7\n" /* wooddoorblock */
+ "h:134: 1\n" /* 134 */
+ "i:134: 2\n" /* 134 */
+ "j: 61: 2\n" /* furnace */
+ "k:134: 6\n" /* 134 */
+ "l:134: 4\n" /* 134 */
+ "m: 19: 0\n" /* sponge */
+ "n: 65: 2\n" /* ladder */
+ "o:101: 0\n" /* ironbars */
+ "p: 50: 2\n" /* torch */
+ "q: 47: 0\n" /* bookshelf */
+ "r: 64:12\n" /* wooddoorblock */
+ "s: 50: 3\n" /* torch */
+ "t:171: 8\n" /* carpet */
+ "u:128: 6\n" /* sandstonestairs */
+ "v:126: 8\n" /* woodenslab */
+ "w:128: 5\n" /* sandstonestairs */
+ "x:128: 4\n" /* sandstonestairs */
+ "y:128: 7\n" /* sandstonestairs */
+ "z: 44: 1\n" /* step */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "aaaaaaaaaaa"
+ /* 1 */ "abbbaaaaaaa"
+ /* 2 */ "abbbaaaaaaa"
+ /* 3 */ "abbbaaaaaaa"
+ /* 4 */ "abbbaaaabaa"
+ /* 5 */ "abbbbbbbbba"
+ /* 6 */ "abbbbbbbbba"
+ /* 7 */ "abbbbbbbbba"
+ /* 8 */ "aaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "cdddc......"
+ /* 1 */ "de..dfff.f."
+ /* 2 */ "d...d....f."
+ /* 3 */ "d...d....f."
+ /* 4 */ "d...ddddgdc"
+ /* 5 */ "d.........d"
+ /* 6 */ "dhf.......d"
+ /* 7 */ "dhi.jkl..nd"
+ /* 8 */ "cdddddddddc"
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "cdodc......"
+ /* 1 */ "de..o......"
+ /* 2 */ "d...o......"
+ /* 3 */ "o..pd......"
+ /* 4 */ "o...qdodrdc"
+ /* 5 */ "o......s..d"
+ /* 6 */ "d.t.......o"
+ /* 7 */ "d........nd"
+ /* 8 */ "cdddooodddc"
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "cdudc......"
+ /* 1 */ "devvw......"
+ /* 2 */ "dvvvw......"
+ /* 3 */ "xvvvd......"
+ /* 4 */ "xvvvddudddc"
+ /* 5 */ "xvvvvvvvvvd"
+ /* 6 */ "dvvvvvvvvvw"
+ /* 7 */ "dvvvqqqvvnd"
+ /* 8 */ "cdddyyydddc"
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "dzzzd......"
+ /* 1 */ "zA..z......"
+ /* 2 */ "z...z......"
+ /* 3 */ "z...z......"
+ /* 4 */ "d...dzzzzzd"
+ /* 5 */ "zddd......z"
+ /* 6 */ "zddd......z"
+ /* 7 */ "zddd.....Bz"
+ /* 8 */ "dzzzzdzzzzd"
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ "..........."
+ /* 5 */ ".cCc......."
+ /* 6 */ ".DEF......."
+ /* 7 */ ".cGc......."
+ /* 8 */ "..........."
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ "..........."
+ /* 5 */ ".c.c......."
+ /* 6 */ "..H........"
+ /* 7 */ ".c.c......."
+ /* 8 */ "..........."
+
+ // Level 7
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ "..........."
+ /* 5 */ ".ddd......."
+ /* 6 */ ".dId......."
+ /* 7 */ ".ddd......."
+ /* 8 */ "..........."
+
+ // Level 8
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ "..........."
+ /* 5 */ ".z.z......."
+ /* 6 */ "..........."
+ /* 7 */ ".z.z......."
+ /* 8 */ "...........",
+
+ // Connectors:
+ "-1: 8, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 80,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // MediumHouse2
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MediumHouse3:
+ // The data has been exported from the gallery Desert, area index 76, ID 575, created by STR_Warrior
+ {
+ // Size:
+ 12, 10, 11, // SizeX = 12, SizeY = 10, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 12, 9, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 12: 0\n" /* sand */
+ "b: 3: 0\n" /* dirt */
+ "c: 2: 0\n" /* grass */
+ "d: 5: 0\n" /* wood */
+ "e: 24: 0\n" /* sandstone */
+ "f: 24: 2\n" /* sandstone */
+ "g: 85: 0\n" /* fence */
+ "h: 64: 3\n" /* wooddoorblock */
+ "i: 64: 6\n" /* wooddoorblock */
+ "j: 65: 4\n" /* ladder */
+ "k: 65: 2\n" /* ladder */
+ "l: 50: 1\n" /* torch */
+ "m: 19: 0\n" /* sponge */
+ "n: 50: 2\n" /* torch */
+ "o:101: 0\n" /* ironbars */
+ "p: 64: 8\n" /* wooddoorblock */
+ "q: 64:12\n" /* wooddoorblock */
+ "r:128: 2\n" /* sandstonestairs */
+ "s:128: 6\n" /* sandstonestairs */
+ "t:126: 8\n" /* woodenslab */
+ "u:128: 5\n" /* sandstonestairs */
+ "v:128: 7\n" /* sandstonestairs */
+ "w: 44: 1\n" /* step */
+ "x: 96: 4\n" /* trapdoor */
+ "y:126: 0\n" /* woodenslab */
+ "z:128: 4\n" /* sandstonestairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "aaaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaaa"
+ /* 2 */ "bbbbbaaaaaaa"
+ /* 3 */ "bbbbbaaaaaaa"
+ /* 4 */ "bbbbbaaaaaaa"
+ /* 5 */ "bbbbbaaaaaaa"
+ /* 6 */ "bbbaaaaaaaaa"
+ /* 7 */ "aaaaaaaaaaaa"
+ /* 8 */ "aaaaaaaaaaaa"
+ /* 9 */ "aaaaaaaaaaaa"
+ /* 10 */ "aaaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "aaaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaaa"
+ /* 2 */ "cccccaaaadaa"
+ /* 3 */ "cccccaddddda"
+ /* 4 */ "cccccdddddda"
+ /* 5 */ "cccccaddddda"
+ /* 6 */ "cccaadddddda"
+ /* 7 */ "aaaaddddddda"
+ /* 8 */ "aaaadddaaaaa"
+ /* 9 */ "aaaadddaaaaa"
+ /* 10 */ "aaaaaaaaaaaa"
+
+ // Level 2
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ ".....e.....f"
+ /* 1 */ "............"
+ /* 2 */ "gggggfeeehef"
+ /* 3 */ "g....e.....e"
+ /* 4 */ "g....i.....e"
+ /* 5 */ "g....e.....e"
+ /* 6 */ "gggfe......e"
+ /* 7 */ "mmme......je"
+ /* 8 */ "mmme...eeeef"
+ /* 9 */ "mmme..kemmmm"
+ /* 10 */ "mmmfeeefmmmm"
+
+ // Level 3
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ ".....el...nf"
+ /* 1 */ "............"
+ /* 2 */ ".....fooepef"
+ /* 3 */ ".....e.....e"
+ /* 4 */ ".....q.....e"
+ /* 5 */ ".....e.....o"
+ /* 6 */ "...ge......e"
+ /* 7 */ "mmme......je"
+ /* 8 */ "mmme...eeoof"
+ /* 9 */ "mmme..kemmmm"
+ /* 10 */ "mmmgeeegmmmm"
+
+ // Level 4
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ ".....r.....r"
+ /* 1 */ ".....e.....e"
+ /* 2 */ ".....fsseeef"
+ /* 3 */ ".....ettttte"
+ /* 4 */ ".....ettttte"
+ /* 5 */ ".....etttttu"
+ /* 6 */ "...getttttte"
+ /* 7 */ "mmmettttttje"
+ /* 8 */ "mmmettteevvf"
+ /* 9 */ "mmmettkemmmm"
+ /* 10 */ "mmmgeeegmmmm"
+
+ // Level 5
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "............"
+ /* 2 */ ".....ewwewwe"
+ /* 3 */ ".....w.....w"
+ /* 4 */ ".....w.....w"
+ /* 5 */ ".....w.....e"
+ /* 6 */ "...geeeg...w"
+ /* 7 */ "mmme...e..xw"
+ /* 8 */ "mmme...ewwwe"
+ /* 9 */ "mmme..kemmmm"
+ /* 10 */ "mmmgeeegmmmm"
+
+ // Level 6
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "............"
+ /* 2 */ "............"
+ /* 3 */ "............"
+ /* 4 */ "............"
+ /* 5 */ "............"
+ /* 6 */ "...ge.eg...."
+ /* 7 */ "mmme...e...."
+ /* 8 */ "mmmo........"
+ /* 9 */ "mmme..kemmmm"
+ /* 10 */ "mmmgeoegmmmm"
+
+ // Level 7
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "............"
+ /* 2 */ "............"
+ /* 3 */ "............"
+ /* 4 */ "............"
+ /* 5 */ "............"
+ /* 6 */ "...ge.eg...."
+ /* 7 */ "mmme...e...."
+ /* 8 */ "mmmo........"
+ /* 9 */ "mmmel.kemmmm"
+ /* 10 */ "mmmgeoegmmmm"
+
+ // Level 8
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "............"
+ /* 2 */ "............"
+ /* 3 */ "............"
+ /* 4 */ "............"
+ /* 5 */ "............"
+ /* 6 */ "...fesef...."
+ /* 7 */ "mmmeyyye...."
+ /* 8 */ "mmmzyyyu...."
+ /* 9 */ "mmmeyykemmmm"
+ /* 10 */ "mmmfevefmmmm"
+
+ // Level 9
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "............"
+ /* 2 */ "............"
+ /* 3 */ "............"
+ /* 4 */ "............"
+ /* 5 */ "............"
+ /* 6 */ "...w.w.w...."
+ /* 7 */ "mmm........."
+ /* 8 */ "mmmw...w...."
+ /* 9 */ "mmm.....mmmm"
+ /* 10 */ "mmmw.w.wmmmm",
+
+ // Connectors:
+ "-1: 9, 2, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 80,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // MediumHouse3
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SmallHouse9:
+ // The data has been exported from the gallery Desert, area index 67, ID 556, created by STR_Warrior
+ {
+ // Size:
+ 9, 5, 11, // SizeX = 9, SizeY = 5, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 9, 4, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c: 24: 2\n" /* sandstone */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f: 65: 2\n" /* ladder */
+ "g: 64:12\n" /* wooddoorblock */
+ "h:101: 0\n" /* ironbars */
+ "i: 50: 2\n" /* torch */
+ "j: 50: 1\n" /* torch */
+ "k:128: 2\n" /* sandstonestairs */
+ "l:126: 8\n" /* woodenslab */
+ "m: 19: 0\n" /* sponge */
+ "n:128: 5\n" /* sandstonestairs */
+ "o:128: 6\n" /* sandstonestairs */
+ "p:128: 4\n" /* sandstonestairs */
+ "q:128: 7\n" /* sandstonestairs */
+ "r: 44: 1\n" /* step */
+ "s: 96: 6\n" /* trapdoor */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 012345678 */
+ /* 0 */ "aaaaaaaaa"
+ /* 1 */ "aaaaaaaaa"
+ /* 2 */ "aaaaaabaa"
+ /* 3 */ "aaaaabbba"
+ /* 4 */ "aaaaabbba"
+ /* 5 */ "aaaaabbba"
+ /* 6 */ "aaaaabbba"
+ /* 7 */ "abbbbbbba"
+ /* 8 */ "abbbbbbba"
+ /* 9 */ "abbbbbbba"
+ /* 10 */ "aaaaaaaaa"
+
+ // Level 1
+ /* z\x* 012345678 */
+ /* 0 */ "mmmmc...c"
+ /* 1 */ "mmmm....."
+ /* 2 */ "mmmmcdedc"
+ /* 3 */ "mmmmd...d"
+ /* 4 */ "mmmmd...d"
+ /* 5 */ "mmmmd...d"
+ /* 6 */ "cdddd...d"
+ /* 7 */ "d.......d"
+ /* 8 */ "d.......d"
+ /* 9 */ "d......fd"
+ /* 10 */ "cdddddddc"
+
+ // Level 2
+ /* z\x* 012345678 */
+ /* 0 */ "mmmmc...c"
+ /* 1 */ "mmmm....."
+ /* 2 */ "mmmmcdgdc"
+ /* 3 */ "mmmmd...d"
+ /* 4 */ "mmmmd...d"
+ /* 5 */ "mmmmd...h"
+ /* 6 */ "cdhdd...h"
+ /* 7 */ "d.......h"
+ /* 8 */ "h......id"
+ /* 9 */ "dj.....fd"
+ /* 10 */ "cddhhhddc"
+
+ // Level 3
+ /* z\x* 012345678 */
+ /* 0 */ "mmmmk...k"
+ /* 1 */ "mmmmd...d"
+ /* 2 */ "mmmmcdddc"
+ /* 3 */ "mmmmdllld"
+ /* 4 */ "mmmmdllld"
+ /* 5 */ "mmmmdllln"
+ /* 6 */ "cdoddllln"
+ /* 7 */ "dllllllln"
+ /* 8 */ "pllllllld"
+ /* 9 */ "dllllllfd"
+ /* 10 */ "cddqqqddc"
+
+ // Level 4
+ /* z\x* 012345678 */
+ /* 0 */ "mmmm....."
+ /* 1 */ "mmmm....."
+ /* 2 */ "mmmmdrdrd"
+ /* 3 */ "mmmmr...r"
+ /* 4 */ "mmmmr...r"
+ /* 5 */ "mmmmr...r"
+ /* 6 */ "drrrd...d"
+ /* 7 */ "r.......r"
+ /* 8 */ "r.......r"
+ /* 9 */ "r......sr"
+ /* 10 */ "drrrdrrrd",
+
+ // Connectors:
+ "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // SmallHouse9
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Temple:
+ // The data has been exported from the gallery Desert, area index 83, ID 599, created by STR_Warrior
+ {
+ // Size:
+ 13, 9, 9, // SizeX = 13, SizeY = 9, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 13, 8, 9, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "A: 44: 9\n" /* step */
+ "a: 12: 0\n" /* sand */
+ "b: 5: 0\n" /* wood */
+ "c: 24: 2\n" /* sandstone */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f: 17: 0\n" /* tree */
+ "g:128: 5\n" /* sandstonestairs */
+ "h:128: 4\n" /* sandstonestairs */
+ "i:128: 7\n" /* sandstonestairs */
+ "j:128: 6\n" /* sandstonestairs */
+ "k:118: 3\n" /* cauldronblock */
+ "l:155: 1\n" /* quartzblock */
+ "m: 19: 0\n" /* sponge */
+ "n: 64:12\n" /* wooddoorblock */
+ "o: 50: 3\n" /* torch */
+ "p:101: 0\n" /* ironbars */
+ "q:140: 0\n" /* flowerpotblock */
+ "r: 24: 1\n" /* sandstone */
+ "s:128: 2\n" /* sandstonestairs */
+ "t:126: 8\n" /* woodenslab */
+ "u: 44: 1\n" /* step */
+ "v:128: 0\n" /* sandstonestairs */
+ "w: 87: 0\n" /* netherstone */
+ "x:128: 1\n" /* sandstonestairs */
+ "y:128: 3\n" /* sandstonestairs */
+ "z: 51: 0\n" /* fire */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "aaaaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaaaa"
+ /* 2 */ "aaabbababbaaa"
+ /* 3 */ "abbbbbbbbbbba"
+ /* 4 */ "abbbbbbbbbbba"
+ /* 5 */ "abbbbbbbbbbba"
+ /* 6 */ "abbbbbbbbbbba"
+ /* 7 */ "abbbbbbbbbbba"
+ /* 8 */ "aaaaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "....c...c...."
+ /* 1 */ "............."
+ /* 2 */ "cdddddedddddc"
+ /* 3 */ "dfg.......hfd"
+ /* 4 */ "di.........id"
+ /* 5 */ "d...........d"
+ /* 6 */ "dj.........jd"
+ /* 7 */ "dfg.khlgk.hfd"
+ /* 8 */ "cdddddddddddc"
+
+ // Level 2
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "....c...c...."
+ /* 1 */ "............."
+ /* 2 */ "cdddddndddddc"
+ /* 3 */ "df...o.o...fd"
+ /* 4 */ "d...........d"
+ /* 5 */ "p...........p"
+ /* 6 */ "d...........d"
+ /* 7 */ "df...qrq...fd"
+ /* 8 */ "cdpppdddpppdc"
+
+ // Level 3
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "....s...s...."
+ /* 1 */ "....r...d...."
+ /* 2 */ "cdddddddddddc"
+ /* 3 */ "dftttttttttfd"
+ /* 4 */ "dtttttttttttd"
+ /* 5 */ "htttttttttttg"
+ /* 6 */ "dtttttttttttd"
+ /* 7 */ "dftttttttttfd"
+ /* 8 */ "cdiiidddiiidc"
+
+ // Level 4
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "............."
+ /* 2 */ "duuuuuduuuuud"
+ /* 3 */ "u...........u"
+ /* 4 */ "u.ddd...ddd.u"
+ /* 5 */ "d.ddd...ddd.d"
+ /* 6 */ "u.ddd...ddd.u"
+ /* 7 */ "u...........u"
+ /* 8 */ "duuuuuduuuuud"
+
+ // Level 5
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "............."
+ /* 2 */ "............."
+ /* 3 */ "............."
+ /* 4 */ "..csc...csc.."
+ /* 5 */ "..vwx...vwx.."
+ /* 6 */ "..cyc...cyc.."
+ /* 7 */ "............."
+ /* 8 */ "............."
+
+ // Level 6
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "............."
+ /* 2 */ "............."
+ /* 3 */ "............."
+ /* 4 */ "..c.c...c.c.."
+ /* 5 */ "...z.....z..."
+ /* 6 */ "..c.c...c.c.."
+ /* 7 */ "............."
+ /* 8 */ "............."
+
+ // Level 7
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "............."
+ /* 2 */ "............."
+ /* 3 */ "............."
+ /* 4 */ "..ddd...ddd.."
+ /* 5 */ "..dAd...dAd.."
+ /* 6 */ "..ddd...ddd.."
+ /* 7 */ "............."
+ /* 8 */ "............."
+
+ // Level 8
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "............."
+ /* 2 */ "............."
+ /* 3 */ "............."
+ /* 4 */ "..u.u...u.u.."
+ /* 5 */ "............."
+ /* 6 */ "..u.u...u.u.."
+ /* 7 */ "............."
+ /* 8 */ ".............",
+
+ // Connectors:
+ "-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 50,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // Temple
+}; // g_AlchemistVillagePrefabs
+
+
+
+
+
+
+const cPrefab::sDef g_AlchemistVillageStartingPrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Well:
+ // The data has been exported from the gallery Desert, area index 90, ID 631, created by STR_Warrior
+ {
+ // Size:
+ 5, 21, 5, // SizeX = 5, SizeY = 21, SizeZ = 5
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 4, 20, 4, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 1: 0\n" /* stone */
+ "b: 24: 0\n" /* sandstone */
+ "c: 8: 0\n" /* water */
+ "d: 24: 2\n" /* sandstone */
+ "e:128: 1\n" /* sandstonestairs */
+ "f: 44: 1\n" /* step */
+ "g:128: 0\n" /* sandstonestairs */
+ "h:128: 3\n" /* sandstonestairs */
+ "i:128: 2\n" /* sandstonestairs */
+ "j: 44: 9\n" /* step */
+ "k:126: 0\n" /* woodenslab */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aaaaa"
+ /* 3 */ "aaaaa"
+ /* 4 */ "aaaaa"
+
+ // Level 1
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 2
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 3
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 4
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 5
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 6
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 7
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 8
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 9
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 10
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 11
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 12
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 13
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 14
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 15
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 16
+ /* z\x* 01234 */
+ /* 0 */ "defgd"
+ /* 1 */ "h...h"
+ /* 2 */ "f...f"
+ /* 3 */ "i...i"
+ /* 4 */ "defgd"
+
+ // Level 17
+ /* z\x* 01234 */
+ /* 0 */ "d...d"
+ /* 1 */ "....."
+ /* 2 */ "....."
+ /* 3 */ "....."
+ /* 4 */ "d...d"
+
+ // Level 18
+ /* z\x* 01234 */
+ /* 0 */ "djjjd"
+ /* 1 */ "j...j"
+ /* 2 */ "j...j"
+ /* 3 */ "j...j"
+ /* 4 */ "djjjd"
+
+ // Level 19
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bkkkb"
+ /* 2 */ "bkkkb"
+ /* 3 */ "bkkkb"
+ /* 4 */ "bbbbb"
+
+ // Level 20
+ /* z\x* 01234 */
+ /* 0 */ "f.f.f"
+ /* 1 */ "....."
+ /* 2 */ "f...f"
+ /* 3 */ "....."
+ /* 4 */ "f.f.f",
+
+ // Connectors:
+ "2: 2, 16, 4: 3\n" /* Type 2, direction Z+ */
+ "2: 0, 16, 2: 4\n" /* Type 2, direction X- */
+ "2: 2, 16, 0: 2\n" /* Type 2, direction Z- */
+ "2: 4, 16, 2: 5\n" /* Type 2, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // Well
+};
+
+
+
+
+
+// The prefab counts:
+
+const size_t g_AlchemistVillagePrefabsCount = ARRAYCOUNT(g_AlchemistVillagePrefabs);
+
+const size_t g_AlchemistVillageStartingPrefabsCount = ARRAYCOUNT(g_AlchemistVillageStartingPrefabs);
+
diff --git a/src/Generating/Prefabs/AlchemistVillagePrefabs.h b/src/Generating/Prefabs/AlchemistVillagePrefabs.h
new file mode 100644
index 000000000..dddc5530a
--- /dev/null
+++ b/src/Generating/Prefabs/AlchemistVillagePrefabs.h
@@ -0,0 +1,15 @@
+
+// AlchemistVillagePrefabs.h
+
+// Declares the prefabs in the group AlchemistVillage
+
+#include "../Prefab.h"
+
+
+
+
+
+extern const cPrefab::sDef g_AlchemistVillagePrefabs[];
+extern const cPrefab::sDef g_AlchemistVillageStartingPrefabs[];
+extern const size_t g_AlchemistVillagePrefabsCount;
+extern const size_t g_AlchemistVillageStartingPrefabsCount;
diff --git a/src/Generating/Prefabs/JapaneseVillagePrefabs.cpp b/src/Generating/Prefabs/JapaneseVillagePrefabs.cpp
new file mode 100644
index 000000000..5ec222f84
--- /dev/null
+++ b/src/Generating/Prefabs/JapaneseVillagePrefabs.cpp
@@ -0,0 +1,3200 @@
+
+// JapaneseVillagePrefabs.cpp
+
+// Defines the prefabs in the group JapaneseVillage
+
+// NOTE: This file has been generated automatically by GalExport!
+// Any manual changes will be overwritten by the next automatic export!
+
+#include "Globals.h"
+#include "JapaneseVillagePrefabs.h"
+
+
+
+
+
+const cPrefab::sDef g_JapaneseVillagePrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Arch:
+ // The data has been exported from the gallery Plains, area index 144, ID 488, created by Aloe_vera
+ {
+ // Size:
+ 11, 7, 5, // SizeX = 11, SizeY = 7, SizeZ = 5
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 11, 6, 4, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 2: 0\n" /* grass */
+ "b: 13: 0\n" /* gravel */
+ "c:113: 0\n" /* netherbrickfence */
+ "d: 50: 5\n" /* torch */
+ "e: 44: 8\n" /* step */
+ "f: 44: 0\n" /* step */
+ "g: 43: 0\n" /* doubleslab */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "aaaabbbaaaa"
+ /* 1 */ "aaaabbbaaaa"
+ /* 2 */ "aaaabbbaaaa"
+ /* 3 */ "aaaabbbaaaa"
+ /* 4 */ "aaaabbbaaaa"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..c.....c.."
+ /* 1 */ "..c.....c.."
+ /* 2 */ "..c.....c.."
+ /* 3 */ "..c.....c.."
+ /* 4 */ "..c.....c.."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..c.....c.."
+ /* 1 */ "..........."
+ /* 2 */ "..c.....c.."
+ /* 3 */ "..........."
+ /* 4 */ "..c.....c.."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..d.....d.."
+ /* 1 */ "..........."
+ /* 2 */ "..c.....c.."
+ /* 3 */ "..........."
+ /* 4 */ "..d.....d.."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "...eeeee..."
+ /* 1 */ "..........."
+ /* 2 */ "..c.....c.."
+ /* 3 */ "..........."
+ /* 4 */ "...eeeee..."
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..f.....f.."
+ /* 1 */ ".egfffffge."
+ /* 2 */ ".egeeeeege."
+ /* 3 */ ".egfffffge."
+ /* 4 */ "..f.....f.."
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "gf.......fg"
+ /* 3 */ "..........."
+ /* 4 */ "...........",
+
+ // Connectors:
+ "2: 5, 1, 4: 3\n" /* Type 2, direction Z+ */
+ "2: 5, 1, 0: 2\n" /* Type 2, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // Arch
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Forge:
+ // The data has been exported from the gallery Plains, area index 79, ID 145, created by Aloe_vera
+ {
+ // Size:
+ 16, 11, 14, // SizeX = 16, SizeY = 11, SizeZ = 14
+
+ // Hitbox (relative to bounding box):
+ 0, 0, -1, // MinX, MinY, MinZ
+ 16, 10, 14, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 17: 1\n" /* tree */
+ "c: 67: 0\n" /* stairs */
+ "d: 5: 2\n" /* wood */
+ "e: 67: 2\n" /* stairs */
+ "f:113: 0\n" /* netherbrickfence */
+ "g:118: 2\n" /* cauldronblock */
+ "h: 67: 6\n" /* stairs */
+ "i: 67: 4\n" /* stairs */
+ "j: 87: 0\n" /* netherstone */
+ "k: 67: 7\n" /* stairs */
+ "l: 54: 5\n" /* chest */
+ "m: 19: 0\n" /* sponge */
+ "n: 61: 2\n" /* furnace */
+ "o:101: 0\n" /* ironbars */
+ "p: 51: 0\n" /* fire */
+ "q: 50: 4\n" /* torch */
+ "r: 50: 2\n" /* torch */
+ "s: 35: 0\n" /* wool */
+ "t: 67: 3\n" /* stairs */
+ "u: 50: 3\n" /* torch */
+ "v: 44: 8\n" /* step */
+ "w: 43: 0\n" /* doubleslab */
+ "x: 44: 0\n" /* step */
+ "y: 17: 5\n" /* tree */
+ "z: 17: 9\n" /* tree */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmmmm"
+ /* 2 */ "mmaaaaaaaaaaaamm"
+ /* 3 */ "mmaaaaaaaaaaaamm"
+ /* 4 */ "mmaaaaaaaaaaaamm"
+ /* 5 */ "mmaaaaaaaaaaaamm"
+ /* 6 */ "mmaaaaaaaaaaaamm"
+ /* 7 */ "mmaaaaaaaaaaaamm"
+ /* 8 */ "mmaaaaaaaaaaaamm"
+ /* 9 */ "mmaaaaaaaaaaaamm"
+ /* 10 */ "mmaaaaaaaaaaaamm"
+ /* 11 */ "mmaaaaaaaaaaaamm"
+ /* 12 */ "mmmmmmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ ".....bbbbbbbbb.."
+ /* 3 */ ".....cdddddddb.."
+ /* 4 */ ".....cddaaaadb.."
+ /* 5 */ "..beeedaaaaadb.."
+ /* 6 */ "..bddddaaaaadb.."
+ /* 7 */ "..bddddaaaaadb.."
+ /* 8 */ "..bddddaaaaadb.."
+ /* 9 */ "..bddddaaaaadb.."
+ /* 10 */ "..bddddddddddb.."
+ /* 11 */ "..bbbbbbbbbbbb.."
+ /* 12 */ "................"
+ /* 13 */ "................"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ ".....bfffbfffb.."
+ /* 3 */ ".............a.."
+ /* 4 */ ".............a.."
+ /* 5 */ "..b.....ghh..a.."
+ /* 6 */ "..f.....haa..b.."
+ /* 7 */ "..f.....ija..b.."
+ /* 8 */ "..f.....kaa..a.."
+ /* 9 */ "..f..........a.."
+ /* 10 */ "..fl.........a.."
+ /* 11 */ "..bffffbbffffb.."
+ /* 12 */ "................"
+ /* 13 */ "................"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ ".....bfffbfffb.."
+ /* 3 */ ".............a.."
+ /* 4 */ ".............a.."
+ /* 5 */ "..b......nn..a.."
+ /* 6 */ "..f.....oaa..b.."
+ /* 7 */ "..f.....opa..b.."
+ /* 8 */ "..f.....oaa..a.."
+ /* 9 */ "..f..........a.."
+ /* 10 */ "..f..........a.."
+ /* 11 */ "..bffffbbffffb.."
+ /* 12 */ "................"
+ /* 13 */ "................"
+
+ // Level 4
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ ".........q...q.."
+ /* 2 */ "....rbsssbsssb.."
+ /* 3 */ ".............a.."
+ /* 4 */ "..q..........a.."
+ /* 5 */ "..b......ce..a.."
+ /* 6 */ "..s......ea..b.."
+ /* 7 */ "..s......aa..b.."
+ /* 8 */ "..s......ta..a.."
+ /* 9 */ "..s..........a.."
+ /* 10 */ "..s..........a.."
+ /* 11 */ ".rbssssbbssssb.."
+ /* 12 */ "..u....uu....u.."
+ /* 13 */ "................"
+
+ // Level 5
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ ".vwxxxxxxxxxxwv."
+ /* 1 */ "vvvvvvvvvvvvvvvv"
+ /* 2 */ "wvbyybyyybbyybvw"
+ /* 3 */ "xvz..........zvx"
+ /* 4 */ "xvz..........zvx"
+ /* 5 */ "xvb..........zvx"
+ /* 6 */ "xvz.......a..bvx"
+ /* 7 */ "xvz......ca..bvx"
+ /* 8 */ "xvz.......a..zvx"
+ /* 9 */ "xvz..........zvx"
+ /* 10 */ "xvz..........zvx"
+ /* 11 */ "wvbyyyyyyyyyybvw"
+ /* 12 */ "vvvvvvvvvvvvvvvv"
+ /* 13 */ ".vwxxxxxxxxxxwv."
+
+ // Level 6
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "wx............xw"
+ /* 1 */ "x..............x"
+ /* 2 */ "..xxxxxxxxxxxx.."
+ /* 3 */ "..xwwwwwwwwwwx.."
+ /* 4 */ "..xwvvvvvvvvvx.."
+ /* 5 */ "..xwv.......vx.."
+ /* 6 */ "..xwv.....a.vx.."
+ /* 7 */ "..xwv.....a.vx.."
+ /* 8 */ "..xwv.....a.vx.."
+ /* 9 */ "..xwvvvvvvvvvx.."
+ /* 10 */ "..xwwwwwwwwwwx.."
+ /* 11 */ "..xxxxxxxxxxxx.."
+ /* 12 */ "x..............x"
+ /* 13 */ "wx............xw"
+
+ // Level 7
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ "................"
+ /* 3 */ "................"
+ /* 4 */ "....xxxxxxxx...."
+ /* 5 */ "....xxxxxxxx...."
+ /* 6 */ "....xwwwwwax...."
+ /* 7 */ "....xwvvvvax...."
+ /* 8 */ "....xwwwwwax...."
+ /* 9 */ "....xxxxxxxx...."
+ /* 10 */ "................"
+ /* 11 */ "................"
+ /* 12 */ "................"
+ /* 13 */ "................"
+
+ // Level 8
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ "................"
+ /* 3 */ "................"
+ /* 4 */ "................"
+ /* 5 */ "................"
+ /* 6 */ "..........a....."
+ /* 7 */ ".......xx.a....."
+ /* 8 */ "..........a....."
+ /* 9 */ "................"
+ /* 10 */ "................"
+ /* 11 */ "................"
+ /* 12 */ "................"
+ /* 13 */ "................"
+
+ // Level 9
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ "................"
+ /* 3 */ "................"
+ /* 4 */ "................"
+ /* 5 */ "................"
+ /* 6 */ "..........a....."
+ /* 7 */ "..........a....."
+ /* 8 */ "..........a....."
+ /* 9 */ "................"
+ /* 10 */ "................"
+ /* 11 */ "................"
+ /* 12 */ "................"
+ /* 13 */ "................"
+
+ // Level 10
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ "................"
+ /* 3 */ "................"
+ /* 4 */ "................"
+ /* 5 */ "................"
+ /* 6 */ "..........a....."
+ /* 7 */ "..........a....."
+ /* 8 */ "..........a....."
+ /* 9 */ "................"
+ /* 10 */ "................"
+ /* 11 */ "................"
+ /* 12 */ "................"
+ /* 13 */ "................",
+
+ // Connectors:
+ "-1: 0, 1, 3: 4\n" /* Type -1, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // Forge
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Garden2:
+ // The data has been exported from the gallery Plains, area index 147, ID 491, created by Aloe_vera
+ {
+ // Size:
+ 16, 5, 16, // SizeX = 16, SizeY = 5, SizeZ = 16
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 15, 4, 15, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 3: 0\n" /* dirt */
+ "b: 8: 0\n" /* water */
+ "c: 2: 0\n" /* grass */
+ "d: 17: 1\n" /* tree */
+ "e: 13: 0\n" /* gravel */
+ "f: 31: 2\n" /* tallgrass */
+ "g: 18: 5\n" /* leaves */
+ "h: 38: 7\n" /* rose */
+ "i: 17: 9\n" /* tree */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "aaaaaaaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaaaaaaa"
+ /* 2 */ "aaaaaaaaaaaaaaaa"
+ /* 3 */ "aaaaaaaaaaaaaaaa"
+ /* 4 */ "aaaaaaaaaaaaaaaa"
+ /* 5 */ "aaaaaaaaaaaaaaaa"
+ /* 6 */ "aaaaaaaaaaaaaaaa"
+ /* 7 */ "aaaaaaaaaaaaaaaa"
+ /* 8 */ "aaaaaaaaaaaaaaaa"
+ /* 9 */ "aaaaaaaaaaaaaaaa"
+ /* 10 */ "aaaaaaaaaaaaaaaa"
+ /* 11 */ "aaaaaaaaaaaaaaaa"
+ /* 12 */ "aaaaaaaaaaaaaaaa"
+ /* 13 */ "aaaaaaaaaaaaaaaa"
+ /* 14 */ "aaaaaaaaaaaaaaaa"
+ /* 15 */ "aaaaaaaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "aaaaaaaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaaaaaaa"
+ /* 2 */ "aaaaaaaaaaaaaaaa"
+ /* 3 */ "aaaaaaaaaaaaaaaa"
+ /* 4 */ "aaaaaaaaaaaaaaaa"
+ /* 5 */ "aaaaaaaaaaaaaaaa"
+ /* 6 */ "aaaabbaaaaaaaaaa"
+ /* 7 */ "aaabbbaaaaaaaaaa"
+ /* 8 */ "aaabbaaaaaaaaaaa"
+ /* 9 */ "aaaabaaaaaaaaaaa"
+ /* 10 */ "aaaaaaaaaaaaaaaa"
+ /* 11 */ "aaaaaaaaaaaaaaaa"
+ /* 12 */ "aaaaaaaaaaaaaaaa"
+ /* 13 */ "aaaaaaaaaaaaaaaa"
+ /* 14 */ "aaaaaaaaaaaaaaaa"
+ /* 15 */ "aaaaaaaaaaaaaaaa"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "cccccccccccccccc"
+ /* 1 */ "ccdccccccccdcccc"
+ /* 2 */ "cccccceecccccdcc"
+ /* 3 */ "ccccccceeccccccc"
+ /* 4 */ "cccccccceccccccc"
+ /* 5 */ "cccbbbbceccccccc"
+ /* 6 */ "cccbbbbceecccccc"
+ /* 7 */ "ccbbbbbcceeeeccc"
+ /* 8 */ "ccbbbbbccccceecc"
+ /* 9 */ "ccbbbbcccccccecc"
+ /* 10 */ "ccccbcccccccceec"
+ /* 11 */ "ccccccccccccccec"
+ /* 12 */ "ccccccccaaacccec"
+ /* 13 */ "cccccccccaccccec"
+ /* 14 */ "ccccccccccccceec"
+ /* 15 */ "cccccccccccceecc"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "......f...gg.g.."
+ /* 1 */ "..gg.....gggggg."
+ /* 2 */ "ffgg......ghgggg"
+ /* 3 */ ".............gg."
+ /* 4 */ "...........f...."
+ /* 5 */ "...........h.ff."
+ /* 6 */ ".............fh."
+ /* 7 */ "...............f"
+ /* 8 */ "................"
+ /* 9 */ ".......ff.f....."
+ /* 10 */ ".f.....ffggf...."
+ /* 11 */ ".......gggg.f..."
+ /* 12 */ ".f......iddg...."
+ /* 13 */ ".....f..gdgg...."
+ /* 14 */ "....ff...gg....."
+ /* 15 */ "................"
+
+ // Level 4
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "...........g.g.."
+ /* 2 */ ".............gg."
+ /* 3 */ "................"
+ /* 4 */ "................"
+ /* 5 */ "................"
+ /* 6 */ "................"
+ /* 7 */ "................"
+ /* 8 */ "................"
+ /* 9 */ "................"
+ /* 10 */ ".........g......"
+ /* 11 */ "........ggg....."
+ /* 12 */ "........ggg....."
+ /* 13 */ ".........g......"
+ /* 14 */ "................"
+ /* 15 */ "................",
+
+ // Connectors:
+ "-1: 12, 3, 15: 3\n" /* Type -1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // Garden2
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HouseMid:
+ // The data has been exported from the gallery Plains, area index 62, ID 119, created by Aloe_vera
+ {
+ // Size:
+ 10, 9, 9, // SizeX = 10, SizeY = 9, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ 0, 0, -1, // MinX, MinY, MinZ
+ 10, 8, 9, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 2\n" /* wood */
+ "b:135: 2\n" /* 135 */
+ "c:135: 0\n" /* 135 */
+ "d: 17: 9\n" /* tree */
+ "e:135: 3\n" /* 135 */
+ "f: 85: 0\n" /* fence */
+ "g: 17: 1\n" /* tree */
+ "h:171: 0\n" /* carpet */
+ "i: 50: 5\n" /* torch */
+ "j: 35: 0\n" /* wool */
+ "k: 17: 5\n" /* tree */
+ "l:124: 0\n" /* redstonelampon */
+ "m: 19: 0\n" /* sponge */
+ "n: 69: 9\n" /* lever */
+ "o: 44: 8\n" /* step */
+ "p: 43: 0\n" /* doubleslab */
+ "q: 44: 0\n" /* step */,
+
+ // Block data:
+ // Level 0
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "maaaaaaaaa"
+ /* 1 */ "maaaaaaaaa"
+ /* 2 */ "aaaaaaaaaa"
+ /* 3 */ "aaaaaaaaaa"
+ /* 4 */ "aaaaaaaaaa"
+ /* 5 */ "aaaaaaaaaa"
+ /* 6 */ "aaaaaaaaaa"
+ /* 7 */ "maaaaaaaaa"
+ /* 8 */ "maaaaaaaaa"
+
+ // Level 1
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".aaaaaaaaa"
+ /* 1 */ ".aaaaaaaaa"
+ /* 2 */ "baaaaaaaaa"
+ /* 3 */ "caaaaaaaaa"
+ /* 4 */ "caadaaaaaa"
+ /* 5 */ "caaaaaaaaa"
+ /* 6 */ "eaaaaaaaaa"
+ /* 7 */ ".aaaaaaaaa"
+ /* 8 */ ".aaaaaaaaa"
+
+ // Level 2
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".fffffffff"
+ /* 1 */ ".f.......f"
+ /* 2 */ ".f.ggggg.f"
+ /* 3 */ "...ghhhg.f"
+ /* 4 */ "....hhhg.f"
+ /* 5 */ "...ghhhg.f"
+ /* 6 */ ".f.ggggg.f"
+ /* 7 */ ".f.......f"
+ /* 8 */ ".fffffffff"
+
+ // Level 3
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".....i...i"
+ /* 1 */ ".........."
+ /* 2 */ ".i.jjgjj.."
+ /* 3 */ "...g...j.."
+ /* 4 */ ".......g.i"
+ /* 5 */ "...g...j.."
+ /* 6 */ ".i.jjgjj.."
+ /* 7 */ ".........."
+ /* 8 */ ".....i...i"
+
+ // Level 4
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".........."
+ /* 1 */ ".........."
+ /* 2 */ "...jjgjj.."
+ /* 3 */ "...g...j.."
+ /* 4 */ "...j...g.."
+ /* 5 */ "...g...j.."
+ /* 6 */ "...jjgjj.."
+ /* 7 */ ".........."
+ /* 8 */ ".........."
+
+ // Level 5
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".........."
+ /* 1 */ "...f...f.."
+ /* 2 */ "..fgkgkgf."
+ /* 3 */ "..fd...d.."
+ /* 4 */ "...d.lng.."
+ /* 5 */ "..fd...d.."
+ /* 6 */ "..fgkgkgf."
+ /* 7 */ "...f...f.."
+ /* 8 */ ".........."
+
+ // Level 6
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "...ooooo.."
+ /* 1 */ "..opppppo."
+ /* 2 */ ".opgjjjgpo"
+ /* 3 */ ".opjgggjpo"
+ /* 4 */ ".opjgggjpo"
+ /* 5 */ ".opjgggjpo"
+ /* 6 */ ".opgjjjgpo"
+ /* 7 */ "..opppppo."
+ /* 8 */ "...ooooo.."
+
+ // Level 7
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".opq...qpo"
+ /* 1 */ ".pq.....qp"
+ /* 2 */ ".q.qqqqq.q"
+ /* 3 */ "...qpppq.."
+ /* 4 */ "...qpppq.."
+ /* 5 */ "...qpppq.."
+ /* 6 */ ".q.qqqqq.q"
+ /* 7 */ ".pq.....qp"
+ /* 8 */ ".opq...qpo"
+
+ // Level 8
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".q.......q"
+ /* 1 */ ".........."
+ /* 2 */ ".........."
+ /* 3 */ ".........."
+ /* 4 */ ".....q...."
+ /* 5 */ ".........."
+ /* 6 */ ".........."
+ /* 7 */ ".........."
+ /* 8 */ ".q.......q",
+
+ // Connectors:
+ "-1: 0, 1, 4: 4\n" /* Type -1, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // HouseMid
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HouseSmall:
+ // The data has been exported from the gallery Plains, area index 68, ID 131, created by Aloe_vera
+ {
+ // Size:
+ 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 7, 5, 7, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 2\n" /* wood */
+ "b: 17: 1\n" /* tree */
+ "c: 35: 0\n" /* wool */
+ "d: 50: 4\n" /* torch */
+ "e: 85: 0\n" /* fence */
+ "f: 44: 8\n" /* step */
+ "g: 43: 0\n" /* doubleslab */
+ "h: 44: 0\n" /* step */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "maaaaam"
+ /* 2 */ "maaaaam"
+ /* 3 */ "maaaaam"
+ /* 4 */ "maaaaam"
+ /* 5 */ "maaaaam"
+ /* 6 */ "mmmmmmm"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".bcc.b."
+ /* 2 */ ".c...c."
+ /* 3 */ ".c...c."
+ /* 4 */ ".c...c."
+ /* 5 */ ".bcccb."
+ /* 6 */ "......."
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ ".....d."
+ /* 1 */ ".bee.b."
+ /* 2 */ ".c...c."
+ /* 3 */ ".e...e."
+ /* 4 */ ".c...c."
+ /* 5 */ ".beeeb."
+ /* 6 */ "......."
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ ".fffff."
+ /* 1 */ "fbcccbf"
+ /* 2 */ "fc...cf"
+ /* 3 */ "fc...cf"
+ /* 4 */ "fc...cf"
+ /* 5 */ "fbcccbf"
+ /* 6 */ ".fffff."
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "gh...hg"
+ /* 1 */ "hhhhhhh"
+ /* 2 */ ".hgggh."
+ /* 3 */ ".hgggh."
+ /* 4 */ ".hgggh."
+ /* 5 */ "hhhhhhh"
+ /* 6 */ "gh...hg"
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "......."
+ /* 2 */ "......."
+ /* 3 */ "...h..."
+ /* 4 */ "......."
+ /* 5 */ "......."
+ /* 6 */ ".......",
+
+ // Connectors:
+ "-1: 4, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // HouseSmall
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HouseSmallDblWithDoor:
+ // The data has been exported from the gallery Plains, area index 113, ID 265, created by Aloe_vera
+ {
+ // Size:
+ 11, 6, 7, // SizeX = 11, SizeY = 6, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 11, 5, 7, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 2\n" /* wood */
+ "b: 17: 9\n" /* tree */
+ "c: 17: 1\n" /* tree */
+ "d: 35: 0\n" /* wool */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:171:12\n" /* carpet */
+ "g:135: 1\n" /* 135 */
+ "h:126: 2\n" /* woodenslab */
+ "i:135: 2\n" /* 135 */
+ "j: 50: 4\n" /* torch */
+ "k: 64:12\n" /* wooddoorblock */
+ "l: 85: 0\n" /* fence */
+ "m: 19: 0\n" /* sponge */
+ "n: 44: 8\n" /* step */
+ "o: 43: 0\n" /* doubleslab */
+ "p: 44: 0\n" /* step */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmmmmmmmm"
+ /* 1 */ "maaaaaaaaam"
+ /* 2 */ "maaaabaaaam"
+ /* 3 */ "maaaabaaaam"
+ /* 4 */ "maaaabaaaam"
+ /* 5 */ "maaaaaaaaam"
+ /* 6 */ "mmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".cdedcdddc."
+ /* 2 */ ".dfff.fffd."
+ /* 3 */ ".dgffdfhfd."
+ /* 4 */ ".diifdfffd."
+ /* 5 */ ".cdddcdddc."
+ /* 6 */ "..........."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ ".j...j...j."
+ /* 1 */ ".cdkdclllc."
+ /* 2 */ ".d.......l."
+ /* 3 */ ".l...l...l."
+ /* 4 */ ".d...l...l."
+ /* 5 */ ".clllclllc."
+ /* 6 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ ".nnnnnnnnn."
+ /* 1 */ "ncdddcdddcn"
+ /* 2 */ "nd...d...dn"
+ /* 3 */ "nd...d...dn"
+ /* 4 */ "nd...d...dn"
+ /* 5 */ "ncdddcdddcn"
+ /* 6 */ ".nnnnnnnnn."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "op.......po"
+ /* 1 */ "ppppppppppp"
+ /* 2 */ ".pooooooop."
+ /* 3 */ ".ponndnnop."
+ /* 4 */ ".pooooooop."
+ /* 5 */ "ppppppppppp"
+ /* 6 */ "op.......po"
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "...ppppp..."
+ /* 4 */ "..........."
+ /* 5 */ "..........."
+ /* 6 */ "...........",
+
+ // Connectors:
+ "-1: 3, 1, -1: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // HouseSmallDblWithDoor
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HouseSmallDouble:
+ // The data has been exported from the gallery Plains, area index 72, ID 135, created by Aloe_vera
+ {
+ // Size:
+ 11, 6, 7, // SizeX = 11, SizeY = 6, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 11, 5, 7, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 2\n" /* wood */
+ "b: 17: 1\n" /* tree */
+ "c: 35: 0\n" /* wool */
+ "d:171:12\n" /* carpet */
+ "e:135: 1\n" /* 135 */
+ "f:126: 2\n" /* woodenslab */
+ "g:135: 2\n" /* 135 */
+ "h: 50: 4\n" /* torch */
+ "i: 85: 0\n" /* fence */
+ "j: 44: 8\n" /* step */
+ "k: 43: 0\n" /* doubleslab */
+ "l: 44: 0\n" /* step */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmmmmmmmm"
+ /* 1 */ "maaaaaaaaam"
+ /* 2 */ "maaaaaaaaam"
+ /* 3 */ "maaaaaaaaam"
+ /* 4 */ "maaaaaaaaam"
+ /* 5 */ "maaaaaaaaam"
+ /* 6 */ "mmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".bcc.bcccb."
+ /* 2 */ ".cddd.dddc."
+ /* 3 */ ".ceddcdfdc."
+ /* 4 */ ".cggdcdddc."
+ /* 5 */ ".bcccbcccb."
+ /* 6 */ "..........."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ ".h...h...h."
+ /* 1 */ ".bii.biiib."
+ /* 2 */ ".c.......c."
+ /* 3 */ ".i...i...i."
+ /* 4 */ ".c...i...c."
+ /* 5 */ ".biiibiiib."
+ /* 6 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ ".jjjjjjjjj."
+ /* 1 */ "jbiiibiiibj"
+ /* 2 */ "jc.......cj"
+ /* 3 */ "jc...c...cj"
+ /* 4 */ "jc...c...cj"
+ /* 5 */ "jbcccbcccbj"
+ /* 6 */ ".jjjjjjjjj."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "kl...l...lk"
+ /* 1 */ "lllllllllll"
+ /* 2 */ ".lkkklkkkl."
+ /* 3 */ ".lkjklkkkl."
+ /* 4 */ ".lkkklkkkl."
+ /* 5 */ "lllllllllll"
+ /* 6 */ "kl...l...lk"
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "...l...l..."
+ /* 4 */ "..........."
+ /* 5 */ "..........."
+ /* 6 */ "...........",
+
+ // Connectors:
+ "-1: 4, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // HouseSmallDouble
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HouseSmallWithDoor:
+ // The data has been exported from the gallery Plains, area index 112, ID 264, created by Aloe_vera
+ {
+ // Size:
+ 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 7, 5, 7, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 2\n" /* wood */
+ "b: 17: 1\n" /* tree */
+ "c: 35: 0\n" /* wool */
+ "d: 64: 7\n" /* wooddoorblock */
+ "e: 50: 4\n" /* torch */
+ "f: 64:12\n" /* wooddoorblock */
+ "g: 85: 0\n" /* fence */
+ "h: 44: 8\n" /* step */
+ "i: 43: 0\n" /* doubleslab */
+ "j: 44: 0\n" /* step */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "maaaaam"
+ /* 2 */ "maaaaam"
+ /* 3 */ "maaaaam"
+ /* 4 */ "maaaaam"
+ /* 5 */ "maaaaam"
+ /* 6 */ "mmmmmmm"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".bcdcb."
+ /* 2 */ ".c...c."
+ /* 3 */ ".c...c."
+ /* 4 */ ".c...c."
+ /* 5 */ ".bcccb."
+ /* 6 */ "......."
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ ".....e."
+ /* 1 */ ".bcfcb."
+ /* 2 */ ".g...g."
+ /* 3 */ ".g...g."
+ /* 4 */ ".g...g."
+ /* 5 */ ".bgggb."
+ /* 6 */ "......."
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ ".hhhhh."
+ /* 1 */ "hbcccbh"
+ /* 2 */ "hc...ch"
+ /* 3 */ "hc...ch"
+ /* 4 */ "hc...ch"
+ /* 5 */ "hbcccbh"
+ /* 6 */ ".hhhhh."
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "ij...ji"
+ /* 1 */ "jjjjjjj"
+ /* 2 */ ".jiiij."
+ /* 3 */ ".jiiij."
+ /* 4 */ ".jiiij."
+ /* 5 */ "jjjjjjj"
+ /* 6 */ "ij...ji"
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "......."
+ /* 2 */ "......."
+ /* 3 */ "...j..."
+ /* 4 */ "......."
+ /* 5 */ "......."
+ /* 6 */ ".......",
+
+ // Connectors:
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // HouseSmallWithDoor
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HouseWide:
+ // The data has been exported from the gallery Plains, area index 64, ID 121, created by STR_Warrior
+ {
+ // Size:
+ 11, 6, 11, // SizeX = 11, SizeY = 6, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ -1, 0, -1, // MinX, MinY, MinZ
+ 11, 5, 10, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 2\n" /* wood */
+ "b: 17: 1\n" /* tree */
+ "c: 35: 0\n" /* wool */
+ "d:171: 0\n" /* carpet */
+ "e:126: 1\n" /* woodenslab */
+ "f: 64: 5\n" /* wooddoorblock */
+ "g: 85: 0\n" /* fence */
+ "h: 50: 1\n" /* torch */
+ "i: 50: 2\n" /* torch */
+ "j: 64:12\n" /* wooddoorblock */
+ "k:126:11\n" /* woodenslab */
+ "l: 17: 5\n" /* tree */
+ "m: 19: 0\n" /* sponge */
+ "n:126: 3\n" /* woodenslab */
+ "o:125: 3\n" /* woodendoubleslab */
+ "p: 5: 3\n" /* wood */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmmmmmmmm"
+ /* 1 */ "mmaaaaaaamm"
+ /* 2 */ "maaaaaaaaam"
+ /* 3 */ "maaaaaaaaam"
+ /* 4 */ "maaaaaaaaam"
+ /* 5 */ "maaaaaaaaam"
+ /* 6 */ "maaaaaaaaam"
+ /* 7 */ "maaaaaaaaam"
+ /* 8 */ "maaaaaaaaam"
+ /* 9 */ "mmaaaaaaamm"
+ /* 10 */ "mmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..bcbcbcb.."
+ /* 2 */ ".b.d.....b."
+ /* 3 */ ".cded....c."
+ /* 4 */ ".bded....b."
+ /* 5 */ ".c.d.....c."
+ /* 6 */ ".b.......b."
+ /* 7 */ ".c.......c."
+ /* 8 */ ".b.......b."
+ /* 9 */ "..bcbfbcb.."
+ /* 10 */ "..........."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..bgbgbgb.."
+ /* 2 */ ".b.......b."
+ /* 3 */ ".g.......g."
+ /* 4 */ ".bh.....ib."
+ /* 5 */ ".g.......g."
+ /* 6 */ ".b.......b."
+ /* 7 */ ".g.......g."
+ /* 8 */ ".b.......b."
+ /* 9 */ "..bgbjbgb.."
+ /* 10 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "...kkkkk..."
+ /* 1 */ "..bcbcbcb.."
+ /* 2 */ ".b.......b."
+ /* 3 */ "kc.......ck"
+ /* 4 */ "kb.......bk"
+ /* 5 */ "kc.......ck"
+ /* 6 */ "kb.......bk"
+ /* 7 */ "kc.......ck"
+ /* 8 */ ".b.......b."
+ /* 9 */ "..bcblbcb.."
+ /* 10 */ "...kkkkk..."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ ".kn.....nk."
+ /* 1 */ "konnnnnnnok"
+ /* 2 */ "nnnnnnnnnnn"
+ /* 3 */ ".nnpppppnn."
+ /* 4 */ ".nnpkkkpnn."
+ /* 5 */ ".nnpkkkpnn."
+ /* 6 */ ".nnpkkkpnn."
+ /* 7 */ ".nnpppppnn."
+ /* 8 */ "nnnnnnnnnnn"
+ /* 9 */ "kknnnnnnnok"
+ /* 10 */ ".kn.....nk."
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "n.........n"
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ "....nnn...."
+ /* 5 */ "....non...."
+ /* 6 */ "....nnn...."
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "n.........n",
+
+ // Connectors:
+ "-1: 5, 1, 10: 3\n" /* Type -1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // HouseWide
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HouseWithGarden:
+ // The data has been exported from the gallery Plains, area index 67, ID 130, created by Aloe_vera
+ {
+ // Size:
+ 16, 9, 16, // SizeX = 16, SizeY = 9, SizeZ = 16
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 16, 8, 16, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 3: 0\n" /* dirt */
+ "b: 5: 2\n" /* wood */
+ "c: 2: 0\n" /* grass */
+ "d:113: 0\n" /* netherbrickfence */
+ "e: 17: 1\n" /* tree */
+ "f: 35: 0\n" /* wool */
+ "g:126: 2\n" /* woodenslab */
+ "h: 31: 2\n" /* tallgrass */
+ "i:125: 2\n" /* woodendoubleslab */
+ "j: 38: 3\n" /* rose */
+ "k: 38: 2\n" /* rose */
+ "l: 38: 1\n" /* rose */
+ "m: 19: 0\n" /* sponge */
+ "n: 17: 2\n" /* tree */
+ "o: 50: 4\n" /* torch */
+ "p: 85: 0\n" /* fence */
+ "q:140: 0\n" /* flowerpotblock */
+ "r: 50: 3\n" /* torch */
+ "s: 44: 8\n" /* step */
+ "t: 50: 1\n" /* torch */
+ "u: 50: 2\n" /* torch */
+ "v: 43: 0\n" /* doubleslab */
+ "w: 44: 0\n" /* step */
+ "x: 18:10\n" /* leaves */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmaammmmm"
+ /* 1 */ "aabbbbbbbbbbaaam"
+ /* 2 */ "aabbbbbbbbbbaaam"
+ /* 3 */ "aabbbbbbbbbbaaam"
+ /* 4 */ "aabbbbbbbbbbaaam"
+ /* 5 */ "aabbbbbbbbbbaaam"
+ /* 6 */ "aabbbbbbbbbbaaam"
+ /* 7 */ "aabbbbbbbbbbaaam"
+ /* 8 */ "aabbbbbbbbbbaaam"
+ /* 9 */ "aabbbbbbbbbbaaam"
+ /* 10 */ "aaaaaaaaaaaaaaam"
+ /* 11 */ "aaaaaaaaaaaaaaam"
+ /* 12 */ "aaaaaaaaaaaaaaam"
+ /* 13 */ "aaaaaaaaaaaaaaam"
+ /* 14 */ "aaaaaaaaaaaaaaam"
+ /* 15 */ "mmmmmmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmccmmmmm"
+ /* 1 */ "ccbbbbbbbbbbcccm"
+ /* 2 */ "ccbbbbbbbbbbcccm"
+ /* 3 */ "ccbbbbbbbbbbcccm"
+ /* 4 */ "ccbbbbbbbbbbcccm"
+ /* 5 */ "ccbbbbbbbbbbcccm"
+ /* 6 */ "ccbbbbbbbbbbcccm"
+ /* 7 */ "ccbbbbbbbbbbcccm"
+ /* 8 */ "ccbbbbbbbbbbcccm"
+ /* 9 */ "ccbbbbbbbbbbcccm"
+ /* 10 */ "cccccccccccccccm"
+ /* 11 */ "cccccccccccccccm"
+ /* 12 */ "cccccccccccccccm"
+ /* 13 */ "cccccccccccccacm"
+ /* 14 */ "cccccccccccccccm"
+ /* 15 */ "mmmmmmmmmmmmmmmm"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "ddeffeffe..eddd."
+ /* 2 */ "d.fbbgggg..f..d."
+ /* 3 */ "d.fbgggggggf.hd."
+ /* 4 */ "d.fbgggggggf..d."
+ /* 5 */ "d.eggggggggehhd."
+ /* 6 */ "d.fgiiggiigf.hd."
+ /* 7 */ "d.fgiiggiigf..d."
+ /* 8 */ "d.fggggggggf..d."
+ /* 9 */ "d.efffeefffe.hd."
+ /* 10 */ "d.............d."
+ /* 11 */ "djhhk.jhh..hh.d."
+ /* 12 */ "d.jlk.hj.h....d."
+ /* 13 */ "d..jh.hh..h..nd."
+ /* 14 */ "ddddddddddddddd."
+ /* 15 */ "................"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "........o..o...."
+ /* 1 */ "..eppeffe..e...."
+ /* 2 */ "..pqq......p...."
+ /* 3 */ "..pq.......p...."
+ /* 4 */ "..pq.......p...."
+ /* 5 */ "..e........e...."
+ /* 6 */ "..p........p...."
+ /* 7 */ "..p........p...."
+ /* 8 */ "..p........p...."
+ /* 9 */ "..epppeepppe...."
+ /* 10 */ "......rr........"
+ /* 11 */ "................"
+ /* 12 */ "................"
+ /* 13 */ ".............n.."
+ /* 14 */ "................"
+ /* 15 */ "................"
+
+ // Level 4
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "..ssssssssss...."
+ /* 1 */ ".seffeffeffes..."
+ /* 2 */ ".sf..r.....fs..."
+ /* 3 */ ".sf........fs..."
+ /* 4 */ ".sf........fs..."
+ /* 5 */ ".set......ues..."
+ /* 6 */ ".sf........fs..."
+ /* 7 */ ".sf........fs..."
+ /* 8 */ ".sf........fs..."
+ /* 9 */ ".sefffeefffes..."
+ /* 10 */ "..ssssssssss...."
+ /* 11 */ "................"
+ /* 12 */ "................"
+ /* 13 */ ".............n.."
+ /* 14 */ "................"
+ /* 15 */ "................"
+
+ // Level 5
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ ".vw........wv..."
+ /* 1 */ ".wwwwwwwwwwww..."
+ /* 2 */ "..wvvvvvvvvw...."
+ /* 3 */ "..wvvvvvvvvw...."
+ /* 4 */ "..wvvvvvvvvw...."
+ /* 5 */ "..wvvvvvvvvw...."
+ /* 6 */ "..wvvvvvvvvw...."
+ /* 7 */ "..wvvvvvvvvw...."
+ /* 8 */ "..wvvvvvvvvw...."
+ /* 9 */ ".wwwwwwwwwwww..."
+ /* 10 */ ".vw........wv..."
+ /* 11 */ "............xxx."
+ /* 12 */ "...........xxxxx"
+ /* 13 */ "...........xxnxx"
+ /* 14 */ "...........xxxxx"
+ /* 15 */ "............xxx."
+
+ // Level 6
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ "................"
+ /* 3 */ "....wwwwww......"
+ /* 4 */ "....wvvvvw......"
+ /* 5 */ "....wvvvvw......"
+ /* 6 */ "....wvvvvw......"
+ /* 7 */ "....wwwwww......"
+ /* 8 */ "................"
+ /* 9 */ "................"
+ /* 10 */ "................"
+ /* 11 */ "............xxx."
+ /* 12 */ "...........xxxxx"
+ /* 13 */ "...........xxnxx"
+ /* 14 */ "...........xxxxx"
+ /* 15 */ "............xxx."
+
+ // Level 7
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ "................"
+ /* 3 */ "................"
+ /* 4 */ "................"
+ /* 5 */ "......ww........"
+ /* 6 */ "................"
+ /* 7 */ "................"
+ /* 8 */ "................"
+ /* 9 */ "................"
+ /* 10 */ "................"
+ /* 11 */ "................"
+ /* 12 */ "............xxx."
+ /* 13 */ "............xnx."
+ /* 14 */ "............xx.."
+ /* 15 */ "................"
+
+ // Level 8
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ "................"
+ /* 3 */ "................"
+ /* 4 */ "................"
+ /* 5 */ "................"
+ /* 6 */ "................"
+ /* 7 */ "................"
+ /* 8 */ "................"
+ /* 9 */ "................"
+ /* 10 */ "................"
+ /* 11 */ "................"
+ /* 12 */ ".............x.."
+ /* 13 */ "............xxx."
+ /* 14 */ ".............x.."
+ /* 15 */ "................",
+
+ // Connectors:
+ "-1: 9, 2, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // HouseWithGarden
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HouseWithSakura1:
+ // The data has been exported from the gallery Plains, area index 75, ID 141, created by Aloe_vera
+ {
+ // Size:
+ 13, 7, 15, // SizeX = 13, SizeY = 7, SizeZ = 15
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 13, 6, 15, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 3: 0\n" /* dirt */
+ "b: 2: 0\n" /* grass */
+ "c: 17: 5\n" /* tree */
+ "d: 5: 2\n" /* wood */
+ "e: 17: 9\n" /* tree */
+ "f:113: 0\n" /* netherbrickfence */
+ "g: 17: 1\n" /* tree */
+ "h: 35: 0\n" /* wool */
+ "i: 31: 2\n" /* tallgrass */
+ "j: 54: 2\n" /* chest */
+ "k: 38: 6\n" /* rose */
+ "l: 38: 2\n" /* rose */
+ "m: 19: 0\n" /* sponge */
+ "n: 50: 4\n" /* torch */
+ "o: 85: 0\n" /* fence */
+ "p: 44: 8\n" /* step */
+ "q: 35: 6\n" /* wool */
+ "r: 43: 0\n" /* doubleslab */
+ "s: 44: 0\n" /* step */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "aaaaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaaaa"
+ /* 2 */ "aaaaaaaaaaaaa"
+ /* 3 */ "aaaaaaaaaaaaa"
+ /* 4 */ "aaaaaaaaaaaaa"
+ /* 5 */ "aaaaaaaaaaaaa"
+ /* 6 */ "aaaaaaaaaaaaa"
+ /* 7 */ "aaaaaaaaaaaaa"
+ /* 8 */ "aaaaaaaaaaaaa"
+ /* 9 */ "aaaaaaaaaaaaa"
+ /* 10 */ "aaaaaaaaaaaaa"
+ /* 11 */ "aaaaaaaaaaaaa"
+ /* 12 */ "aaaaaaaaaaaaa"
+ /* 13 */ "aaaaaaaaaaaaa"
+ /* 14 */ "aaaaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "bbbbbbbbbbbbb"
+ /* 1 */ "bbbbbbbbbbbbb"
+ /* 2 */ "bbbaccdabbbbb"
+ /* 3 */ "bbbedddebbbbb"
+ /* 4 */ "bbbedddebbbbb"
+ /* 5 */ "bbbedddebbbbb"
+ /* 6 */ "bbbacccabbbbb"
+ /* 7 */ "bbbbbbbbbbbbb"
+ /* 8 */ "bbbbbbbbbbbbb"
+ /* 9 */ "bbbbbbbbbbbbb"
+ /* 10 */ "bbbbbbbbbbabb"
+ /* 11 */ "bbbbbbbbbbbbb"
+ /* 12 */ "bbbbbbbbbbbbb"
+ /* 13 */ "bbbbbbbbbbbbb"
+ /* 14 */ "bbbbbbbbbbbbb"
+
+ // Level 2
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "ffff...ffffff"
+ /* 1 */ "f...........f"
+ /* 2 */ "f..ghh.g..i.f"
+ /* 3 */ "f..h...h..i.f"
+ /* 4 */ "f..h...h....f"
+ /* 5 */ "fi.h..jh..i.f"
+ /* 6 */ "f..ghhhg....f"
+ /* 7 */ "f.........i.f"
+ /* 8 */ "fii.........f"
+ /* 9 */ "f.k..k.i....f"
+ /* 10 */ "fl.i..i...g.f"
+ /* 11 */ "f.i..i.k....f"
+ /* 12 */ "f.l.k.......f"
+ /* 13 */ "f.....l.....f"
+ /* 14 */ "fffffffffffff"
+
+ // Level 3
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ ".......n....."
+ /* 2 */ "...goo.g....."
+ /* 3 */ "...h...h....."
+ /* 4 */ "...o...o....."
+ /* 5 */ "...h...h....."
+ /* 6 */ "...gooog....."
+ /* 7 */ "............."
+ /* 8 */ "............."
+ /* 9 */ "............."
+ /* 10 */ "..........g.."
+ /* 11 */ "............."
+ /* 12 */ "............."
+ /* 13 */ "............."
+ /* 14 */ "............."
+
+ // Level 4
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "...ppppp....."
+ /* 2 */ "..pghhhgp...."
+ /* 3 */ "..ph...hp...."
+ /* 4 */ "..ph...hp...."
+ /* 5 */ "..ph...hp...."
+ /* 6 */ "..pghhhgp...."
+ /* 7 */ "...ppppp....."
+ /* 8 */ "............."
+ /* 9 */ "..........q.."
+ /* 10 */ ".........qgq."
+ /* 11 */ "..........q.."
+ /* 12 */ "............."
+ /* 13 */ "............."
+ /* 14 */ "............."
+
+ // Level 5
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "..rs...sr...."
+ /* 2 */ "..sssssss...."
+ /* 3 */ "...srrrs....."
+ /* 4 */ "...srrrs....."
+ /* 5 */ "...srrrs....."
+ /* 6 */ "..sssssss...."
+ /* 7 */ "..rs...sr...."
+ /* 8 */ "............."
+ /* 9 */ ".........qqq."
+ /* 10 */ ".........qqq."
+ /* 11 */ ".........qqq."
+ /* 12 */ "............."
+ /* 13 */ "............."
+ /* 14 */ "............."
+
+ // Level 6
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "............."
+ /* 2 */ "............."
+ /* 3 */ "............."
+ /* 4 */ ".....s......."
+ /* 5 */ "............."
+ /* 6 */ "............."
+ /* 7 */ "............."
+ /* 8 */ "............."
+ /* 9 */ "............."
+ /* 10 */ "..........q.."
+ /* 11 */ "............."
+ /* 12 */ "............."
+ /* 13 */ "............."
+ /* 14 */ ".............",
+
+ // Connectors:
+ "-1: 5, 2, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // HouseWithSakura1
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HouseWithSpa:
+ // The data has been exported from the gallery Plains, area index 73, ID 139, created by Aloe_vera
+ {
+ // Size:
+ 16, 8, 14, // SizeX = 16, SizeY = 8, SizeZ = 14
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 15, 7, 13, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 2\n" /* wood */
+ "b: 3: 0\n" /* dirt */
+ "c: 2: 0\n" /* grass */
+ "d: 8: 0\n" /* water */
+ "e:135: 3\n" /* 135 */
+ "f:135: 1\n" /* 135 */
+ "g:113: 0\n" /* netherbrickfence */
+ "h: 17: 1\n" /* tree */
+ "i: 35: 0\n" /* wool */
+ "j:171:12\n" /* carpet */
+ "k: 64: 6\n" /* wooddoorblock */
+ "l:126: 2\n" /* woodenslab */
+ "m: 19: 0\n" /* sponge */
+ "n:135: 2\n" /* 135 */
+ "o: 64: 7\n" /* wooddoorblock */
+ "p: 50: 4\n" /* torch */
+ "q: 85: 0\n" /* fence */
+ "r: 64:12\n" /* wooddoorblock */
+ "s: 50: 3\n" /* torch */
+ "t: 44: 8\n" /* step */
+ "u: 43: 0\n" /* doubleslab */
+ "v: 44: 0\n" /* step */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ ".aaaaaaaaaaaaaa."
+ /* 2 */ ".aaaaaaaaaaaaaa."
+ /* 3 */ ".aaaaaaaaaaaaaa."
+ /* 4 */ ".aaaaaaaaaaaaaa."
+ /* 5 */ ".aaaaaaaaaaaaaa."
+ /* 6 */ ".aaaaaaaaaaaaaa."
+ /* 7 */ ".aaaaaabbbbbbbbb"
+ /* 8 */ ".aaaaaabbbbbbbbb"
+ /* 9 */ ".aaaaaabbbbbbbbb"
+ /* 10 */ ".aaaaaabbbbbbbbb"
+ /* 11 */ ".aaaaaabbbbbbbbb"
+ /* 12 */ ".aaaaaabbbbbbbbb"
+ /* 13 */ ".......bbbbbbbbb"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "maaaaaaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaaaaaam"
+ /* 6 */ "maaaaaaaaaaaaaam"
+ /* 7 */ "maaaaaaaaaaccccc"
+ /* 8 */ "maaaaaaacccccccc"
+ /* 9 */ "maaaaaaacccccccc"
+ /* 10 */ "maaaaaaacccccccc"
+ /* 11 */ "maaaaaaccccccccc"
+ /* 12 */ "maaaaaaccccccccc"
+ /* 13 */ "mmmmmmmccccccccc"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ ".aaaaaaaaaaaaaa."
+ /* 2 */ ".aaaaaaaaaaaaaa."
+ /* 3 */ ".aaaaaaaaaaaaaa."
+ /* 4 */ ".aaaaaaaaaaaaaa."
+ /* 5 */ ".aaaaaaaaaaaaaa."
+ /* 6 */ ".aaddaaaaaaaaaa."
+ /* 7 */ ".aaddaaeeef....."
+ /* 8 */ ".aaddaaf........"
+ /* 9 */ ".aaddaaf........"
+ /* 10 */ ".aaddaae........"
+ /* 11 */ ".aaddaa........."
+ /* 12 */ ".aaaaaa........."
+ /* 13 */ "................"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ ".ggggghiiihiiih."
+ /* 2 */ ".geee.ijjjjjjji."
+ /* 3 */ ".gf...kjjjijlji."
+ /* 4 */ ".gf...innjijjji."
+ /* 5 */ ".g....hiiohiiih."
+ /* 6 */ ".g....g........."
+ /* 7 */ ".g.............."
+ /* 8 */ ".g.............."
+ /* 9 */ ".g.............."
+ /* 10 */ ".g....g........."
+ /* 11 */ ".g....g........."
+ /* 12 */ ".gggggg........."
+ /* 13 */ "................"
+
+ // Level 4
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "......p...p...p."
+ /* 1 */ ".g....hqqqhqqqh."
+ /* 2 */ "......i.......i."
+ /* 3 */ "......r...q...q."
+ /* 4 */ "......i...q...i."
+ /* 5 */ "......hqqrhqqqh."
+ /* 6 */ "......g...s....."
+ /* 7 */ "................"
+ /* 8 */ "................"
+ /* 9 */ "................"
+ /* 10 */ "................"
+ /* 11 */ "................"
+ /* 12 */ ".g....g........."
+ /* 13 */ "................"
+
+ // Level 5
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ ".tttttttttttttt."
+ /* 1 */ "tggggghqqqhqqqht"
+ /* 2 */ "tg....i.......it"
+ /* 3 */ "tg....i...i...it"
+ /* 4 */ "tg....i...i...it"
+ /* 5 */ "tg....hiiihiiiht"
+ /* 6 */ "tg....gtttttttt."
+ /* 7 */ "tg....gt........"
+ /* 8 */ "tg....gt........"
+ /* 9 */ "tg....gt........"
+ /* 10 */ "tg....gt........"
+ /* 11 */ "tg....gt........"
+ /* 12 */ "tggggggt........"
+ /* 13 */ ".tttttt........."
+
+ // Level 6
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "uv............vu"
+ /* 1 */ "vvvvvvvvvvvvvvvv"
+ /* 2 */ ".vuuuuuuuuuuuuv."
+ /* 3 */ ".vuuuuuutuuuuuv."
+ /* 4 */ ".vuuuuuuuuuuuuv."
+ /* 5 */ ".vuuuuvvvvvvvvvv"
+ /* 6 */ ".vuuuuv.......vu"
+ /* 7 */ ".vuuuuv........."
+ /* 8 */ ".vuuuuv........."
+ /* 9 */ ".vuuuuv........."
+ /* 10 */ ".vuuuuv........."
+ /* 11 */ ".vuuuuv........."
+ /* 12 */ "vvvvvvvv........"
+ /* 13 */ "uv....vu........"
+
+ // Level 7
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ "................"
+ /* 3 */ "...vvvvvvvvvv..."
+ /* 4 */ "...vv..........."
+ /* 5 */ "...vv..........."
+ /* 6 */ "...vv..........."
+ /* 7 */ "...vv..........."
+ /* 8 */ "...vv..........."
+ /* 9 */ "...vv..........."
+ /* 10 */ "...vv..........."
+ /* 11 */ "................"
+ /* 12 */ "................"
+ /* 13 */ "................",
+
+ // Connectors:
+ "",
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // HouseWithSpa
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MediumSakuraTree:
+ // The data has been exported from the gallery Plains, area index 146, ID 490, created by STR_Warrior
+ {
+ // Size:
+ 7, 10, 7, // SizeX = 7, SizeY = 10, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 9, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 3: 0\n" /* dirt */
+ "b: 2: 0\n" /* grass */
+ "c: 31: 1\n" /* tallgrass */
+ "d: 38: 7\n" /* rose */
+ "e: 17: 1\n" /* tree */
+ "f: 38: 0\n" /* rose */
+ "g: 38: 8\n" /* rose */
+ "h: 38: 5\n" /* rose */
+ "i: 35: 6\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "aaaaaaa"
+ /* 2 */ "aaaaaaa"
+ /* 3 */ "aaaaaaa"
+ /* 4 */ "aaaaaaa"
+ /* 5 */ "aaaaaaa"
+ /* 6 */ "aaaaaaa"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "bbbbbbb"
+ /* 1 */ "bbbbbbb"
+ /* 2 */ "bbbbbbb"
+ /* 3 */ "bbbabbb"
+ /* 4 */ "bbbbbbb"
+ /* 5 */ "bbbbbbb"
+ /* 6 */ "bbbbbbb"
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "..c.c.."
+ /* 2 */ ".dccdc."
+ /* 3 */ "..cefc."
+ /* 4 */ ".ccfgh."
+ /* 5 */ "..ccc.."
+ /* 6 */ "......."
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "......."
+ /* 2 */ "......."
+ /* 3 */ "...e..."
+ /* 4 */ "......."
+ /* 5 */ "......."
+ /* 6 */ "......."
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "..i...."
+ /* 2 */ "......."
+ /* 3 */ "...e.i."
+ /* 4 */ ".i....."
+ /* 5 */ "......."
+ /* 6 */ "......."
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "..i...."
+ /* 2 */ "...i..."
+ /* 3 */ "..ieii."
+ /* 4 */ ".i.ii.."
+ /* 5 */ "...i..."
+ /* 6 */ "......."
+
+ // Level 6
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "..ii..."
+ /* 2 */ "..iii.."
+ /* 3 */ ".iieii."
+ /* 4 */ ".iiii.."
+ /* 5 */ "..iii.."
+ /* 6 */ "......."
+
+ // Level 7
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "..iii.."
+ /* 2 */ ".iiiii."
+ /* 3 */ ".iieii."
+ /* 4 */ ".iiiii."
+ /* 5 */ "..iii.."
+ /* 6 */ "......."
+
+ // Level 8
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "...i..."
+ /* 2 */ "..iiii."
+ /* 3 */ ".iiiii."
+ /* 4 */ "..iii.."
+ /* 5 */ "...i..."
+ /* 6 */ "......."
+
+ // Level 9
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "......."
+ /* 2 */ "...i..."
+ /* 3 */ "..iii.."
+ /* 4 */ "...i..."
+ /* 5 */ "......."
+ /* 6 */ ".......",
+
+ // Connectors:
+ "-1: 3, 2, 0: 2\n" /* Type -1, direction Z- */
+ "3: 6, 2, 3: 5\n" /* Type 3, direction X+ */
+ "-3: 0, 2, 3: 4\n" /* Type -3, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // MediumSakuraTree
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Restaurant:
+ // The data has been exported from the gallery Plains, area index 61, ID 117, created by Aloe_vera
+ {
+ // Size:
+ 15, 10, 15, // SizeX = 15, SizeY = 10, SizeZ = 15
+
+ // Hitbox (relative to bounding box):
+ -1, 0, -1, // MinX, MinY, MinZ
+ 14, 9, 15, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 2\n" /* wood */
+ "b:135: 0\n" /* 135 */
+ "c:135: 2\n" /* 135 */
+ "d:135: 1\n" /* 135 */
+ "e: 17: 9\n" /* tree */
+ "f:135: 3\n" /* 135 */
+ "g: 85: 0\n" /* fence */
+ "h: 17: 1\n" /* tree */
+ "i:171: 0\n" /* carpet */
+ "j:171:12\n" /* carpet */
+ "k:126: 1\n" /* woodenslab */
+ "l: 50: 5\n" /* torch */
+ "m: 19: 0\n" /* sponge */
+ "n: 35: 0\n" /* wool */
+ "o: 50: 3\n" /* torch */
+ "p: 50: 1\n" /* torch */
+ "q: 50: 4\n" /* torch */
+ "r: 35:14\n" /* wool */
+ "s: 44: 8\n" /* step */
+ "t: 43: 0\n" /* doubleslab */
+ "u: 44: 0\n" /* step */
+ "v: 17: 5\n" /* tree */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "mmmmaaaaaaammmm"
+ /* 1 */ "maaaaaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaaaaam"
+ /* 4 */ "aaaaaaaaaaaaaaa"
+ /* 5 */ "aaaaaaaaaaaaaaa"
+ /* 6 */ "aaaaaaaaaaaaaaa"
+ /* 7 */ "aaaaaaaaaaaaaaa"
+ /* 8 */ "aaaaaaaaaaaaaaa"
+ /* 9 */ "aaaaaaaaaaaaaaa"
+ /* 10 */ "aaaaaaaaaaaaaaa"
+ /* 11 */ "maaaaaaaaaaaaam"
+ /* 12 */ "maaaaaaaaaaaaam"
+ /* 13 */ "maaaaaaaaaaaaam"
+ /* 14 */ "mmmmaaaaaaammmm"
+
+ // Level 1
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "....bcccccd...."
+ /* 1 */ ".aaaaaaaaaaaaa."
+ /* 2 */ ".aaaaaaaaaaaaa."
+ /* 3 */ ".aaaaaaaaaaaaa."
+ /* 4 */ "caaaaaaaaaaaaac"
+ /* 5 */ "baaaaaaaaaaaaad"
+ /* 6 */ "baaaaaaaaaaaaad"
+ /* 7 */ "baaaaaaaaaaeaad"
+ /* 8 */ "baaaaaaaaaaaaad"
+ /* 9 */ "baaaaaaaaaaaaad"
+ /* 10 */ "faaaaaaaaaaaaaf"
+ /* 11 */ ".aaaaaaaaaaaaa."
+ /* 12 */ ".aaaaaaaaaaaaa."
+ /* 13 */ ".aaaaaaaaaaaaa."
+ /* 14 */ "....bfffffd...."
+
+ // Level 2
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".gggg.....gggg."
+ /* 2 */ ".g...........g."
+ /* 3 */ ".g.hhhhhhhhh.g."
+ /* 4 */ ".g.hiiijiiih.g."
+ /* 5 */ "...hikijikih..."
+ /* 6 */ "...hiiijiiihg.."
+ /* 7 */ "...hjjjjjjj...."
+ /* 8 */ "...hiiijiiihg.."
+ /* 9 */ "...hikijikih..."
+ /* 10 */ ".g.hiiijiiih.g."
+ /* 11 */ ".g.hhhhhhhhh.g."
+ /* 12 */ ".g...........g."
+ /* 13 */ ".gggg.....gggg."
+ /* 14 */ "..............."
+
+ // Level 3
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".l..g.....g..l."
+ /* 2 */ "..............."
+ /* 3 */ "...hnnnhnnnh..."
+ /* 4 */ ".g.n.......n.g."
+ /* 5 */ "...n.......n..."
+ /* 6 */ "...n.......hl.."
+ /* 7 */ "...h..........."
+ /* 8 */ "...n.......hl.."
+ /* 9 */ "...n.......n..."
+ /* 10 */ ".g.n.......n.g."
+ /* 11 */ "...hnnnhnnnh..."
+ /* 12 */ "..............."
+ /* 13 */ ".l..g.....g..l."
+ /* 14 */ "..............."
+
+ // Level 4
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "....g.....g...."
+ /* 2 */ "..............."
+ /* 3 */ "...hn.nhn.nh..."
+ /* 4 */ ".g.n...o...n.g."
+ /* 5 */ "...n.......n..."
+ /* 6 */ "...n.......h..."
+ /* 7 */ "...hp......e..."
+ /* 8 */ "...n.......h..."
+ /* 9 */ "...n.......n..."
+ /* 10 */ ".g.n...q...n.g."
+ /* 11 */ "...hn.nhn.nh..."
+ /* 12 */ "..............."
+ /* 13 */ "....g.....g...."
+ /* 14 */ "..............."
+
+ // Level 5
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "....g.....g...."
+ /* 2 */ "....ggggggg...."
+ /* 3 */ "...hnnnhnnnh..."
+ /* 4 */ ".ggn.......ngg."
+ /* 5 */ "..gn.......ng.."
+ /* 6 */ "..gn.......hg.."
+ /* 7 */ "..gh..r.r..ng.."
+ /* 8 */ "..gn.......hg.."
+ /* 9 */ "..gn.......ng.."
+ /* 10 */ ".ggn.......ngg."
+ /* 11 */ "...hnnnhnnnh..."
+ /* 12 */ "....ggggggg...."
+ /* 13 */ "....g.....g...."
+ /* 14 */ "..............."
+
+ // Level 6
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "...stuuuuuts..."
+ /* 2 */ "..sttttttttts.."
+ /* 3 */ ".sthvvvhvvvhts."
+ /* 4 */ ".tte.......ett."
+ /* 5 */ ".ute.......etu."
+ /* 6 */ ".ute.......htu."
+ /* 7 */ ".uth..g.g..etu."
+ /* 8 */ ".ute.......htu."
+ /* 9 */ ".ute.......etu."
+ /* 10 */ ".tte.......ett."
+ /* 11 */ ".sthvvvhvvvhts."
+ /* 12 */ "..sttttttttts.."
+ /* 13 */ "...stuuuuuts..."
+ /* 14 */ "..............."
+
+ // Level 7
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".stu.......uts."
+ /* 2 */ ".tu.........ut."
+ /* 3 */ ".u.uuuuuuuuu.u."
+ /* 4 */ "...utttttttu..."
+ /* 5 */ "...utttttttu..."
+ /* 6 */ "...utttttttu..."
+ /* 7 */ "...utttttttu..."
+ /* 8 */ "...utttttttu..."
+ /* 9 */ "...utttttttu..."
+ /* 10 */ "...utttttttu..."
+ /* 11 */ ".u.uuuuuuuuu.u."
+ /* 12 */ ".tu.........ut."
+ /* 13 */ ".stu.......uts."
+ /* 14 */ "..............."
+
+ // Level 8
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".u...........u."
+ /* 2 */ "..............."
+ /* 3 */ "..............."
+ /* 4 */ "..............."
+ /* 5 */ ".....uuuuu....."
+ /* 6 */ ".....utttu....."
+ /* 7 */ ".....utttu....."
+ /* 8 */ ".....utttu....."
+ /* 9 */ ".....uuuuu....."
+ /* 10 */ "..............."
+ /* 11 */ "..............."
+ /* 12 */ "..............."
+ /* 13 */ ".u...........u."
+ /* 14 */ "..............."
+
+ // Level 9
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "..............."
+ /* 3 */ "..............."
+ /* 4 */ "..............."
+ /* 5 */ "..............."
+ /* 6 */ "..............."
+ /* 7 */ ".......u......."
+ /* 8 */ "..............."
+ /* 9 */ "..............."
+ /* 10 */ "..............."
+ /* 11 */ "..............."
+ /* 12 */ "..............."
+ /* 13 */ "..............."
+ /* 14 */ "...............",
+
+ // Connectors:
+ "-1: 14, 1, 7: 5\n" /* Type -1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // Restaurant
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SakuraDouble:
+ // The data has been exported from the gallery Plains, area index 76, ID 142, created by Aloe_vera
+ {
+ // Size:
+ 12, 8, 6, // SizeX = 12, SizeY = 8, SizeZ = 6
+
+ // Hitbox (relative to bounding box):
+ -1, 0, -1, // MinX, MinY, MinZ
+ 12, 7, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 3: 0\n" /* dirt */
+ "b: 2: 0\n" /* grass */
+ "c: 17: 1\n" /* tree */
+ "d: 35: 6\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "aaaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaaa"
+ /* 2 */ "aaaaaaaaaaaa"
+ /* 3 */ "aaaaaaaaaaaa"
+ /* 4 */ "aaaaaaaaaaaa"
+ /* 5 */ "aaaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "bbbbbbbbbbbb"
+ /* 1 */ "bbbbbbbbbbbb"
+ /* 2 */ "bbabbbbbbbbb"
+ /* 3 */ "bbbbbbbbbabb"
+ /* 4 */ "bbbbbbbbbbbb"
+ /* 5 */ "bbbbbbbbbbbb"
+
+ // Level 2
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "............"
+ /* 2 */ "..c........."
+ /* 3 */ ".........c.."
+ /* 4 */ "............"
+ /* 5 */ "............"
+
+ // Level 3
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "............"
+ /* 2 */ "..c........."
+ /* 3 */ ".........c.."
+ /* 4 */ "............"
+ /* 5 */ "............"
+
+ // Level 4
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "..d........."
+ /* 1 */ "ddddd......."
+ /* 2 */ "ddcdd...ddd."
+ /* 3 */ "ddddd...dcd."
+ /* 4 */ "..d.....ddd."
+ /* 5 */ "............"
+
+ // Level 5
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ ".ddd........"
+ /* 1 */ ".ddd....ddd."
+ /* 2 */ "ddddd..ddddd"
+ /* 3 */ ".ddd...ddcdd"
+ /* 4 */ ".ddd...ddddd"
+ /* 5 */ "........ddd."
+
+ // Level 6
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "..d......d.."
+ /* 2 */ ".ddd....ddd."
+ /* 3 */ "..d....ddddd"
+ /* 4 */ "........ddd."
+ /* 5 */ ".........d.."
+
+ // Level 7
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "............"
+ /* 2 */ "............"
+ /* 3 */ ".........d.."
+ /* 4 */ "............"
+ /* 5 */ "............",
+
+ // Connectors:
+ "-1: -1, 2, 2: 4\n" /* Type -1, direction X- */
+ "3: 5, 2, 6: 3\n" /* Type 3, direction Z+ */
+ "-3: 6, 2, -1: 2\n" /* Type -3, direction Z- */
+ "-3: 12, 2, 2: 5\n" /* Type -3, direction X+ */
+ "3: 12, 2, 2: 5\n" /* Type 3, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // SakuraDouble
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SakuraSmall:
+ // The data has been exported from the gallery Plains, area index 145, ID 489, created by Aloe_vera
+ {
+ // Size:
+ 5, 7, 5, // SizeX = 5, SizeY = 7, SizeZ = 5
+
+ // Hitbox (relative to bounding box):
+ -1, 0, -1, // MinX, MinY, MinZ
+ 5, 6, 5, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 3: 0\n" /* dirt */
+ "b: 2: 0\n" /* grass */
+ "c: 17: 1\n" /* tree */
+ "d: 35: 6\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aaaaa"
+ /* 3 */ "aaaaa"
+ /* 4 */ "aaaaa"
+
+ // Level 1
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bbbbb"
+ /* 2 */ "bbabb"
+ /* 3 */ "bbbbb"
+ /* 4 */ "bbbbb"
+
+ // Level 2
+ /* z\x* 01234 */
+ /* 0 */ "....."
+ /* 1 */ "....."
+ /* 2 */ "..c.."
+ /* 3 */ "....."
+ /* 4 */ "....."
+
+ // Level 3
+ /* z\x* 01234 */
+ /* 0 */ "....."
+ /* 1 */ "....."
+ /* 2 */ "..c.."
+ /* 3 */ "....."
+ /* 4 */ "....."
+
+ // Level 4
+ /* z\x* 01234 */
+ /* 0 */ "..d.."
+ /* 1 */ "ddddd"
+ /* 2 */ "ddcdd"
+ /* 3 */ "ddddd"
+ /* 4 */ "..d.."
+
+ // Level 5
+ /* z\x* 01234 */
+ /* 0 */ ".ddd."
+ /* 1 */ ".ddd."
+ /* 2 */ "ddddd"
+ /* 3 */ ".ddd."
+ /* 4 */ ".ddd."
+
+ // Level 6
+ /* z\x* 01234 */
+ /* 0 */ "....."
+ /* 1 */ "..d.."
+ /* 2 */ ".ddd."
+ /* 3 */ "..d.."
+ /* 4 */ ".....",
+
+ // Connectors:
+ "-1: 2, 2, -1: 2\n" /* Type -1, direction Z- */
+ "3: 5, 2, 2: 5\n" /* Type 3, direction X+ */
+ "-3: -1, 2, 2: 4\n" /* Type -3, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // SakuraSmall
+}; // g_JapaneseVillagePrefabs
+
+
+
+
+
+
+const cPrefab::sDef g_JapaneseVillageStartingPrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HighTemple:
+ // The data has been exported from the gallery Plains, area index 70, ID 133, created by Aloe_vera
+ {
+ // Size:
+ 11, 19, 11, // SizeX = 11, SizeY = 19, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 10, 18, 10, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 2\n" /* wood */
+ "b:135: 0\n" /* 135 */
+ "c:135: 2\n" /* 135 */
+ "d:135: 1\n" /* 135 */
+ "e: 17: 9\n" /* tree */
+ "f:135: 3\n" /* 135 */
+ "g: 85: 0\n" /* fence */
+ "h: 17: 1\n" /* tree */
+ "i:171: 0\n" /* carpet */
+ "j: 50: 5\n" /* torch */
+ "k: 35: 0\n" /* wool */
+ "l: 17: 5\n" /* tree */
+ "m: 19: 0\n" /* sponge */
+ "n:124: 0\n" /* redstonelampon */
+ "o: 69: 9\n" /* lever */
+ "p: 44: 8\n" /* step */
+ "q: 43: 0\n" /* doubleslab */
+ "r: 44: 0\n" /* step */
+ "s: 50: 4\n" /* torch */
+ "t: 50: 1\n" /* torch */
+ "u: 50: 3\n" /* torch */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmaaaaammm"
+ /* 1 */ "maaaaaaaaam"
+ /* 2 */ "maaaaaaaaam"
+ /* 3 */ "aaaaaaaaaaa"
+ /* 4 */ "aaaaaaaaaaa"
+ /* 5 */ "aaaaaaaaaaa"
+ /* 6 */ "aaaaaaaaaaa"
+ /* 7 */ "aaaaaaaaaaa"
+ /* 8 */ "maaaaaaaaam"
+ /* 9 */ "maaaaaaaaam"
+ /* 10 */ "mmmaaaaammm"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "...bcccd..."
+ /* 1 */ ".aaaaaaaaa."
+ /* 2 */ ".aaaaaaaaa."
+ /* 3 */ "caaaaaaaaac"
+ /* 4 */ "baaaaaaaaad"
+ /* 5 */ "baaeaaaaaad"
+ /* 6 */ "baaaaaaaaad"
+ /* 7 */ "faaaaaaaaaf"
+ /* 8 */ ".aaaaaaaaa."
+ /* 9 */ ".aaaaaaaaa."
+ /* 10 */ "...bfffd..."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".ggg...ggg."
+ /* 2 */ ".g.......g."
+ /* 3 */ ".g.hhhhh.g."
+ /* 4 */ "...hiiih..."
+ /* 5 */ "....iiih..."
+ /* 6 */ "...hiiih..."
+ /* 7 */ ".g.hhhhh.g."
+ /* 8 */ ".g.......g."
+ /* 9 */ ".ggg...ggg."
+ /* 10 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".j.g...g.j."
+ /* 2 */ "..........."
+ /* 3 */ ".g.kkhkk.g."
+ /* 4 */ "...h...k..."
+ /* 5 */ ".......h..."
+ /* 6 */ "...h...k..."
+ /* 7 */ ".g.kkhkk.g."
+ /* 8 */ "..........."
+ /* 9 */ ".j.g...g.j."
+ /* 10 */ "..........."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "...g...g..."
+ /* 2 */ "..........."
+ /* 3 */ ".g.kkhkk.g."
+ /* 4 */ "...h...k..."
+ /* 5 */ "...k...h..."
+ /* 6 */ "...h...k..."
+ /* 7 */ ".g.kkhkk.g."
+ /* 8 */ "..........."
+ /* 9 */ "...g...g..."
+ /* 10 */ "..........."
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "...g...g..."
+ /* 2 */ "...ggggg..."
+ /* 3 */ ".gghlhlhgg."
+ /* 4 */ "..ge...eg.."
+ /* 5 */ "..ge.nohg.."
+ /* 6 */ "..ge...eg.."
+ /* 7 */ ".gghlhlhgg."
+ /* 8 */ "...ggggg..."
+ /* 9 */ "...g...g..."
+ /* 10 */ "..........."
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..pqrrrqp.."
+ /* 2 */ ".pqqqqqqqp."
+ /* 3 */ ".qqhkkkhqq."
+ /* 4 */ ".rqkhhhkqr."
+ /* 5 */ ".rqkhhhkqr."
+ /* 6 */ ".rqkhhhkqr."
+ /* 7 */ ".qqhkkkhqq."
+ /* 8 */ ".pqqqqqqqp."
+ /* 9 */ "..pqrrrqp.."
+ /* 10 */ "..........."
+
+ // Level 7
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".qr.....rq."
+ /* 2 */ ".........r."
+ /* 3 */ "...hhhhh..."
+ /* 4 */ "...hiiih..."
+ /* 5 */ "....iiih..."
+ /* 6 */ "...hiiih..."
+ /* 7 */ "...hhhhh..."
+ /* 8 */ ".r.......r."
+ /* 9 */ ".qr.....rq."
+ /* 10 */ "..........."
+
+ // Level 8
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "...kkhkk..."
+ /* 4 */ "...h...k..."
+ /* 5 */ ".......h..."
+ /* 6 */ "...h...k..."
+ /* 7 */ "...kkhkk..."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 9
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ ".....s....."
+ /* 3 */ "...kkhkk..."
+ /* 4 */ "...h...k..."
+ /* 5 */ "...k...ht.."
+ /* 6 */ "...h...k..."
+ /* 7 */ "...kkhkk..."
+ /* 8 */ ".....u....."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 10
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "...ggggg..."
+ /* 3 */ "..ghlhlhg.."
+ /* 4 */ "..ge...eg.."
+ /* 5 */ "..ge.nohg.."
+ /* 6 */ "..ge...eg.."
+ /* 7 */ "..ghlhlhg.."
+ /* 8 */ "...ggggg..."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 11
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..prrrrrp.."
+ /* 2 */ ".pqqqqqqqp."
+ /* 3 */ ".qqhkkkhqq."
+ /* 4 */ ".rqkhhhkqr."
+ /* 5 */ ".rqkhhhkqr."
+ /* 6 */ ".rqkhhhkqr."
+ /* 7 */ ".qqhkkkhqr."
+ /* 8 */ ".pqqqqqqqp."
+ /* 9 */ "..pqrrrqp.."
+ /* 10 */ "..........."
+
+ // Level 12
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".qr.....rq."
+ /* 2 */ ".r.......r."
+ /* 3 */ "...hhhhh..."
+ /* 4 */ "...hiiih..."
+ /* 5 */ "....iiih..."
+ /* 6 */ "...hiiih..."
+ /* 7 */ "...hhhhh..."
+ /* 8 */ ".r.......r."
+ /* 9 */ ".qr.....rq."
+ /* 10 */ "..........."
+
+ // Level 13
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "...kkhkk..."
+ /* 4 */ "...h...k..."
+ /* 5 */ ".......h..."
+ /* 6 */ "...h...k..."
+ /* 7 */ "...kkhkk..."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 14
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ ".....s....."
+ /* 3 */ "...kkhkk..."
+ /* 4 */ "...h...k..."
+ /* 5 */ "...k...ht.."
+ /* 6 */ "...h...k..."
+ /* 7 */ "...kkhkk..."
+ /* 8 */ ".....u....."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 15
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "...ggggg..."
+ /* 3 */ "..ghlhlhg.."
+ /* 4 */ "..ge...eg.."
+ /* 5 */ "..ge.nohg.."
+ /* 6 */ "..ge...eg.."
+ /* 7 */ "..ghlhlhg.."
+ /* 8 */ "...ggggg..."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 16
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..pqrrrqp.."
+ /* 2 */ ".pqqqqqqqp."
+ /* 3 */ ".qqrrrrrqq."
+ /* 4 */ ".rqrrrrrqr."
+ /* 5 */ ".rqrrrrrqr."
+ /* 6 */ ".rqrrrrrqr."
+ /* 7 */ ".qqrrrrrqq."
+ /* 8 */ ".pqqqqqqqp."
+ /* 9 */ "..pqrrrqp.."
+ /* 10 */ "..........."
+
+ // Level 17
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".qr.....rq."
+ /* 2 */ ".rr.....rr."
+ /* 3 */ "...rrrrr..."
+ /* 4 */ "...rqqqr..."
+ /* 5 */ "...rqqqr..."
+ /* 6 */ "...rqqqr..."
+ /* 7 */ "...rrrrr..."
+ /* 8 */ ".rr.....rr."
+ /* 9 */ ".qr.....rq."
+ /* 10 */ "..........."
+
+ // Level 18
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ "..........."
+ /* 5 */ ".....r....."
+ /* 6 */ "..........."
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "...........",
+
+ // Connectors:
+ "2: 0, 1, 5: 4\n" /* Type 2, direction X- */
+ "2: 5, 1, 0: 2\n" /* Type 2, direction Z- */
+ "2: 10, 1, 5: 5\n" /* Type 2, direction X+ */
+ "2: 5, 1, 10: 3\n" /* Type 2, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // HighTemple
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Well:
+ // The data has been exported from the gallery Plains, area index 143, ID 487, created by STR_Warrior
+ {
+ // Size:
+ 7, 14, 7, // SizeX = 7, SizeY = 14, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 13, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 1: 0\n" /* stone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 8: 0\n" /* water */
+ "d: 3: 0\n" /* dirt */
+ "e: 2: 0\n" /* grass */
+ "f: 13: 0\n" /* gravel */
+ "g: 67: 1\n" /* stairs */
+ "h: 67: 2\n" /* stairs */
+ "i: 67: 0\n" /* stairs */
+ "j: 67: 3\n" /* stairs */
+ "k: 85: 0\n" /* fence */
+ "l: 44: 8\n" /* step */
+ "m: 19: 0\n" /* sponge */
+ "n: 44: 0\n" /* step */
+ "o: 43: 0\n" /* doubleslab */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "aaaaaaa"
+ /* 2 */ "aaaaaaa"
+ /* 3 */ "aaaaaaa"
+ /* 4 */ "aaaaaaa"
+ /* 5 */ "aaaaaaa"
+ /* 6 */ "aaaaaaa"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "abbbbba"
+ /* 2 */ "abcc.ba"
+ /* 3 */ "abcccba"
+ /* 4 */ "abcccba"
+ /* 5 */ "abbbbba"
+ /* 6 */ "aaaaaaa"
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "abbbbba"
+ /* 2 */ "abcccba"
+ /* 3 */ "abcccba"
+ /* 4 */ "abcccba"
+ /* 5 */ "abbbbba"
+ /* 6 */ "aaaaaaa"
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "abbbbba"
+ /* 2 */ "abcccba"
+ /* 3 */ "abcccba"
+ /* 4 */ "abcccba"
+ /* 5 */ "abbbbba"
+ /* 6 */ "aaaaaaa"
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "abbbbba"
+ /* 2 */ "abcccba"
+ /* 3 */ "abcccba"
+ /* 4 */ "abcccba"
+ /* 5 */ "abbbbba"
+ /* 6 */ "aaaaaaa"
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "ddddddd"
+ /* 1 */ "dbbbbbd"
+ /* 2 */ "dbcccbd"
+ /* 3 */ "dbcccbd"
+ /* 4 */ "dbcccbd"
+ /* 5 */ "dbbbbbd"
+ /* 6 */ "ddddddd"
+
+ // Level 6
+ /* z\x* 0123456 */
+ /* 0 */ "ddddddd"
+ /* 1 */ "dbbbbbd"
+ /* 2 */ "dbcccbd"
+ /* 3 */ "dbcccbd"
+ /* 4 */ "dbcccbd"
+ /* 5 */ "dbbbbbd"
+ /* 6 */ "ddddddd"
+
+ // Level 7
+ /* z\x* 0123456 */
+ /* 0 */ "ddddddd"
+ /* 1 */ "dbbbbbd"
+ /* 2 */ "dbcccbd"
+ /* 3 */ "dbcccbd"
+ /* 4 */ "dbcccbd"
+ /* 5 */ "dbbbbbd"
+ /* 6 */ "ddddddd"
+
+ // Level 8
+ /* z\x* 0123456 */
+ /* 0 */ "eefffee"
+ /* 1 */ "ebbbbbe"
+ /* 2 */ "fbcccbf"
+ /* 3 */ "fbcccbf"
+ /* 4 */ "fbcccbf"
+ /* 5 */ "ebbbbbe"
+ /* 6 */ "eefffee"
+
+ // Level 9
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".bghib."
+ /* 2 */ ".j...j."
+ /* 3 */ ".i...g."
+ /* 4 */ ".h...h."
+ /* 5 */ ".bgjib."
+ /* 6 */ "......."
+
+ // Level 10
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".k...k."
+ /* 2 */ "......."
+ /* 3 */ "......."
+ /* 4 */ "......."
+ /* 5 */ ".k...k."
+ /* 6 */ "......."
+
+ // Level 11
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".k...k."
+ /* 2 */ "......."
+ /* 3 */ "......."
+ /* 4 */ "......."
+ /* 5 */ ".k...k."
+ /* 6 */ "......."
+
+ // Level 12
+ /* z\x* 0123456 */
+ /* 0 */ ".lnnnl."
+ /* 1 */ "loooool"
+ /* 2 */ "nooooon"
+ /* 3 */ "nooooon"
+ /* 4 */ "nooooon"
+ /* 5 */ "loooool"
+ /* 6 */ ".lnnnl."
+
+ // Level 13
+ /* z\x* 0123456 */
+ /* 0 */ "n.....n"
+ /* 1 */ "......."
+ /* 2 */ "..nnn.."
+ /* 3 */ "..non.."
+ /* 4 */ "..nnn.."
+ /* 5 */ "......."
+ /* 6 */ "n.....n",
+
+ // Connectors:
+ "2: 0, 9, 3: 4\n" /* Type 2, direction X- */
+ "2: 3, 9, 0: 2\n" /* Type 2, direction Z- */
+ "2: 6, 9, 3: 5\n" /* Type 2, direction X+ */
+ "2: 3, 9, 6: 3\n" /* Type 2, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // Well
+};
+
+
+
+
+
+// The prefab counts:
+
+const size_t g_JapaneseVillagePrefabsCount = ARRAYCOUNT(g_JapaneseVillagePrefabs);
+
+const size_t g_JapaneseVillageStartingPrefabsCount = ARRAYCOUNT(g_JapaneseVillageStartingPrefabs);
+
diff --git a/src/Generating/Prefabs/JapaneseVillagePrefabs.h b/src/Generating/Prefabs/JapaneseVillagePrefabs.h
new file mode 100644
index 000000000..501b6c1cd
--- /dev/null
+++ b/src/Generating/Prefabs/JapaneseVillagePrefabs.h
@@ -0,0 +1,15 @@
+
+// JapaneseVillagePrefabs.h
+
+// Declares the prefabs in the group JapaneseVillage
+
+#include "../Prefab.h"
+
+
+
+
+
+extern const cPrefab::sDef g_JapaneseVillagePrefabs[];
+extern const cPrefab::sDef g_JapaneseVillageStartingPrefabs[];
+extern const size_t g_JapaneseVillagePrefabsCount;
+extern const size_t g_JapaneseVillageStartingPrefabsCount;
diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp
index 088340391..2c97f28ea 100644
--- a/src/Generating/Prefabs/NetherFortPrefabs.cpp
+++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp
@@ -155,6 +155,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // BalconyCorridor
@@ -315,6 +318,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // BalconyTee2
@@ -435,6 +441,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // BlazePlatform
@@ -605,6 +614,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // BlazePlatformOverhang
@@ -805,6 +817,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
-1000,
+
+ // MoveToGround:
+ false,
}, // BridgeCircleCrossing
@@ -1006,6 +1021,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // BridgeCrossing
@@ -1100,6 +1118,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // BridgeCrumble1
@@ -1200,6 +1221,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // BridgeCrumble2
@@ -1379,6 +1403,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
1000,
+
+ // MoveToGround:
+ false,
}, // BridgeDoubleCrumble
@@ -1619,6 +1646,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // BridgeFunnelDown
@@ -1948,6 +1978,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // BridgeLevelCrossing
@@ -2067,6 +2100,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
1000,
+
+ // MoveToGround:
+ false,
}, // BridgeSegment
@@ -2227,6 +2263,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // BridgeTee
@@ -2328,6 +2367,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // Corridor11
@@ -2429,6 +2471,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // Corridor13
@@ -2524,6 +2569,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
500,
+
+ // MoveToGround:
+ false,
}, // Corridor5
@@ -2663,6 +2711,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // CorridorCorner5
@@ -2803,6 +2854,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // CorridorCornerChest5
@@ -2928,6 +2982,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
-50,
+
+ // MoveToGround:
+ false,
}, // CorridorCrossing
@@ -3080,6 +3137,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // CorridorStairs
@@ -3181,6 +3241,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // DarkCorridor
@@ -3438,6 +3501,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // LavaStaircase
@@ -3769,6 +3835,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
-1000,
+
+ // MoveToGround:
+ false,
}, // LavaStaircaseBig
@@ -4047,6 +4116,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // LavaStairsBridge
@@ -4235,6 +4307,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
-1000,
+
+ // MoveToGround:
+ false,
}, // MidStaircase
@@ -4378,6 +4453,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // StairsToOpen1
@@ -4521,6 +4599,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // StairsToOpen2
@@ -4638,6 +4719,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // Tee2x4
@@ -4767,6 +4851,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // Tee4x4
@@ -4863,6 +4950,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
-50,
+
+ // MoveToGround:
+ false,
}, // TinyCorridorCorner
@@ -4960,6 +5050,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // TinyCorridorCornerChest
@@ -5059,6 +5152,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
-50,
+
+ // MoveToGround:
+ false,
}, // TinyCorridorCrossing
@@ -5174,6 +5270,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
// AddWeightIfSame:
-99,
+
+ // MoveToGround:
+ false,
}, // Turret
}; // g_NetherFortPrefabs
@@ -5378,6 +5477,9 @@ const cPrefab::sDef g_NetherFortStartingPrefabs[] =
// AddWeightIfSame:
0,
+
+ // MoveToGround:
+ false,
}, // CentralRoom
};
diff --git a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp
new file mode 100644
index 000000000..f5c5b7a20
--- /dev/null
+++ b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp
@@ -0,0 +1,6114 @@
+
+// PlainsVillagePrefabs.cpp
+
+// Defines the prefabs in the group PlainsVillage
+
+// NOTE: This file has been generated automatically by GalExport!
+// Any manual changes will be overwritten by the next automatic export!
+
+#include "Globals.h"
+#include "PlainsVillagePrefabs.h"
+
+
+
+
+
+const cPrefab::sDef g_PlainsVillagePrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // BigPlantBed:
+ // The data has been exported from the gallery Plains, area index 26, ID 70, created by Taugrammaton
+ {
+ // Size:
+ 13, 8, 12, // SizeX = 13, SizeY = 8, SizeZ = 12
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 12, 7, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 3: 0\n" /* dirt */
+ "b: 5: 0\n" /* wood */
+ "c: 13: 0\n" /* gravel */
+ "d: 17: 0\n" /* tree */
+ "e: 60: 7\n" /* tilleddirt */
+ "f: 8: 0\n" /* water */
+ "g: 85: 0\n" /* fence */
+ "h: 59: 7\n" /* crops */
+ "i: 50: 5\n" /* torch */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "aaaaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaaaa"
+ /* 2 */ "aaaaaaaaaaaaa"
+ /* 3 */ "aaaaaaaaaaaaa"
+ /* 4 */ "aaaaaaaaaaaaa"
+ /* 5 */ "aaaaaaaaaaaaa"
+ /* 6 */ "aaaaaaaaaaaaa"
+ /* 7 */ "aaaaaaaaaaaaa"
+ /* 8 */ "aaaaaaaaaaaaa"
+ /* 9 */ "aaaaaaaaaaaaa"
+ /* 10 */ "aaaaaaaaaaaaa"
+ /* 11 */ "aaaaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "bbbbbbbbbbbbb"
+ /* 1 */ "bcccccccccccb"
+ /* 2 */ "bcccccccccccb"
+ /* 3 */ "bcccccccccccb"
+ /* 4 */ "bcccccccccccb"
+ /* 5 */ "bcccccccccccb"
+ /* 6 */ "bcccccccccccb"
+ /* 7 */ "bcccccccccccb"
+ /* 8 */ "bcccccccccccb"
+ /* 9 */ "bcccccccccccb"
+ /* 10 */ "bcccccccccccb"
+ /* 11 */ "bbbbbbbbbbbbb"
+
+ // Level 2
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "ddddddddddddd"
+ /* 1 */ "deefeefeefeed"
+ /* 2 */ "deefeefeefeed"
+ /* 3 */ "deefeefeefeed"
+ /* 4 */ "deefeefeefeed"
+ /* 5 */ "deefeefeefeed"
+ /* 6 */ "deefeefeefeed"
+ /* 7 */ "deefeefeefeed"
+ /* 8 */ "deefeefeefeed"
+ /* 9 */ "deefeefeefeed"
+ /* 10 */ "deefeefeefeed"
+ /* 11 */ "ddddddddddddd"
+
+ // Level 3
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "g..g..g..g..g"
+ /* 1 */ "ghh.h..hh.hhg"
+ /* 2 */ "ghh..h.hh.hhg"
+ /* 3 */ "ghh.h..h..hhg"
+ /* 4 */ "ghh.hh.h..hhg"
+ /* 5 */ "ghh.h..hh.hhg"
+ /* 6 */ "ghh.hh.hh.hhg"
+ /* 7 */ "ghh....h..hhg"
+ /* 8 */ "ghh..h....hhg"
+ /* 9 */ "ghh.....h.hhg"
+ /* 10 */ "ghh.hh.h..hhg"
+ /* 11 */ "g..g..g..g..g"
+
+ // Level 4
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "i..i..i..i..i"
+ /* 1 */ "............."
+ /* 2 */ "............."
+ /* 3 */ "............."
+ /* 4 */ "............."
+ /* 5 */ "............."
+ /* 6 */ "............."
+ /* 7 */ "............."
+ /* 8 */ "............."
+ /* 9 */ "............."
+ /* 10 */ "............."
+ /* 11 */ "i..i..i..i..i"
+
+ // Level 5
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "............."
+ /* 2 */ "............."
+ /* 3 */ "............."
+ /* 4 */ "............."
+ /* 5 */ "............."
+ /* 6 */ "............."
+ /* 7 */ "............."
+ /* 8 */ "............."
+ /* 9 */ "............."
+ /* 10 */ "............."
+ /* 11 */ "............."
+
+ // Level 6
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "............."
+ /* 2 */ "............."
+ /* 3 */ "............."
+ /* 4 */ "............."
+ /* 5 */ "............."
+ /* 6 */ "............."
+ /* 7 */ "............."
+ /* 8 */ "............."
+ /* 9 */ "............."
+ /* 10 */ "............."
+ /* 11 */ "............."
+
+ // Level 7
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "............."
+ /* 2 */ "............."
+ /* 3 */ "............."
+ /* 4 */ "............."
+ /* 5 */ "............."
+ /* 6 */ "............."
+ /* 7 */ "............."
+ /* 8 */ "............."
+ /* 9 */ "............."
+ /* 10 */ "............."
+ /* 11 */ ".............",
+
+ // Connectors:
+ "-1: 7, 1, 11: 3\n" /* Type -1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // BigPlantBed
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CobbleHouse10x5Library:
+ // The data has been exported from the gallery Plains, area index 23, ID 66, created by xoft
+ {
+ // Size:
+ 12, 7, 7, // SizeX = 12, SizeY = 7, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 12, 6, 7, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 0\n" /* stairs */
+ "c: 67: 2\n" /* stairs */
+ "d: 67: 1\n" /* stairs */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f: 53: 3\n" /* woodstairs */
+ "g: 53: 1\n" /* woodstairs */
+ "h: 85: 0\n" /* fence */
+ "i: 53: 0\n" /* woodstairs */
+ "j: 53: 2\n" /* woodstairs */
+ "k:102: 0\n" /* glasspane */
+ "l: 64:12\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */
+ "n: 50: 3\n" /* torch */
+ "o: 72: 0\n" /* woodplate */
+ "p: 50: 4\n" /* torch */
+ "q: 53: 7\n" /* woodstairs */
+ "r: 47: 0\n" /* bookshelf */
+ "s: 50: 1\n" /* torch */
+ "t: 50: 2\n" /* torch */
+ "u: 53: 6\n" /* woodstairs */
+ "v: 5: 0\n" /* wood */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "mmmmmmmaaamm"
+ /* 1 */ "maaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaam"
+ /* 6 */ "mmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ ".......bcd.."
+ /* 1 */ ".aaaaaaaaaa."
+ /* 2 */ ".aaaaaaaaaa."
+ /* 3 */ ".aaaaaaaaaa."
+ /* 4 */ ".aaaaaaaaaa."
+ /* 5 */ ".aaaaaaaaaa."
+ /* 6 */ "............"
+
+ // Level 2
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ ".aaaaaaaeaa."
+ /* 2 */ ".af.ghi...a."
+ /* 3 */ ".ah.......a."
+ /* 4 */ ".aj.ghighia."
+ /* 5 */ ".aaaaaaaaaa."
+ /* 6 */ "............"
+
+ // Level 3
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ ".akkakkalaa."
+ /* 2 */ ".k..no.n.nk."
+ /* 3 */ ".ko.......k."
+ /* 4 */ ".k..po.po.k."
+ /* 5 */ ".akkakkakka."
+ /* 6 */ "............"
+
+ // Level 4
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "jjjjjjjjjjjj"
+ /* 1 */ "qaaaaaaaaaaq"
+ /* 2 */ ".arrrrrrrra."
+ /* 3 */ ".as......ta."
+ /* 4 */ ".arrrrrrrra."
+ /* 5 */ "uaaaaaaaaaau"
+ /* 6 */ "ffffffffffff"
+
+ // Level 5
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "jjjjjjjjjjjj"
+ /* 2 */ "qvvvvvvvvvvq"
+ /* 3 */ ".vvvvvvvvvv."
+ /* 4 */ "uvvvvvvvvvvu"
+ /* 5 */ "ffffffffffff"
+ /* 6 */ "............"
+
+ // Level 6
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "............"
+ /* 2 */ "jjjjjjjjjjjj"
+ /* 3 */ "vvvvvvvvvvvv"
+ /* 4 */ "ffffffffffff"
+ /* 5 */ "............"
+ /* 6 */ "............",
+
+ // Connectors:
+ "-1: 8, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // CobbleHouse10x5Library
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // DoublePlantBed:
+ // The data has been exported from the gallery Plains, area index 5, ID 20, created by tonibm1999
+ {
+ // Size:
+ 15, 8, 9, // SizeX = 15, SizeY = 8, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 14, 7, 8, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 3: 0\n" /* dirt */
+ "b: 2: 0\n" /* grass */
+ "c: 17: 0\n" /* tree */
+ "d: 60: 7\n" /* tilleddirt */
+ "e: 8: 0\n" /* water */
+ "f: 50: 5\n" /* torch */
+ "g: 59: 7\n" /* crops */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "aaaaaaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaaaaaa"
+ /* 2 */ "aaaaaaaaaaaaaaa"
+ /* 3 */ "aaaaaaaaaaaaaaa"
+ /* 4 */ "aaaaaaaaaaaaaaa"
+ /* 5 */ "aaaaaaaaaaaaaaa"
+ /* 6 */ "aaaaaaaaaaaaaaa"
+ /* 7 */ "aaaaaaaaaaaaaaa"
+ /* 8 */ "aaaaaaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "aaaaaaabaaaaaaa"
+ /* 1 */ "aaaaaaabaaaaaaa"
+ /* 2 */ "aaaaaaabaaaaaaa"
+ /* 3 */ "aaaaaaabaaaaaaa"
+ /* 4 */ "aaaaaaabaaaaaaa"
+ /* 5 */ "aaaaaaabaaaaaaa"
+ /* 6 */ "aaaaaaabaaaaaaa"
+ /* 7 */ "aaaaaaabaaaaaaa"
+ /* 8 */ "aaaaaaabaaaaaaa"
+
+ // Level 2
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "ccccccc.ccccccc"
+ /* 1 */ "cddeddc.cddeddc"
+ /* 2 */ "cddeddc.cddeddc"
+ /* 3 */ "cddeddc.cddeddc"
+ /* 4 */ "cddeddc.cddeddc"
+ /* 5 */ "cddeddc.cddeddc"
+ /* 6 */ "cddeddc.cddeddc"
+ /* 7 */ "cddeddc.cddeddc"
+ /* 8 */ "ccccccc.ccccccc"
+
+ // Level 3
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "f.....f.f.....f"
+ /* 1 */ ".gg.gg...gg.gg."
+ /* 2 */ ".g...g...gg.gg."
+ /* 3 */ ".g.......gg.gg."
+ /* 4 */ ".gg..g...gg.gg."
+ /* 5 */ ".gg..g...gg.gg."
+ /* 6 */ "..g..g...gg.gg."
+ /* 7 */ "..g.g....gg.gg."
+ /* 8 */ "f.....f.f.....f"
+
+ // Level 4
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "..............."
+ /* 3 */ "..............."
+ /* 4 */ "..............."
+ /* 5 */ "..............."
+ /* 6 */ "..............."
+ /* 7 */ "..............."
+ /* 8 */ "..............."
+
+ // Level 5
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "..............."
+ /* 3 */ "..............."
+ /* 4 */ "..............."
+ /* 5 */ "..............."
+ /* 6 */ "..............."
+ /* 7 */ "..............."
+ /* 8 */ "..............."
+
+ // Level 6
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "..............."
+ /* 3 */ "..............."
+ /* 4 */ "..............."
+ /* 5 */ "..............."
+ /* 6 */ "..............."
+ /* 7 */ "..............."
+ /* 8 */ "..............."
+
+ // Level 7
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "..............."
+ /* 3 */ "..............."
+ /* 4 */ "..............."
+ /* 5 */ "..............."
+ /* 6 */ "..............."
+ /* 7 */ "..............."
+ /* 8 */ "...............",
+
+ // Connectors:
+ "-1: 7, 2, 8: 3\n" /* Type -1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // DoublePlantBed
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Forge:
+ // The data has been exported from the gallery Plains, area index 51, ID 102, created by Aloe_vera
+ {
+ // Size:
+ 12, 9, 11, // SizeX = 12, SizeY = 9, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 12, 8, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 0\n" /* stairs */
+ "c: 67: 2\n" /* stairs */
+ "d: 67: 1\n" /* stairs */
+ "e: 17: 0\n" /* tree */
+ "f: 5: 0\n" /* wood */
+ "g: 64: 6\n" /* wooddoorblock */
+ "h: 10: 0\n" /* lava */
+ "i: 54: 2\n" /* chest */
+ "j: 61: 2\n" /* furnace */
+ "k:102: 0\n" /* glasspane */
+ "l: 64:12\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */
+ "n:139: 0\n" /* cobblestonewall */
+ "o:101: 0\n" /* ironbars */
+ "p: 53: 2\n" /* woodstairs */
+ "q: 53: 7\n" /* woodstairs */
+ "r: 50: 2\n" /* torch */
+ "s: 50: 1\n" /* torch */
+ "t: 53: 6\n" /* woodstairs */
+ "u: 53: 3\n" /* woodstairs */
+ "v: 43: 0\n" /* doubleslab */
+ "w: 44: 0\n" /* step */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "mmmmmaaaaamm"
+ /* 1 */ "maaaaaaaaamm"
+ /* 2 */ "maaaaaaaaamm"
+ /* 3 */ "maaaaaaaaaaa"
+ /* 4 */ "maaaaaaaaaaa"
+ /* 5 */ "maaaaaaaaaaa"
+ /* 6 */ "maaaaaaaaaaa"
+ /* 7 */ "maaaaaaaaaaa"
+ /* 8 */ "maaaaammmmmm"
+ /* 9 */ "maaaaammmmmm"
+ /* 10 */ "mmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ ".....bcccd.."
+ /* 1 */ ".aaaaaaaad.."
+ /* 2 */ ".aaaaaaaad.."
+ /* 3 */ ".aaaaaaaaaaa"
+ /* 4 */ ".aaaaaaaaaaa"
+ /* 5 */ ".aaaaaaaaaaa"
+ /* 6 */ ".aaaaaaaaaaa"
+ /* 7 */ ".aaaaaaaaaaa"
+ /* 8 */ ".aaaaa......"
+ /* 9 */ ".aaaaa......"
+ /* 10 */ "............"
+
+ // Level 2
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ ".efffe......"
+ /* 2 */ ".f...g......"
+ /* 3 */ ".f...ea..aaa"
+ /* 4 */ ".f...f...aha"
+ /* 5 */ ".f...f...aha"
+ /* 6 */ ".f...fijjaha"
+ /* 7 */ ".f...eaaaaaa"
+ /* 8 */ ".f...f......"
+ /* 9 */ ".efffe......"
+ /* 10 */ "............"
+
+ // Level 3
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ ".ekkke......"
+ /* 2 */ ".k...l......"
+ /* 3 */ ".k...en..n.a"
+ /* 4 */ ".k...k.....o"
+ /* 5 */ ".f...k.....o"
+ /* 6 */ ".k...k.....o"
+ /* 7 */ ".k...eaooooa"
+ /* 8 */ ".k...f......"
+ /* 9 */ ".ekkke......"
+ /* 10 */ "............"
+
+ // Level 4
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "ppppppp....."
+ /* 1 */ "qfffffq....."
+ /* 2 */ ".f...f......"
+ /* 3 */ ".f..rfa..aoa"
+ /* 4 */ ".f...f...o.a"
+ /* 5 */ ".f...f...o.a"
+ /* 6 */ ".fs..f...o.a"
+ /* 7 */ ".f...faaaaaa"
+ /* 8 */ ".f...f......"
+ /* 9 */ "tffffft....."
+ /* 10 */ "uuuuuuu....."
+
+ // Level 5
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "ppppppp....."
+ /* 2 */ "qfffffq....."
+ /* 3 */ ".f...fvvvvvv"
+ /* 4 */ ".f...fvwwwwv"
+ /* 5 */ ".f...fvwwwwv"
+ /* 6 */ ".f...fvwwwwv"
+ /* 7 */ ".f...fvvvvvv"
+ /* 8 */ "tffffft....."
+ /* 9 */ "uuuuuuu....."
+ /* 10 */ "............"
+
+ // Level 6
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "............"
+ /* 2 */ "ppppppp....."
+ /* 3 */ "qfffffq....."
+ /* 4 */ ".f...f......"
+ /* 5 */ ".f...f......"
+ /* 6 */ ".f...f......"
+ /* 7 */ "tffffft....."
+ /* 8 */ "uuuuuuu....."
+ /* 9 */ "............"
+ /* 10 */ "............"
+
+ // Level 7
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "............"
+ /* 2 */ "............"
+ /* 3 */ "ppppppp....."
+ /* 4 */ "qfffffq....."
+ /* 5 */ ".f...f......"
+ /* 6 */ "tffffft....."
+ /* 7 */ "uuuuuuu....."
+ /* 8 */ "............"
+ /* 9 */ "............"
+ /* 10 */ "............"
+
+ // Level 8
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "............"
+ /* 2 */ "............"
+ /* 3 */ "............"
+ /* 4 */ "ppppppp....."
+ /* 5 */ "fffffff....."
+ /* 6 */ "uuuuuuu....."
+ /* 7 */ "............"
+ /* 8 */ "............"
+ /* 9 */ "............"
+ /* 10 */ "............",
+
+ // Connectors:
+ "-1: 7, 1, -1: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // Forge
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // LampPost:
+ // The data has been exported from the gallery Plains, area index 28, ID 73, created by STR_Warrior
+ {
+ // Size:
+ 3, 7, 3, // SizeX = 3, SizeY = 7, SizeZ = 3
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 2, 6, 2, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 3: 0\n" /* dirt */
+ "b: 43: 0\n" /* doubleslab */
+ "c:139: 0\n" /* cobblestonewall */
+ "d: 50: 4\n" /* torch */
+ "e: 50: 2\n" /* torch */
+ "f: 50: 1\n" /* torch */
+ "g: 50: 3\n" /* torch */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 012 */
+ /* 0 */ "mmm"
+ /* 1 */ "mam"
+ /* 2 */ "mmm"
+
+ // Level 1
+ /* z\x* 012 */
+ /* 0 */ "..."
+ /* 1 */ ".b."
+ /* 2 */ "..."
+
+ // Level 2
+ /* z\x* 012 */
+ /* 0 */ "..."
+ /* 1 */ ".c."
+ /* 2 */ "..."
+
+ // Level 3
+ /* z\x* 012 */
+ /* 0 */ "..."
+ /* 1 */ ".c."
+ /* 2 */ "..."
+
+ // Level 4
+ /* z\x* 012 */
+ /* 0 */ ".d."
+ /* 1 */ "ebf"
+ /* 2 */ ".g."
+
+ // Level 5
+ /* z\x* 012 */
+ /* 0 */ "..."
+ /* 1 */ "..."
+ /* 2 */ "..."
+
+ // Level 6
+ /* z\x* 012 */
+ /* 0 */ "..."
+ /* 1 */ "..."
+ /* 2 */ "...",
+
+ // Connectors:
+ "-1: 1, 1, 2: 3\n" /* Type -1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // LampPost
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MineshaftCorridor:
+ // The data has been exported from the gallery Plains, area index 139, ID 447, created by STR_Warrior
+ {
+ // Size:
+ 10, 4, 3, // SizeX = 10, SizeY = 4, SizeZ = 3
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 9, 3, 2, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 0\n" /* wood */
+ "b: 85: 0\n" /* fence */
+ "c: 66: 1\n" /* tracks */
+ "d: 50: 2\n" /* torch */
+ "e: 50: 1\n" /* torch */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "aaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaa"
+ /* 2 */ "aaaaaaaaaa"
+
+ // Level 1
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "..b....b.."
+ /* 1 */ "cccccccccc"
+ /* 2 */ "..b....b.."
+
+ // Level 2
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "..b....b.."
+ /* 1 */ ".........."
+ /* 2 */ "..b....b.."
+
+ // Level 3
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "..a....a.."
+ /* 1 */ ".dae..dae."
+ /* 2 */ "..a....a..",
+
+ // Connectors:
+ "-3: 0, 1, 1: 4\n" /* Type -3, direction X- */
+ "3: 9, 1, 1: 5\n" /* Type 3, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 200,
+
+ // MoveToGround:
+ false,
+ }, // MineshaftCorridor
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MineshaftCrossing:
+ // The data has been exported from the gallery Plains, area index 171, ID 578, created by Aloe_vera
+ {
+ // Size:
+ 5, 4, 5, // SizeX = 5, SizeY = 4, SizeZ = 5
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 4, 3, 4, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 0\n" /* wood */
+ "b: 66: 0\n" /* tracks */
+ "c: 66: 1\n" /* tracks */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aaaaa"
+ /* 3 */ "aaaaa"
+ /* 4 */ "aaaaa"
+
+ // Level 1
+ /* z\x* 01234 */
+ /* 0 */ "m.b.m"
+ /* 1 */ ".aba."
+ /* 2 */ "ccccc"
+ /* 3 */ ".aba."
+ /* 4 */ "m.b.m"
+
+ // Level 2
+ /* z\x* 01234 */
+ /* 0 */ "m...m"
+ /* 1 */ ".a.a."
+ /* 2 */ "....."
+ /* 3 */ ".a.a."
+ /* 4 */ "m...m"
+
+ // Level 3
+ /* z\x* 01234 */
+ /* 0 */ "m...m"
+ /* 1 */ ".a.a."
+ /* 2 */ "....."
+ /* 3 */ ".a.a."
+ /* 4 */ "m...m",
+
+ // Connectors:
+ "3: 4, 1, 2: 5\n" /* Type 3, direction X+ */
+ "-3: 4, 1, 2: 5\n" /* Type -3, direction X+ */
+ "-3: 2, 1, 4: 3\n" /* Type -3, direction Z+ */
+ "3: 2, 1, 4: 3\n" /* Type 3, direction Z+ */
+ "3: 0, 1, 2: 4\n" /* Type 3, direction X- */
+ "-3: 0, 1, 2: 4\n" /* Type -3, direction X- */
+ "3: 2, 1, 0: 2\n" /* Type 3, direction Z- */
+ "-3: 2, 1, 0: 2\n" /* Type -3, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 1,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // MineshaftCrossing
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MineshaftCrossing:
+ // The data has been exported from the gallery Plains, area index 193, ID 657, created by Aloe_vera
+ {
+ // Size:
+ 11, 4, 11, // SizeX = 11, SizeY = 4, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 10, 3, 10, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 0\n" /* wood */
+ "b: 66: 0\n" /* tracks */
+ "c: 85: 0\n" /* fence */
+ "d: 66: 1\n" /* tracks */
+ "e: 50: 4\n" /* torch */
+ "f: 50: 3\n" /* torch */
+ "g: 50: 2\n" /* torch */
+ "h: 50: 1\n" /* torch */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmaaammmm"
+ /* 1 */ "mmmmaaammmm"
+ /* 2 */ "mmmmaaammmm"
+ /* 3 */ "mmmmaaammmm"
+ /* 4 */ "aaaaaaaaaaa"
+ /* 5 */ "aaaaaaaaaaa"
+ /* 6 */ "aaaaaaaaaaa"
+ /* 7 */ "mmmmaaammmm"
+ /* 8 */ "mmmmaaammmm"
+ /* 9 */ "mmmmaaammmm"
+ /* 10 */ "mmmmaaammmm"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmm.b.mmmm"
+ /* 1 */ "mmmm.b.mmmm"
+ /* 2 */ "mmmmcbcmmmm"
+ /* 3 */ "mmmm.b.mmmm"
+ /* 4 */ "..c..b..c.."
+ /* 5 */ "ddddddddddd"
+ /* 6 */ "..c..b..c.."
+ /* 7 */ "mmmm.b.mmmm"
+ /* 8 */ "mmmmcbcmmmm"
+ /* 9 */ "mmmm.b.mmmm"
+ /* 10 */ "mmmm.b.mmmm"
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmm...mmmm"
+ /* 1 */ "mmmm...mmmm"
+ /* 2 */ "mmmmc.cmmmm"
+ /* 3 */ "mmmm...mmmm"
+ /* 4 */ "..c.....c.."
+ /* 5 */ "..........."
+ /* 6 */ "..c.....c.."
+ /* 7 */ "mmmm...mmmm"
+ /* 8 */ "mmmmc.cmmmm"
+ /* 9 */ "mmmm...mmmm"
+ /* 10 */ "mmmm...mmmm"
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmm...mmmm"
+ /* 1 */ "mmmm.e.mmmm"
+ /* 2 */ "mmmmaaammmm"
+ /* 3 */ "mmmm.f.mmmm"
+ /* 4 */ "..a.....a.."
+ /* 5 */ ".gah...gah."
+ /* 6 */ "..a.....a.."
+ /* 7 */ "mmmm.e.mmmm"
+ /* 8 */ "mmmmaaammmm"
+ /* 9 */ "mmmm.f.mmmm"
+ /* 10 */ "mmmm...mmmm",
+
+ // Connectors:
+ "3: 5, 1, 0: 2\n" /* Type 3, direction Z- */
+ "-3: 5, 1, 0: 2\n" /* Type -3, direction Z- */
+ "3: 0, 1, 5: 4\n" /* Type 3, direction X- */
+ "-3: 0, 1, 5: 4\n" /* Type -3, direction X- */
+ "3: 5, 1, 10: 3\n" /* Type 3, direction Z+ */
+ "-3: 5, 1, 10: 3\n" /* Type -3, direction Z+ */
+ "3: 10, 1, 5: 5\n" /* Type 3, direction X+ */
+ "-3: 10, 1, 5: 5\n" /* Type -3, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 10,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // MineshaftCrossing
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MineshaftDoubleCrossing:
+ // The data has been exported from the gallery Plains, area index 172, ID 579, created by Aloe_vera
+ {
+ // Size:
+ 5, 8, 5, // SizeX = 5, SizeY = 8, SizeZ = 5
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 4, 7, 4, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 0\n" /* wood */
+ "b: 66: 0\n" /* tracks */
+ "c: 66: 1\n" /* tracks */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aaaaa"
+ /* 3 */ "aaaaa"
+ /* 4 */ "aaaaa"
+
+ // Level 1
+ /* z\x* 01234 */
+ /* 0 */ "m.b.m"
+ /* 1 */ ".aba."
+ /* 2 */ "ccccc"
+ /* 3 */ ".aba."
+ /* 4 */ "m.b.m"
+
+ // Level 2
+ /* z\x* 01234 */
+ /* 0 */ "m...m"
+ /* 1 */ ".a.a."
+ /* 2 */ "....."
+ /* 3 */ ".a.a."
+ /* 4 */ "m...m"
+
+ // Level 3
+ /* z\x* 01234 */
+ /* 0 */ "m...m"
+ /* 1 */ ".a.a."
+ /* 2 */ "....."
+ /* 3 */ ".a.a."
+ /* 4 */ "m...m"
+
+ // Level 4
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "aa.aa"
+ /* 2 */ "a...a"
+ /* 3 */ "aa.aa"
+ /* 4 */ "aaaaa"
+
+ // Level 5
+ /* z\x* 01234 */
+ /* 0 */ "m...m"
+ /* 1 */ ".a.a."
+ /* 2 */ "....."
+ /* 3 */ ".a.a."
+ /* 4 */ "m...m"
+
+ // Level 6
+ /* z\x* 01234 */
+ /* 0 */ "m...m"
+ /* 1 */ ".a.a."
+ /* 2 */ "....."
+ /* 3 */ ".a.a."
+ /* 4 */ "m...m"
+
+ // Level 7
+ /* z\x* 01234 */
+ /* 0 */ "m...m"
+ /* 1 */ ".a.a."
+ /* 2 */ "....."
+ /* 3 */ ".a.a."
+ /* 4 */ "m...m",
+
+ // Connectors:
+ "-3: 4, 5, 2: 5\n" /* Type -3, direction X+ */
+ "3: 4, 5, 2: 5\n" /* Type 3, direction X+ */
+ "-3: 2, 1, 4: 3\n" /* Type -3, direction Z+ */
+ "3: 2, 1, 4: 3\n" /* Type 3, direction Z+ */
+ "-3: 0, 1, 2: 4\n" /* Type -3, direction X- */
+ "3: 0, 1, 2: 4\n" /* Type 3, direction X- */
+ "-3: 2, 1, 0: 2\n" /* Type -3, direction Z- */
+ "3: 2, 1, 0: 2\n" /* Type 3, direction Z- */
+ "-3: 4, 1, 2: 5\n" /* Type -3, direction X+ */
+ "3: 4, 1, 2: 5\n" /* Type 3, direction X+ */
+ "-3: 2, 5, 4: 3\n" /* Type -3, direction Z+ */
+ "3: 2, 5, 4: 3\n" /* Type 3, direction Z+ */
+ "-3: 0, 5, 2: 4\n" /* Type -3, direction X- */
+ "3: 0, 5, 2: 4\n" /* Type 3, direction X- */
+ "-3: 2, 5, 0: 2\n" /* Type -3, direction Z- */
+ "3: 2, 5, 0: 2\n" /* Type 3, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 1,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // MineshaftDoubleCrossing
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MineshaftSpiral:
+ // The data has been exported from the gallery Plains, area index 198, ID 662, created by Aloe_vera
+ {
+ // Size:
+ 7, 12, 7, // SizeX = 7, SizeY = 12, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 11, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 0\n" /* wood */
+ "b: 85: 0\n" /* fence */
+ "c: 66: 4\n" /* tracks */
+ "d: 66: 0\n" /* tracks */
+ "e: 66: 6\n" /* tracks */
+ "f: 66: 2\n" /* tracks */
+ "g: 50: 1\n" /* torch */
+ "h: 50: 3\n" /* torch */
+ "i: 66: 1\n" /* tracks */
+ "j: 66: 7\n" /* tracks */
+ "k: 66: 5\n" /* tracks */
+ "l: 50: 2\n" /* torch */
+ "m: 19: 0\n" /* sponge */
+ "n: 66: 3\n" /* tracks */
+ "o: 66: 8\n" /* tracks */
+ "p: 50: 4\n" /* torch */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmmmmm"
+ /* 2 */ "mmmmmmm"
+ /* 3 */ "aaabmmm"
+ /* 4 */ "aaammmm"
+ /* 5 */ "aaammmm"
+ /* 6 */ "aaammmm"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmmmmm"
+ /* 2 */ "aaammmm"
+ /* 3 */ "aaabmmm"
+ /* 4 */ ".c.mmmm"
+ /* 5 */ ".d.mmmm"
+ /* 6 */ ".d.mmmm"
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "aaaammm"
+ /* 1 */ "aaaammm"
+ /* 2 */ "aaaammm"
+ /* 3 */ ".c.bmmm"
+ /* 4 */ "...mmmm"
+ /* 5 */ "...mmmm"
+ /* 6 */ "...mmmm"
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "b..aamm"
+ /* 1 */ ".efaamm"
+ /* 2 */ ".d.aamm"
+ /* 3 */ "...bmmm"
+ /* 4 */ "...mmmm"
+ /* 5 */ "...mmmm"
+ /* 6 */ "...mmmm"
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "b...aaa"
+ /* 1 */ "...faaa"
+ /* 2 */ "....aaa"
+ /* 3 */ "...baaa"
+ /* 4 */ "...mmmm"
+ /* 5 */ "mmmmmmm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "ag....b"
+ /* 1 */ "h...ij."
+ /* 2 */ ".....k."
+ /* 3 */ "...baaa"
+ /* 4 */ "mmmmaaa"
+ /* 5 */ "mmmmmmm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 6
+ /* z\x* 0123456 */
+ /* 0 */ "mm....b"
+ /* 1 */ "mm....."
+ /* 2 */ "mm....."
+ /* 3 */ "mmmb.k."
+ /* 4 */ "mmmaaaa"
+ /* 5 */ "mmmaaaa"
+ /* 6 */ "mmmaaaa"
+
+ // Level 7
+ /* z\x* 0123456 */
+ /* 0 */ "mmm..la"
+ /* 1 */ "mmm...h"
+ /* 2 */ "mmm...."
+ /* 3 */ "mmmb..."
+ /* 4 */ "mmaa.d."
+ /* 5 */ "mmaano."
+ /* 6 */ "mmaa..b"
+
+ // Level 8
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmmmmm"
+ /* 2 */ "mmmm..."
+ /* 3 */ "mmmb..."
+ /* 4 */ "aaa...."
+ /* 5 */ "aaan..."
+ /* 6 */ "aaa...b"
+
+ // Level 9
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmmmmm"
+ /* 2 */ "mmmmmmm"
+ /* 3 */ "mmmb..."
+ /* 4 */ "......."
+ /* 5 */ "iii...p"
+ /* 6 */ ".....la"
+
+ // Level 10
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmmmmm"
+ /* 2 */ "mmmmmmm"
+ /* 3 */ "mmmbmmm"
+ /* 4 */ ".....mm"
+ /* 5 */ ".....mm"
+ /* 6 */ ".....mm"
+
+ // Level 11
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmmmmm"
+ /* 2 */ "mmmmmmm"
+ /* 3 */ "mmmbmmm"
+ /* 4 */ "....mmm"
+ /* 5 */ "....mmm"
+ /* 6 */ "....mmm",
+
+ // Connectors:
+ "3: 1, 1, 6: 3\n" /* Type 3, direction Z+ */
+ "-3: 1, 1, 6: 3\n" /* Type -3, direction Z+ */
+ "3: 0, 9, 5: 4\n" /* Type 3, direction X- */
+ "-3: 0, 9, 5: 4\n" /* Type -3, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // MineshaftSpiral
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MineshaftStairs:
+ // The data has been exported from the gallery Plains, area index 195, ID 659, created by Aloe_vera
+ {
+ // Size:
+ 7, 8, 3, // SizeX = 7, SizeY = 8, SizeZ = 3
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 7, 2, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 0\n" /* wood */
+ "b: 66: 1\n" /* tracks */
+ "c: 66: 2\n" /* tracks */
+ "d: 85: 0\n" /* fence */
+ "e: 50: 1\n" /* torch */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "aaammmm"
+ /* 1 */ "aaammmm"
+ /* 2 */ "aaammmm"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "..aammm"
+ /* 1 */ "bcaammm"
+ /* 2 */ "..aammm"
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "...aamm"
+ /* 1 */ "..caamm"
+ /* 2 */ "...aamm"
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "...daam"
+ /* 1 */ "...caam"
+ /* 2 */ "...daam"
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "m..d.aa"
+ /* 1 */ "m...caa"
+ /* 2 */ "m..d.aa"
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "mm.d..."
+ /* 1 */ "mm...bb"
+ /* 2 */ "mm.d..."
+
+ // Level 6
+ /* z\x* 0123456 */
+ /* 0 */ "mmmd..."
+ /* 1 */ "mmm...."
+ /* 2 */ "mmmd..."
+
+ // Level 7
+ /* z\x* 0123456 */
+ /* 0 */ "mmma..."
+ /* 1 */ "mmmae.."
+ /* 2 */ "mmma...",
+
+ // Connectors:
+ "3: 0, 1, 1: 4\n" /* Type 3, direction X- */
+ "-3: 0, 1, 1: 4\n" /* Type -3, direction X- */
+ "3: 6, 5, 1: 5\n" /* Type 3, direction X+ */
+ "-3: 6, 5, 1: 5\n" /* Type -3, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // MineshaftStairs
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MineshaftStairsCrossing:
+ // The data has been exported from the gallery Plains, area index 199, ID 663, created by Aloe_vera
+ {
+ // Size:
+ 11, 12, 12, // SizeX = 11, SizeY = 12, SizeZ = 12
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 10, 11, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 0\n" /* wood */
+ "b: 66: 0\n" /* tracks */
+ "c: 66: 5\n" /* tracks */
+ "d: 85: 0\n" /* fence */
+ "e: 66: 1\n" /* tracks */
+ "f: 50: 3\n" /* torch */
+ "g: 50: 2\n" /* torch */
+ "h: 50: 1\n" /* torch */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmaaammmm"
+ /* 1 */ "mmmmaaammmm"
+ /* 2 */ "mmmmaaammmm"
+ /* 3 */ "mmmmmmmmmmm"
+ /* 4 */ "mmmmmmmmmmm"
+ /* 5 */ "mmmmmmmmmmm"
+ /* 6 */ "mmmmmmmmmmm"
+ /* 7 */ "mmmmmmmmmmm"
+ /* 8 */ "mmmmmmmmmmm"
+ /* 9 */ "mmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmm.b.mmmm"
+ /* 1 */ "mmmm.c.mmmm"
+ /* 2 */ "mmmmaaammmm"
+ /* 3 */ "mmmmaaammmm"
+ /* 4 */ "mmmmmmmmmmm"
+ /* 5 */ "mmmmmmmmmmm"
+ /* 6 */ "mmmmmmmmmmm"
+ /* 7 */ "mmmmmmmmmmm"
+ /* 8 */ "mmmmmmmmmmm"
+ /* 9 */ "mmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmm"
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmm...mmmm"
+ /* 1 */ "mmmm...mmmm"
+ /* 2 */ "mmmm.c.mmmm"
+ /* 3 */ "mmmmaaammmm"
+ /* 4 */ "mmmmaaammmm"
+ /* 5 */ "mmmmmmmmmmm"
+ /* 6 */ "mmmmmmmmmmm"
+ /* 7 */ "mmmmmmmmmmm"
+ /* 8 */ "mmmmmmmmmmm"
+ /* 9 */ "mmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmm"
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmm...mmmm"
+ /* 1 */ "mmmm...mmmm"
+ /* 2 */ "mmmm...mmmm"
+ /* 3 */ "mmmmdcdmmmm"
+ /* 4 */ "mmmmaaammmm"
+ /* 5 */ "mmmmaaammmm"
+ /* 6 */ "mmmmmmmmmmm"
+ /* 7 */ "mmmmmmmmmmm"
+ /* 8 */ "mmmmmmmmmmm"
+ /* 9 */ "mmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmm"
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmmmmmmmm"
+ /* 1 */ "mmmm...mmmm"
+ /* 2 */ "mmmm...mmmm"
+ /* 3 */ "mmmmd.dmmmm"
+ /* 4 */ "mmmm.c.mmmm"
+ /* 5 */ "aaaaaaaaaaa"
+ /* 6 */ "aaaaaaaaaaa"
+ /* 7 */ "aaaaaaaaaaa"
+ /* 8 */ "mmmmaaammmm"
+ /* 9 */ "mmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmm"
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmm"
+ /* 2 */ "mmmm...mmmm"
+ /* 3 */ "mmmmd.dmmmm"
+ /* 4 */ "mmmm...mmmm"
+ /* 5 */ "..d..b..d.."
+ /* 6 */ "eeeeeeeeeee"
+ /* 7 */ "..d..c..d.."
+ /* 8 */ "mmmmaaammmm"
+ /* 9 */ "mmmmaaammmm"
+ /* 10 */ "mmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmm"
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmm"
+ /* 3 */ "mmmmd.dmmmm"
+ /* 4 */ "mmmm...mmmm"
+ /* 5 */ "..d.....d.."
+ /* 6 */ "..........."
+ /* 7 */ "..d.....d.."
+ /* 8 */ "mmmm.c.mmmm"
+ /* 9 */ "mmmmaaammmm"
+ /* 10 */ "mmmmaaammmm"
+ /* 11 */ "mmmmmmmmmmm"
+
+ // Level 7
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmm"
+ /* 3 */ "mmmmaaammmm"
+ /* 4 */ "mmmm.f.mmmm"
+ /* 5 */ "..a.....a.."
+ /* 6 */ ".gah...gah."
+ /* 7 */ "..a.....a.."
+ /* 8 */ "mmmm...mmmm"
+ /* 9 */ "mmmmdcdmmmm"
+ /* 10 */ "mmmmaaammmm"
+ /* 11 */ "mmmmaaammmm"
+
+ // Level 8
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmm"
+ /* 4 */ "mmmmmmmmmmm"
+ /* 5 */ "mmmmmmmmmmm"
+ /* 6 */ "mmmmmmmmmmm"
+ /* 7 */ "mmmm...mmmm"
+ /* 8 */ "mmmm...mmmm"
+ /* 9 */ "mmmmd.dmmmm"
+ /* 10 */ "mmmm.c.mmmm"
+ /* 11 */ "mmmmaaammmm"
+
+ // Level 9
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmm"
+ /* 4 */ "mmmmmmmmmmm"
+ /* 5 */ "mmmmmmmmmmm"
+ /* 6 */ "mmmmmmmmmmm"
+ /* 7 */ "mmmmmmmmmmm"
+ /* 8 */ "mmmm...mmmm"
+ /* 9 */ "mmmmd.dmmmm"
+ /* 10 */ "mmmm...mmmm"
+ /* 11 */ "mmmm.b.mmmm"
+
+ // Level 10
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmm"
+ /* 4 */ "mmmmmmmmmmm"
+ /* 5 */ "mmmmmmmmmmm"
+ /* 6 */ "mmmmmmmmmmm"
+ /* 7 */ "mmmmmmmmmmm"
+ /* 8 */ "mmmmmmmmmmm"
+ /* 9 */ "mmmmd.dmmmm"
+ /* 10 */ "mmmm...mmmm"
+ /* 11 */ "mmmm...mmmm"
+
+ // Level 11
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmm"
+ /* 4 */ "mmmmmmmmmmm"
+ /* 5 */ "mmmmmmmmmmm"
+ /* 6 */ "mmmmmmmmmmm"
+ /* 7 */ "mmmmmmmmmmm"
+ /* 8 */ "mmmmmmmmmmm"
+ /* 9 */ "mmmmaaammmm"
+ /* 10 */ "mmmm.f.mmmm"
+ /* 11 */ "mmmm...mmmm",
+
+ // Connectors:
+ "3: 0, 5, 6: 4\n" /* Type 3, direction X- */
+ "-3: 0, 5, 6: 4\n" /* Type -3, direction X- */
+ "3: 10, 5, 6: 5\n" /* Type 3, direction X+ */
+ "-3: 10, 5, 6: 5\n" /* Type -3, direction X+ */
+ "3: 5, 9, 11: 3\n" /* Type 3, direction Z+ */
+ "-3: 5, 9, 11: 3\n" /* Type -3, direction Z+ */
+ "3: 5, 1, 1: 2\n" /* Type 3, direction Z- */
+ "-3: 5, 1, 1: 2\n" /* Type -3, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 30,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // MineshaftStairsCrossing
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MineshaftTee:
+ // The data has been exported from the gallery Plains, area index 194, ID 658, created by Aloe_vera
+ {
+ // Size:
+ 11, 4, 7, // SizeX = 11, SizeY = 4, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 10, 3, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 0\n" /* wood */
+ "b: 66: 0\n" /* tracks */
+ "c: 85: 0\n" /* fence */
+ "d: 66: 1\n" /* tracks */
+ "e: 50: 4\n" /* torch */
+ "f: 50: 3\n" /* torch */
+ "g: 50: 2\n" /* torch */
+ "h: 50: 1\n" /* torch */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmaaammmm"
+ /* 1 */ "mmmmaaammmm"
+ /* 2 */ "mmmmaaammmm"
+ /* 3 */ "mmmmaaammmm"
+ /* 4 */ "aaaaaaaaaaa"
+ /* 5 */ "aaaaaaaaaaa"
+ /* 6 */ "aaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmm.b.mmmm"
+ /* 1 */ "mmmm.b.mmmm"
+ /* 2 */ "mmmmcbcmmmm"
+ /* 3 */ "mmmm.b.mmmm"
+ /* 4 */ "..c..b..c.."
+ /* 5 */ "ddddddddddd"
+ /* 6 */ "..c.....c.."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmm...mmmm"
+ /* 1 */ "mmmm...mmmm"
+ /* 2 */ "mmmmc.cmmmm"
+ /* 3 */ "mmmm...mmmm"
+ /* 4 */ "..c.....c.."
+ /* 5 */ "..........."
+ /* 6 */ "..c.....c.."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmm...mmmm"
+ /* 1 */ "mmmm.e.mmmm"
+ /* 2 */ "mmmmaaammmm"
+ /* 3 */ "mmmm.f.mmmm"
+ /* 4 */ "..a.....a.."
+ /* 5 */ ".gah...gah."
+ /* 6 */ "..a.....a..",
+
+ // Connectors:
+ "3: 0, 1, 5: 4\n" /* Type 3, direction X- */
+ "-3: 0, 1, 5: 4\n" /* Type -3, direction X- */
+ "3: 5, 1, 0: 2\n" /* Type 3, direction Z- */
+ "-3: 5, 1, 0: 2\n" /* Type -3, direction Z- */
+ "3: 10, 1, 5: 5\n" /* Type 3, direction X+ */
+ "-3: 10, 1, 5: 5\n" /* Type -3, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 20,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // MineshaftTee
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MineshaftsCorridor5:
+ // The data has been exported from the gallery Plains, area index 200, ID 664, created by Aloe_vera
+ {
+ // Size:
+ 11, 4, 3, // SizeX = 11, SizeY = 4, SizeZ = 3
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 10, 3, 2, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 0\n" /* wood */
+ "b: 85: 0\n" /* fence */
+ "c: 66: 1\n" /* tracks */
+ "d: 50: 2\n" /* torch */
+ "e: 50: 1\n" /* torch */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "aaaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaaa"
+ /* 2 */ "aaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..b.....b.."
+ /* 1 */ "ccccccccccc"
+ /* 2 */ "..b.....b.."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..b.....b.."
+ /* 1 */ "..........."
+ /* 2 */ "..b.....b.."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..a.....a.."
+ /* 1 */ ".dae...dae."
+ /* 2 */ "..a.....a..",
+
+ // Connectors:
+ "3: 10, 1, 1: 5\n" /* Type 3, direction X+ */
+ "-3: 10, 1, 1: 5\n" /* Type -3, direction X+ */
+ "-3: 0, 1, 1: 4\n" /* Type -3, direction X- */
+ "3: 0, 1, 1: 4\n" /* Type 3, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // MineshaftsCorridor5
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Scarecrow:
+ // The data has been exported from the gallery Plains, area index 150, ID 494, created by STR_Warrior
+ {
+ // Size:
+ 1, 6, 3, // SizeX = 1, SizeY = 6, SizeZ = 3
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 0, 5, 2, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:139: 0\n" /* cobblestonewall */
+ "b: 85: 0\n" /* fence */
+ "c:126: 4\n" /* woodenslab */
+ "d: 86: 1\n" /* pumpkin */
+ "e:139: 1\n" /* cobblestonewall */
+ "f:163: 4\n" /* acaciawoodenstairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0 */
+ /* 0 */ "."
+ /* 1 */ "a"
+ /* 2 */ "."
+
+ // Level 1
+ /* z\x* 0 */
+ /* 0 */ "."
+ /* 1 */ "b"
+ /* 2 */ "."
+
+ // Level 2
+ /* z\x* 0 */
+ /* 0 */ "c"
+ /* 1 */ "d"
+ /* 2 */ "c"
+
+ // Level 3
+ /* z\x* 0 */
+ /* 0 */ "."
+ /* 1 */ "e"
+ /* 2 */ "."
+
+ // Level 4
+ /* z\x* 0 */
+ /* 0 */ "f"
+ /* 1 */ "d"
+ /* 2 */ "f"
+
+ // Level 5
+ /* z\x* 0 */
+ /* 0 */ "."
+ /* 1 */ "f"
+ /* 2 */ ".",
+
+ // Connectors:
+ "-1: -1, 0, 1: 4\n" /* Type -1, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 10,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // Scarecrow
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SinglePlantBed:
+ // The data has been exported from the gallery Plains, area index 17, ID 60, created by Aloe_vera
+ {
+ // Size:
+ 10, 7, 7, // SizeX = 10, SizeY = 7, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 9, 6, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 3: 0\n" /* dirt */
+ "b: 17: 0\n" /* tree */
+ "c: 60: 7\n" /* tilleddirt */
+ "d: 8: 0\n" /* water */
+ "e: 59: 7\n" /* crops */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "aaaaaaaaaa"
+ /* 1 */ "aaaaaaaaaa"
+ /* 2 */ "aaaaaaaaaa"
+ /* 3 */ "aaaaaaaaaa"
+ /* 4 */ "aaaaaaaaaa"
+ /* 5 */ "aaaaaaaaaa"
+ /* 6 */ "aaaaaaaaaa"
+
+ // Level 1
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "bbbbbbbbbb"
+ /* 1 */ "bccccccccb"
+ /* 2 */ "bccccccccb"
+ /* 3 */ "bddddddddb"
+ /* 4 */ "bccccccccb"
+ /* 5 */ "bccccccccb"
+ /* 6 */ "bbbbbbbbbb"
+
+ // Level 2
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".........."
+ /* 1 */ ".eeeeeeee."
+ /* 2 */ ".eeeeeeee."
+ /* 3 */ ".........."
+ /* 4 */ ".eeeeeeee."
+ /* 5 */ ".eeeeeeee."
+ /* 6 */ ".........."
+
+ // Level 3
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".........."
+ /* 1 */ ".........."
+ /* 2 */ ".........."
+ /* 3 */ ".........."
+ /* 4 */ ".........."
+ /* 5 */ ".........."
+ /* 6 */ ".........."
+
+ // Level 4
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".........."
+ /* 1 */ ".........."
+ /* 2 */ ".........."
+ /* 3 */ ".........."
+ /* 4 */ ".........."
+ /* 5 */ ".........."
+ /* 6 */ ".........."
+
+ // Level 5
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".........."
+ /* 1 */ ".........."
+ /* 2 */ ".........."
+ /* 3 */ ".........."
+ /* 4 */ ".........."
+ /* 5 */ ".........."
+ /* 6 */ ".........."
+
+ // Level 6
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".........."
+ /* 1 */ ".........."
+ /* 2 */ ".........."
+ /* 3 */ ".........."
+ /* 4 */ ".........."
+ /* 5 */ ".........."
+ /* 6 */ "..........",
+
+ // Connectors:
+ "-1: 9, 1, 3: 5\n" /* Type -1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // SinglePlantBed
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenChurchMid:
+ // The data has been exported from the gallery Plains, area index 58, ID 109, created by Aloe_vera
+ {
+ // Size:
+ 7, 15, 13, // SizeX = 7, SizeY = 15, SizeZ = 13
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 7, 14, 13, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "A: 85: 0\n" /* fence */
+ "B:126: 8\n" /* woodenslab */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 0\n" /* stairs */
+ "c: 67: 2\n" /* stairs */
+ "d: 67: 1\n" /* stairs */
+ "e: 17: 0\n" /* tree */
+ "f: 5: 0\n" /* wood */
+ "g: 64: 7\n" /* wooddoorblock */
+ "h: 65: 3\n" /* ladder */
+ "i: 53: 3\n" /* woodstairs */
+ "j: 53: 7\n" /* woodstairs */
+ "k: 64:12\n" /* wooddoorblock */
+ "l:102: 0\n" /* glasspane */
+ "m: 19: 0\n" /* sponge */
+ "n: 50: 1\n" /* torch */
+ "o: 50: 2\n" /* torch */
+ "p:171:14\n" /* carpet */
+ "q: 50: 3\n" /* torch */
+ "r: 53: 2\n" /* woodstairs */
+ "s: 53: 0\n" /* woodstairs */
+ "t: 53: 1\n" /* woodstairs */
+ "u: 53: 5\n" /* woodstairs */
+ "v: 53: 4\n" /* woodstairs */
+ "w: 17: 4\n" /* tree */
+ "x: 17: 8\n" /* tree */
+ "y: 54: 2\n" /* chest */
+ "z: 50: 4\n" /* torch */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "mmaaamm"
+ /* 1 */ "maaaaam"
+ /* 2 */ "maaaaam"
+ /* 3 */ "maaaaam"
+ /* 4 */ "maaaaam"
+ /* 5 */ "maaaaam"
+ /* 6 */ "maaaaam"
+ /* 7 */ "maaaaam"
+ /* 8 */ "maaaaam"
+ /* 9 */ "maaaaam"
+ /* 10 */ "maaaaam"
+ /* 11 */ "maaaaam"
+ /* 12 */ "mmmmmmm"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "..bcd.."
+ /* 1 */ ".aaaaa."
+ /* 2 */ ".aaaaa."
+ /* 3 */ ".aaaaa."
+ /* 4 */ ".aaaaa."
+ /* 5 */ ".aaaaa."
+ /* 6 */ ".aaaaa."
+ /* 7 */ ".aaaaa."
+ /* 8 */ ".aaaaa."
+ /* 9 */ ".aaaaa."
+ /* 10 */ ".aaaaa."
+ /* 11 */ ".aaaaa."
+ /* 12 */ "......."
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".efgfe."
+ /* 2 */ ".f..hf."
+ /* 3 */ ".f...f."
+ /* 4 */ ".f...f."
+ /* 5 */ ".ei.ie."
+ /* 6 */ ".f...f."
+ /* 7 */ ".fi.if."
+ /* 8 */ ".f...f."
+ /* 9 */ ".f.j.f."
+ /* 10 */ ".f...f."
+ /* 11 */ ".efffe."
+ /* 12 */ "......."
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".efkfe."
+ /* 2 */ ".l..hl."
+ /* 3 */ ".l...l."
+ /* 4 */ ".l...l."
+ /* 5 */ ".e...e."
+ /* 6 */ ".l...l."
+ /* 7 */ ".l...l."
+ /* 8 */ ".fn.of."
+ /* 9 */ ".l.p.l."
+ /* 10 */ ".l...l."
+ /* 11 */ ".ellle."
+ /* 12 */ "......."
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".efffe."
+ /* 2 */ ".f.qhf."
+ /* 3 */ ".f...f."
+ /* 4 */ ".f...f."
+ /* 5 */ "re...er"
+ /* 6 */ "sf...ft"
+ /* 7 */ "sf...ft"
+ /* 8 */ "sf...ft"
+ /* 9 */ "sf...ft"
+ /* 10 */ "sf...ft"
+ /* 11 */ "sefffet"
+ /* 12 */ "su...vt"
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".ewwwe."
+ /* 2 */ ".xffhx."
+ /* 3 */ ".xfffx."
+ /* 4 */ ".xfffx."
+ /* 5 */ ".ewwwe."
+ /* 6 */ ".sf.ft."
+ /* 7 */ ".sf.ft."
+ /* 8 */ ".sf.ft."
+ /* 9 */ ".sf.ft."
+ /* 10 */ ".sf.ft."
+ /* 11 */ ".sffft."
+ /* 12 */ ".su.vt."
+
+ // Level 6
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".eflfe."
+ /* 2 */ ".f..hf."
+ /* 3 */ ".f...f."
+ /* 4 */ ".f.y.f."
+ /* 5 */ ".efffe."
+ /* 6 */ "..sft.."
+ /* 7 */ "..sft.."
+ /* 8 */ "..sft.."
+ /* 9 */ "..sft.."
+ /* 10 */ "..sft.."
+ /* 11 */ "..sft.."
+ /* 12 */ "..sft.."
+
+ // Level 7
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".eflfe."
+ /* 2 */ ".f..hf."
+ /* 3 */ ".l...l."
+ /* 4 */ ".f...f."
+ /* 5 */ ".efffe."
+ /* 6 */ "......."
+ /* 7 */ "......."
+ /* 8 */ "......."
+ /* 9 */ "......."
+ /* 10 */ "......."
+ /* 11 */ "......."
+ /* 12 */ "......."
+
+ // Level 8
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".eflfe."
+ /* 2 */ ".f..hf."
+ /* 3 */ ".f...f."
+ /* 4 */ ".f.z.f."
+ /* 5 */ ".efffe."
+ /* 6 */ "......."
+ /* 7 */ "......."
+ /* 8 */ "......."
+ /* 9 */ "......."
+ /* 10 */ "......."
+ /* 11 */ "......."
+ /* 12 */ "......."
+
+ // Level 9
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".ewwwe."
+ /* 2 */ ".xffhx."
+ /* 3 */ ".xfffx."
+ /* 4 */ ".xfffx."
+ /* 5 */ ".ewwwe."
+ /* 6 */ "......."
+ /* 7 */ "......."
+ /* 8 */ "......."
+ /* 9 */ "......."
+ /* 10 */ "......."
+ /* 11 */ "......."
+ /* 12 */ "......."
+
+ // Level 10
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".eAAAe."
+ /* 2 */ ".A...A."
+ /* 3 */ ".A...A."
+ /* 4 */ ".A...A."
+ /* 5 */ ".eAAAe."
+ /* 6 */ "......."
+ /* 7 */ "......."
+ /* 8 */ "......."
+ /* 9 */ "......."
+ /* 10 */ "......."
+ /* 11 */ "......."
+ /* 12 */ "......."
+
+ // Level 11
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".e...e."
+ /* 2 */ "......."
+ /* 3 */ "......."
+ /* 4 */ "......."
+ /* 5 */ ".e...e."
+ /* 6 */ "......."
+ /* 7 */ "......."
+ /* 8 */ "......."
+ /* 9 */ "......."
+ /* 10 */ "......."
+ /* 11 */ "......."
+ /* 12 */ "......."
+
+ // Level 12
+ /* z\x* 0123456 */
+ /* 0 */ "su...vt"
+ /* 1 */ "sefffet"
+ /* 2 */ "sfBBBft"
+ /* 3 */ "sfBBBft"
+ /* 4 */ "sfBBBft"
+ /* 5 */ "sefffet"
+ /* 6 */ "su...vt"
+ /* 7 */ "......."
+ /* 8 */ "......."
+ /* 9 */ "......."
+ /* 10 */ "......."
+ /* 11 */ "......."
+ /* 12 */ "......."
+
+ // Level 13
+ /* z\x* 0123456 */
+ /* 0 */ ".su.vt."
+ /* 1 */ ".sffft."
+ /* 2 */ ".sffft."
+ /* 3 */ ".sffft."
+ /* 4 */ ".sffft."
+ /* 5 */ ".sffft."
+ /* 6 */ ".su.vt."
+ /* 7 */ "......."
+ /* 8 */ "......."
+ /* 9 */ "......."
+ /* 10 */ "......."
+ /* 11 */ "......."
+ /* 12 */ "......."
+
+ // Level 14
+ /* z\x* 0123456 */
+ /* 0 */ "..sft.."
+ /* 1 */ "..sft.."
+ /* 2 */ "..sft.."
+ /* 3 */ "..sft.."
+ /* 4 */ "..sft.."
+ /* 5 */ "..sft.."
+ /* 6 */ "..sft.."
+ /* 7 */ "......."
+ /* 8 */ "......."
+ /* 9 */ "......."
+ /* 10 */ "......."
+ /* 11 */ "......."
+ /* 12 */ ".......",
+
+ // Connectors:
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 20,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenChurchMid
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenGranary:
+ // The data has been exported from the gallery Plains, area index 54, ID 105, created by Aloe_vera
+ {
+ // Size:
+ 7, 7, 9, // SizeX = 7, SizeY = 7, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 7, 6, 9, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b:170: 0\n" /* haybale */
+ "c: 67: 0\n" /* stairs */
+ "d: 67: 2\n" /* stairs */
+ "e: 67: 1\n" /* stairs */
+ "f: 17: 0\n" /* tree */
+ "g: 5: 0\n" /* wood */
+ "h:170: 4\n" /* haybale */
+ "i:170: 8\n" /* haybale */
+ "j: 54: 2\n" /* chest */
+ "k: 50: 4\n" /* torch */
+ "l: 53: 0\n" /* woodstairs */
+ "m: 19: 0\n" /* sponge */
+ "n: 53: 5\n" /* woodstairs */
+ "o: 53: 4\n" /* woodstairs */
+ "p: 53: 1\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "maaaaam"
+ /* 1 */ "maaaaam"
+ /* 2 */ "maaaaam"
+ /* 3 */ "maaaaam"
+ /* 4 */ "maaaaam"
+ /* 5 */ "maaaaam"
+ /* 6 */ "maaaaam"
+ /* 7 */ "maaaaam"
+ /* 8 */ "mmmmmmm"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "bcddde."
+ /* 1 */ ".aaaaa."
+ /* 2 */ ".aaaaa."
+ /* 3 */ ".aaaaa."
+ /* 4 */ ".aaaaa."
+ /* 5 */ ".aaaaa."
+ /* 6 */ ".aaaaa."
+ /* 7 */ ".aaaaa."
+ /* 8 */ "......."
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".f..bf."
+ /* 2 */ ".g...g."
+ /* 3 */ ".gb.hg."
+ /* 4 */ ".fihif."
+ /* 5 */ ".gbbbg."
+ /* 6 */ ".gijbg."
+ /* 7 */ ".fgfgf."
+ /* 8 */ "......."
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ ".k...k."
+ /* 1 */ ".f...f."
+ /* 2 */ ".g...g."
+ /* 3 */ ".g...g."
+ /* 4 */ ".fh..f."
+ /* 5 */ ".ghibg."
+ /* 6 */ ".ghiig."
+ /* 7 */ ".fgfgf."
+ /* 8 */ "......."
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "ln...op"
+ /* 1 */ "lgggggp"
+ /* 2 */ "lg...gp"
+ /* 3 */ "lg...gp"
+ /* 4 */ "lg...gp"
+ /* 5 */ "lgbb.gp"
+ /* 6 */ "lgibigp"
+ /* 7 */ "lgggggp"
+ /* 8 */ "ln...op"
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ ".ln.op."
+ /* 1 */ ".lgggp."
+ /* 2 */ ".lg.gp."
+ /* 3 */ ".lg.gp."
+ /* 4 */ ".lg.gp."
+ /* 5 */ ".lg.gp."
+ /* 6 */ ".lg.gp."
+ /* 7 */ ".lgggp."
+ /* 8 */ ".ln.op."
+
+ // Level 6
+ /* z\x* 0123456 */
+ /* 0 */ "..lgp.."
+ /* 1 */ "..lgp.."
+ /* 2 */ "..lgp.."
+ /* 3 */ "..lgp.."
+ /* 4 */ "..lgp.."
+ /* 5 */ "..lgp.."
+ /* 6 */ "..lgp.."
+ /* 7 */ "..lgp.."
+ /* 8 */ "..lgp..",
+
+ // Connectors:
+ "-1: 3, 1, -1: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenGranary
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenHouse10x7Library:
+ // The data has been exported from the gallery Plains, area index 47, ID 98, created by Aloe_vera
+ {
+ // Size:
+ 12, 8, 9, // SizeX = 12, SizeY = 8, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 12, 7, 9, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 0\n" /* stairs */
+ "c: 67: 2\n" /* stairs */
+ "d: 67: 1\n" /* stairs */
+ "e: 17: 0\n" /* tree */
+ "f: 5: 0\n" /* wood */
+ "g: 64: 7\n" /* wooddoorblock */
+ "h: 64: 5\n" /* wooddoorblock */
+ "i: 53: 3\n" /* woodstairs */
+ "j: 85: 0\n" /* fence */
+ "k: 53: 2\n" /* woodstairs */
+ "l: 53: 1\n" /* woodstairs */
+ "m: 19: 0\n" /* sponge */
+ "n: 53: 0\n" /* woodstairs */
+ "o:102: 0\n" /* glasspane */
+ "p: 64:12\n" /* wooddoorblock */
+ "q: 50: 3\n" /* torch */
+ "r: 72: 0\n" /* woodplate */
+ "s: 53: 7\n" /* woodstairs */
+ "t: 47: 0\n" /* bookshelf */
+ "u: 50: 1\n" /* torch */
+ "v: 50: 2\n" /* torch */
+ "w: 53: 6\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "mmmmaaaammmm"
+ /* 1 */ "maaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaam"
+ /* 6 */ "maaaaaaaaaam"
+ /* 7 */ "maaaaaaaaaam"
+ /* 8 */ "mmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "....bccd...."
+ /* 1 */ ".aaaaaaaaaa."
+ /* 2 */ ".aaaaaaaaaa."
+ /* 3 */ ".aaaaaaaaaa."
+ /* 4 */ ".aaaaaaaaaa."
+ /* 5 */ ".aaaaaaaaaa."
+ /* 6 */ ".aaaaaaaaaa."
+ /* 7 */ ".aaaaaaaaaa."
+ /* 8 */ "............"
+
+ // Level 2
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ ".efffghfffe."
+ /* 2 */ ".f........f."
+ /* 3 */ ".fi......if."
+ /* 4 */ ".fj......jf."
+ /* 5 */ ".fk......kf."
+ /* 6 */ ".f.ljnljn.f."
+ /* 7 */ ".effffffffe."
+ /* 8 */ "............"
+
+ // Level 3
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ ".eoofppfooe."
+ /* 2 */ ".o..q..q..o."
+ /* 3 */ ".o........o."
+ /* 4 */ ".fr......rf."
+ /* 5 */ ".o........o."
+ /* 6 */ ".o..r..r..o."
+ /* 7 */ ".eoofoofooe."
+ /* 8 */ "............"
+
+ // Level 4
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "kkkkkkkkkkkk"
+ /* 1 */ "sffffffffffs"
+ /* 2 */ ".fttttttttf."
+ /* 3 */ ".f........f."
+ /* 4 */ ".fu......vf."
+ /* 5 */ ".f........f."
+ /* 6 */ ".fttttttttf."
+ /* 7 */ "wffffffffffw"
+ /* 8 */ "iiiiiiiiiiii"
+
+ // Level 5
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "kkkkkkkkkkkk"
+ /* 2 */ "sffffffffffs"
+ /* 3 */ ".fttttttttf."
+ /* 4 */ ".f........f."
+ /* 5 */ ".fttttttttf."
+ /* 6 */ "wffffffffffw"
+ /* 7 */ "iiiiiiiiiiii"
+ /* 8 */ "............"
+
+ // Level 6
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "............"
+ /* 2 */ "kkkkkkkkkkkk"
+ /* 3 */ "sffffffffffs"
+ /* 4 */ ".f........f."
+ /* 5 */ "wffffffffffw"
+ /* 6 */ "iiiiiiiiiiii"
+ /* 7 */ "............"
+ /* 8 */ "............"
+
+ // Level 7
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ "............"
+ /* 2 */ "............"
+ /* 3 */ "kkkkkkkkkkkk"
+ /* 4 */ "ffffffffffff"
+ /* 5 */ "iiiiiiiiiiii"
+ /* 6 */ "............"
+ /* 7 */ "............"
+ /* 8 */ "............",
+
+ // Connectors:
+ "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenHouse10x7Library
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenHouse5x5:
+ // The data has been exported from the gallery Plains, area index 49, ID 100, created by Aloe_vera
+ {
+ // Size:
+ 7, 7, 7, // SizeX = 7, SizeY = 7, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 7, 6, 7, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 0\n" /* stairs */
+ "c: 67: 2\n" /* stairs */
+ "d: 67: 1\n" /* stairs */
+ "e: 17: 0\n" /* tree */
+ "f: 5: 0\n" /* wood */
+ "g: 64: 7\n" /* wooddoorblock */
+ "h: 64:12\n" /* wooddoorblock */
+ "i:102: 0\n" /* glasspane */
+ "j: 53: 2\n" /* woodstairs */
+ "k: 53: 7\n" /* woodstairs */
+ "l: 50: 3\n" /* torch */
+ "m: 19: 0\n" /* sponge */
+ "n: 53: 6\n" /* woodstairs */
+ "o: 53: 3\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "mmaaamm"
+ /* 1 */ "maaaaam"
+ /* 2 */ "maaaaam"
+ /* 3 */ "maaaaam"
+ /* 4 */ "maaaaam"
+ /* 5 */ "maaaaam"
+ /* 6 */ "mmmmmmm"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "..bcd.."
+ /* 1 */ ".aaaaa."
+ /* 2 */ ".aaaaa."
+ /* 3 */ ".aaaaa."
+ /* 4 */ ".aaaaa."
+ /* 5 */ ".aaaaa."
+ /* 6 */ "......."
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".efgfe."
+ /* 2 */ ".f...f."
+ /* 3 */ ".f...f."
+ /* 4 */ ".f...f."
+ /* 5 */ ".efffe."
+ /* 6 */ "......."
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".efhfe."
+ /* 2 */ ".i...i."
+ /* 3 */ ".i...i."
+ /* 4 */ ".i...i."
+ /* 5 */ ".eiiie."
+ /* 6 */ "......."
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "jjjjjjj"
+ /* 1 */ "kfffffk"
+ /* 2 */ ".fl.lf."
+ /* 3 */ ".f...f."
+ /* 4 */ ".f...f."
+ /* 5 */ "nfffffn"
+ /* 6 */ "ooooooo"
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "jjjjjjj"
+ /* 2 */ "kfffffk"
+ /* 3 */ ".f...f."
+ /* 4 */ "nfffffn"
+ /* 5 */ "ooooooo"
+ /* 6 */ "......."
+
+ // Level 6
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "......."
+ /* 2 */ "jjjjjjj"
+ /* 3 */ "fffffff"
+ /* 4 */ "ooooooo"
+ /* 5 */ "......."
+ /* 6 */ ".......",
+
+ // Connectors:
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenHouse5x5
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenHouse7x5:
+ // The data has been exported from the gallery Plains, area index 40, ID 91, created by xoft
+ {
+ // Size:
+ 9, 7, 7, // SizeX = 9, SizeY = 7, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 9, 6, 7, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 0\n" /* stairs */
+ "c: 67: 2\n" /* stairs */
+ "d: 67: 1\n" /* stairs */
+ "e: 17: 0\n" /* tree */
+ "f: 5: 0\n" /* wood */
+ "g: 64: 7\n" /* wooddoorblock */
+ "h:102: 0\n" /* glasspane */
+ "i: 64:12\n" /* wooddoorblock */
+ "j: 53: 2\n" /* woodstairs */
+ "k: 53: 7\n" /* woodstairs */
+ "l: 50: 3\n" /* torch */
+ "m: 19: 0\n" /* sponge */
+ "n: 53: 6\n" /* woodstairs */
+ "o: 53: 3\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 012345678 */
+ /* 0 */ "mmmaaammm"
+ /* 1 */ "maaaaaaam"
+ /* 2 */ "maaaaaaam"
+ /* 3 */ "maaaaaaam"
+ /* 4 */ "maaaaaaam"
+ /* 5 */ "maaaaaaam"
+ /* 6 */ "mmmmmmmmm"
+
+ // Level 1
+ /* z\x* 012345678 */
+ /* 0 */ "...bcd..."
+ /* 1 */ ".aaaaaaa."
+ /* 2 */ ".aaaaaaa."
+ /* 3 */ ".aaaaaaa."
+ /* 4 */ ".aaaaaaa."
+ /* 5 */ ".aaaaaaa."
+ /* 6 */ "........."
+
+ // Level 2
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ ".effgffe."
+ /* 2 */ ".f.....f."
+ /* 3 */ ".f.....f."
+ /* 4 */ ".f.....f."
+ /* 5 */ ".efffffe."
+ /* 6 */ "........."
+
+ // Level 3
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ ".ehfifhe."
+ /* 2 */ ".h.....h."
+ /* 3 */ ".h.....h."
+ /* 4 */ ".h.....h."
+ /* 5 */ ".ehhfhhe."
+ /* 6 */ "........."
+
+ // Level 4
+ /* z\x* 012345678 */
+ /* 0 */ "jjjjjjjjj"
+ /* 1 */ "kefffffek"
+ /* 2 */ ".f.l.l.f."
+ /* 3 */ ".f.....f."
+ /* 4 */ ".f.....f."
+ /* 5 */ "nefffffen"
+ /* 6 */ "ooooooooo"
+
+ // Level 5
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "jjjjjjjjj"
+ /* 2 */ "kfffffffk"
+ /* 3 */ ".f.....f."
+ /* 4 */ "nfffffffn"
+ /* 5 */ "ooooooooo"
+ /* 6 */ "........."
+
+ // Level 6
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "jjjjjjjjj"
+ /* 3 */ "fffffffff"
+ /* 4 */ "ooooooooo"
+ /* 5 */ "........."
+ /* 6 */ ".........",
+
+ // Connectors:
+ "-1: 4, 1, -1: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenHouse7x5
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenHouse9x5:
+ // The data has been exported from the gallery Plains, area index 41, ID 92, created by xoft
+ {
+ // Size:
+ 11, 7, 7, // SizeX = 11, SizeY = 7, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 11, 6, 7, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 0\n" /* stairs */
+ "c: 67: 2\n" /* stairs */
+ "d: 67: 1\n" /* stairs */
+ "e: 17: 0\n" /* tree */
+ "f: 5: 0\n" /* wood */
+ "g: 64: 7\n" /* wooddoorblock */
+ "h:102: 0\n" /* glasspane */
+ "i: 64:12\n" /* wooddoorblock */
+ "j: 53: 2\n" /* woodstairs */
+ "k: 53: 7\n" /* woodstairs */
+ "l: 50: 3\n" /* torch */
+ "m: 19: 0\n" /* sponge */
+ "n: 53: 6\n" /* woodstairs */
+ "o: 53: 3\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmaaammmm"
+ /* 1 */ "maaaaaaaaam"
+ /* 2 */ "maaaaaaaaam"
+ /* 3 */ "maaaaaaaaam"
+ /* 4 */ "maaaaaaaaam"
+ /* 5 */ "maaaaaaaaam"
+ /* 6 */ "mmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "....bcd...."
+ /* 1 */ ".aaaaaaaaa."
+ /* 2 */ ".aaaaaaaaa."
+ /* 3 */ ".aaaaaaaaa."
+ /* 4 */ ".aaaaaaaaa."
+ /* 5 */ ".aaaaaaaaa."
+ /* 6 */ "..........."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".efffgfffe."
+ /* 2 */ ".f.......f."
+ /* 3 */ ".f.......f."
+ /* 4 */ ".f.......f."
+ /* 5 */ ".efffffffe."
+ /* 6 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".ehhfifhhe."
+ /* 2 */ ".h.......h."
+ /* 3 */ ".h.......h."
+ /* 4 */ ".h.......h."
+ /* 5 */ ".ehhhfhhhe."
+ /* 6 */ "..........."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "jjjjjjjjjjj"
+ /* 1 */ "kfffffffffk"
+ /* 2 */ ".f..l.l.ff."
+ /* 3 */ ".f......ff."
+ /* 4 */ ".f......ff."
+ /* 5 */ "nfffffffffn"
+ /* 6 */ "ooooooooooo"
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "jjjjjjjjjjj"
+ /* 2 */ "kfffffffffk"
+ /* 3 */ ".fffffffff."
+ /* 4 */ "nfffffffffn"
+ /* 5 */ "ooooooooooo"
+ /* 6 */ "..........."
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "jjjjjjjjjjj"
+ /* 3 */ "fffffffffff"
+ /* 4 */ "ooooooooooo"
+ /* 5 */ "..........."
+ /* 6 */ "...........",
+
+ // Connectors:
+ "-1: 5, 1, -1: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenHouse9x5
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenHouse9x5Fence:
+ // The data has been exported from the gallery Plains, area index 9, ID 26, created by Aloe_vera
+ {
+ // Size:
+ 10, 7, 11, // SizeX = 10, SizeY = 7, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ 0, -1, -1, // MinX, MinY, MinZ
+ 10, 6, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 3: 0\n" /* dirt */
+ "c: 5: 0\n" /* wood */
+ "d: 2: 0\n" /* grass */
+ "e: 67: 2\n" /* stairs */
+ "f: 43: 0\n" /* doubleslab */
+ "g: 67: 0\n" /* stairs */
+ "h: 67: 3\n" /* stairs */
+ "i: 17: 0\n" /* tree */
+ "j: 53: 1\n" /* woodstairs */
+ "k: 85: 0\n" /* fence */
+ "l: 53: 0\n" /* woodstairs */
+ "m: 19: 0\n" /* sponge */
+ "n: 64: 6\n" /* wooddoorblock */
+ "o: 64: 4\n" /* wooddoorblock */
+ "p:102: 0\n" /* glasspane */
+ "q: 72: 0\n" /* woodplate */
+ "r: 64:12\n" /* wooddoorblock */
+ "s: 53: 5\n" /* woodstairs */
+ "t: 53: 4\n" /* woodstairs */
+ "u: 50: 1\n" /* torch */
+ "v: 50: 2\n" /* torch */,
+
+ // Block data:
+ // Level 0
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".........."
+ /* 1 */ ".aaaaa...."
+ /* 2 */ ".aaaaa...."
+ /* 3 */ ".aaaaabbbb"
+ /* 4 */ "aaaaaabbbb"
+ /* 5 */ "aaaaaabbbb"
+ /* 6 */ "aaaaaabbbb"
+ /* 7 */ ".aaaaabbbb"
+ /* 8 */ ".aaaaabbbb"
+ /* 9 */ ".aaaaa...."
+ /* 10 */ ".........."
+
+ // Level 1
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "......mmmm"
+ /* 1 */ ".aaaaammmm"
+ /* 2 */ ".acccammmm"
+ /* 3 */ ".acccadddd"
+ /* 4 */ "eafffadddd"
+ /* 5 */ "gaffffdddd"
+ /* 6 */ "hafffadddd"
+ /* 7 */ ".afffadddd"
+ /* 8 */ ".afffadddd"
+ /* 9 */ ".aaaaammmm"
+ /* 10 */ "......mmmm"
+
+ // Level 2
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "......mmmm"
+ /* 1 */ ".icccimmmm"
+ /* 2 */ ".cjklcmmmm"
+ /* 3 */ ".c...ckkkk"
+ /* 4 */ ".c...c...k"
+ /* 5 */ ".n...o...k"
+ /* 6 */ ".c...c...k"
+ /* 7 */ ".cff.c...k"
+ /* 8 */ ".c...ckkkk"
+ /* 9 */ ".icccimmmm"
+ /* 10 */ "......mmmm"
+
+ // Level 3
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "......mmmm"
+ /* 1 */ ".ipppimmmm"
+ /* 2 */ ".p.q.pmmmm"
+ /* 3 */ ".p...p...."
+ /* 4 */ ".c...c...."
+ /* 5 */ ".r...r...."
+ /* 6 */ ".c...c...."
+ /* 7 */ ".p...p...."
+ /* 8 */ ".p...p...."
+ /* 9 */ ".ipppimmmm"
+ /* 10 */ "......mmmm"
+
+ // Level 4
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "ls...tjmmm"
+ /* 1 */ "licccijmmm"
+ /* 2 */ "lc...cjmmm"
+ /* 3 */ "lc...cj..."
+ /* 4 */ "lcu.vcj..."
+ /* 5 */ "lc...cj..."
+ /* 6 */ "lcu.vcj..."
+ /* 7 */ "lc...cj..."
+ /* 8 */ "lc...cj..."
+ /* 9 */ "licccijmmm"
+ /* 10 */ "ls...tjmmm"
+
+ // Level 5
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "mls.tjmmmm"
+ /* 1 */ "mlcccjmmmm"
+ /* 2 */ "mlc.cjmmmm"
+ /* 3 */ "mlc.cjm..."
+ /* 4 */ "mlc.cjm..."
+ /* 5 */ "mlc.cjm..."
+ /* 6 */ "mlc.cjm..."
+ /* 7 */ "mlc.cjm..."
+ /* 8 */ "mlc.cjm..."
+ /* 9 */ "mlcccjmmmm"
+ /* 10 */ "mls.tjmmmm"
+
+ // Level 6
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "mmlcjmmmmm"
+ /* 1 */ "mmlcjmmmmm"
+ /* 2 */ "mmlcjmmmmm"
+ /* 3 */ "mmlcjmm..."
+ /* 4 */ "mmlcjmm..."
+ /* 5 */ "mmlcjmm..."
+ /* 6 */ "mmlcjmm..."
+ /* 7 */ "mmlcjmm..."
+ /* 8 */ "mmlcjmm..."
+ /* 9 */ "mmlcjmmmmm"
+ /* 10 */ "mmlcjmmmmm",
+
+ // Connectors:
+ "-1: 0, 1, 5: 4\n" /* Type -1, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenHouse9x5Fence
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenHouse9x5Library:
+ // The data has been exported from the gallery Plains, area index 46, ID 97, created by Aloe_vera
+ {
+ // Size:
+ 11, 7, 7, // SizeX = 11, SizeY = 7, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 11, 6, 7, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 0\n" /* stairs */
+ "c: 67: 2\n" /* stairs */
+ "d: 67: 1\n" /* stairs */
+ "e: 17: 0\n" /* tree */
+ "f: 5: 0\n" /* wood */
+ "g: 64: 7\n" /* wooddoorblock */
+ "h: 53: 3\n" /* woodstairs */
+ "i: 85: 0\n" /* fence */
+ "j: 53: 2\n" /* woodstairs */
+ "k: 53: 1\n" /* woodstairs */
+ "l: 53: 0\n" /* woodstairs */
+ "m: 19: 0\n" /* sponge */
+ "n:102: 0\n" /* glasspane */
+ "o: 64:12\n" /* wooddoorblock */
+ "p: 50: 3\n" /* torch */
+ "q: 72: 0\n" /* woodplate */
+ "r: 53: 7\n" /* woodstairs */
+ "s: 47: 0\n" /* bookshelf */
+ "t: 50: 1\n" /* torch */
+ "u: 50: 2\n" /* torch */
+ "v: 53: 6\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmaaammmm"
+ /* 1 */ "maaaaaaaaam"
+ /* 2 */ "maaaaaaaaam"
+ /* 3 */ "maaaaaaaaam"
+ /* 4 */ "maaaaaaaaam"
+ /* 5 */ "maaaaaaaaam"
+ /* 6 */ "mmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "....bcd...."
+ /* 1 */ ".aaaaaaaaa."
+ /* 2 */ ".aaaaaaaaa."
+ /* 3 */ ".aaaaaaaaa."
+ /* 4 */ ".aaaaaaaaa."
+ /* 5 */ ".aaaaaaaaa."
+ /* 6 */ "..........."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".efffgfffe."
+ /* 2 */ ".fh.....hf."
+ /* 3 */ ".fi.....if."
+ /* 4 */ ".fj.kil.jf."
+ /* 5 */ ".efffffffe."
+ /* 6 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".ennfofnne."
+ /* 2 */ ".n..p.p..n."
+ /* 3 */ ".nq.....qn."
+ /* 4 */ ".n...q...n."
+ /* 5 */ ".ennnfnnne."
+ /* 6 */ "..........."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "jjjjjjjjjjj"
+ /* 1 */ "rfffffffffr"
+ /* 2 */ ".fsssssssf."
+ /* 3 */ ".ft.....uf."
+ /* 4 */ ".fsssssssf."
+ /* 5 */ "vfffffffffv"
+ /* 6 */ "hhhhhhhhhhh"
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "jjjjjjjjjjj"
+ /* 2 */ "rfffffffffr"
+ /* 3 */ ".f.......f."
+ /* 4 */ "vfffffffffv"
+ /* 5 */ "hhhhhhhhhhh"
+ /* 6 */ "..........."
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "jjjjjjjjjjj"
+ /* 3 */ "fffffffffff"
+ /* 4 */ "hhhhhhhhhhh"
+ /* 5 */ "..........."
+ /* 6 */ "...........",
+
+ // Connectors:
+ "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenHouse9x5Library
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenHouse9x7:
+ // The data has been exported from the gallery Plains, area index 52, ID 103, created by Aloe_vera
+ {
+ // Size:
+ 11, 8, 9, // SizeX = 11, SizeY = 8, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 11, 7, 9, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 0\n" /* stairs */
+ "c: 67: 2\n" /* stairs */
+ "d: 67: 1\n" /* stairs */
+ "e: 17: 0\n" /* tree */
+ "f: 5: 0\n" /* wood */
+ "g: 64: 7\n" /* wooddoorblock */
+ "h:102: 0\n" /* glasspane */
+ "i: 64:12\n" /* wooddoorblock */
+ "j: 53: 2\n" /* woodstairs */
+ "k: 53: 7\n" /* woodstairs */
+ "l: 50: 3\n" /* torch */
+ "m: 19: 0\n" /* sponge */
+ "n: 50: 4\n" /* torch */
+ "o: 53: 6\n" /* woodstairs */
+ "p: 53: 3\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmaaammmm"
+ /* 1 */ "maaaaaaaaam"
+ /* 2 */ "maaaaaaaaam"
+ /* 3 */ "maaaaaaaaam"
+ /* 4 */ "maaaaaaaaam"
+ /* 5 */ "maaaaaaaaam"
+ /* 6 */ "maaaaaaaaam"
+ /* 7 */ "maaaaaaaaam"
+ /* 8 */ "mmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "....bcd...."
+ /* 1 */ ".aaaaaaaaa."
+ /* 2 */ ".aaaaaaaaa."
+ /* 3 */ ".aaaaaaaaa."
+ /* 4 */ ".aaaaaaaaa."
+ /* 5 */ ".aaaaaaaaa."
+ /* 6 */ ".aaaaaaaaa."
+ /* 7 */ ".aaaaaaaaa."
+ /* 8 */ "..........."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".efffgfffe."
+ /* 2 */ ".f.......f."
+ /* 3 */ ".f.......f."
+ /* 4 */ ".f.......f."
+ /* 5 */ ".f.......f."
+ /* 6 */ ".f.......f."
+ /* 7 */ ".efffffffe."
+ /* 8 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".ehhfifhhe."
+ /* 2 */ ".h.......h."
+ /* 3 */ ".h.......h."
+ /* 4 */ ".f.......f."
+ /* 5 */ ".h.......h."
+ /* 6 */ ".h.......h."
+ /* 7 */ ".ehhhfhhhe."
+ /* 8 */ "..........."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "jjjjjjjjjjj"
+ /* 1 */ "kfffffffffk"
+ /* 2 */ ".f..l.l..f."
+ /* 3 */ ".f.......f."
+ /* 4 */ ".f.......f."
+ /* 5 */ ".f.......f."
+ /* 6 */ ".f...n...f."
+ /* 7 */ "offfffffffo"
+ /* 8 */ "ppppppppppp"
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "jjjjjjjjjjj"
+ /* 2 */ "kfffffffffk"
+ /* 3 */ ".f.......f."
+ /* 4 */ ".f.......f."
+ /* 5 */ ".f.......f."
+ /* 6 */ "offfffffffo"
+ /* 7 */ "ppppppppppp"
+ /* 8 */ "..........."
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "jjjjjjjjjjj"
+ /* 3 */ "kfffffffffk"
+ /* 4 */ ".f.......f."
+ /* 5 */ "offfffffffo"
+ /* 6 */ "ppppppppppp"
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+
+ // Level 7
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "jjjjjjjjjjj"
+ /* 4 */ "fffffffffff"
+ /* 5 */ "ppppppppppp"
+ /* 6 */ "..........."
+ /* 7 */ "..........."
+ /* 8 */ "...........",
+
+ // Connectors:
+ "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenHouse9x7
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenHouse9x7Butcher:
+ // The data has been exported from the gallery Plains, area index 48, ID 99, created by Aloe_vera
+ {
+ // Size:
+ 11, 9, 13, // SizeX = 11, SizeY = 9, SizeZ = 13
+
+ // Hitbox (relative to bounding box):
+ -1, 0, 0, // MinX, MinY, MinZ
+ 11, 8, 13, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 2: 0\n" /* grass */
+ "b: 3: 0\n" /* dirt */
+ "c: 4: 0\n" /* cobblestone */
+ "d: 67: 0\n" /* stairs */
+ "e: 67: 2\n" /* stairs */
+ "f: 67: 1\n" /* stairs */
+ "g: 43: 0\n" /* doubleslab */
+ "h: 17: 0\n" /* tree */
+ "i: 5: 0\n" /* wood */
+ "j: 64: 7\n" /* wooddoorblock */
+ "k: 53: 3\n" /* woodstairs */
+ "l: 85: 0\n" /* fence */
+ "m: 19: 0\n" /* sponge */
+ "n: 53: 2\n" /* woodstairs */
+ "o:102: 0\n" /* glasspane */
+ "p: 64:12\n" /* wooddoorblock */
+ "q: 72: 0\n" /* woodplate */
+ "r: 53: 7\n" /* woodstairs */
+ "s: 50: 1\n" /* torch */
+ "t: 50: 2\n" /* torch */
+ "u: 53: 6\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "aaabbbbaaaa"
+ /* 1 */ "abbbbbbbbba"
+ /* 2 */ "abbbbbbbbba"
+ /* 3 */ "abbbbbbbbba"
+ /* 4 */ "abbbbbbbbba"
+ /* 5 */ "abbbbbbbbba"
+ /* 6 */ "abbbbbbbbba"
+ /* 7 */ "abbbbbbbbba"
+ /* 8 */ "aabbbbbbbaa"
+ /* 9 */ "aabbbbbbbaa"
+ /* 10 */ "aabbbbbbbaa"
+ /* 11 */ "aabbbbbbbaa"
+ /* 12 */ "aabbbbbbbaa"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmcccmmmm"
+ /* 1 */ "mcccccccccm"
+ /* 2 */ "mcccccccccm"
+ /* 3 */ "mcccccccccm"
+ /* 4 */ "mcccccccccm"
+ /* 5 */ "mcccccccccm"
+ /* 6 */ "mcccccccccm"
+ /* 7 */ "mcccccccccm"
+ /* 8 */ "mmbbbbbbbmm"
+ /* 9 */ "mmbbbbbbbmm"
+ /* 10 */ "mmbbbbbbbmm"
+ /* 11 */ "mmbbbbbbbmm"
+ /* 12 */ "mmbbbbbbbmm"
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "....def...."
+ /* 1 */ ".ccccccccc."
+ /* 2 */ ".cggggcccc."
+ /* 3 */ ".cggggcccc."
+ /* 4 */ ".cggggcccc."
+ /* 5 */ ".cggggcccc."
+ /* 6 */ ".cggggcccc."
+ /* 7 */ ".ccccccccc."
+ /* 8 */ "..aaaaaaa.."
+ /* 9 */ "..aaaaaaa.."
+ /* 10 */ "..aaaaaaa.."
+ /* 11 */ "..aaaaaaa.."
+ /* 12 */ "..aaaaaaa.."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".hiiijiiih."
+ /* 2 */ ".i.g....ki."
+ /* 3 */ ".i.g....li."
+ /* 4 */ ".i.g....ni."
+ /* 5 */ ".i.......i."
+ /* 6 */ ".i.......i."
+ /* 7 */ ".hiiijiiih."
+ /* 8 */ "..l.....l.."
+ /* 9 */ "..l.....l.."
+ /* 10 */ "..l.....l.."
+ /* 11 */ "..l.....l.."
+ /* 12 */ "..lllllll.."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".hooipiooh."
+ /* 2 */ ".o.......o."
+ /* 3 */ ".o......qo."
+ /* 4 */ ".i.......i."
+ /* 5 */ ".o.......o."
+ /* 6 */ ".o.......o."
+ /* 7 */ ".hooipiooh."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+ /* 11 */ "..........."
+ /* 12 */ "..........."
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "nnnnnnnnnnn"
+ /* 1 */ "riiiiiiiiir"
+ /* 2 */ ".i.......i."
+ /* 3 */ ".i.......i."
+ /* 4 */ ".is.....ti."
+ /* 5 */ ".i.......i."
+ /* 6 */ ".i.......i."
+ /* 7 */ "uiiiiiiiiiu"
+ /* 8 */ "kkkkkkkkkkk"
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+ /* 11 */ "..........."
+ /* 12 */ "..........."
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "nnnnnnnnnnn"
+ /* 2 */ "riiiiiiiiir"
+ /* 3 */ ".i.......i."
+ /* 4 */ ".i.......i."
+ /* 5 */ ".i.......i."
+ /* 6 */ "uiiiiiiiiiu"
+ /* 7 */ "kkkkkkkkkkk"
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+ /* 11 */ "..........."
+ /* 12 */ "..........."
+
+ // Level 7
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "nnnnnnnnnnn"
+ /* 3 */ "riiiiiiiiir"
+ /* 4 */ ".i.......i."
+ /* 5 */ "uiiiiiiiiiu"
+ /* 6 */ "kkkkkkkkkkk"
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+ /* 11 */ "..........."
+ /* 12 */ "..........."
+
+ // Level 8
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "nnnnnnnnnnn"
+ /* 4 */ "iiiiiiiiiii"
+ /* 5 */ "kkkkkkkkkkk"
+ /* 6 */ "..........."
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+ /* 11 */ "..........."
+ /* 12 */ "...........",
+
+ // Connectors:
+ "-1: 5, 2, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenHouse9x7Butcher
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenHouse9x7DoubleDoor:
+ // The data has been exported from the gallery Plains, area index 38, ID 87, created by Aloe_vera
+ {
+ // Size:
+ 11, 8, 9, // SizeX = 11, SizeY = 8, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 11, 7, 9, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 0\n" /* stairs */
+ "c: 67: 2\n" /* stairs */
+ "d: 67: 1\n" /* stairs */
+ "e: 67: 3\n" /* stairs */
+ "f: 17: 0\n" /* tree */
+ "g: 5: 0\n" /* wood */
+ "h: 64: 7\n" /* wooddoorblock */
+ "i:102: 0\n" /* glasspane */
+ "j: 64:12\n" /* wooddoorblock */
+ "k: 53: 2\n" /* woodstairs */
+ "l: 53: 7\n" /* woodstairs */
+ "m: 19: 0\n" /* sponge */
+ "n: 17: 4\n" /* tree */
+ "o: 17: 8\n" /* tree */
+ "p: 50: 3\n" /* torch */
+ "q: 50: 4\n" /* torch */
+ "r: 53: 6\n" /* woodstairs */
+ "s: 53: 3\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmaaammmm"
+ /* 1 */ "maaaaaaaaam"
+ /* 2 */ "maaaaaaaaam"
+ /* 3 */ "maaaaaaaaam"
+ /* 4 */ "maaaaaaaaam"
+ /* 5 */ "maaaaaaaaam"
+ /* 6 */ "maaaaaaaaam"
+ /* 7 */ "maaaaaaaaam"
+ /* 8 */ "mmmmaaammmm"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "....bcd...."
+ /* 1 */ ".aaaaaaaaa."
+ /* 2 */ ".aaaaaaaaa."
+ /* 3 */ ".aaaaaaaaa."
+ /* 4 */ ".aaaaaaaaa."
+ /* 5 */ ".aaaaaaaaa."
+ /* 6 */ ".aaaaaaaaa."
+ /* 7 */ ".aaaaaaaaa."
+ /* 8 */ "....bed...."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".fggfhfggf."
+ /* 2 */ ".g.......g."
+ /* 3 */ ".g.......g."
+ /* 4 */ ".f.......f."
+ /* 5 */ ".g.......g."
+ /* 6 */ ".g.......g."
+ /* 7 */ ".fggfhfggf."
+ /* 8 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".fiifjfiif."
+ /* 2 */ ".i.......i."
+ /* 3 */ ".i.......i."
+ /* 4 */ ".f.......f."
+ /* 5 */ ".i.......i."
+ /* 6 */ ".i.......i."
+ /* 7 */ ".fiifjfiif."
+ /* 8 */ "..........."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "kkkkkkkkkkk"
+ /* 1 */ "lfnnnnnnnfl"
+ /* 2 */ ".o..p.p..o."
+ /* 3 */ ".o.......o."
+ /* 4 */ ".o.......o."
+ /* 5 */ ".o.......o."
+ /* 6 */ ".o..q.q..o."
+ /* 7 */ "rfnnnnnnnfr"
+ /* 8 */ "sssssssssss"
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "kkkkkkkkkkk"
+ /* 2 */ "lgggggggggl"
+ /* 3 */ ".g.......g."
+ /* 4 */ ".g.......g."
+ /* 5 */ ".g.......g."
+ /* 6 */ "rgggggggggr"
+ /* 7 */ "sssssssssss"
+ /* 8 */ "..........."
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "kkkkkkkkkkk"
+ /* 3 */ "lgggggggggl"
+ /* 4 */ ".g.......g."
+ /* 5 */ "rgggggggggr"
+ /* 6 */ "sssssssssss"
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+
+ // Level 7
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "kkkkkkkkkkk"
+ /* 4 */ "ggggggggggg"
+ /* 5 */ "sssssssssss"
+ /* 6 */ "..........."
+ /* 7 */ "..........."
+ /* 8 */ "...........",
+
+ // Connectors:
+ "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenHouse9x7DoubleDoor
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenHouseL13x14:
+ // The data has been exported from the gallery Plains, area index 39, ID 90, created by STR_Warrior
+ {
+ // Size:
+ 15, 9, 16, // SizeX = 15, SizeY = 9, SizeZ = 16
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 15, 8, 16, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "A: 53: 7\n" /* woodstairs */
+ "B: 53: 4\n" /* woodstairs */
+ "C: 53: 5\n" /* woodstairs */
+ "D: 53: 6\n" /* woodstairs */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 0\n" /* stairs */
+ "c: 67: 2\n" /* stairs */
+ "d: 67: 1\n" /* stairs */
+ "e: 43: 0\n" /* doubleslab */
+ "f: 17: 0\n" /* tree */
+ "g: 5: 0\n" /* wood */
+ "h: 64: 7\n" /* wooddoorblock */
+ "i: 96: 8\n" /* trapdoor */
+ "j: 61: 2\n" /* furnace */
+ "k: 53: 3\n" /* woodstairs */
+ "l: 85: 0\n" /* fence */
+ "m: 19: 0\n" /* sponge */
+ "n: 53: 2\n" /* woodstairs */
+ "o: 53: 1\n" /* woodstairs */
+ "p: 53: 0\n" /* woodstairs */
+ "q: 47: 0\n" /* bookshelf */
+ "r:102: 0\n" /* glasspane */
+ "s: 64:12\n" /* wooddoorblock */
+ "t: 72: 0\n" /* woodplate */
+ "u: 17: 4\n" /* tree */
+ "v: 17: 8\n" /* tree */
+ "w: 50: 3\n" /* torch */
+ "x: 50: 1\n" /* torch */
+ "y: 50: 4\n" /* torch */
+ "z: 50: 2\n" /* torch */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "mmmmmmaaammmmmm"
+ /* 1 */ "maaaaaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaaaaam"
+ /* 6 */ "maaaaaaaaaaaaam"
+ /* 7 */ "maaaaaaaaaaaaam"
+ /* 8 */ "mmmmmmmmaaaaaam"
+ /* 9 */ "mmmmmmmmaaaaaam"
+ /* 10 */ "mmmmmmmmaaaaaam"
+ /* 11 */ "mmmmmmmmaaaaaam"
+ /* 12 */ "mmmmmmmmaaaaaam"
+ /* 13 */ "mmmmmmmmaaaaaam"
+ /* 14 */ "mmmmmmmmaaaaaam"
+ /* 15 */ "mmmmmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "......bcd......"
+ /* 1 */ ".aaaaaaaaaaaaa."
+ /* 2 */ ".aeeeeaaaaaaaa."
+ /* 3 */ ".aeeeeaaaaaaaa."
+ /* 4 */ ".aaaaaaaaaaaaa."
+ /* 5 */ ".aaaaaaaaaaaaa."
+ /* 6 */ ".aaaaaaaaaaaaa."
+ /* 7 */ ".aaaaaaaaaaaaa."
+ /* 8 */ "........aaaaaa."
+ /* 9 */ "mmmmmmm.aaaaaa."
+ /* 10 */ "mmmmmmm.aaaaaa."
+ /* 11 */ "mmmmmmm.aaaaaa."
+ /* 12 */ "mmmmmmm.aaaaaa."
+ /* 13 */ "mmmmmmm.aaaaaa."
+ /* 14 */ "mmmmmmm.aaaaaa."
+ /* 15 */ "mmmmmmm........"
+
+ // Level 2
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".fggggfhfggggf."
+ /* 2 */ ".g...i.......g."
+ /* 3 */ ".gjeee......kg."
+ /* 4 */ ".f..........lg."
+ /* 5 */ ".g..........ng."
+ /* 6 */ ".g.olp..ol...g."
+ /* 7 */ ".fggggggfn...f."
+ /* 8 */ "........g....g."
+ /* 9 */ "mmmmmmm.gk...g."
+ /* 10 */ "mmmmmmm.gl..kg."
+ /* 11 */ "mmmmmmm.gn..lg."
+ /* 12 */ "mmmmmmm.g...ng."
+ /* 13 */ "mmmmmmm.gq..qg."
+ /* 14 */ "mmmmmmm.fggggf."
+ /* 15 */ "mmmmmmm........"
+
+ // Level 3
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".fgrrgfsfgrrgf."
+ /* 2 */ ".g...........g."
+ /* 3 */ ".g...........r."
+ /* 4 */ ".f..........tr."
+ /* 5 */ ".g...........r."
+ /* 6 */ ".g..t....t...g."
+ /* 7 */ ".fgrrrrgf....f."
+ /* 8 */ "........g....g."
+ /* 9 */ "mmmmmmm.r....r."
+ /* 10 */ "mmmmmmm.rt...r."
+ /* 11 */ "mmmmmmm.r...tr."
+ /* 12 */ "mmmmmmm.r....r."
+ /* 13 */ "mmmmmmm.gq..qg."
+ /* 14 */ "mmmmmmm.fgrrgf."
+ /* 15 */ "mmmmmmm........"
+
+ // Level 4
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".fuuuuuuuuuuuf."
+ /* 2 */ ".v....w.w....v."
+ /* 3 */ ".v...........v."
+ /* 4 */ ".vx..........v."
+ /* 5 */ ".v...........v."
+ /* 6 */ ".v......y....v."
+ /* 7 */ ".fuuuuuufx..zv."
+ /* 8 */ "........v....v."
+ /* 9 */ "mmmmmmm.v....v."
+ /* 10 */ "mmmmmmm.v....v."
+ /* 11 */ "mmmmmmm.v....v."
+ /* 12 */ "mmmmmmm.v....v."
+ /* 13 */ "mmmmmmm.v.yy.v."
+ /* 14 */ "mmmmmmm.fuuuuf."
+ /* 15 */ "mmmmmmm........"
+
+ // Level 5
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "nnnnnnnnnnnnnno"
+ /* 1 */ "pgggggggggggggo"
+ /* 2 */ "pgAAAAAAAAAABgo"
+ /* 3 */ "pgC.........Bgo"
+ /* 4 */ "pgC.........Bgo"
+ /* 5 */ "pgC.........Bgo"
+ /* 6 */ "pgCDDDDDDD..Bgo"
+ /* 7 */ "pggggggggC..Bgo"
+ /* 8 */ "pkkkkkkpgC..Bgo"
+ /* 9 */ "mmmmmmmpgC..Bgo"
+ /* 10 */ "mmmmmmmpgC..Bgo"
+ /* 11 */ "mmmmmmmpgC..Bgo"
+ /* 12 */ "mmmmmmmpgC..Bgo"
+ /* 13 */ "mmmmmmmpgCDDBgo"
+ /* 14 */ "mmmmmmmpggggggo"
+ /* 15 */ "mmmmmmmpkkkkkkk"
+
+ // Level 6
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".pnnnnnnnnnnno."
+ /* 2 */ ".pgggggggggggo."
+ /* 3 */ ".pgggggggggggo."
+ /* 4 */ ".pgggggggggggo."
+ /* 5 */ ".pgggggggggggo."
+ /* 6 */ ".pgggggggggggo."
+ /* 7 */ ".pkkkkkkkggggo."
+ /* 8 */ "........pggggo."
+ /* 9 */ "mmmmmmm.pggggo."
+ /* 10 */ "mmmmmmm.pggggo."
+ /* 11 */ "mmmmmmm.pggggo."
+ /* 12 */ "mmmmmmm.pggggo."
+ /* 13 */ "mmmmmmm.pggggo."
+ /* 14 */ "mmmmmmm.kkkkko."
+ /* 15 */ "mmmmmmm........"
+
+ // Level 7
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "..nnnnnnnnnnn.."
+ /* 3 */ "..pgggggggggo.."
+ /* 4 */ "..pgggggggggo.."
+ /* 5 */ "..pgggggggggo.."
+ /* 6 */ "..kkkkkkkkggo.."
+ /* 7 */ ".........pggo.."
+ /* 8 */ ".........pggo.."
+ /* 9 */ "mmmmmmm..pggo.."
+ /* 10 */ "mmmmmmm..pggo.."
+ /* 11 */ "mmmmmmm..pggo.."
+ /* 12 */ "mmmmmmm..pggo.."
+ /* 13 */ "mmmmmmm..kkko.."
+ /* 14 */ "mmmmmmm........"
+ /* 15 */ "mmmmmmm........"
+
+ // Level 8
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "..............."
+ /* 3 */ "...pnnnnnnno..."
+ /* 4 */ "...pgggggggo..."
+ /* 5 */ "...pkkkkkkpo..."
+ /* 6 */ "..........po..."
+ /* 7 */ "..........po..."
+ /* 8 */ "..........po..."
+ /* 9 */ "mmmmmmm...po..."
+ /* 10 */ "mmmmmmm...po..."
+ /* 11 */ "mmmmmmm...po..."
+ /* 12 */ "mmmmmmm...pk..."
+ /* 13 */ "mmmmmmm........"
+ /* 14 */ "mmmmmmm........"
+ /* 15 */ "mmmmmmm........",
+
+ // Connectors:
+ "-1: 7, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenHouseL13x14
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenHouseL14x14:
+ // The data has been exported from the gallery Plains, area index 0, ID 4, created by Aloe_vera
+ {
+ // Size:
+ 16, 8, 16, // SizeX = 16, SizeY = 8, SizeZ = 16
+
+ // Hitbox (relative to bounding box):
+ -1, 1, 0, // MinX, MinY, MinZ
+ 16, 7, 16, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 2: 0\n" /* grass */
+ "c: 67: 0\n" /* stairs */
+ "d: 67: 2\n" /* stairs */
+ "e: 67: 1\n" /* stairs */
+ "f: 5: 0\n" /* wood */
+ "g: 67: 3\n" /* stairs */
+ "h: 17: 0\n" /* tree */
+ "i: 64: 7\n" /* wooddoorblock */
+ "j: 64: 5\n" /* wooddoorblock */
+ "k:102: 0\n" /* glasspane */
+ "l: 64:12\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */
+ "n: 53: 2\n" /* woodstairs */
+ "o: 53: 1\n" /* woodstairs */
+ "p: 53: 7\n" /* woodstairs */
+ "q: 53: 6\n" /* woodstairs */
+ "r: 53: 3\n" /* woodstairs */
+ "s: 53: 0\n" /* woodstairs */
+ "t: 53: 5\n" /* woodstairs */
+ "u: 53: 4\n" /* woodstairs */
+ "v: 50: 3\n" /* torch */
+ "w: 50: 2\n" /* torch */
+ "x: 50: 4\n" /* torch */
+ "y: 50: 1\n" /* torch */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmaaammmmm"
+ /* 1 */ "maaaaaaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaaaaaam"
+ /* 6 */ "maaaaaaaaaaaaaam"
+ /* 7 */ "maaaaaaaaaaaaaam"
+ /* 8 */ "bbbbbaaaaaaaaaam"
+ /* 9 */ "bbbbbbbbaaaaaaam"
+ /* 10 */ "bbbbbbbbaaaaaaam"
+ /* 11 */ "bbbbbbbbaaaaaaam"
+ /* 12 */ "bbbbbbbbaaaaaaam"
+ /* 13 */ "bbbbbbbbaaaaaaam"
+ /* 14 */ "bbbbbbbbaaaaaaam"
+ /* 15 */ "bbbbbbbbmmmmmmmm"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "........cde....."
+ /* 1 */ ".aaaaaaaaaaaaaa."
+ /* 2 */ ".affffffffffffa."
+ /* 3 */ ".affffffffffffa."
+ /* 4 */ ".affffffffffffa."
+ /* 5 */ ".affffffffffffa."
+ /* 6 */ ".affffffffffffa."
+ /* 7 */ ".aaaaaaaafffffa."
+ /* 8 */ ".....cgeafffffa."
+ /* 9 */ "........afffffa."
+ /* 10 */ "........afffffa."
+ /* 11 */ "........afffffa."
+ /* 12 */ "........afffffa."
+ /* 13 */ "........afffffa."
+ /* 14 */ "........aaaaaaa."
+ /* 15 */ "................"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ ".hffffffhihfffh."
+ /* 2 */ ".f............f."
+ /* 3 */ ".f............f."
+ /* 4 */ ".f............f."
+ /* 5 */ ".f............f."
+ /* 6 */ ".f............f."
+ /* 7 */ ".hffffjfh.....f."
+ /* 8 */ "........f.....f."
+ /* 9 */ "........f.....f."
+ /* 10 */ "........f.....f."
+ /* 11 */ "........f.....f."
+ /* 12 */ "........f.....f."
+ /* 13 */ "........f.....f."
+ /* 14 */ "........hfffffh."
+ /* 15 */ "................"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ ".hfkkfkkhlhkkfh."
+ /* 2 */ ".k............f."
+ /* 3 */ ".k............k."
+ /* 4 */ ".k............k."
+ /* 5 */ ".k............f."
+ /* 6 */ ".k............k."
+ /* 7 */ ".hfkkflfh.....k."
+ /* 8 */ "........f.....f."
+ /* 9 */ "........k.....k."
+ /* 10 */ "........k.....k."
+ /* 11 */ "........f.....f."
+ /* 12 */ "........k.....k."
+ /* 13 */ "........k.....k."
+ /* 14 */ "........hkkkkkh."
+ /* 15 */ "................"
+
+ // Level 4
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "nnnnnnnnnnnnnnno"
+ /* 1 */ "phffffffhfhfffho"
+ /* 2 */ ".f............fo"
+ /* 3 */ ".f............fo"
+ /* 4 */ ".f............fo"
+ /* 5 */ ".f............fo"
+ /* 6 */ ".f............fo"
+ /* 7 */ "qhffffffh.....fo"
+ /* 8 */ "rrrrrrrsf.....fo"
+ /* 9 */ ".......sf.....fo"
+ /* 10 */ ".......sf.....fo"
+ /* 11 */ ".......sf.....fo"
+ /* 12 */ ".......sf.....fo"
+ /* 13 */ ".......sf.....fo"
+ /* 14 */ ".......shfffffho"
+ /* 15 */ ".......st.....uo"
+
+ // Level 5
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "nnnnnnnnnnnnnnn."
+ /* 2 */ "pfffffffffffffo."
+ /* 3 */ ".f.........v.fo."
+ /* 4 */ ".f..........wfo."
+ /* 5 */ ".f......x....fo."
+ /* 6 */ "qfffffffff...fo."
+ /* 7 */ "rrrrrrrrsfy..fo."
+ /* 8 */ "........sf...fo."
+ /* 9 */ "........sf...fo."
+ /* 10 */ "........sf...fo."
+ /* 11 */ "........sf...fo."
+ /* 12 */ "........sf...fo."
+ /* 13 */ "........sf...fo."
+ /* 14 */ "........sfffffo."
+ /* 15 */ "........st...uo."
+
+ // Level 6
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ "nnnnnnnnnnnnno.."
+ /* 3 */ "pffffffffffffo.."
+ /* 4 */ ".fy.........fo.."
+ /* 5 */ "qffffffffff.fo.."
+ /* 6 */ "rrrrrrrrrsf.fo.."
+ /* 7 */ ".........sf.fo.."
+ /* 8 */ ".........sf.fo.."
+ /* 9 */ ".........sf.fo.."
+ /* 10 */ ".........sf.fo.."
+ /* 11 */ ".........sf.fo.."
+ /* 12 */ ".........sf.fo.."
+ /* 13 */ ".........sfxfo.."
+ /* 14 */ ".........sfffo.."
+ /* 15 */ ".........st.uo.."
+
+ // Level 7
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ "................"
+ /* 3 */ "nnnnnnnnnnnnn..."
+ /* 4 */ "ffffffffffffo..."
+ /* 5 */ "rrrrrrrrrrsfo..."
+ /* 6 */ "..........sfo..."
+ /* 7 */ "..........sfo..."
+ /* 8 */ "..........sfo..."
+ /* 9 */ "..........sfo..."
+ /* 10 */ "..........sfo..."
+ /* 11 */ "..........sfo..."
+ /* 12 */ "..........sfo..."
+ /* 13 */ "..........sfo..."
+ /* 14 */ "..........sfo..."
+ /* 15 */ "..........sfo...",
+
+ // Connectors:
+ "-1: 9, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenHouseL14x14
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenHouseL9x9:
+ // The data has been exported from the gallery Plains, area index 42, ID 93, created by xoft
+ {
+ // Size:
+ 11, 7, 11, // SizeX = 11, SizeY = 7, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 11, 6, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 0\n" /* stairs */
+ "c: 67: 2\n" /* stairs */
+ "d: 67: 1\n" /* stairs */
+ "e: 17: 0\n" /* tree */
+ "f: 5: 0\n" /* wood */
+ "g: 64: 7\n" /* wooddoorblock */
+ "h:102: 0\n" /* glasspane */
+ "i: 64:12\n" /* wooddoorblock */
+ "j: 53: 2\n" /* woodstairs */
+ "k: 53: 7\n" /* woodstairs */
+ "l: 53: 1\n" /* woodstairs */
+ "m: 19: 0\n" /* sponge */
+ "n: 50: 3\n" /* torch */
+ "o: 50: 4\n" /* torch */
+ "p: 53: 6\n" /* woodstairs */
+ "q: 50: 1\n" /* torch */
+ "r: 50: 2\n" /* torch */
+ "s: 53: 3\n" /* woodstairs */
+ "t: 53: 0\n" /* woodstairs */
+ "u: 53: 5\n" /* woodstairs */
+ "v: 53: 4\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmmmaaammmm"
+ /* 1 */ "maaaaaaaaam"
+ /* 2 */ "maaaaaaaaam"
+ /* 3 */ "maaaaaaaaam"
+ /* 4 */ "maaaaaaaaam"
+ /* 5 */ "maaaaaaaaam"
+ /* 6 */ "mmmmmaaaaam"
+ /* 7 */ "mmmmmaaaaam"
+ /* 8 */ "mmmmmaaaaam"
+ /* 9 */ "mmmmmaaaaam"
+ /* 10 */ "mmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "....bcd...."
+ /* 1 */ ".aaaaaaaaa."
+ /* 2 */ ".aaaaaaaaa."
+ /* 3 */ ".aaaaaaaaa."
+ /* 4 */ ".aaaaaaaaa."
+ /* 5 */ ".aaaaaaaaa."
+ /* 6 */ ".....aaaaa."
+ /* 7 */ ".....aaaaa."
+ /* 8 */ ".....aaaaa."
+ /* 9 */ ".....aaaaa."
+ /* 10 */ "..........."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".efffgfffe."
+ /* 2 */ ".f.......f."
+ /* 3 */ ".f.......f."
+ /* 4 */ ".f.......f."
+ /* 5 */ ".efffe...f."
+ /* 6 */ ".....f...f."
+ /* 7 */ ".....f...f."
+ /* 8 */ ".....f...f."
+ /* 9 */ ".....efffe."
+ /* 10 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".ehhfifhhe."
+ /* 2 */ ".h.......h."
+ /* 3 */ ".h.......h."
+ /* 4 */ ".h.......h."
+ /* 5 */ ".ehhhe...f."
+ /* 6 */ ".....h...h."
+ /* 7 */ ".....h...h."
+ /* 8 */ ".....h...h."
+ /* 9 */ ".....ehhhe."
+ /* 10 */ "..........."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "jjjjjjjjjjj"
+ /* 1 */ "kfffffffffl"
+ /* 2 */ ".f..n.n..fl"
+ /* 3 */ ".f.......fl"
+ /* 4 */ ".f...o...fl"
+ /* 5 */ "pfffffq.rfl"
+ /* 6 */ "sssssf...fl"
+ /* 7 */ "....tf...fl"
+ /* 8 */ "....tf...fl"
+ /* 9 */ "....tfffffl"
+ /* 10 */ "....tu...vl"
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "jjjjjjjjjl."
+ /* 2 */ "kffffffffl."
+ /* 3 */ ".f......fl."
+ /* 4 */ "pffffff.fl."
+ /* 5 */ "ssssssf.fl."
+ /* 6 */ ".....tf.fl."
+ /* 7 */ ".....tf.fl."
+ /* 8 */ ".....tf.fl."
+ /* 9 */ ".....tfffl."
+ /* 10 */ ".....tu.vl."
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "jjjjjjjjj.."
+ /* 3 */ "ffffffffl.."
+ /* 4 */ "sssssstfl.."
+ /* 5 */ "......tfl.."
+ /* 6 */ "......tfl.."
+ /* 7 */ "......tfl.."
+ /* 8 */ "......tfl.."
+ /* 9 */ "......tfl.."
+ /* 10 */ "......tfl..",
+
+ // Connectors:
+ "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenHouseL9x9
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenHouseU13x9:
+ // The data has been exported from the gallery Plains, area index 43, ID 94, created by xoft
+ {
+ // Size:
+ 15, 7, 11, // SizeX = 15, SizeY = 7, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 15, 6, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 0\n" /* stairs */
+ "c: 67: 2\n" /* stairs */
+ "d: 67: 1\n" /* stairs */
+ "e: 17: 0\n" /* tree */
+ "f: 5: 0\n" /* wood */
+ "g: 64: 7\n" /* wooddoorblock */
+ "h:102: 0\n" /* glasspane */
+ "i: 64:12\n" /* wooddoorblock */
+ "j: 53: 2\n" /* woodstairs */
+ "k: 53: 0\n" /* woodstairs */
+ "l: 53: 1\n" /* woodstairs */
+ "m: 19: 0\n" /* sponge */
+ "n: 50: 3\n" /* torch */
+ "o: 50: 4\n" /* torch */
+ "p: 50: 2\n" /* torch */
+ "q: 50: 1\n" /* torch */
+ "r: 53: 3\n" /* woodstairs */
+ "s: 53: 5\n" /* woodstairs */
+ "t: 53: 4\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "mmmmmmaaammmmmm"
+ /* 1 */ "maaaaaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaaaaam"
+ /* 6 */ "maaaaammmaaaaam"
+ /* 7 */ "maaaaammmaaaaam"
+ /* 8 */ "maaaaammmaaaaam"
+ /* 9 */ "maaaaammmaaaaam"
+ /* 10 */ "mmmmmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "......bcd......"
+ /* 1 */ ".aaaaaaaaaaaaa."
+ /* 2 */ ".aaaaaaaaaaaaa."
+ /* 3 */ ".aaaaaaaaaaaaa."
+ /* 4 */ ".aaaaaaaaaaaaa."
+ /* 5 */ ".aaaaaaaaaaaaa."
+ /* 6 */ ".aaaaa...aaaaa."
+ /* 7 */ ".aaaaa...aaaaa."
+ /* 8 */ ".aaaaa...aaaaa."
+ /* 9 */ ".aaaaa...aaaaa."
+ /* 10 */ "..............."
+
+ // Level 2
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".efffffgfffffe."
+ /* 2 */ ".f...........f."
+ /* 3 */ ".f...........f."
+ /* 4 */ ".f...........f."
+ /* 5 */ ".f...efffe...f."
+ /* 6 */ ".f...f...f...f."
+ /* 7 */ ".f...f...f...f."
+ /* 8 */ ".f...f...f...f."
+ /* 9 */ ".efffe...efffe."
+ /* 10 */ "..............."
+
+ // Level 3
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".ehhhhfifhhhhe."
+ /* 2 */ ".h...........h."
+ /* 3 */ ".h...........h."
+ /* 4 */ ".h...........h."
+ /* 5 */ ".f...ehhhe...f."
+ /* 6 */ ".h...h...h...h."
+ /* 7 */ ".h...h...h...h."
+ /* 8 */ ".h...h...h...h."
+ /* 9 */ ".ehhhe...ehhhe."
+ /* 10 */ "..............."
+
+ // Level 4
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "jjjjjjjjjjjjjjj"
+ /* 1 */ "kfffffffffffffl"
+ /* 2 */ "kf....n.n....fl"
+ /* 3 */ "kf...........fl"
+ /* 4 */ "kf...o...o...fl"
+ /* 5 */ "kf..pfffffq..fl"
+ /* 6 */ "kf...frrrf...fl"
+ /* 7 */ "kf...fl.kf...fl"
+ /* 8 */ "kf...fl.kf...fl"
+ /* 9 */ "kfffffl.kfffffl"
+ /* 10 */ "ks...tl.ks...tl"
+
+ // Level 5
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".jjjjjjjjjjjjl."
+ /* 2 */ ".kfffffffffffl."
+ /* 3 */ ".kfffffffffffl."
+ /* 4 */ ".kfffffffffffl."
+ /* 5 */ ".kffflrrrrfffl."
+ /* 6 */ ".kfffl...kfffl."
+ /* 7 */ ".kfffl...kfffl."
+ /* 8 */ ".kfffl...kfffl."
+ /* 9 */ ".kfffl...kfffl."
+ /* 10 */ ".ks.tl...ks.tl."
+
+ // Level 6
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "..kjjjjjjjjjj.."
+ /* 3 */ "..kfffffffffl.."
+ /* 4 */ "..kflrrrrrkfl.."
+ /* 5 */ "..kfl.....kfl.."
+ /* 6 */ "..kfl.....kfl.."
+ /* 7 */ "..kfl.....kfl.."
+ /* 8 */ "..kfl.....kfl.."
+ /* 9 */ "..kfl.....kfl.."
+ /* 10 */ "..kfl.....kfl..",
+
+ // Connectors:
+ "-1: 7, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenHouseU13x9
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenMill5x5:
+ // The data has been exported from the gallery Plains, area index 60, ID 111, created by Aloe_vera
+ {
+ // Size:
+ 9, 17, 13, // SizeX = 9, SizeY = 17, SizeZ = 13
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 8, 16, 12, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 2\n" /* stairs */
+ "c: 67: 1\n" /* stairs */
+ "d: 67: 3\n" /* stairs */
+ "e: 17: 0\n" /* tree */
+ "f: 5: 0\n" /* wood */
+ "g: 54: 4\n" /* chest */
+ "h:154: 4\n" /* hopper */
+ "i: 64: 4\n" /* wooddoorblock */
+ "j:102: 0\n" /* glasspane */
+ "k: 85: 0\n" /* fence */
+ "l: 64:12\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */
+ "n: 50: 2\n" /* torch */
+ "o: 35: 0\n" /* wool */
+ "p: 17: 4\n" /* tree */
+ "q: 17: 8\n" /* tree */
+ "r: 53: 2\n" /* woodstairs */
+ "s: 53: 7\n" /* woodstairs */
+ "t: 53: 6\n" /* woodstairs */
+ "u: 53: 3\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 012345678 */
+ /* 0 */ "mmmmmmmmm"
+ /* 1 */ "mmmmmmmmm"
+ /* 2 */ "mmmmmmmmm"
+ /* 3 */ "mmmmmmmmm"
+ /* 4 */ "maaaaammm"
+ /* 5 */ "maaaaaamm"
+ /* 6 */ "maaaaaamm"
+ /* 7 */ "maaaaaamm"
+ /* 8 */ "maaaaammm"
+ /* 9 */ "mmmmmmmmm"
+ /* 10 */ "mmmmmmmmm"
+ /* 11 */ "mmmmmmmmm"
+ /* 12 */ "mmmmmmmmm"
+
+ // Level 1
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........."
+ /* 3 */ "........."
+ /* 4 */ ".aaaaa..."
+ /* 5 */ ".aaaaab.."
+ /* 6 */ ".aaaaac.."
+ /* 7 */ ".aaaaad.."
+ /* 8 */ ".aaaaa..."
+ /* 9 */ "........."
+ /* 10 */ "........."
+ /* 11 */ "........."
+ /* 12 */ "........."
+
+ // Level 2
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........."
+ /* 3 */ "........."
+ /* 4 */ ".efffe..."
+ /* 5 */ ".f...f..."
+ /* 6 */ ".fgh.i..."
+ /* 7 */ ".f...f..."
+ /* 8 */ ".efffe..."
+ /* 9 */ "........."
+ /* 10 */ "........."
+ /* 11 */ "........."
+ /* 12 */ "........."
+
+ // Level 3
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........."
+ /* 3 */ "........."
+ /* 4 */ ".ejjje..."
+ /* 5 */ ".j...f..."
+ /* 6 */ ".j.k.l..."
+ /* 7 */ ".j...f..."
+ /* 8 */ ".ejjje..."
+ /* 9 */ "........."
+ /* 10 */ "........."
+ /* 11 */ "........."
+ /* 12 */ "........."
+
+ // Level 4
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........."
+ /* 3 */ "........."
+ /* 4 */ ".efffe..."
+ /* 5 */ ".f..nf..."
+ /* 6 */ ".f.k.f..."
+ /* 7 */ ".f..nf..k"
+ /* 8 */ ".efffe..o"
+ /* 9 */ "........."
+ /* 10 */ "........."
+ /* 11 */ "........."
+ /* 12 */ "........."
+
+ // Level 5
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........."
+ /* 3 */ "........."
+ /* 4 */ ".epppe..."
+ /* 5 */ ".q...q..."
+ /* 6 */ ".q.k.q..."
+ /* 7 */ ".q...q..k"
+ /* 8 */ ".epppe..o"
+ /* 9 */ "........."
+ /* 10 */ "........."
+ /* 11 */ "........."
+ /* 12 */ "........."
+
+ // Level 6
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........."
+ /* 3 */ "........."
+ /* 4 */ ".efffe..."
+ /* 5 */ ".f...f..."
+ /* 6 */ ".f.k.f..k"
+ /* 7 */ ".f...f..o"
+ /* 8 */ ".efffe..o"
+ /* 9 */ "........."
+ /* 10 */ "........."
+ /* 11 */ "........."
+ /* 12 */ "........."
+
+ // Level 7
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........."
+ /* 3 */ "........."
+ /* 4 */ ".ejjje..."
+ /* 5 */ ".j...j..."
+ /* 6 */ ".j.k.j..k"
+ /* 7 */ ".j...j..o"
+ /* 8 */ ".ejjje..."
+ /* 9 */ "........."
+ /* 10 */ "........."
+ /* 11 */ "........."
+ /* 12 */ "........."
+
+ // Level 8
+ /* z\x* 012345678 */
+ /* 0 */ "........o"
+ /* 1 */ "........o"
+ /* 2 */ "........o"
+ /* 3 */ "........."
+ /* 4 */ ".efffe..."
+ /* 5 */ ".f...f..k"
+ /* 6 */ ".f.k.f..o"
+ /* 7 */ ".f...f..o"
+ /* 8 */ ".efffe..."
+ /* 9 */ "........."
+ /* 10 */ "........."
+ /* 11 */ "........."
+ /* 12 */ "........."
+
+ // Level 9
+ /* z\x* 012345678 */
+ /* 0 */ "........k"
+ /* 1 */ "........k"
+ /* 2 */ "........o"
+ /* 3 */ "........o"
+ /* 4 */ ".epppe..o"
+ /* 5 */ ".q...q..k"
+ /* 6 */ ".q.k.q..o"
+ /* 7 */ ".q...q..k"
+ /* 8 */ ".epppe..k"
+ /* 9 */ "........."
+ /* 10 */ "........."
+ /* 11 */ "........."
+ /* 12 */ "........."
+
+ // Level 10
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........k"
+ /* 3 */ "rrrrrrr.k"
+ /* 4 */ "sfffffs.o"
+ /* 5 */ ".f...f..o"
+ /* 6 */ ".f.kppppp"
+ /* 7 */ ".f...f..o"
+ /* 8 */ "tffffft.o"
+ /* 9 */ "uuuuuuu.k"
+ /* 10 */ "........k"
+ /* 11 */ "........."
+ /* 12 */ "........."
+
+ // Level 11
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........."
+ /* 3 */ "........."
+ /* 4 */ "rrrrrrr.k"
+ /* 5 */ "sfffffs.k"
+ /* 6 */ ".f...f..o"
+ /* 7 */ "tffffft.k"
+ /* 8 */ "uuuuuuu.o"
+ /* 9 */ "........o"
+ /* 10 */ "........o"
+ /* 11 */ "........k"
+ /* 12 */ "........k"
+
+ // Level 12
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........."
+ /* 3 */ "........."
+ /* 4 */ "........."
+ /* 5 */ "rrrrrrr.o"
+ /* 6 */ "fffffff.o"
+ /* 7 */ "uuuuuuu.k"
+ /* 8 */ "........."
+ /* 9 */ "........."
+ /* 10 */ "........o"
+ /* 11 */ "........o"
+ /* 12 */ "........o"
+
+ // Level 13
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........."
+ /* 3 */ "........."
+ /* 4 */ "........."
+ /* 5 */ "........o"
+ /* 6 */ "........k"
+ /* 7 */ "........."
+ /* 8 */ "........."
+ /* 9 */ "........."
+ /* 10 */ "........."
+ /* 11 */ "........."
+ /* 12 */ "........."
+
+ // Level 14
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........."
+ /* 3 */ "........."
+ /* 4 */ "........o"
+ /* 5 */ "........o"
+ /* 6 */ "........k"
+ /* 7 */ "........."
+ /* 8 */ "........."
+ /* 9 */ "........."
+ /* 10 */ "........."
+ /* 11 */ "........."
+ /* 12 */ "........."
+
+ // Level 15
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........."
+ /* 3 */ "........."
+ /* 4 */ "........o"
+ /* 5 */ "........k"
+ /* 6 */ "........."
+ /* 7 */ "........."
+ /* 8 */ "........."
+ /* 9 */ "........."
+ /* 10 */ "........."
+ /* 11 */ "........."
+ /* 12 */ "........."
+
+ // Level 16
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........."
+ /* 3 */ "........."
+ /* 4 */ "........o"
+ /* 5 */ "........k"
+ /* 6 */ "........."
+ /* 7 */ "........."
+ /* 8 */ "........."
+ /* 9 */ "........."
+ /* 10 */ "........."
+ /* 11 */ "........."
+ /* 12 */ ".........",
+
+ // Connectors:
+ "-1: 8, 1, 6: 5\n" /* Type -1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenMill5x5
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WoodenStables:
+ // The data has been exported from the gallery Plains, area index 55, ID 106, created by Aloe_vera
+ {
+ // Size:
+ 15, 9, 9, // SizeX = 15, SizeY = 9, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ -1, -1, 0, // MinX, MinY, MinZ
+ 15, 8, 9, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 4: 0\n" /* cobblestone */
+ "b: 67: 0\n" /* stairs */
+ "c: 67: 2\n" /* stairs */
+ "d: 67: 1\n" /* stairs */
+ "e: 3: 0\n" /* dirt */
+ "f: 17: 0\n" /* tree */
+ "g:107: 0\n" /* fencegate */
+ "h:107: 4\n" /* fencegate */
+ "i: 5: 0\n" /* wood */
+ "j:107: 6\n" /* fencegate */
+ "k: 85: 0\n" /* fence */
+ "l:170: 0\n" /* haybale */
+ "m: 19: 0\n" /* sponge */
+ "n:170: 4\n" /* haybale */
+ "o:170: 8\n" /* haybale */
+ "p: 50: 1\n" /* torch */
+ "q: 50: 2\n" /* torch */
+ "r: 53: 2\n" /* woodstairs */
+ "s: 53: 7\n" /* woodstairs */
+ "t: 53: 6\n" /* woodstairs */
+ "u: 53: 3\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "maaaaaaaaaaaaam"
+ /* 1 */ "maaaaaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaaaaam"
+ /* 6 */ "maaaaaaaaaaaaam"
+ /* 7 */ "maaaaaaaaaaaaam"
+ /* 8 */ "mmmmmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ ".bcccccccccccd."
+ /* 1 */ ".aaaaaaaaaaaaa."
+ /* 2 */ ".aeeeeeeeeeeea."
+ /* 3 */ ".aeeeeeeeeeeea."
+ /* 4 */ ".aeeeeeeeeeeea."
+ /* 5 */ ".aeeeeeeeeeeea."
+ /* 6 */ ".aeeeeeeeeeeea."
+ /* 7 */ ".aaaaaaaaaaaaa."
+ /* 8 */ "..............."
+
+ // Level 2
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".fghgighgigjgf."
+ /* 2 */ ".k...k...k...k."
+ /* 3 */ ".k...k...k...k."
+ /* 4 */ ".k...k...k...k."
+ /* 5 */ ".k...k...k...k."
+ /* 6 */ ".kl..k..nko..k."
+ /* 7 */ ".fkkkikkkikkkf."
+ /* 8 */ "..............."
+
+ // Level 3
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".f...i...i...f."
+ /* 2 */ "..............."
+ /* 3 */ "..............."
+ /* 4 */ "..............."
+ /* 5 */ "..............."
+ /* 6 */ "..............."
+ /* 7 */ ".f...i...i...f."
+ /* 8 */ "..............."
+
+ // Level 4
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".fp.qip.qip.qf."
+ /* 2 */ "..............."
+ /* 3 */ "..............."
+ /* 4 */ "..............."
+ /* 5 */ "..............."
+ /* 6 */ "..............."
+ /* 7 */ ".f...i...i...f."
+ /* 8 */ "..............."
+
+ // Level 5
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "rrrrrrrrrrrrrrr"
+ /* 1 */ "siiiiiiiiiiiiis"
+ /* 2 */ ".i...........i."
+ /* 3 */ ".i...........i."
+ /* 4 */ ".i...........i."
+ /* 5 */ ".i...........i."
+ /* 6 */ ".i...........i."
+ /* 7 */ "tiiiiiiiiiiiiit"
+ /* 8 */ "uuuuuuuuuuuuuuu"
+
+ // Level 6
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "rrrrrrrrrrrrrrr"
+ /* 2 */ "siiiiiiiiiiiiis"
+ /* 3 */ ".i...........i."
+ /* 4 */ ".i...........i."
+ /* 5 */ ".i...........i."
+ /* 6 */ "tiiiiiiiiiiiiit"
+ /* 7 */ "uuuuuuuuuuuuuuu"
+ /* 8 */ "..............."
+
+ // Level 7
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "rrrrrrrrrrrrrrr"
+ /* 3 */ "siiiiiiiiiiiiis"
+ /* 4 */ ".i...........i."
+ /* 5 */ "tiiiiiiiiiiiiit"
+ /* 6 */ "uuuuuuuuuuuuuuu"
+ /* 7 */ "..............."
+ /* 8 */ "..............."
+
+ // Level 8
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "..............."
+ /* 3 */ "rrrrrrrrrrrrrrr"
+ /* 4 */ "iiiiiiiiiiiiiii"
+ /* 5 */ "uuuuuuuuuuuuuuu"
+ /* 6 */ "..............."
+ /* 7 */ "..............."
+ /* 8 */ "...............",
+
+ // Connectors:
+ "-1: 7, 1, -1: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // WoodenStables
+}; // g_PlainsVillagePrefabs
+
+
+
+
+
+
+const cPrefab::sDef g_PlainsVillageStartingPrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CobbleWell4x4:
+ // The data has been exported from the gallery Plains, area index 1, ID 5, created by Aloe_vera
+ {
+ // Size:
+ 4, 13, 4, // SizeX = 4, SizeY = 13, SizeZ = 4
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 3, 12, 3, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 1: 0\n" /* stone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 8: 0\n" /* water */
+ "d: 85: 0\n" /* fence */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123 */
+ /* 0 */ "aaaa"
+ /* 1 */ "aaaa"
+ /* 2 */ "aaaa"
+ /* 3 */ "aaaa"
+
+ // Level 1
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 2
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 3
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 4
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 5
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 6
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 7
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 8
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 9
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "b..b"
+ /* 2 */ "b..b"
+ /* 3 */ "bbbb"
+
+ // Level 10
+ /* z\x* 0123 */
+ /* 0 */ "d..d"
+ /* 1 */ "...."
+ /* 2 */ "...."
+ /* 3 */ "d..d"
+
+ // Level 11
+ /* z\x* 0123 */
+ /* 0 */ "d..d"
+ /* 1 */ "...."
+ /* 2 */ "...."
+ /* 3 */ "d..d"
+
+ // Level 12
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bbbb"
+ /* 2 */ "bbbb"
+ /* 3 */ "bbbb",
+
+ // Connectors:
+ "2: 1, 9, 3: 3\n" /* Type 2, direction Z+ */
+ "2: 2, 9, 0: 2\n" /* Type 2, direction Z- */
+ "2: 0, 9, 1: 4\n" /* Type 2, direction X- */
+ "2: 3, 9, 2: 5\n" /* Type 2, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // CobbleWell4x4
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MineEntrance:
+ // The data has been exported from the gallery Plains, area index 138, ID 446, created by STR_Warrior
+ {
+ // Size:
+ 7, 38, 7, // SizeX = 7, SizeY = 38, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 37, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 0\n" /* wood */
+ "b: 77: 2\n" /* stonebutton */
+ "c: 66: 6\n" /* tracks */
+ "d: 27: 1\n" /* poweredrail */
+ "e: 66: 5\n" /* tracks */
+ "f: 66: 9\n" /* tracks */
+ "g: 66: 2\n" /* tracks */
+ "h: 50: 4\n" /* torch */
+ "i: 66: 4\n" /* tracks */
+ "j: 66: 8\n" /* tracks */
+ "k: 66: 3\n" /* tracks */
+ "l: 66: 7\n" /* tracks */
+ "m: 19: 0\n" /* sponge */
+ "n: 50: 2\n" /* torch */
+ "o: 2: 0\n" /* grass */
+ "p: 53: 2\n" /* woodstairs */
+ "q: 77: 1\n" /* stonebutton */
+ "r: 27: 0\n" /* poweredrail */
+ "s: 53: 7\n" /* woodstairs */
+ "t: 53: 6\n" /* woodstairs */
+ "u: 53: 3\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "maaaaam"
+ /* 1 */ "maaaaam"
+ /* 2 */ "maaaaam"
+ /* 3 */ "maaaaam"
+ /* 4 */ "maaaaam"
+ /* 5 */ "maaaaam"
+ /* 6 */ "mmmmmmm"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "mm...mm"
+ /* 1 */ "mm.abam"
+ /* 2 */ "mmcddam"
+ /* 3 */ "mae..am"
+ /* 4 */ "mmaa.mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "mm...mm"
+ /* 1 */ "mm.a.mm"
+ /* 2 */ "mm...mm"
+ /* 3 */ "ma..aam"
+ /* 4 */ "mmfgamm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "mm.h.mm"
+ /* 1 */ "mm.a.mm"
+ /* 2 */ "mm.aamm"
+ /* 3 */ "ma..iam"
+ /* 4 */ "mm..jmm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mmaklmm"
+ /* 3 */ "maa..am"
+ /* 4 */ "mm...mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mmc..mm"
+ /* 3 */ "mae.nam"
+ /* 4 */ "mmaa.mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 6
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mm...mm"
+ /* 3 */ "ma..aam"
+ /* 4 */ "mmfgamm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 7
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mm.aamm"
+ /* 3 */ "ma..iam"
+ /* 4 */ "mm..jmm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 8
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mmaklmm"
+ /* 3 */ "maa..am"
+ /* 4 */ "mm...mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 9
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mmc..mm"
+ /* 3 */ "mae.nam"
+ /* 4 */ "mmaa.mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 10
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mm...mm"
+ /* 3 */ "ma..aam"
+ /* 4 */ "mmfgamm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 11
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mm.aamm"
+ /* 3 */ "ma..iam"
+ /* 4 */ "mm..jmm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 12
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mmaklmm"
+ /* 3 */ "maa..am"
+ /* 4 */ "mm...mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 13
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mmc..mm"
+ /* 3 */ "mae.nam"
+ /* 4 */ "mmaa.mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 14
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mm...mm"
+ /* 3 */ "ma..aam"
+ /* 4 */ "mmfgamm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 15
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mm.aamm"
+ /* 3 */ "ma..iam"
+ /* 4 */ "mm..jmm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 16
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mmaklmm"
+ /* 3 */ "maa..am"
+ /* 4 */ "mm...mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 17
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mmc..mm"
+ /* 3 */ "mae.nam"
+ /* 4 */ "mmaa.mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 18
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mm...mm"
+ /* 3 */ "ma..aam"
+ /* 4 */ "mmfgamm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 19
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mm.aamm"
+ /* 3 */ "ma..iam"
+ /* 4 */ "mm..jmm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 20
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mmaklmm"
+ /* 3 */ "maa..am"
+ /* 4 */ "mm...mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 21
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mmc..mm"
+ /* 3 */ "mae.nam"
+ /* 4 */ "mmaa.mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 22
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mm...mm"
+ /* 3 */ "ma..aam"
+ /* 4 */ "mmfgamm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 23
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mm.aamm"
+ /* 3 */ "ma..iam"
+ /* 4 */ "mm..jmm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 24
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mmaklmm"
+ /* 3 */ "maa..am"
+ /* 4 */ "mm...mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 25
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mmc..mm"
+ /* 3 */ "mae.nam"
+ /* 4 */ "mmaa.mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 26
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mm...mm"
+ /* 3 */ "ma..aam"
+ /* 4 */ "mmfgamm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 27
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mm.aamm"
+ /* 3 */ "ma..iam"
+ /* 4 */ "mm..jmm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 28
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mmaklmm"
+ /* 3 */ "maa..am"
+ /* 4 */ "mm...mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 29
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mmc..mm"
+ /* 3 */ "mae.nam"
+ /* 4 */ "mmaa.mm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 30
+ /* z\x* 0123456 */
+ /* 0 */ "mmmmmmm"
+ /* 1 */ "mmmammm"
+ /* 2 */ "mm...mm"
+ /* 3 */ "ma..aam"
+ /* 4 */ "mmfgamm"
+ /* 5 */ "mmmammm"
+ /* 6 */ "mmmmmmm"
+
+ // Level 31
+ /* z\x* 0123456 */
+ /* 0 */ "ooomooo"
+ /* 1 */ "oaaaaao"
+ /* 2 */ "oa.aaao"
+ /* 3 */ "oa..iao"
+ /* 4 */ "oa..jao"
+ /* 5 */ "oaaaaao"
+ /* 6 */ "ooooooo"
+
+ // Level 32
+ /* z\x* 0123456 */
+ /* 0 */ "...p..."
+ /* 1 */ ".aqrba."
+ /* 2 */ "...fl.."
+ /* 3 */ "......."
+ /* 4 */ "......."
+ /* 5 */ ".a...a."
+ /* 6 */ "......."
+
+ // Level 33
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".a...a."
+ /* 2 */ "......."
+ /* 3 */ "......."
+ /* 4 */ "......."
+ /* 5 */ ".a...a."
+ /* 6 */ "......."
+
+ // Level 34
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".a...a."
+ /* 2 */ "......."
+ /* 3 */ "......."
+ /* 4 */ "......."
+ /* 5 */ ".a...a."
+ /* 6 */ "......."
+
+ // Level 35
+ /* z\x* 0123456 */
+ /* 0 */ "ppppppp"
+ /* 1 */ "saaaaas"
+ /* 2 */ ".a...a."
+ /* 3 */ ".a...a."
+ /* 4 */ ".a...a."
+ /* 5 */ "taaaaat"
+ /* 6 */ "uuuuuuu"
+
+ // Level 36
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "ppppppp"
+ /* 2 */ "saaaaas"
+ /* 3 */ ".aaaaa."
+ /* 4 */ "taaaaat"
+ /* 5 */ "uuuuuuu"
+ /* 6 */ "......."
+
+ // Level 37
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "......."
+ /* 2 */ "ppppppp"
+ /* 3 */ "aaaaaaa"
+ /* 4 */ "uuuuuuu"
+ /* 5 */ "......."
+ /* 6 */ ".......",
+
+ // Connectors:
+ "2: 6, 32, 3: 5\n" /* Type 2, direction X+ */
+ "2: 3, 32, 6: 3\n" /* Type 2, direction Z+ */
+ "2: 0, 32, 3: 4\n" /* Type 2, direction X- */
+ "2: 3, 32, 0: 2\n" /* Type 2, direction Z- */
+ "3: 3, 1, 0: 2\n" /* Type 3, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // MineEntrance
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // RoofedWell:
+ // The data has been exported from the gallery Plains, area index 119, ID 271, created by STR_Warrior
+ {
+ // Size:
+ 7, 15, 7, // SizeX = 7, SizeY = 15, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 14, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 1: 0\n" /* stone */
+ "b: 4: 0\n" /* cobblestone */
+ "c: 8: 0\n" /* water */
+ "d: 3: 0\n" /* dirt */
+ "e: 2: 0\n" /* grass */
+ "f: 13: 0\n" /* gravel */
+ "g:118: 3\n" /* cauldronblock */
+ "h: 85: 0\n" /* fence */
+ "i: 53: 2\n" /* woodstairs */
+ "j: 53: 7\n" /* woodstairs */
+ "k: 5: 0\n" /* wood */
+ "l: 53: 4\n" /* woodstairs */
+ "m: 19: 0\n" /* sponge */
+ "n: 53: 5\n" /* woodstairs */
+ "o: 53: 6\n" /* woodstairs */
+ "p: 53: 3\n" /* woodstairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "aaaaaaa"
+ /* 2 */ "aaaaaaa"
+ /* 3 */ "aaaaaaa"
+ /* 4 */ "aaaaaaa"
+ /* 5 */ "aaaaaaa"
+ /* 6 */ "aaaaaaa"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "abbbbba"
+ /* 2 */ "abcccba"
+ /* 3 */ "abcccba"
+ /* 4 */ "abcccba"
+ /* 5 */ "abbbbba"
+ /* 6 */ "aaaaaaa"
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "abbbbba"
+ /* 2 */ "abcccba"
+ /* 3 */ "abcccba"
+ /* 4 */ "abcccba"
+ /* 5 */ "abbbbba"
+ /* 6 */ "aaaaaaa"
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "abbbbba"
+ /* 2 */ "abcccba"
+ /* 3 */ "abcccba"
+ /* 4 */ "abcccba"
+ /* 5 */ "abbbbba"
+ /* 6 */ "aaaaaaa"
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "abbbbba"
+ /* 2 */ "abcccba"
+ /* 3 */ "abcccba"
+ /* 4 */ "abcccba"
+ /* 5 */ "abbbbba"
+ /* 6 */ "aaaaaaa"
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "ddddddd"
+ /* 1 */ "dbbbbbd"
+ /* 2 */ "dbcccbd"
+ /* 3 */ "dbcccbd"
+ /* 4 */ "dbcccbd"
+ /* 5 */ "dbbbbbd"
+ /* 6 */ "ddddddd"
+
+ // Level 6
+ /* z\x* 0123456 */
+ /* 0 */ "ddddddd"
+ /* 1 */ "dbbbbbd"
+ /* 2 */ "dbcccbd"
+ /* 3 */ "dbcccbd"
+ /* 4 */ "dbcccbd"
+ /* 5 */ "dbbbbbd"
+ /* 6 */ "ddddddd"
+
+ // Level 7
+ /* z\x* 0123456 */
+ /* 0 */ "ddddddd"
+ /* 1 */ "dbbbbbd"
+ /* 2 */ "dbcccbd"
+ /* 3 */ "dbcccbd"
+ /* 4 */ "dbcccbd"
+ /* 5 */ "dbbbbbd"
+ /* 6 */ "ddddddd"
+
+ // Level 8
+ /* z\x* 0123456 */
+ /* 0 */ "eefffee"
+ /* 1 */ "ebbbbbe"
+ /* 2 */ "fbcccbf"
+ /* 3 */ "fbcccbf"
+ /* 4 */ "fbcccbf"
+ /* 5 */ "ebbbbbe"
+ /* 6 */ "eefffee"
+
+ // Level 9
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".bbbbb."
+ /* 2 */ ".b...b."
+ /* 3 */ ".b.g.b."
+ /* 4 */ ".b...b."
+ /* 5 */ ".bbbbb."
+ /* 6 */ "......."
+
+ // Level 10
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".h...h."
+ /* 2 */ "......."
+ /* 3 */ "...h..."
+ /* 4 */ "......."
+ /* 5 */ ".h...h."
+ /* 6 */ "......."
+
+ // Level 11
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".h...h."
+ /* 2 */ "......."
+ /* 3 */ "...h..."
+ /* 4 */ "......."
+ /* 5 */ ".h...h."
+ /* 6 */ "......."
+
+ // Level 12
+ /* z\x* 0123456 */
+ /* 0 */ "iiiiiii"
+ /* 1 */ "jkjjjkj"
+ /* 2 */ ".l...n."
+ /* 3 */ ".l.h.n."
+ /* 4 */ ".l...n."
+ /* 5 */ "okoooko"
+ /* 6 */ "ppppppp"
+
+ // Level 13
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "iiiiiii"
+ /* 2 */ "jkjjjkj"
+ /* 3 */ ".k.h.k."
+ /* 4 */ "okoooko"
+ /* 5 */ "ppppppp"
+ /* 6 */ "......."
+
+ // Level 14
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "......."
+ /* 2 */ "iiiiiii"
+ /* 3 */ "kkkkkkk"
+ /* 4 */ "ppppppp"
+ /* 5 */ "......."
+ /* 6 */ ".......",
+
+ // Connectors:
+ "2: 0, 9, 3: 4\n" /* Type 2, direction X- */
+ "2: 3, 9, 6: 3\n" /* Type 2, direction Z+ */
+ "2: 6, 9, 3: 5\n" /* Type 2, direction X+ */
+ "2: 3, 9, 0: 2\n" /* Type 2, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // RoofedWell
+};
+
+
+
+
+
+// The prefab counts:
+
+const size_t g_PlainsVillagePrefabsCount = ARRAYCOUNT(g_PlainsVillagePrefabs);
+
+const size_t g_PlainsVillageStartingPrefabsCount = ARRAYCOUNT(g_PlainsVillageStartingPrefabs);
+
diff --git a/src/Generating/Prefabs/PlainsVillagePrefabs.h b/src/Generating/Prefabs/PlainsVillagePrefabs.h
new file mode 100644
index 000000000..087783b1e
--- /dev/null
+++ b/src/Generating/Prefabs/PlainsVillagePrefabs.h
@@ -0,0 +1,15 @@
+
+// PlainsVillagePrefabs.h
+
+// Declares the prefabs in the group PlainsVillage
+
+#include "../Prefab.h"
+
+
+
+
+
+extern const cPrefab::sDef g_PlainsVillagePrefabs[];
+extern const cPrefab::sDef g_PlainsVillageStartingPrefabs[];
+extern const size_t g_PlainsVillagePrefabsCount;
+extern const size_t g_PlainsVillageStartingPrefabsCount;
diff --git a/src/Generating/Prefabs/RainbowRoadPrefabs.cpp b/src/Generating/Prefabs/RainbowRoadPrefabs.cpp
new file mode 100644
index 000000000..1a3765c5a
--- /dev/null
+++ b/src/Generating/Prefabs/RainbowRoadPrefabs.cpp
@@ -0,0 +1,1406 @@
+
+// RainbowRoadPrefabs.cpp
+
+// Defines the prefabs in the group RainbowRoad
+
+// NOTE: This file has been generated automatically by GalExport!
+// Any manual changes will be overwritten by the next automatic export!
+
+#include "Globals.h"
+#include "RainbowRoadPrefabs.h"
+
+
+
+
+
+const cPrefab::sDef g_RainbowRoadPrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CurveDouble:
+ // The data has been exported from the gallery Cube, area index 89, ID 467, created by Aloe_vera
+ {
+ // Size:
+ 14, 1, 14, // SizeX = 14, SizeY = 1, SizeZ = 14
+
+ // Hitbox (relative to bounding box):
+ 0, -2, 0, // MinX, MinY, MinZ
+ 13, 2, 13, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 35:11\n" /* wool */
+ "b: 35: 3\n" /* wool */
+ "c: 35: 5\n" /* wool */
+ "d: 35: 4\n" /* wool */
+ "e: 35: 1\n" /* wool */
+ "f: 35:14\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "aaaaaa........"
+ /* 1 */ "bbbbbba......."
+ /* 2 */ "cccccbbaaa...."
+ /* 3 */ "dddddccbbaa..."
+ /* 4 */ "eeeeeddccbaa.."
+ /* 5 */ "fffffeddccba.."
+ /* 6 */ "ffffffeedcbaa."
+ /* 7 */ "eeeefffeddcba."
+ /* 8 */ "dddeefffedcbba"
+ /* 9 */ "cccddefffedcba"
+ /* 10 */ "bbccdeeffedcba"
+ /* 11 */ "abbccdeffedcba"
+ /* 12 */ ".abbcdeffedcba"
+ /* 13 */ "..abcdeffedcba",
+
+ // Connectors:
+ "2: 2, 1, 13: 3\n" /* Type 2, direction Z+ */
+ "2: 0, 1, 0: 4\n" /* Type 2, direction X- */
+ "-2: 0, 1, 11: 4\n" /* Type -2, direction X- */
+ "-2: 13, 1, 13: 3\n" /* Type -2, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // CurveDouble
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CurveDownFromTopSingle:
+ // The data has been exported from the gallery Cube, area index 100, ID 478, created by Aloe_vera
+ {
+ // Size:
+ 11, 8, 11, // SizeX = 11, SizeY = 8, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ 0, -2, 0, // MinX, MinY, MinZ
+ 10, 9, 10, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 35:14\n" /* wool */
+ "b: 35: 5\n" /* wool */
+ "c: 35: 4\n" /* wool */
+ "d: 35: 1\n" /* wool */
+ "e: 35:11\n" /* wool */
+ "f: 35: 3\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ "..........."
+ /* 5 */ "..........."
+ /* 6 */ "..........."
+ /* 7 */ "..........."
+ /* 8 */ "..........a"
+ /* 9 */ ".......bcda"
+ /* 10 */ ".....efbcda"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ "..........."
+ /* 5 */ "..........."
+ /* 6 */ "........cda"
+ /* 7 */ ".......bcda"
+ /* 8 */ ".......bcd."
+ /* 9 */ ".....ef...."
+ /* 10 */ "..........."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ ".........a."
+ /* 5 */ ".......cdda"
+ /* 6 */ "......bc..."
+ /* 7 */ "......b...."
+ /* 8 */ ".....ff...."
+ /* 9 */ "....ee....."
+ /* 10 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "........aa."
+ /* 4 */ "......ccd.."
+ /* 5 */ ".....bb...."
+ /* 6 */ ".....f....."
+ /* 7 */ "....ef....."
+ /* 8 */ "....e......"
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "......daa.."
+ /* 3 */ ".....ccd..."
+ /* 4 */ "....bb....."
+ /* 5 */ "....f......"
+ /* 6 */ "...ef......"
+ /* 7 */ "...ee......"
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".....daa..."
+ /* 2 */ "...ccd....."
+ /* 3 */ "...bc......"
+ /* 4 */ "...b......."
+ /* 5 */ "..ff......."
+ /* 6 */ "..ee......."
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "...aaa....."
+ /* 1 */ "..ddd......"
+ /* 2 */ ".cc........"
+ /* 3 */ ".bb........"
+ /* 4 */ ".ff........"
+ /* 5 */ ".e........."
+ /* 6 */ ".ee........"
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 7
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "aaa........"
+ /* 1 */ "dd........."
+ /* 2 */ "cc........."
+ /* 3 */ "bb........."
+ /* 4 */ "ff........."
+ /* 5 */ "e.........."
+ /* 6 */ "..........."
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "...........",
+
+ // Connectors:
+ "-1: 0, 8, 5: 4\n" /* Type -1, direction X- */
+ "1: 5, 1, 10: 3\n" /* Type 1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // CurveDownFromTopSingle
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CurveSingle:
+ // The data has been exported from the gallery Cube, area index 84, ID 462, created by Aloe_vera
+ {
+ // Size:
+ 11, 1, 11, // SizeX = 11, SizeY = 1, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ 0, -2, 0, // MinX, MinY, MinZ
+ 10, 2, 10, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 35:14\n" /* wool */
+ "b: 35: 1\n" /* wool */
+ "c: 35: 4\n" /* wool */
+ "d: 35: 5\n" /* wool */
+ "e: 35: 3\n" /* wool */
+ "f: 35:11\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "aaaaaa....."
+ /* 1 */ "bbbbbbaa..."
+ /* 2 */ "cccccbbaa.."
+ /* 3 */ "ddddcccbaa."
+ /* 4 */ "eeedddccba."
+ /* 5 */ "ffeeeddcbba"
+ /* 6 */ ".fffeedccba"
+ /* 7 */ "...ffeddcba"
+ /* 8 */ "....feedcba"
+ /* 9 */ "....ffedcba"
+ /* 10 */ ".....fedcba",
+
+ // Connectors:
+ "-1: 0, 1, 5: 4\n" /* Type -1, direction X- */
+ "1: 5, 1, 10: 3\n" /* Type 1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // CurveSingle
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CurveSingleLeft:
+ // The data has been exported from the gallery Cube, area index 97, ID 475, created by Aloe_vera
+ {
+ // Size:
+ 11, 1, 11, // SizeX = 11, SizeY = 1, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ 0, -2, 0, // MinX, MinY, MinZ
+ 10, 2, 10, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 35:14\n" /* wool */
+ "b: 35: 1\n" /* wool */
+ "c: 35: 4\n" /* wool */
+ "d: 35: 5\n" /* wool */
+ "e: 35: 3\n" /* wool */
+ "f: 35:11\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ ".....abcdef"
+ /* 1 */ "....aabcdef"
+ /* 2 */ "....abbcdef"
+ /* 3 */ "...aabccdef"
+ /* 4 */ ".aaabbcddef"
+ /* 5 */ "aabbbccdeef"
+ /* 6 */ "bbbcccddef."
+ /* 7 */ "ccccdddeff."
+ /* 8 */ "dddddeeff.."
+ /* 9 */ "eeeeeeff..."
+ /* 10 */ "ffffff.....",
+
+ // Connectors:
+ "-1: 0, 1, 10: 4\n" /* Type -1, direction X- */
+ "1: 10, 1, 0: 2\n" /* Type 1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // CurveSingleLeft
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CurveUpDouble:
+ // The data has been exported from the gallery Cube, area index 92, ID 470, created by Aloe_vera
+ {
+ // Size:
+ 14, 8, 14, // SizeX = 14, SizeY = 8, SizeZ = 14
+
+ // Hitbox (relative to bounding box):
+ 0, -2, 0, // MinX, MinY, MinZ
+ 13, 9, 13, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 35:11\n" /* wool */
+ "b: 35: 3\n" /* wool */
+ "c: 35: 5\n" /* wool */
+ "d: 35: 4\n" /* wool */
+ "e: 35: 1\n" /* wool */
+ "f: 35:14\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "a............."
+ /* 1 */ "b............."
+ /* 2 */ "c............."
+ /* 3 */ "d............."
+ /* 4 */ "e............."
+ /* 5 */ "f............."
+ /* 6 */ "f............."
+ /* 7 */ "e............."
+ /* 8 */ "d............."
+ /* 9 */ "c............."
+ /* 10 */ "b............."
+ /* 11 */ "a............."
+ /* 12 */ ".............."
+ /* 13 */ ".............."
+
+ // Level 1
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".aa..........."
+ /* 1 */ ".bb..........."
+ /* 2 */ ".cc..........."
+ /* 3 */ ".dd..........."
+ /* 4 */ ".ee..........."
+ /* 5 */ ".f............"
+ /* 6 */ ".f............"
+ /* 7 */ ".e............"
+ /* 8 */ ".d............"
+ /* 9 */ ".c............"
+ /* 10 */ ".b............"
+ /* 11 */ ".b............"
+ /* 12 */ ".............."
+ /* 13 */ ".............."
+
+ // Level 2
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "...aaa........"
+ /* 1 */ "...bb........."
+ /* 2 */ "...cc........."
+ /* 3 */ "...dd........."
+ /* 4 */ "...ee........."
+ /* 5 */ "..ff.........."
+ /* 6 */ "..ff.........."
+ /* 7 */ "..ee.........."
+ /* 8 */ "..de.........."
+ /* 9 */ "..c..........."
+ /* 10 */ ".b............"
+ /* 11 */ ".b............"
+ /* 12 */ ".............."
+ /* 13 */ ".............."
+
+ // Level 3
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ ".....baa......"
+ /* 2 */ ".....bbaaa...."
+ /* 3 */ "....dccbba...."
+ /* 4 */ "....eddcc....."
+ /* 5 */ "....fedd......"
+ /* 6 */ "....ffee......"
+ /* 7 */ "....ff........"
+ /* 8 */ "....e........."
+ /* 9 */ "...dd........."
+ /* 10 */ "..cc.........."
+ /* 11 */ "..b..........."
+ /* 12 */ ".a............"
+ /* 13 */ ".............."
+
+ // Level 4
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ ".............."
+ /* 2 */ ".............."
+ /* 3 */ "..........a..."
+ /* 4 */ ".........ba..."
+ /* 5 */ "........cc...."
+ /* 6 */ ".......edc...."
+ /* 7 */ "......fedd...."
+ /* 8 */ ".....ff......."
+ /* 9 */ "....de........"
+ /* 10 */ "...cde........"
+ /* 11 */ "..b..........."
+ /* 12 */ ".a............"
+ /* 13 */ ".............."
+
+ // Level 5
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ ".............."
+ /* 2 */ ".............."
+ /* 3 */ ".............."
+ /* 4 */ "...........a.."
+ /* 5 */ "..........ba.."
+ /* 6 */ "..........baa."
+ /* 7 */ "..........cba."
+ /* 8 */ ".......fedcb.."
+ /* 9 */ "......fffed..."
+ /* 10 */ ".....eef......"
+ /* 11 */ "...ccd........"
+ /* 12 */ "..b..........."
+ /* 13 */ ".............."
+
+ // Level 6
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ ".............."
+ /* 2 */ ".............."
+ /* 3 */ ".............."
+ /* 4 */ ".............."
+ /* 5 */ ".............."
+ /* 6 */ ".............."
+ /* 7 */ ".............."
+ /* 8 */ "............ba"
+ /* 9 */ "...........cba"
+ /* 10 */ "........fedcba"
+ /* 11 */ "......effedc.."
+ /* 12 */ "..bbcdef......"
+ /* 13 */ "..a..........."
+
+ // Level 7
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ ".............."
+ /* 2 */ ".............."
+ /* 3 */ ".............."
+ /* 4 */ ".............."
+ /* 5 */ ".............."
+ /* 6 */ ".............."
+ /* 7 */ ".............."
+ /* 8 */ ".............."
+ /* 9 */ ".............."
+ /* 10 */ ".............."
+ /* 11 */ "............ba"
+ /* 12 */ "........fedcba"
+ /* 13 */ "..abcdeffedcba",
+
+ // Connectors:
+ "-2: 0, 1, 11: 4\n" /* Type -2, direction X- */
+ "2: 0, 1, 0: 4\n" /* Type 2, direction X- */
+ "2: 2, 8, 13: 3\n" /* Type 2, direction Z+ */
+ "-2: 13, 8, 13: 3\n" /* Type -2, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // CurveUpDouble
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CurveUpSingle:
+ // The data has been exported from the gallery Cube, area index 87, ID 465, created by Aloe_vera
+ {
+ // Size:
+ 11, 8, 11, // SizeX = 11, SizeY = 8, SizeZ = 11
+
+ // Hitbox (relative to bounding box):
+ 0, -2, 0, // MinX, MinY, MinZ
+ 10, 9, 10, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 35:14\n" /* wool */
+ "b: 35: 1\n" /* wool */
+ "c: 35: 4\n" /* wool */
+ "d: 35: 5\n" /* wool */
+ "e: 35: 3\n" /* wool */
+ "f: 35:11\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "aaa........"
+ /* 1 */ "bb........."
+ /* 2 */ "cc........."
+ /* 3 */ "dd........."
+ /* 4 */ "ee........."
+ /* 5 */ "f.........."
+ /* 6 */ "..........."
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "...aaa....."
+ /* 1 */ "..bbb......"
+ /* 2 */ ".cc........"
+ /* 3 */ ".dd........"
+ /* 4 */ ".ee........"
+ /* 5 */ ".f........."
+ /* 6 */ ".ff........"
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".....baa..."
+ /* 2 */ "...ccb....."
+ /* 3 */ "...dc......"
+ /* 4 */ "...d......."
+ /* 5 */ "..ee......."
+ /* 6 */ "..ff......."
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "......baa.."
+ /* 3 */ ".....ccb..."
+ /* 4 */ "....dd....."
+ /* 5 */ "....e......"
+ /* 6 */ "...fe......"
+ /* 7 */ "...ff......"
+ /* 8 */ "..........."
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "........aa."
+ /* 4 */ "......ccb.."
+ /* 5 */ ".....dd...."
+ /* 6 */ ".....e....."
+ /* 7 */ "....fe....."
+ /* 8 */ "....f......"
+ /* 9 */ "..........."
+ /* 10 */ "..........."
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ ".........a."
+ /* 5 */ ".......cbba"
+ /* 6 */ "......dc..."
+ /* 7 */ "......d...."
+ /* 8 */ ".....ee...."
+ /* 9 */ "....ff....."
+ /* 10 */ "..........."
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ "..........."
+ /* 5 */ "..........."
+ /* 6 */ "........cba"
+ /* 7 */ ".......dcba"
+ /* 8 */ ".......dcb."
+ /* 9 */ ".....fe...."
+ /* 10 */ ".....f....."
+
+ // Level 7
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "..........."
+ /* 4 */ "..........."
+ /* 5 */ "..........."
+ /* 6 */ "..........."
+ /* 7 */ "..........."
+ /* 8 */ "..........a"
+ /* 9 */ ".......dcba"
+ /* 10 */ ".....fedcba",
+
+ // Connectors:
+ "-1: 0, 1, 5: 4\n" /* Type -1, direction X- */
+ "1: 5, 8, 10: 3\n" /* Type 1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // CurveUpSingle
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SlopeDownFromTopSingle:
+ // The data has been exported from the gallery Cube, area index 98, ID 476, created by Aloe_vera
+ {
+ // Size:
+ 16, 8, 6, // SizeX = 16, SizeY = 8, SizeZ = 6
+
+ // Hitbox (relative to bounding box):
+ 0, -2, 0, // MinX, MinY, MinZ
+ 15, 9, 5, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 35:14\n" /* wool */
+ "b: 35: 1\n" /* wool */
+ "c: 35: 4\n" /* wool */
+ "d: 35: 5\n" /* wool */
+ "e: 35: 3\n" /* wool */
+ "f: 35:11\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "..............aa"
+ /* 1 */ "..............bb"
+ /* 2 */ "..............cc"
+ /* 3 */ "..............dd"
+ /* 4 */ "..............ee"
+ /* 5 */ "..............ff"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "............aa.."
+ /* 1 */ "............bb.."
+ /* 2 */ "............cc.."
+ /* 3 */ "............dd.."
+ /* 4 */ "............ee.."
+ /* 5 */ "............ff.."
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "..........aa...."
+ /* 1 */ "..........bb...."
+ /* 2 */ "..........cc...."
+ /* 3 */ "..........dd...."
+ /* 4 */ "..........ee...."
+ /* 5 */ "..........ff...."
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "........aa......"
+ /* 1 */ "........bb......"
+ /* 2 */ "........cc......"
+ /* 3 */ "........dd......"
+ /* 4 */ "........ee......"
+ /* 5 */ "........ff......"
+
+ // Level 4
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "......aa........"
+ /* 1 */ "......bb........"
+ /* 2 */ "......cc........"
+ /* 3 */ "......dd........"
+ /* 4 */ "......ee........"
+ /* 5 */ "......ff........"
+
+ // Level 5
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "....aa.........."
+ /* 1 */ "....bb.........."
+ /* 2 */ "....cc.........."
+ /* 3 */ "....dd.........."
+ /* 4 */ "....ee.........."
+ /* 5 */ "....ff.........."
+
+ // Level 6
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "..aa............"
+ /* 1 */ "..bb............"
+ /* 2 */ "..cc............"
+ /* 3 */ "..dd............"
+ /* 4 */ "..ee............"
+ /* 5 */ "..ff............"
+
+ // Level 7
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "aa.............."
+ /* 1 */ "bb.............."
+ /* 2 */ "cc.............."
+ /* 3 */ "dd.............."
+ /* 4 */ "ee.............."
+ /* 5 */ "ff..............",
+
+ // Connectors:
+ "-1: 0, 8, 5: 4\n" /* Type -1, direction X- */
+ "1: 15, 1, 5: 5\n" /* Type 1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // SlopeDownFromTopSingle
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SlopeUpDouble:
+ // The data has been exported from the gallery Cube, area index 90, ID 468, created by Aloe_vera
+ {
+ // Size:
+ 16, 8, 12, // SizeX = 16, SizeY = 8, SizeZ = 12
+
+ // Hitbox (relative to bounding box):
+ 0, -2, 0, // MinX, MinY, MinZ
+ 15, 9, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 35:11\n" /* wool */
+ "b: 35: 3\n" /* wool */
+ "c: 35: 5\n" /* wool */
+ "d: 35: 4\n" /* wool */
+ "e: 35: 1\n" /* wool */
+ "f: 35:14\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "aa.............."
+ /* 1 */ "bb.............."
+ /* 2 */ "cc.............."
+ /* 3 */ "dd.............."
+ /* 4 */ "ee.............."
+ /* 5 */ "ff.............."
+ /* 6 */ "ff.............."
+ /* 7 */ "ee.............."
+ /* 8 */ "dd.............."
+ /* 9 */ "cc.............."
+ /* 10 */ "bb.............."
+ /* 11 */ "aa.............."
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "..aa............"
+ /* 1 */ "..bb............"
+ /* 2 */ "..cc............"
+ /* 3 */ "..dd............"
+ /* 4 */ "..ee............"
+ /* 5 */ "..ff............"
+ /* 6 */ "..ff............"
+ /* 7 */ "..ee............"
+ /* 8 */ "..dd............"
+ /* 9 */ "..cc............"
+ /* 10 */ "..bb............"
+ /* 11 */ "..aa............"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "....aa.........."
+ /* 1 */ "....bb.........."
+ /* 2 */ "....cc.........."
+ /* 3 */ "....dd.........."
+ /* 4 */ "....ee.........."
+ /* 5 */ "....ff.........."
+ /* 6 */ "....ff.........."
+ /* 7 */ "....ee.........."
+ /* 8 */ "....dd.........."
+ /* 9 */ "....cc.........."
+ /* 10 */ "....bb.........."
+ /* 11 */ "....aa.........."
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "......aa........"
+ /* 1 */ "......bb........"
+ /* 2 */ "......cc........"
+ /* 3 */ "......dd........"
+ /* 4 */ "......ee........"
+ /* 5 */ "......ff........"
+ /* 6 */ "......ff........"
+ /* 7 */ "......ee........"
+ /* 8 */ "......dd........"
+ /* 9 */ "......cc........"
+ /* 10 */ "......bb........"
+ /* 11 */ "......aa........"
+
+ // Level 4
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "........aa......"
+ /* 1 */ "........bb......"
+ /* 2 */ "........cc......"
+ /* 3 */ "........dd......"
+ /* 4 */ "........ee......"
+ /* 5 */ "........ff......"
+ /* 6 */ "........ff......"
+ /* 7 */ "........ee......"
+ /* 8 */ "........dd......"
+ /* 9 */ "........cc......"
+ /* 10 */ "........bb......"
+ /* 11 */ "........aa......"
+
+ // Level 5
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "..........aa...."
+ /* 1 */ "..........bb...."
+ /* 2 */ "..........cc...."
+ /* 3 */ "..........dd...."
+ /* 4 */ "..........ee...."
+ /* 5 */ "..........ff...."
+ /* 6 */ "..........ff...."
+ /* 7 */ "..........ee...."
+ /* 8 */ "..........dd...."
+ /* 9 */ "..........cc...."
+ /* 10 */ "..........bb...."
+ /* 11 */ "..........aa...."
+
+ // Level 6
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "............aa.."
+ /* 1 */ "............bb.."
+ /* 2 */ "............cc.."
+ /* 3 */ "............dd.."
+ /* 4 */ "............ee.."
+ /* 5 */ "............ff.."
+ /* 6 */ "............ff.."
+ /* 7 */ "............ee.."
+ /* 8 */ "............dd.."
+ /* 9 */ "............cc.."
+ /* 10 */ "............bb.."
+ /* 11 */ "............aa.."
+
+ // Level 7
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "..............aa"
+ /* 1 */ "..............bb"
+ /* 2 */ "..............cc"
+ /* 3 */ "..............dd"
+ /* 4 */ "..............ee"
+ /* 5 */ "..............ff"
+ /* 6 */ "..............ff"
+ /* 7 */ "..............ee"
+ /* 8 */ "..............dd"
+ /* 9 */ "..............cc"
+ /* 10 */ "..............bb"
+ /* 11 */ "..............aa",
+
+ // Connectors:
+ "-2: 0, 1, 11: 4\n" /* Type -2, direction X- */
+ "2: 0, 1, 0: 4\n" /* Type 2, direction X- */
+ "-2: 15, 8, 0: 5\n" /* Type -2, direction X+ */
+ "2: 15, 8, 11: 5\n" /* Type 2, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // SlopeUpDouble
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SlopeUpSingle:
+ // The data has been exported from the gallery Cube, area index 85, ID 463, created by Aloe_vera
+ {
+ // Size:
+ 16, 8, 6, // SizeX = 16, SizeY = 8, SizeZ = 6
+
+ // Hitbox (relative to bounding box):
+ 0, -2, 0, // MinX, MinY, MinZ
+ 15, 9, 5, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 35:14\n" /* wool */
+ "b: 35: 1\n" /* wool */
+ "c: 35: 4\n" /* wool */
+ "d: 35: 5\n" /* wool */
+ "e: 35: 3\n" /* wool */
+ "f: 35:11\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "aa.............."
+ /* 1 */ "bb.............."
+ /* 2 */ "cc.............."
+ /* 3 */ "dd.............."
+ /* 4 */ "ee.............."
+ /* 5 */ "ff.............."
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "..aa............"
+ /* 1 */ "..bb............"
+ /* 2 */ "..cc............"
+ /* 3 */ "..dd............"
+ /* 4 */ "..ee............"
+ /* 5 */ "..ff............"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "....aa.........."
+ /* 1 */ "....bb.........."
+ /* 2 */ "....cc.........."
+ /* 3 */ "....dd.........."
+ /* 4 */ "....ee.........."
+ /* 5 */ "....ff.........."
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "......aa........"
+ /* 1 */ "......bb........"
+ /* 2 */ "......cc........"
+ /* 3 */ "......dd........"
+ /* 4 */ "......ee........"
+ /* 5 */ "......ff........"
+
+ // Level 4
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "........aa......"
+ /* 1 */ "........bb......"
+ /* 2 */ "........cc......"
+ /* 3 */ "........dd......"
+ /* 4 */ "........ee......"
+ /* 5 */ "........ff......"
+
+ // Level 5
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "..........aa...."
+ /* 1 */ "..........bb...."
+ /* 2 */ "..........cc...."
+ /* 3 */ "..........dd...."
+ /* 4 */ "..........ee...."
+ /* 5 */ "..........ff...."
+
+ // Level 6
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "............aa.."
+ /* 1 */ "............bb.."
+ /* 2 */ "............cc.."
+ /* 3 */ "............dd.."
+ /* 4 */ "............ee.."
+ /* 5 */ "............ff.."
+
+ // Level 7
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "..............aa"
+ /* 1 */ "..............bb"
+ /* 2 */ "..............cc"
+ /* 3 */ "..............dd"
+ /* 4 */ "..............ee"
+ /* 5 */ "..............ff",
+
+ // Connectors:
+ "-1: 0, 1, 5: 4\n" /* Type -1, direction X- */
+ "1: 15, 8, 5: 5\n" /* Type 1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ -1000,
+
+ // MoveToGround:
+ false,
+ }, // SlopeUpSingle
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SplitTee:
+ // The data has been exported from the gallery Cube, area index 93, ID 471, created by Aloe_vera
+ {
+ // Size:
+ 16, 1, 14, // SizeX = 16, SizeY = 1, SizeZ = 14
+
+ // Hitbox (relative to bounding box):
+ 0, -2, 0, // MinX, MinY, MinZ
+ 15, 2, 13, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 35:11\n" /* wool */
+ "b: 35: 3\n" /* wool */
+ "c: 35: 5\n" /* wool */
+ "d: 35: 4\n" /* wool */
+ "e: 35: 1\n" /* wool */
+ "f: 35:14\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "aaaaaa.........."
+ /* 1 */ "bbbbbbaaa......."
+ /* 2 */ "ccccccbbbaaa...."
+ /* 3 */ "ddddddcccbbbaaaa"
+ /* 4 */ "eeeeeedddcccbbbb"
+ /* 5 */ "ffffffeeedddcccc"
+ /* 6 */ "fffffffffeeedddd"
+ /* 7 */ "eeeeff...fffeeee"
+ /* 8 */ "dddeeff.....ffff"
+ /* 9 */ "cccddeff........"
+ /* 10 */ "bbbccdeef......."
+ /* 11 */ "aaabbcddef......"
+ /* 12 */ "...aabcddef....."
+ /* 13 */ ".....abcdef.....",
+
+ // Connectors:
+ "-2: 0, 1, 11: 4\n" /* Type -2, direction X- */
+ "2: 0, 1, 0: 4\n" /* Type 2, direction X- */
+ "-1: 15, 1, 3: 5\n" /* Type -1, direction X+ */
+ "1: 5, 1, 13: 3\n" /* Type 1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // SplitTee
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // StraightDouble:
+ // The data has been exported from the gallery Cube, area index 88, ID 466, created by Aloe_vera
+ {
+ // Size:
+ 16, 1, 12, // SizeX = 16, SizeY = 1, SizeZ = 12
+
+ // Hitbox (relative to bounding box):
+ 0, -2, 0, // MinX, MinY, MinZ
+ 15, 2, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 35:11\n" /* wool */
+ "b: 35: 3\n" /* wool */
+ "c: 35: 5\n" /* wool */
+ "d: 35: 4\n" /* wool */
+ "e: 35: 1\n" /* wool */
+ "f: 35:14\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "aaaaaaaaaaaaaaaa"
+ /* 1 */ "bbbbbbbbbbbbbbbb"
+ /* 2 */ "cccccccccccccccc"
+ /* 3 */ "dddddddddddddddd"
+ /* 4 */ "eeeeeeeeeeeeeeee"
+ /* 5 */ "ffffffffffffffff"
+ /* 6 */ "ffffffffffffffff"
+ /* 7 */ "eeeeeeeeeeeeeeee"
+ /* 8 */ "dddddddddddddddd"
+ /* 9 */ "cccccccccccccccc"
+ /* 10 */ "bbbbbbbbbbbbbbbb"
+ /* 11 */ "aaaaaaaaaaaaaaaa",
+
+ // Connectors:
+ "-2: 0, 1, 11: 4\n" /* Type -2, direction X- */
+ "2: 0, 1, 0: 4\n" /* Type 2, direction X- */
+ "-2: 15, 1, 0: 5\n" /* Type -2, direction X+ */
+ "2: 15, 1, 11: 5\n" /* Type 2, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // StraightDouble
+}; // g_RainbowRoadPrefabs
+
+
+
+
+
+
+const cPrefab::sDef g_RainbowRoadStartingPrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // StraightSingle:
+ // The data has been exported from the gallery Cube, area index 83, ID 461, created by Aloe_vera
+ {
+ // Size:
+ 16, 1, 6, // SizeX = 16, SizeY = 1, SizeZ = 6
+
+ // Hitbox (relative to bounding box):
+ 0, -2, 0, // MinX, MinY, MinZ
+ 15, 2, 5, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 35:14\n" /* wool */
+ "b: 35: 1\n" /* wool */
+ "c: 35: 4\n" /* wool */
+ "d: 35: 5\n" /* wool */
+ "e: 35: 3\n" /* wool */
+ "f: 35:11\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "aaaaaaaaaaaaaaaa"
+ /* 1 */ "bbbbbbbbbbbbbbbb"
+ /* 2 */ "cccccccccccccccc"
+ /* 3 */ "dddddddddddddddd"
+ /* 4 */ "eeeeeeeeeeeeeeee"
+ /* 5 */ "ffffffffffffffff",
+
+ // Connectors:
+ "-1: 0, 1, 5: 4\n" /* Type -1, direction X- */
+ "1: 15, 1, 5: 5\n" /* Type 1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ false,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 500,
+
+ // MoveToGround:
+ false,
+ }, // StraightSingle
+};
+
+
+
+
+
+// The prefab counts:
+
+const size_t g_RainbowRoadPrefabsCount = ARRAYCOUNT(g_RainbowRoadPrefabs);
+
+const size_t g_RainbowRoadStartingPrefabsCount = ARRAYCOUNT(g_RainbowRoadStartingPrefabs);
+
diff --git a/src/Generating/Prefabs/RainbowRoadPrefabs.h b/src/Generating/Prefabs/RainbowRoadPrefabs.h
new file mode 100644
index 000000000..ab0a0fbb2
--- /dev/null
+++ b/src/Generating/Prefabs/RainbowRoadPrefabs.h
@@ -0,0 +1,15 @@
+
+// RainbowRoadPrefabs.h
+
+// Declares the prefabs in the group RainbowRoad
+
+#include "../Prefab.h"
+
+
+
+
+
+extern const cPrefab::sDef g_RainbowRoadPrefabs[];
+extern const cPrefab::sDef g_RainbowRoadStartingPrefabs[];
+extern const size_t g_RainbowRoadPrefabsCount;
+extern const size_t g_RainbowRoadStartingPrefabsCount;
diff --git a/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp b/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp
new file mode 100644
index 000000000..eb01cf59e
--- /dev/null
+++ b/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp
@@ -0,0 +1,1651 @@
+
+// SandFlatRoofVillagePrefabs.cpp
+
+// Defines the prefabs in the group SandFlatRoofVillage
+
+// NOTE: This file has been generated automatically by GalExport!
+// Any manual changes will be overwritten by the next automatic export!
+
+#include "Globals.h"
+#include "SandFlatRoofVillagePrefabs.h"
+
+
+
+
+
+const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Forge:
+ // The data has been exported from the gallery Desert, area index 32, ID 173, created by Aloe_vera
+ {
+ // Size:
+ 12, 6, 10, // SizeX = 12, SizeY = 6, SizeZ = 10
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 11, 5, 9, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
+ "e:128: 3\n" /* sandstonestairs */
+ "f:171:15\n" /* carpet */
+ "g: 64: 6\n" /* wooddoorblock */
+ "h:171: 0\n" /* carpet */
+ "i:171:14\n" /* carpet */
+ "j: 61: 2\n" /* furnace */
+ "k: 10: 0\n" /* lava */
+ "l: 54: 2\n" /* chest */
+ "m: 19: 0\n" /* sponge */
+ "n: 24: 2\n" /* sandstone */
+ "o: 64:12\n" /* wooddoorblock */
+ "p: 50: 1\n" /* torch */
+ "q:101: 0\n" /* ironbars */
+ "r:128: 4\n" /* sandstonestairs */
+ "s:128: 6\n" /* sandstonestairs */
+ "t:128: 5\n" /* sandstonestairs */
+ "u:128: 7\n" /* sandstonestairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "aaaaaaammmmm"
+ /* 1 */ "aaaaaaaaaaam"
+ /* 2 */ "aaaaaaaaaaam"
+ /* 3 */ "aaaaaaaaaaam"
+ /* 4 */ "aaaaaaaaaaam"
+ /* 5 */ "aaaaaaaaaaam"
+ /* 6 */ "maaaaaaaaaam"
+ /* 7 */ "maaaaaaaaaam"
+ /* 8 */ "maaaaaaaaaam"
+ /* 9 */ "mmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "bcccccd....."
+ /* 1 */ "baaaaaaaaaa."
+ /* 2 */ "baaaaaaaaaa."
+ /* 3 */ "baaaaaaaaaa."
+ /* 4 */ "baaaaaaaaaa."
+ /* 5 */ "eaaaaaaaaaa."
+ /* 6 */ ".aaaaaaaaaa."
+ /* 7 */ ".aaaaaaaaaa."
+ /* 8 */ ".aaaaaaaaaa."
+ /* 9 */ "............"
+
+ // Level 2
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ ".a....aaaaa."
+ /* 2 */ "......afffa."
+ /* 3 */ "......ghfha."
+ /* 4 */ "......aiiia."
+ /* 5 */ ".a....ahfha."
+ /* 6 */ ".ajaajafffa."
+ /* 7 */ ".aakkaal..a."
+ /* 8 */ ".aaaaaaaaaa."
+ /* 9 */ "............"
+
+ // Level 3
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ ".n....nn.nn."
+ /* 2 */ "......n...n."
+ /* 3 */ "......o...n."
+ /* 4 */ "......n....."
+ /* 5 */ ".n....n...n."
+ /* 6 */ ".n....n...n."
+ /* 7 */ ".n....n...n."
+ /* 8 */ ".nnn.nnn.nn."
+ /* 9 */ "............"
+
+ // Level 4
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "............"
+ /* 1 */ ".a....aaaaa."
+ /* 2 */ "......a...a."
+ /* 3 */ "......a...a."
+ /* 4 */ "......ap..a."
+ /* 5 */ ".a....a...a."
+ /* 6 */ ".aqqqqa...a."
+ /* 7 */ ".a....a...a."
+ /* 8 */ ".aaaaaaaaaa."
+ /* 9 */ "............"
+
+ // Level 5
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "rsssssssssss"
+ /* 1 */ "raaaaaaaaaat"
+ /* 2 */ "raaaaaaaaaat"
+ /* 3 */ "raaaaaaaaaat"
+ /* 4 */ "raaaaaaaaaat"
+ /* 5 */ "raaaaaaaaaat"
+ /* 6 */ "raaaaaaaaaat"
+ /* 7 */ "raaaaaaaaaat"
+ /* 8 */ "raaaaaaaaaat"
+ /* 9 */ "uuuuuuuuuuut",
+
+ // Connectors:
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // Forge
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House11x7:
+ // The data has been exported from the gallery Desert, area index 31, ID 172, created by Aloe_vera
+ {
+ // Size:
+ 13, 6, 9, // SizeX = 13, SizeY = 6, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 12, 5, 8, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:171: 0\n" /* carpet */
+ "g:171:15\n" /* carpet */
+ "h:171:14\n" /* carpet */
+ "i: 24: 2\n" /* sandstone */
+ "j: 64:12\n" /* wooddoorblock */
+ "k: 50: 3\n" /* torch */
+ "l: 50: 1\n" /* torch */
+ "m: 19: 0\n" /* sponge */
+ "n: 50: 2\n" /* torch */
+ "o: 50: 4\n" /* torch */
+ "p:128: 4\n" /* sandstonestairs */
+ "q:128: 6\n" /* sandstonestairs */
+ "r:128: 5\n" /* sandstonestairs */
+ "s:128: 7\n" /* sandstonestairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "mmaaammmmmmmm"
+ /* 1 */ "maaaaaaaaaaam"
+ /* 2 */ "maaaaaaaaaaam"
+ /* 3 */ "maaaaaaaaaaam"
+ /* 4 */ "maaaaaaaaaaam"
+ /* 5 */ "maaaaaaaaaaam"
+ /* 6 */ "maaaaaaaaaaam"
+ /* 7 */ "maaaaaaaaaaam"
+ /* 8 */ "mmmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "..bcd........"
+ /* 1 */ ".aaaaaaaaaaa."
+ /* 2 */ ".aaaaaaaaaaa."
+ /* 3 */ ".aaaaaaaaaaa."
+ /* 4 */ ".aaaaaaaaaaa."
+ /* 5 */ ".aaaaaaaaaaa."
+ /* 6 */ ".aaaaaaaaaaa."
+ /* 7 */ ".aaaaaaaaaaa."
+ /* 8 */ "............."
+
+ // Level 2
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ ".aaeaaaaaaaa."
+ /* 2 */ ".affgggggffa."
+ /* 3 */ ".afghhhhhgfa."
+ /* 4 */ ".afghfffhgfa."
+ /* 5 */ ".afghhhhhgfa."
+ /* 6 */ ".affgggggffa."
+ /* 7 */ ".aaaaaaaaaaa."
+ /* 8 */ "............."
+
+ // Level 3
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ ".iiji.iii.ii."
+ /* 2 */ ".i.........i."
+ /* 3 */ ".i.........i."
+ /* 4 */ "............."
+ /* 5 */ ".i.........i."
+ /* 6 */ ".i.........i."
+ /* 7 */ ".ii.ii.ii.ii."
+ /* 8 */ "............."
+
+ // Level 4
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ ".aaaaaaaaaaa."
+ /* 2 */ ".a..k..k...a."
+ /* 3 */ ".a.........a."
+ /* 4 */ ".al.......na."
+ /* 5 */ ".a.........a."
+ /* 6 */ ".a....o....a."
+ /* 7 */ ".aaaaaaaaaaa."
+ /* 8 */ "............."
+
+ // Level 5
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "pqqqqqqqqqqqq"
+ /* 1 */ "paaaaaaaaaaar"
+ /* 2 */ "paaaaaaaaaaar"
+ /* 3 */ "paaaaaaaaaaar"
+ /* 4 */ "paaaaaaaaaaar"
+ /* 5 */ "paaaaaaaaaaar"
+ /* 6 */ "paaaaaaaaaaar"
+ /* 7 */ "paaaaaaaaaaar"
+ /* 8 */ "ssssssssssssr",
+
+ // Connectors:
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House11x7
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House5x4:
+ // The data has been exported from the gallery Desert, area index 25, ID 166, created by Aloe_vera
+ {
+ // Size:
+ 7, 6, 6, // SizeX = 7, SizeY = 6, SizeZ = 6
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 5, 5, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:171: 0\n" /* carpet */
+ "g:171:14\n" /* carpet */
+ "h: 24: 2\n" /* sandstone */
+ "i: 64:12\n" /* wooddoorblock */
+ "j: 50: 3\n" /* torch */
+ "k:128: 4\n" /* sandstonestairs */
+ "l:128: 6\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */
+ "n:128: 5\n" /* sandstonestairs */
+ "o:128: 7\n" /* sandstonestairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "mmaaamm"
+ /* 1 */ "maaaaam"
+ /* 2 */ "maaaaam"
+ /* 3 */ "maaaaam"
+ /* 4 */ "maaaaam"
+ /* 5 */ "mmmmmmm"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "..bcd.."
+ /* 1 */ ".aaaaa."
+ /* 2 */ ".aaaaa."
+ /* 3 */ ".aaaaa."
+ /* 4 */ ".aaaaa."
+ /* 5 */ "......."
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".aaeaa."
+ /* 2 */ ".afgfa."
+ /* 3 */ ".afgfa."
+ /* 4 */ ".aaaaa."
+ /* 5 */ "......."
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".hhihh."
+ /* 2 */ ".h...h."
+ /* 3 */ ".h...h."
+ /* 4 */ ".hh.hh."
+ /* 5 */ "......."
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".aaaaa."
+ /* 2 */ ".aj.ja."
+ /* 3 */ ".a...a."
+ /* 4 */ ".aaaaa."
+ /* 5 */ "......."
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "kllllln"
+ /* 1 */ "kaaaaan"
+ /* 2 */ "kaaaaan"
+ /* 3 */ "kaaaaan"
+ /* 4 */ "kaaaaan"
+ /* 5 */ "oooooon",
+
+ // Connectors:
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House5x4
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House5x5:
+ // The data has been exported from the gallery Desert, area index 26, ID 167, created by Aloe_vera
+ {
+ // Size:
+ 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 5, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:171: 0\n" /* carpet */
+ "g:171:15\n" /* carpet */
+ "h:171:14\n" /* carpet */
+ "i: 24: 2\n" /* sandstone */
+ "j: 64:12\n" /* wooddoorblock */
+ "k: 50: 3\n" /* torch */
+ "l:128: 4\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */
+ "n:128: 6\n" /* sandstonestairs */
+ "o:128: 5\n" /* sandstonestairs */
+ "p:128: 7\n" /* sandstonestairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "mmaaamm"
+ /* 1 */ "maaaaam"
+ /* 2 */ "maaaaam"
+ /* 3 */ "maaaaam"
+ /* 4 */ "maaaaam"
+ /* 5 */ "maaaaam"
+ /* 6 */ "mmmmmmm"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "..bcd.."
+ /* 1 */ ".aaaaa."
+ /* 2 */ ".aaaaa."
+ /* 3 */ ".aaaaa."
+ /* 4 */ ".aaaaa."
+ /* 5 */ ".aaaaa."
+ /* 6 */ "......."
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".aaeaa."
+ /* 2 */ ".afffa."
+ /* 3 */ ".aghga."
+ /* 4 */ ".afffa."
+ /* 5 */ ".aaaaa."
+ /* 6 */ "......."
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".iijii."
+ /* 2 */ ".i...i."
+ /* 3 */ "......."
+ /* 4 */ ".i...i."
+ /* 5 */ ".ii.ii."
+ /* 6 */ "......."
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".aaaaa."
+ /* 2 */ ".ak.ka."
+ /* 3 */ ".a...a."
+ /* 4 */ ".a...a."
+ /* 5 */ ".aaaaa."
+ /* 6 */ "......."
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "lnnnnno"
+ /* 1 */ "laaaaao"
+ /* 2 */ "laaaaao"
+ /* 3 */ "laaaaao"
+ /* 4 */ "laaaaao"
+ /* 5 */ "laaaaao"
+ /* 6 */ "ppppppo",
+
+ // Connectors:
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House5x5
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House7x5:
+ // The data has been exported from the gallery Desert, area index 27, ID 168, created by Aloe_vera
+ {
+ // Size:
+ 9, 6, 7, // SizeX = 9, SizeY = 6, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 8, 5, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:171:14\n" /* carpet */
+ "g:171: 0\n" /* carpet */
+ "h:171:15\n" /* carpet */
+ "i: 24: 2\n" /* sandstone */
+ "j: 64:12\n" /* wooddoorblock */
+ "k: 50: 3\n" /* torch */
+ "l:128: 4\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */
+ "n:128: 6\n" /* sandstonestairs */
+ "o:128: 5\n" /* sandstonestairs */
+ "p:128: 7\n" /* sandstonestairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 012345678 */
+ /* 0 */ "mmaaammmm"
+ /* 1 */ "maaaaaaam"
+ /* 2 */ "maaaaaaam"
+ /* 3 */ "maaaaaaam"
+ /* 4 */ "maaaaaaam"
+ /* 5 */ "maaaaaaam"
+ /* 6 */ "mmmmmmmmm"
+
+ // Level 1
+ /* z\x* 012345678 */
+ /* 0 */ "..bcd...."
+ /* 1 */ ".aaaaaaa."
+ /* 2 */ ".aaaaaaa."
+ /* 3 */ ".aaaaaaa."
+ /* 4 */ ".aaaaaaa."
+ /* 5 */ ".aaaaaaa."
+ /* 6 */ "........."
+
+ // Level 2
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ ".aaeaaaa."
+ /* 2 */ ".afffffa."
+ /* 3 */ ".aghhhga."
+ /* 4 */ ".afffffa."
+ /* 5 */ ".aaaaaaa."
+ /* 6 */ "........."
+
+ // Level 3
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ ".iiji.ii."
+ /* 2 */ ".i.....i."
+ /* 3 */ "........."
+ /* 4 */ ".i.....i."
+ /* 5 */ ".iii.iii."
+ /* 6 */ "........."
+
+ // Level 4
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ ".aaaaaaa."
+ /* 2 */ ".ak.k..a."
+ /* 3 */ ".a.....a."
+ /* 4 */ ".a.....a."
+ /* 5 */ ".aaaaaaa."
+ /* 6 */ "........."
+
+ // Level 5
+ /* z\x* 012345678 */
+ /* 0 */ "lnnnnnnnn"
+ /* 1 */ "laaaaaaao"
+ /* 2 */ "laaaaaaao"
+ /* 3 */ "laaaaaaao"
+ /* 4 */ "laaaaaaao"
+ /* 5 */ "laaaaaaao"
+ /* 6 */ "ppppppppo",
+
+ // Connectors:
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House7x5
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House8x5:
+ // The data has been exported from the gallery Desert, area index 28, ID 169, created by Aloe_vera
+ {
+ // Size:
+ 10, 6, 7, // SizeX = 10, SizeY = 6, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 9, 5, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:171: 0\n" /* carpet */
+ "g:171:14\n" /* carpet */
+ "h:171:15\n" /* carpet */
+ "i: 24: 2\n" /* sandstone */
+ "j: 64:12\n" /* wooddoorblock */
+ "k: 50: 3\n" /* torch */
+ "l:128: 4\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */
+ "n:128: 6\n" /* sandstonestairs */
+ "o:128: 5\n" /* sandstonestairs */
+ "p:128: 7\n" /* sandstonestairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "mmaaammmmm"
+ /* 1 */ "maaaaaaaam"
+ /* 2 */ "maaaaaaaam"
+ /* 3 */ "maaaaaaaam"
+ /* 4 */ "maaaaaaaam"
+ /* 5 */ "maaaaaaaam"
+ /* 6 */ "mmmmmmmmmm"
+
+ // Level 1
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "..bcd....."
+ /* 1 */ ".aaaaaaaa."
+ /* 2 */ ".aaaaaaaa."
+ /* 3 */ ".aaaaaaaa."
+ /* 4 */ ".aaaaaaaa."
+ /* 5 */ ".aaaaaaaa."
+ /* 6 */ ".........."
+
+ // Level 2
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".........."
+ /* 1 */ ".aaeaaaaa."
+ /* 2 */ ".afghhgfa."
+ /* 3 */ ".afhffhfa."
+ /* 4 */ ".afghhgfa."
+ /* 5 */ ".aaaaaaaa."
+ /* 6 */ ".........."
+
+ // Level 3
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".........."
+ /* 1 */ ".iijii.ii."
+ /* 2 */ ".i......i."
+ /* 3 */ ".........."
+ /* 4 */ ".i......i."
+ /* 5 */ ".ii.ii.ii."
+ /* 6 */ ".........."
+
+ // Level 4
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".........."
+ /* 1 */ ".aaaaaaaa."
+ /* 2 */ ".ak.k...a."
+ /* 3 */ ".a......a."
+ /* 4 */ ".a......a."
+ /* 5 */ ".aaaaaaaa."
+ /* 6 */ ".........."
+
+ // Level 5
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "lnnnnnnnnn"
+ /* 1 */ "laaaaaaaao"
+ /* 2 */ "laaaaaaaao"
+ /* 3 */ "laaaaaaaao"
+ /* 4 */ "laaaaaaaao"
+ /* 5 */ "laaaaaaaao"
+ /* 6 */ "pppppppppo",
+
+ // Connectors:
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House8x5
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House8x7:
+ // The data has been exported from the gallery Desert, area index 29, ID 170, created by Aloe_vera
+ {
+ // Size:
+ 10, 6, 9, // SizeX = 10, SizeY = 6, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 9, 5, 8, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:171: 0\n" /* carpet */
+ "g:171:14\n" /* carpet */
+ "h:171:15\n" /* carpet */
+ "i: 24: 2\n" /* sandstone */
+ "j: 64:12\n" /* wooddoorblock */
+ "k: 50: 3\n" /* torch */
+ "l: 50: 1\n" /* torch */
+ "m: 19: 0\n" /* sponge */
+ "n: 50: 2\n" /* torch */
+ "o:128: 4\n" /* sandstonestairs */
+ "p:128: 6\n" /* sandstonestairs */
+ "q:128: 5\n" /* sandstonestairs */
+ "r:128: 7\n" /* sandstonestairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "mmaaammmmm"
+ /* 1 */ "maaaaaaaam"
+ /* 2 */ "maaaaaaaam"
+ /* 3 */ "maaaaaaaam"
+ /* 4 */ "maaaaaaaam"
+ /* 5 */ "maaaaaaaam"
+ /* 6 */ "maaaaaaaam"
+ /* 7 */ "maaaaaaaam"
+ /* 8 */ "mmmmmmmmmm"
+
+ // Level 1
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "..bcd....."
+ /* 1 */ ".aaaaaaaa."
+ /* 2 */ ".aaaaaaaa."
+ /* 3 */ ".aaaaaaaa."
+ /* 4 */ ".aaaaaaaa."
+ /* 5 */ ".aaaaaaaa."
+ /* 6 */ ".aaaaaaaa."
+ /* 7 */ ".aaaaaaaa."
+ /* 8 */ ".........."
+
+ // Level 2
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".........."
+ /* 1 */ ".aaeaaaaa."
+ /* 2 */ ".afghhgfa."
+ /* 3 */ ".afhffhfa."
+ /* 4 */ ".afhgghfa."
+ /* 5 */ ".afhffhfa."
+ /* 6 */ ".afghhgfa."
+ /* 7 */ ".aaaaaaaa."
+ /* 8 */ ".........."
+
+ // Level 3
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".........."
+ /* 1 */ ".iijii.ii."
+ /* 2 */ ".i......i."
+ /* 3 */ ".i......i."
+ /* 4 */ ".........."
+ /* 5 */ ".i......i."
+ /* 6 */ ".i......i."
+ /* 7 */ ".ii.ii.ii."
+ /* 8 */ ".........."
+
+ // Level 4
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ ".........."
+ /* 1 */ ".aaaaaaaa."
+ /* 2 */ ".a..k...a."
+ /* 3 */ ".a......a."
+ /* 4 */ ".al....na."
+ /* 5 */ ".a......a."
+ /* 6 */ ".a......a."
+ /* 7 */ ".aaaaaaaa."
+ /* 8 */ ".........."
+
+ // Level 5
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "oppppppppp"
+ /* 1 */ "oaaaaaaaaq"
+ /* 2 */ "oaaaaaaaaq"
+ /* 3 */ "oaaaaaaaaq"
+ /* 4 */ "oaaaaaaaaq"
+ /* 5 */ "oaaaaaaaaq"
+ /* 6 */ "oaaaaaaaaq"
+ /* 7 */ "oaaaaaaaaq"
+ /* 8 */ "rrrrrrrrrq",
+
+ // Connectors:
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House8x7
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House9x7:
+ // The data has been exported from the gallery Desert, area index 30, ID 171, created by Aloe_vera
+ {
+ // Size:
+ 11, 6, 9, // SizeX = 11, SizeY = 6, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 10, 5, 8, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 0\n" /* sandstonestairs */
+ "c:128: 2\n" /* sandstonestairs */
+ "d:128: 1\n" /* sandstonestairs */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:171: 0\n" /* carpet */
+ "g:171:15\n" /* carpet */
+ "h:171:14\n" /* carpet */
+ "i: 24: 2\n" /* sandstone */
+ "j: 64:12\n" /* wooddoorblock */
+ "k: 50: 3\n" /* torch */
+ "l: 50: 1\n" /* torch */
+ "m: 19: 0\n" /* sponge */
+ "n: 50: 2\n" /* torch */
+ "o: 50: 4\n" /* torch */
+ "p:128: 4\n" /* sandstonestairs */
+ "q:128: 6\n" /* sandstonestairs */
+ "r:128: 5\n" /* sandstonestairs */
+ "s:128: 7\n" /* sandstonestairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "mmaaammmmmm"
+ /* 1 */ "maaaaaaaaam"
+ /* 2 */ "maaaaaaaaam"
+ /* 3 */ "maaaaaaaaam"
+ /* 4 */ "maaaaaaaaam"
+ /* 5 */ "maaaaaaaaam"
+ /* 6 */ "maaaaaaaaam"
+ /* 7 */ "maaaaaaaaam"
+ /* 8 */ "mmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..bcd......"
+ /* 1 */ ".aaaaaaaaa."
+ /* 2 */ ".aaaaaaaaa."
+ /* 3 */ ".aaaaaaaaa."
+ /* 4 */ ".aaaaaaaaa."
+ /* 5 */ ".aaaaaaaaa."
+ /* 6 */ ".aaaaaaaaa."
+ /* 7 */ ".aaaaaaaaa."
+ /* 8 */ "..........."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".aaeaaaaaa."
+ /* 2 */ ".affgggffa."
+ /* 3 */ ".afghhhgfa."
+ /* 4 */ ".afghfhgfa."
+ /* 5 */ ".afghhhgfa."
+ /* 6 */ ".affgggffa."
+ /* 7 */ ".aaaaaaaaa."
+ /* 8 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".iijii.iii."
+ /* 2 */ ".i.......i."
+ /* 3 */ ".i.......i."
+ /* 4 */ "..........."
+ /* 5 */ ".i.......i."
+ /* 6 */ ".i.......i."
+ /* 7 */ ".ii.iii.ii."
+ /* 8 */ "..........."
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".aaaaaaaaa."
+ /* 2 */ ".a..k....a."
+ /* 3 */ ".a.......a."
+ /* 4 */ ".al.....na."
+ /* 5 */ ".a.......a."
+ /* 6 */ ".a...o...a."
+ /* 7 */ ".aaaaaaaaa."
+ /* 8 */ "..........."
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "pqqqqqqqqqq"
+ /* 1 */ "paaaaaaaaar"
+ /* 2 */ "paaaaaaaaar"
+ /* 3 */ "paaaaaaaaar"
+ /* 4 */ "paaaaaaaaar"
+ /* 5 */ "paaaaaaaaar"
+ /* 6 */ "paaaaaaaaar"
+ /* 7 */ "paaaaaaaaar"
+ /* 8 */ "ssssssssssr",
+
+ // Connectors:
+ "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House9x7
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HouseL13x12:
+ // The data has been exported from the gallery Desert, area index 53, ID 345, created by jakibaki
+ {
+ // Size:
+ 15, 5, 14, // SizeX = 15, SizeY = 5, SizeZ = 14
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 14, 4, 13, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:128: 0\n" /* sandstonestairs */
+ "b:128: 2\n" /* sandstonestairs */
+ "c:128: 1\n" /* sandstonestairs */
+ "d: 24: 0\n" /* sandstone */
+ "e: 43: 1\n" /* doubleslab */
+ "f: 64: 7\n" /* wooddoorblock */
+ "g:171: 0\n" /* carpet */
+ "h:171:15\n" /* carpet */
+ "i:171:14\n" /* carpet */
+ "j: 58: 0\n" /* workbench */
+ "k: 24: 2\n" /* sandstone */
+ "l: 64:12\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */
+ "n: 50: 3\n" /* torch */
+ "o: 50: 1\n" /* torch */
+ "p: 50: 2\n" /* torch */
+ "q: 50: 4\n" /* torch */
+ "r:128: 6\n" /* sandstonestairs */
+ "s:128: 5\n" /* sandstonestairs */
+ "t:128: 4\n" /* sandstonestairs */
+ "u:128: 7\n" /* sandstonestairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "...abc........."
+ /* 1 */ ".ddddddddddddd."
+ /* 2 */ ".ddddddddddddd."
+ /* 3 */ ".ddddddddddddd."
+ /* 4 */ ".ddddddddddddd."
+ /* 5 */ ".ddddddddddded."
+ /* 6 */ ".ddddddddddddd."
+ /* 7 */ ".ddddddddddddd."
+ /* 8 */ ".......deddddd."
+ /* 9 */ "mmmmmm.ddddddd."
+ /* 10 */ "mmmmmm.ddddddd."
+ /* 11 */ "mmmmmm.ddddddd."
+ /* 12 */ "mmmmmm.ddddddd."
+ /* 13 */ "..............."
+
+ // Level 1
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".dddfddddddddd."
+ /* 2 */ ".dgghhhhhhhhgd."
+ /* 3 */ ".dghiiiiiiiihd."
+ /* 4 */ ".dghiggggggihd."
+ /* 5 */ ".dghiiiiiigihd."
+ /* 6 */ ".dgghhhhhigihd."
+ /* 7 */ ".dddddddhigihd."
+ /* 8 */ ".......dhigihd."
+ /* 9 */ "mmmmmm.dhiiihd."
+ /* 10 */ "mmmmmm.dghhhgd."
+ /* 11 */ "mmmmmm.dggggjd."
+ /* 12 */ "mmmmmm.ddddddd."
+ /* 13 */ "..............."
+
+ // Level 2
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".kkklkkkk.kkkk."
+ /* 2 */ ".k...........k."
+ /* 3 */ ".k...........k."
+ /* 4 */ "..............."
+ /* 5 */ ".k...........k."
+ /* 6 */ ".k...........k."
+ /* 7 */ ".kkk.kkk.....k."
+ /* 8 */ ".......k.....k."
+ /* 9 */ "mmmmmm.k......."
+ /* 10 */ "mmmmmm.......k."
+ /* 11 */ "mmmmmm.k.....k."
+ /* 12 */ "mmmmmm.kkk.kkk."
+ /* 13 */ "..............."
+
+ // Level 3
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".ddddddddddddd."
+ /* 2 */ ".d......n....d."
+ /* 3 */ ".d...........d."
+ /* 4 */ ".do..........d."
+ /* 5 */ ".d...........d."
+ /* 6 */ ".d..........pd."
+ /* 7 */ ".ddddddd.....d."
+ /* 8 */ ".......d.....d."
+ /* 9 */ "mmmmmm.d.....d."
+ /* 10 */ "mmmmmm.d.....d."
+ /* 11 */ "mmmmmm.d..q..d."
+ /* 12 */ "mmmmmm.ddddddd."
+ /* 13 */ "..............."
+
+ // Level 4
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "rrrrrrrrrrrrrrs"
+ /* 1 */ "tddddddddddddds"
+ /* 2 */ "tddddddddddddds"
+ /* 3 */ "tddddddddddddds"
+ /* 4 */ "tddddddddddddds"
+ /* 5 */ "tddddddddddddds"
+ /* 6 */ "tddddddddddddds"
+ /* 7 */ "tddddddddddddds"
+ /* 8 */ "tuuuuutddddddds"
+ /* 9 */ "mmmmmmtddddddds"
+ /* 10 */ "mmmmmmtddddddds"
+ /* 11 */ "mmmmmmtddddddds"
+ /* 12 */ "mmmmmmtddddddds"
+ /* 13 */ "......tuuuuuuuu",
+
+ // Connectors:
+ "-1: 4, 0, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // HouseL13x12
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MarketStall:
+ // The data has been exported from the gallery Desert, area index 34, ID 175, created by Aloe_vera
+ {
+ // Size:
+ 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 5, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 12: 0\n" /* sand */
+ "b: 85: 0\n" /* fence */
+ "c:171:14\n" /* carpet */
+ "d:171:15\n" /* carpet */
+ "e:171: 0\n" /* carpet */
+ "f: 35:14\n" /* wool */
+ "g: 35: 0\n" /* wool */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "aaaaaaa"
+ /* 2 */ "aaaaaaa"
+ /* 3 */ "aaaaaaa"
+ /* 4 */ "aaaaaaa"
+ /* 5 */ "aaaaaaa"
+ /* 6 */ "aaaaaaa"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "b.....b"
+ /* 1 */ "cddeddc"
+ /* 2 */ "cdeeedc"
+ /* 3 */ "cdeeedc"
+ /* 4 */ "cddeddc"
+ /* 5 */ "b.....b"
+ /* 6 */ "......."
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "b.....b"
+ /* 1 */ "......."
+ /* 2 */ "......."
+ /* 3 */ "......."
+ /* 4 */ "......."
+ /* 5 */ "b.....b"
+ /* 6 */ "......."
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "b.....b"
+ /* 1 */ "......."
+ /* 2 */ "......."
+ /* 3 */ "......."
+ /* 4 */ "......."
+ /* 5 */ "b.....b"
+ /* 6 */ "fgfgfgf"
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "fgfgfgf"
+ /* 1 */ "......."
+ /* 2 */ "......."
+ /* 3 */ "......."
+ /* 4 */ "......."
+ /* 5 */ "fgfgfgf"
+ /* 6 */ "......."
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "fgfgfgf"
+ /* 2 */ "fgfgfgf"
+ /* 3 */ "fgfgfgf"
+ /* 4 */ "fgfgfgf"
+ /* 5 */ "......."
+ /* 6 */ ".......",
+
+ // Connectors:
+ "-1: 2, 0, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 5,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // MarketStall
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Marketplace:
+ // The data has been exported from the gallery Desert, area index 38, ID 261, created by Aloe_vera
+ {
+ // Size:
+ 14, 4, 16, // SizeX = 14, SizeY = 4, SizeZ = 16
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 13, 3, 15, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 24: 0\n" /* sandstone */
+ "b: 12: 0\n" /* sand */
+ "c: 24: 2\n" /* sandstone */
+ "d: 12: 2\n" /* sand */
+ "e: 85: 0\n" /* fence */
+ "f: 5: 0\n" /* wood */
+ "g:128: 2\n" /* sandstonestairs */
+ "h:128: 0\n" /* sandstonestairs */
+ "i: 8: 0\n" /* water */
+ "j:128: 1\n" /* sandstonestairs */
+ "k:128: 3\n" /* sandstonestairs */
+ "l: 35: 0\n" /* wool */
+ "m: 19: 0\n" /* sponge */
+ "n: 35:14\n" /* wool */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "aaaabbbaaabbbb"
+ /* 1 */ "aaaabbaabbabbb"
+ /* 2 */ "aababbabcabbbb"
+ /* 3 */ "aaaaabaaaaabbb"
+ /* 4 */ "bbbbbbbbbbbbbb"
+ /* 5 */ "bbbbbbbbbbaabb"
+ /* 6 */ "bbbbccccbbabab"
+ /* 7 */ "ccbbccccbbaaab"
+ /* 8 */ "ccbbccccbbabbb"
+ /* 9 */ "dcbbccccbbabaa"
+ /* 10 */ "ccbbbbbbbbaaba"
+ /* 11 */ "ccbbbbbbbbabaa"
+ /* 12 */ "bbbbbbbbbbabaa"
+ /* 13 */ "bbbaababbbaaba"
+ /* 14 */ "bbbcaaaabbabbb"
+ /* 15 */ "bbbcccabbbabbb"
+
+ // Level 1
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "e...e.e...e..."
+ /* 1 */ ".............."
+ /* 2 */ ".............."
+ /* 3 */ "fffff.fffff..."
+ /* 4 */ ".............."
+ /* 5 */ "..........f..e"
+ /* 6 */ "....gggg..f..."
+ /* 7 */ ".f..hiij..f..."
+ /* 8 */ ".f..hiij..f..."
+ /* 9 */ ".f..kkkk..f..e"
+ /* 10 */ ".f............"
+ /* 11 */ ".f........f..e"
+ /* 12 */ "...fffff..f..."
+ /* 13 */ "..........f..."
+ /* 14 */ "..........f..."
+ /* 15 */ "...e...e..f..e"
+
+ // Level 2
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "lnlnl.lnlnl..."
+ /* 1 */ ".............."
+ /* 2 */ ".............."
+ /* 3 */ "e...e.e...e..."
+ /* 4 */ ".............."
+ /* 5 */ "..........e..l"
+ /* 6 */ ".............n"
+ /* 7 */ ".e...........l"
+ /* 8 */ ".............n"
+ /* 9 */ "..........e..l"
+ /* 10 */ ".............."
+ /* 11 */ ".e........e..l"
+ /* 12 */ "...e...e.....n"
+ /* 13 */ ".............l"
+ /* 14 */ ".............n"
+ /* 15 */ "...lnlnl..e..l"
+
+ // Level 3
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ "lnlnl.lnlnl..."
+ /* 2 */ "lnlnl.lnlnl..."
+ /* 3 */ "lnlnl.lnlnl..."
+ /* 4 */ ".............."
+ /* 5 */ "..........lll."
+ /* 6 */ "..........nnn."
+ /* 7 */ "ll........lll."
+ /* 8 */ "nn........nnn."
+ /* 9 */ "ll........lll."
+ /* 10 */ "nn............"
+ /* 11 */ "ll........lll."
+ /* 12 */ "...lnlnl..nnn."
+ /* 13 */ "...lnlnl..lll."
+ /* 14 */ "...lnlnl..nnn."
+ /* 15 */ "..........lll.",
+
+ // Connectors:
+ "-1: 5, 0, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 20,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // Marketplace
+}; // g_SandFlatRoofVillagePrefabs
+
+
+
+
+
+
+const cPrefab::sDef g_SandFlatRoofVillageStartingPrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Well:
+ // The data has been exported from the gallery Desert, area index 44, ID 275, created by Aloe_vera
+ {
+ // Size:
+ 5, 16, 5, // SizeX = 5, SizeY = 16, SizeZ = 5
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 4, 15, 4, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 1: 0\n" /* stone */
+ "b: 24: 0\n" /* sandstone */
+ "c: 8: 0\n" /* water */
+ "d:128: 2\n" /* sandstonestairs */
+ "e:128: 0\n" /* sandstonestairs */
+ "f:128: 1\n" /* sandstonestairs */
+ "g:128: 3\n" /* sandstonestairs */
+ "h:128: 6\n" /* sandstonestairs */
+ "i:128: 4\n" /* sandstonestairs */
+ "j:128: 5\n" /* sandstonestairs */
+ "k:128: 7\n" /* sandstonestairs */
+ "l: 44: 1\n" /* step */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "abbba"
+ /* 2 */ "abbba"
+ /* 3 */ "abbba"
+ /* 4 */ "aaaaa"
+
+ // Level 1
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 2
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 3
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 4
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 5
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 6
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 7
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcccb"
+ /* 2 */ "bcccb"
+ /* 3 */ "bcccb"
+ /* 4 */ "bbbbb"
+
+ // Level 8
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcbcb"
+ /* 2 */ "bbcbb"
+ /* 3 */ "bcbcb"
+ /* 4 */ "bbbbb"
+
+ // Level 9
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcbcb"
+ /* 2 */ "bbbbb"
+ /* 3 */ "bcbcb"
+ /* 4 */ "bbbbb"
+
+ // Level 10
+ /* z\x* 01234 */
+ /* 0 */ "bbbbb"
+ /* 1 */ "bcbcb"
+ /* 2 */ "bbbbb"
+ /* 3 */ "bcbcb"
+ /* 4 */ "bbbbb"
+
+ // Level 11
+ /* z\x* 01234 */
+ /* 0 */ "ddddd"
+ /* 1 */ "ecccf"
+ /* 2 */ "ecbcf"
+ /* 3 */ "ecccf"
+ /* 4 */ "ggggf"
+
+ // Level 12
+ /* z\x* 01234 */
+ /* 0 */ "....."
+ /* 1 */ "....."
+ /* 2 */ "..b.."
+ /* 3 */ "....."
+ /* 4 */ "....."
+
+ // Level 13
+ /* z\x* 01234 */
+ /* 0 */ "....."
+ /* 1 */ "....."
+ /* 2 */ "..b.."
+ /* 3 */ "....."
+ /* 4 */ "....."
+
+ // Level 14
+ /* z\x* 01234 */
+ /* 0 */ "....."
+ /* 1 */ ".hhh."
+ /* 2 */ ".ibj."
+ /* 3 */ ".kkj."
+ /* 4 */ "....."
+
+ // Level 15
+ /* z\x* 01234 */
+ /* 0 */ "lllll"
+ /* 1 */ "lllll"
+ /* 2 */ "lllll"
+ /* 3 */ "lllll"
+ /* 4 */ "lllll",
+
+ // Connectors:
+ "2: 4, 11, 2: 5\n" /* Type 2, direction X+ */
+ "2: 2, 11, 4: 3\n" /* Type 2, direction Z+ */
+ "2: 0, 11, 2: 4\n" /* Type 2, direction X- */
+ "2: 2, 11, 0: 2\n" /* Type 2, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // Well
+};
+
+
+
+
+
+// The prefab counts:
+
+const size_t g_SandFlatRoofVillagePrefabsCount = ARRAYCOUNT(g_SandFlatRoofVillagePrefabs);
+
+const size_t g_SandFlatRoofVillageStartingPrefabsCount = ARRAYCOUNT(g_SandFlatRoofVillageStartingPrefabs);
+
diff --git a/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.h b/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.h
new file mode 100644
index 000000000..ea06de5b5
--- /dev/null
+++ b/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.h
@@ -0,0 +1,15 @@
+
+// SandFlatRoofVillagePrefabs.h
+
+// Declares the prefabs in the group SandFlatRoofVillage
+
+#include "../Prefab.h"
+
+
+
+
+
+extern const cPrefab::sDef g_SandFlatRoofVillagePrefabs[];
+extern const cPrefab::sDef g_SandFlatRoofVillageStartingPrefabs[];
+extern const size_t g_SandFlatRoofVillagePrefabsCount;
+extern const size_t g_SandFlatRoofVillageStartingPrefabsCount;
diff --git a/src/Generating/Prefabs/SandVillagePrefabs.cpp b/src/Generating/Prefabs/SandVillagePrefabs.cpp
new file mode 100644
index 000000000..a062f8cd4
--- /dev/null
+++ b/src/Generating/Prefabs/SandVillagePrefabs.cpp
@@ -0,0 +1,2133 @@
+
+// SandVillagePrefabs.cpp
+
+// Defines the prefabs in the group SandVillage
+
+// NOTE: This file has been generated automatically by GalExport!
+// Any manual changes will be overwritten by the next automatic export!
+
+#include "Globals.h"
+#include "SandVillagePrefabs.h"
+
+
+
+
+
+const cPrefab::sDef g_SandVillagePrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // DoubleField:
+ // The data has been exported from the gallery Desert, area index 5, ID 75, created by tonibm1999
+ {
+ // Size:
+ 13, 2, 9, // SizeX = 13, SizeY = 2, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 12, 1, 8, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 24: 0\n" /* sandstone */
+ "b: 60: 7\n" /* tilleddirt */
+ "c: 8: 0\n" /* water */
+ "d: 50: 5\n" /* torch */
+ "e: 59: 7\n" /* crops */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "aaaaaaaaaaaaa"
+ /* 1 */ "abbcbbabbcbba"
+ /* 2 */ "abbcbbabbcbba"
+ /* 3 */ "abbcbbabbcbba"
+ /* 4 */ "abbcbbabbcbba"
+ /* 5 */ "abbcbbabbcbba"
+ /* 6 */ "abbcbbabbcbba"
+ /* 7 */ "abbcbbabbcbba"
+ /* 8 */ "aaaaaaaaaaaaa"
+
+ // Level 1
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "d.....d.....d"
+ /* 1 */ ".......ee.ee."
+ /* 2 */ ".......ee.ee."
+ /* 3 */ ".......ee.ee."
+ /* 4 */ ".......ee.ee."
+ /* 5 */ ".......ee.ee."
+ /* 6 */ ".......ee.ee."
+ /* 7 */ ".......ee.ee."
+ /* 8 */ "d.....d.....d",
+
+ // Connectors:
+ "-1: 6, 0, 8: 3\n" /* Type -1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // DoubleField
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House11x7:
+ // The data has been exported from the gallery Desert, area index 6, ID 81, created by Aloe_vera
+ {
+ // Size:
+ 11, 6, 7, // SizeX = 11, SizeY = 6, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 10, 5, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:128: 0\n" /* sandstonestairs */
+ "b:128: 2\n" /* sandstonestairs */
+ "c:128: 1\n" /* sandstonestairs */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:102: 0\n" /* glasspane */
+ "g: 64:12\n" /* wooddoorblock */
+ "h:128: 7\n" /* sandstonestairs */
+ "i: 50: 3\n" /* torch */
+ "j: 50: 4\n" /* torch */
+ "k:128: 6\n" /* sandstonestairs */
+ "l:128: 3\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */
+ "n: 50: 1\n" /* torch */
+ "o: 50: 2\n" /* torch */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "....abc...."
+ /* 1 */ ".ddddddddd."
+ /* 2 */ ".ddddddddd."
+ /* 3 */ ".ddddddddd."
+ /* 4 */ ".ddddddddd."
+ /* 5 */ ".ddddddddd."
+ /* 6 */ "..........."
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".ddddedddd."
+ /* 2 */ ".d.......d."
+ /* 3 */ ".d.......d."
+ /* 4 */ ".d.......d."
+ /* 5 */ ".ddddddddd."
+ /* 6 */ "..........."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".dffdgdffd."
+ /* 2 */ ".f.......f."
+ /* 3 */ ".f.......f."
+ /* 4 */ ".f.......f."
+ /* 5 */ ".dffdfdffd."
+ /* 6 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "bbbbbbbbbbb"
+ /* 1 */ "hdddddddddh"
+ /* 2 */ ".d..i.i..d."
+ /* 3 */ ".d.......d."
+ /* 4 */ ".d..j.j..d."
+ /* 5 */ "kdddddddddk"
+ /* 6 */ "lllllllllll"
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "bbbbbbbbbbb"
+ /* 2 */ "hdddddddddh"
+ /* 3 */ ".dn.....od."
+ /* 4 */ "kdddddddddk"
+ /* 5 */ "lllllllllll"
+ /* 6 */ "..........."
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "bbbbbbbbbbb"
+ /* 3 */ "ddddddddddd"
+ /* 4 */ "lllllllllll"
+ /* 5 */ "..........."
+ /* 6 */ "...........",
+
+ // Connectors:
+ "-1: 5, 0, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House11x7
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House11x9:
+ // The data has been exported from the gallery Desert, area index 11, ID 115, created by xoft
+ {
+ // Size:
+ 11, 7, 9, // SizeX = 11, SizeY = 7, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 10, 6, 8, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:128: 0\n" /* sandstonestairs */
+ "b:128: 2\n" /* sandstonestairs */
+ "c:128: 1\n" /* sandstonestairs */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:102: 0\n" /* glasspane */
+ "g: 64:12\n" /* wooddoorblock */
+ "h:128: 7\n" /* sandstonestairs */
+ "i: 50: 3\n" /* torch */
+ "j: 50: 4\n" /* torch */
+ "k:128: 6\n" /* sandstonestairs */
+ "l:128: 3\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "....abc...."
+ /* 1 */ ".ddddddddd."
+ /* 2 */ ".ddddddddd."
+ /* 3 */ ".ddddddddd."
+ /* 4 */ ".ddddddddd."
+ /* 5 */ ".ddddddddd."
+ /* 6 */ ".ddddddddd."
+ /* 7 */ ".ddddddddd."
+ /* 8 */ "..........."
+
+ // Level 1
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".ddddedddd."
+ /* 2 */ ".d.......d."
+ /* 3 */ ".d.......d."
+ /* 4 */ ".d.......d."
+ /* 5 */ ".d.......d."
+ /* 6 */ ".d.......d."
+ /* 7 */ ".ddddddddd."
+ /* 8 */ "..........."
+
+ // Level 2
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ ".dffdgdffd."
+ /* 2 */ ".f.......f."
+ /* 3 */ ".f.......f."
+ /* 4 */ ".d.......d."
+ /* 5 */ ".f.......f."
+ /* 6 */ ".f.......f."
+ /* 7 */ ".dfffdfffd."
+ /* 8 */ "..........."
+
+ // Level 3
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "bbbbbbbbbbb"
+ /* 1 */ "hdddddddddh"
+ /* 2 */ ".d..i.i..d."
+ /* 3 */ ".d.......d."
+ /* 4 */ ".d.......d."
+ /* 5 */ ".d.......d."
+ /* 6 */ ".d...j...d."
+ /* 7 */ "kdddddddddk"
+ /* 8 */ "lllllllllll"
+
+ // Level 4
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "bbbbbbbbbbb"
+ /* 2 */ "hdddddddddh"
+ /* 3 */ ".d.......d."
+ /* 4 */ ".d.......d."
+ /* 5 */ ".d.......d."
+ /* 6 */ "kdddddddddk"
+ /* 7 */ "lllllllllll"
+ /* 8 */ "..........."
+
+ // Level 5
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "bbbbbbbbbbb"
+ /* 3 */ "hdddddddddh"
+ /* 4 */ ".d.......d."
+ /* 5 */ "kdddddddddk"
+ /* 6 */ "lllllllllll"
+ /* 7 */ "..........."
+ /* 8 */ "..........."
+
+ // Level 6
+ /* z\x* 1 */
+ /* * 01234567890 */
+ /* 0 */ "..........."
+ /* 1 */ "..........."
+ /* 2 */ "..........."
+ /* 3 */ "bbbbbbbbbbb"
+ /* 4 */ "ddddddddddd"
+ /* 5 */ "lllllllllll"
+ /* 6 */ "..........."
+ /* 7 */ "..........."
+ /* 8 */ "...........",
+
+ // Connectors:
+ "-1: 5, 0, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House11x9
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House13x7:
+ // The data has been exported from the gallery Desert, area index 15, ID 125, created by Aloe_vera
+ {
+ // Size:
+ 13, 6, 7, // SizeX = 13, SizeY = 6, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 12, 5, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:128: 0\n" /* sandstonestairs */
+ "b:128: 2\n" /* sandstonestairs */
+ "c:128: 1\n" /* sandstonestairs */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:102: 0\n" /* glasspane */
+ "g: 64:12\n" /* wooddoorblock */
+ "h:128: 7\n" /* sandstonestairs */
+ "i: 50: 3\n" /* torch */
+ "j: 50: 4\n" /* torch */
+ "k:128: 6\n" /* sandstonestairs */
+ "l:128: 3\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ ".....abc....."
+ /* 1 */ ".ddddddddddd."
+ /* 2 */ ".ddddddddddd."
+ /* 3 */ ".ddddddddddd."
+ /* 4 */ ".ddddddddddd."
+ /* 5 */ ".ddddddddddd."
+ /* 6 */ "............."
+
+ // Level 1
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ ".dddddeddddd."
+ /* 2 */ ".d.........d."
+ /* 3 */ ".d.........d."
+ /* 4 */ ".d.........d."
+ /* 5 */ ".ddddddddddd."
+ /* 6 */ "............."
+
+ // Level 2
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ ".dfffdgdfffd."
+ /* 2 */ ".f.........f."
+ /* 3 */ ".f.........f."
+ /* 4 */ ".f.........f."
+ /* 5 */ ".dffdfffdffd."
+ /* 6 */ "............."
+
+ // Level 3
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "bbbbbbbbbbbbb"
+ /* 1 */ "hdddddddddddh"
+ /* 2 */ ".d...i.i...d."
+ /* 3 */ ".d.........d."
+ /* 4 */ ".d..j...j..d."
+ /* 5 */ "kdddddddddddk"
+ /* 6 */ "lllllllllllll"
+
+ // Level 4
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "bbbbbbbbbbbbb"
+ /* 2 */ "hdddddddddddh"
+ /* 3 */ ".d.........d."
+ /* 4 */ "kdddddddddddk"
+ /* 5 */ "lllllllllllll"
+ /* 6 */ "............."
+
+ // Level 5
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "............."
+ /* 2 */ "bbbbbbbbbbbbb"
+ /* 3 */ "ddddddddddddd"
+ /* 4 */ "lllllllllllll"
+ /* 5 */ "............."
+ /* 6 */ ".............",
+
+ // Connectors:
+ "-1: 6, 0, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House13x7
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House13x9:
+ // The data has been exported from the gallery Desert, area index 12, ID 116, created by xoft
+ {
+ // Size:
+ 13, 7, 9, // SizeX = 13, SizeY = 7, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 12, 6, 8, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:128: 0\n" /* sandstonestairs */
+ "b:128: 2\n" /* sandstonestairs */
+ "c:128: 1\n" /* sandstonestairs */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:102: 0\n" /* glasspane */
+ "g: 64:12\n" /* wooddoorblock */
+ "h:128: 7\n" /* sandstonestairs */
+ "i: 50: 3\n" /* torch */
+ "j: 50: 4\n" /* torch */
+ "k:128: 6\n" /* sandstonestairs */
+ "l:128: 3\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ ".....abc....."
+ /* 1 */ ".ddddddddddd."
+ /* 2 */ ".ddddddddddd."
+ /* 3 */ ".ddddddddddd."
+ /* 4 */ ".ddddddddddd."
+ /* 5 */ ".ddddddddddd."
+ /* 6 */ ".ddddddddddd."
+ /* 7 */ ".ddddddddddd."
+ /* 8 */ "............."
+
+ // Level 1
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ ".dddddeddddd."
+ /* 2 */ ".d.........d."
+ /* 3 */ ".d.........d."
+ /* 4 */ ".d.........d."
+ /* 5 */ ".d.........d."
+ /* 6 */ ".d.........d."
+ /* 7 */ ".ddddddddddd."
+ /* 8 */ "............."
+
+ // Level 2
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ ".dfffdgdfffd."
+ /* 2 */ ".f.........f."
+ /* 3 */ ".f.........f."
+ /* 4 */ ".d.........d."
+ /* 5 */ ".f.........f."
+ /* 6 */ ".f.........f."
+ /* 7 */ ".dffdffdfffd."
+ /* 8 */ "............."
+
+ // Level 3
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "bbbbbbbbbbbbb"
+ /* 1 */ "hdddddddddddh"
+ /* 2 */ ".d...i.i...d."
+ /* 3 */ ".d.........d."
+ /* 4 */ ".d.........d."
+ /* 5 */ ".d.........d."
+ /* 6 */ ".d..j..j...d."
+ /* 7 */ "kdddddddddddk"
+ /* 8 */ "lllllllllllll"
+
+ // Level 4
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "bbbbbbbbbbbbb"
+ /* 2 */ "hdddddddddddh"
+ /* 3 */ ".d.........d."
+ /* 4 */ ".d.........d."
+ /* 5 */ ".d.........d."
+ /* 6 */ "kdddddddddddk"
+ /* 7 */ "lllllllllllll"
+ /* 8 */ "............."
+
+ // Level 5
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "............."
+ /* 2 */ "bbbbbbbbbbbbb"
+ /* 3 */ "hdddddddddddh"
+ /* 4 */ ".d.........d."
+ /* 5 */ "kdddddddddddk"
+ /* 6 */ "lllllllllllll"
+ /* 7 */ "............."
+ /* 8 */ "............."
+
+ // Level 6
+ /* z\x* 111 */
+ /* * 0123456789012 */
+ /* 0 */ "............."
+ /* 1 */ "............."
+ /* 2 */ "............."
+ /* 3 */ "bbbbbbbbbbbbb"
+ /* 4 */ "ddddddddddddd"
+ /* 5 */ "lllllllllllll"
+ /* 6 */ "............."
+ /* 7 */ "............."
+ /* 8 */ ".............",
+
+ // Connectors:
+ "-1: 6, 0, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House13x9
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House15x9:
+ // The data has been exported from the gallery Desert, area index 13, ID 118, created by xoft
+ {
+ // Size:
+ 15, 7, 9, // SizeX = 15, SizeY = 7, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 14, 6, 8, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:128: 0\n" /* sandstonestairs */
+ "b:128: 2\n" /* sandstonestairs */
+ "c:128: 1\n" /* sandstonestairs */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:102: 0\n" /* glasspane */
+ "g: 64:12\n" /* wooddoorblock */
+ "h:128: 7\n" /* sandstonestairs */
+ "i: 50: 3\n" /* torch */
+ "j: 50: 4\n" /* torch */
+ "k:128: 6\n" /* sandstonestairs */
+ "l:128: 3\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ ".....abc......."
+ /* 1 */ ".ddddddddddddd."
+ /* 2 */ ".ddddddddddddd."
+ /* 3 */ ".ddddddddddddd."
+ /* 4 */ ".ddddddddddddd."
+ /* 5 */ ".ddddddddddddd."
+ /* 6 */ ".ddddddddddddd."
+ /* 7 */ ".ddddddddddddd."
+ /* 8 */ "..............."
+
+ // Level 1
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".dddddeddddddd."
+ /* 2 */ ".d...........d."
+ /* 3 */ ".d...........d."
+ /* 4 */ ".d...........d."
+ /* 5 */ ".d...........d."
+ /* 6 */ ".d...........d."
+ /* 7 */ ".ddddddddddddd."
+ /* 8 */ "..............."
+
+ // Level 2
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ ".dfffdgdffdffd."
+ /* 2 */ ".f...........f."
+ /* 3 */ ".f...........f."
+ /* 4 */ ".d...........d."
+ /* 5 */ ".f...........f."
+ /* 6 */ ".f...........f."
+ /* 7 */ ".dffdffdffdffd."
+ /* 8 */ "..............."
+
+ // Level 3
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "bbbbbbbbbbbbbbb"
+ /* 1 */ "hdddddddddddddh"
+ /* 2 */ ".d...i.i..i..d."
+ /* 3 */ ".d...........d."
+ /* 4 */ ".d...........d."
+ /* 5 */ ".d...........d."
+ /* 6 */ ".d..j..j..j..d."
+ /* 7 */ "kdddddddddddddk"
+ /* 8 */ "lllllllllllllll"
+
+ // Level 4
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "bbbbbbbbbbbbbbb"
+ /* 2 */ "hdddddddddddddh"
+ /* 3 */ ".d...........d."
+ /* 4 */ ".d...........d."
+ /* 5 */ ".d...........d."
+ /* 6 */ "kdddddddddddddk"
+ /* 7 */ "lllllllllllllll"
+ /* 8 */ "..............."
+
+ // Level 5
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "bbbbbbbbbbbbbbb"
+ /* 3 */ "hdddddddddddddh"
+ /* 4 */ ".d...........d."
+ /* 5 */ "kdddddddddddddk"
+ /* 6 */ "lllllllllllllll"
+ /* 7 */ "..............."
+ /* 8 */ "..............."
+
+ // Level 6
+ /* z\x* 11111 */
+ /* * 012345678901234 */
+ /* 0 */ "..............."
+ /* 1 */ "..............."
+ /* 2 */ "..............."
+ /* 3 */ "bbbbbbbbbbbbbbb"
+ /* 4 */ "ddddddddddddddd"
+ /* 5 */ "lllllllllllllll"
+ /* 6 */ "..............."
+ /* 7 */ "..............."
+ /* 8 */ "...............",
+
+ // Connectors:
+ "-1: 6, 0, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House15x9
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House16x9:
+ // The data has been exported from the gallery Desert, area index 16, ID 126, created by Aloe_vera
+ {
+ // Size:
+ 16, 7, 9, // SizeX = 16, SizeY = 7, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 15, 6, 8, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:128: 0\n" /* sandstonestairs */
+ "b:128: 2\n" /* sandstonestairs */
+ "c:128: 1\n" /* sandstonestairs */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:102: 0\n" /* glasspane */
+ "g: 64:12\n" /* wooddoorblock */
+ "h:128: 7\n" /* sandstonestairs */
+ "i: 50: 3\n" /* torch */
+ "j: 50: 4\n" /* torch */
+ "k:128: 6\n" /* sandstonestairs */
+ "l:128: 3\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "........abc....."
+ /* 1 */ ".dddddddddddddd."
+ /* 2 */ ".dddddddddddddd."
+ /* 3 */ ".dddddddddddddd."
+ /* 4 */ ".dddddddddddddd."
+ /* 5 */ ".dddddddddddddd."
+ /* 6 */ ".dddddddddddddd."
+ /* 7 */ ".dddddddddddddd."
+ /* 8 */ "................"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ ".ddddddddeddddd."
+ /* 2 */ ".d............d."
+ /* 3 */ ".d............d."
+ /* 4 */ ".d............d."
+ /* 5 */ ".d............d."
+ /* 6 */ ".d............d."
+ /* 7 */ ".dddddddddddddd."
+ /* 8 */ "................"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ ".dffdfffdgdfffd."
+ /* 2 */ ".f............f."
+ /* 3 */ ".f............f."
+ /* 4 */ ".d............d."
+ /* 5 */ ".f............f."
+ /* 6 */ ".f............f."
+ /* 7 */ ".dffdffdfffdffd."
+ /* 8 */ "................"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "bbbbbbbbbbbbbbbb"
+ /* 1 */ "hddddddddddddddh"
+ /* 2 */ ".d..i...i.i...d."
+ /* 3 */ ".d............d."
+ /* 4 */ ".d............d."
+ /* 5 */ ".d............d."
+ /* 6 */ ".d..j..j...j..d."
+ /* 7 */ "kddddddddddddddk"
+ /* 8 */ "llllllllllllllll"
+
+ // Level 4
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "bbbbbbbbbbbbbbbb"
+ /* 2 */ "hddddddddddddddh"
+ /* 3 */ ".d............d."
+ /* 4 */ ".d............d."
+ /* 5 */ ".d............d."
+ /* 6 */ "kddddddddddddddk"
+ /* 7 */ "llllllllllllllll"
+ /* 8 */ "................"
+
+ // Level 5
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ "bbbbbbbbbbbbbbbb"
+ /* 3 */ "hddddddddddddddh"
+ /* 4 */ ".d............d."
+ /* 5 */ "kddddddddddddddk"
+ /* 6 */ "llllllllllllllll"
+ /* 7 */ "................"
+ /* 8 */ "................"
+
+ // Level 6
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "................"
+ /* 1 */ "................"
+ /* 2 */ "................"
+ /* 3 */ "bbbbbbbbbbbbbbbb"
+ /* 4 */ "dddddddddddddddd"
+ /* 5 */ "llllllllllllllll"
+ /* 6 */ "................"
+ /* 7 */ "................"
+ /* 8 */ "................",
+
+ // Connectors:
+ "-1: 9, 0, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House16x9
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House7x7:
+ // The data has been exported from the gallery Desert, area index 8, ID 112, created by Aloe_vera
+ {
+ // Size:
+ 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 5, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:128: 0\n" /* sandstonestairs */
+ "b:128: 2\n" /* sandstonestairs */
+ "c:128: 1\n" /* sandstonestairs */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:102: 0\n" /* glasspane */
+ "g: 64:12\n" /* wooddoorblock */
+ "h:128: 7\n" /* sandstonestairs */
+ "i: 50: 3\n" /* torch */
+ "j:128: 6\n" /* sandstonestairs */
+ "k:128: 3\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "...abc."
+ /* 1 */ ".ddddd."
+ /* 2 */ ".ddddd."
+ /* 3 */ ".ddddd."
+ /* 4 */ ".ddddd."
+ /* 5 */ ".ddddd."
+ /* 6 */ "......."
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".ddded."
+ /* 2 */ ".d...d."
+ /* 3 */ ".d...d."
+ /* 4 */ ".d...d."
+ /* 5 */ ".ddddd."
+ /* 6 */ "......."
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".dfdgd."
+ /* 2 */ ".f...f."
+ /* 3 */ ".f...f."
+ /* 4 */ ".f...f."
+ /* 5 */ ".dfffd."
+ /* 6 */ "......."
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "bbbbbbb"
+ /* 1 */ "hdddddh"
+ /* 2 */ ".d.i.d."
+ /* 3 */ ".d...d."
+ /* 4 */ ".d...d."
+ /* 5 */ "jdddddj"
+ /* 6 */ "kkkkkkk"
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "bbbbbbb"
+ /* 2 */ "hdddddh"
+ /* 3 */ ".d...d."
+ /* 4 */ "jdddddj"
+ /* 5 */ "kkkkkkk"
+ /* 6 */ "......."
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "......."
+ /* 2 */ "bbbbbbb"
+ /* 3 */ "ddddddd"
+ /* 4 */ "kkkkkkk"
+ /* 5 */ "......."
+ /* 6 */ ".......",
+
+ // Connectors:
+ "-1: 4, 0, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House7x7
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House9x7:
+ // The data has been exported from the gallery Desert, area index 9, ID 113, created by xoft
+ {
+ // Size:
+ 9, 6, 7, // SizeX = 9, SizeY = 6, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 8, 5, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:128: 0\n" /* sandstonestairs */
+ "b:128: 2\n" /* sandstonestairs */
+ "c:128: 1\n" /* sandstonestairs */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:102: 0\n" /* glasspane */
+ "g: 64:12\n" /* wooddoorblock */
+ "h:128: 7\n" /* sandstonestairs */
+ "i: 50: 3\n" /* torch */
+ "j: 50: 4\n" /* torch */
+ "k:128: 6\n" /* sandstonestairs */
+ "l:128: 3\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 012345678 */
+ /* 0 */ "...abc..."
+ /* 1 */ ".ddddddd."
+ /* 2 */ ".ddddddd."
+ /* 3 */ ".ddddddd."
+ /* 4 */ ".ddddddd."
+ /* 5 */ ".ddddddd."
+ /* 6 */ "........."
+
+ // Level 1
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ ".dddeddd."
+ /* 2 */ ".d.....d."
+ /* 3 */ ".d.....d."
+ /* 4 */ ".d.....d."
+ /* 5 */ ".ddddddd."
+ /* 6 */ "........."
+
+ // Level 2
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ ".dfdgdfd."
+ /* 2 */ ".f.....f."
+ /* 3 */ ".f.....f."
+ /* 4 */ ".f.....f."
+ /* 5 */ ".dffdffd."
+ /* 6 */ "........."
+
+ // Level 3
+ /* z\x* 012345678 */
+ /* 0 */ "bbbbbbbbb"
+ /* 1 */ "hdddddddh"
+ /* 2 */ ".d.i.i.d."
+ /* 3 */ ".d.....d."
+ /* 4 */ ".d..j..d."
+ /* 5 */ "kdddddddk"
+ /* 6 */ "lllllllll"
+
+ // Level 4
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "bbbbbbbbb"
+ /* 2 */ "hdddddddh"
+ /* 3 */ ".d.....d."
+ /* 4 */ "kdddddddk"
+ /* 5 */ "lllllllll"
+ /* 6 */ "........."
+
+ // Level 5
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "bbbbbbbbb"
+ /* 3 */ "ddddddddd"
+ /* 4 */ "lllllllll"
+ /* 5 */ "........."
+ /* 6 */ ".........",
+
+ // Connectors:
+ "-1: 4, 0, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House9x7
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // House9x9:
+ // The data has been exported from the gallery Desert, area index 10, ID 114, created by xoft
+ {
+ // Size:
+ 9, 7, 9, // SizeX = 9, SizeY = 7, SizeZ = 9
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 8, 6, 8, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:128: 0\n" /* sandstonestairs */
+ "b:128: 2\n" /* sandstonestairs */
+ "c:128: 1\n" /* sandstonestairs */
+ "d: 24: 0\n" /* sandstone */
+ "e: 64: 7\n" /* wooddoorblock */
+ "f:102: 0\n" /* glasspane */
+ "g: 64:12\n" /* wooddoorblock */
+ "h:128: 7\n" /* sandstonestairs */
+ "i: 50: 3\n" /* torch */
+ "j: 50: 4\n" /* torch */
+ "k:128: 6\n" /* sandstonestairs */
+ "l:128: 3\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 012345678 */
+ /* 0 */ "...abc..."
+ /* 1 */ ".ddddddd."
+ /* 2 */ ".ddddddd."
+ /* 3 */ ".ddddddd."
+ /* 4 */ ".ddddddd."
+ /* 5 */ ".ddddddd."
+ /* 6 */ ".ddddddd."
+ /* 7 */ ".ddddddd."
+ /* 8 */ "........."
+
+ // Level 1
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ ".dddeddd."
+ /* 2 */ ".d.....d."
+ /* 3 */ ".d.....d."
+ /* 4 */ ".d.....d."
+ /* 5 */ ".d.....d."
+ /* 6 */ ".d.....d."
+ /* 7 */ ".ddddddd."
+ /* 8 */ "........."
+
+ // Level 2
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ ".dfdgdfd."
+ /* 2 */ ".f.....f."
+ /* 3 */ ".f.....f."
+ /* 4 */ ".d.....d."
+ /* 5 */ ".f.....f."
+ /* 6 */ ".f.....f."
+ /* 7 */ ".dffdffd."
+ /* 8 */ "........."
+
+ // Level 3
+ /* z\x* 012345678 */
+ /* 0 */ "bbbbbbbbb"
+ /* 1 */ "hdddddddh"
+ /* 2 */ ".d.i.i.d."
+ /* 3 */ ".d.....d."
+ /* 4 */ ".d.....d."
+ /* 5 */ ".d.....d."
+ /* 6 */ ".d..j..d."
+ /* 7 */ "kdddddddk"
+ /* 8 */ "lllllllll"
+
+ // Level 4
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "bbbbbbbbb"
+ /* 2 */ "hdddddddh"
+ /* 3 */ ".d.....d."
+ /* 4 */ ".d.....d."
+ /* 5 */ ".d.....d."
+ /* 6 */ "kdddddddk"
+ /* 7 */ "lllllllll"
+ /* 8 */ "........."
+
+ // Level 5
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "bbbbbbbbb"
+ /* 3 */ "hdddddddh"
+ /* 4 */ ".d.....d."
+ /* 5 */ "kdddddddk"
+ /* 6 */ "lllllllll"
+ /* 7 */ "........."
+ /* 8 */ "........."
+
+ // Level 6
+ /* z\x* 012345678 */
+ /* 0 */ "........."
+ /* 1 */ "........."
+ /* 2 */ "........."
+ /* 3 */ "bbbbbbbbb"
+ /* 4 */ "ddddddddd"
+ /* 5 */ "lllllllll"
+ /* 6 */ "........."
+ /* 7 */ "........."
+ /* 8 */ ".........",
+
+ // Connectors:
+ "-1: 4, 0, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // House9x9
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HouseL14x12:
+ // The data has been exported from the gallery Desert, area index 14, ID 124, created by Aloe_vera
+ {
+ // Size:
+ 14, 7, 12, // SizeX = 14, SizeY = 7, SizeZ = 12
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 13, 6, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:128: 0\n" /* sandstonestairs */
+ "b:128: 2\n" /* sandstonestairs */
+ "c:128: 1\n" /* sandstonestairs */
+ "d: 24: 0\n" /* sandstone */
+ "e:128: 3\n" /* sandstonestairs */
+ "f: 64: 7\n" /* wooddoorblock */
+ "g:102: 0\n" /* glasspane */
+ "h: 64:12\n" /* wooddoorblock */
+ "i:128: 7\n" /* sandstonestairs */
+ "j: 50: 3\n" /* torch */
+ "k: 50: 2\n" /* torch */
+ "l: 50: 4\n" /* torch */
+ "m: 19: 0\n" /* sponge */
+ "n:128: 6\n" /* sandstonestairs */
+ "o: 50: 1\n" /* torch */
+ "p:128: 5\n" /* sandstonestairs */
+ "q:128: 4\n" /* sandstonestairs */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "....abc......."
+ /* 1 */ ".dddddddddddd."
+ /* 2 */ ".dddddddddddd."
+ /* 3 */ ".dddddddddddd."
+ /* 4 */ ".dddddddddddd."
+ /* 5 */ ".dddddddddddd."
+ /* 6 */ ".dddddddddddd."
+ /* 7 */ ".dddddddddddd."
+ /* 8 */ "....aeddddddd."
+ /* 9 */ "mmmmm.ddddddd."
+ /* 10 */ "mmmmm.ddddddd."
+ /* 11 */ "mmmmm........."
+
+ // Level 1
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ ".ddddfddddddd."
+ /* 2 */ ".d..........d."
+ /* 3 */ ".d..........d."
+ /* 4 */ ".d..........d."
+ /* 5 */ ".d..........d."
+ /* 6 */ ".d..........d."
+ /* 7 */ ".ddddfd.....d."
+ /* 8 */ "......d.....d."
+ /* 9 */ "mmmmm.d.....d."
+ /* 10 */ "mmmmm.ddddddd."
+ /* 11 */ "mmmmm........."
+
+ // Level 2
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ ".dggdhdggdggd."
+ /* 2 */ ".g..........g."
+ /* 3 */ ".g..........g."
+ /* 4 */ ".d..........d."
+ /* 5 */ ".g..........g."
+ /* 6 */ ".g..........g."
+ /* 7 */ ".dggdhd.....d."
+ /* 8 */ "......g.....g."
+ /* 9 */ "mmmmm.g.....g."
+ /* 10 */ "mmmmm.dggdggd."
+ /* 11 */ "mmmmm........."
+
+ // Level 3
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "bbbbbbbbbbbbbb"
+ /* 1 */ "iddddddddddddc"
+ /* 2 */ ".d..j.j.....dc"
+ /* 3 */ ".d..........dc"
+ /* 4 */ ".d.........kdc"
+ /* 5 */ ".d..........dc"
+ /* 6 */ ".d..l.l.....dc"
+ /* 7 */ "nddddddo...kdc"
+ /* 8 */ "eeeeead.....dc"
+ /* 9 */ "mmmmmad.....dc"
+ /* 10 */ "mmmmmadddddddc"
+ /* 11 */ "mmmmmap.....qc"
+
+ // Level 4
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ "bbbbbbbbbbbbc."
+ /* 2 */ "idddddddddddc."
+ /* 3 */ ".d.........dc."
+ /* 4 */ ".d.........dc."
+ /* 5 */ ".d.........dc."
+ /* 6 */ "nddddddd...dc."
+ /* 7 */ "eeeeeead...dc."
+ /* 8 */ "......ad...dc."
+ /* 9 */ "mmmmm.ad...dc."
+ /* 10 */ "mmmmm.adddddc."
+ /* 11 */ "mmmmm.ap...qc."
+
+ // Level 5
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ ".............."
+ /* 2 */ "bbbbbbbbbbbb.."
+ /* 3 */ "iddddddddddc.."
+ /* 4 */ ".d........dc.."
+ /* 5 */ "ndddddddd.dc.."
+ /* 6 */ "eeeeeeeed.dc.."
+ /* 7 */ ".......ad.dc.."
+ /* 8 */ ".......ad.dc.."
+ /* 9 */ "mmmmm..ad.dc.."
+ /* 10 */ "mmmmm..adddc.."
+ /* 11 */ "mmmmm..ap.qc.."
+
+ // Level 6
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ ".............."
+ /* 2 */ ".............."
+ /* 3 */ "bbbbbbbbbbb..."
+ /* 4 */ "ddddddddddc..."
+ /* 5 */ "eeeeeeeeadc..."
+ /* 6 */ "........adc..."
+ /* 7 */ "........adc..."
+ /* 8 */ "........adc..."
+ /* 9 */ "mmmmm...adc..."
+ /* 10 */ "mmmmm...adc..."
+ /* 11 */ "mmmmm...adc...",
+
+ // Connectors:
+ "-1: 5, 0, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // HouseL14x12
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HouseL14x12:
+ // The data has been exported from the gallery Desert, area index 7, ID 82, created by Aloe_vera
+ {
+ // Size:
+ 14, 6, 12, // SizeX = 14, SizeY = 6, SizeZ = 12
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 13, 5, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a:128: 0\n" /* sandstonestairs */
+ "b:128: 2\n" /* sandstonestairs */
+ "c:128: 1\n" /* sandstonestairs */
+ "d: 24: 0\n" /* sandstone */
+ "e:128: 3\n" /* sandstonestairs */
+ "f: 64: 7\n" /* wooddoorblock */
+ "g: 64: 5\n" /* wooddoorblock */
+ "h:102: 0\n" /* glasspane */
+ "i: 64:12\n" /* wooddoorblock */
+ "j:128: 7\n" /* sandstonestairs */
+ "k: 50: 3\n" /* torch */
+ "l: 50: 4\n" /* torch */
+ "m: 19: 0\n" /* sponge */
+ "n:128: 6\n" /* sandstonestairs */
+ "o:128: 5\n" /* sandstonestairs */
+ "p:128: 4\n" /* sandstonestairs */
+ "q: 50: 1\n" /* torch */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".......abc...."
+ /* 1 */ ".dddddddddddd."
+ /* 2 */ ".dddddddddddd."
+ /* 3 */ ".dddddddddddd."
+ /* 4 */ ".dddddddddddd."
+ /* 5 */ ".dddddddddddd."
+ /* 6 */ "....aec.ddddd."
+ /* 7 */ "mmmmmmm.ddddd."
+ /* 8 */ "mmmmmmm.ddddd."
+ /* 9 */ "mmmmmmm.ddddd."
+ /* 10 */ "mmmmmmm.ddddd."
+ /* 11 */ "mmmmmmm......."
+
+ // Level 1
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ ".dddddddfdddd."
+ /* 2 */ ".d..........d."
+ /* 3 */ ".d..........d."
+ /* 4 */ ".d..........d."
+ /* 5 */ ".ddddgddd...d."
+ /* 6 */ "........d...d."
+ /* 7 */ "mmmmmmm.d...d."
+ /* 8 */ "mmmmmmm.d...d."
+ /* 9 */ "mmmmmmm.d...d."
+ /* 10 */ "mmmmmmm.ddddd."
+ /* 11 */ "mmmmmmm......."
+
+ // Level 2
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ ".dhhdhhdidhhd."
+ /* 2 */ ".h..........h."
+ /* 3 */ ".h..........h."
+ /* 4 */ ".h..........d."
+ /* 5 */ ".dhhdidhh...h."
+ /* 6 */ "........h...h."
+ /* 7 */ "mmmmmmm.d...d."
+ /* 8 */ "mmmmmmm.h...h."
+ /* 9 */ "mmmmmmm.h...h."
+ /* 10 */ "mmmmmmm.dhhhd."
+ /* 11 */ "mmmmmmm......."
+
+ // Level 3
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "bbbbbbbbbbbbbb"
+ /* 1 */ "jddddddddddddc"
+ /* 2 */ ".d.....k.k..dc"
+ /* 3 */ ".d..........dc"
+ /* 4 */ ".d..l.l.....dc"
+ /* 5 */ "ndddddddd...dc"
+ /* 6 */ "eeeeeeead...dc"
+ /* 7 */ "mmmmmmmad...dc"
+ /* 8 */ "mmmmmmmad...dc"
+ /* 9 */ "mmmmmmmad...dc"
+ /* 10 */ "mmmmmmmadddddc"
+ /* 11 */ "mmmmmmmao...pc"
+
+ // Level 4
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ "bbbbbbbbbbbbb."
+ /* 2 */ "jdddddddddddc."
+ /* 3 */ ".dq........dc."
+ /* 4 */ "nddddddddd.dc."
+ /* 5 */ "eeeeeeeead.dc."
+ /* 6 */ "........ad.dc."
+ /* 7 */ "mmmmmmm.ad.dc."
+ /* 8 */ "mmmmmmm.ad.dc."
+ /* 9 */ "mmmmmmm.adldc."
+ /* 10 */ "mmmmmmm.adddc."
+ /* 11 */ "mmmmmmm.ao.pc."
+
+ // Level 5
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ ".............."
+ /* 1 */ ".............."
+ /* 2 */ "bbbbbbbbbbbb.."
+ /* 3 */ "dddddddddddc.."
+ /* 4 */ "eeeeeeeeeadc.."
+ /* 5 */ ".........adc.."
+ /* 6 */ ".........adc.."
+ /* 7 */ "mmmmmmm..adc.."
+ /* 8 */ "mmmmmmm..adc.."
+ /* 9 */ "mmmmmmm..adc.."
+ /* 10 */ "mmmmmmm..adc.."
+ /* 11 */ "mmmmmmm..adc..",
+
+ // Connectors:
+ "-1: 8, 0, 0: 2\n" /* Type -1, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // HouseL14x12
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SingleField:
+ // The data has been exported from the gallery Desert, area index 17, ID 127, created by Aloe_vera
+ {
+ // Size:
+ 10, 2, 7, // SizeX = 10, SizeY = 2, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 9, 1, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 24: 0\n" /* sandstone */
+ "b: 60: 7\n" /* tilleddirt */
+ "c: 8: 0\n" /* water */
+ "d: 50: 5\n" /* torch */
+ "e: 59: 7\n" /* crops */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "aaaaaaaaaa"
+ /* 1 */ "abbbbbbbba"
+ /* 2 */ "abbbbbbbba"
+ /* 3 */ "acccccccca"
+ /* 4 */ "abbbbbbbba"
+ /* 5 */ "abbbbbbbba"
+ /* 6 */ "aaaaaaaaaa"
+
+ // Level 1
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "d........d"
+ /* 1 */ ".eeeeeeee."
+ /* 2 */ ".eeeeeeee."
+ /* 3 */ ".........."
+ /* 4 */ ".eeeeeeee."
+ /* 5 */ ".eeeeeeee."
+ /* 6 */ "d........d",
+
+ // Connectors:
+ "-1: 0, 0, 3: 4\n" /* Type -1, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // SingleField
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SmallHut:
+ // The data has been exported from the gallery Desert, area index 4, ID 68, created by tonibm1999
+ {
+ // Size:
+ 5, 5, 6, // SizeX = 5, SizeY = 5, SizeZ = 6
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 4, 4, 5, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 24: 0\n" /* sandstone */
+ "b:128: 3\n" /* sandstonestairs */
+ "c: 24: 2\n" /* sandstone */
+ "d: 50: 5\n" /* torch */
+ "e: 26:10\n" /* bedblock */
+ "f: 26: 2\n" /* bedblock */
+ "g: 64: 5\n" /* wooddoorblock */
+ "h: 64:12\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 01234 */
+ /* 0 */ "aaaaa"
+ /* 1 */ "aaaaa"
+ /* 2 */ "aaaaa"
+ /* 3 */ "aaaaa"
+ /* 4 */ "aaaaa"
+ /* 5 */ "..b.."
+
+ // Level 1
+ /* z\x* 01234 */
+ /* 0 */ "accca"
+ /* 1 */ "cdedc"
+ /* 2 */ "c.f.c"
+ /* 3 */ "c...c"
+ /* 4 */ "acgca"
+ /* 5 */ "....."
+
+ // Level 2
+ /* z\x* 01234 */
+ /* 0 */ "ac.ca"
+ /* 1 */ "c...c"
+ /* 2 */ "....."
+ /* 3 */ "c...c"
+ /* 4 */ "achca"
+ /* 5 */ "....."
+
+ // Level 3
+ /* z\x* 01234 */
+ /* 0 */ "accca"
+ /* 1 */ "c...c"
+ /* 2 */ "c...c"
+ /* 3 */ "c...c"
+ /* 4 */ "accca"
+ /* 5 */ "....."
+
+ // Level 4
+ /* z\x* 01234 */
+ /* 0 */ ".aaa."
+ /* 1 */ "aaaaa"
+ /* 2 */ "aaaaa"
+ /* 3 */ "aaaaa"
+ /* 4 */ ".aaa."
+ /* 5 */ ".....",
+
+ // Connectors:
+ "-1: 2, 0, 5: 3\n" /* Type -1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // SmallHut
+}; // g_SandVillagePrefabs
+
+
+
+
+
+
+const cPrefab::sDef g_SandVillageStartingPrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // RoofedWell:
+ // The data has been exported from the gallery Desert, area index 43, ID 274, created by Aloe_vera
+ {
+ // Size:
+ 7, 14, 7, // SizeX = 7, SizeY = 14, SizeZ = 7
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 6, 13, 6, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 1: 0\n" /* stone */
+ "b: 24: 0\n" /* sandstone */
+ "c: 8: 0\n" /* water */
+ "d: 12: 0\n" /* sand */
+ "e:118: 3\n" /* cauldronblock */
+ "f: 85: 0\n" /* fence */
+ "g:128: 2\n" /* sandstonestairs */
+ "h:128: 7\n" /* sandstonestairs */
+ "i:128: 4\n" /* sandstonestairs */
+ "j:128: 5\n" /* sandstonestairs */
+ "k:128: 6\n" /* sandstonestairs */
+ "l:128: 3\n" /* sandstonestairs */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "aaaaaaa"
+ /* 2 */ "aaaaaaa"
+ /* 3 */ "aaaaaaa"
+ /* 4 */ "aaaaaaa"
+ /* 5 */ "aaaaaaa"
+ /* 6 */ "aaaaaaa"
+
+ // Level 1
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "abbbbba"
+ /* 2 */ "abcccba"
+ /* 3 */ "abcccba"
+ /* 4 */ "abcccba"
+ /* 5 */ "abbbbba"
+ /* 6 */ "aaaaaaa"
+
+ // Level 2
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "abbbbba"
+ /* 2 */ "abcccba"
+ /* 3 */ "abcccba"
+ /* 4 */ "abcccba"
+ /* 5 */ "abbbbba"
+ /* 6 */ "aaaaaaa"
+
+ // Level 3
+ /* z\x* 0123456 */
+ /* 0 */ "aaaaaaa"
+ /* 1 */ "abbbbba"
+ /* 2 */ "abcccba"
+ /* 3 */ "abcccba"
+ /* 4 */ "abcccba"
+ /* 5 */ "abbbbba"
+ /* 6 */ "aaaaaaa"
+
+ // Level 4
+ /* z\x* 0123456 */
+ /* 0 */ "ddddddd"
+ /* 1 */ "dbbbbbd"
+ /* 2 */ "dbcccbd"
+ /* 3 */ "dbcccbd"
+ /* 4 */ "dbcccbd"
+ /* 5 */ "dbbbbbd"
+ /* 6 */ "ddddddd"
+
+ // Level 5
+ /* z\x* 0123456 */
+ /* 0 */ "ddddddd"
+ /* 1 */ "dbbbbbd"
+ /* 2 */ "dbcccbd"
+ /* 3 */ "dbcccbd"
+ /* 4 */ "dbcccbd"
+ /* 5 */ "dbbbbbd"
+ /* 6 */ "ddddddd"
+
+ // Level 6
+ /* z\x* 0123456 */
+ /* 0 */ "ddddddd"
+ /* 1 */ "dbbbbbd"
+ /* 2 */ "dbcccbd"
+ /* 3 */ "dbcccbd"
+ /* 4 */ "dbcccbd"
+ /* 5 */ "dbbbbbd"
+ /* 6 */ "ddddddd"
+
+ // Level 7
+ /* z\x* 0123456 */
+ /* 0 */ "ddbbbdd"
+ /* 1 */ "dbbbbbd"
+ /* 2 */ "bbcccbb"
+ /* 3 */ "bbcccbb"
+ /* 4 */ "bbcccbb"
+ /* 5 */ "dbbbbbd"
+ /* 6 */ "ddbbbdd"
+
+ // Level 8
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".bbbbb."
+ /* 2 */ ".b...b."
+ /* 3 */ ".b.e.b."
+ /* 4 */ ".b...b."
+ /* 5 */ ".bbbbb."
+ /* 6 */ "......."
+
+ // Level 9
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".f...f."
+ /* 2 */ "......."
+ /* 3 */ "...f..."
+ /* 4 */ "......."
+ /* 5 */ ".f...f."
+ /* 6 */ "......."
+
+ // Level 10
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ ".f...f."
+ /* 2 */ "......."
+ /* 3 */ "...f..."
+ /* 4 */ "......."
+ /* 5 */ ".f...f."
+ /* 6 */ "......."
+
+ // Level 11
+ /* z\x* 0123456 */
+ /* 0 */ "ggggggg"
+ /* 1 */ "hbhhhbh"
+ /* 2 */ ".i...j."
+ /* 3 */ ".i.f.j."
+ /* 4 */ ".i...j."
+ /* 5 */ "kbkkkbk"
+ /* 6 */ "lllllll"
+
+ // Level 12
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "ggggggg"
+ /* 2 */ "hb...bh"
+ /* 3 */ ".b.f.b."
+ /* 4 */ "kb...bk"
+ /* 5 */ "lllllll"
+ /* 6 */ "......."
+
+ // Level 13
+ /* z\x* 0123456 */
+ /* 0 */ "......."
+ /* 1 */ "......."
+ /* 2 */ "ggggggg"
+ /* 3 */ "bbbbbbb"
+ /* 4 */ "lllllll"
+ /* 5 */ "......."
+ /* 6 */ ".......",
+
+ // Connectors:
+ "2: 6, 8, 3: 5\n" /* Type 2, direction X+ */
+ "2: 3, 8, 6: 3\n" /* Type 2, direction Z+ */
+ "2: 0, 8, 3: 4\n" /* Type 2, direction X- */
+ "2: 3, 8, 0: 2\n" /* Type 2, direction Z- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // RoofedWell
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Well:
+ // The data has been exported from the gallery Desert, area index 0, ID 1, created by Aloe_vera
+ {
+ // Size:
+ 4, 13, 4, // SizeX = 4, SizeY = 13, SizeZ = 4
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 3, 12, 3, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 1: 0\n" /* stone */
+ "b: 24: 0\n" /* sandstone */
+ "c: 8: 0\n" /* water */
+ "d: 85: 0\n" /* fence */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 0123 */
+ /* 0 */ "aaaa"
+ /* 1 */ "aaaa"
+ /* 2 */ "aaaa"
+ /* 3 */ "aaaa"
+
+ // Level 1
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 2
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 3
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 4
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 5
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 6
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 7
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bccb"
+ /* 2 */ "bccb"
+ /* 3 */ "bbbb"
+
+ // Level 8
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "b..b"
+ /* 2 */ "b..b"
+ /* 3 */ "bbbb"
+
+ // Level 9
+ /* z\x* 0123 */
+ /* 0 */ "d..d"
+ /* 1 */ "...."
+ /* 2 */ "...."
+ /* 3 */ "d..d"
+
+ // Level 10
+ /* z\x* 0123 */
+ /* 0 */ "d..d"
+ /* 1 */ "...."
+ /* 2 */ "...."
+ /* 3 */ "d..d"
+
+ // Level 11
+ /* z\x* 0123 */
+ /* 0 */ "d..d"
+ /* 1 */ "...."
+ /* 2 */ "...."
+ /* 3 */ "d..d"
+
+ // Level 12
+ /* z\x* 0123 */
+ /* 0 */ "bbbb"
+ /* 1 */ "bbbb"
+ /* 2 */ "bbbb"
+ /* 3 */ "bbbb",
+
+ // Connectors:
+ "2: 2, 8, 0: 2\n" /* Type 2, direction Z- */
+ "2: 0, 8, 1: 4\n" /* Type 2, direction X- */
+ "2: 1, 8, 3: 3\n" /* Type 2, direction Z+ */
+ "2: 3, 8, 2: 5\n" /* Type 2, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ true,
+ }, // Well
+};
+
+
+
+
+
+// The prefab counts:
+
+const size_t g_SandVillagePrefabsCount = ARRAYCOUNT(g_SandVillagePrefabs);
+
+const size_t g_SandVillageStartingPrefabsCount = ARRAYCOUNT(g_SandVillageStartingPrefabs);
+
diff --git a/src/Generating/Prefabs/SandVillagePrefabs.h b/src/Generating/Prefabs/SandVillagePrefabs.h
new file mode 100644
index 000000000..7b00db56f
--- /dev/null
+++ b/src/Generating/Prefabs/SandVillagePrefabs.h
@@ -0,0 +1,15 @@
+
+// SandVillagePrefabs.h
+
+// Declares the prefabs in the group SandVillage
+
+#include "../Prefab.h"
+
+
+
+
+
+extern const cPrefab::sDef g_SandVillagePrefabs[];
+extern const cPrefab::sDef g_SandVillageStartingPrefabs[];
+extern const size_t g_SandVillagePrefabsCount;
+extern const size_t g_SandVillageStartingPrefabsCount;
diff --git a/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp b/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp
new file mode 100644
index 000000000..39748a223
--- /dev/null
+++ b/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp
@@ -0,0 +1,2274 @@
+
+// UnderwaterBasePrefabs.cpp
+
+// Defines the prefabs in the group UnderwaterBase
+
+// NOTE: This file has been generated automatically by GalExport!
+// Any manual changes will be overwritten by the next automatic export!
+
+#include "Globals.h"
+#include "UnderwaterBasePrefabs.h"
+
+
+
+
+
+const cPrefab::sDef g_UnderwaterBasePrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // BrokenRoom:
+ // The data has been exported from the gallery Water, area index 49, ID 680, created by STR_Warrior
+ {
+ // Size:
+ 14, 7, 12, // SizeX = 14, SizeY = 7, SizeZ = 12
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 13, 6, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 0\n" /* wood */
+ "b: 20: 0\n" /* glass */
+ "c: 5: 5\n" /* wood */
+ "d: 8: 0\n" /* water */
+ "e: 64: 4\n" /* wooddoorblock */
+ "f: 64:12\n" /* wooddoorblock */
+ "g: 64:13\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmaaaammmmmm"
+ /* 2 */ "mmmaabbaammmmm"
+ /* 3 */ "mmaabbbbaammmm"
+ /* 4 */ "maabbbbbbaammm"
+ /* 5 */ "mabbbbbbbbaaac"
+ /* 6 */ "mabbbbbbbbaaac"
+ /* 7 */ "maabbbbbbaammm"
+ /* 8 */ "mmaabbbbaammmm"
+ /* 9 */ "mmmaabbaammmmm"
+ /* 10 */ "mmmmaaaammmmmm"
+ /* 11 */ "mmmmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmaammmmmmm"
+ /* 1 */ "mmmaaddaammmmm"
+ /* 2 */ "mmaaddddaammmm"
+ /* 3 */ "maaddddddaammm"
+ /* 4 */ "maddddddddaaac"
+ /* 5 */ "adddddddddddde"
+ /* 6 */ "adddddddddddde"
+ /* 7 */ "maddddddddaaac"
+ /* 8 */ "maaddddddaammm"
+ /* 9 */ "mmaaddddaammmm"
+ /* 10 */ "mmmaaddaammmmm"
+ /* 11 */ "mmmmmaammmmmmm"
+
+ // Level 2
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmbbmmmmmmm"
+ /* 1 */ "mmmbb..bbmmmmm"
+ /* 2 */ "mmbb....bbmmmm"
+ /* 3 */ "mbb......bbmmm"
+ /* 4 */ "mb........bbac"
+ /* 5 */ "b............f"
+ /* 6 */ "b............g"
+ /* 7 */ "mb........bbac"
+ /* 8 */ "mbb......bbmmm"
+ /* 9 */ "mmbb....bbmmmm"
+ /* 10 */ "mmmbb..bbmmmmm"
+ /* 11 */ "mmmmmbbmmmmmmm"
+
+ // Level 3
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmbbmmmmmmm"
+ /* 1 */ "mmmbb..bbmmmmm"
+ /* 2 */ "mmbb....bbmmmm"
+ /* 3 */ "mbb......bbmmm"
+ /* 4 */ "mb........bbac"
+ /* 5 */ "b..........bac"
+ /* 6 */ "b..........bac"
+ /* 7 */ "mb........bbac"
+ /* 8 */ "mbb......bbmmm"
+ /* 9 */ "mmbb....bbmmmm"
+ /* 10 */ "mmmbb..bbmmmmm"
+ /* 11 */ "mmmmmbbmmmmmmm"
+
+ // Level 4
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmm.bmmmmmmm"
+ /* 2 */ "mmmmb..bmmmmmm"
+ /* 3 */ "mmmb....bmmmmm"
+ /* 4 */ "mmb......bmmmm"
+ /* 5 */ "m.........bmmm"
+ /* 6 */ "mb........bmmm"
+ /* 7 */ "mmb......bmmmm"
+ /* 8 */ "mmm.....bmmmmm"
+ /* 9 */ "mmmmb..bmmmmmm"
+ /* 10 */ "mmmmmbbmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmm"
+
+ // Level 5
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmbbmmmmmmm"
+ /* 3 */ "mmmm....mmmmmm"
+ /* 4 */ "mmmb....bmmmmm"
+ /* 5 */ "mmb......bmmmm"
+ /* 6 */ "mmb......bmmmm"
+ /* 7 */ "mmmb.....mmmmm"
+ /* 8 */ "mmmmb..bmmmmmm"
+ /* 9 */ "mmmmmbbmmmmmmm"
+ /* 10 */ "mmmmmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmm"
+
+ // Level 6
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmbbmmmmmmm"
+ /* 4 */ "mmmmbbbbmmmmmm"
+ /* 5 */ "mmmbbbbbbmmmmm"
+ /* 6 */ "mmmbb.bbbmmmmm"
+ /* 7 */ "mmmmbbbbmmmmmm"
+ /* 8 */ "mmmmmbbmmmmmmm"
+ /* 9 */ "mmmmmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmm",
+
+ // Connectors:
+ "1: 13, 1, 6: 5\n" /* Type 1, direction X+ */
+ "-1: 13, 1, 5: 5\n" /* Type -1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // BrokenRoom
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Corridor16:
+ // The data has been exported from the gallery Water, area index 25, ID 566, created by xoft
+ {
+ // Size:
+ 16, 4, 4, // SizeX = 16, SizeY = 4, SizeZ = 4
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 15, 3, 3, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 5\n" /* wood */
+ "b: 5: 0\n" /* wood */
+ "c: 64: 2\n" /* wooddoorblock */
+ "d: 64: 0\n" /* wooddoorblock */
+ "e: 20: 0\n" /* glass */
+ "f: 64: 9\n" /* wooddoorblock */
+ "g: 76: 3\n" /* redstonetorchon */
+ "h: 64: 8\n" /* wooddoorblock */
+ "i: 76: 4\n" /* redstonetorchon */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "abbbbbbbbbbbbbba"
+ /* 2 */ "abbbbbbbbbbbbbba"
+ /* 3 */ "mmmmmmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "abbbbbbbbbbbbbba"
+ /* 1 */ "c..............d"
+ /* 2 */ "c..............d"
+ /* 3 */ "abbbbbbbbbbbbbba"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "abeebbbeebbbeeba"
+ /* 1 */ "f...g......g...h"
+ /* 2 */ "h...i......i...f"
+ /* 3 */ "abeebbbeebbbeeba"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "abbbbbbbbbbbbbba"
+ /* 1 */ "abbbbbbbbbbbbbba"
+ /* 2 */ "abbbbbbbbbbbbbba"
+ /* 3 */ "abbbbbbbbbbbbbba",
+
+ // Connectors:
+ "1: 0, 1, 1: 4\n" /* Type 1, direction X- */
+ "-1: 0, 1, 2: 4\n" /* Type -1, direction X- */
+ "1: 15, 1, 2: 5\n" /* Type 1, direction X+ */
+ "-1: 15, 1, 1: 5\n" /* Type -1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 500,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // Corridor16
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CorridorCorner:
+ // The data has been exported from the gallery Water, area index 26, ID 569, created by xoft
+ {
+ // Size:
+ 10, 4, 10, // SizeX = 10, SizeY = 4, SizeZ = 10
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 9, 3, 9, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 5\n" /* wood */
+ "b: 5: 0\n" /* wood */
+ "c: 64: 5\n" /* wooddoorblock */
+ "d: 64: 2\n" /* wooddoorblock */
+ "e: 64: 4\n" /* wooddoorblock */
+ "f: 64: 1\n" /* wooddoorblock */
+ "g: 20: 0\n" /* glass */
+ "h: 64:12\n" /* wooddoorblock */
+ "i: 76: 3\n" /* redstonetorchon */
+ "j: 64: 8\n" /* wooddoorblock */
+ "k: 76: 4\n" /* redstonetorchon */
+ "l: 76: 2\n" /* redstonetorchon */
+ "m: 19: 0\n" /* sponge */
+ "n: 76: 1\n" /* redstonetorchon */,
+
+ // Block data:
+ // Level 0
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "mmmmmmmmmm"
+ /* 1 */ "abbbbbmmmm"
+ /* 2 */ "abbbbbbbmm"
+ /* 3 */ "mmmbbbbbmm"
+ /* 4 */ "mmmmmbbbbm"
+ /* 5 */ "mmmmmmbbbm"
+ /* 6 */ "mmmmmmbbbm"
+ /* 7 */ "mmmmmmmbbm"
+ /* 8 */ "mmmmmmmbbm"
+ /* 9 */ "mmmmmmmaam"
+
+ // Level 1
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "abbbbbmmmm"
+ /* 1 */ "c.....bbmm"
+ /* 2 */ "d.......bm"
+ /* 3 */ "abb.....bm"
+ /* 4 */ "mmmbb....b"
+ /* 5 */ "mmmmmb...b"
+ /* 6 */ "mmmmmb...b"
+ /* 7 */ "mmmmmmb..b"
+ /* 8 */ "mmmmmmb..b"
+ /* 9 */ "mmmmmmaefa"
+
+ // Level 2
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "abggbbmmmm"
+ /* 1 */ "h...i.bbmm"
+ /* 2 */ "j.......bm"
+ /* 3 */ "abbk....bm"
+ /* 4 */ "mmmbb....b"
+ /* 5 */ "mmmmmb..lb"
+ /* 6 */ "mmmmmbn..g"
+ /* 7 */ "mmmmmmb..g"
+ /* 8 */ "mmmmmmb..b"
+ /* 9 */ "mmmmmmahja"
+
+ // Level 3
+ /* z\x* */
+ /* * 0123456789 */
+ /* 0 */ "abbbbbmmmm"
+ /* 1 */ "abbbbbbbmm"
+ /* 2 */ "abbbbbbbbm"
+ /* 3 */ "abbbbbbbbm"
+ /* 4 */ "mmmbbbbbbb"
+ /* 5 */ "mmmmmbbbbb"
+ /* 6 */ "mmmmmbbbbb"
+ /* 7 */ "mmmmmmbbbb"
+ /* 8 */ "mmmmmmbbbb"
+ /* 9 */ "mmmmmmaaaa",
+
+ // Connectors:
+ "1: 7, 1, 9: 3\n" /* Type 1, direction Z+ */
+ "-1: 8, 1, 9: 3\n" /* Type -1, direction Z+ */
+ "1: 0, 1, 1: 4\n" /* Type 1, direction X- */
+ "-1: 0, 1, 2: 4\n" /* Type -1, direction X- */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // CorridorCorner
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CorridorCrossing:
+ // The data has been exported from the gallery Water, area index 31, ID 581, created by LO1ZB
+ {
+ // Size:
+ 16, 4, 16, // SizeX = 16, SizeY = 4, SizeZ = 16
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 15, 3, 15, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 5\n" /* wood */
+ "b: 5: 0\n" /* wood */
+ "c: 64: 3\n" /* wooddoorblock */
+ "d: 64: 6\n" /* wooddoorblock */
+ "e: 64: 5\n" /* wooddoorblock */
+ "f: 64: 0\n" /* wooddoorblock */
+ "g: 64: 2\n" /* wooddoorblock */
+ "h: 64: 1\n" /* wooddoorblock */
+ "i: 64: 8\n" /* wooddoorblock */
+ "j: 64:12\n" /* wooddoorblock */
+ "k: 20: 0\n" /* glass */
+ "l: 76: 1\n" /* redstonetorchon */
+ "m: 19: 0\n" /* sponge */
+ "n: 76: 2\n" /* redstonetorchon */
+ "o: 76: 3\n" /* redstonetorchon */
+ "p: 76: 4\n" /* redstonetorchon */
+ "q: 64: 9\n" /* wooddoorblock */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmaammmmmmm"
+ /* 1 */ "mmmmmmmbbmmmmmmm"
+ /* 2 */ "mmmmmmmbbmmmmmmm"
+ /* 3 */ "mmmmmmmbbmmmmmmm"
+ /* 4 */ "mmmmmmmbbmmmmmmm"
+ /* 5 */ "mmmmmmmbbmmmmmmm"
+ /* 6 */ "mmmmmmmbbmmmmmmm"
+ /* 7 */ "abbbbbbbbbbbbbba"
+ /* 8 */ "abbbbbbbbbbbbbba"
+ /* 9 */ "mmmmmmmbbmmmmmmm"
+ /* 10 */ "mmmmmmmbbmmmmmmm"
+ /* 11 */ "mmmmmmmbbmmmmmmm"
+ /* 12 */ "mmmmmmmbbmmmmmmm"
+ /* 13 */ "mmmmmmmbbmmmmmmm"
+ /* 14 */ "mmmmmmmbbmmmmmmm"
+ /* 15 */ "mmmmmmmaammmmmmm"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmacdammmmmm"
+ /* 1 */ "mmmmmmb..bmmmmmm"
+ /* 2 */ "mmmmmmb..bmmmmmm"
+ /* 3 */ "mmmmmmb..bmmmmmm"
+ /* 4 */ "mmmmmmb..bmmmmmm"
+ /* 5 */ "mmmmmmb..bmmmmmm"
+ /* 6 */ "abbbbbb..bbbbbba"
+ /* 7 */ "e..............f"
+ /* 8 */ "g..............f"
+ /* 9 */ "abbbbbb..bbbbbba"
+ /* 10 */ "mmmmmmb..bmmmmmm"
+ /* 11 */ "mmmmmmb..bmmmmmm"
+ /* 12 */ "mmmmmmb..bmmmmmm"
+ /* 13 */ "mmmmmmb..bmmmmmm"
+ /* 14 */ "mmmmmmb..bmmmmmm"
+ /* 15 */ "mmmmmmahhammmmmm"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmaijammmmmm"
+ /* 1 */ "mmmmmmb..bmmmmmm"
+ /* 2 */ "mmmmmmk..kmmmmmm"
+ /* 3 */ "mmmmmmk..kmmmmmm"
+ /* 4 */ "mmmmmmblnbmmmmmm"
+ /* 5 */ "mmmmmmb..bmmmmmm"
+ /* 6 */ "abkkbbb..bbbkkba"
+ /* 7 */ "j...o......o...i"
+ /* 8 */ "i...p......p...q"
+ /* 9 */ "abkkbbb..bbbkkba"
+ /* 10 */ "mmmmmmb..bmmmmmm"
+ /* 11 */ "mmmmmmblnbmmmmmm"
+ /* 12 */ "mmmmmmk..kmmmmmm"
+ /* 13 */ "mmmmmmk..kmmmmmm"
+ /* 14 */ "mmmmmmb..bmmmmmm"
+ /* 15 */ "mmmmmmaqiammmmmm"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmaaaammmmmm"
+ /* 1 */ "mmmmmmbbbbmmmmmm"
+ /* 2 */ "mmmmmmbbbbmmmmmm"
+ /* 3 */ "mmmmmmbbbbmmmmmm"
+ /* 4 */ "mmmmmmbbbbmmmmmm"
+ /* 5 */ "mmmmmmbbbbmmmmmm"
+ /* 6 */ "abbbbbbbbbbbbbba"
+ /* 7 */ "abbbbbbbbbbbbbba"
+ /* 8 */ "abbbbbbbbbbbbbba"
+ /* 9 */ "abbbbbbbbbbbbbba"
+ /* 10 */ "mmmmmmbbbbmmmmmm"
+ /* 11 */ "mmmmmmbbbbmmmmmm"
+ /* 12 */ "mmmmmmbbbbmmmmmm"
+ /* 13 */ "mmmmmmbbbbmmmmmm"
+ /* 14 */ "mmmmmmbbbbmmmmmm"
+ /* 15 */ "mmmmmmaaaammmmmm",
+
+ // Connectors:
+ "1: 0, 1, 7: 4\n" /* Type 1, direction X- */
+ "-1: 0, 1, 8: 4\n" /* Type -1, direction X- */
+ "1: 7, 1, 15: 3\n" /* Type 1, direction Z+ */
+ "-1: 8, 1, 15: 3\n" /* Type -1, direction Z+ */
+ "1: 8, 1, 0: 2\n" /* Type 1, direction Z- */
+ "-1: 7, 1, 0: 2\n" /* Type -1, direction Z- */
+ "1: 15, 1, 8: 5\n" /* Type 1, direction X+ */
+ "-1: 15, 1, 7: 5\n" /* Type -1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // CorridorCrossing
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CorridorStairs:
+ // The data has been exported from the gallery Water, area index 32, ID 582, created by LO1ZB
+ {
+ // Size:
+ 16, 9, 4, // SizeX = 16, SizeY = 9, SizeZ = 4
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 15, 8, 3, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 5\n" /* wood */
+ "b: 5: 0\n" /* wood */
+ "c: 64: 2\n" /* wooddoorblock */
+ "d: 53: 0\n" /* woodstairs */
+ "e: 20: 0\n" /* glass */
+ "f: 64: 9\n" /* wooddoorblock */
+ "g: 76: 3\n" /* redstonetorchon */
+ "h: 64: 8\n" /* wooddoorblock */
+ "i: 76: 4\n" /* redstonetorchon */
+ "j: 64: 0\n" /* wooddoorblock */
+ "k: 64: 7\n" /* wooddoorblock */
+ "l: 64:12\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "abbbbbbbmmmmmmmm"
+ /* 2 */ "abbbbbbbmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "abbbbbbbmmmmmmmm"
+ /* 1 */ "c.....dbbmmmmmmm"
+ /* 2 */ "c.....dbbmmmmmmm"
+ /* 3 */ "abbbbbbbmmmmmmmm"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "abeebbbbbmmmmmmm"
+ /* 1 */ "f...g..dbbmmmmmm"
+ /* 2 */ "h...i..dbbmmmmmm"
+ /* 3 */ "abeebbbbbmmmmmmm"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "abbbbbbbbbmmmmmm"
+ /* 1 */ "abbbb...dbbmmmmm"
+ /* 2 */ "abbbb...dbbmmmmm"
+ /* 3 */ "abbbbbbbbbmmmmmm"
+
+ // Level 4
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmbbbbbmmmmmm"
+ /* 1 */ "mmmmmb...dbbmmmm"
+ /* 2 */ "mmmmmb...dbbmmmm"
+ /* 3 */ "mmmmmbbbbbmmmmmm"
+
+ // Level 5
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmbbbbbmmmmm"
+ /* 1 */ "mmmmmmb...dbbbba"
+ /* 2 */ "mmmmmmb...dbbbba"
+ /* 3 */ "mmmmmmbbbbbmmmmm"
+
+ // Level 6
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmbbbbbbbba"
+ /* 1 */ "mmmmmmmb.......j"
+ /* 2 */ "mmmmmmmb.......k"
+ /* 3 */ "mmmmmmmbbbbbbbba"
+
+ // Level 7
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmbbbeebba"
+ /* 1 */ "mmmmmmmmb.g....h"
+ /* 2 */ "mmmmmmmmb.i....l"
+ /* 3 */ "mmmmmmmmbbbeebba"
+
+ // Level 8
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmbbbbbba"
+ /* 1 */ "mmmmmmmmmbbbbbba"
+ /* 2 */ "mmmmmmmmmbbbbbba"
+ /* 3 */ "mmmmmmmmmbbbbbba",
+
+ // Connectors:
+ "1: 0, 1, 1: 4\n" /* Type 1, direction X- */
+ "-1: 0, 1, 2: 4\n" /* Type -1, direction X- */
+ "1: 15, 6, 2: 5\n" /* Type 1, direction X+ */
+ "-1: 15, 6, 1: 5\n" /* Type -1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // CorridorStairs
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CorridorTee:
+ // The data has been exported from the gallery Water, area index 29, ID 576, created by LO1ZB
+ {
+ // Size:
+ 16, 4, 10, // SizeX = 16, SizeY = 4, SizeZ = 10
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 15, 3, 9, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 5\n" /* wood */
+ "b: 5: 0\n" /* wood */
+ "c: 64: 3\n" /* wooddoorblock */
+ "d: 64: 6\n" /* wooddoorblock */
+ "e: 64: 5\n" /* wooddoorblock */
+ "f: 64: 0\n" /* wooddoorblock */
+ "g: 64: 2\n" /* wooddoorblock */
+ "h: 64: 8\n" /* wooddoorblock */
+ "i: 64:12\n" /* wooddoorblock */
+ "j: 20: 0\n" /* glass */
+ "k: 76: 1\n" /* redstonetorchon */
+ "l: 76: 2\n" /* redstonetorchon */
+ "m: 19: 0\n" /* sponge */
+ "n: 76: 3\n" /* redstonetorchon */
+ "o: 76: 4\n" /* redstonetorchon */
+ "p: 64: 9\n" /* wooddoorblock */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmaammmmmmm"
+ /* 1 */ "mmmmmmmbbmmmmmmm"
+ /* 2 */ "mmmmmmmbbmmmmmmm"
+ /* 3 */ "mmmmmmmbbmmmmmmm"
+ /* 4 */ "mmmmmmmbbmmmmmmm"
+ /* 5 */ "mmmmmmmbbmmmmmmm"
+ /* 6 */ "mmmmmmmbbmmmmmmm"
+ /* 7 */ "abbbbbbbbbbbbbba"
+ /* 8 */ "abbbbbbbbbbbbbba"
+ /* 9 */ "mmmmmmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmacdammmmmm"
+ /* 1 */ "mmmmmmb..bmmmmmm"
+ /* 2 */ "mmmmmmb..bmmmmmm"
+ /* 3 */ "mmmmmmb..bmmmmmm"
+ /* 4 */ "mmmmmmb..bmmmmmm"
+ /* 5 */ "mmmmmmb..bmmmmmm"
+ /* 6 */ "abbbbbb..bbbbbba"
+ /* 7 */ "e..............f"
+ /* 8 */ "g..............f"
+ /* 9 */ "abbbbbbbbbbbbbba"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmahiammmmmm"
+ /* 1 */ "mmmmmmb..bmmmmmm"
+ /* 2 */ "mmmmmmj..jmmmmmm"
+ /* 3 */ "mmmmmmj..jmmmmmm"
+ /* 4 */ "mmmmmmbklbmmmmmm"
+ /* 5 */ "mmmmmmb..bmmmmmm"
+ /* 6 */ "abjjbbb..bbbjjba"
+ /* 7 */ "i...n......n...h"
+ /* 8 */ "h...o......o...p"
+ /* 9 */ "abjjbbbjjbbbjjba"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmaaaammmmmm"
+ /* 1 */ "mmmmmmbbbbmmmmmm"
+ /* 2 */ "mmmmmmbbbbmmmmmm"
+ /* 3 */ "mmmmmmbbbbmmmmmm"
+ /* 4 */ "mmmmmmbbbbmmmmmm"
+ /* 5 */ "mmmmmmbbbbmmmmmm"
+ /* 6 */ "abbbbbbbbbbbbbba"
+ /* 7 */ "abbbbbbbbbbbbbba"
+ /* 8 */ "abbbbbbbbbbbbbba"
+ /* 9 */ "abbbbbbbbbbbbbba",
+
+ // Connectors:
+ "1: 0, 1, 7: 4\n" /* Type 1, direction X- */
+ "-1: 0, 1, 8: 4\n" /* Type -1, direction X- */
+ "1: 8, 1, 0: 2\n" /* Type 1, direction Z- */
+ "-1: 7, 1, 0: 2\n" /* Type -1, direction Z- */
+ "1: 15, 1, 8: 5\n" /* Type 1, direction X+ */
+ "-1: 15, 1, 7: 5\n" /* Type -1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // CorridorTee
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // ViewingCorner:
+ // The data has been exported from the gallery Water, area index 40, ID 613, created by LO1ZB
+ {
+ // Size:
+ 14, 7, 14, // SizeX = 14, SizeY = 7, SizeZ = 14
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 13, 6, 13, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 0\n" /* wood */
+ "b: 20: 0\n" /* glass */
+ "c: 5: 5\n" /* wood */
+ "d: 76: 3\n" /* redstonetorchon */
+ "e: 76: 1\n" /* redstonetorchon */
+ "f: 64: 0\n" /* wooddoorblock */
+ "g: 76: 4\n" /* redstonetorchon */
+ "h: 76: 2\n" /* redstonetorchon */
+ "i: 64: 1\n" /* wooddoorblock */
+ "j: 64: 8\n" /* wooddoorblock */
+ "k: 64: 9\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmaaaammmmmm"
+ /* 2 */ "mmmaabbaammmmm"
+ /* 3 */ "mmaabbbbaammmm"
+ /* 4 */ "maabbbbbbaammm"
+ /* 5 */ "mabbbbbbbbaaac"
+ /* 6 */ "mabbbbbbbbaaac"
+ /* 7 */ "maabbbbbbaammm"
+ /* 8 */ "mmaabbbbaammmm"
+ /* 9 */ "mmmaabbaammmmm"
+ /* 10 */ "mmmmaaaammmmmm"
+ /* 11 */ "mmmmmaammmmmmm"
+ /* 12 */ "mmmmmaammmmmmm"
+ /* 13 */ "mmmmmccmmmmmmm"
+
+ // Level 1
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmaammmmmmm"
+ /* 1 */ "mmmaaddaammmmm"
+ /* 2 */ "mmaa....aammmm"
+ /* 3 */ "maa......aammm"
+ /* 4 */ "ma........aaac"
+ /* 5 */ "ae........d..f"
+ /* 6 */ "ae........g..f"
+ /* 7 */ "ma........aaac"
+ /* 8 */ "maa......aammm"
+ /* 9 */ "mmaa....aammmm"
+ /* 10 */ "mmmaaehaammmmm"
+ /* 11 */ "mmmma..ammmmmm"
+ /* 12 */ "mmmma..ammmmmm"
+ /* 13 */ "mmmmciicmmmmmm"
+
+ // Level 2
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmbbmmmmmmm"
+ /* 1 */ "mmmbb..bbmmmmm"
+ /* 2 */ "mmbb....bbmmmm"
+ /* 3 */ "mbb......bbmmm"
+ /* 4 */ "mb........bbac"
+ /* 5 */ "b............j"
+ /* 6 */ "b............k"
+ /* 7 */ "mb........bbac"
+ /* 8 */ "mbb......bbmmm"
+ /* 9 */ "mmbb....bbmmmm"
+ /* 10 */ "mmmbb..bbmmmmm"
+ /* 11 */ "mmmmb..bmmmmmm"
+ /* 12 */ "mmmma..ammmmmm"
+ /* 13 */ "mmmmckjcmmmmmm"
+
+ // Level 3
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmbbmmmmmmm"
+ /* 1 */ "mmmbb..bbmmmmm"
+ /* 2 */ "mmbb....bbmmmm"
+ /* 3 */ "mbb......bbmmm"
+ /* 4 */ "mb........bbac"
+ /* 5 */ "b..........bac"
+ /* 6 */ "b..........bac"
+ /* 7 */ "mb........bbac"
+ /* 8 */ "mbb......bbmmm"
+ /* 9 */ "mmbb....bbmmmm"
+ /* 10 */ "mmmbb..bbmmmmm"
+ /* 11 */ "mmmmbbbbmmmmmm"
+ /* 12 */ "mmmmaaaammmmmm"
+ /* 13 */ "mmmmccccmmmmmm"
+
+ // Level 4
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmbbmmmmmmm"
+ /* 2 */ "mmmmb..bmmmmmm"
+ /* 3 */ "mmmb....bmmmmm"
+ /* 4 */ "mmb......bmmmm"
+ /* 5 */ "mb........bmmm"
+ /* 6 */ "mb........bmmm"
+ /* 7 */ "mmb......bmmmm"
+ /* 8 */ "mmmb....bmmmmm"
+ /* 9 */ "mmmmb..bmmmmmm"
+ /* 10 */ "mmmmmbbmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmm"
+ /* 12 */ "mmmmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmm"
+
+ // Level 5
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmbbmmmmmmm"
+ /* 3 */ "mmmmb..bmmmmmm"
+ /* 4 */ "mmmb....bmmmmm"
+ /* 5 */ "mmb......bmmmm"
+ /* 6 */ "mmb......bmmmm"
+ /* 7 */ "mmmb....bmmmmm"
+ /* 8 */ "mmmmb..bmmmmmm"
+ /* 9 */ "mmmmmbbmmmmmmm"
+ /* 10 */ "mmmmmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmm"
+ /* 12 */ "mmmmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmm"
+
+ // Level 6
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmbbmmmmmmm"
+ /* 4 */ "mmmmbbbbmmmmmm"
+ /* 5 */ "mmmbbbbbbmmmmm"
+ /* 6 */ "mmmbbbbbbmmmmm"
+ /* 7 */ "mmmmbbbbmmmmmm"
+ /* 8 */ "mmmmmbbmmmmmmm"
+ /* 9 */ "mmmmmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmm"
+ /* 12 */ "mmmmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmm",
+
+ // Connectors:
+ "1: 13, 1, 6: 5\n" /* Type 1, direction X+ */
+ "-1: 13, 1, 5: 5\n" /* Type -1, direction X+ */
+ "1: 5, 1, 13: 3\n" /* Type 1, direction Z+ */
+ "-1: 6, 1, 13: 3\n" /* Type -1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // ViewingCorner
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // ViewingCorridor:
+ // The data has been exported from the gallery Water, area index 27, ID 571, created by LO1ZB
+ {
+ // Size:
+ 16, 5, 6, // SizeX = 16, SizeY = 5, SizeZ = 6
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 15, 4, 5, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 0\n" /* wood */
+ "b: 5: 5\n" /* wood */
+ "c: 20: 0\n" /* glass */
+ "d: 64: 5\n" /* wooddoorblock */
+ "e: 64: 0\n" /* wooddoorblock */
+ "f: 64: 2\n" /* wooddoorblock */
+ "g: 76: 3\n" /* redstonetorchon */
+ "h: 64:12\n" /* wooddoorblock */
+ "i: 64: 8\n" /* wooddoorblock */
+ "j: 64: 9\n" /* wooddoorblock */
+ "k: 76: 4\n" /* redstonetorchon */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmaaaaaaaaaaaamm"
+ /* 1 */ "mmaaaaaaaaaaaamm"
+ /* 2 */ "baaccccccccccaab"
+ /* 3 */ "baaccccccccccaab"
+ /* 4 */ "mmaaaaaaaaaaaamm"
+ /* 5 */ "mmmaaaaaaaaaammm"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmaccccccccccamm"
+ /* 1 */ "ba............ab"
+ /* 2 */ "d..............e"
+ /* 3 */ "f..............e"
+ /* 4 */ "ba............ab"
+ /* 5 */ "mmaccccccccccamm"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmaccccccccccamm"
+ /* 1 */ "bag..........gab"
+ /* 2 */ "h..............i"
+ /* 3 */ "i..............j"
+ /* 4 */ "bak..........kab"
+ /* 5 */ "mmaccccccccccamm"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmaccccccccccamm"
+ /* 1 */ "ba............ab"
+ /* 2 */ "ba............ab"
+ /* 3 */ "ba............ab"
+ /* 4 */ "ba............ab"
+ /* 5 */ "mmaccccccccccamm"
+
+ // Level 4
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmaaaaaaaaaammm"
+ /* 1 */ "mmaaaaaaaaaaaamm"
+ /* 2 */ "mmaccccccccccamm"
+ /* 3 */ "mmaccccccccccamm"
+ /* 4 */ "mmaaaaaaaaaaaamm"
+ /* 5 */ "mmmaaaaaaaaaammm",
+
+ // Connectors:
+ "1: 0, 1, 2: 4\n" /* Type 1, direction X- */
+ "-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
+ "1: 15, 1, 3: 5\n" /* Type 1, direction X+ */
+ "-1: 15, 1, 2: 5\n" /* Type -1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // ViewingCorridor
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // ViewingCorridorBulge:
+ // The data has been exported from the gallery Water, area index 42, ID 615, created by LO1ZB
+ {
+ // Size:
+ 12, 8, 16, // SizeX = 12, SizeY = 8, SizeZ = 16
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 11, 7, 15, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 5\n" /* wood */
+ "b: 5: 0\n" /* wood */
+ "c: 20: 0\n" /* glass */
+ "d: 64: 3\n" /* wooddoorblock */
+ "e: 76: 1\n" /* redstonetorchon */
+ "f: 76: 2\n" /* redstonetorchon */
+ "g: 64: 1\n" /* wooddoorblock */
+ "h: 64: 8\n" /* wooddoorblock */
+ "i: 64: 9\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "mmmmmaammmmm"
+ /* 1 */ "mmmmmbbmmmmm"
+ /* 2 */ "mmmmmbbmmmmm"
+ /* 3 */ "mmmmbbbbmmmm"
+ /* 4 */ "mmmbbccbbmmm"
+ /* 5 */ "mmbbccccbbmm"
+ /* 6 */ "mbbccccccbbm"
+ /* 7 */ "mbccccccccbm"
+ /* 8 */ "mbccccccccbm"
+ /* 9 */ "mbbccccccbbm"
+ /* 10 */ "mmbbccccbbmm"
+ /* 11 */ "mmmbbccbbmmm"
+ /* 12 */ "mmmmbbbbmmmm"
+ /* 13 */ "mmmmmbbmmmmm"
+ /* 14 */ "mmmmmbbmmmmm"
+ /* 15 */ "mmmmmaammmmm"
+
+ // Level 1
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "mmmmaddammmm"
+ /* 1 */ "mmmmb..bmmmm"
+ /* 2 */ "mmmmb..bmmmm"
+ /* 3 */ "mmmbbefbbmmm"
+ /* 4 */ "mmbb....bbmm"
+ /* 5 */ "mbb......bbm"
+ /* 6 */ "mb........bm"
+ /* 7 */ "be........fb"
+ /* 8 */ "be........fb"
+ /* 9 */ "mb........bm"
+ /* 10 */ "mbb......bbm"
+ /* 11 */ "mmbb....bbmm"
+ /* 12 */ "mmmbbefbbmmm"
+ /* 13 */ "mmmmb..bmmmm"
+ /* 14 */ "mmmmb..bmmmm"
+ /* 15 */ "mmmmaggammmm"
+
+ // Level 2
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "mmmmahiammmm"
+ /* 1 */ "mmmmb..bmmmm"
+ /* 2 */ "mmmmc..cmmmm"
+ /* 3 */ "mmmcc..ccmmm"
+ /* 4 */ "mmcc....ccmm"
+ /* 5 */ "mcc......ccm"
+ /* 6 */ "mc........cm"
+ /* 7 */ "c..........c"
+ /* 8 */ "c..........c"
+ /* 9 */ "mc........cm"
+ /* 10 */ "mcc......ccm"
+ /* 11 */ "mmcc....ccmm"
+ /* 12 */ "mmmcc..ccmmm"
+ /* 13 */ "mmmmc..cmmmm"
+ /* 14 */ "mmmmb..bmmmm"
+ /* 15 */ "mmmmaihammmm"
+
+ // Level 3
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "mmmmaaaammmm"
+ /* 1 */ "mmmmbbbbmmmm"
+ /* 2 */ "mmmmccccmmmm"
+ /* 3 */ "mmmcc..ccmmm"
+ /* 4 */ "mmcc....ccmm"
+ /* 5 */ "mcc......ccm"
+ /* 6 */ "mc........cm"
+ /* 7 */ "c..........c"
+ /* 8 */ "c..........c"
+ /* 9 */ "mc........cm"
+ /* 10 */ "mcc......ccm"
+ /* 11 */ "mmcc....ccmm"
+ /* 12 */ "mmmcc..ccmmm"
+ /* 13 */ "mmmmccccmmmm"
+ /* 14 */ "mmmmbbbbmmmm"
+ /* 15 */ "mmmmaaaammmm"
+
+ // Level 4
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "mmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmm"
+ /* 3 */ "mmmmmccmmmmm"
+ /* 4 */ "mmmmc..cmmmm"
+ /* 5 */ "mmmc....cmmm"
+ /* 6 */ "mmc......cmm"
+ /* 7 */ "mc........cm"
+ /* 8 */ "mc........cm"
+ /* 9 */ "mmc......cmm"
+ /* 10 */ "mmmc....cmmm"
+ /* 11 */ "mmmmc..cmmmm"
+ /* 12 */ "mmmmmccmmmmm"
+ /* 13 */ "mmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmm"
+
+ // Level 5
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "mmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmmm"
+ /* 4 */ "mmmmmccmmmmm"
+ /* 5 */ "mmmmc..cmmmm"
+ /* 6 */ "mmmc....cmmm"
+ /* 7 */ "mmc......cmm"
+ /* 8 */ "mmc......cmm"
+ /* 9 */ "mmmc....cmmm"
+ /* 10 */ "mmmmc..cmmmm"
+ /* 11 */ "mmmmmccmmmmm"
+ /* 12 */ "mmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmm"
+
+ // Level 6
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "mmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmmm"
+ /* 4 */ "mmmmmmmmmmmm"
+ /* 5 */ "mmmmmccmmmmm"
+ /* 6 */ "mmmmccccmmmm"
+ /* 7 */ "mmmccccccmmm"
+ /* 8 */ "mmmccccccmmm"
+ /* 9 */ "mmmmccccmmmm"
+ /* 10 */ "mmmmmccmmmmm"
+ /* 11 */ "mmmmmmmmmmmm"
+ /* 12 */ "mmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmm"
+
+ // Level 7
+ /* z\x* 11 */
+ /* * 012345678901 */
+ /* 0 */ "mmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmmm"
+ /* 4 */ "mmmmmmmmmmmm"
+ /* 5 */ "mmmmmmmmmmmm"
+ /* 6 */ "mmmmmmmmmmmm"
+ /* 7 */ "mmmmmmmmmmmm"
+ /* 8 */ "mmmmmmmmmmmm"
+ /* 9 */ "mmmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmm"
+ /* 12 */ "mmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmm",
+
+ // Connectors:
+ "1: 6, 1, 0: 2\n" /* Type 1, direction Z- */
+ "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */
+ "1: 5, 1, 15: 3\n" /* Type 1, direction Z+ */
+ "-1: 6, 1, 15: 3\n" /* Type -1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // ViewingCorridorBulge
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // ViewingCrossing:
+ // The data has been exported from the gallery Water, area index 38, ID 611, created by LO1ZB
+ {
+ // Size:
+ 16, 7, 16, // SizeX = 16, SizeY = 7, SizeZ = 16
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 15, 6, 15, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 5\n" /* wood */
+ "b: 5: 0\n" /* wood */
+ "c: 20: 0\n" /* glass */
+ "d: 64: 3\n" /* wooddoorblock */
+ "e: 76: 1\n" /* redstonetorchon */
+ "f: 76: 2\n" /* redstonetorchon */
+ "g: 64: 2\n" /* wooddoorblock */
+ "h: 76: 3\n" /* redstonetorchon */
+ "i: 64: 0\n" /* wooddoorblock */
+ "j: 76: 4\n" /* redstonetorchon */
+ "k: 64: 1\n" /* wooddoorblock */
+ "l: 64: 8\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */
+ "n: 64: 9\n" /* wooddoorblock */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmaammmmmmm"
+ /* 1 */ "mmmmmmmbbmmmmmmm"
+ /* 2 */ "mmmmmmmbbmmmmmmm"
+ /* 3 */ "mmmmmmbbbbmmmmmm"
+ /* 4 */ "mmmmmbbccbbmmmmm"
+ /* 5 */ "mmmmbbccccbbmmmm"
+ /* 6 */ "mmmbbccccccbbmmm"
+ /* 7 */ "abbbccccccccbbba"
+ /* 8 */ "abbbccccccccbbba"
+ /* 9 */ "mmmbbccccccbbmmm"
+ /* 10 */ "mmmmbbccccbbmmmm"
+ /* 11 */ "mmmmmbbccbbmmmmm"
+ /* 12 */ "mmmmmmbbbbmmmmmm"
+ /* 13 */ "mmmmmmmbbmmmmmmm"
+ /* 14 */ "mmmmmmmbbmmmmmmm"
+ /* 15 */ "mmmmmmmaammmmmmm"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmaddammmmmm"
+ /* 1 */ "mmmmmmb..bmmmmmm"
+ /* 2 */ "mmmmmmb..bmmmmmm"
+ /* 3 */ "mmmmmbbefbbmmmmm"
+ /* 4 */ "mmmmbb....bbmmmm"
+ /* 5 */ "mmmbb......bbmmm"
+ /* 6 */ "abbb........bbba"
+ /* 7 */ "g..h........h..i"
+ /* 8 */ "g..j........j..i"
+ /* 9 */ "abbb........bbba"
+ /* 10 */ "mmmbb......bbmmm"
+ /* 11 */ "mmmmbb....bbmmmm"
+ /* 12 */ "mmmmmbbefbbmmmmm"
+ /* 13 */ "mmmmmmb..bmmmmmm"
+ /* 14 */ "mmmmmmb..bmmmmmm"
+ /* 15 */ "mmmmmmakkammmmmm"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmalnammmmmm"
+ /* 1 */ "mmmmmmb..bmmmmmm"
+ /* 2 */ "mmmmmmc..cmmmmmm"
+ /* 3 */ "mmmmmcc..ccmmmmm"
+ /* 4 */ "mmmmcc....ccmmmm"
+ /* 5 */ "mmmcc......ccmmm"
+ /* 6 */ "abcc........ccba"
+ /* 7 */ "n..............l"
+ /* 8 */ "l..............n"
+ /* 9 */ "abcc........ccba"
+ /* 10 */ "mmmcc......ccmmm"
+ /* 11 */ "mmmmcc....ccmmmm"
+ /* 12 */ "mmmmmcc..ccmmmmm"
+ /* 13 */ "mmmmmmc..cmmmmmm"
+ /* 14 */ "mmmmmmb..bmmmmmm"
+ /* 15 */ "mmmmmmanlammmmmm"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmaaaammmmmm"
+ /* 1 */ "mmmmmmbbbbmmmmmm"
+ /* 2 */ "mmmmmmccccmmmmmm"
+ /* 3 */ "mmmmmcc..ccmmmmm"
+ /* 4 */ "mmmmcc....ccmmmm"
+ /* 5 */ "mmmcc......ccmmm"
+ /* 6 */ "abcc........ccba"
+ /* 7 */ "abc..........cba"
+ /* 8 */ "abc..........cba"
+ /* 9 */ "abcc........ccba"
+ /* 10 */ "mmmcc......ccmmm"
+ /* 11 */ "mmmmcc....ccmmmm"
+ /* 12 */ "mmmmmcc..ccmmmmm"
+ /* 13 */ "mmmmmmccccmmmmmm"
+ /* 14 */ "mmmmmmbbbbmmmmmm"
+ /* 15 */ "mmmmmmaaaammmmmm"
+
+ // Level 4
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmccmmmmmmm"
+ /* 4 */ "mmmmmmc..cmmmmmm"
+ /* 5 */ "mmmmmc....cmmmmm"
+ /* 6 */ "mmmmc......cmmmm"
+ /* 7 */ "mmmc........cmmm"
+ /* 8 */ "mmmc........cmmm"
+ /* 9 */ "mmmmc......cmmmm"
+ /* 10 */ "mmmmmc....cmmmmm"
+ /* 11 */ "mmmmmmc..cmmmmmm"
+ /* 12 */ "mmmmmmmccmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmmmmmm"
+
+ // Level 5
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmmmmmmm"
+ /* 4 */ "mmmmmmmccmmmmmmm"
+ /* 5 */ "mmmmmmc..cmmmmmm"
+ /* 6 */ "mmmmmc....cmmmmm"
+ /* 7 */ "mmmmc......cmmmm"
+ /* 8 */ "mmmmc......cmmmm"
+ /* 9 */ "mmmmmc....cmmmmm"
+ /* 10 */ "mmmmmmc..cmmmmmm"
+ /* 11 */ "mmmmmmmccmmmmmmm"
+ /* 12 */ "mmmmmmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmmmmmm"
+
+ // Level 6
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmmmmmmm"
+ /* 4 */ "mmmmmmmmmmmmmmmm"
+ /* 5 */ "mmmmmmmccmmmmmmm"
+ /* 6 */ "mmmmmmccccmmmmmm"
+ /* 7 */ "mmmmmccccccmmmmm"
+ /* 8 */ "mmmmmccccccmmmmm"
+ /* 9 */ "mmmmmmccccmmmmmm"
+ /* 10 */ "mmmmmmmccmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmmmm"
+ /* 12 */ "mmmmmmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmmmmmm",
+
+ // Connectors:
+ "1: 0, 1, 7: 4\n" /* Type 1, direction X- */
+ "-1: 0, 1, 8: 4\n" /* Type -1, direction X- */
+ "1: 8, 1, 0: 2\n" /* Type 1, direction Z- */
+ "-1: 7, 1, 0: 2\n" /* Type -1, direction Z- */
+ "1: 15, 1, 8: 5\n" /* Type 1, direction X+ */
+ "-1: 15, 1, 7: 5\n" /* Type -1, direction X+ */
+ "1: 7, 1, 15: 3\n" /* Type 1, direction Z+ */
+ "-1: 8, 1, 15: 3\n" /* Type -1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 50,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // ViewingCrossing
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // ViewingEnd:
+ // The data has been exported from the gallery Water, area index 41, ID 614, created by LO1ZB
+ {
+ // Size:
+ 14, 7, 12, // SizeX = 14, SizeY = 7, SizeZ = 12
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 13, 6, 11, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 0\n" /* wood */
+ "b: 20: 0\n" /* glass */
+ "c: 5: 5\n" /* wood */
+ "d: 76: 3\n" /* redstonetorchon */
+ "e: 76: 1\n" /* redstonetorchon */
+ "f: 64: 0\n" /* wooddoorblock */
+ "g: 76: 4\n" /* redstonetorchon */
+ "h: 64: 8\n" /* wooddoorblock */
+ "i: 64: 9\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmaaaammmmmm"
+ /* 2 */ "mmmaabbaammmmm"
+ /* 3 */ "mmaabbbbaammmm"
+ /* 4 */ "maabbbbbbaammm"
+ /* 5 */ "mabbbbbbbbaaac"
+ /* 6 */ "mabbbbbbbbaaac"
+ /* 7 */ "maabbbbbbaammm"
+ /* 8 */ "mmaabbbbaammmm"
+ /* 9 */ "mmmaabbaammmmm"
+ /* 10 */ "mmmmaaaammmmmm"
+ /* 11 */ "mmmmmmmmmmmmmm"
+
+ // Level 1
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmaammmmmmm"
+ /* 1 */ "mmmaaddaammmmm"
+ /* 2 */ "mmaa....aammmm"
+ /* 3 */ "maa......aammm"
+ /* 4 */ "ma........aaac"
+ /* 5 */ "ae........d..f"
+ /* 6 */ "ae........g..f"
+ /* 7 */ "ma........aaac"
+ /* 8 */ "maa......aammm"
+ /* 9 */ "mmaa....aammmm"
+ /* 10 */ "mmmaaggaammmmm"
+ /* 11 */ "mmmmmaammmmmmm"
+
+ // Level 2
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmbbmmmmmmm"
+ /* 1 */ "mmmbb..bbmmmmm"
+ /* 2 */ "mmbb....bbmmmm"
+ /* 3 */ "mbb......bbmmm"
+ /* 4 */ "mb........bbac"
+ /* 5 */ "b............h"
+ /* 6 */ "b............i"
+ /* 7 */ "mb........bbac"
+ /* 8 */ "mbb......bbmmm"
+ /* 9 */ "mmbb....bbmmmm"
+ /* 10 */ "mmmbb..bbmmmmm"
+ /* 11 */ "mmmmmbbmmmmmmm"
+
+ // Level 3
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmbbmmmmmmm"
+ /* 1 */ "mmmbb..bbmmmmm"
+ /* 2 */ "mmbb....bbmmmm"
+ /* 3 */ "mbb......bbmmm"
+ /* 4 */ "mb........bbac"
+ /* 5 */ "b..........bac"
+ /* 6 */ "b..........bac"
+ /* 7 */ "mb........bbac"
+ /* 8 */ "mbb......bbmmm"
+ /* 9 */ "mmbb....bbmmmm"
+ /* 10 */ "mmmbb..bbmmmmm"
+ /* 11 */ "mmmmmbbmmmmmmm"
+
+ // Level 4
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmbbmmmmmmm"
+ /* 2 */ "mmmmb..bmmmmmm"
+ /* 3 */ "mmmb....bmmmmm"
+ /* 4 */ "mmb......bmmmm"
+ /* 5 */ "mb........bmmm"
+ /* 6 */ "mb........bmmm"
+ /* 7 */ "mmb......bmmmm"
+ /* 8 */ "mmmb....bmmmmm"
+ /* 9 */ "mmmmb..bmmmmmm"
+ /* 10 */ "mmmmmbbmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmm"
+
+ // Level 5
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmbbmmmmmmm"
+ /* 3 */ "mmmmb..bmmmmmm"
+ /* 4 */ "mmmb....bmmmmm"
+ /* 5 */ "mmb......bmmmm"
+ /* 6 */ "mmb......bmmmm"
+ /* 7 */ "mmmb....bmmmmm"
+ /* 8 */ "mmmmb..bmmmmmm"
+ /* 9 */ "mmmmmbbmmmmmmm"
+ /* 10 */ "mmmmmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmm"
+
+ // Level 6
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmbbmmmmmmm"
+ /* 4 */ "mmmmbbbbmmmmmm"
+ /* 5 */ "mmmbbbbbbmmmmm"
+ /* 6 */ "mmmbbbbbbmmmmm"
+ /* 7 */ "mmmmbbbbmmmmmm"
+ /* 8 */ "mmmmmbbmmmmmmm"
+ /* 9 */ "mmmmmmmmmmmmmm"
+ /* 10 */ "mmmmmmmmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmm",
+
+ // Connectors:
+ "1: 13, 1, 6: 5\n" /* Type 1, direction X+ */
+ "-1: 13, 1, 5: 5\n" /* Type -1, direction X+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 200,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // ViewingEnd
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // ViewingTee:
+ // The data has been exported from the gallery Water, area index 39, ID 612, created by LO1ZB
+ {
+ // Size:
+ 14, 7, 17, // SizeX = 14, SizeY = 7, SizeZ = 17
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 13, 6, 16, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 5\n" /* wood */
+ "b: 5: 0\n" /* wood */
+ "c: 20: 0\n" /* glass */
+ "d: 1: 0\n" /* stone */
+ "e: 64: 3\n" /* wooddoorblock */
+ "f: 76: 1\n" /* redstonetorchon */
+ "g: 76: 2\n" /* redstonetorchon */
+ "h: 76: 3\n" /* redstonetorchon */
+ "i: 64: 0\n" /* wooddoorblock */
+ "j: 76: 4\n" /* redstonetorchon */
+ "k: 64: 1\n" /* wooddoorblock */
+ "l: 64: 8\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmaammmmmmm"
+ /* 1 */ "mmmmmbbmmmmmmm"
+ /* 2 */ "mmmmmbbmmmmmmm"
+ /* 3 */ "mmmmbbbbmmmmmm"
+ /* 4 */ "mmmbbccbbmmmmm"
+ /* 5 */ "mmbbccccbbmmmm"
+ /* 6 */ "mbbccccccbbmmm"
+ /* 7 */ "mbccccccccbbba"
+ /* 8 */ "mbccccccccbbba"
+ /* 9 */ "mbbccccccbbmmm"
+ /* 10 */ "mmbbccccbbmmmm"
+ /* 11 */ "mmmbbccbbmmmmm"
+ /* 12 */ "mmmmbbbbmmmmmm"
+ /* 13 */ "mmmmmbbmmmmmmm"
+ /* 14 */ "mmmmmbbmmmmmmm"
+ /* 15 */ "mmmmmaammmmmmm"
+ /* 16 */ "dddddddddddddd"
+
+ // Level 1
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmaeeammmmmm"
+ /* 1 */ "mmmmb..bmmmmmm"
+ /* 2 */ "mmmmb..bmmmmmm"
+ /* 3 */ "mmmbbfgbbmmmmm"
+ /* 4 */ "mmbb....bbmmmm"
+ /* 5 */ "mbb......bbmmm"
+ /* 6 */ "mb........bbba"
+ /* 7 */ "bf........h..i"
+ /* 8 */ "bf........j..i"
+ /* 9 */ "mb........bbba"
+ /* 10 */ "mbb......bbmmm"
+ /* 11 */ "mmbb....bbmmmm"
+ /* 12 */ "mmmbbfgbbmmmmm"
+ /* 13 */ "mmmmb..bmmmmmm"
+ /* 14 */ "mmmmb..bmmmmmm"
+ /* 15 */ "mmmmakkammmmmm"
+ /* 16 */ "dddddddddddddd"
+
+ // Level 2
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmallammmmmm"
+ /* 1 */ "mmmmb..bmmmmmm"
+ /* 2 */ "mmmmc..cmmmmmm"
+ /* 3 */ "mmmcc..ccmmmmm"
+ /* 4 */ "mmcc....ccmmmm"
+ /* 5 */ "mcc......ccmmm"
+ /* 6 */ "mc........ccba"
+ /* 7 */ "c............l"
+ /* 8 */ "c............l"
+ /* 9 */ "mc........ccba"
+ /* 10 */ "mcc......ccmmm"
+ /* 11 */ "mmcc....ccmmmm"
+ /* 12 */ "mmmcc..ccmmmmm"
+ /* 13 */ "mmmmc..cmmmmmm"
+ /* 14 */ "mmmmb..bmmmmmm"
+ /* 15 */ "mmmmallammmmmm"
+ /* 16 */ "dddddddddddddd"
+
+ // Level 3
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmaaaammmmmm"
+ /* 1 */ "mmmmbbbbmmmmmm"
+ /* 2 */ "mmmmccccmmmmmm"
+ /* 3 */ "mmmcc..ccmmmmm"
+ /* 4 */ "mmcc....ccmmmm"
+ /* 5 */ "mcc......ccmmm"
+ /* 6 */ "mc........ccba"
+ /* 7 */ "c..........cba"
+ /* 8 */ "c..........cba"
+ /* 9 */ "mc........ccba"
+ /* 10 */ "mcc......ccmmm"
+ /* 11 */ "mmcc....ccmmmm"
+ /* 12 */ "mmmcc..ccmmmmm"
+ /* 13 */ "mmmmccccmmmmmm"
+ /* 14 */ "mmmmbbbbmmmmmm"
+ /* 15 */ "mmmmaaaammmmmm"
+ /* 16 */ "dddddddddddddd"
+
+ // Level 4
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmccmmmmmmm"
+ /* 4 */ "mmmmc..cmmmmmm"
+ /* 5 */ "mmmc....cmmmmm"
+ /* 6 */ "mmc......cmmmm"
+ /* 7 */ "mc........cmmm"
+ /* 8 */ "mc........cmmm"
+ /* 9 */ "mmc......cmmmm"
+ /* 10 */ "mmmc....cmmmmm"
+ /* 11 */ "mmmmc..cmmmmmm"
+ /* 12 */ "mmmmmccmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmmmm"
+ /* 16 */ "dddddddddddddd"
+
+ // Level 5
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmmmmm"
+ /* 4 */ "mmmmmccmmmmmmm"
+ /* 5 */ "mmmmc..cmmmmmm"
+ /* 6 */ "mmmc....cmmmmm"
+ /* 7 */ "mmc......cmmmm"
+ /* 8 */ "mmc......cmmmm"
+ /* 9 */ "mmmc....cmmmmm"
+ /* 10 */ "mmmmc..cmmmmmm"
+ /* 11 */ "mmmmmccmmmmmmm"
+ /* 12 */ "mmmmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmmmm"
+ /* 16 */ "dddddddddddddd"
+
+ // Level 6
+ /* z\x* 1111 */
+ /* * 01234567890123 */
+ /* 0 */ "mmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmmmmm"
+ /* 4 */ "mmmmmmmmmmmmmm"
+ /* 5 */ "mmmmmccmmmmmmm"
+ /* 6 */ "mmmmccccmmmmmm"
+ /* 7 */ "mmmccccccmmmmm"
+ /* 8 */ "mmmccccccmmmmm"
+ /* 9 */ "mmmmccccmmmmmm"
+ /* 10 */ "mmmmmccmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmm"
+ /* 12 */ "mmmmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmmmm"
+ /* 16 */ "dddddddddddddd",
+
+ // Connectors:
+ "",
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 75,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // ViewingTee
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WaterfallRoom:
+ // The data has been exported from the gallery Water, area index 50, ID 681, created by Aloe_vera
+ {
+ // Size:
+ 16, 7, 16, // SizeX = 16, SizeY = 7, SizeZ = 16
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 15, 6, 15, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 5\n" /* wood */
+ "b: 5: 0\n" /* wood */
+ "c: 20: 0\n" /* glass */
+ "d: 64: 3\n" /* wooddoorblock */
+ "e: 76: 1\n" /* redstonetorchon */
+ "f: 76: 2\n" /* redstonetorchon */
+ "g: 64: 2\n" /* wooddoorblock */
+ "h: 76: 3\n" /* redstonetorchon */
+ "i: 64: 0\n" /* wooddoorblock */
+ "j: 76: 4\n" /* redstonetorchon */
+ "k: 64: 1\n" /* wooddoorblock */
+ "l: 64: 8\n" /* wooddoorblock */
+ "m: 19: 0\n" /* sponge */
+ "n: 64: 9\n" /* wooddoorblock */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmaammmmmmm"
+ /* 1 */ "mmmmmmmbbmmmmmmm"
+ /* 2 */ "mmmmmmmbbmmmmmmm"
+ /* 3 */ "mmmmmmbbbbmmmmmm"
+ /* 4 */ "mmmmmbbccbbmmmmm"
+ /* 5 */ "mmmmbbccccbbmmmm"
+ /* 6 */ "mmmbbccccccbbmmm"
+ /* 7 */ "abbbcccmmcccbbba"
+ /* 8 */ "abbbcccmmcccbbba"
+ /* 9 */ "mmmbbccccccbbmmm"
+ /* 10 */ "mmmmbbccccbbmmmm"
+ /* 11 */ "mmmmmbbccbbmmmmm"
+ /* 12 */ "mmmmmmbbbbmmmmmm"
+ /* 13 */ "mmmmmmmbbmmmmmmm"
+ /* 14 */ "mmmmmmmbbmmmmmmm"
+ /* 15 */ "mmmmmmmaammmmmmm"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmaddammmmmm"
+ /* 1 */ "mmmmmmb..bmmmmmm"
+ /* 2 */ "mmmmmmb..bmmmmmm"
+ /* 3 */ "mmmmmbbefbbmmmmm"
+ /* 4 */ "mmmmbb....bbmmmm"
+ /* 5 */ "mmmbb......bbmmm"
+ /* 6 */ "abbb...cc...bbba"
+ /* 7 */ "g..h..c..c..h..i"
+ /* 8 */ "g..j..c..c..j..i"
+ /* 9 */ "abbb...cc...bbba"
+ /* 10 */ "mmmbb......bbmmm"
+ /* 11 */ "mmmmbb....bbmmmm"
+ /* 12 */ "mmmmmbbefbbmmmmm"
+ /* 13 */ "mmmmmmb..bmmmmmm"
+ /* 14 */ "mmmmmmb..bmmmmmm"
+ /* 15 */ "mmmmmmakkammmmmm"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmalnammmmmm"
+ /* 1 */ "mmmmmmb..bmmmmmm"
+ /* 2 */ "mmmmmmc..cmmmmmm"
+ /* 3 */ "mmmmmcc..ccmmmmm"
+ /* 4 */ "mmmmcc....ccmmmm"
+ /* 5 */ "mmmcc......ccmmm"
+ /* 6 */ "abcc........ccba"
+ /* 7 */ "n..............l"
+ /* 8 */ "l..............n"
+ /* 9 */ "abcc........ccba"
+ /* 10 */ "mmmcc......ccmmm"
+ /* 11 */ "mmmmcc....ccmmmm"
+ /* 12 */ "mmmmmcc..ccmmmmm"
+ /* 13 */ "mmmmmmc..cmmmmmm"
+ /* 14 */ "mmmmmmb..bmmmmmm"
+ /* 15 */ "mmmmmmanlammmmmm"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmaaaammmmmm"
+ /* 1 */ "mmmmmmbbbbmmmmmm"
+ /* 2 */ "mmmmmmccccmmmmmm"
+ /* 3 */ "mmmmmcc..ccmmmmm"
+ /* 4 */ "mmmmcc....ccmmmm"
+ /* 5 */ "mmmcc......ccmmm"
+ /* 6 */ "abcc........ccba"
+ /* 7 */ "abc..........cba"
+ /* 8 */ "abc..........cba"
+ /* 9 */ "abcc........ccba"
+ /* 10 */ "mmmcc......ccmmm"
+ /* 11 */ "mmmmcc....ccmmmm"
+ /* 12 */ "mmmmmcc..ccmmmmm"
+ /* 13 */ "mmmmmmccccmmmmmm"
+ /* 14 */ "mmmmmmbbbbmmmmmm"
+ /* 15 */ "mmmmmmaaaammmmmm"
+
+ // Level 4
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmccmmmmmmm"
+ /* 4 */ "mmmmm.c..cmmmmmm"
+ /* 5 */ "mmmmmc....cmmmmm"
+ /* 6 */ "mmmmc......cmmmm"
+ /* 7 */ "mmmc........cmmm"
+ /* 8 */ "mmmc........cmmm"
+ /* 9 */ "mmmmc......cmmmm"
+ /* 10 */ "mmmmmc....cmmmmm"
+ /* 11 */ "mmmmmmc..cmmmmmm"
+ /* 12 */ "mmmmmmmccmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmmmmmm"
+
+ // Level 5
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmmmmmmm"
+ /* 4 */ "mmmmmm.ccmmmmmmm"
+ /* 5 */ "mmmmmmc..cmmmmmm"
+ /* 6 */ "mmmmmc....cmmmmm"
+ /* 7 */ "mmmmc......cmmmm"
+ /* 8 */ "mmmmc......cmmmm"
+ /* 9 */ "mmmmmc....cmmmmm"
+ /* 10 */ "mmmmmmc..cmmmmmm"
+ /* 11 */ "mmmmmmmccmmmmmmm"
+ /* 12 */ "mmmmmmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmmmmmm"
+
+ // Level 6
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmmmmmmm"
+ /* 4 */ "mmmmmmmmmmmmmmmm"
+ /* 5 */ "mmmmmmmccmmmmmmm"
+ /* 6 */ "mmmmmmccccmmmmmm"
+ /* 7 */ "mmmmmcc..ccmmmmm"
+ /* 8 */ "mmmmmcc..ccmmmmm"
+ /* 9 */ "mmmmmmccccmmmmmm"
+ /* 10 */ "mmmmmmmccmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmmmm"
+ /* 12 */ "mmmmmmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmmmmmm",
+
+ // Connectors:
+ "1: 15, 1, 8: 5\n" /* Type 1, direction X+ */
+ "-1: 15, 1, 7: 5\n" /* Type -1, direction X+ */
+ "1: 8, 1, 0: 2\n" /* Type 1, direction Z- */
+ "-1: 7, 1, 0: 2\n" /* Type -1, direction Z- */
+ "1: 0, 1, 7: 4\n" /* Type 1, direction X- */
+ "-1: 0, 1, 8: 4\n" /* Type -1, direction X- */
+ "1: 7, 1, 15: 3\n" /* Type 1, direction Z+ */
+ "-1: 8, 1, 15: 3\n" /* Type -1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 5,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // WaterfallRoom
+}; // g_UnderwaterBasePrefabs
+
+
+
+
+
+
+const cPrefab::sDef g_UnderwaterBaseStartingPrefabs[] =
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CentralRoom:
+ // The data has been exported from the gallery Water, area index 24, ID 564, created by xoft
+ {
+ // Size:
+ 16, 7, 16, // SizeX = 16, SizeY = 7, SizeZ = 16
+
+ // Hitbox (relative to bounding box):
+ 0, 0, 0, // MinX, MinY, MinZ
+ 15, 6, 15, // MaxX, MaxY, MaxZ
+
+ // Block definitions:
+ ".: 0: 0\n" /* air */
+ "a: 5: 5\n" /* wood */
+ "b: 5: 0\n" /* wood */
+ "c: 20: 0\n" /* glass */
+ "d: 64: 3\n" /* wooddoorblock */
+ "e: 64: 2\n" /* wooddoorblock */
+ "f: 64: 0\n" /* wooddoorblock */
+ "g: 64: 1\n" /* wooddoorblock */
+ "h: 64: 8\n" /* wooddoorblock */
+ "i: 64: 9\n" /* wooddoorblock */
+ "j: 76: 3\n" /* redstonetorchon */
+ "k: 76: 1\n" /* redstonetorchon */
+ "l: 76: 2\n" /* redstonetorchon */
+ "m: 19: 0\n" /* sponge */
+ "n: 76: 4\n" /* redstonetorchon */
+ "o:125: 8\n" /* woodendoubleslab */,
+
+ // Block data:
+ // Level 0
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmaammmmmmm"
+ /* 1 */ "mmmmmmmbbmmmmmmm"
+ /* 2 */ "mmmmmmmbbmmmmmmm"
+ /* 3 */ "mmmmmmbbbbmmmmmm"
+ /* 4 */ "mmmmmbbbbbbmmmmm"
+ /* 5 */ "mmmmbbbccbbbmmmm"
+ /* 6 */ "mmmbbbccccbbbmmm"
+ /* 7 */ "abbbbccccccbbbba"
+ /* 8 */ "abbbbccccccbbbba"
+ /* 9 */ "mmmbbbccccbbbmmm"
+ /* 10 */ "mmmmbbbccbbbmmmm"
+ /* 11 */ "mmmmmbbbbbbmmmmm"
+ /* 12 */ "mmmmmmbbbbmmmmmm"
+ /* 13 */ "mmmmmmmbbmmmmmmm"
+ /* 14 */ "mmmmmmmbbmmmmmmm"
+ /* 15 */ "mmmmmmmaammmmmmm"
+
+ // Level 1
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmaddammmmmm"
+ /* 1 */ "mmmmmmb..bmmmmmm"
+ /* 2 */ "mmmmmmb..bmmmmmm"
+ /* 3 */ "mmmmmbb..bbmmmmm"
+ /* 4 */ "mmmmbb....bbmmmm"
+ /* 5 */ "mmmbb......bbmmm"
+ /* 6 */ "abbb........bbba"
+ /* 7 */ "e..............f"
+ /* 8 */ "e..............f"
+ /* 9 */ "abbb........bbba"
+ /* 10 */ "mmmbb......bbmmm"
+ /* 11 */ "mmmmbb....bbmmmm"
+ /* 12 */ "mmmmmbb..bbmmmmm"
+ /* 13 */ "mmmmmmb..bmmmmmm"
+ /* 14 */ "mmmmmmb..bmmmmmm"
+ /* 15 */ "mmmmmmaggammmmmm"
+
+ // Level 2
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmahiammmmmm"
+ /* 1 */ "mmmmmmb..bmmmmmm"
+ /* 2 */ "mmmmmmb..bmmmmmm"
+ /* 3 */ "mmmmmcc..ccmmmmm"
+ /* 4 */ "mmmmcc....ccmmmm"
+ /* 5 */ "mmmcc......ccmmm"
+ /* 6 */ "abbc........cbba"
+ /* 7 */ "i..............h"
+ /* 8 */ "h..............i"
+ /* 9 */ "abbc........cbba"
+ /* 10 */ "mmmcc......ccmmm"
+ /* 11 */ "mmmmcc....ccmmmm"
+ /* 12 */ "mmmmmcc..ccmmmmm"
+ /* 13 */ "mmmmmmb..bmmmmmm"
+ /* 14 */ "mmmmmmb..bmmmmmm"
+ /* 15 */ "mmmmmmaihammmmmm"
+
+ // Level 3
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmaaaammmmmm"
+ /* 1 */ "mmmmmmbbbbmmmmmm"
+ /* 2 */ "mmmmmmbbbbmmmmmm"
+ /* 3 */ "mmmmmbb..bbmmmmm"
+ /* 4 */ "mmmmbb....bbmmmm"
+ /* 5 */ "mmmbb......bbmmm"
+ /* 6 */ "abbb........bbba"
+ /* 7 */ "abb..........bba"
+ /* 8 */ "abb..........bba"
+ /* 9 */ "abbb........bbba"
+ /* 10 */ "mmmbb......bbmmm"
+ /* 11 */ "mmmmbb....bbmmmm"
+ /* 12 */ "mmmmmbb..bbmmmmm"
+ /* 13 */ "mmmmmmbbbbmmmmmm"
+ /* 14 */ "mmmmmmbbbbmmmmmm"
+ /* 15 */ "mmmmmmaaaammmmmm"
+
+ // Level 4
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmbbmmmmmmm"
+ /* 4 */ "mmmmmmbjjbmmmmmm"
+ /* 5 */ "mmmmmb....bmmmmm"
+ /* 6 */ "mmmmb......bmmmm"
+ /* 7 */ "mmmbk......lbmmm"
+ /* 8 */ "mmmbk......lbmmm"
+ /* 9 */ "mmmmb......bmmmm"
+ /* 10 */ "mmmmmb....bmmmmm"
+ /* 11 */ "mmmmmmbnnbmmmmmm"
+ /* 12 */ "mmmmmmmbbmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmmmmmm"
+
+ // Level 5
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmmmmmmm"
+ /* 4 */ "mmmmmmmbbmmmmmmm"
+ /* 5 */ "mmmmmmb..bmmmmmm"
+ /* 6 */ "mmmmmb....bmmmmm"
+ /* 7 */ "mmmmb......bmmmm"
+ /* 8 */ "mmmmb......bmmmm"
+ /* 9 */ "mmmmmb....bmmmmm"
+ /* 10 */ "mmmmmmboobmmmmmm"
+ /* 11 */ "mmmmmmmbbmmmmmmm"
+ /* 12 */ "mmmmmmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmmmmmm"
+
+ // Level 6
+ /* z\x* 111111 */
+ /* * 0123456789012345 */
+ /* 0 */ "mmmmmmmmmmmmmmmm"
+ /* 1 */ "mmmmmmmmmmmmmmmm"
+ /* 2 */ "mmmmmmmmmmmmmmmm"
+ /* 3 */ "mmmmmmmmmmmmmmmm"
+ /* 4 */ "mmmmmmmmmmmmmmmm"
+ /* 5 */ "mmmmmmmbbmmmmmmm"
+ /* 6 */ "mmmmmmbbbbmmmmmm"
+ /* 7 */ "mmmmmbbccbbmmmmm"
+ /* 8 */ "mmmmmbbccbbmmmmm"
+ /* 9 */ "mmmmmmbbbbmmmmmm"
+ /* 10 */ "mmmmmmmbbmmmmmmm"
+ /* 11 */ "mmmmmmmmmmmmmmmm"
+ /* 12 */ "mmmmmmmmmmmmmmmm"
+ /* 13 */ "mmmmmmmmmmmmmmmm"
+ /* 14 */ "mmmmmmmmmmmmmmmm"
+ /* 15 */ "mmmmmmmmmmmmmmmm",
+
+ // Connectors:
+ "1: 0, 1, 7: 4\n" /* Type 1, direction X- */
+ "-1: 0, 1, 8: 4\n" /* Type -1, direction X- */
+ "-1: 7, 1, 0: 2\n" /* Type -1, direction Z- */
+ "1: 8, 1, 0: 2\n" /* Type 1, direction Z- */
+ "1: 15, 1, 8: 5\n" /* Type 1, direction X+ */
+ "-1: 15, 1, 7: 5\n" /* Type -1, direction X+ */
+ "1: 7, 1, 15: 3\n" /* Type 1, direction Z+ */
+ "-1: 8, 1, 15: 3\n" /* Type -1, direction Z+ */,
+
+ // AllowedRotations:
+ 7, /* 1, 2, 3 CCW rotation allowed */
+
+ // Merge strategy:
+ cBlockArea::msSpongePrint,
+
+ // ShouldExtendFloor:
+ true,
+
+ // DefaultWeight:
+ 100,
+
+ // DepthWeight:
+ "",
+
+ // AddWeightIfSame:
+ 0,
+
+ // MoveToGround:
+ false,
+ }, // CentralRoom
+};
+
+
+
+
+
+// The prefab counts:
+
+const size_t g_UnderwaterBasePrefabsCount = ARRAYCOUNT(g_UnderwaterBasePrefabs);
+
+const size_t g_UnderwaterBaseStartingPrefabsCount = ARRAYCOUNT(g_UnderwaterBaseStartingPrefabs);
+
diff --git a/src/Generating/Prefabs/UnderwaterBasePrefabs.h b/src/Generating/Prefabs/UnderwaterBasePrefabs.h
new file mode 100644
index 000000000..d7b248bb8
--- /dev/null
+++ b/src/Generating/Prefabs/UnderwaterBasePrefabs.h
@@ -0,0 +1,15 @@
+
+// UnderwaterBasePrefabs.h
+
+// Declares the prefabs in the group UnderwaterBase
+
+#include "../Prefab.h"
+
+
+
+
+
+extern const cPrefab::sDef g_UnderwaterBasePrefabs[];
+extern const cPrefab::sDef g_UnderwaterBaseStartingPrefabs[];
+extern const size_t g_UnderwaterBasePrefabsCount;
+extern const size_t g_UnderwaterBaseStartingPrefabsCount;
diff --git a/src/Generating/RainbowRoadsGen.cpp b/src/Generating/RainbowRoadsGen.cpp
new file mode 100644
index 000000000..3b0ff7df8
--- /dev/null
+++ b/src/Generating/RainbowRoadsGen.cpp
@@ -0,0 +1,116 @@
+
+// RainbowRoadsGen.cpp
+
+// Implements the cRainbowRoadsGen class representing the rainbow road generator
+
+#include "Globals.h"
+#include "RainbowRoadsGen.h"
+#include "Prefabs/RainbowRoadPrefabs.h"
+#include "PieceGenerator.h"
+
+
+
+
+
+static cPrefabPiecePool g_RainbowRoads(g_RainbowRoadPrefabs, g_RainbowRoadPrefabsCount, g_RainbowRoadStartingPrefabs, g_RainbowRoadStartingPrefabsCount);
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cRainbowRoadsGen::cRainbowRoads:
+
+class cRainbowRoadsGen::cRainbowRoads :
+ public cGridStructGen::cStructure
+{
+ typedef cGridStructGen::cStructure super;
+
+public:
+ cRainbowRoads(
+ int a_Seed,
+ int a_GridX, int a_GridZ,
+ int a_OriginX, int a_OriginZ,
+ int a_MaxDepth,
+ int a_MaxSize
+ ) :
+ super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
+ m_Seed(a_Seed),
+ m_Noise(a_Seed),
+ m_MaxSize(a_MaxSize),
+ m_Borders(a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize, a_OriginX + a_MaxSize, 255, a_OriginZ + a_MaxSize)
+ {
+ // Generate the pieces for this base:
+ cBFSPieceGenerator pg(g_RainbowRoads, a_Seed);
+ pg.PlacePieces(a_OriginX, 190, a_OriginZ, a_MaxDepth, m_Pieces);
+ if (m_Pieces.empty())
+ {
+ return;
+ }
+ }
+
+ ~cRainbowRoads()
+ {
+ cPieceGenerator::FreePieces(m_Pieces);
+ }
+
+protected:
+ /** Seed for the random functions */
+ int m_Seed;
+
+ /** The noise used as a pseudo-random generator */
+ cNoise m_Noise;
+
+ /** Maximum size, in X/Z blocks, of the village (radius from the origin) */
+ int m_MaxSize;
+
+ /** Borders of the vilalge - no item may reach out of this cuboid. */
+ cCuboid m_Borders;
+
+ /** The village pieces, placed by the generator. */
+ cPlacedPieces m_Pieces;
+
+
+ // cGridStructGen::cStructure overrides:
+ virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override
+ {
+ for (cPlacedPieces::iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr)
+ {
+ cPrefab & Prefab = (cPrefab &)((*itr)->GetPiece());
+ Prefab.Draw(a_Chunk, *itr);
+ } // for itr - m_PlacedPieces[]
+ }
+} ;
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cRainbowRoadsGen:
+
+
+
+
+
+cRainbowRoadsGen::cRainbowRoadsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize) :
+ super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100),
+ m_Noise(a_Seed + 9000),
+ m_MaxDepth(a_MaxDepth),
+ m_MaxSize(a_MaxSize)
+{
+}
+
+
+
+
+
+cGridStructGen::cStructurePtr cRainbowRoadsGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
+{
+ // Create a base based on the chosen prefabs:
+ return cStructurePtr(new cRainbowRoads(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize));
+}
+
+
+
+
diff --git a/src/Generating/RainbowRoadsGen.h b/src/Generating/RainbowRoadsGen.h
new file mode 100644
index 000000000..5813e1d14
--- /dev/null
+++ b/src/Generating/RainbowRoadsGen.h
@@ -0,0 +1,47 @@
+
+// RainbowRoadsGen.h
+
+// Declares the cRainbowRoadsGen class representing the underwater base generator
+
+
+
+
+
+#pragma once
+
+#include "GridStructGen.h"
+#include "PrefabPiecePool.h"
+
+
+
+
+
+class cRainbowRoadsGen :
+ public cGridStructGen
+{
+ typedef cGridStructGen super;
+
+public:
+ cRainbowRoadsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize);
+
+protected:
+ class cRainbowRoads; // fwd: RainbowRoadsGen.cpp
+
+
+ /** The noise used for generating random numbers */
+ cNoise m_Noise;
+
+ /** Maximum depth of the generator tree*/
+ int m_MaxDepth;
+
+ /** Maximum size, in X/Z blocks, of the base (radius from the origin) */
+ int m_MaxSize;
+
+
+ // cGridStructGen overrides:
+ virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
+} ;
+
+
+
+
diff --git a/src/Generating/Ravines.cpp b/src/Generating/Ravines.cpp
index 2722e4ca3..24f2cc3ab 100644
--- a/src/Generating/Ravines.cpp
+++ b/src/Generating/Ravines.cpp
@@ -61,7 +61,7 @@ class cStructGenRavines::cRavine :
public:
- cRavine(int a_BlockX, int a_BlockZ, int a_Size, cNoise & a_Noise);
+ cRavine(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_Size, cNoise & a_Noise);
#ifdef _DEBUG
/// Exports itself as a SVG line definition
@@ -81,7 +81,7 @@ protected:
// cStructGenRavines:
cStructGenRavines::cStructGenRavines(int a_Seed, int a_Size) :
- super(a_Seed, a_Size, a_Size, a_Size * 2, a_Size * 2, 100),
+ super(a_Seed, a_Size, a_Size, a_Size, a_Size, a_Size * 2, a_Size * 2, 100),
m_Noise(a_Seed),
m_Size(a_Size)
{
@@ -91,9 +91,9 @@ cStructGenRavines::cStructGenRavines(int a_Seed, int a_Size) :
-cGridStructGen::cStructurePtr cStructGenRavines::CreateStructure(int a_OriginX, int a_OriginZ)
+cGridStructGen::cStructurePtr cStructGenRavines::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
- return cStructurePtr(new cRavine(a_OriginX, a_OriginZ, m_Size, m_Noise));
+ return cStructurePtr(new cRavine(a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_Size, m_Noise));
}
@@ -104,8 +104,8 @@ cGridStructGen::cStructurePtr cStructGenRavines::CreateStructure(int a_OriginX,
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cStructGenRavines::cRavine
-cStructGenRavines::cRavine::cRavine(int a_OriginX, int a_OriginZ, int a_Size, cNoise & a_Noise) :
- super(a_OriginX, a_OriginZ)
+cStructGenRavines::cRavine::cRavine(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_Size, cNoise & a_Noise) :
+ super(a_GridX, a_GridZ, a_OriginX, a_OriginZ)
{
// Calculate the ravine shape-defining points:
GenerateBaseDefPoints(a_OriginX, a_OriginZ, a_Size, a_Noise);
diff --git a/src/Generating/Ravines.h b/src/Generating/Ravines.h
index 30b47e9ec..3e41c5ce6 100644
--- a/src/Generating/Ravines.h
+++ b/src/Generating/Ravines.h
@@ -32,7 +32,7 @@ protected:
// cGridStructGen overrides:
- virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) override;
+ virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ;
diff --git a/src/Generating/UnderwaterBaseGen.cpp b/src/Generating/UnderwaterBaseGen.cpp
new file mode 100644
index 000000000..d3abae9b7
--- /dev/null
+++ b/src/Generating/UnderwaterBaseGen.cpp
@@ -0,0 +1,143 @@
+
+// UnderwaterBaseGen.cpp
+
+// Implements the cUnderwaterBaseGen class representing the underwater base generator
+
+#include "Globals.h"
+#include "UnderwaterBaseGen.h"
+#include "Prefabs/UnderwaterBasePrefabs.h"
+#include "PieceGenerator.h"
+
+
+
+
+
+static cPrefabPiecePool g_UnderwaterBase(g_UnderwaterBasePrefabs, g_UnderwaterBasePrefabsCount, g_UnderwaterBaseStartingPrefabs, g_UnderwaterBaseStartingPrefabsCount);
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cUnderwaterBaseGen::cUnderwaterBase:
+
+class cUnderwaterBaseGen::cUnderwaterBase :
+ public cGridStructGen::cStructure
+{
+ typedef cGridStructGen::cStructure super;
+
+public:
+ cUnderwaterBase(
+ int a_Seed,
+ int a_GridX, int a_GridZ,
+ int a_OriginX, int a_OriginZ,
+ int a_MaxDepth,
+ int a_MaxSize
+ ) :
+ super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
+ m_Seed(a_Seed),
+ m_Noise(a_Seed),
+ m_MaxSize(a_MaxSize),
+ m_Borders(a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize, a_OriginX + a_MaxSize, 255, a_OriginZ + a_MaxSize)
+ {
+ // Generate the pieces for this base:
+ cBFSPieceGenerator pg(g_UnderwaterBase, a_Seed);
+ pg.PlacePieces(a_OriginX, 50, a_OriginZ, a_MaxDepth, m_Pieces);
+ if (m_Pieces.empty())
+ {
+ return;
+ }
+ }
+
+ ~cUnderwaterBase()
+ {
+ cPieceGenerator::FreePieces(m_Pieces);
+ }
+
+protected:
+ /** Seed for the random functions */
+ int m_Seed;
+
+ /** The noise used as a pseudo-random generator */
+ cNoise m_Noise;
+
+ /** Maximum size, in X/Z blocks, of the village (radius from the origin) */
+ int m_MaxSize;
+
+ /** Borders of the vilalge - no item may reach out of this cuboid. */
+ cCuboid m_Borders;
+
+ /** The village pieces, placed by the generator. */
+ cPlacedPieces m_Pieces;
+
+
+ // cGridStructGen::cStructure overrides:
+ virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override
+ {
+ for (cPlacedPieces::iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr)
+ {
+ cPrefab & Prefab = (cPrefab &)((*itr)->GetPiece());
+ Prefab.Draw(a_Chunk, *itr);
+ } // for itr - m_PlacedPieces[]
+ }
+} ;
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cUnderwaterBaseGen:
+
+
+
+
+
+cUnderwaterBaseGen::cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen) :
+ super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100),
+ m_Noise(a_Seed + 1000),
+ m_MaxDepth(a_MaxDepth),
+ m_MaxSize(a_MaxSize),
+ m_BiomeGen(a_BiomeGen)
+{
+}
+
+
+
+
+
+cGridStructGen::cStructurePtr cUnderwaterBaseGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
+{
+ // Generate the biomes for the chunk surrounding the origin:
+ int ChunkX, ChunkZ;
+ cChunkDef::BlockToChunk(a_OriginX, a_OriginZ, ChunkX, ChunkZ);
+ cChunkDef::BiomeMap Biomes;
+ m_BiomeGen.GenBiomes(ChunkX, ChunkZ, Biomes);
+
+ // Check if all the biomes are ocean:
+ // If just one is not, no base is created, because it's likely that an unfriendly biome is too close
+ for (size_t i = 0; i < ARRAYCOUNT(Biomes); i++)
+ {
+ switch (Biomes[i])
+ {
+ case biOcean:
+ case biDeepOcean:
+ {
+ // These biomes allow underwater bases
+ break;
+ }
+ default:
+ {
+ // base-unfriendly biome, bail out with zero structure:
+ return cStructurePtr();
+ }
+ } // switch (Biomes[i])
+ } // for i - Biomes[]
+
+ // Create a base based on the chosen prefabs:
+ return cStructurePtr(new cUnderwaterBase(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize));
+}
+
+
+
+
diff --git a/src/Generating/UnderwaterBaseGen.h b/src/Generating/UnderwaterBaseGen.h
new file mode 100644
index 000000000..d6267b602
--- /dev/null
+++ b/src/Generating/UnderwaterBaseGen.h
@@ -0,0 +1,50 @@
+
+// UnderwaterBaseGen.h
+
+// Declares the cUnderwaterBaseGen class representing the underwater base generator
+
+
+
+
+
+#pragma once
+
+#include "GridStructGen.h"
+#include "PrefabPiecePool.h"
+
+
+
+
+
+class cUnderwaterBaseGen :
+ public cGridStructGen
+{
+ typedef cGridStructGen super;
+
+public:
+ cUnderwaterBaseGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen);
+
+protected:
+ class cUnderwaterBase; // fwd: UnderwaterBaseGen.cpp
+
+
+ /** The noise used for generating random numbers */
+ cNoise m_Noise;
+
+ /** Maximum depth of the generator tree*/
+ int m_MaxDepth;
+
+ /** Maximum size, in X/Z blocks, of the base (radius from the origin) */
+ int m_MaxSize;
+
+ /** The underlying biome generator that defines whether the base is created or not */
+ cBiomeGen & m_BiomeGen;
+
+
+ // cGridStructGen overrides:
+ virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
+} ;
+
+
+
+
diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp
new file mode 100644
index 000000000..2b7ecc837
--- /dev/null
+++ b/src/Generating/VillageGen.cpp
@@ -0,0 +1,444 @@
+
+// VillageGen.cpp
+
+// Implements the cVillageGen class representing the village generator
+
+#include "Globals.h"
+#include "VillageGen.h"
+#include "Prefabs/AlchemistVillagePrefabs.h"
+#include "Prefabs/JapaneseVillagePrefabs.h"
+#include "Prefabs/PlainsVillagePrefabs.h"
+#include "Prefabs/SandVillagePrefabs.h"
+#include "Prefabs/SandFlatRoofVillagePrefabs.h"
+#include "PieceGenerator.h"
+
+
+
+
+
+/*
+How village generating works:
+By descending from a cGridStructGen, a semi-random grid is generated. A village may be generated for each of
+the grid's cells. Each cell checks the biomes in an entire chunk around it, only generating a village if all
+biomes are village-friendly. If yes, the entire village structure is built for that cell. If not, the cell
+is left village-less.
+
+A village is generated using the regular BFS piece generator. The well piece is used as the starting piece,
+the roads and houses are then used as the following pieces. Only the houses are read from the prefabs,
+though, the roads are generated by code and their content is ignored. A special subclass of the cPiecePool
+class is used, so that the roads connect to each other and to the well only in predefined manners.
+
+The well has connectors of type "2". The houses have connectors of type "-1". The roads have connectors of
+both types' opposites, type "-2" at the far ends and type "1" on the long edges. Additionally, there are
+type "2" connectors along the long edges of the roads as well, so that the roads create T junctions.
+
+When the village is about to be drawn into a chunk, it queries the heights for each piece intersecting the
+chunk. The pieces are shifted so that their pivot points lie on the surface, and the roads are drawn
+directly by turning the surface blocks into gravel / sandstone.
+
+The village prefabs are stored in global piecepools (one pool per village type). In order to support
+per-village density setting, the cVillage class itself implements the cPiecePool interface, relaying the
+calls to the underlying cVillagePiecePool, after processing the density check.
+*/
+
+class cVillagePiecePool :
+ public cPrefabPiecePool
+{
+ typedef cPrefabPiecePool super;
+public:
+ cVillagePiecePool(
+ const cPrefab::sDef * a_PieceDefs, size_t a_NumPieceDefs,
+ const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs
+ ) :
+ super(a_PieceDefs, a_NumPieceDefs, a_StartingPieceDefs, a_NumStartingPieceDefs)
+ {
+ // Add the road pieces:
+ for (int len = 27; len < 60; len += 12)
+ {
+ cBlockArea BA;
+ BA.Create(len, 1, 3, cBlockArea::baTypes | cBlockArea::baMetas);
+ BA.Fill(cBlockArea::baTypes | cBlockArea::baMetas, E_BLOCK_GRAVEL, 0);
+ cPrefab * RoadPiece = new cPrefab(BA, 1);
+ RoadPiece->AddConnector(0, 0, 1, BLOCK_FACE_XM, -2);
+ RoadPiece->AddConnector(len - 1, 0, 1, BLOCK_FACE_XP, -2);
+ RoadPiece->SetDefaultWeight(100);
+
+ // Add the road connectors:
+ for (int x = 1; x < len; x += 12)
+ {
+ RoadPiece->AddConnector(x, 0, 0, BLOCK_FACE_ZM, 2);
+ RoadPiece->AddConnector(x, 0, 2, BLOCK_FACE_ZP, 2);
+ }
+
+ // Add the buildings connectors:
+ for (int x = 7; x < len; x += 12)
+ {
+ RoadPiece->AddConnector(x, 0, 0, BLOCK_FACE_ZM, 1);
+ RoadPiece->AddConnector(x, 0, 2, BLOCK_FACE_ZP, 1);
+ }
+ m_AllPieces.push_back(RoadPiece);
+ m_PiecesByConnector[-2].push_back(RoadPiece);
+ m_PiecesByConnector[1].push_back(RoadPiece);
+ m_PiecesByConnector[2].push_back(RoadPiece);
+ } // for len - roads of varying length
+ }
+
+
+ // cPrefabPiecePool overrides:
+ virtual int GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, const cPiece & a_NewPiece) override
+ {
+ // Roads cannot branch T-wise (appending -2 connector to a +2 connector on a 1-high piece):
+ if ((a_ExistingConnector.m_Type == 2) && (a_PlacedPiece.GetDepth() > 0) && (a_PlacedPiece.GetPiece().GetSize().y == 1))
+ {
+ return 0;
+ }
+
+ return ((const cPrefab &)a_NewPiece).GetPieceWeight(a_PlacedPiece, a_ExistingConnector);
+ }
+} ;
+
+
+
+
+
+class cVillageGen::cVillage :
+ public cGridStructGen::cStructure,
+ protected cPiecePool
+{
+ typedef cGridStructGen::cStructure super;
+
+public:
+ cVillage(
+ int a_Seed,
+ int a_GridX, int a_GridZ,
+ int a_OriginX, int a_OriginZ,
+ int a_MaxRoadDepth,
+ int a_MaxSize,
+ int a_Density,
+ cPiecePool & a_Prefabs,
+ cTerrainHeightGen & a_HeightGen,
+ BLOCKTYPE a_RoadBlock,
+ BLOCKTYPE a_WaterRoadBlock
+ ) :
+ super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
+ m_Seed(a_Seed),
+ m_Noise(a_Seed),
+ m_MaxSize(a_MaxSize),
+ m_Density(a_Density),
+ m_Borders(a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize, a_OriginX + a_MaxSize, 255, a_OriginZ + a_MaxSize),
+ m_Prefabs(a_Prefabs),
+ m_HeightGen(a_HeightGen),
+ m_RoadBlock(a_RoadBlock),
+ m_WaterRoadBlock(a_WaterRoadBlock)
+ {
+ // Generate the pieces for this village; don't care about the Y coord:
+ cBFSPieceGenerator pg(*this, a_Seed);
+ pg.PlacePieces(a_OriginX, 0, a_OriginZ, a_MaxRoadDepth + 1, m_Pieces);
+ if (m_Pieces.empty())
+ {
+ return;
+ }
+
+ // If the central piece should be moved to ground, move it, and
+ // check all of its dependents and move those that are strictly connector-driven based on its new Y coord:
+ if (((cPrefab &)m_Pieces[0]->GetPiece()).ShouldMoveToGround())
+ {
+ int OrigPosY = m_Pieces[0]->GetCoords().y;
+ PlacePieceOnGround(*m_Pieces[0]);
+ int NewPosY = m_Pieces[0]->GetCoords().y;
+ MoveAllDescendants(m_Pieces, 0, NewPosY - OrigPosY);
+ }
+ }
+
+ ~cVillage()
+ {
+ cPieceGenerator::FreePieces(m_Pieces);
+ }
+
+protected:
+ /** Seed for the random functions */
+ int m_Seed;
+
+ /** The noise used as a pseudo-random generator */
+ cNoise m_Noise;
+
+ /** Maximum size, in X/Z blocks, of the village (radius from the origin) */
+ int m_MaxSize;
+
+ /** The density for this village. Used to refrain from populating all house connectors. Range [0, 100] */
+ int m_Density;
+
+ /** Borders of the vilalge - no item may reach out of this cuboid. */
+ cCuboid m_Borders;
+
+ /** Prefabs to use for buildings */
+ cPiecePool & m_Prefabs;
+
+ /** The underlying height generator, used for placing the structures on top of the terrain. */
+ cTerrainHeightGen & m_HeightGen;
+
+ /** The village pieces, placed by the generator. */
+ cPlacedPieces m_Pieces;
+
+ /** The block to use for the roads. */
+ BLOCKTYPE m_RoadBlock;
+
+ /** The block used for the roads if the road is on water. */
+ BLOCKTYPE m_WaterRoadBlock;
+
+
+ // cGridStructGen::cStructure overrides:
+ virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override
+ {
+ // Iterate over all items
+ // Each intersecting prefab is placed on ground, then drawn
+ // Each intersecting road is drawn by replacing top soil blocks with gravel / sandstone blocks
+ cChunkDef::HeightMap HeightMap; // Heightmap for this chunk, used by roads
+ m_HeightGen.GenHeightMap(a_Chunk.GetChunkX(), a_Chunk.GetChunkZ(), HeightMap);
+ for (cPlacedPieces::iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr)
+ {
+ cPrefab & Prefab = (cPrefab &)((*itr)->GetPiece());
+ if ((*itr)->GetPiece().GetSize().y == 1)
+ {
+ // It's a road, special handling (change top terrain blocks to m_RoadBlock)
+ DrawRoad(a_Chunk, **itr, HeightMap);
+ continue;
+ }
+ if (Prefab.ShouldMoveToGround() && !(*itr)->HasBeenMovedToGround())
+ {
+ PlacePieceOnGround(**itr);
+ }
+ Prefab.Draw(a_Chunk, *itr);
+ } // for itr - m_PlacedPieces[]
+ }
+
+
+ /** Adjusts the Y coord of the given piece so that the piece is on the ground.
+ Ground level is assumed to be represented by the first connector in the piece. */
+ void PlacePieceOnGround(cPlacedPiece & a_Piece)
+ {
+ cPiece::cConnector FirstConnector = a_Piece.GetRotatedConnector(0);
+ int ChunkX, ChunkZ;
+ int BlockX = FirstConnector.m_Pos.x;
+ int BlockZ = FirstConnector.m_Pos.z;
+ int BlockY;
+ cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ);
+ cChunkDef::HeightMap HeightMap;
+ m_HeightGen.GenHeightMap(ChunkX, ChunkZ, HeightMap);
+ int TerrainHeight = cChunkDef::GetHeight(HeightMap, BlockX, BlockZ);
+ a_Piece.MoveToGroundBy(TerrainHeight - FirstConnector.m_Pos.y + 1);
+ }
+
+
+ /** Draws the road into the chunk.
+ The heightmap is not queried from the heightgen, but is given via parameter, so that it may be queried just
+ once for all roads in a chunk. */
+ void DrawRoad(cChunkDesc & a_Chunk, cPlacedPiece & a_Road, cChunkDef::HeightMap & a_HeightMap)
+ {
+ cCuboid RoadCoords = a_Road.GetHitBox();
+ RoadCoords.Sort();
+ int MinX = std::max(RoadCoords.p1.x - a_Chunk.GetChunkX() * cChunkDef::Width, 0);
+ int MaxX = std::min(RoadCoords.p2.x - a_Chunk.GetChunkX() * cChunkDef::Width, cChunkDef::Width - 1);
+ int MinZ = std::max(RoadCoords.p1.z - a_Chunk.GetChunkZ() * cChunkDef::Width, 0);
+ int MaxZ = std::min(RoadCoords.p2.z - a_Chunk.GetChunkZ() * cChunkDef::Width, cChunkDef::Width - 1);
+ for (int z = MinZ; z <= MaxZ; z++)
+ {
+ for (int x = MinX; x <= MaxX; x++)
+ {
+ if (IsBlockWater(a_Chunk.GetBlockType(x, cChunkDef::GetHeight(a_HeightMap, x, z), z)))
+ {
+ a_Chunk.SetBlockType(x, cChunkDef::GetHeight(a_HeightMap, x, z), z, m_WaterRoadBlock);
+ }
+ else
+ {
+ a_Chunk.SetBlockType(x, cChunkDef::GetHeight(a_HeightMap, x, z), z, m_RoadBlock);
+ }
+ }
+ }
+ }
+
+
+ // cPiecePool overrides:
+ virtual cPieces GetPiecesWithConnector(int a_ConnectorType)
+ {
+ return m_Prefabs.GetPiecesWithConnector(a_ConnectorType);
+ }
+
+
+ virtual cPieces GetStartingPieces(void)
+ {
+ return m_Prefabs.GetStartingPieces();
+ }
+
+
+ virtual int GetPieceWeight(
+ const cPlacedPiece & a_PlacedPiece,
+ const cPiece::cConnector & a_ExistingConnector,
+ const cPiece & a_NewPiece
+ ) override
+ {
+ // Check against the density:
+ if (a_ExistingConnector.m_Type == 1)
+ {
+ const Vector3i & Coords = a_PlacedPiece.GetRotatedConnector(a_ExistingConnector).m_Pos;
+ int rnd = (m_Noise.IntNoise3DInt(Coords.x, Coords.y, Coords.z) / 7) % 100;
+ if (rnd > m_Density)
+ {
+ return 0;
+ }
+ }
+
+ // Density check passed, relay to m_Prefabs:
+ return m_Prefabs.GetPieceWeight(a_PlacedPiece, a_ExistingConnector, a_NewPiece);
+ }
+
+
+ virtual int GetStartingPieceWeight(const cPiece & a_NewPiece) override
+ {
+ return m_Prefabs.GetStartingPieceWeight(a_NewPiece);
+ }
+
+
+ virtual void PiecePlaced(const cPiece & a_Piece) override
+ {
+ m_Prefabs.PiecePlaced(a_Piece);
+ }
+
+
+ virtual void Reset(void) override
+ {
+ m_Prefabs.Reset();
+ }
+
+
+ void MoveAllDescendants(cPlacedPieces & a_PlacedPieces, size_t a_Pivot, int a_HeightDifference)
+ {
+ size_t num = a_PlacedPieces.size();
+ cPlacedPiece * Pivot = a_PlacedPieces[a_Pivot];
+ for (size_t i = a_Pivot + 1; i < num; i++)
+ {
+ if (
+ (a_PlacedPieces[i]->GetParent() == Pivot) && // It is a direct dependant of the pivot
+ !((const cPrefab &)a_PlacedPieces[i]->GetPiece()).ShouldMoveToGround() // It attaches strictly by connectors
+ )
+ {
+ a_PlacedPieces[i]->MoveToGroundBy(a_HeightDifference);
+ MoveAllDescendants(a_PlacedPieces, i, a_HeightDifference);
+ }
+ } // for i - a_PlacedPieces[]
+ }
+} ;
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cVillageGen:
+
+static cVillagePiecePool g_SandVillage(g_SandVillagePrefabs, g_SandVillagePrefabsCount, g_SandVillageStartingPrefabs, g_SandVillageStartingPrefabsCount);
+static cVillagePiecePool g_SandFlatRoofVillage(g_SandFlatRoofVillagePrefabs, g_SandFlatRoofVillagePrefabsCount, g_SandFlatRoofVillageStartingPrefabs, g_SandFlatRoofVillageStartingPrefabsCount);
+static cVillagePiecePool g_AlchemistVillage(g_AlchemistVillagePrefabs, g_AlchemistVillagePrefabsCount, g_AlchemistVillageStartingPrefabs, g_AlchemistVillageStartingPrefabsCount);
+static cVillagePiecePool g_PlainsVillage(g_PlainsVillagePrefabs, g_PlainsVillagePrefabsCount, g_PlainsVillageStartingPrefabs, g_PlainsVillageStartingPrefabsCount);
+static cVillagePiecePool g_JapaneseVillage(g_JapaneseVillagePrefabs, g_JapaneseVillagePrefabsCount, g_JapaneseVillageStartingPrefabs, g_JapaneseVillageStartingPrefabsCount);
+
+static cVillagePiecePool * g_DesertVillagePools[] =
+{
+ &g_SandVillage,
+ &g_SandFlatRoofVillage,
+ &g_AlchemistVillage,
+} ;
+
+static cVillagePiecePool * g_PlainsVillagePools[] =
+{
+ &g_PlainsVillage,
+ &g_JapaneseVillage,
+} ;
+
+
+
+
+
+cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen) :
+ super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100),
+ m_Noise(a_Seed + 1000),
+ m_MaxDepth(a_MaxDepth),
+ m_MaxSize(a_MaxSize),
+ m_MinDensity(a_MinDensity),
+ m_MaxDensity(a_MaxDensity),
+ m_BiomeGen(a_BiomeGen),
+ m_HeightGen(a_HeightGen)
+{
+}
+
+
+
+
+
+cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
+{
+ // Generate the biomes for the chunk surrounding the origin:
+ int ChunkX, ChunkZ;
+ cChunkDef::BlockToChunk(a_OriginX, a_OriginZ, ChunkX, ChunkZ);
+ cChunkDef::BiomeMap Biomes;
+ m_BiomeGen.GenBiomes(ChunkX, ChunkZ, Biomes);
+
+ // Check if all the biomes are village-friendly:
+ // If just one is not, no village is created, because it's likely that an unfriendly biome is too close
+ cVillagePiecePool * VillagePrefabs = NULL;
+ BLOCKTYPE RoadBlock = E_BLOCK_GRAVEL;
+ BLOCKTYPE WaterRoadBlock = E_BLOCK_PLANKS;
+ int rnd = m_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 11;
+ cVillagePiecePool * PlainsVillage = g_PlainsVillagePools[rnd % ARRAYCOUNT(g_PlainsVillagePools)];
+ cVillagePiecePool * DesertVillage = g_DesertVillagePools[rnd % ARRAYCOUNT(g_DesertVillagePools)];
+ for (size_t i = 0; i < ARRAYCOUNT(Biomes); i++)
+ {
+ switch (Biomes[i])
+ {
+ case biDesert:
+ case biDesertM:
+ {
+ // These biomes allow sand villages
+ VillagePrefabs = DesertVillage;
+ // RoadBlock = E_BLOCK_SANDSTONE;
+ break;
+ }
+ case biPlains:
+ case biSavanna:
+ case biSavannaM:
+ case biSunflowerPlains:
+ {
+ // These biomes allow plains-style villages
+ VillagePrefabs = PlainsVillage;
+ break;
+ }
+ default:
+ {
+ // Village-unfriendly biome, bail out with zero structure:
+ return cStructurePtr();
+ }
+ } // switch (Biomes[i])
+ } // for i - Biomes[]
+
+ // Choose density for the village, random between m_MinDensity and m_MaxDensity:
+ int Density;
+ if (m_MaxDensity > m_MinDensity)
+ {
+ Density = m_MinDensity + rnd % (m_MaxDensity - m_MinDensity);
+ }
+ else
+ {
+ Density = m_MinDensity;
+ }
+
+ // Create a village based on the chosen prefabs:
+ if (VillagePrefabs == NULL)
+ {
+ return cStructurePtr();
+ }
+ return cStructurePtr(new cVillage(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, Density, *VillagePrefabs, m_HeightGen, RoadBlock, WaterRoadBlock));
+}
+
+
+
+
diff --git a/src/Generating/VillageGen.h b/src/Generating/VillageGen.h
new file mode 100644
index 000000000..694ea2358
--- /dev/null
+++ b/src/Generating/VillageGen.h
@@ -0,0 +1,57 @@
+
+// VillageGen.h
+
+// Declares the cVillageGen class representing the village generator
+
+
+
+
+
+#pragma once
+
+#include "GridStructGen.h"
+#include "PrefabPiecePool.h"
+
+
+
+
+
+class cVillageGen :
+ public cGridStructGen
+{
+ typedef cGridStructGen super;
+public:
+ cVillageGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen);
+
+protected:
+ class cVillage; // fwd: VillageGen.cpp
+
+ /** The noise used for generating random numbers */
+ cNoise m_Noise;
+
+ /** Maximum depth of the generator tree*/
+ int m_MaxDepth;
+
+ /** Maximum size, in X/Z blocks, of the village (radius from the origin) */
+ int m_MaxSize;
+
+ /** Minimum density - percentage of allowed house connections. Range [0, 100] */
+ int m_MinDensity;
+
+ /** Maximum density - percentage of allowed house connections. Range [0, 100] */
+ int m_MaxDensity;
+
+ /** The underlying biome generator that defines whether the village is created or not */
+ cBiomeGen & m_BiomeGen;
+
+ /** The underlying height generator, used to position the prefabs crossing chunk borders */
+ cTerrainHeightGen & m_HeightGen;
+
+
+ // cGridStructGen overrides:
+ virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
+} ;
+
+
+
+
diff --git a/src/Globals.h b/src/Globals.h
index 71e9191e4..c5768facf 100644
--- a/src/Globals.h
+++ b/src/Globals.h
@@ -225,16 +225,28 @@ template class SizeChecker<UInt16, 2>;
+#ifndef TEST_GLOBALS
+ // Common headers (part 1, without macros):
+ #include "StringUtils.h"
+ #include "OSSupport/Sleep.h"
+ #include "OSSupport/CriticalSection.h"
+ #include "OSSupport/Semaphore.h"
+ #include "OSSupport/Event.h"
+ #include "OSSupport/Thread.h"
+ #include "OSSupport/File.h"
+ #include "MCLogger.h"
+#else
+ // Logging functions
+void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1,2);
-// Common headers (part 1, without macros):
-#include "StringUtils.h"
-#include "OSSupport/Sleep.h"
-#include "OSSupport/CriticalSection.h"
-#include "OSSupport/Semaphore.h"
-#include "OSSupport/Event.h"
-#include "OSSupport/Thread.h"
-#include "OSSupport/File.h"
-#include "MCLogger.h"
+void inline LOGERROR(const char* a_Format, ...)
+{
+ va_list argList;
+ va_start(argList, a_Format);
+ vprintf(a_Format, argList);
+ va_end(argList);
+}
+#endif
@@ -253,10 +265,44 @@ template class SizeChecker<UInt16, 2>;
#define FAST_FLOOR_DIV( x, div ) (((x) - (((x) < 0) ? ((div) - 1) : 0)) / (div))
// Own version of assert() that writes failed assertions to the log for review
-#ifdef _DEBUG
- #define ASSERT( x ) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), assert(0), 0 ) )
+#ifdef TEST_GLOBALS
+
+ class cAssertFailure
+ {
+ };
+
+ #ifdef _WIN32
+ #if (defined(_MSC_VER) && defined(_DEBUG))
+ #define DBG_BREAK _CrtDbgBreak()
+ #else
+ #define DBG_BREAK
+ #endif
+ #define REPORT_ERROR(FMT, ...) \
+ { \
+ AString msg = Printf(FMT, __VA_ARGS__); \
+ puts(msg.c_str()); \
+ fflush(stdout); \
+ OutputDebugStringA(msg.c_str()); \
+ DBG_BREAK; \
+ }
+ #else
+ #define REPORT_ERROR(FMT, ...) \
+ { \
+ AString msg = Printf(FMT, __VA_ARGS__); \
+ puts(msg.c_str()); \
+ fflush(stdout); \
+ }
+ #endif
+ #define ASSERT(x) do { if (!(x)) { throw cAssertFailure();} } while (0)
+ #define testassert(x) do { if(!(x)) { REPORT_ERROR("Test failure: %s, file %s, line %d\n", #x, __FILE__, __LINE__); exit(1); } } while (0)
+ #define CheckAsserts(x) do { try {x} catch (cAssertFailure) { break; } REPORT_ERROR("Test failure: assert didn't fire for %s, file %s, line %d\n", #x, __FILE__, __LINE__); exit(1); } while (0)
+
#else
- #define ASSERT(x) ((void)(x))
+ #ifdef _DEBUG
+ #define ASSERT( x ) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), assert(0), 0 ) )
+ #else
+ #define ASSERT(x) ((void)(x))
+ #endif
#endif
// Pretty much the same as ASSERT() but stays in Release builds
diff --git a/src/GroupManager.cpp b/src/GroupManager.cpp
index 523697b07..e570bb2b1 100644
--- a/src/GroupManager.cpp
+++ b/src/GroupManager.cpp
@@ -123,7 +123,7 @@ bool cGroupManager::LoadGroups()
IniFile.SetValue("Owner", "Permissions", "*", true);
IniFile.SetValue("Owner", "Color", "2", true);
- IniFile.SetValue("Moderator", "Permissions", "core.time,core.item,core.teleport,core.ban,core.unban,core.save-all,core.toggledownfall");
+ IniFile.SetValue("Moderator", "Permissions", "core.time,core.item,core.tpa,core.tpaccept,core.ban,core.unban,core.save-all,core.toggledownfall");
IniFile.SetValue("Moderator", "Color", "2", true);
IniFile.SetValue("Moderator", "Inherits", "Player", true);
diff --git a/src/Items/ItemBoat.h b/src/Items/ItemBoat.h
index 42f4ffc8f..7faac1e32 100644
--- a/src/Items/ItemBoat.h
+++ b/src/Items/ItemBoat.h
@@ -75,7 +75,7 @@ public:
double z = Callbacks.m_Pos.z;
cBoat * Boat = new cBoat(x + 0.5, y + 1, z + 0.5);
- Boat->Initialize(a_World);
+ Boat->Initialize(*a_World);
return true;
}
diff --git a/src/Items/ItemBow.h b/src/Items/ItemBow.h
index 8c0b3a0a3..e0ab339d3 100644
--- a/src/Items/ItemBow.h
+++ b/src/Items/ItemBow.h
@@ -66,7 +66,7 @@ public:
{
return;
}
- if (!Arrow->Initialize(a_Player->GetWorld()))
+ if (!Arrow->Initialize(*a_Player->GetWorld()))
{
delete Arrow;
return;
diff --git a/src/Items/ItemFishingRod.h b/src/Items/ItemFishingRod.h
index 32c151db5..3b1ad1717 100644
--- a/src/Items/ItemFishingRod.h
+++ b/src/Items/ItemFishingRod.h
@@ -231,7 +231,7 @@ public:
else
{
cFloater * Floater = new cFloater(a_Player->GetPosX(), a_Player->GetStance(), a_Player->GetPosZ(), a_Player->GetLookVector() * 15, a_Player->GetUniqueID(), 100 + a_World->GetTickRandomNumber(800) - (a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchLure) * 100));
- Floater->Initialize(a_World);
+ Floater->Initialize(*a_World);
a_Player->SetIsFishing(true, Floater->GetUniqueID());
}
return true;
diff --git a/src/Items/ItemItemFrame.h b/src/Items/ItemItemFrame.h
index 27e7dba35..097f04d0b 100644
--- a/src/Items/ItemItemFrame.h
+++ b/src/Items/ItemItemFrame.h
@@ -34,7 +34,7 @@ public:
if (Block == E_BLOCK_AIR)
{
cItemFrame * ItemFrame = new cItemFrame(a_Dir, a_BlockX, a_BlockY, a_BlockZ);
- if (!ItemFrame->Initialize(a_World))
+ if (!ItemFrame->Initialize(*a_World))
{
delete ItemFrame;
return false;
diff --git a/src/Items/ItemMinecart.h b/src/Items/ItemMinecart.h
index 4e7d8fcff..63038de51 100644
--- a/src/Items/ItemMinecart.h
+++ b/src/Items/ItemMinecart.h
@@ -70,7 +70,7 @@ public:
return false;
}
} // switch (m_ItemType)
- Minecart->Initialize(a_World);
+ Minecart->Initialize(*a_World);
if (!a_Player->IsGameModeCreative())
{
diff --git a/src/Items/ItemPainting.h b/src/Items/ItemPainting.h
index b85098221..e4bb76ebe 100644
--- a/src/Items/ItemPainting.h
+++ b/src/Items/ItemPainting.h
@@ -79,7 +79,7 @@ public:
};
cPainting * Painting = new cPainting(gPaintingTitlesList[a_World->GetTickRandomNumber(ARRAYCOUNT(gPaintingTitlesList) - 1)].Title, Dir, a_BlockX, a_BlockY, a_BlockZ);
- Painting->Initialize(a_World);
+ Painting->Initialize(*a_World);
if (!a_Player->IsGameModeCreative())
{
diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp
index 5459644af..33bc08467 100644
--- a/src/LightingThread.cpp
+++ b/src/LightingThread.cpp
@@ -18,20 +18,18 @@
class cReader :
public cChunkDataCallback
{
- virtual void BlockTypes(const BLOCKTYPE * a_Type) override
+ virtual void ChunkData(const cChunkData & a_ChunkBuffer) override
{
- // ROW is a block of 16 Blocks, one whole row is copied at a time (hopefully the compiler will optimize that)
- // C++ doesn't permit copying arrays, but arrays as a part of a struct is ok :)
- typedef struct {BLOCKTYPE m_Row[16]; } ROW;
- ROW * InputRows = (ROW *)a_Type;
- ROW * OutputRows = (ROW *)m_BlockTypes;
+ BLOCKTYPE * OutputRows = m_BlockTypes;
int InputIdx = 0;
int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3;
- for (int y = 0; y < cChunkDef::Height; y++)
+ int MaxHeight = std::min(+cChunkDef::Height, m_MaxHeight + 16); // Need 16 blocks above the highest
+ for (int y = 0; y < MaxHeight; y++)
{
for (int z = 0; z < cChunkDef::Width; z++)
{
- OutputRows[OutputIdx] = InputRows[InputIdx++];
+ a_ChunkBuffer.CopyBlockTypes(OutputRows + OutputIdx * 16, InputIdx * 16, 16);
+ InputIdx++;
OutputIdx += 3;
} // for z
// Skip into the next y-level in the 3x3 chunk blob; each level has cChunkDef::Width * 9 rows
@@ -43,6 +41,7 @@ class cReader :
virtual void HeightMap(const cChunkDef::HeightMap * a_Heightmap) override
{
+ // Copy the entire heightmap, distribute it into the 3x3 chunk blob:
typedef struct {HEIGHTTYPE m_Row[16]; } ROW;
ROW * InputRows = (ROW *)a_Heightmap;
ROW * OutputRows = (ROW *)m_HeightMap;
@@ -53,13 +52,32 @@ class cReader :
OutputRows[OutputIdx] = InputRows[InputIdx++];
OutputIdx += 3;
} // for z
+
+ // Find the highest block in the entire chunk, use it as a base for m_MaxHeight:
+ HEIGHTTYPE MaxHeight = m_MaxHeight;
+ for (size_t i = 0; i < ARRAYCOUNT(*a_Heightmap); i++)
+ {
+ if ((*a_Heightmap)[i] > MaxHeight)
+ {
+ MaxHeight = (*a_Heightmap)[i];
+ }
+ }
+ m_MaxHeight = MaxHeight;
}
public:
int m_ReadingChunkX; // 0, 1 or 2; x-offset of the chunk we're reading from the BlockTypes start
int m_ReadingChunkZ; // 0, 1 or 2; z-offset of the chunk we're reading from the BlockTypes start
+ HEIGHTTYPE m_MaxHeight; // Maximum value in this chunk's heightmap
BLOCKTYPE * m_BlockTypes; // 3x3 chunks of block types, organized as a single XZY blob of data (instead of 3x3 XZY blobs)
HEIGHTTYPE * m_HeightMap; // 3x3 chunks of height map, organized as a single XZY blob of data (instead of 3x3 XZY blobs)
+
+ cReader(BLOCKTYPE * a_BlockTypes, HEIGHTTYPE * a_HeightMap) :
+ m_MaxHeight(0),
+ m_BlockTypes(a_BlockTypes),
+ m_HeightMap(a_HeightMap)
+ {
+ }
} ;
@@ -227,7 +245,7 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item)
// DEBUG: Save chunk data with highlighted seeds for visual inspection:
cFile f4;
if (
- f4.Open(Printf("Chunk_%d_%d_seeds.grab", a_Item.x, a_Item.z), cFile::fmWrite)
+ f4.Open(Printf("Chunk_%d_%d_seeds.grab", a_Item.m_ChunkX, a_Item.m_ChunkZ), cFile::fmWrite)
)
{
for (int z = 0; z < cChunkDef::Width * 3; z++)
@@ -246,6 +264,7 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item)
f4.Write(Seeds, cChunkDef::Width * 3);
}
}
+ f4.Close();
}
//*/
@@ -255,9 +274,9 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item)
// DEBUG: Save XY slices of the chunk data and lighting for visual inspection:
cFile f1, f2, f3;
if (
- f1.Open(Printf("Chunk_%d_%d_data.grab", a_Item.x, a_Item.z), cFile::fmWrite) &&
- f2.Open(Printf("Chunk_%d_%d_sky.grab", a_Item.x, a_Item.z), cFile::fmWrite) &&
- f3.Open(Printf("Chunk_%d_%d_glow.grab", a_Item.x, a_Item.z), cFile::fmWrite)
+ f1.Open(Printf("Chunk_%d_%d_data.grab", a_Item.m_ChunkX, a_Item.m_ChunkZ), cFile::fmWrite) &&
+ f2.Open(Printf("Chunk_%d_%d_sky.grab", a_Item.m_ChunkX, a_Item.m_ChunkZ), cFile::fmWrite) &&
+ f3.Open(Printf("Chunk_%d_%d_glow.grab", a_Item.m_ChunkX, a_Item.m_ChunkZ), cFile::fmWrite)
)
{
for (int z = 0; z < cChunkDef::Width * 3; z++)
@@ -276,6 +295,9 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item)
f3.Write(BlockLight, cChunkDef::Width * 3);
}
}
+ f1.Close();
+ f2.Close();
+ f3.Close();
}
//*/
@@ -296,11 +318,9 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item)
-bool cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ)
+void cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ)
{
- cReader Reader;
- Reader.m_BlockTypes = m_BlockTypes;
- Reader.m_HeightMap = m_HeightMap;
+ cReader Reader(m_BlockTypes, m_HeightMap);
for (int z = 0; z < 3; z++)
{
@@ -308,16 +328,13 @@ bool cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ)
for (int x = 0; x < 3; x++)
{
Reader.m_ReadingChunkX = x;
- if (!m_World->GetChunkData(a_ChunkX + x - 1, a_ChunkZ + z - 1, Reader))
- {
- return false;
- }
+ VERIFY(m_World->GetChunkData(a_ChunkX + x - 1, a_ChunkZ + z - 1, Reader));
} // for z
} // for x
memset(m_BlockLight, 0, sizeof(m_BlockLight));
memset(m_SkyLight, 0, sizeof(m_SkyLight));
- return true;
+ m_MaxHeight = Reader.m_MaxHeight;
}
@@ -408,6 +425,50 @@ void cLightingThread::PrepareBlockLight(void)
+void cLightingThread::PrepareBlockLight2(void)
+{
+ // Clear seeds:
+ memset(m_IsSeed1, 0, sizeof(m_IsSeed1));
+ memset(m_IsSeed2, 0, sizeof(m_IsSeed2));
+ m_NumSeeds = 0;
+
+ // Add each emissive block into the seeds:
+ for (int y = 0; y < m_MaxHeight; y++)
+ {
+ int BaseY = y * BlocksPerYLayer; // Partial offset into m_BlockTypes for the Y coord
+ for (int z = 1; z < cChunkDef::Width * 3 - 1; z++)
+ {
+ int HBaseZ = z * cChunkDef::Width * 3; // Partial offset into m_Heightmap for the Z coord
+ int BaseZ = BaseY + HBaseZ; // Partial offset into m_BlockTypes for the Y and Z coords
+ for (int x = 1; x < cChunkDef::Width * 3 - 1; x++)
+ {
+ int idx = BaseZ + x;
+ if (y > m_HeightMap[HBaseZ + x])
+ {
+ // We're above the heightmap, ignore the block
+ continue;
+ }
+ if (cBlockInfo::GetLightValue(m_BlockTypes[idx]) == 0)
+ {
+ // Not a light-emissive block
+ continue;
+ }
+
+ // Add current block as a seed:
+ m_IsSeed1[idx] = true;
+ m_SeedIdx1[m_NumSeeds++] = idx;
+
+ // Light it up:
+ m_BlockLight[idx] = cBlockInfo::GetLightValue(m_BlockTypes[idx]);
+ }
+ }
+ }
+}
+
+
+
+
+
void cLightingThread::CalcLight(NIBBLETYPE * a_Light)
{
int NumSeeds2 = 0;
diff --git a/src/LightingThread.h b/src/LightingThread.h
index 770ae809f..a484fcbed 100644
--- a/src/LightingThread.h
+++ b/src/LightingThread.h
@@ -108,6 +108,9 @@ protected:
cEvent m_evtItemAdded; // Set when queue is appended, or to stop the thread
cEvent m_evtQueueEmpty; // Set when the queue gets empty
+ /** The highest block in the current 3x3 chunk data */
+ HEIGHTTYPE m_MaxHeight;
+
// Buffers for the 3x3 chunk data
// These buffers alone are 1.7 MiB in size, therefore they cannot be located on the stack safely - some architectures may have only 1 MiB for stack, or even less
@@ -136,8 +139,8 @@ protected:
/** Lights the entire chunk. If neighbor chunks don't exist, touches them and re-queues the chunk */
void LightChunk(cLightingChunkStay & a_Item);
- /** Prepares m_BlockTypes and m_HeightMap data; returns false if any of the chunks fail. Zeroes out the light arrays */
- bool ReadChunks(int a_ChunkX, int a_ChunkZ);
+ /** Prepares m_BlockTypes and m_HeightMap data; zeroes out the light arrays */
+ void ReadChunks(int a_ChunkX, int a_ChunkZ);
/** Uses m_HeightMap to initialize the m_SkyLight[] data; fills in seeds for the skylight */
void PrepareSkyLight(void);
@@ -145,6 +148,10 @@ protected:
/** Uses m_BlockTypes to initialize the m_BlockLight[] data; fills in seeds for the blocklight */
void PrepareBlockLight(void);
+ /** Same as PrepareBlockLight(), but uses a different traversal scheme; possibly better perf cache-wise.
+ To be compared in perf benchmarks. */
+ void PrepareBlockLight2(void);
+
/** Calculates light in the light array specified, using stored seeds */
void CalcLight(NIBBLETYPE * a_Light);
diff --git a/src/MobProximityCounter.cpp b/src/MobProximityCounter.cpp
index 519757c2c..ce20bf56b 100644
--- a/src/MobProximityCounter.cpp
+++ b/src/MobProximityCounter.cpp
@@ -24,7 +24,7 @@ void cMobProximityCounter::CollectMob(cEntity& a_Monster, cChunk& a_Chunk, doubl
if (a_Distance < it->second.m_Distance)
{
it->second.m_Distance = a_Distance;
- it->second.m_Chunk = a_Chunk;
+ it->second.m_Chunk = &a_Chunk;
}
}
@@ -36,7 +36,7 @@ void cMobProximityCounter::convertMaps()
{
for(tMonsterToDistance::const_iterator itr = m_MonsterToDistance.begin(); itr != m_MonsterToDistance.end(); ++itr)
{
- m_DistanceToMonster.insert(tDistanceToMonster::value_type(itr->second.m_Distance,sMonsterAndChunk(*itr->first,itr->second.m_Chunk)));
+ m_DistanceToMonster.insert(tDistanceToMonster::value_type(itr->second.m_Distance,sMonsterAndChunk(*itr->first,*itr->second.m_Chunk)));
}
}
diff --git a/src/MobProximityCounter.h b/src/MobProximityCounter.h
index 8a67139aa..79429eb60 100644
--- a/src/MobProximityCounter.h
+++ b/src/MobProximityCounter.h
@@ -16,9 +16,9 @@ protected :
// structs used for later maps (see m_MonsterToDistance and m_DistanceToMonster)
struct sDistanceAndChunk
{
- sDistanceAndChunk(double a_Distance, cChunk& a_Chunk) : m_Distance(a_Distance), m_Chunk(a_Chunk) {}
+ sDistanceAndChunk(double a_Distance, cChunk& a_Chunk) : m_Distance(a_Distance), m_Chunk(&a_Chunk) {}
double m_Distance;
- cChunk& m_Chunk;
+ cChunk* m_Chunk;
};
struct sMonsterAndChunk
{
diff --git a/src/Mobs/Bat.cpp b/src/Mobs/Bat.cpp
index 1417ddd9e..c072d4f48 100644
--- a/src/Mobs/Bat.cpp
+++ b/src/Mobs/Bat.cpp
@@ -7,8 +7,7 @@
cBat::cBat(void) :
- // TODO: The size is only a guesstimate, measure in vanilla and fix the size values here
- super("Bat", mtBat, "mob.bat.hurt", "mob.bat.death", 0.7, 0.7)
+ super("Bat", mtBat, "mob.bat.hurt", "mob.bat.death", 0.5, 0.9)
{
}
diff --git a/src/Mobs/Blaze.cpp b/src/Mobs/Blaze.cpp
index 326b42f07..19bdf8737 100644
--- a/src/Mobs/Blaze.cpp
+++ b/src/Mobs/Blaze.cpp
@@ -9,8 +9,7 @@
cBlaze::cBlaze(void) :
- // TODO: The size is only a guesstimate, measure in vanilla and fix the size values here
- super("Blaze", mtBlaze, "mob.blaze.hit", "mob.blaze.death", 0.7, 1.8)
+ super("Blaze", mtBlaze, "mob.blaze.hit", "mob.blaze.death", 0.6, 1.8)
{
}
@@ -45,7 +44,7 @@ void cBlaze::Attack(float a_Dt)
{
return;
}
- if (!FireCharge->Initialize(m_World))
+ if (!FireCharge->Initialize(*m_World))
{
delete FireCharge;
return;
diff --git a/src/Mobs/CaveSpider.cpp b/src/Mobs/CaveSpider.cpp
index 56ecd2d28..1157b81f9 100644
--- a/src/Mobs/CaveSpider.cpp
+++ b/src/Mobs/CaveSpider.cpp
@@ -20,7 +20,6 @@ void cCaveSpider::Tick(float a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
- // TODO: Check vanilla if cavespiders really get passive during the day / in daylight
m_EMPersonality = (GetWorld()->GetTimeOfDay() < (12000 + 1000)) ? PASSIVE : AGGRESSIVE;
}
diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp
index 9cf539427..a7b97f604 100644
--- a/src/Mobs/Creeper.cpp
+++ b/src/Mobs/Creeper.cpp
@@ -43,7 +43,7 @@ void cCreeper::Tick(float a_Dt, cChunk & a_Chunk)
if (m_ExplodingTimer == 30)
{
m_World->DoExplosionAt((m_bIsCharged ? 5 : 3), GetPosX(), GetPosY(), GetPosZ(), false, esMonster, this);
- Destroy();
+ Destroy(); // Just in case we aren't killed by the explosion
}
}
}
@@ -54,6 +54,12 @@ void cCreeper::Tick(float a_Dt, cChunk & a_Chunk)
void cCreeper::GetDrops(cItems & a_Drops, cEntity * a_Killer)
{
+ if (m_ExplodingTimer == 30)
+ {
+ // Exploded creepers drop naught but charred flesh, which Minecraft doesn't have
+ return;
+ }
+
int LootingLevel = 0;
if (a_Killer != NULL)
{
@@ -65,7 +71,7 @@ void cCreeper::GetDrops(cItems & a_Drops, cEntity * a_Killer)
{
if (((cMonster *)((cProjectileEntity *)a_Killer)->GetCreator())->GetMobType() == mtSkeleton)
{
- // 12 music discs. TickRand starts from 0, so range = 11. Disk IDs start at 2256, so add that. There.
+ // 12 music discs. TickRand starts from 0 to 11. Disk IDs start at 2256, so add that. There.
AddRandomDropItem(a_Drops, 1, 1, (short)m_World->GetTickRandomNumber(11) + 2256);
}
}
diff --git a/src/Mobs/Ghast.cpp b/src/Mobs/Ghast.cpp
index d8a7663f8..4df8e165c 100644
--- a/src/Mobs/Ghast.cpp
+++ b/src/Mobs/Ghast.cpp
@@ -46,7 +46,7 @@ void cGhast::Attack(float a_Dt)
{
return;
}
- if (!GhastBall->Initialize(m_World))
+ if (!GhastBall->Initialize(*m_World))
{
delete GhastBall;
return;
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index a9ca7a2fa..5843ca5a6 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -301,7 +301,7 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
if (DoesPosYRequireJump((int)floor(m_Destination.y)))
{
m_bOnGround = false;
- AddPosY(1.5); // Jump!!
+ AddSpeedY(5.2); // Jump!!
}
}
@@ -310,9 +310,19 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
{
Distance.y = 0;
Distance.Normalize();
- Distance *= 5;
- SetSpeedX(Distance.x);
- SetSpeedZ(Distance.z);
+
+ if (m_bOnGround)
+ {
+ Distance *= 2.5;
+ }
+ else
+ {
+ // Don't let the mob move too much if he's falling.
+ Distance *= 0.25;
+ }
+
+ AddSpeedX(Distance.x);
+ AddSpeedZ(Distance.z);
if (m_EMState == ESCAPING)
{ //Runs Faster when escaping :D otherwise they just walk away
diff --git a/src/Mobs/Skeleton.cpp b/src/Mobs/Skeleton.cpp
index 1e62d7987..e7f3971cc 100644
--- a/src/Mobs/Skeleton.cpp
+++ b/src/Mobs/Skeleton.cpp
@@ -81,7 +81,7 @@ void cSkeleton::Attack(float a_Dt)
{
return;
}
- if (!Arrow->Initialize(m_World))
+ if (!Arrow->Initialize(*m_World))
{
delete Arrow;
return;
diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp
index 170f4fdc0..da4cc7765 100644
--- a/src/Mobs/Wither.cpp
+++ b/src/Mobs/Wither.cpp
@@ -30,7 +30,7 @@ bool cWither::IsArmored(void) const
-bool cWither::Initialize(cWorld * a_World)
+bool cWither::Initialize(cWorld & a_World)
{
// Set health before BroadcastSpawnEntity()
SetHealth(GetMaxHealth() / 3);
diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h
index 93b4f8bfc..03a320788 100644
--- a/src/Mobs/Wither.h
+++ b/src/Mobs/Wither.h
@@ -25,7 +25,7 @@ public:
bool IsArmored(void) const;
// cEntity overrides
- virtual bool Initialize(cWorld * a_World) override;
+ virtual bool Initialize(cWorld & a_World) override;
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
diff --git a/src/Noise.cpp b/src/Noise.cpp
index 89115d992..040421106 100644
--- a/src/Noise.cpp
+++ b/src/Noise.cpp
@@ -854,7 +854,7 @@ void cPerlinNoise::Generate2D(
NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
for (int i = 0; i < ArrayCount; i++)
{
- a_Array[i] *= Amplitude;
+ a_Array[i] = a_Workspace[i] * Amplitude;
}
// Add each octave:
@@ -949,3 +949,171 @@ void cPerlinNoise::Generate3D(
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cRidgedMultiNoise:
+
+cRidgedMultiNoise::cRidgedMultiNoise(void) :
+ m_Seed(0)
+{
+}
+
+
+
+
+
+cRidgedMultiNoise::cRidgedMultiNoise(int a_Seed) :
+ m_Seed(a_Seed)
+{
+}
+
+
+
+
+
+void cRidgedMultiNoise::SetSeed(int a_Seed)
+{
+ m_Seed = a_Seed;
+}
+
+
+
+
+
+void cRidgedMultiNoise::AddOctave(float a_Frequency, float a_Amplitude)
+{
+ m_Octaves.push_back(cOctave(m_Seed * ((int)m_Octaves.size() + 4) * 4 + 1024, a_Frequency, a_Amplitude));
+}
+
+
+
+
+
+void cRidgedMultiNoise::Generate2D(
+ NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y]
+ int a_SizeX, int a_SizeY, ///< Count of the array, in each direction
+ NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction
+ NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction
+ NOISE_DATATYPE * a_Workspace ///< Workspace that this function can use and trash
+) const
+{
+ if (m_Octaves.empty())
+ {
+ // No work to be done
+ ASSERT(!"RidgedMulti: No octaves to generate!");
+ return;
+ }
+
+ bool ShouldFreeWorkspace = (a_Workspace == NULL);
+ int ArrayCount = a_SizeX * a_SizeY;
+ if (ShouldFreeWorkspace)
+ {
+ a_Workspace = new NOISE_DATATYPE[ArrayCount];
+ }
+
+ // Generate the first octave directly into array:
+ const cOctave & FirstOctave = m_Octaves.front();
+
+ FirstOctave.m_Noise.Generate2D(
+ a_Workspace, a_SizeX, a_SizeY,
+ a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency,
+ a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency
+ );
+ NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
+ for (int i = 0; i < ArrayCount; i++)
+ {
+ a_Array[i] = fabs(a_Workspace[i] * Amplitude);
+ }
+
+ // Add each octave:
+ for (cOctaves::const_iterator itr = m_Octaves.begin() + 1, end = m_Octaves.end(); itr != end; ++itr)
+ {
+ // Generate cubic noise for the octave:
+ itr->m_Noise.Generate2D(
+ a_Workspace, a_SizeX, a_SizeY,
+ a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency,
+ a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency
+ );
+ // Add the cubic noise into the output:
+ NOISE_DATATYPE Amplitude = itr->m_Amplitude;
+ for (int i = 0; i < ArrayCount; i++)
+ {
+ a_Array[i] += fabs(a_Workspace[i] * Amplitude);
+ }
+ }
+
+ if (ShouldFreeWorkspace)
+ {
+ delete[] a_Workspace;
+ }
+}
+
+
+
+
+
+void cRidgedMultiNoise::Generate3D(
+ NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z]
+ int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction
+ NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction
+ NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction
+ NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction
+ NOISE_DATATYPE * a_Workspace ///< Workspace that this function can use and trash
+) const
+{
+ if (m_Octaves.empty())
+ {
+ // No work to be done
+ ASSERT(!"RidgedMulti: No octaves to generate!");
+ return;
+ }
+
+ bool ShouldFreeWorkspace = (a_Workspace == NULL);
+ int ArrayCount = a_SizeX * a_SizeY * a_SizeZ;
+ if (ShouldFreeWorkspace)
+ {
+ a_Workspace = new NOISE_DATATYPE[ArrayCount];
+ }
+
+ // Generate the first octave directly into array:
+ const cOctave & FirstOctave = m_Octaves.front();
+
+ FirstOctave.m_Noise.Generate3D(
+ a_Workspace, a_SizeX, a_SizeY, a_SizeZ,
+ a_StartX * FirstOctave.m_Frequency, a_EndX * FirstOctave.m_Frequency,
+ a_StartY * FirstOctave.m_Frequency, a_EndY * FirstOctave.m_Frequency,
+ a_StartZ * FirstOctave.m_Frequency, a_EndZ * FirstOctave.m_Frequency
+ );
+ NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude;
+ for (int i = 0; i < ArrayCount; i++)
+ {
+ a_Array[i] = a_Workspace[i] * Amplitude;
+ }
+
+ // Add each octave:
+ for (cOctaves::const_iterator itr = m_Octaves.begin() + 1, end = m_Octaves.end(); itr != end; ++itr)
+ {
+ // Generate cubic noise for the octave:
+ itr->m_Noise.Generate3D(
+ a_Workspace, a_SizeX, a_SizeY, a_SizeZ,
+ a_StartX * itr->m_Frequency, a_EndX * itr->m_Frequency,
+ a_StartY * itr->m_Frequency, a_EndY * itr->m_Frequency,
+ a_StartZ * itr->m_Frequency, a_EndZ * itr->m_Frequency
+ );
+ // Add the cubic noise into the output:
+ NOISE_DATATYPE Amplitude = itr->m_Amplitude;
+ for (int i = 0; i < ArrayCount; i++)
+ {
+ a_Array[i] += a_Workspace[i] * Amplitude;
+ }
+ }
+
+ if (ShouldFreeWorkspace)
+ {
+ delete[] a_Workspace;
+ }
+}
+
+
+
+
diff --git a/src/Noise.h b/src/Noise.h
index e605051b5..83af0cf08 100644
--- a/src/Noise.h
+++ b/src/Noise.h
@@ -192,6 +192,70 @@ protected:
+class cRidgedMultiNoise
+{
+public:
+ cRidgedMultiNoise(void);
+ cRidgedMultiNoise(int a_Seed);
+
+
+ void SetSeed(int a_Seed);
+
+ void AddOctave(NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude);
+
+ void Generate1D(
+ NOISE_DATATYPE * a_Array, ///< Array to generate into
+ int a_SizeX, ///< Count of the array
+ NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array
+ NOISE_DATATYPE * a_Workspace = NULL ///< Workspace that this function can use and trash
+ ) const;
+
+
+ void Generate2D(
+ NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y]
+ int a_SizeX, int a_SizeY, ///< Count of the array, in each direction
+ NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction
+ NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction
+ NOISE_DATATYPE * a_Workspace = NULL ///< Workspace that this function can use and trash
+ ) const;
+
+
+ void Generate3D(
+ NOISE_DATATYPE * a_Array, ///< Array to generate into [x + a_SizeX * y + a_SizeX * a_SizeY * z]
+ int a_SizeX, int a_SizeY, int a_SizeZ, ///< Count of the array, in each direction
+ NOISE_DATATYPE a_StartX, NOISE_DATATYPE a_EndX, ///< Noise-space coords of the array in the X direction
+ NOISE_DATATYPE a_StartY, NOISE_DATATYPE a_EndY, ///< Noise-space coords of the array in the Y direction
+ NOISE_DATATYPE a_StartZ, NOISE_DATATYPE a_EndZ, ///< Noise-space coords of the array in the Z direction
+ NOISE_DATATYPE * a_Workspace = NULL ///< Workspace that this function can use and trash
+ ) const;
+
+protected:
+ class cOctave
+ {
+ public:
+ cCubicNoise m_Noise;
+
+ NOISE_DATATYPE m_Frequency; // Coord multiplier
+ NOISE_DATATYPE m_Amplitude; // Value multiplier
+
+ cOctave(int a_Seed, NOISE_DATATYPE a_Frequency, NOISE_DATATYPE a_Amplitude) :
+ m_Noise(a_Seed),
+ m_Frequency(a_Frequency),
+ m_Amplitude(a_Amplitude)
+ {
+ }
+ } ;
+
+ typedef std::vector<cOctave> cOctaves;
+
+ int m_Seed;
+ cOctaves m_Octaves;
+} ;
+
+
+
+
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Inline function definitions:
// These need to be in the header, otherwise linker error occur in MSVC
diff --git a/src/OSSupport/IsThread.cpp b/src/OSSupport/IsThread.cpp
index 04fc818e4..67f336c97 100644
--- a/src/OSSupport/IsThread.cpp
+++ b/src/OSSupport/IsThread.cpp
@@ -60,6 +60,9 @@ static void SetThreadName(DWORD dwThreadID, const char * threadName)
cIsThread::cIsThread(const AString & iThreadName) :
m_ShouldTerminate(false),
m_ThreadName(iThreadName),
+ #ifdef _WIN32
+ m_ThreadID(0),
+ #endif
m_Handle(NULL_HANDLE)
{
}
@@ -83,8 +86,8 @@ bool cIsThread::Start(void)
ASSERT(m_Handle == NULL_HANDLE); // Has already started one thread?
#ifdef _WIN32
// Create the thread suspended, so that the mHandle variable is valid in the thread procedure
- DWORD ThreadID = 0;
- m_Handle = CreateThread(NULL, 0, thrExecute, this, CREATE_SUSPENDED, &ThreadID);
+ m_ThreadID = 0;
+ m_Handle = CreateThread(NULL, 0, thrExecute, this, CREATE_SUSPENDED, &m_ThreadID);
if (m_Handle == NULL)
{
LOGERROR("ERROR: Could not create thread \"%s\", GLE = %d!", m_ThreadName.c_str(), GetLastError());
@@ -96,7 +99,7 @@ bool cIsThread::Start(void)
// Thread naming is available only in MSVC
if (!m_ThreadName.empty())
{
- SetThreadName(ThreadID, m_ThreadName.c_str());
+ SetThreadName(m_ThreadID, m_ThreadName.c_str());
}
#endif // _DEBUG and _MSC_VER
@@ -177,3 +180,15 @@ unsigned long cIsThread::GetCurrentID(void)
+bool cIsThread::IsCurrentThread(void) const
+{
+ #ifdef _WIN32
+ return (GetCurrentThreadId() == m_ThreadID);
+ #else
+ return (m_Handle == pthread_self());
+ #endif
+}
+
+
+
+
diff --git a/src/OSSupport/IsThread.h b/src/OSSupport/IsThread.h
index 57651a490..c20fc3e7e 100644
--- a/src/OSSupport/IsThread.h
+++ b/src/OSSupport/IsThread.h
@@ -48,6 +48,9 @@ public:
/// Returns the OS-dependent thread ID for the caller's thread
static unsigned long GetCurrentID(void);
+ /** Returns true if the thread calling this function is the thread contained within this object. */
+ bool IsCurrentThread(void) const;
+
protected:
AString m_ThreadName;
@@ -60,6 +63,7 @@ protected:
#ifdef _WIN32
+ DWORD m_ThreadID;
HANDLE m_Handle;
static DWORD __stdcall thrExecute(LPVOID a_Param)
diff --git a/src/Piston.cpp b/src/Piston.cpp
deleted file mode 100644
index b21d576f3..000000000
--- a/src/Piston.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "Piston.h"
-#include "ChunkDef.h"
-#include "Entities/Pickup.h"
-#include "Item.h"
-#include "Root.h"
-#include "ClientHandle.h"
-#include "World.h"
-#include "Server.h"
-#include "Blocks/BlockHandler.h"
-#include "BlockInServerPluginInterface.h"
-
-
-
-
-
-/// Number of ticks that the piston extending / retracting waits before setting the block
-const int PISTON_TICK_DELAY = 1;
-
-
-
-
-
-cPiston::cPiston(cWorld * a_World)
- : m_World(a_World)
-{
-}
-
-
-
-
-
-int cPiston::FirstPassthroughBlock(int pistonX, int pistonY, int pistonZ, NIBBLETYPE pistonmeta)
-{
- // Examine each of the 12 blocks ahead of the piston:
- for (int ret = 0; ret < 12; ret++)
- {
- BLOCKTYPE currBlock;
- NIBBLETYPE currMeta;
- AddDir(pistonX, pistonY, pistonZ, pistonmeta, 1);
- m_World->GetBlockTypeMeta(pistonX, pistonY, pistonZ, currBlock, currMeta);
- if (CanBreakPush(currBlock, currMeta))
- {
- // This block breaks when pushed, extend up to here
- return ret;
- }
- if (!CanPush(currBlock, currMeta))
- {
- // This block cannot be pushed at all, the piston can't extend
- return -1;
- }
- }
- // There is no space for the blocks to move, piston can't extend
- return -1;
-}
-
-
-
-
-
-void cPiston::ExtendPiston(int pistx, int pisty, int pistz)
-{
- BLOCKTYPE pistonBlock;
- NIBBLETYPE pistonMeta;
- m_World->GetBlockTypeMeta(pistx, pisty, pistz, pistonBlock, pistonMeta);
-
- if (IsExtended(pistonMeta))
- {
- // Already extended, bail out
- return;
- }
-
- int dist = FirstPassthroughBlock(pistx, pisty, pistz, pistonMeta);
- if (dist < 0)
- {
- // FirstPassthroughBlock says piston can't push anything, bail out
- return;
- }
-
- m_World->BroadcastBlockAction(pistx, pisty, pistz, 0, pistonMeta, pistonBlock);
- m_World->BroadcastSoundEffect("tile.piston.out", pistx * 8, pisty * 8, pistz * 8, 0.5f, 0.7f);
-
- // Drop the breakable block in the line, if appropriate:
- AddDir(pistx, pisty, pistz, pistonMeta, dist + 1); // "pist" now at the breakable / empty block
- BLOCKTYPE currBlock;
- NIBBLETYPE currMeta;
- m_World->GetBlockTypeMeta(pistx, pisty, pistz, currBlock, currMeta);
- if (currBlock != E_BLOCK_AIR)
- {
- cBlockHandler * Handler = BlockHandler(currBlock);
- if (Handler->DoesDropOnUnsuitable())
- {
- cChunkInterface ChunkInterface(m_World->GetChunkMap());
- cBlockInServerPluginInterface PluginInterface(*m_World);
- Handler->DropBlock(ChunkInterface, *m_World, PluginInterface, NULL, pistx, pisty, pistz);
- }
- }
-
- // Push blocks, from the furthest to the nearest:
- int oldx = pistx, oldy = pisty, oldz = pistz;
- NIBBLETYPE currBlockMeta;
- for (int i = dist + 1; i > 1; i--)
- {
- AddDir(pistx, pisty, pistz, pistonMeta, -1);
- m_World->GetBlockTypeMeta(pistx, pisty, pistz, currBlock, currBlockMeta);
- m_World->QueueSetBlock( oldx, oldy, oldz, currBlock, currBlockMeta, PISTON_TICK_DELAY);
- oldx = pistx;
- oldy = pisty;
- oldz = pistz;
- }
-
- int extx = pistx;
- int exty = pisty;
- int extz = pistz;
- AddDir(pistx, pisty, pistz, pistonMeta, -1);
- // "pist" now at piston body, "ext" at future extension
-
- m_World->SetBlock(pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8);
- m_World->QueueSetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0), PISTON_TICK_DELAY);
-}
-
-
-
-
-
-void cPiston::RetractPiston(int pistx, int pisty, int pistz)
-{
- BLOCKTYPE pistonBlock;
- NIBBLETYPE pistonMeta;
- m_World->GetBlockTypeMeta(pistx, pisty, pistz, pistonBlock, pistonMeta);
-
- if (!IsExtended(pistonMeta))
- {
- // Already retracted, bail out
- return;
- }
-
- // Check the extension:
- AddDir(pistx, pisty, pistz, pistonMeta, 1);
- if (m_World->GetBlock(pistx, pisty, pistz) != E_BLOCK_PISTON_EXTENSION)
- {
- LOGD("%s: Piston without an extension - still extending, or just in an invalid state?", __FUNCTION__);
- return;
- }
-
- AddDir(pistx, pisty, pistz, pistonMeta, -1);
- m_World->SetBlock(pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8));
- m_World->BroadcastBlockAction(pistx, pisty, pistz, 1, pistonMeta & ~(8), pistonBlock);
- m_World->BroadcastSoundEffect("tile.piston.in", pistx * 8, pisty * 8, pistz * 8, 0.5f, 0.7f);
- AddDir(pistx, pisty, pistz, pistonMeta, 1);
-
- // Retract the extension, pull block if appropriate
- if (IsSticky(pistonBlock))
- {
- int tempx = pistx, tempy = pisty, tempz = pistz;
- AddDir(tempx, tempy, tempz, pistonMeta, 1);
- BLOCKTYPE tempBlock;
- NIBBLETYPE tempMeta;
- m_World->GetBlockTypeMeta(tempx, tempy, tempz, tempBlock, tempMeta);
- if (CanPull(tempBlock, tempMeta))
- {
- // Pull the block
- m_World->QueueSetBlock(pistx, pisty, pistz, tempBlock, tempMeta, PISTON_TICK_DELAY);
- m_World->QueueSetBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0, PISTON_TICK_DELAY);
- }
- else
- {
- // Retract without pulling
- m_World->QueueSetBlock(pistx, pisty, pistz, E_BLOCK_AIR, 0, PISTON_TICK_DELAY);
- }
- }
- else
- {
- m_World->QueueSetBlock(pistx, pisty, pistz, E_BLOCK_AIR, 0, PISTON_TICK_DELAY);
- }
-}
-
-
-
-
-
-bool cPiston::IsExtended(NIBBLETYPE a_PistonMeta)
-{
- return ((a_PistonMeta & 0x8) != 0x0);
-}
-
-
-
-
-
-bool cPiston::IsSticky(BLOCKTYPE a_BlockType)
-{
- return (a_BlockType == E_BLOCK_STICKY_PISTON);
-}
-
-
-
-
-
-bool cPiston::CanPush(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
-{
- switch (a_BlockType)
- {
- case E_BLOCK_ANVIL:
- case E_BLOCK_BED:
- case E_BLOCK_BEDROCK:
- case E_BLOCK_BREWING_STAND:
- case E_BLOCK_CHEST:
- case E_BLOCK_COMMAND_BLOCK:
- case E_BLOCK_DISPENSER:
- case E_BLOCK_DROPPER:
- case E_BLOCK_ENCHANTMENT_TABLE:
- case E_BLOCK_END_PORTAL:
- case E_BLOCK_END_PORTAL_FRAME:
- case E_BLOCK_FURNACE:
- case E_BLOCK_LIT_FURNACE:
- case E_BLOCK_HOPPER:
- case E_BLOCK_JUKEBOX:
- case E_BLOCK_MOB_SPAWNER:
- case E_BLOCK_NETHER_PORTAL:
- case E_BLOCK_NOTE_BLOCK:
- case E_BLOCK_OBSIDIAN:
- case E_BLOCK_PISTON_EXTENSION:
- {
- return false;
- }
- case E_BLOCK_STICKY_PISTON:
- case E_BLOCK_PISTON:
- {
- // A piston can only be pushed if retracted:
- return !IsExtended(a_BlockMeta);
- }
- }
- return true;
-}
-
-
-
-
-
-bool cPiston::CanBreakPush(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
-{
- UNUSED(a_BlockMeta);
- return cBlockInfo::IsPistonBreakable(a_BlockType);
-}
-
-
-
-
-
-bool cPiston::CanPull(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
-{
- switch (a_BlockType)
- {
- case E_BLOCK_LAVA:
- case E_BLOCK_STATIONARY_LAVA:
- case E_BLOCK_STATIONARY_WATER:
- case E_BLOCK_WATER:
- {
- return false;
- }
- }
-
- if (CanBreakPush(a_BlockType, a_BlockMeta))
- {
- return false; // CanBreakPush returns true, but we need false to prevent pulling
- }
-
- return CanPush(a_BlockType, a_BlockMeta);
-}
-
-
-
-
-
-void cPiston::AddDir(int & a_BlockX, int & a_BlockY, int & a_BlockZ, NIBBLETYPE a_PistonMeta, int a_Amount)
-{
- switch (a_PistonMeta & 0x07)
- {
- case 0: a_BlockY -= a_Amount; break;
- case 1: a_BlockY += a_Amount; break;
- case 2: a_BlockZ -= a_Amount; break;
- case 3: a_BlockZ += a_Amount; break;
- case 4: a_BlockX -= a_Amount; break;
- case 5: a_BlockX += a_Amount; break;
- default:
- {
- LOGWARNING("%s: invalid direction %d, ignoring", __FUNCTION__, a_PistonMeta & 0x07);
- break;
- }
- }
-}
-
-
-
-
diff --git a/src/Piston.h b/src/Piston.h
deleted file mode 100644
index 9bbc8c6b9..000000000
--- a/src/Piston.h
+++ /dev/null
@@ -1,110 +0,0 @@
-
-#pragma once
-
-
-#include "Defines.h"
-
-
-// fwd: World.h
-class cWorld;
-
-
-
-
-
-class cPiston
-{
-public:
-
- cPiston(cWorld * a_World);
-
- static NIBBLETYPE RotationPitchToMetaData(double a_Rotation, double a_Pitch)
- {
- if (a_Pitch >= 50)
- {
- return 0x1;
- }
- else if (a_Pitch <= -50)
- {
- return 0x0;
- }
- else
- {
- a_Rotation += 90 + 45; // So its not aligned with axis
-
- if (a_Rotation > 360)
- {
- a_Rotation -= 360;
- }
- if ((a_Rotation >= 0) && (a_Rotation < 90))
- {
- return 0x4;
- }
- else if ((a_Rotation >= 180) && (a_Rotation < 270))
- {
- return 0x5;
- }
- else if ((a_Rotation >= 90) && (a_Rotation < 180))
- {
- return 0x2;
- }
- else
- {
- return 0x3;
- }
- }
- }
-
- static eBlockFace MetaDataToDirection(NIBBLETYPE a_MetaData)
- {
- switch (a_MetaData)
- {
- //case -1: return BLOCK_FACE_NONE; //can never happen as metadata is unsigned
- case 0x0: return BLOCK_FACE_YM;
- case 0x1: return BLOCK_FACE_YP;
- case 0x2: return BLOCK_FACE_ZM;
- case 0x3: return BLOCK_FACE_ZP;
- case 0x4: return BLOCK_FACE_XM;
- case 0x5: return BLOCK_FACE_XP;
- default:
- {
- ASSERT(!"Invalid Metadata");
- return BLOCK_FACE_NONE;
- }
- }
- }
-
- void ExtendPiston( int, int, int );
- void RetractPiston( int, int, int );
-
- /// Returns true if the piston (specified by blocktype) is a sticky piston
- static bool IsSticky(BLOCKTYPE a_BlockType);
-
- /// Returns true if the piston (with the specified meta) is extended
- static bool IsExtended(NIBBLETYPE a_PistonMeta);
-
- /// Returns true if the specified block can be pushed by a piston (and left intact)
- static bool CanPush(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
-
- /// Returns true if the specified block can be pushed by a piston and broken / replaced
- static bool CanBreakPush(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
-
- /// Returns true if the specified block can be pulled by a sticky piston
- static bool CanPull(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
-
- /// Updates the coords by the specified amount in the direction a piston of the specified meta is facing
- static void AddDir(int & a_BlockX, int & a_BlockY, int & a_BlockZ, NIBBLETYPE a_PistonMeta, int a_Amount);
-
-
- cWorld * m_World;
-
-private:
- void ChainMove( int, int, int, char, unsigned short * );
-
- /// Returns how many blocks the piston has to push (where the first free space is); <0 when unpushable
- int FirstPassthroughBlock(int a_PistonX, int a_PistonY, int a_PistonZ, NIBBLETYPE a_PistonMeta);
-} ;
-
-
-
-
diff --git a/src/PolarSSL++/AesCfb128Decryptor.h b/src/PolarSSL++/AesCfb128Decryptor.h
index 68c203d70..84c790b83 100644
--- a/src/PolarSSL++/AesCfb128Decryptor.h
+++ b/src/PolarSSL++/AesCfb128Decryptor.h
@@ -19,7 +19,6 @@
class cAesCfb128Decryptor
{
public:
- Byte test;
cAesCfb128Decryptor(void);
~cAesCfb128Decryptor();
diff --git a/src/PolarSSL++/CallbackSslContext.cpp b/src/PolarSSL++/CallbackSslContext.cpp
index 0cc88a14a..c4d19b2a0 100644
--- a/src/PolarSSL++/CallbackSslContext.cpp
+++ b/src/PolarSSL++/CallbackSslContext.cpp
@@ -11,7 +11,8 @@
-cCallbackSslContext::cCallbackSslContext(void)
+cCallbackSslContext::cCallbackSslContext(void) :
+ m_Callbacks(NULL)
{
// Nothing needed, but the constructor needs to exist so
}
diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h
index a543c6361..c6e569919 100644
--- a/src/Protocol/Protocol.h
+++ b/src/Protocol/Protocol.h
@@ -100,7 +100,7 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0;
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) = 0;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) = 0;
- virtual void SendRespawn (void) = 0;
+ virtual void SendRespawn (const cWorld & a_World) = 0;
virtual void SendExperience (void) = 0;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) = 0;
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) = 0;
diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp
index f3bdae3ac..491058919 100644
--- a/src/Protocol/Protocol125.cpp
+++ b/src/Protocol/Protocol125.cpp
@@ -133,7 +133,8 @@ typedef unsigned char Byte;
cProtocol125::cProtocol125(cClientHandle * a_Client) :
super(a_Client),
- m_ReceivedData(32 KiB)
+ m_ReceivedData(32 KiB),
+ m_LastSentDimension(dimNotSet)
{
}
@@ -591,6 +592,7 @@ void cProtocol125::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
WriteByte (0); // Unused
WriteByte (60); // Client list width or something
Flush();
+ m_LastSentDimension = a_World.GetDimension();
}
@@ -831,16 +833,23 @@ void cProtocol125::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect
-void cProtocol125::SendRespawn(void)
+void cProtocol125::SendRespawn(const cWorld & a_World)
{
cCSLock Lock(m_CSPacket);
+ if (m_LastSentDimension == a_World.GetDimension())
+ {
+ // Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do
+ return;
+ }
cPlayer * Player = m_Client->GetPlayer();
WriteByte (PACKET_RESPAWN);
- WriteInt ((int)(Player->GetWorld()->GetDimension()));
+ WriteInt (a_World.GetDimension());
WriteByte (2); // TODO: Difficulty; 2 = Normal
WriteChar ((char)Player->GetGameMode());
WriteShort (256); // Current world height
WriteString("default");
+ Flush();
+ m_LastSentDimension = a_World.GetDimension();
}
diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h
index 18a626a2d..85418f71f 100644
--- a/src/Protocol/Protocol125.h
+++ b/src/Protocol/Protocol125.h
@@ -72,7 +72,7 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
- virtual void SendRespawn (void) override;
+ virtual void SendRespawn (const cWorld & a_World) override;
virtual void SendExperience (void) override;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
@@ -113,6 +113,10 @@ protected:
cByteBuffer m_ReceivedData; ///< Buffer for the received data
AString m_Username; ///< Stored in ParseHandshake(), compared to Login username
+
+ /** The dimension that was last sent to a player in a Respawn or Login packet.
+ Used to avoid Respawning into the same dimension, which confuses the client. */
+ eDimension m_LastSentDimension;
virtual void SendData(const char * a_Data, size_t a_Size) override;
diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp
index f4717f592..1e3fc8de8 100644
--- a/src/Protocol/Protocol132.cpp
+++ b/src/Protocol/Protocol132.cpp
@@ -253,7 +253,7 @@ void cProtocol132::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
WriteByte (0); // Unused, used to be world height
WriteByte (8); // Client list width or something
Flush();
-
+ m_LastSentDimension = a_World.GetDimension();
SendCompass(a_World);
}
diff --git a/src/Protocol/Protocol16x.cpp b/src/Protocol/Protocol16x.cpp
index 714bf5e46..9e0f3f852 100644
--- a/src/Protocol/Protocol16x.cpp
+++ b/src/Protocol/Protocol16x.cpp
@@ -158,10 +158,10 @@ void cProtocol161::SendPlayerMaxSpeed(void)
-void cProtocol161::SendRespawn(void)
+void cProtocol161::SendRespawn(const cWorld & a_World)
{
// Besides sending the respawn, we need to also send the player max speed, otherwise the client reverts to super-fast
- super::SendRespawn();
+ super::SendRespawn(a_World);
SendPlayerMaxSpeed();
}
diff --git a/src/Protocol/Protocol16x.h b/src/Protocol/Protocol16x.h
index 8eedce8d5..e91dc8a1c 100644
--- a/src/Protocol/Protocol16x.h
+++ b/src/Protocol/Protocol16x.h
@@ -42,7 +42,7 @@ protected:
virtual void SendGameMode (eGameMode a_GameMode) override;
virtual void SendHealth (void) override;
virtual void SendPlayerMaxSpeed(void) override;
- virtual void SendRespawn (void) override;
+ virtual void SendRespawn (const cWorld & a_World) override;
virtual void SendWindowOpen (const cWindow & a_Window) override;
virtual int ParseEntityAction (void) override;
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index 7c526d103..02c577dc8 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -92,7 +92,8 @@ cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAdd
m_ReceivedData(32 KiB),
m_OutPacketBuffer(64 KiB),
m_OutPacketLenBuffer(20), // 20 bytes is more than enough for one VarInt
- m_IsEncrypted(false)
+ m_IsEncrypted(false),
+ m_LastSentDimension(dimNotSet)
{
// Create the comm log file, if so requested:
if (g_ShouldLogCommIn || g_ShouldLogCommOut)
@@ -234,7 +235,8 @@ void cProtocol172::SendChat(const cCompositeChat & a_Message)
// Compose the complete Json string to send:
Json::Value msg;
- msg["text"] = cClientHandle::FormatMessageType(m_Client->GetPlayer()->GetWorld()->ShouldUseChatPrefixes(), a_Message.GetMessageType(), a_Message.GetAdditionalMessageTypeData()); // The client crashes without this field being present
+ cWorld * World = m_Client->GetPlayer()->GetWorld();
+ msg["text"] = cClientHandle::FormatMessageType((World == NULL) ? false : World->ShouldUseChatPrefixes(), a_Message.GetMessageType(), a_Message.GetAdditionalMessageTypeData()); // The client crashes without this field being present
const cCompositeChat::cParts & Parts = a_Message.GetParts();
for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr)
{
@@ -655,6 +657,7 @@ void cProtocol172::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
Pkt.WriteByte(std::min(Server->GetMaxPlayers(), 60));
Pkt.WriteString("default"); // Level type - wtf?
}
+ m_LastSentDimension = a_World.GetDimension();
// Send the spawn position:
{
@@ -983,14 +986,21 @@ void cProtocol172::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect
-void cProtocol172::SendRespawn(void)
+void cProtocol172::SendRespawn(const cWorld & a_World)
{
+ if (m_LastSentDimension == a_World.GetDimension())
+ {
+ // Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do
+ return;
+ }
+
cPacketizer Pkt(*this, 0x07); // Respawn packet
cPlayer * Player = m_Client->GetPlayer();
- Pkt.WriteInt(Player->GetWorld()->GetDimension());
+ Pkt.WriteInt(a_World.GetDimension());
Pkt.WriteByte(2); // TODO: Difficulty (set to Normal)
Pkt.WriteByte((Byte)Player->GetEffectiveGameMode());
Pkt.WriteString("default");
+ m_LastSentDimension = a_World.GetDimension();
}
diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h
index 3c6a8c085..8be1d9211 100644
--- a/src/Protocol/Protocol17x.h
+++ b/src/Protocol/Protocol17x.h
@@ -104,7 +104,7 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
- virtual void SendRespawn (void) override;
+ virtual void SendRespawn (const cWorld & a_World) override;
virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8
virtual void SendExperience (void) override;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
@@ -244,6 +244,10 @@ protected:
/** The logfile where the comm is logged, when g_ShouldLogComm is true */
cFile m_CommLogFile;
+ /** The dimension that was last sent to a player in a Respawn or Login packet.
+ Used to avoid Respawning into the same dimension, which confuses the client. */
+ eDimension m_LastSentDimension;
+
/** Adds the received (unencrypted) data to m_ReceivedData, parses complete packets */
void AddReceivedData(const char * a_Data, size_t a_Size);
diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp
index b0cbb6def..35a331f43 100644
--- a/src/Protocol/ProtocolRecognizer.cpp
+++ b/src/Protocol/ProtocolRecognizer.cpp
@@ -555,10 +555,10 @@ void cProtocolRecognizer::SendRemoveEntityEffect(const cEntity & a_Entity, int a
-void cProtocolRecognizer::SendRespawn(void)
+void cProtocolRecognizer::SendRespawn(const cWorld & a_World)
{
ASSERT(m_Protocol != NULL);
- m_Protocol->SendRespawn();
+ m_Protocol->SendRespawn(a_World);
}
diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h
index 3a291bf7a..5e178447c 100644
--- a/src/Protocol/ProtocolRecognizer.h
+++ b/src/Protocol/ProtocolRecognizer.h
@@ -107,7 +107,7 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
- virtual void SendRespawn (void) override;
+ virtual void SendRespawn (const cWorld & a_World) override;
virtual void SendExperience (void) override;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
diff --git a/src/Server.cpp b/src/Server.cpp
index aa731cdd2..66bccd680 100644
--- a/src/Server.cpp
+++ b/src/Server.cpp
@@ -107,10 +107,16 @@ void cServer::cTickThread::Execute(void)
cServer::cServer(void) :
m_ListenThreadIPv4(*this, cSocket::IPv4, "Client IPv4"),
m_ListenThreadIPv6(*this, cSocket::IPv6, "Client IPv6"),
+ m_PlayerCount(0),
+ m_PlayerCountDiff(0),
+ m_ClientViewDistance(0),
m_bIsConnected(false),
m_bRestarting(false),
m_RCONServer(*this),
- m_TickThread(*this)
+ m_MaxPlayers(0),
+ m_bIsHardcore(false),
+ m_TickThread(*this),
+ m_ShouldAuthenticate(false)
{
}
diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp
index 4fbfffd43..311f8b4c4 100644
--- a/src/Simulator/FireSimulator.cpp
+++ b/src/Simulator/FireSimulator.cpp
@@ -95,8 +95,10 @@ void cFireSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChun
int NumMSecs = (int)a_Dt;
for (cCoordWithIntList::iterator itr = Data.begin(); itr != Data.end();)
{
- int idx = cChunkDef::MakeIndexNoCheck(itr->x, itr->y, itr->z);
- BLOCKTYPE BlockType = a_Chunk->GetBlock(idx);
+ int x = itr->x;
+ int y = itr->y;
+ int z = itr->z;
+ BLOCKTYPE BlockType = a_Chunk->GetBlock(x,y,z);
if (!IsAllowedBlock(BlockType))
{
@@ -125,7 +127,7 @@ void cFireSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChun
itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width
);
*/
- NIBBLETYPE BlockMeta = a_Chunk->GetMeta(idx);
+ NIBBLETYPE BlockMeta = a_Chunk->GetMeta(x, y, z);
if (BlockMeta == 0x0f)
{
// The fire burnt out completely
@@ -140,7 +142,7 @@ void cFireSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChun
if((itr->y > 0) && (!DoesBurnForever(a_Chunk->GetBlock(itr->x, itr->y - 1, itr->z))))
{
- a_Chunk->SetMeta(idx, BlockMeta + 1);
+ a_Chunk->SetMeta(x, y, z, BlockMeta + 1);
}
itr->Data = GetBurnStepTime(a_Chunk, itr->x, itr->y, itr->z); // TODO: Add some randomness into this
} // for itr - Data[]
diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp
index 074063add..69c8b9f56 100644
--- a/src/Simulator/IncrementalRedstoneSimulator.cpp
+++ b/src/Simulator/IncrementalRedstoneSimulator.cpp
@@ -11,14 +11,20 @@
#include "../Blocks/BlockDoor.h"
#include "../Blocks/BlockButton.h"
#include "../Blocks/BlockLever.h"
-#include "../Piston.h"
+#include "../Blocks/BlockPiston.h"
-cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulator(cWorld & a_World)
- : super(a_World)
+cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulator(cWorld & a_World) :
+ super(a_World),
+ m_RedstoneSimulatorChunkData(),
+ m_PoweredBlocks(),
+ m_LinkedPoweredBlocks(),
+ m_SimulatedPlayerToggleableBlocks(),
+ m_RepeatersDelayList(),
+ m_Chunk()
{
}
@@ -53,18 +59,21 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
int RelZ = 0;
BLOCKTYPE Block;
NIBBLETYPE Meta;
+ cChunk * Chunk;
if (a_OtherChunk != NULL)
{
RelX = a_BlockX - a_OtherChunk->GetPosX() * cChunkDef::Width;
RelZ = a_BlockZ - a_OtherChunk->GetPosZ() * cChunkDef::Width;
a_OtherChunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta);
+ Chunk = a_OtherChunk;
}
else
{
RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width;
RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width;
a_Chunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta);
+ Chunk = a_Chunk;
}
// Every time a block is changed (AddBlock called), we want to go through all lists and check to see if the coordiantes stored within are still valid
@@ -83,6 +92,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list as it no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = PoweredBlocks->erase(itr);
+ Chunk->SetIsRedstoneDirty(true);
continue;
}
else if (
@@ -97,8 +107,25 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = PoweredBlocks->erase(itr);
+ Chunk->SetIsRedstoneDirty(true);
continue;
}
+ else if (Block == E_BLOCK_DAYLIGHT_SENSOR)
+ {
+ if (!m_World.IsChunkLighted(Chunk->GetPosX(), Chunk->GetPosZ()))
+ {
+ m_World.QueueLightChunk(Chunk->GetPosX(), Chunk->GetPosZ());
+ }
+ else
+ {
+ if (Chunk->GetTimeAlteredLight(Chunk->GetSkyLight(RelX, a_BlockY + 1, RelZ)) <= 7)
+ {
+ itr = PoweredBlocks->erase(itr);
+ Chunk->SetIsRedstoneDirty(true);
+ continue;
+ }
+ }
+ }
++itr;
}
@@ -112,6 +139,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = LinkedPoweredBlocks->erase(itr);
+ Chunk->SetIsRedstoneDirty(true);
continue;
}
else if (
@@ -125,6 +153,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = LinkedPoweredBlocks->erase(itr);
+ Chunk->SetIsRedstoneDirty(true);
continue;
}
}
@@ -134,6 +163,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer powered through a valid middle block", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = LinkedPoweredBlocks->erase(itr);
+ Chunk->SetIsRedstoneDirty(true);
continue;
}
}
@@ -188,6 +218,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
}
else
{
+ itr->DataTwo = false;
itr->Data = Block; // Update block information
}
return;
@@ -198,8 +229,16 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{
return;
}
-
- RedstoneSimulatorChunkData->push_back(cCoordWithBlockAndBool(RelX, a_BlockY, RelZ, Block, false));
+
+ for (cRedstoneSimulatorChunkData::iterator itr = a_Chunk->GetRedstoneSimulatorQueuedData()->begin(); itr != a_Chunk->GetRedstoneSimulatorQueuedData()->end(); ++itr)
+ {
+ if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ))
+ {
+ // Can't have duplicates in here either, in case something adds the block again before the structure can written to the main chunk data
+ return;
+ }
+ }
+ a_Chunk->GetRedstoneSimulatorQueuedData()->push_back(cCoordWithBlockAndBool(RelX, a_BlockY, RelZ, Block, false));
}
@@ -208,22 +247,29 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk)
{
- // We still attempt to simulate all blocks in the chunk every tick, because of outside influence that needs to be taken into account
- // For example, repeaters need to be ticked, pressure plates checked for entities, daylight sensor checked for light changes, etc.
- // The easiest way to make this more efficient is probably just to reduce code within the handlers that put too much strain on server, like getting or setting blocks
- // A marking dirty system might be a TODO for later on, perhaps
-
m_RedstoneSimulatorChunkData = a_Chunk->GetRedstoneSimulatorData();
- if (m_RedstoneSimulatorChunkData->empty())
+ if (m_RedstoneSimulatorChunkData->empty() && a_Chunk->GetRedstoneSimulatorQueuedData()->empty())
{
return;
}
+ m_RedstoneSimulatorChunkData->insert(m_RedstoneSimulatorChunkData->end(), a_Chunk->GetRedstoneSimulatorQueuedData()->begin(), a_Chunk->GetRedstoneSimulatorQueuedData()->end());
+ a_Chunk->GetRedstoneSimulatorQueuedData()->clear();
+
m_PoweredBlocks = a_Chunk->GetRedstoneSimulatorPoweredBlocksList();
m_RepeatersDelayList = a_Chunk->GetRedstoneSimulatorRepeatersDelayList();
m_SimulatedPlayerToggleableBlocks = a_Chunk->GetRedstoneSimulatorSimulatedPlayerToggleableList();
m_LinkedPoweredBlocks = a_Chunk->GetRedstoneSimulatorLinkedBlocksList();
m_Chunk = a_Chunk;
+ bool ShouldUpdateSimulateOnceBlocks = false;
+
+ if (a_Chunk->IsRedstoneDirty())
+ {
+ // Simulate the majority of devices only if something (blockwise or power-wise) has changed
+ // Make sure to allow the chunk to resimulate after the initial run if there was a power change (ShouldUpdateSimulateOnceBlocks helps to do this)
+ a_Chunk->SetIsRedstoneDirty(false);
+ ShouldUpdateSimulateOnceBlocks = true;
+ }
for (cRedstoneSimulatorChunkData::iterator dataitr = m_RedstoneSimulatorChunkData->begin(); dataitr != m_RedstoneSimulatorChunkData->end();)
{
@@ -235,63 +281,25 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
switch (dataitr->Data)
{
- case E_BLOCK_BLOCK_OF_REDSTONE: HandleRedstoneBlock(dataitr->x, dataitr->y, dataitr->z); break;
- case E_BLOCK_LEVER: HandleRedstoneLever(dataitr->x, dataitr->y, dataitr->z); break;
- case E_BLOCK_FENCE_GATE: HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); break;
- case E_BLOCK_TNT: HandleTNT(dataitr->x, dataitr->y, dataitr->z); break;
- case E_BLOCK_TRAPDOOR: HandleTrapdoor(dataitr->x, dataitr->y, dataitr->z); break;
- case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(dataitr->x, dataitr->y, dataitr->z); break;
- case E_BLOCK_NOTE_BLOCK: HandleNoteBlock(dataitr->x, dataitr->y, dataitr->z); break;
- case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(dataitr->x, dataitr->y, dataitr->z); break;
- case E_BLOCK_COMMAND_BLOCK: HandleCommandBlock(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(dataitr->x, dataitr->y, dataitr->z); break;
- case E_BLOCK_REDSTONE_TORCH_OFF:
- case E_BLOCK_REDSTONE_TORCH_ON:
- {
- HandleRedstoneTorch(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
- break;
- }
- case E_BLOCK_STONE_BUTTON:
- case E_BLOCK_WOODEN_BUTTON:
- {
- HandleRedstoneButton(dataitr->x, dataitr->y, dataitr->z);
- break;
- }
case E_BLOCK_REDSTONE_REPEATER_OFF:
case E_BLOCK_REDSTONE_REPEATER_ON:
{
- HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
- break;
- }
- case E_BLOCK_PISTON:
- case E_BLOCK_STICKY_PISTON:
- {
- HandlePiston(dataitr->x, dataitr->y, dataitr->z);
- break;
- }
- case E_BLOCK_REDSTONE_LAMP_OFF:
- case E_BLOCK_REDSTONE_LAMP_ON:
- {
- HandleRedstoneLamp(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
- break;
- }
- case E_BLOCK_DISPENSER:
- case E_BLOCK_DROPPER:
- {
- HandleDropSpenser(dataitr->x, dataitr->y, dataitr->z);
- break;
- }
- case E_BLOCK_WOODEN_DOOR:
- case E_BLOCK_IRON_DOOR:
- {
- HandleDoor(dataitr->x, dataitr->y, dataitr->z);
- break;
- }
- case E_BLOCK_ACTIVATOR_RAIL:
- case E_BLOCK_DETECTOR_RAIL:
- case E_BLOCK_POWERED_RAIL:
- {
- HandleRail(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
+ bool FoundItem = false;
+ for (RepeatersDelayList::iterator repeateritr = m_RepeatersDelayList->begin(); repeateritr != m_RepeatersDelayList->end(); ++repeateritr)
+ {
+ if (repeateritr->a_RelBlockPos == Vector3i(dataitr->x, dataitr->y, dataitr->z))
+ {
+ HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data, repeateritr);
+ FoundItem = true;
+ break;
+ }
+ }
+ if (!FoundItem && ShouldUpdateSimulateOnceBlocks)
+ {
+ HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data, m_RepeatersDelayList->end());
+ }
break;
}
case E_BLOCK_WOODEN_PRESSURE_PLATE:
@@ -302,7 +310,67 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
HandlePressurePlate(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
break;
}
- default: LOGD("Unhandled block (!) or unimplemented redstone block: %s", ItemToString(dataitr->Data).c_str()); break;
+ default: break;
+ }
+
+ if (ShouldUpdateSimulateOnceBlocks)
+ {
+ switch (dataitr->Data)
+ {
+ case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_COMMAND_BLOCK: HandleCommandBlock(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_NOTE_BLOCK: HandleNoteBlock(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_BLOCK_OF_REDSTONE: HandleRedstoneBlock(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_LEVER: HandleRedstoneLever(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_FENCE_GATE: HandleFenceGate(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_TNT: HandleTNT(dataitr->x, dataitr->y, dataitr->z); break;
+ case E_BLOCK_TRAPDOOR: HandleTrapdoor(dataitr->x, dataitr->y, dataitr->z); break;
+
+ case E_BLOCK_ACTIVATOR_RAIL:
+ case E_BLOCK_DETECTOR_RAIL:
+ case E_BLOCK_POWERED_RAIL:
+ {
+ HandleRail(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
+ break;
+ }
+ case E_BLOCK_WOODEN_DOOR:
+ case E_BLOCK_IRON_DOOR:
+ {
+ HandleDoor(dataitr->x, dataitr->y, dataitr->z);
+ break;
+ }
+ case E_BLOCK_REDSTONE_LAMP_OFF:
+ case E_BLOCK_REDSTONE_LAMP_ON:
+ {
+ HandleRedstoneLamp(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
+ break;
+ }
+ case E_BLOCK_DISPENSER:
+ case E_BLOCK_DROPPER:
+ {
+ HandleDropSpenser(dataitr->x, dataitr->y, dataitr->z);
+ break;
+ }
+ case E_BLOCK_PISTON:
+ case E_BLOCK_STICKY_PISTON:
+ {
+ HandlePiston(dataitr->x, dataitr->y, dataitr->z);
+ break;
+ }
+ case E_BLOCK_REDSTONE_TORCH_OFF:
+ case E_BLOCK_REDSTONE_TORCH_ON:
+ {
+ HandleRedstoneTorch(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
+ break;
+ }
+ case E_BLOCK_STONE_BUTTON:
+ case E_BLOCK_WOODEN_BUTTON:
+ {
+ HandleRedstoneButton(dataitr->x, dataitr->y, dataitr->z);
+ break;
+ }
+ default: break;
+ }
}
++dataitr;
}
@@ -699,7 +767,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_RelBlockX, int a_Re
-void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState)
+void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState, RepeatersDelayList::iterator a_Itr)
{
/* Repeater Orientation Mini Guide:
===================================
@@ -725,87 +793,103 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int
// Create a variable holding my meta to avoid multiple lookups.
NIBBLETYPE a_Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
bool IsOn = (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON);
-
+
+ bool WereItrsChanged = false;
if (!IsRepeaterLocked(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta)) // If we're locked, change nothing. Otherwise:
{
bool IsSelfPowered = IsRepeaterPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta);
if (IsSelfPowered && !IsOn) // Queue a power change if powered, but not on and not locked.
{
- QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, true);
+ WereItrsChanged = QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, true);
}
else if (!IsSelfPowered && IsOn) // Queue a power change if unpowered, on, and not locked.
{
- QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false);
+ WereItrsChanged = QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false);
+ }
+ else if (a_Itr == m_RepeatersDelayList->end())
+ {
+ return;
}
}
+ else if (a_Itr == m_RepeatersDelayList->end())
+ {
+ return;
+ }
- for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end(); ++itr)
+ if (WereItrsChanged)
{
- if (!itr->a_RelBlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ)))
+ for (a_Itr = m_RepeatersDelayList->begin(); a_Itr != m_RepeatersDelayList->end(); ++a_Itr)
{
- continue;
+ if (a_Itr->a_RelBlockPos == Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ))
+ {
+ // Leave a_Itr at where we found the entry
+ break;
+ }
}
+ }
- if (itr->a_ElapsedTicks >= itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks?
+ // a_Itr may be passed with m_RepeatersDelayList::end, however, we can guarantee this iterator is always valid because...
+ // ...QueueRepeaterPowerChange is called to add an entry (and the above code updates iterator). However, if the repeater was locked or something similar...
+ // ...we will never get here because of the returns.
+ if (a_Itr->a_ElapsedTicks >= a_Itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks?
+ {
+ if (a_Itr->ShouldPowerOn)
{
- if (itr->ShouldPowerOn)
+ if (!IsOn)
+ {
+ m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); // For performance
+ }
+
+ switch (a_Meta & 0x3) // We only want the direction (bottom) bits
{
- if (!IsOn)
+ case 0x0:
{
- m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); // For performance
+ SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZM);
+ break;
}
-
- switch (a_Meta & 0x3) // We only want the direction (bottom) bits
+ case 0x1:
{
- case 0x0:
- {
- SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
- SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZM);
- break;
- }
- case 0x1:
- {
- SetBlockPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
- SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XP);
- break;
- }
- case 0x2:
- {
- SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
- SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZP);
- break;
- }
- case 0x3:
- {
- SetBlockPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
- SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XM);
- break;
- }
+ SetBlockPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XP);
+ break;
}
-
- // Removal of the data entry will be handled in SimChunk - we still want to continue trying to power blocks, even if our delay time has reached
- // Otherwise, the power state of blocks in front won't update after we have powered on
- return;
- }
- else
- {
- if (IsOn)
+ case 0x2:
{
- m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta);
+ SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZP);
+ break;
+ }
+ case 0x3:
+ {
+ SetBlockPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
+ SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XM);
+ break;
}
- m_RepeatersDelayList->erase(itr); // We can remove off repeaters which don't need further updating
- return;
}
+
+ // Removal of the data entry will be handled in SimChunk - we still want to continue trying to power blocks, even if our delay time has reached
+ // Otherwise, the power state of blocks in front won't update after we have powered on
+ return;
}
else
{
- // Apparently, incrementing ticks only works reliably here, and not in SimChunk;
- // With a world with lots of redstone, the repeaters simply do not delay
- // I am confounded to say why. Perhaps optimisation failure.
- LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", itr->a_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks);
- itr->a_ElapsedTicks++;
+ if (IsOn)
+ {
+ m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta);
+ }
+ m_RepeatersDelayList->erase(a_Itr); // We can remove off repeaters which don't need further updating
+ return;
}
}
+ else
+ {
+ // Apparently, incrementing ticks only works reliably here, and not in SimChunk;
+ // With a world with lots of redstone, the repeaters simply do not delay
+ // I am confounded to say why. Perhaps optimisation failure.
+ LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", a_Itr->a_RelBlockPos.x, a_Itr->a_RelBlockPos.y, a_Itr->a_RelBlockPos.z, a_Itr->a_ElapsedTicks, a_Itr->a_DelayTicks);
+ a_Itr->a_ElapsedTicks++;
+ }
}
@@ -814,17 +898,16 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int
void cIncrementalRedstoneSimulator::HandlePiston(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{
- cPiston Piston(&m_World);
int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
if (IsPistonPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x7)) // We only want the bottom three bits (4th controls extended-ness)
{
- Piston.ExtendPiston(BlockX, a_RelBlockY, BlockZ);
+ cBlockPistonHandler::ExtendPiston(BlockX, a_RelBlockY, BlockZ, &m_World);
}
else
{
- Piston.RetractPiston(BlockX, a_RelBlockY, BlockZ);
+ cBlockPistonHandler::RetractPiston(BlockX, a_RelBlockY, BlockZ, &m_World);
}
}
@@ -906,8 +989,11 @@ void cIncrementalRedstoneSimulator::HandleDoor(int a_RelBlockX, int a_RelBlockY,
if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true))
{
cChunkInterface ChunkInterface(m_World.GetChunkMap());
- cBlockDoorHandler::ChangeDoor(ChunkInterface, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
- m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0);
+ if (!cBlockDoorHandler::IsOpen(ChunkInterface, BlockX, a_RelBlockY, BlockZ))
+ {
+ cBlockDoorHandler::SetOpen(ChunkInterface, BlockX, a_RelBlockY, BlockZ, true);
+ m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0);
+ }
SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true);
}
}
@@ -916,8 +1002,11 @@ void cIncrementalRedstoneSimulator::HandleDoor(int a_RelBlockX, int a_RelBlockY,
if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false))
{
cChunkInterface ChunkInterface(m_World.GetChunkMap());
- cBlockDoorHandler::ChangeDoor(ChunkInterface, a_RelBlockX, a_RelBlockY, a_RelBlockZ);
- m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0);
+ if (cBlockDoorHandler::IsOpen(ChunkInterface, BlockX, a_RelBlockY, BlockZ))
+ {
+ cBlockDoorHandler::SetOpen(ChunkInterface, BlockX, a_RelBlockY, BlockZ, false);
+ m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0);
+ }
SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false);
}
}
@@ -1074,6 +1163,10 @@ void cIncrementalRedstoneSimulator::HandleDaylightSensor(int a_RelBlockX, int a_
{
SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
}
+ else
+ {
+ WakeUp(BlockX, a_RelBlockY, BlockZ, m_Chunk);
+ }
}
}
@@ -1358,8 +1451,7 @@ bool cIncrementalRedstoneSimulator::AreCoordsLinkedPowered(int a_RelBlockX, int
-// IsRepeaterPowered tests if a repeater should be powered by testing for power sources behind the repeater.
-// It takes the coordinates of the repeater the the meta value.
+
bool cIncrementalRedstoneSimulator::IsRepeaterPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta)
{
// Repeaters cannot be powered by any face except their back; verify that this is true for a source
@@ -1439,19 +1531,19 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelB
case 0x0:
case 0x2:
{
- // Check if eastern(right) neighbor is a powered on repeater who is facing us.
+ // Check if eastern(right) neighbor is a powered on repeater who is facing us
BLOCKTYPE Block = 0;
if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON)) // Is right neighbor a powered repeater?
{
NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ) & 0x3;
- if (OtherRepeaterDir == 0x3) { return true; } // If so, I am latched/locked.
+ if (OtherRepeaterDir == 0x3) { return true; } // If so, I am latched/locked
}
- // Check if western(left) neighbor is a powered on repeater who is facing us.
+ // Check if western(left) neighbor is a powered on repeater who is facing us
if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON))
{
NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX -1, a_RelBlockY, a_RelBlockZ) & 0x3;
- if (OtherRepeaterDir == 0x1) { return true; } // If so, I am latched/locked.
+ if (OtherRepeaterDir == 0x1) { return true; } // If so, I am latched/locked
}
break;
@@ -1461,26 +1553,26 @@ bool cIncrementalRedstoneSimulator::IsRepeaterLocked(int a_RelBlockX, int a_RelB
case 0x1:
case 0x3:
{
- // Check if southern(down) neighbor is a powered on repeater who is facing us.
+ // Check if southern(down) neighbor is a powered on repeater who is facing us
BLOCKTYPE Block = 0;
if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON))
{
NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1) & 0x3;
- if (OtherRepeaterDir == 0x0) { return true; } // If so, am latched/locked.
+ if (OtherRepeaterDir == 0x0) { return true; } // If so, am latched/locked
}
- // Check if northern(up) neighbor is a powered on repeater who is facing us.
+ // Check if northern(up) neighbor is a powered on repeater who is facing us
if (m_Chunk->UnboundedRelGetBlockType(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, Block) && (Block == E_BLOCK_REDSTONE_REPEATER_ON))
{
NIBBLETYPE OtherRepeaterDir = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1) & 0x3;
- if (OtherRepeaterDir == 0x2) { return true; } // If so, I am latched/locked.
+ if (OtherRepeaterDir == 0x2) { return true; } // If so, I am latched/locked
}
break;
}
}
- return false; // None of the checks succeeded, I am not a locked repeater.
+ return false; // None of the checks succeeded, I am not a locked repeater
}
@@ -1490,41 +1582,36 @@ bool cIncrementalRedstoneSimulator::IsPistonPowered(int a_RelBlockX, int a_RelBl
{
// Pistons cannot be powered through their front face; this function verifies that a source meets this requirement
- int OldX = a_RelBlockX, OldY = a_RelBlockY, OldZ = a_RelBlockZ;
- eBlockFace Face = cPiston::MetaDataToDirection(a_Meta);
- int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
- int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
+ eBlockFace Face = cBlockPistonHandler::MetaDataToDirection(a_Meta);
+ int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX;
+ int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ;
for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks->begin(); itr != m_PoweredBlocks->end(); ++itr)
{
if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { continue; }
- AddFaceDirection(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Face);
+ AddFaceDirection(BlockX, a_RelBlockY, BlockZ, Face);
if (!itr->a_SourcePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)))
{
return true;
}
- a_RelBlockX = OldX;
- a_RelBlockY = OldY;
- a_RelBlockZ = OldZ;
+ AddFaceDirection(BlockX, a_RelBlockY, BlockZ, Face, true);
}
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr)
{
if (!itr->a_BlockPos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ))) { continue; }
- AddFaceDirection(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Face);
+ AddFaceDirection(BlockX, a_RelBlockY, BlockZ, Face);
if (!itr->a_MiddlePos.Equals(Vector3i(BlockX, a_RelBlockY, BlockZ)))
{
return true;
}
- a_RelBlockX = OldX;
- a_RelBlockY = OldY;
- a_RelBlockZ = OldZ;
+ AddFaceDirection(BlockX, a_RelBlockY, BlockZ, Face, true);
}
return false; // Source was in front of the piston's front face
}
@@ -1544,7 +1631,7 @@ bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBloc
{
continue;
}
- a_PowerLevel = std::max(a_PowerLevel, itr->a_PowerLevel);
+ a_PowerLevel = itr->a_PowerLevel;
}
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks->begin(); itr != m_LinkedPoweredBlocks->end(); ++itr) // Check linked powered list
@@ -1553,10 +1640,10 @@ bool cIncrementalRedstoneSimulator::IsWirePowered(int a_RelBlockX, int a_RelBloc
{
continue;
}
- a_PowerLevel = std::max(a_PowerLevel, itr->a_PowerLevel);
+ a_PowerLevel = itr->a_PowerLevel;
}
- return (a_PowerLevel != 0); // Source was in front of the piston's front face
+ return (a_PowerLevel != 0); // Answer the inital question: is the wire powered?
}
@@ -1736,7 +1823,8 @@ void cIncrementalRedstoneSimulator::SetBlockPowered(int a_RelBlockX, int a_RelBl
return;
}
- PoweredBlocksList * Powered = m_Chunk->GetNeighborChunk(BlockX, BlockZ)->GetRedstoneSimulatorPoweredBlocksList();
+ cChunk * Neighbour = m_Chunk->GetNeighborChunk(BlockX, BlockZ);
+ PoweredBlocksList * Powered = Neighbour->GetRedstoneSimulatorPoweredBlocksList();
for (PoweredBlocksList::iterator itr = Powered->begin(); itr != Powered->end(); ++itr) // Check powered list
{
if (
@@ -1768,6 +1856,8 @@ void cIncrementalRedstoneSimulator::SetBlockPowered(int a_RelBlockX, int a_RelBl
RC.a_SourcePos = Vector3i(SourceX, a_RelSourceY, SourceZ);
RC.a_PowerLevel = a_PowerLevel;
Powered->push_back(RC);
+ Neighbour->SetIsRedstoneDirty(true);
+ m_Chunk->SetIsRedstoneDirty(true);
}
@@ -1807,7 +1897,8 @@ void cIncrementalRedstoneSimulator::SetBlockLinkedPowered(
return;
}
- LinkedBlocksList * Linked = m_Chunk->GetNeighborChunk(BlockX, BlockZ)->GetRedstoneSimulatorLinkedBlocksList();
+ cChunk * Neighbour = m_Chunk->GetNeighborChunk(BlockX, BlockZ);
+ LinkedBlocksList * Linked = Neighbour->GetRedstoneSimulatorLinkedBlocksList();
for (LinkedBlocksList::iterator itr = Linked->begin(); itr != Linked->end(); ++itr) // Check linked powered list
{
if (
@@ -1828,6 +1919,8 @@ void cIncrementalRedstoneSimulator::SetBlockLinkedPowered(
RC.a_SourcePos = Vector3i(SourceX, a_RelSourceY, SourceZ);
RC.a_PowerLevel = a_PowerLevel;
Linked->push_back(RC);
+ Neighbour->SetIsRedstoneDirty(true);
+ m_Chunk->SetIsRedstoneDirty(true);
}
@@ -1867,7 +1960,7 @@ void cIncrementalRedstoneSimulator::SetPlayerToggleableBlockAsSimulated(int a_Re
-void cIncrementalRedstoneSimulator::QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn)
+bool cIncrementalRedstoneSimulator::QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn)
{
for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end(); ++itr)
{
@@ -1875,14 +1968,14 @@ void cIncrementalRedstoneSimulator::QueueRepeaterPowerChange(int a_RelBlockX, in
{
if (ShouldPowerOn == itr->ShouldPowerOn) // We are queued already for the same thing, don't replace entry
{
- return;
+ return false;
}
// Already in here (normal to allow repeater to continue on powering and updating blocks in front) - just update info and quit
itr->a_DelayTicks = (((a_Meta & 0xC) >> 0x2) + 1) * 2; // See below for description
itr->a_ElapsedTicks = 0;
itr->ShouldPowerOn = ShouldPowerOn;
- return;
+ return false;
}
}
@@ -1897,7 +1990,7 @@ void cIncrementalRedstoneSimulator::QueueRepeaterPowerChange(int a_RelBlockX, in
RC.a_ElapsedTicks = 0;
RC.ShouldPowerOn = ShouldPowerOn;
m_RepeatersDelayList->push_back(RC);
- return;
+ return true;
}
diff --git a/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h
index 233a3d408..1d6a49aca 100644
--- a/src/Simulator/IncrementalRedstoneSimulator.h
+++ b/src/Simulator/IncrementalRedstoneSimulator.h
@@ -108,7 +108,7 @@ private:
/** Handles redstone wire */
void HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles repeaters */
- void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
+ void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState, RepeatersDelayList::iterator a_Itr);
/* ====================== */
/* ====== DEVICES ====== */
@@ -145,8 +145,8 @@ private:
void SetDirectionLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, char a_Direction, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
/** Marks all blocks immediately surrounding a coordinate as powered */
void SetAllDirsAsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
- /** Queues a repeater to be powered or unpowered */
- void QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn);
+ /** Queues a repeater to be powered or unpowered and returns if the m_RepeatersDelayList iterators were invalidated */
+ bool QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn);
/** Returns if a coordinate is powered or linked powered */
bool AreCoordsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { return AreCoordsDirectlyPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ) || AreCoordsLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); }
@@ -156,7 +156,7 @@ private:
bool AreCoordsLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */
bool AreCoordsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool IsCurrentStatePowered);
- /** Returns if a repeater is powered */
+ /** Returns if a repeater is powered by testing for power sources behind the repeater */
bool IsRepeaterPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta);
/** Returns if a repeater is locked */
bool IsRepeaterLocked(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta);
diff --git a/src/Simulator/SandSimulator.cpp b/src/Simulator/SandSimulator.cpp
index b8f34559f..1380f8841 100644
--- a/src/Simulator/SandSimulator.cpp
+++ b/src/Simulator/SandSimulator.cpp
@@ -60,7 +60,7 @@ void cSandSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChun
);
*/
cFallingBlock * FallingBlock = new cFallingBlock(Pos, BlockType, a_Chunk->GetMeta(itr->x, itr->y, itr->z));
- FallingBlock->Initialize(&m_World);
+ FallingBlock->Initialize(m_World);
a_Chunk->SetBlock(itr->x, itr->y, itr->z, E_BLOCK_AIR, 0);
}
}
diff --git a/src/StringUtils.h b/src/StringUtils.h
index caad85aef..87b574a34 100644
--- a/src/StringUtils.h
+++ b/src/StringUtils.h
@@ -11,6 +11,9 @@
+#include <string>
+
+
typedef std::string AString;
diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp
index 507b45833..728692f2a 100644
--- a/src/UI/SlotArea.cpp
+++ b/src/UI/SlotArea.cpp
@@ -625,7 +625,8 @@ void cSlotAreaCrafting::HandleCraftItem(const cItem & a_Result, cPlayer & a_Play
cSlotAreaAnvil::cSlotAreaAnvil(cAnvilWindow & a_ParentWindow) :
cSlotAreaTemporary(3, a_ParentWindow),
- m_MaximumCost(0)
+ m_MaximumCost(0),
+ m_StackSizeToBeUsedInRepair(0)
{
}
@@ -796,6 +797,7 @@ void cSlotAreaAnvil::OnTakeResult(cPlayer & a_Player)
{
cItem NewSecondItem(*Item);
NewSecondItem.m_ItemCount -= m_StackSizeToBeUsedInRepair;
+ m_StackSizeToBeUsedInRepair = 0;
SetSlot(1, a_Player, NewSecondItem);
}
else
@@ -1381,14 +1383,141 @@ cSlotAreaFurnace::~cSlotAreaFurnace()
void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem)
{
- super::Clicked(a_Player, a_SlotNum, a_ClickAction, a_ClickedItem);
-
if (m_Furnace == NULL)
{
LOGERROR("cSlotAreaFurnace::Clicked(): m_Furnace == NULL");
ASSERT(!"cSlotAreaFurnace::Clicked(): m_Furnace == NULL");
return;
}
+
+ if (a_SlotNum == 2)
+ {
+ bool bAsync = false;
+ if (GetSlot(a_SlotNum, a_Player) == NULL)
+ {
+ LOGWARNING("GetSlot(%d) returned NULL! Ignoring click", a_SlotNum);
+ return;
+ }
+
+ cItem Slot(*GetSlot(a_SlotNum, a_Player));
+ if (!Slot.IsSameType(a_ClickedItem))
+ {
+ LOGWARNING("*** Window lost sync at item %d in SlotArea with %d items ***", a_SlotNum, m_NumSlots);
+ LOGWARNING("My item: %s", ItemToFullString(Slot).c_str());
+ LOGWARNING("Their item: %s", ItemToFullString(a_ClickedItem).c_str());
+ bAsync = true;
+ }
+
+ if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick))
+ {
+ HandleSmeltItem(Slot, a_Player);
+ ShiftClicked(a_Player, a_SlotNum, Slot);
+ return;
+ }
+
+ cItem & DraggingItem = a_Player.GetDraggingItem();
+ if (!DraggingItem.IsEmpty())
+ {
+ if (a_ClickAction == caDblClick)
+ {
+ return;
+ }
+ if (!DraggingItem.IsEqual(Slot))
+ {
+ return;
+ }
+ if ((DraggingItem.m_ItemCount + Slot.m_ItemCount) > Slot.GetMaxStackSize())
+ {
+ return;
+ }
+
+ DraggingItem.m_ItemCount += Slot.m_ItemCount;
+ HandleSmeltItem(Slot, a_Player);
+ Slot.Empty();
+ }
+ else
+ {
+ switch (a_ClickAction)
+ {
+ case caDblClick:
+ {
+ DblClicked(a_Player, a_SlotNum);
+ return;
+ }
+ case caLeftClick:
+ {
+ DraggingItem = Slot;
+ HandleSmeltItem(Slot, a_Player);
+ Slot.Empty();
+ break;
+ }
+ case caRightClick:
+ {
+ DraggingItem = Slot.CopyOne();
+ DraggingItem.m_ItemCount = (char)(((float)Slot.m_ItemCount) / 2.f + 0.5f);
+ Slot.m_ItemCount -= DraggingItem.m_ItemCount;
+
+ if (Slot.m_ItemCount <= 0)
+ {
+ Slot.Empty();
+ }
+ HandleSmeltItem(DraggingItem, a_Player);
+ break;
+ }
+ default:
+ {
+ ASSERT(!"Unhandled click type!");
+ }
+ }
+ }
+
+ SetSlot(a_SlotNum, a_Player, Slot);
+ if (bAsync)
+ {
+ m_ParentWindow.BroadcastWholeWindow();
+ }
+ return;
+ }
+
+ super::Clicked(a_Player, a_SlotNum, a_ClickAction, a_ClickedItem);
+}
+
+
+
+
+
+void cSlotAreaFurnace::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots)
+{
+ for (int i = 0; i < 2; i++)
+ {
+ const cItem * Slot = GetSlot(i, a_Player);
+ if (!Slot->IsEqual(a_ItemStack) && (!Slot->IsEmpty() || a_KeepEmptySlots))
+ {
+ // Different items
+ continue;
+ }
+ int NumFit = ItemHandler(Slot->m_ItemType)->GetMaxStackSize() - Slot->m_ItemCount;
+ if (NumFit <= 0)
+ {
+ // Full stack already
+ continue;
+ }
+ if (NumFit > a_ItemStack.m_ItemCount)
+ {
+ NumFit = a_ItemStack.m_ItemCount;
+ }
+ if (a_ShouldApply)
+ {
+ cItem NewSlot(a_ItemStack);
+ NewSlot.m_ItemCount = Slot->m_ItemCount + NumFit;
+ SetSlot(i, a_Player, NewSlot);
+ }
+ a_ItemStack.m_ItemCount -= NumFit;
+ if (a_ItemStack.IsEmpty())
+ {
+ return;
+ }
+ } // for i - Slots
}
@@ -1397,6 +1526,7 @@ void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a
const cItem * cSlotAreaFurnace::GetSlot(int a_SlotNum, cPlayer & a_Player) const
{
+ UNUSED(a_Player);
// a_SlotNum ranges from 0 to 2, query the items from the underlying furnace:
return &(m_Furnace->GetSlot(a_SlotNum));
}
@@ -1407,6 +1537,7 @@ const cItem * cSlotAreaFurnace::GetSlot(int a_SlotNum, cPlayer & a_Player) const
void cSlotAreaFurnace::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item)
{
+ UNUSED(a_Player);
m_Furnace->SetSlot(a_SlotNum, a_Item);
}
@@ -1416,6 +1547,7 @@ void cSlotAreaFurnace::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem &
void cSlotAreaFurnace::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
{
+ UNUSED(a_SlotNum);
// Something has changed in the window, broadcast the entire window to all clients
ASSERT(a_ItemGrid == &(m_Furnace->GetContents()));
diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h
index e297bcff7..b4b693cf6 100644
--- a/src/UI/SlotArea.h
+++ b/src/UI/SlotArea.h
@@ -392,6 +392,7 @@ public:
virtual ~cSlotAreaFurnace();
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
+ virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) override;
virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override;
virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;
diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp
index 46885390b..98a9a0cec 100644
--- a/src/UI/Window.cpp
+++ b/src/UI/Window.cpp
@@ -854,6 +854,7 @@ void cAnvilWindow::GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ)
cEnchantingWindow::cEnchantingWindow(int a_BlockX, int a_BlockY, int a_BlockZ) :
cWindow(wtEnchantment, "Enchant"),
+ m_SlotArea(),
m_BlockX(a_BlockX),
m_BlockY(a_BlockY),
m_BlockZ(a_BlockZ)
diff --git a/src/Vector3.h b/src/Vector3.h
index fed776018..5faac1457 100644
--- a/src/Vector3.h
+++ b/src/Vector3.h
@@ -5,6 +5,8 @@
#define _USE_MATH_DEFINES // Enable non-standard math defines (MSVC)
#include <math.h>
+#include <list>
+#include <vector>
diff --git a/src/World.cpp b/src/World.cpp
index 807065bfa..6bcd1391a 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -743,6 +743,20 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec)
m_LastTimeUpdate = m_WorldAge;
}
+ // Add entities waiting in the queue to be added:
+ {
+ cCSLock Lock(m_CSEntitiesToAdd);
+ for (cEntityList::iterator itr = m_EntitiesToAdd.begin(), end = m_EntitiesToAdd.end(); itr != end; ++itr)
+ {
+ (*itr)->SetWorld(this);
+ m_ChunkMap->AddEntity(*itr);
+ }
+ m_EntitiesToAdd.clear();
+ }
+
+ // Add players waiting in the queue to be added:
+ AddQueuedPlayers();
+
m_ChunkMap->Tick(a_Dt);
TickClients(a_Dt);
@@ -1551,9 +1565,9 @@ bool cWorld::SetAreaBiome(const cCuboid & a_Area, EMCSBiome a_Biome)
-void cWorld::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
+void cWorld::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients)
{
- m_ChunkMap->SetBlock(*this, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
+ m_ChunkMap->SetBlock(*this, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_SendToClients);
}
@@ -1631,7 +1645,7 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double
a_BlockX, a_BlockY, a_BlockZ,
*itr, IsPlayerCreated, SpeedX, SpeedY, SpeedZ
);
- Pickup->Initialize(this);
+ Pickup->Initialize(*this);
}
}
@@ -1652,7 +1666,7 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double
a_BlockX, a_BlockY, a_BlockZ,
*itr, IsPlayerCreated, (float)a_SpeedX, (float)a_SpeedY, (float)a_SpeedZ
);
- Pickup->Initialize(this);
+ Pickup->Initialize(*this);
}
}
@@ -1663,7 +1677,7 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double
int cWorld::SpawnFallingBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE BlockType, NIBBLETYPE BlockMeta)
{
cFallingBlock * FallingBlock = new cFallingBlock(Vector3i(a_X, a_Y, a_Z), BlockType, BlockMeta);
- FallingBlock->Initialize(this);
+ FallingBlock->Initialize(*this);
return FallingBlock->GetUniqueID();
}
@@ -1679,7 +1693,7 @@ int cWorld::SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward)
}
cExpOrb * ExpOrb = new cExpOrb(a_X, a_Y, a_Z, a_Reward);
- ExpOrb->Initialize(this);
+ ExpOrb->Initialize(*this);
return ExpOrb->GetUniqueID();
}
@@ -1702,7 +1716,7 @@ int cWorld::SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType
return -1;
}
} // switch (a_MinecartType)
- Minecart->Initialize(this);
+ Minecart->Initialize(*this);
return Minecart->GetUniqueID();
}
@@ -1713,7 +1727,7 @@ int cWorld::SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType
void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTicks, double a_InitialVelocityCoeff)
{
cTNTEntity * TNT = new cTNTEntity(a_X, a_Y, a_Z, a_FuseTicks);
- TNT->Initialize(this);
+ TNT->Initialize(*this);
TNT->SetSpeed(
a_InitialVelocityCoeff * (GetTickRandomNumber(2) - 1), /** -1, 0, 1 */
a_InitialVelocityCoeff * 2,
@@ -2229,7 +2243,7 @@ void cWorld::SetChunkData(
// Initialize the entities (outside the m_ChunkMap's CS, to fix FS #347):
for (cEntityList::iterator itr = a_Entities.begin(), end = a_Entities.end(); itr != end; ++itr)
{
- (*itr)->Initialize(this);
+ (*itr)->Initialize(*this);
}
// If a client is requesting this chunk, send it to them:
@@ -2322,23 +2336,8 @@ void cWorld::CollectPickupsByPlayer(cPlayer * a_Player)
void cWorld::AddPlayer(cPlayer * a_Player)
{
- {
- cCSLock Lock(m_CSPlayers);
-
- ASSERT(std::find(m_Players.begin(), m_Players.end(), a_Player) == m_Players.end()); // Is it already in the list? HOW?
-
- m_Players.remove(a_Player); // Make sure the player is registered only once
- m_Players.push_back(a_Player);
- }
-
- // Add the player's client to the list of clients to be ticked:
- if (a_Player->GetClientHandle() != NULL)
- {
- cCSLock Lock(m_CSClients);
- m_ClientsToAdd.push_back(a_Player->GetClientHandle());
- }
-
- // The player has already been added to the chunkmap as the entity, do NOT add again!
+ cCSLock Lock(m_CSPlayersToAdd);
+ m_PlayersToAdd.push_back(a_Player);
}
@@ -2347,17 +2346,26 @@ void cWorld::AddPlayer(cPlayer * a_Player)
void cWorld::RemovePlayer(cPlayer * a_Player)
{
+
m_ChunkMap->RemoveEntity(a_Player);
{
+ cCSLock Lock(m_CSPlayersToAdd);
+ m_PlayersToAdd.remove(a_Player);
+ }
+ {
cCSLock Lock(m_CSPlayers);
+ LOGD("Removing player \"%s\" from world \"%s\".", a_Player->GetName().c_str(), m_WorldName.c_str());
m_Players.remove(a_Player);
}
// Remove the player's client from the list of clients to be ticked:
- if (a_Player->GetClientHandle() != NULL)
+ cClientHandle * Client = a_Player->GetClientHandle();
+ if (Client != NULL)
{
+ Client->RemoveFromWorld();
+ m_ChunkMap->RemoveClientFromChunks(Client);
cCSLock Lock(m_CSClients);
- m_ClientsToRemove.push_back(a_Player->GetClientHandle());
+ m_ClientsToRemove.push_back(Client);
}
}
@@ -2808,9 +2816,11 @@ void cWorld::ScheduleTask(int a_DelayTicks, cTask * a_Task)
+
void cWorld::AddEntity(cEntity * a_Entity)
{
- m_ChunkMap->AddEntity(a_Entity);
+ cCSLock Lock(m_CSEntitiesToAdd);
+ m_EntitiesToAdd.push_back(a_Entity);
}
@@ -2819,6 +2829,19 @@ void cWorld::AddEntity(cEntity * a_Entity)
bool cWorld::HasEntity(int a_UniqueID)
{
+ // Check if the entity is in the queue to be added to the world:
+ {
+ cCSLock Lock(m_CSEntitiesToAdd);
+ for (cEntityList::const_iterator itr = m_EntitiesToAdd.begin(), end = m_EntitiesToAdd.end(); itr != end; ++itr)
+ {
+ if ((*itr)->GetUniqueID() == a_UniqueID)
+ {
+ return true;
+ }
+ } // for itr - m_EntitiesToAdd[]
+ }
+
+ // Check if the entity is in the chunkmap:
return m_ChunkMap->HasEntity(a_UniqueID);
}
@@ -2951,7 +2974,7 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster)
delete a_Monster;
return -1;
}
- if (!a_Monster->Initialize(this))
+ if (!a_Monster->Initialize(*this))
{
delete a_Monster;
return -1;
@@ -2973,7 +2996,7 @@ int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProje
{
return -1;
}
- if (!Projectile->Initialize(this))
+ if (!Projectile->Initialize(*this))
{
delete Projectile;
return -1;
@@ -3103,6 +3126,60 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c
+void cWorld::AddQueuedPlayers(void)
+{
+ ASSERT(m_TickThread.IsCurrentThread());
+
+ // Grab the list of players to add, it has to be locked to access it:
+ cPlayerList PlayersToAdd;
+ {
+ cCSLock Lock(m_CSPlayersToAdd);
+ std::swap(PlayersToAdd, m_PlayersToAdd);
+ }
+
+ // Add all the players in the grabbed list:
+ {
+ cCSLock Lock(m_CSPlayers);
+ for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr)
+ {
+ ASSERT(std::find(m_Players.begin(), m_Players.end(), *itr) == m_Players.end()); // Is it already in the list? HOW?
+
+ m_Players.push_back(*itr);
+ (*itr)->SetWorld(this);
+
+ // Add to chunkmap, if not already there (Spawn vs MoveToWorld):
+ m_ChunkMap->AddEntityIfNotPresent(*itr);
+ } // for itr - PlayersToAdd[]
+ } // Lock(m_CSPlayers)
+
+ // Add all the players' clienthandles:
+ {
+ cCSLock Lock(m_CSClients);
+ for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr)
+ {
+ cClientHandle * Client = (*itr)->GetClientHandle();
+ if (Client != NULL)
+ {
+ m_Clients.push_back(Client);
+ }
+ } // for itr - PlayersToAdd[]
+ } // Lock(m_CSClients)
+
+ // Stream chunks to all eligible clients:
+ for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr)
+ {
+ cClientHandle * Client = (*itr)->GetClientHandle();
+ if (Client != NULL)
+ {
+ Client->StreamChunks();
+ }
+ } // for itr - PlayersToAdd[]
+}
+
+
+
+
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cWorld::cTaskSaveAllChunks:
@@ -3128,6 +3205,49 @@ void cWorld::cTaskUnloadUnusedChunks::Run(cWorld & a_World)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cWorld::cTaskSendBlockTo
+
+cWorld::cTaskSendBlockToAllPlayers::cTaskSendBlockToAllPlayers(std::vector<Vector3i> & a_SendQueue) :
+ m_SendQueue(a_SendQueue)
+{
+}
+
+void cWorld::cTaskSendBlockToAllPlayers::Run(cWorld & a_World)
+{
+ class cPlayerCallback :
+ public cPlayerListCallback
+ {
+ public:
+ cPlayerCallback(std::vector<Vector3i> & a_SendQueue, cWorld & a_World) :
+ m_SendQueue(a_SendQueue),
+ m_World(a_World)
+ {
+ }
+
+ virtual bool Item(cPlayer * a_Player)
+ {
+ for (std::vector<Vector3i>::const_iterator itr = m_SendQueue.begin(); itr != m_SendQueue.end(); ++itr)
+ {
+ m_World.SendBlockTo(itr->x, itr->y, itr->z, a_Player);
+ }
+ return false;
+ }
+
+ private:
+
+ std::vector<Vector3i> m_SendQueue;
+ cWorld & m_World;
+
+ } PlayerCallback(m_SendQueue, a_World);
+
+ a_World.ForEachPlayer(PlayerCallback);
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cWorld::cChunkGeneratorCallbacks:
cWorld::cChunkGeneratorCallbacks::cChunkGeneratorCallbacks(cWorld & a_World) :
@@ -3200,4 +3320,3 @@ void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerated (cChunkDesc & a_Ch
-
diff --git a/src/World.h b/src/World.h
index cd465bece..f638b4b22 100644
--- a/src/World.h
+++ b/src/World.h
@@ -47,7 +47,6 @@ class cFlowerPotEntity;
class cFurnaceEntity;
class cNoteEntity;
class cMobHeadEntity;
-class cMobCensus;
class cCompositeChat;
class cCuboid;
@@ -117,6 +116,20 @@ public:
};
+ class cTaskSendBlockToAllPlayers :
+ public cTask
+ {
+ public:
+ cTaskSendBlockToAllPlayers(std::vector<Vector3i> & a_SendQueue);
+
+ protected:
+ // cTask overrides:
+ virtual void Run(cWorld & a_World) override;
+
+ std::vector<Vector3i> m_SendQueue;
+ };
+
+
static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates
{
return "cWorld";
@@ -270,8 +283,15 @@ public:
void CollectPickupsByPlayer(cPlayer * a_Player);
- void AddPlayer( cPlayer* a_Player );
- void RemovePlayer( cPlayer* a_Player );
+ /** Adds the player to the world.
+ Uses a queue to store the player object until the Tick thread processes the addition event.
+ Also adds the player as an entity in the chunkmap, and the player's ClientHandle, if any, for ticking. */
+ void AddPlayer(cPlayer * a_Player);
+
+ /** Removes the player from the world.
+ Removes the player from the addition queue, too, if appropriate.
+ If the player has a ClientHandle, the ClientHandle is removed from all chunks in the world and will not be ticked by this world anymore. */
+ void RemovePlayer(cPlayer * a_Player);
/** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */
virtual bool ForEachPlayer(cPlayerListCallback & a_Callback) override; // >> EXPORTED IN MANUALBINDINGS <<
@@ -287,7 +307,8 @@ public:
void SendPlayerList(cPlayer * a_DestPlayer); // Sends playerlist to the player
- /** Adds the entity into its appropriate chunk; takes ownership of the entity ptr */
+ /** Adds the entity into its appropriate chunk; takes ownership of the entity ptr.
+ The entity is added lazily - this function only puts it in a queue that is then processed by the Tick thread. */
void AddEntity(cEntity * a_Entity);
bool HasEntity(int a_UniqueID);
@@ -373,7 +394,7 @@ public:
/** Sets the block at the specified coords to the specified value.
Full processing, incl. updating neighbors, is performed.
*/
- void SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
+ void SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients = true);
/** Sets the block at the specified coords to the specified value.
The replacement doesn't trigger block updates.
@@ -685,13 +706,41 @@ public:
/** Returns the current weather. Instead of comparing values directly to the weather constants, use IsWeatherXXX() functions, if possible */
eWeather GetWeather (void) const { return m_Weather; };
+ /** Returns true if the current weather is sun */
bool IsWeatherSunny(void) const { return (m_Weather == wSunny); }
- bool IsWeatherRain (void) const { return (m_Weather == wRain); }
+
+ /** Returns true if it is sunny at the specified location. This takes into account biomes. */
+ bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ)
+ {
+ return (IsWeatherSunny() || IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ)));
+ }
+
+ /** Returns true if the current weather is rain */
+ bool IsWeatherRain(void) const { return (m_Weather == wRain); }
+
+ /** Returns true if it is raining at the specified location. This takes into account biomes. */
+ bool IsWeatherRainAt (int a_BlockX, int a_BlockZ)
+ {
+ return (IsWeatherRain() && !IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ)));
+ }
+
+ /** Returns true if the current weather is stormy */
bool IsWeatherStorm(void) const { return (m_Weather == wStorm); }
- /** Returns true if the current weather has any precipitation - rain or storm */
- bool IsWeatherWet (void) const { return (m_Weather != wSunny); }
+ /** Returns true if the weather is stormy at the specified location. This takes into account biomes. */
+ bool IsWeatherStormAt(int a_BlockX, int a_BlockZ)
+ {
+ return (IsWeatherStorm() && !IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ)));
+ }
+
+ /** Returns true if the current weather has any precipitation - rain, storm or snow */
+ bool IsWeatherWet(void) const { return !IsWeatherSunny(); }
+ /** Returns true if it is raining, stormy or snowing at the specified location. This takes into account biomes. */
+ bool IsWeatherWetAt(int a_BlockX, int a_BlockZ)
+ {
+ return (IsWeatherWet() && !IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ)));
+ }
// tolua_end
cChunkGenerator & GetGenerator(void) { return m_Generator; }
@@ -912,6 +961,18 @@ private:
/** Clients that are scheduled for adding, waiting for TickClients to add them */
cClientHandleList m_ClientsToAdd;
+ /** Guards m_EntitiesToAdd */
+ cCriticalSection m_CSEntitiesToAdd;
+
+ /** List of entities that are scheduled for adding, waiting for the Tick thread to add them. */
+ cEntityList m_EntitiesToAdd;
+
+ /** Guards m_PlayersToAdd */
+ cCriticalSection m_CSPlayersToAdd;
+
+ /** List of players that are scheduled for adding, waiting for the Tick thread to add them. */
+ cPlayerList m_PlayersToAdd;
+
cWorld(const AString & a_WorldName);
virtual ~cWorld();
@@ -949,6 +1010,10 @@ private:
/** Creates a new redstone simulator.*/
cRedstoneSimulator * InitializeRedstoneSimulator(cIniFile & a_IniFile);
+
+ /** Adds the players queued in the m_PlayersToAdd queue into the m_Players list.
+ Assumes it is called from the Tick thread. */
+ void AddQueuedPlayers(void);
}; // tolua_export
diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp
index 6e1bf41aa..8294d4a00 100644
--- a/src/WorldStorage/NBTChunkSerializer.cpp
+++ b/src/WorldStorage/NBTChunkSerializer.cpp
@@ -722,10 +722,9 @@ void cNBTChunkSerializer::AddMinecartChestContents(cMinecartWithChest * a_Mineca
-bool cNBTChunkSerializer::LightIsValid(bool a_IsLightValid)
+void cNBTChunkSerializer::LightIsValid(bool a_IsLightValid)
{
m_IsLightValid = a_IsLightValid;
- return a_IsLightValid; // We want lighting only if it's valid, otherwise don't bother
}
diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h
index 51d104970..112afc27e 100644
--- a/src/WorldStorage/NBTChunkSerializer.h
+++ b/src/WorldStorage/NBTChunkSerializer.h
@@ -9,7 +9,7 @@
#pragma once
-#include "../ChunkDef.h"
+#include "ChunkDataCallback.h"
@@ -121,7 +121,7 @@ protected:
void AddMinecartChestContents(cMinecartWithChest * a_Minecart);
// cChunkDataSeparateCollector overrides:
- virtual bool LightIsValid(bool a_IsLightValid) override;
+ virtual void LightIsValid(bool a_IsLightValid) override;
virtual void BiomeData(const cChunkDef::BiomeMap * a_BiomeMap) override;
virtual void Entity(cEntity * a_Entity) override;
virtual void BlockEntity(cBlockEntity * a_Entity) override;
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index d310c9124..1891762fd 100644
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -2445,7 +2445,7 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N
bool cWSSAnvil::LoadMonsterBaseFromNBT(cMonster & a_Monster, const cParsedNBT & a_NBT, int a_TagIdx)
{
float DropChance[5];
- if (!LoadFloatsListFromNBT(DropChance, 5, a_NBT, a_NBT.FindChildByName(a_TagIdx, "DropChance")))
+ if (!LoadFloatsListFromNBT(DropChance, 5, a_NBT, a_NBT.FindChildByName(a_TagIdx, "DropChances")))
{
return false;
}
diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp
index 6d06b8fe3..7a113849a 100644
--- a/src/WorldStorage/WSSCompact.cpp
+++ b/src/WorldStorage/WSSCompact.cpp
@@ -107,15 +107,13 @@ void cJsonChunkSerializer::BlockEntity(cBlockEntity * a_BlockEntity)
-bool cJsonChunkSerializer::LightIsValid(bool a_IsLightValid)
+void cJsonChunkSerializer::LightIsValid(bool a_IsLightValid)
{
- if (!a_IsLightValid)
+ if (a_IsLightValid)
{
- return false;
+ m_Root["IsLightValid"] = true;
+ m_HasJsonData = true;
}
- m_Root["IsLightValid"] = true;
- m_HasJsonData = true;
- return true;
}
diff --git a/src/WorldStorage/WSSCompact.h b/src/WorldStorage/WSSCompact.h
index 97e3b82f9..b148005f6 100644
--- a/src/WorldStorage/WSSCompact.h
+++ b/src/WorldStorage/WSSCompact.h
@@ -14,6 +14,7 @@
#include "WorldStorage.h"
#include "../Vector3.h"
#include "json/json.h"
+#include "ChunkDataCallback.h"
@@ -21,7 +22,7 @@
/// Helper class for serializing a chunk into Json
class cJsonChunkSerializer :
- public cChunkDataCollector
+ public cChunkDataArrayCollector
{
public:
@@ -42,7 +43,7 @@ protected:
// cChunkDataCollector overrides:
virtual void Entity (cEntity * a_Entity) override;
virtual void BlockEntity (cBlockEntity * a_Entity) override;
- virtual bool LightIsValid (bool a_IsLightValid) override;
+ virtual void LightIsValid (bool a_IsLightValid) override;
} ;
diff --git a/src/main.cpp b/src/main.cpp
index 68eea7f4d..6925d9ff1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -61,7 +61,7 @@ void NonCtrlHandler(int a_Signal)
std::signal(SIGSEGV, SIG_DFL);
LOGERROR(" D: | MCServer has encountered an error and needs to close");
LOGERROR("Details | SIGSEGV: Segmentation fault");
- exit(EXIT_FAILURE);
+ abort();
}
case SIGABRT:
#ifdef SIGABRT_COMPAT
@@ -71,7 +71,7 @@ void NonCtrlHandler(int a_Signal)
std::signal(a_Signal, SIG_DFL);
LOGERROR(" D: | MCServer has encountered an error and needs to close");
LOGERROR("Details | SIGABRT: Server self-terminated due to an internal fault");
- exit(EXIT_FAILURE);
+ abort();
}
case SIGINT:
case SIGTERM:
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 000000000..1fbd88f04
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required (VERSION 2.6)
+
+enable_testing()
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+add_subdirectory(ChunkData)
diff --git a/tests/ChunkData/ArraytoCoord.cpp b/tests/ChunkData/ArraytoCoord.cpp
new file mode 100644
index 000000000..9d0ca6c8c
--- /dev/null
+++ b/tests/ChunkData/ArraytoCoord.cpp
@@ -0,0 +1,103 @@
+
+#include "Globals.h"
+#include "ChunkData.h"
+
+
+
+int main(int argc, char** argv)
+{
+ class cMockAllocationPool
+ : public cAllocationPool<cChunkData::sChunkSection>
+ {
+ virtual cChunkData::sChunkSection * Allocate()
+ {
+ return new cChunkData::sChunkSection();
+ }
+
+ virtual void Free(cChunkData::sChunkSection * a_Ptr)
+ {
+ delete a_Ptr;
+ }
+ } Pool;
+ {
+
+ // Test first segment
+ cChunkData buffer(Pool);
+
+ BLOCKTYPE SrcBlockBuffer[16 * 16 * 256];
+ memset(SrcBlockBuffer, 0x00, sizeof(SrcBlockBuffer));
+ SrcBlockBuffer[7 + (4 * 16) + (5 * 16 * 16)] = 0xcd;
+ buffer.SetBlockTypes(SrcBlockBuffer);
+ testassert(buffer.GetBlock(7, 5, 4) == 0xcd);
+
+ NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2];
+ memset(SrcNibbleBuffer, 0x00, sizeof(SrcNibbleBuffer));
+ SrcNibbleBuffer[(6 + (1 * 16) + (2 * 16 * 16)) / 2] = 0xe;
+ buffer.SetMetas(SrcNibbleBuffer);
+ testassert(buffer.GetMeta(6, 2, 1) == 0xe);
+
+ memset(SrcNibbleBuffer, 0x00, sizeof(SrcNibbleBuffer));
+ SrcNibbleBuffer[(6 + (1 * 16) + (2 * 16 * 16)) / 2] = 0xe;
+ buffer.SetBlockLight(SrcNibbleBuffer);
+ testassert(buffer.GetBlockLight(6, 2, 1) == 0xe);
+
+ memset(SrcNibbleBuffer, 0x00, sizeof(SrcNibbleBuffer));
+ SrcNibbleBuffer[(6 + (1 * 16) + (2 * 16 * 16)) / 2] = 0xe;
+ buffer.SetSkyLight(SrcNibbleBuffer);
+ testassert(buffer.GetSkyLight(6, 2, 1) == 0xe);
+ }
+
+ {
+ // test following segment
+ cChunkData buffer(Pool);
+
+ BLOCKTYPE SrcBlockBuffer[16 * 16 * 256];
+ memset(SrcBlockBuffer, 0x00, sizeof(SrcBlockBuffer));
+ SrcBlockBuffer[7 + (4 * 16) + (24 * 16 * 16)] = 0xcd;
+ buffer.SetBlockTypes(SrcBlockBuffer);
+ testassert(buffer.GetBlock(7, 24, 4) == 0xcd);
+
+ NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2];
+ memset(SrcNibbleBuffer, 0x00, sizeof(SrcNibbleBuffer));
+ SrcNibbleBuffer[(6 + (1 * 16) + (24 * 16 * 16)) / 2] = 0xe;
+ buffer.SetMetas(SrcNibbleBuffer);
+ testassert(buffer.GetMeta(6, 24, 1) == 0xe);
+
+ memset(SrcNibbleBuffer, 0x00, sizeof(SrcNibbleBuffer));
+ SrcNibbleBuffer[(6 + 1 * 16 + 24 * 16 * 16) / 2] = 0xe;
+ buffer.SetBlockLight(SrcNibbleBuffer);
+ testassert(buffer.GetBlockLight(6, 24, 1) == 0xe);
+
+ memset(SrcNibbleBuffer, 0xff, sizeof(SrcNibbleBuffer));
+ SrcNibbleBuffer[(6 + (1 * 16) + (24 * 16 * 16)) / 2] = 0xe;
+ buffer.SetSkyLight(SrcNibbleBuffer);
+ testassert(buffer.GetSkyLight(6, 24, 1) == 0xe);
+ }
+
+ {
+ // test zeros
+ cChunkData buffer(Pool);
+
+ BLOCKTYPE SrcBlockBuffer[16 * 16 * 256];
+ memset(SrcBlockBuffer, 0x00, sizeof(SrcBlockBuffer));
+ buffer.SetBlockTypes(SrcBlockBuffer);
+ testassert(buffer.GetBlock(7, 24, 4) == 0x00);
+
+ NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2];
+ memset(SrcNibbleBuffer, 0x00, sizeof(SrcNibbleBuffer));
+ buffer.SetMetas(SrcNibbleBuffer);
+ testassert(buffer.GetMeta(6, 24, 1) == 0x0);
+
+ memset(SrcNibbleBuffer, 0x00, sizeof(SrcNibbleBuffer));
+ buffer.SetBlockLight(SrcNibbleBuffer);
+ testassert(buffer.GetBlockLight(6, 24, 1) == 0x0);
+
+ memset(SrcNibbleBuffer, 0xff, sizeof(SrcNibbleBuffer));
+ buffer.SetSkyLight(SrcNibbleBuffer);
+ testassert(buffer.GetSkyLight(6, 24, 1) == 0xf);
+ }
+
+ // All tests passed:
+ return 0;
+}
+
diff --git a/tests/ChunkData/CMakeLists.txt b/tests/ChunkData/CMakeLists.txt
new file mode 100644
index 000000000..381e11cc2
--- /dev/null
+++ b/tests/ChunkData/CMakeLists.txt
@@ -0,0 +1,29 @@
+cmake_minimum_required (VERSION 2.6)
+
+enable_testing()
+
+include_directories(${CMAKE_SOURCE_DIR}/src/)
+
+add_definitions(-DTEST_GLOBALS=1)
+add_library(ChunkBuffer ${CMAKE_SOURCE_DIR}/src/ChunkData.cpp ${CMAKE_SOURCE_DIR}/src/StringUtils.cpp)
+
+
+add_executable(creatable-exe creatable.cpp)
+target_link_libraries(creatable-exe ChunkBuffer)
+add_test(NAME creatable-test COMMAND creatable-exe)
+
+add_executable(coordinates-exe Coordinates.cpp)
+target_link_libraries(coordinates-exe ChunkBuffer)
+add_test(NAME coordinates-test COMMAND coordinates-exe)
+
+add_executable(copies-exe Copies.cpp)
+target_link_libraries(copies-exe ChunkBuffer)
+add_test(NAME copies-test COMMAND copies-exe)
+
+add_executable(arraystocoords-exe ArraytoCoord.cpp)
+target_link_libraries(arraystocoords-exe ChunkBuffer)
+add_test(NAME arraystocoords-test COMMAND arraystocoords-exe)
+
+add_executable(copyblocks-exe CopyBlocks.cpp)
+target_link_libraries(copyblocks-exe ChunkBuffer)
+add_test(NAME copyblocks-test COMMAND copyblocks-exe)
diff --git a/tests/ChunkData/Coordinates.cpp b/tests/ChunkData/Coordinates.cpp
new file mode 100644
index 000000000..b3c66dde5
--- /dev/null
+++ b/tests/ChunkData/Coordinates.cpp
@@ -0,0 +1,156 @@
+
+#include "Globals.h"
+#include "ChunkData.h"
+
+
+
+int main(int argc, char** argv)
+{
+ class cMockAllocationPool
+ : public cAllocationPool<cChunkData::sChunkSection>
+ {
+ virtual cChunkData::sChunkSection * Allocate()
+ {
+ return new cChunkData::sChunkSection();
+ }
+
+ virtual void Free(cChunkData::sChunkSection * a_Ptr)
+ {
+ delete a_Ptr;
+ }
+ } Pool;
+ {
+ cChunkData buffer(Pool);
+
+ // Empty chunks
+ buffer.SetBlock(0, 0, 0, 0xAB);
+ testassert(buffer.GetBlock(0, 0, 0) == 0xAB);
+ buffer.SetMeta(0, 16, 0, 0xC);
+ testassert(buffer.GetMeta(0, 16, 0) == 0xC);
+
+ // loaded but not written segments
+ testassert(buffer.GetBlock(1, 0, 0) == 0x0);
+ testassert(buffer.GetMeta(1, 16, 0) == 0x0);
+
+ // Notloaded segments
+ testassert(buffer.GetBlock(0, 32, 0) == 0x0);
+ testassert(buffer.GetMeta(0, 48, 0) == 0x0);
+
+ // Out of Range
+ CheckAsserts(
+ buffer.SetBlock(-1, 0, 0, 0);
+ );
+ CheckAsserts(
+ buffer.SetBlock(0, -1, 0, 0);
+ );
+ CheckAsserts(
+ buffer.SetBlock(0, 0, -1, 0);
+ );
+ CheckAsserts(
+ buffer.SetBlock(256, 0, 0, 0);
+ );
+ CheckAsserts(
+ buffer.SetBlock(0, 256, 0, 0);
+ );
+ CheckAsserts(
+ buffer.SetBlock(0, 0, 256, 0);
+ );
+
+ // Out of Range
+ CheckAsserts(
+ buffer.GetBlock(-1, 0, 0);
+ );
+ CheckAsserts(
+ buffer.GetBlock(0, -1, 0);
+ );
+ CheckAsserts(
+ buffer.GetBlock(0, 0, -1);
+ );
+ CheckAsserts(
+ buffer.GetBlock(256, 0, 0);
+ );
+ CheckAsserts(
+ buffer.GetBlock(0, 256, 0);
+ );
+ CheckAsserts(
+ buffer.GetBlock(0, 0, 256);
+ );
+
+ // Out of Range
+ CheckAsserts(
+ buffer.SetMeta(-1, 0, 0, 0);
+ );
+ CheckAsserts(
+ buffer.SetMeta(0, -1, 0, 0);
+ );
+ CheckAsserts(
+ buffer.SetMeta(0, 0, -1, 0);
+ );
+ CheckAsserts(
+ buffer.SetMeta(256, 0, 0, 0);
+ );
+ CheckAsserts(
+ buffer.SetMeta(0, 256, 0, 0);
+ );
+ CheckAsserts(
+ buffer.SetMeta(0, 0, 256, 0);
+ );
+
+ // Out of Range
+ CheckAsserts(
+ buffer.GetMeta(-1, 0, 0);
+ );
+ CheckAsserts(
+ buffer.GetMeta(0, -1, 0);
+ );
+ CheckAsserts(
+ buffer.GetMeta(0, 0, -1);
+ );
+ CheckAsserts(
+ buffer.GetMeta(256, 0, 0);
+ );
+ CheckAsserts(
+ buffer.GetMeta(0, 256, 0);
+ );
+ CheckAsserts(
+ buffer.GetMeta(0, 0, 256);
+ );
+ }
+
+ {
+ cChunkData buffer(Pool);
+
+ // Zero's
+ buffer.SetBlock(0, 0, 0, 0x0);
+ buffer.SetBlock(0, 0, 1, 0xab);
+ testassert(buffer.GetBlock(0, 0, 0) == 0x0);
+ testassert(buffer.GetBlock(0, 0, 1) == 0xab);
+
+ buffer.SetMeta(0, 16, 0, 0x0);
+ buffer.SetMeta(0, 16, 1, 0xc);
+ testassert(buffer.GetMeta(0, 16, 0) == 0x0);
+ testassert(buffer.GetMeta(0, 16, 1) == 0xc);
+ }
+
+
+ {
+ // Operator =
+ cChunkData buffer(Pool);
+ buffer.SetBlock(0, 0, 0, 0x42);
+ cChunkData copy(Pool);
+ #if __cplusplus < 201103L
+ copy = buffer;
+ #else
+ copy = std::move(buffer);
+ #endif
+ testassert(copy.GetBlock(0, 0, 0) == 0x42);
+ #if __cplusplus < 201103L
+ copy = copy;
+ #else
+ copy = std::move(copy);
+ #endif
+ testassert(copy.GetBlock(0, 0, 0) == 0x42);
+ }
+
+ return 0;
+}
diff --git a/tests/ChunkData/Copies.cpp b/tests/ChunkData/Copies.cpp
new file mode 100644
index 000000000..440819e91
--- /dev/null
+++ b/tests/ChunkData/Copies.cpp
@@ -0,0 +1,147 @@
+
+#include "Globals.h"
+#include "ChunkData.h"
+
+
+
+int main(int argc, char** argv)
+{
+ class cMockAllocationPool
+ : public cAllocationPool<cChunkData::sChunkSection>
+ {
+ virtual cChunkData::sChunkSection * Allocate()
+ {
+ return new cChunkData::sChunkSection();
+ }
+
+ virtual void Free(cChunkData::sChunkSection * a_Ptr)
+ {
+ delete a_Ptr;
+ }
+ } Pool;
+ {
+ cChunkData buffer(Pool);
+
+ buffer.SetBlock(3, 1, 4, 0xDE);
+ buffer.SetMeta(3, 1, 4, 0xA);
+
+ cChunkData copy = buffer.Copy();
+ testassert(copy.GetBlock(3, 1, 4) == 0xDE);
+ testassert(copy.GetMeta(3, 1, 4) == 0xA);
+
+ BLOCKTYPE SrcBlockBuffer[16 * 16 * 256];
+ for (int i = 0; i < 16 * 16 * 256; i += 4)
+ {
+ SrcBlockBuffer[i + 0] = 0xde;
+ SrcBlockBuffer[i + 1] = 0xad;
+ SrcBlockBuffer[i + 2] = 0xbe;
+ SrcBlockBuffer[i + 3] = 0xef;
+ }
+
+ buffer.SetBlockTypes(SrcBlockBuffer);
+ BLOCKTYPE DstBlockBuffer[16 * 16 * 256];
+ buffer.CopyBlockTypes(DstBlockBuffer);
+ testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) - 1) == 0);
+
+ memset(SrcBlockBuffer, 0x00, 16 * 16 * 256);
+ buffer.SetBlockTypes(SrcBlockBuffer);
+ buffer.CopyBlockTypes(DstBlockBuffer);
+ testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) - 1) == 0);
+ }
+
+ {
+ cChunkData buffer(Pool);
+
+ NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2];
+ for (int i = 0; i < 16 * 16 * 256 / 2; i += 4)
+ {
+ SrcNibbleBuffer[i + 0] = 0xde;
+ SrcNibbleBuffer[i + 1] = 0xad;
+ SrcNibbleBuffer[i + 2] = 0xbe;
+ SrcNibbleBuffer[i + 3] = 0xef;
+ }
+
+ buffer.SetMetas(SrcNibbleBuffer);
+ NIBBLETYPE DstNibbleBuffer[16 * 16 * 256/ 2];
+ buffer.CopyMetas(DstNibbleBuffer);
+ testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0);
+
+ memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2);
+ buffer.SetMetas(SrcNibbleBuffer);
+ buffer.CopyMetas(DstNibbleBuffer);
+ testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0);
+ }
+
+ {
+ cChunkData buffer(Pool);
+
+ NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2];
+ for (int i = 0; i < 16 * 16 * 256 / 2; i += 4)
+ {
+ SrcNibbleBuffer[i + 0] = 0xde;
+ SrcNibbleBuffer[i + 1] = 0xad;
+ SrcNibbleBuffer[i + 2] = 0xbe;
+ SrcNibbleBuffer[i + 3] = 0xef;
+ }
+
+ buffer.SetBlockLight(SrcNibbleBuffer);
+ NIBBLETYPE DstNibbleBuffer[16 * 16 * 256 / 2];
+ buffer.CopyBlockLight(DstNibbleBuffer);
+ testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) - 1) == 0);
+
+ memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2);
+ buffer.SetBlockLight(SrcNibbleBuffer);
+ buffer.CopyBlockLight(DstNibbleBuffer);
+ testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) - 1) == 0);
+ }
+
+ {
+ cChunkData buffer(Pool);
+
+ NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2];
+ for (int i = 0; i < 16 * 16 * 256 / 2; i += 4)
+ {
+ SrcNibbleBuffer[i + 0] = 0xde;
+ SrcNibbleBuffer[i + 1] = 0xad;
+ SrcNibbleBuffer[i + 2] = 0xbe;
+ SrcNibbleBuffer[i + 3] = 0xef;
+ }
+
+ buffer.SetSkyLight(SrcNibbleBuffer);
+ NIBBLETYPE DstNibbleBuffer[16 * 16 * 256/ 2];
+ buffer.CopySkyLight(DstNibbleBuffer);
+ testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0);
+
+ memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 / 2);
+ buffer.SetSkyLight(SrcNibbleBuffer);
+ buffer.CopySkyLight(DstNibbleBuffer);
+ testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0);
+ }
+
+ {
+ cChunkData buffer(Pool);
+
+ BLOCKTYPE SrcBlockBuffer[16 * 16 * 256];
+ memset(SrcBlockBuffer, 0x00, 16 * 16 * 256);
+ BLOCKTYPE DstBlockBuffer[16 * 16 * 256];
+ buffer.CopyBlockTypes(DstBlockBuffer);
+ testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) - 1) == 0);
+
+ NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2];
+ memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2);
+ NIBBLETYPE DstNibbleBuffer[16 * 16 * 256 / 2];
+ buffer.CopyMetas(DstNibbleBuffer);
+ testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0);
+
+ memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2);
+ buffer.CopyBlockLight(DstNibbleBuffer);
+ testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0);
+
+ memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 / 2);
+ buffer.CopySkyLight(DstNibbleBuffer);
+ testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0);
+ }
+
+ // All tests successful:
+ return 0;
+}
diff --git a/tests/ChunkData/CopyBlocks.cpp b/tests/ChunkData/CopyBlocks.cpp
new file mode 100644
index 000000000..ec9451099
--- /dev/null
+++ b/tests/ChunkData/CopyBlocks.cpp
@@ -0,0 +1,89 @@
+
+// CopyBlocks.cpp
+
+// Implements the test for cChunkData::CopyBlockTypes() range copying
+
+
+
+
+
+#include "Globals.h"
+#include "ChunkData.h"
+
+
+
+
+
+int main(int argc, char ** argv)
+{
+ // Set up a cChunkData with known contents - all blocks 0x01, all metas 0x02:
+ class cMockAllocationPool
+ : public cAllocationPool<cChunkData::sChunkSection>
+ {
+ virtual cChunkData::sChunkSection * Allocate()
+ {
+ return new cChunkData::sChunkSection();
+ }
+
+ virtual void Free(cChunkData::sChunkSection * a_Ptr)
+ {
+ delete a_Ptr;
+ }
+ } Pool;
+ cChunkData Data(Pool);
+ cChunkDef::BlockTypes BlockTypes;
+ cChunkDef::BlockNibbles BlockMetas;
+ memset(BlockTypes, 0x01, sizeof(BlockTypes));
+ memset(BlockMetas, 0x02, sizeof(BlockMetas));
+ Data.SetBlockTypes(BlockTypes);
+ Data.SetMetas(BlockMetas);
+
+ // Try to read varying amounts of blocktypes from the cChunkData.
+ // Verify that the exact amount of memory is copied, by copying to a larger buffer and checking its boundaries
+ BLOCKTYPE TestBuffer[5 * cChunkDef::NumBlocks];
+ size_t WritePosIdx = 2 * cChunkDef::NumBlocks;
+ BLOCKTYPE * WritePosition = &TestBuffer[WritePosIdx];
+ memset(TestBuffer, 0x03, sizeof(TestBuffer));
+ size_t LastReportedStep = 1;
+ for (size_t idx = 0; idx < 5000; idx += 7)
+ {
+ if (idx / 500 != LastReportedStep)
+ {
+ printf("Testing index %u...\n", (unsigned)idx);
+ LastReportedStep = idx / 500;
+ }
+
+ for (size_t len = 3; len < 1000; len += 13)
+ {
+ Data.CopyBlockTypes(WritePosition, idx, len);
+
+ // Verify the data copied:
+ for (size_t i = 0; i < len; i++)
+ {
+ assert_test(WritePosition[i] == 0x01);
+ }
+ // Verify the space before the copied data hasn't been changed:
+ for (size_t i = 0; i < WritePosIdx; i++)
+ {
+ assert_test(TestBuffer[i] == 0x03);
+ }
+ // Verify the space after the copied data hasn't been changed:
+ for (size_t i = WritePosIdx + idx + len; i < ARRAYCOUNT(TestBuffer); i++)
+ {
+ assert_test(TestBuffer[i] == 0x03);
+ }
+
+ // Re-initialize the buffer for the next test:
+ for (size_t i = 0; i < len; i++)
+ {
+ WritePosition[i] = 0x03;
+ }
+ } // for len
+ } // for idx
+ return 0;
+}
+
+
+
+
+
diff --git a/tests/ChunkData/creatable.cpp b/tests/ChunkData/creatable.cpp
new file mode 100644
index 000000000..fc786f688
--- /dev/null
+++ b/tests/ChunkData/creatable.cpp
@@ -0,0 +1,22 @@
+
+#include "Globals.h"
+#include "ChunkData.h"
+
+int main(int argc, char** argv)
+{
+ class cMockAllocationPool
+ : public cAllocationPool<cChunkData::sChunkSection>
+ {
+ virtual cChunkData::sChunkSection * Allocate()
+ {
+ return new cChunkData::sChunkSection();
+ }
+
+ virtual void Free(cChunkData::sChunkSection * a_Ptr)
+ {
+ delete a_Ptr;
+ }
+ } Pool;
+ cChunkData buffer(Pool);
+ return 0;
+}
diff --git a/uploadCoverage.sh b/uploadCoverage.sh
new file mode 100755
index 000000000..fc17ddc2c
--- /dev/null
+++ b/uploadCoverage.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ]
+ then
+ find tests -type f -name '*.gcda' -exec sh -c 'cp {} $(dirname {})/../$(basename {})' \;
+ coveralls --exclude lib --exclude Android >/dev/null
+fi
+
+